adding new file - not part of build
git-svn-id: svn://10.0.0.236/trunk@64329 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
106
mozilla/xpcom/reflect/xptinfo/public/nsIInterfaceInfo.idl
Normal file
106
mozilla/xpcom/reflect/xptinfo/public/nsIInterfaceInfo.idl
Normal file
@@ -0,0 +1,106 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* The nsIInterfaceInfo public declaration. */
|
||||
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
// forward declaration of non-XPCOM types
|
||||
|
||||
[ptr] native nsXPTMethodInfoPtr(nsXPTMethodInfo);
|
||||
[ptr] native nsXPTConstantPtr(nsXPTConstant);
|
||||
[ptr] native nsXPTParamInfoPtr(nsXPTParamInfo);
|
||||
native nsXPTType(nsXPTType);
|
||||
|
||||
%{C++
|
||||
class nsXPTMethodInfo;
|
||||
class nsXPTConstant;
|
||||
class nsXPTParamInfo;
|
||||
class nsXPTType;
|
||||
%}
|
||||
|
||||
/* this is NOT intended to be scriptable */
|
||||
[uuid(215DBE04-94A7-11d2-BA58-00805F8A5DD7)]
|
||||
interface nsIInterfaceInfo : nsISupports
|
||||
{
|
||||
readonly attribute string name;
|
||||
readonly attribute nsIIDPtr IID;
|
||||
|
||||
PRBool isScriptable();
|
||||
|
||||
readonly attribute nsIInterfaceInfo parent;
|
||||
|
||||
/**
|
||||
* These include counts for parent (and all ancestors).
|
||||
*/
|
||||
readonly attribute PRUint16 methodCount;
|
||||
readonly attribute PRUint16 constantCount;
|
||||
|
||||
/**
|
||||
* These include methods and constants for parent (and all ancestors).
|
||||
*
|
||||
* These do *not* make copies ***explicit bending of XPCOM rules***.
|
||||
*/
|
||||
|
||||
void getMethodInfo(in PRUint16 index,
|
||||
[shared, retval] out nsXPTMethodInfoPtr info);
|
||||
|
||||
void getMethodInfoForName(in string methodName, out PRUint16 index,
|
||||
[shared, retval] out nsXPTMethodInfoPtr info);
|
||||
|
||||
void getConstant(in PRUint16 index,
|
||||
[shared, retval] out nsXPTConstantPtr constant);
|
||||
|
||||
|
||||
/**
|
||||
* Get the interface information or iid associated with a param of some
|
||||
* method in this interface.
|
||||
*/
|
||||
|
||||
nsIInterfaceInfo getInfoForParam(in PRUint16 methodIndex,
|
||||
[const] in nsXPTParamInfoPtr param);
|
||||
|
||||
nsIIDPtr getIIDForParam(in PRUint16 methodIndex,
|
||||
[const] in nsXPTParamInfoPtr param);
|
||||
|
||||
|
||||
/**
|
||||
* These do *not* make copies ***explicit bending of XPCOM rules***.
|
||||
*/
|
||||
|
||||
nsXPTType getTypeForParam(in PRUint16 methodIndex,
|
||||
[const] in nsXPTParamInfoPtr param,
|
||||
in PRUint16 dimension);
|
||||
|
||||
PRUint8 getSizeIsArgNumberForParam(in PRUint16 methodIndex,
|
||||
[const] in nsXPTParamInfoPtr param,
|
||||
in PRUint16 dimension);
|
||||
|
||||
PRUint8 getLengthIsArgNumberForParam(in PRUint16 methodIndex,
|
||||
[const] in nsXPTParamInfoPtr param,
|
||||
in PRUint16 dimension);
|
||||
|
||||
PRUint8 getInterfaceIsArgNumberForParam(in PRUint16 methodIndex,
|
||||
[const] in nsXPTParamInfoPtr param);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* The nsIInterfaceInfoManager public declaration. */
|
||||
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIInterfaceInfo.idl"
|
||||
#include "nsIEnumerator.idl"
|
||||
|
||||
/* this is NOT intended to be scriptable */
|
||||
[uuid(8B161900-BE2B-11d2-9831-006008962422)]
|
||||
interface nsIInterfaceInfoManager : nsISupports
|
||||
{
|
||||
nsIInterfaceInfo getInfoForIID(in nsIIDPtr iid);
|
||||
nsIInterfaceInfo getInfoForName(in string name);
|
||||
|
||||
nsIIDPtr getIIDForName(in string name);
|
||||
string getNameForIID(in nsIIDPtr iid);
|
||||
|
||||
nsIEnumerator enumerateInterfaces();
|
||||
|
||||
void autoRegisterInterfaces();
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
#ifndef NS_DECL_NSIINTERFACEINFO
|
||||
#define NS_DECL_NSIINTERFACEINFO \
|
||||
NS_IMETHOD GetName(char * *aName); \
|
||||
NS_IMETHOD GetIID(nsIID * *aIID); \
|
||||
NS_IMETHOD IsScriptable(PRBool *_retval); \
|
||||
NS_IMETHOD GetParent(nsIInterfaceInfo * *aParent); \
|
||||
NS_IMETHOD GetMethodCount(PRUint16 *aMethodCount); \
|
||||
NS_IMETHOD GetConstantCount(PRUint16 *aConstantCount); \
|
||||
NS_IMETHOD GetMethodInfo(PRUint16 index, const nsXPTMethodInfo * *info); \
|
||||
NS_IMETHOD GetMethodInfoForName(const char *methodName, PRUint16 *index, const nsXPTMethodInfo * *info); \
|
||||
NS_IMETHOD GetConstant(PRUint16 index, const nsXPTConstant * *constant); \
|
||||
NS_IMETHOD GetInfoForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIInterfaceInfo **_retval); \
|
||||
NS_IMETHOD GetIIDForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID * *_retval); \
|
||||
NS_IMETHOD GetTypeForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, nsXPTType *_retval); \
|
||||
NS_IMETHOD GetSizeIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval); \
|
||||
NS_IMETHOD GetLengthIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval); \
|
||||
NS_IMETHOD GetInterfaceIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint8 *_retval);
|
||||
#endif
|
||||
|
||||
#ifndef NS_DECL_NSIINTERFACEINFOMANAGER
|
||||
#define NS_DECL_NSIINTERFACEINFOMANAGER \
|
||||
NS_IMETHOD GetInfoForIID(const nsIID * iid, nsIInterfaceInfo **_retval); \
|
||||
NS_IMETHOD GetInfoForName(const char *name, nsIInterfaceInfo **_retval); \
|
||||
NS_IMETHOD GetIIDForName(const char *name, nsIID * *_retval); \
|
||||
NS_IMETHOD GetNameForIID(const nsIID * iid, char **_retval); \
|
||||
NS_IMETHOD EnumerateInterfaces(nsIEnumerator **_retval); \
|
||||
NS_IMETHOD AutoRegisterInterfaces(void);
|
||||
#endif
|
||||
|
||||
88
mozilla/xpcom/reflect/xptinfo/src/xptiFile.cpp
Normal file
88
mozilla/xpcom/reflect/xptinfo/src/xptiFile.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* Implementation of xptiFile. */
|
||||
|
||||
#include "xptiprivate.h"
|
||||
|
||||
|
||||
xptiFile::xptiFile()
|
||||
: mSize(),
|
||||
mDate(),
|
||||
mName(nsnull),
|
||||
mGuts(nsnull)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
xptiFile::xptiFile(const nsInt64& aSize,
|
||||
const nsInt64& aDate,
|
||||
const char* aName,
|
||||
xptiWorkingSet* aWorkingSet,
|
||||
XPTHeader* aHeader /*= nsnull */)
|
||||
|
||||
: mSize(aSize),
|
||||
mDate(aDate),
|
||||
mName(aName),
|
||||
mGuts(nsnull)
|
||||
{
|
||||
NS_ASSERTION(aWorkingSet,"bad param");
|
||||
mName = XPT_STRDUP(aWorkingSet->GetStringArena(), aName);
|
||||
|
||||
if(aHeader)
|
||||
SetHeader(aHeader);
|
||||
}
|
||||
|
||||
xptiFile::xptiFile(const xptiFile& r, xptiWorkingSet* aWorkingSet,
|
||||
PRBool cloneGuts)
|
||||
: mSize(r.mSize),
|
||||
mDate(r.mDate),
|
||||
mName(nsnull),
|
||||
mGuts(nsnull)
|
||||
{
|
||||
NS_ASSERTION(aWorkingSet,"bad param");
|
||||
mName = XPT_STRDUP(aWorkingSet->GetStringArena(), r.mName);
|
||||
|
||||
if(cloneGuts && r.mGuts)
|
||||
mGuts = r.mGuts->Clone();
|
||||
}
|
||||
|
||||
xptiFile::~xptiFile()
|
||||
{
|
||||
if(mGuts)
|
||||
delete mGuts;
|
||||
}
|
||||
|
||||
PRBool
|
||||
xptiFile::SetHeader(XPTHeader* aHeader)
|
||||
{
|
||||
NS_ASSERTION(!mGuts,"bad state");
|
||||
NS_ASSERTION(aHeader,"bad param");
|
||||
|
||||
mGuts = new xptiTypelibGuts(aHeader);
|
||||
if(mGuts && !mGuts->IsValid())
|
||||
{
|
||||
delete mGuts;
|
||||
mGuts = nsnull;
|
||||
}
|
||||
return mGuts != nsnull;
|
||||
}
|
||||
594
mozilla/xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
Normal file
594
mozilla/xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
Normal file
@@ -0,0 +1,594 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* Implementation of xptiInterfaceInfo. */
|
||||
|
||||
#include "xptiprivate.h"
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(xptiInterfaceInfo, nsIInterfaceInfo)
|
||||
|
||||
xptiInterfaceInfo::xptiInterfaceInfo(const char* name,
|
||||
const nsID& iid,
|
||||
const xptiTypelib& typelib,
|
||||
xptiWorkingSet& aWorkingSet)
|
||||
: mIID(iid),
|
||||
mName(nsnull),
|
||||
mTypelib(typelib)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
int len = PL_strlen(name);
|
||||
char* ptr = (char*) XPT_MALLOC(aWorkingSet.GetStringArena(), len+2);
|
||||
if(ptr)
|
||||
{
|
||||
mName = &ptr[1];
|
||||
memcpy(mName, name, len);
|
||||
// XXX These are redundant as long as the underlying arena continues
|
||||
// to zero out all mallocs. But...
|
||||
mName[-1] = mName[len] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
xptiInterfaceInfo::~xptiInterfaceInfo()
|
||||
{
|
||||
if(HasInterfaceRecord())
|
||||
delete mInterface;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
xptiInterfaceInfo::Resolve(xptiWorkingSet* aWorkingSet)
|
||||
{
|
||||
int resolvedState = GetResolveState();
|
||||
|
||||
if(resolvedState == FULLY_RESOLVED)
|
||||
return PR_TRUE;
|
||||
if(resolvedState == RESOLVE_FAILED)
|
||||
return PR_FALSE;
|
||||
|
||||
xptiInterfaceInfoManager* mgr =
|
||||
xptiInterfaceInfoManager::GetInterfaceInfoManager();
|
||||
|
||||
if(!mgr)
|
||||
return PR_FALSE;
|
||||
|
||||
if(!aWorkingSet)
|
||||
{
|
||||
aWorkingSet = mgr->GetWorkingSet();
|
||||
}
|
||||
|
||||
if(resolvedState == NOT_RESOLVED)
|
||||
{
|
||||
printf("~ partial resolve of %s\n", mName);
|
||||
// Make a copy of mTypelib because the underlying memory will change!
|
||||
xptiTypelib typelib = mTypelib;
|
||||
|
||||
// We expect our PartiallyResolve() to get called before this returns.
|
||||
if(!mgr->LoadFile(typelib, aWorkingSet))
|
||||
{
|
||||
NS_RELEASE(mgr);
|
||||
SetResolvedState(RESOLVE_FAILED);
|
||||
return PR_FALSE;
|
||||
}
|
||||
// The state was changed by LoadFile to PARTIALLY_RESOLVED, so this
|
||||
// ...falls through...
|
||||
}
|
||||
NS_IF_RELEASE(mgr);
|
||||
|
||||
NS_ASSERTION(GetResolveState() == PARTIALLY_RESOLVED, "bad state!");
|
||||
|
||||
printf("+ final resolve of %s\n", mName);
|
||||
|
||||
// Finish out resolution by finding parent and Resolving it so
|
||||
// we can set the info we get from it.
|
||||
|
||||
PRUint16 parent_index = mInterface->mDescriptor->parent_interface;
|
||||
|
||||
if(parent_index)
|
||||
{
|
||||
xptiInterfaceInfo* parent =
|
||||
aWorkingSet->GetTypelibGuts(mInterface->mTypelib)->
|
||||
GetInfoAtNoAddRef(parent_index - 1);
|
||||
|
||||
if(!parent || !parent->EnsureResolved())
|
||||
{
|
||||
xptiTypelib aTypelib = mInterface->mTypelib;
|
||||
delete mInterface;
|
||||
mTypelib = aTypelib;
|
||||
SetResolvedState(RESOLVE_FAILED);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_ADDREF(mInterface->mParent = parent);
|
||||
|
||||
mInterface->mMethodBaseIndex =
|
||||
parent->mInterface->mMethodBaseIndex +
|
||||
parent->mInterface->mDescriptor->num_methods;
|
||||
|
||||
mInterface->mConstantBaseIndex =
|
||||
parent->mInterface->mConstantBaseIndex +
|
||||
parent->mInterface->mDescriptor->num_constants;
|
||||
|
||||
}
|
||||
SetResolvedState(FULLY_RESOLVED);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
xptiInterfaceInfo::PartiallyResolve(XPTInterfaceDescriptor* aDescriptor,
|
||||
xptiWorkingSet* aWorkingSet)
|
||||
{
|
||||
NS_ASSERTION(GetResolveState() == NOT_RESOLVED, "bad state");
|
||||
|
||||
xptiInterfaceGuts* iface =
|
||||
new xptiInterfaceGuts(aDescriptor, mTypelib, aWorkingSet);
|
||||
|
||||
if(!iface)
|
||||
return PR_FALSE;
|
||||
|
||||
mInterface = iface;
|
||||
SetResolvedState(PARTIALLY_RESOLVED);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetName(char **name)
|
||||
{
|
||||
NS_PRECONDITION(name, "bad param");
|
||||
|
||||
if(!mName)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
char* ptr = *name = (char*) nsAllocator::Clone(mName, PL_strlen(mName)+1);
|
||||
return ptr ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetIID(nsIID **iid)
|
||||
{
|
||||
NS_PRECONDITION(iid, "bad param");
|
||||
|
||||
nsIID* ptr = *iid = (nsIID*) nsAllocator::Clone(&mIID, sizeof(nsIID));
|
||||
return ptr ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::IsScriptable(PRBool* result)
|
||||
{
|
||||
NS_ASSERTION(result, "bad bad caller!");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
*result = XPT_ID_IS_SCRIPTABLE(mInterface->mDescriptor->flags);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetParent(nsIInterfaceInfo** parent)
|
||||
{
|
||||
NS_PRECONDITION(parent, "bad param");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
NS_IF_ADDREF(*parent = mInterface->mParent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetMethodCount(uint16* count)
|
||||
{
|
||||
NS_PRECONDITION(count, "bad param");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
*count = mInterface->mMethodBaseIndex +
|
||||
mInterface->mDescriptor->num_methods;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetConstantCount(uint16* count)
|
||||
{
|
||||
NS_PRECONDITION(count, "bad param");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
*count = mInterface->mConstantBaseIndex +
|
||||
mInterface->mDescriptor->num_constants;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetMethodInfo(uint16 index, const nsXPTMethodInfo** info)
|
||||
{
|
||||
NS_PRECONDITION(info, "bad param");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(index < mInterface->mMethodBaseIndex)
|
||||
return mInterface->mParent->GetMethodInfo(index, info);
|
||||
|
||||
if(index >= mInterface->mMethodBaseIndex +
|
||||
mInterface->mDescriptor->num_methods)
|
||||
{
|
||||
NS_ASSERTION(0, "bad param");
|
||||
*info = NULL;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// else...
|
||||
*info = NS_REINTERPRET_CAST(nsXPTMethodInfo*,
|
||||
&mInterface->mDescriptor->
|
||||
method_descriptors[index -
|
||||
mInterface->mMethodBaseIndex]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetMethodInfoForName(const char* methodName, uint16 *index,
|
||||
const nsXPTMethodInfo** result)
|
||||
{
|
||||
NS_PRECONDITION(methodName, "bad param");
|
||||
NS_PRECONDITION(index, "bad param");
|
||||
NS_PRECONDITION(result, "bad param");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
// This is a slow algorithm, but this is not expected to be called much.
|
||||
for(uint16 i = mInterface->mMethodBaseIndex;
|
||||
i < mInterface->mDescriptor->num_methods;
|
||||
++i)
|
||||
{
|
||||
const nsXPTMethodInfo* info;
|
||||
info = NS_REINTERPRET_CAST(nsXPTMethodInfo*,
|
||||
&mInterface->mDescriptor->
|
||||
method_descriptors[i -
|
||||
mInterface->mMethodBaseIndex]);
|
||||
*index = i;
|
||||
*result = info;
|
||||
return NS_OK;
|
||||
}
|
||||
if(mInterface->mParent)
|
||||
return mInterface->mParent->GetMethodInfoForName(methodName, index, result);
|
||||
else
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetConstant(uint16 index, const nsXPTConstant** constant)
|
||||
{
|
||||
NS_PRECONDITION(constant, "bad param");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(index < mInterface->mConstantBaseIndex)
|
||||
return mInterface->mParent->GetConstant(index, constant);
|
||||
|
||||
if(index >= mInterface->mConstantBaseIndex +
|
||||
mInterface->mDescriptor->num_constants)
|
||||
{
|
||||
NS_PRECONDITION(0, "bad param");
|
||||
*constant = NULL;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// else...
|
||||
*constant =
|
||||
NS_REINTERPRET_CAST(nsXPTConstant*,
|
||||
&mInterface->mDescriptor->
|
||||
const_descriptors[index -
|
||||
mInterface->mConstantBaseIndex]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetInfoForParam(uint16 methodIndex,
|
||||
const nsXPTParamInfo *param,
|
||||
nsIInterfaceInfo** info)
|
||||
{
|
||||
NS_PRECONDITION(param, "bad pointer");
|
||||
NS_PRECONDITION(info, "bad pointer");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(methodIndex < mInterface->mMethodBaseIndex)
|
||||
return mInterface->mParent->GetInfoForParam(methodIndex, param, info);
|
||||
|
||||
if(methodIndex >= mInterface->mMethodBaseIndex +
|
||||
mInterface->mDescriptor->num_methods)
|
||||
{
|
||||
NS_PRECONDITION(0, "bad param");
|
||||
*info = NULL;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const XPTTypeDescriptor *td = ¶m->type;
|
||||
|
||||
while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
|
||||
td = &mInterface->mDescriptor->
|
||||
additional_types[td->type.additional_type];
|
||||
}
|
||||
|
||||
if(XPT_TDP_TAG(td->prefix) != TD_INTERFACE_TYPE) {
|
||||
NS_ASSERTION(0, "not an interface");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsIInterfaceInfo* theInfo =
|
||||
mInterface->mWorkingSet->GetTypelibGuts(mInterface->mTypelib)->
|
||||
GetInfoAtNoAddRef(td->type.interface - 1);
|
||||
|
||||
NS_IF_ADDREF(*info = theInfo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetIIDForParam(uint16 methodIndex,
|
||||
const nsXPTParamInfo* param, nsIID** iid)
|
||||
{
|
||||
NS_PRECONDITION(param, "bad pointer");
|
||||
NS_PRECONDITION(iid, "bad pointer");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(methodIndex < mInterface->mMethodBaseIndex)
|
||||
return mInterface->mParent->GetIIDForParam(methodIndex, param, iid);
|
||||
|
||||
if(methodIndex >= mInterface->mMethodBaseIndex +
|
||||
mInterface->mDescriptor->num_methods)
|
||||
{
|
||||
NS_PRECONDITION(0, "bad param");
|
||||
*iid = NULL;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const XPTTypeDescriptor *td = ¶m->type;
|
||||
|
||||
while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
|
||||
td = &mInterface->mDescriptor->
|
||||
additional_types[td->type.additional_type];
|
||||
}
|
||||
|
||||
if(XPT_TDP_TAG(td->prefix) != TD_INTERFACE_TYPE) {
|
||||
NS_ASSERTION(0, "not an interface");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsIInterfaceInfo* theInfo =
|
||||
mInterface->mWorkingSet->GetTypelibGuts(mInterface->mTypelib)->
|
||||
GetInfoAtNoAddRef(td->type.interface - 1);
|
||||
|
||||
return theInfo->GetIID(iid);
|
||||
}
|
||||
|
||||
// this is a private helper
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetTypeInArray(const nsXPTParamInfo* param,
|
||||
uint16 dimension,
|
||||
const XPTTypeDescriptor** type)
|
||||
{
|
||||
NS_ASSERTION(param, "bad state");
|
||||
NS_ASSERTION(type, "bad state");
|
||||
NS_ASSERTION(IsFullyResolved(), "bad state");
|
||||
|
||||
const XPTTypeDescriptor *td = ¶m->type;
|
||||
const XPTTypeDescriptor *additional_types =
|
||||
mInterface->mDescriptor->additional_types;
|
||||
|
||||
for (uint16 i = 0; i < dimension; i++) {
|
||||
if(XPT_TDP_TAG(td->prefix) != TD_ARRAY) {
|
||||
NS_ASSERTION(0, "bad dimension");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
td = &additional_types[td->type.additional_type];
|
||||
}
|
||||
|
||||
*type = td;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetTypeForParam(uint16 methodIndex,
|
||||
const nsXPTParamInfo* param,
|
||||
uint16 dimension,
|
||||
nsXPTType* type)
|
||||
{
|
||||
NS_PRECONDITION(param, "bad pointer");
|
||||
NS_PRECONDITION(type, "bad pointer");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(methodIndex < mInterface->mMethodBaseIndex)
|
||||
return mInterface->mParent->GetTypeForParam(methodIndex, param,
|
||||
dimension, type);
|
||||
|
||||
if(methodIndex >= mInterface->mMethodBaseIndex +
|
||||
mInterface->mDescriptor->num_methods)
|
||||
{
|
||||
NS_ASSERTION(0, "bad index");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const XPTTypeDescriptor *td;
|
||||
|
||||
if(dimension) {
|
||||
nsresult rv = GetTypeInArray(param, dimension, &td);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
td = ¶m->type;
|
||||
|
||||
*type = nsXPTType(td->prefix);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetSizeIsArgNumberForParam(uint16 methodIndex,
|
||||
const nsXPTParamInfo* param,
|
||||
uint16 dimension,
|
||||
uint8* argnum)
|
||||
{
|
||||
NS_PRECONDITION(param, "bad pointer");
|
||||
NS_PRECONDITION(argnum, "bad pointer");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(methodIndex < mInterface->mMethodBaseIndex)
|
||||
return mInterface->mParent->
|
||||
GetSizeIsArgNumberForParam(methodIndex, param,
|
||||
dimension, argnum);
|
||||
|
||||
if(methodIndex >= mInterface->mMethodBaseIndex +
|
||||
mInterface->mDescriptor->num_methods)
|
||||
{
|
||||
NS_ASSERTION(0, "bad index");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const XPTTypeDescriptor *td;
|
||||
|
||||
if(dimension) {
|
||||
nsresult rv = GetTypeInArray(param, dimension, &td);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
td = ¶m->type;
|
||||
|
||||
// verify that this is a type that has size_is
|
||||
switch (XPT_TDP_TAG(td->prefix)) {
|
||||
case TD_ARRAY:
|
||||
case TD_PSTRING_SIZE_IS:
|
||||
case TD_PWSTRING_SIZE_IS:
|
||||
break;
|
||||
default:
|
||||
NS_ASSERTION(0, "not a size_is");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*argnum = td->argnum;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetLengthIsArgNumberForParam(uint16 methodIndex,
|
||||
const nsXPTParamInfo* param,
|
||||
uint16 dimension,
|
||||
uint8* argnum)
|
||||
{
|
||||
NS_PRECONDITION(param, "bad pointer");
|
||||
NS_PRECONDITION(argnum, "bad pointer");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(methodIndex < mInterface->mMethodBaseIndex)
|
||||
return mInterface->mParent->
|
||||
GetLengthIsArgNumberForParam(methodIndex, param,
|
||||
dimension, argnum);
|
||||
|
||||
if(methodIndex >= mInterface->mMethodBaseIndex +
|
||||
mInterface->mDescriptor->num_methods)
|
||||
{
|
||||
NS_ASSERTION(0, "bad index");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const XPTTypeDescriptor *td;
|
||||
|
||||
if(dimension) {
|
||||
nsresult rv = GetTypeInArray(param, dimension, &td);
|
||||
if(NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
else
|
||||
td = ¶m->type;
|
||||
|
||||
// verify that this is a type that has length_is
|
||||
switch (XPT_TDP_TAG(td->prefix)) {
|
||||
case TD_ARRAY:
|
||||
case TD_PSTRING_SIZE_IS:
|
||||
case TD_PWSTRING_SIZE_IS:
|
||||
break;
|
||||
default:
|
||||
NS_ASSERTION(0, "not a length_is");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*argnum = td->argnum2;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xptiInterfaceInfo::GetInterfaceIsArgNumberForParam(uint16 methodIndex,
|
||||
const nsXPTParamInfo* param,
|
||||
uint8* argnum)
|
||||
{
|
||||
NS_PRECONDITION(param, "bad pointer");
|
||||
NS_PRECONDITION(argnum, "bad pointer");
|
||||
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(methodIndex < mInterface->mMethodBaseIndex)
|
||||
return mInterface->mParent->
|
||||
GetInterfaceIsArgNumberForParam(methodIndex, param,
|
||||
argnum);
|
||||
|
||||
if(methodIndex >= mInterface->mMethodBaseIndex +
|
||||
mInterface->mDescriptor->num_methods)
|
||||
{
|
||||
NS_ASSERTION(0, "bad index");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const XPTTypeDescriptor *td = ¶m->type;
|
||||
|
||||
while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
|
||||
td = &mInterface->mDescriptor->
|
||||
additional_types[td->type.additional_type];
|
||||
}
|
||||
|
||||
if(XPT_TDP_TAG(td->prefix) != TD_INTERFACE_IS_TYPE) {
|
||||
NS_ASSERTION(0, "not an iid_is");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*argnum = td->argnum;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
1208
mozilla/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
Normal file
1208
mozilla/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
Normal file
File diff suppressed because it is too large
Load Diff
567
mozilla/xpcom/reflect/xptinfo/src/xptiManifest.cpp
Normal file
567
mozilla/xpcom/reflect/xptinfo/src/xptiManifest.cpp
Normal file
@@ -0,0 +1,567 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* Implementation of xptiManifest. */
|
||||
|
||||
#include "xptiprivate.h"
|
||||
|
||||
|
||||
static const char g_MainManifestFilename[] = "xpti.dat";
|
||||
static const char g_TempManifestFilename[] = "xptitemp.dat";
|
||||
|
||||
static const char g_Disclaimer[] = "# Generated file. ** DO NOT EDIT! **";
|
||||
|
||||
static const char g_TOKEN_Files[] = "Files";
|
||||
static const char g_TOKEN_ArchiveItems[] = "ArchiveItems";
|
||||
static const char g_TOKEN_Interfaces[] = "Interfaces";
|
||||
static const char g_TOKEN_Header[] = "Header";
|
||||
static const char g_TOKEN_Version[] = "Version";
|
||||
|
||||
static const int g_VERSION_MAJOR = 1;
|
||||
static const int g_VERSION_MINOR = 0;
|
||||
|
||||
// This is used to make PR_sscanf for strings safer. We refuse to even
|
||||
// attempt to do a PR_sscanf from a line longer than this.
|
||||
static const int g_MAX_LINE_LEN = 256;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static PRBool
|
||||
WriteFormatted(FILE* file, const char* fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
char* buf = PR_vsmprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if(!buf)
|
||||
return PR_FALSE;
|
||||
|
||||
size_t len = PL_strlen(buf);
|
||||
|
||||
PRBool result = (len == fwrite(buf, 1, len, file));
|
||||
|
||||
PR_smprintf_free(buf);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static PR_CALLBACK PRIntn
|
||||
xpti_InterfaceWriter(PLHashEntry *he, PRIntn i, void *arg)
|
||||
{
|
||||
xptiInterfaceInfo* info = (xptiInterfaceInfo*) he->value;
|
||||
FILE* file = (FILE*) arg;
|
||||
|
||||
if(!info->IsValid())
|
||||
return HT_ENUMERATE_STOP;
|
||||
|
||||
char* iidStr = info->GetTheIID()->ToString();
|
||||
if(!iidStr)
|
||||
return HT_ENUMERATE_STOP;
|
||||
|
||||
const xptiTypelib& typelib = info->GetTypelibRecord();
|
||||
|
||||
PRBool success = WriteFormatted(file, "%d,%s,%s,%d,%d\n",
|
||||
(int) i,
|
||||
info->GetTheName(),
|
||||
iidStr,
|
||||
(int) typelib.GetFileIndex(),
|
||||
(int) (typelib.IsZip() ?
|
||||
typelib.GetZipItemIndex() : -1));
|
||||
|
||||
nsCRT::free(iidStr);
|
||||
|
||||
return success ? HT_ENUMERATE_NEXT : HT_ENUMERATE_STOP;
|
||||
}
|
||||
|
||||
// static
|
||||
PRBool xptiManifest::Write(xptiInterfaceInfoManager* aMgr,
|
||||
xptiWorkingSet& aWorkingSet)
|
||||
{
|
||||
|
||||
PRBool succeeded = PR_FALSE;
|
||||
FILE* file = nsnull;
|
||||
PRUint32 i;
|
||||
PRIntn interfaceCount = 0;
|
||||
|
||||
nsCOMPtr<nsILocalFile> tempFile;
|
||||
if(!aMgr->GetComponentsDir(getter_AddRefs(tempFile)) || !tempFile)
|
||||
return PR_FALSE;
|
||||
|
||||
if(NS_FAILED(tempFile->Append(g_TempManifestFilename)))
|
||||
return PR_FALSE;
|
||||
|
||||
// exist via "goto out;" from here on...
|
||||
|
||||
|
||||
if(NS_FAILED(tempFile->OpenANSIFileDesc("w", &file)) || !file)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
// write file header comments
|
||||
|
||||
if(!WriteFormatted(file, "%s\n", g_Disclaimer))
|
||||
goto out;
|
||||
|
||||
// write the [Header] block and version number.
|
||||
|
||||
if(!WriteFormatted(file, "\n[%s,%d]\n", g_TOKEN_Header, 1))
|
||||
goto out;
|
||||
|
||||
if(!WriteFormatted(file, "%d,%s,%d,%d\n",
|
||||
0, g_TOKEN_Version, g_VERSION_MAJOR, g_VERSION_MINOR))
|
||||
goto out;
|
||||
|
||||
// write Files list
|
||||
|
||||
if(!WriteFormatted(file, "\n[%s,%d]\n",
|
||||
g_TOKEN_Files,
|
||||
(int) aWorkingSet.GetFileCount()))
|
||||
goto out;
|
||||
|
||||
for(i = 0; i < aWorkingSet.GetFileCount(); i++)
|
||||
{
|
||||
if(!WriteFormatted(file, "%d,%s,%lld,%lld\n",
|
||||
(int) i,
|
||||
aWorkingSet.GetFileAt(i).GetName(),
|
||||
PRInt64(aWorkingSet.GetFileAt(i).GetSize()),
|
||||
PRInt64(aWorkingSet.GetFileAt(i).GetDate())))
|
||||
goto out;
|
||||
}
|
||||
|
||||
// write ArchiveItems list
|
||||
|
||||
if(!WriteFormatted(file, "\n[%s,%d]\n",
|
||||
g_TOKEN_ArchiveItems,
|
||||
(int) aWorkingSet.GetZipItemCount()))
|
||||
goto out;
|
||||
|
||||
for(i = 0; i < aWorkingSet.GetZipItemCount(); i++)
|
||||
{
|
||||
if(!WriteFormatted(file, "%d,%s\n",
|
||||
(int) i,
|
||||
aWorkingSet.GetZipItemAt(i).GetName()))
|
||||
goto out;
|
||||
}
|
||||
|
||||
// write the Interfaces list
|
||||
|
||||
interfaceCount = aWorkingSet.mNameTable->nentries;
|
||||
|
||||
if(!WriteFormatted(file, "\n[%s,%d]\n",
|
||||
g_TOKEN_Interfaces,
|
||||
(int) interfaceCount))
|
||||
goto out;
|
||||
|
||||
if(interfaceCount !=
|
||||
PL_HashTableEnumerateEntries(aWorkingSet.mNameTable,
|
||||
xpti_InterfaceWriter, file))
|
||||
goto out;
|
||||
|
||||
|
||||
if(0 == fclose(file))
|
||||
{
|
||||
succeeded = PR_TRUE;
|
||||
}
|
||||
file = nsnull;
|
||||
|
||||
out:
|
||||
if(file)
|
||||
fclose(file);
|
||||
|
||||
if(succeeded)
|
||||
{
|
||||
// delete the old file and rename this
|
||||
nsCOMPtr<nsILocalFile> mainFile;
|
||||
if(!aMgr->GetComponentsDir(getter_AddRefs(mainFile)) || !mainFile)
|
||||
return PR_FALSE;
|
||||
|
||||
if(NS_FAILED(mainFile->Append(g_MainManifestFilename)))
|
||||
return PR_FALSE;
|
||||
|
||||
PRBool exists;
|
||||
if(NS_FAILED(mainFile->Exists(&exists)))
|
||||
return PR_FALSE;
|
||||
|
||||
if(exists && NS_FAILED(mainFile->Delete(PR_FALSE)))
|
||||
return PR_FALSE;
|
||||
|
||||
// XXX Would prefer MoveTo with a 'null' newdir, the but nsILocalFile
|
||||
// implementation are broken.
|
||||
// http://bugzilla.mozilla.org/show_bug.cgi?id=33098
|
||||
|
||||
nsCOMPtr<nsILocalFile> dir;
|
||||
if(!aMgr->GetComponentsDir(getter_AddRefs(dir)) || !dir)
|
||||
return PR_FALSE;
|
||||
|
||||
if(NS_FAILED(tempFile->CopyTo(dir, g_MainManifestFilename)))
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
|
||||
static char*
|
||||
ReadManifestIntoMemory(xptiInterfaceInfoManager* aMgr,
|
||||
PRUint32* pLength)
|
||||
{
|
||||
FILE* file = nsnull;
|
||||
PRUint32 flen;
|
||||
PRInt64 fileSize;
|
||||
char* whole = nsnull;
|
||||
|
||||
nsCOMPtr<nsILocalFile> aFile;
|
||||
if(!aMgr->GetComponentsDir(getter_AddRefs(aFile)) || !aFile)
|
||||
return nsnull;
|
||||
|
||||
if(NS_FAILED(aFile->Append(g_MainManifestFilename)))
|
||||
return nsnull;
|
||||
|
||||
if(NS_FAILED(aFile->GetFileSize(&fileSize)) || !(flen = nsInt64(fileSize)))
|
||||
return nsnull;
|
||||
|
||||
whole = new char[flen];
|
||||
if (!whole)
|
||||
return nsnull;
|
||||
|
||||
// all exits from on here should be via 'goto out'
|
||||
|
||||
if(NS_FAILED(aFile->OpenANSIFileDesc("rb", &file)) || !file)
|
||||
goto out;
|
||||
|
||||
if(flen > fread(whole, 1, flen, file))
|
||||
goto out;
|
||||
|
||||
out:
|
||||
if(file)
|
||||
fclose(file);
|
||||
*pLength = flen;
|
||||
return whole;
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
class ManifestLineReader
|
||||
{
|
||||
public:
|
||||
ManifestLineReader() : mBase(nsnull) {}
|
||||
~ManifestLineReader() {}
|
||||
|
||||
void Init(char* base, PRUint32 flen)
|
||||
{mBase = mCur = mNext = base;
|
||||
mLength = 0;
|
||||
mLimit = base + flen;}
|
||||
|
||||
PRBool NextLine();
|
||||
char* LinePtr() {return mCur;}
|
||||
PRUint32 LineLength() {return mLength;}
|
||||
|
||||
private:
|
||||
char* mCur;
|
||||
PRUint32 mLength;
|
||||
char* mNext;
|
||||
char* mBase;
|
||||
char* mLimit;
|
||||
};
|
||||
|
||||
PRBool
|
||||
ManifestLineReader::NextLine()
|
||||
{
|
||||
if(mNext == mLimit)
|
||||
return PR_FALSE;
|
||||
|
||||
mCur = mNext;
|
||||
mLength = 0;
|
||||
|
||||
while(mNext < mLimit)
|
||||
{
|
||||
char c = *(mNext);
|
||||
if(c == '\n' || c == '\r')
|
||||
{
|
||||
do
|
||||
{
|
||||
*(mNext++) = '\0';
|
||||
char c = *(mNext);
|
||||
if(c != '\n' && c != '\r')
|
||||
return PR_TRUE;
|
||||
} while(mNext < mLimit);
|
||||
return PR_TRUE;
|
||||
}
|
||||
++mNext;
|
||||
++mLength;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
/***************************************************/
|
||||
|
||||
static
|
||||
PRBool ReadSectionHeader(ManifestLineReader& reader,
|
||||
const char *token, int minCount,
|
||||
char* name, int* count)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
if(!reader.NextLine())
|
||||
break;
|
||||
if(*reader.LinePtr() == '[')
|
||||
{
|
||||
if(reader.LineLength() > g_MAX_LINE_LEN)
|
||||
break;
|
||||
if(2 == PR_sscanf(reader.LinePtr(), "[%[^','],%d]",
|
||||
name, count) &&
|
||||
0 == PL_strcmp(name, token) &&
|
||||
*count >= minCount)
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
PRBool xptiManifest::Read(xptiInterfaceInfoManager* aMgr,
|
||||
xptiWorkingSet& aWorkingSet)
|
||||
{
|
||||
char* whole = nsnull;
|
||||
char* name = nsnull;
|
||||
char* iidStr = nsnull;
|
||||
PRBool succeeded = PR_FALSE;
|
||||
PRUint32 flen;
|
||||
ManifestLineReader reader;
|
||||
int headerCount = 0;
|
||||
int fileCount = 0;
|
||||
int zipItemCount = -1;
|
||||
int interfaceCount = 0;
|
||||
int i;
|
||||
int index;
|
||||
int major;
|
||||
int minor;
|
||||
PRInt64 size;
|
||||
PRInt64 date;
|
||||
|
||||
whole = ReadManifestIntoMemory(aMgr, &flen);
|
||||
if(!whole)
|
||||
return PR_FALSE;
|
||||
|
||||
reader.Init(whole, flen);
|
||||
|
||||
// all exits from on here should be via 'goto out'
|
||||
|
||||
// We are going to scanf into these buffers, let's make them big.
|
||||
name = new char[g_MAX_LINE_LEN];
|
||||
if(!name)
|
||||
goto out;
|
||||
|
||||
iidStr = new char[g_MAX_LINE_LEN];
|
||||
if(!iidStr)
|
||||
goto out;
|
||||
|
||||
// Look for "Header" section
|
||||
|
||||
// This version accepts only version 1,0. We also freak if the header
|
||||
// has more than one entry. The rationale is that we want to force an
|
||||
// autoreg if the xpti.dat file was written by *any* other version of
|
||||
// the software. Future versions may wish to support updating older
|
||||
// manifests in some interesting way.
|
||||
|
||||
if(!ReadSectionHeader(reader, g_TOKEN_Header, 1, name, &headerCount))
|
||||
goto out;
|
||||
|
||||
// get the version
|
||||
|
||||
if(headerCount != 1)
|
||||
goto out;
|
||||
|
||||
if(!reader.NextLine())
|
||||
goto out;
|
||||
|
||||
if(reader.LineLength() > g_MAX_LINE_LEN)
|
||||
goto out;
|
||||
|
||||
if(4 != PR_sscanf(reader.LinePtr(), "%d,%[^','],%d,%d",
|
||||
&index, name, &major, &minor) ||
|
||||
0 != index ||
|
||||
0 != PL_strcmp(name, g_TOKEN_Version) ||
|
||||
major != g_VERSION_MAJOR ||
|
||||
minor != g_VERSION_MINOR)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Look for "Files" section
|
||||
|
||||
if(!ReadSectionHeader(reader, g_TOKEN_Files, 1, name, &fileCount))
|
||||
goto out;
|
||||
|
||||
|
||||
// Alloc room in the WorkingSet for the filearray.
|
||||
|
||||
if(!aWorkingSet.NewFileArray(fileCount))
|
||||
goto out;
|
||||
|
||||
// Read the file records
|
||||
|
||||
for(i = 0; i < fileCount; ++i)
|
||||
{
|
||||
if(!reader.NextLine())
|
||||
goto out;
|
||||
|
||||
if(reader.LineLength() > g_MAX_LINE_LEN)
|
||||
goto out;
|
||||
|
||||
if(4 != PR_sscanf(reader.LinePtr(), "%d,%[^','],%lld,%lld",
|
||||
&index, name, &size, &date) ||
|
||||
i != index ||
|
||||
!*name)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Append a new file record to the array.
|
||||
|
||||
aWorkingSet.AppendFile(
|
||||
xptiFile(nsInt64(size), nsInt64(date), name, &aWorkingSet));
|
||||
}
|
||||
|
||||
// Look for "ZipItems" section
|
||||
|
||||
if(!ReadSectionHeader(reader, g_TOKEN_ArchiveItems, 0, name, &zipItemCount))
|
||||
goto out;
|
||||
|
||||
// Alloc room in the WorkingSet for the zipItemarray.
|
||||
|
||||
if(zipItemCount)
|
||||
if(!aWorkingSet.NewZipItemArray(zipItemCount))
|
||||
goto out;
|
||||
|
||||
// Read the zipItem records
|
||||
|
||||
for(i = 0; i < zipItemCount; ++i)
|
||||
{
|
||||
if(!reader.NextLine())
|
||||
goto out;
|
||||
|
||||
if(reader.LineLength() > g_MAX_LINE_LEN)
|
||||
goto out;
|
||||
|
||||
if(2 != PR_sscanf(reader.LinePtr(), "%d,%[^',']",
|
||||
&index, name) ||
|
||||
i != index ||
|
||||
!*name)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Append a new zipItem record to the array.
|
||||
|
||||
aWorkingSet.AppendZipItem(xptiZipItem(name, &aWorkingSet));
|
||||
}
|
||||
|
||||
// Look for "Interfaces" section
|
||||
|
||||
if(!ReadSectionHeader(reader, g_TOKEN_Interfaces, 1, name, &interfaceCount))
|
||||
goto out;
|
||||
|
||||
// Read the interface records
|
||||
|
||||
for(i = 0; i < interfaceCount; ++i)
|
||||
{
|
||||
int fileIndex;
|
||||
int zipItemIndex;
|
||||
nsIID iid;
|
||||
xptiInterfaceInfo* info;
|
||||
xptiTypelib typelibRecord;
|
||||
|
||||
if(!reader.NextLine())
|
||||
goto out;
|
||||
|
||||
if(reader.LineLength() > g_MAX_LINE_LEN)
|
||||
goto out;
|
||||
|
||||
if(5 != PR_sscanf(reader.LinePtr(), "%d,%[^','],%[^','],%d,%d",
|
||||
&index, name, iidStr, &fileIndex, &zipItemIndex) ||
|
||||
i != index ||
|
||||
!*name ||
|
||||
!*iidStr ||
|
||||
!iid.Parse(iidStr) ||
|
||||
fileIndex < 0 ||
|
||||
fileIndex >= fileCount ||
|
||||
(zipItemIndex != -1 && zipItemIndex >= zipItemCount))
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Build an InterfaceInfo and hook it in.
|
||||
|
||||
if(zipItemIndex == -1)
|
||||
typelibRecord.Init(fileIndex);
|
||||
else
|
||||
typelibRecord.Init(fileIndex, zipItemIndex);
|
||||
info = new xptiInterfaceInfo(name, iid, typelibRecord, aWorkingSet);
|
||||
if(!info)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
NS_ADDREF(info);
|
||||
if(!info->IsValid())
|
||||
{
|
||||
// XXX bad!
|
||||
NS_RELEASE(info);
|
||||
goto out;
|
||||
}
|
||||
|
||||
// The name table now owns the reference we AddRef'd above
|
||||
PL_HashTableAdd(aWorkingSet.mNameTable, info->GetTheName(), info);
|
||||
PL_HashTableAdd(aWorkingSet.mIIDTable, info->GetTheIID(), info);
|
||||
}
|
||||
|
||||
// success!
|
||||
|
||||
succeeded = PR_TRUE;
|
||||
|
||||
out:
|
||||
if(whole)
|
||||
delete [] whole;
|
||||
if(name)
|
||||
delete [] name;
|
||||
if(iidStr)
|
||||
delete [] iidStr;
|
||||
|
||||
if(!succeeded)
|
||||
{
|
||||
// Cleanup the WorkingSet on failure.
|
||||
aWorkingSet.InvalidateInterfaceInfos();
|
||||
aWorkingSet.ClearHashTables();
|
||||
aWorkingSet.ClearFiles();
|
||||
}
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
95
mozilla/xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
Normal file
95
mozilla/xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* Implementation of xptiTypelibGuts. */
|
||||
|
||||
#include "xptiprivate.h"
|
||||
|
||||
xptiTypelibGuts::xptiTypelibGuts(XPTHeader* aHeader)
|
||||
: mHeader(aHeader),
|
||||
mInfoArray(nsnull)
|
||||
{
|
||||
NS_ASSERTION(mHeader, "bad param");
|
||||
|
||||
if(mHeader->num_interfaces)
|
||||
{
|
||||
mInfoArray = new xptiInterfaceInfo*[GetInfoCount()];
|
||||
if(mInfoArray)
|
||||
memset(mInfoArray, 0, sizeof(xptiInterfaceInfo*) * GetInfoCount());
|
||||
else
|
||||
mHeader = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
xptiTypelibGuts::~xptiTypelibGuts()
|
||||
{
|
||||
if(mHeader && mInfoArray)
|
||||
for(PRUint16 i = 0; i < GetInfoCount(); ++i)
|
||||
NS_IF_RELEASE(mInfoArray[i]);
|
||||
delete [] mInfoArray;
|
||||
}
|
||||
|
||||
xptiTypelibGuts*
|
||||
xptiTypelibGuts::Clone()
|
||||
{
|
||||
xptiTypelibGuts* clone = new xptiTypelibGuts(mHeader);
|
||||
if(clone && clone->IsValid())
|
||||
for(PRUint16 i = 0; i < GetInfoCount(); ++i)
|
||||
clone->SetInfoAt(i, GetInfoAtNoAddRef(i));
|
||||
return clone;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiTypelibGuts::GetInfoAt(PRUint16 i, xptiInterfaceInfo** ptr)
|
||||
{
|
||||
NS_ASSERTION(mHeader,"bad state!");
|
||||
NS_ASSERTION(mInfoArray,"bad state!");
|
||||
NS_ASSERTION(i < GetInfoCount(),"bad param!");
|
||||
NS_ASSERTION(ptr,"bad param!");
|
||||
|
||||
NS_IF_ADDREF(*ptr = mInfoArray[i]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
xptiInterfaceInfo*
|
||||
xptiTypelibGuts::GetInfoAtNoAddRef(PRUint16 i)
|
||||
{
|
||||
NS_ASSERTION(mHeader,"bad state!");
|
||||
NS_ASSERTION(mInfoArray,"bad state!");
|
||||
NS_ASSERTION(i < GetInfoCount(),"bad param!");
|
||||
|
||||
return mInfoArray[i];
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
xptiTypelibGuts::SetInfoAt(PRUint16 i, xptiInterfaceInfo* ptr)
|
||||
{
|
||||
NS_ASSERTION(mHeader,"bad state!");
|
||||
NS_ASSERTION(mInfoArray,"bad state!");
|
||||
NS_ASSERTION(i < GetInfoCount(),"bad param!");
|
||||
|
||||
NS_IF_ADDREF(ptr);
|
||||
NS_IF_RELEASE(mInfoArray[i]);
|
||||
mInfoArray[i] = ptr;
|
||||
return NS_OK;
|
||||
}
|
||||
244
mozilla/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp
Normal file
244
mozilla/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp
Normal file
@@ -0,0 +1,244 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* Implementation of xptiWorkingSet. */
|
||||
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#define XPTI_STRING_ARENA_BLOCK_SIZE (1024 * 1)
|
||||
#define XPTI_STRUCT_ARENA_BLOCK_SIZE (1024 * 1)
|
||||
#define XPTI_HASHTABLE_SIZE 128
|
||||
|
||||
static PR_CALLBACK PLHashNumber
|
||||
xpti_HashIID(const void *key)
|
||||
{
|
||||
return ((nsID*)key)->m0;
|
||||
}
|
||||
|
||||
static PR_CALLBACK PRIntn
|
||||
xpti_CompareIIDs(const void *v1, const void *v2)
|
||||
{
|
||||
return (PRIntn) ((const nsID*)v1)->Equals(*((const nsID*)v2));
|
||||
}
|
||||
|
||||
xptiWorkingSet::xptiWorkingSet()
|
||||
: mFileCount(0),
|
||||
mMaxFileCount(0),
|
||||
mFileArray(nsnull),
|
||||
mZipItemCount(0),
|
||||
mMaxZipItemCount(0),
|
||||
mZipItemArray(nsnull),
|
||||
mStringArena(XPT_NewArena(XPTI_STRING_ARENA_BLOCK_SIZE, sizeof(char),
|
||||
"xptiWorkingSet strings")),
|
||||
mStructArena(XPT_NewArena(XPTI_STRUCT_ARENA_BLOCK_SIZE, sizeof(double),
|
||||
"xptiWorkingSet structs")),
|
||||
mNameTable(PL_NewHashTable(XPTI_HASHTABLE_SIZE, PL_HashString,
|
||||
PL_CompareStrings, PL_CompareValues,
|
||||
nsnull, nsnull)),
|
||||
mIIDTable(PL_NewHashTable(XPTI_HASHTABLE_SIZE, xpti_HashIID,
|
||||
xpti_CompareIIDs, PL_CompareValues,
|
||||
nsnull, nsnull)),
|
||||
mMergeOffsetMap(nsnull)
|
||||
{
|
||||
// do nothing else...
|
||||
}
|
||||
|
||||
PRBool
|
||||
xptiWorkingSet::IsValid() const
|
||||
{
|
||||
return (mFileCount == 0 || mFileArray) &&
|
||||
(mZipItemCount == 0 || mZipItemArray) &&
|
||||
mStringArena &&
|
||||
mStructArena &&
|
||||
mNameTable &&
|
||||
mIIDTable;
|
||||
}
|
||||
|
||||
static PR_CALLBACK PRIntn
|
||||
xpti_Remover(PLHashEntry *he, PRIntn i, void *arg)
|
||||
{
|
||||
return HT_ENUMERATE_REMOVE;
|
||||
}
|
||||
|
||||
static PR_CALLBACK PRIntn
|
||||
xpti_ReleaseAndRemover(PLHashEntry *he, PRIntn i, void *arg)
|
||||
{
|
||||
nsIInterfaceInfo* ii = (nsIInterfaceInfo*) he->value;
|
||||
NS_RELEASE(ii);
|
||||
return HT_ENUMERATE_REMOVE;
|
||||
}
|
||||
|
||||
|
||||
static PR_CALLBACK PRIntn
|
||||
xpti_Invalidator(PLHashEntry *he, PRIntn i, void *arg)
|
||||
{
|
||||
((xptiInterfaceInfo*)he->value)->Invalidate();
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
xptiWorkingSet::InvalidateInterfaceInfos()
|
||||
{
|
||||
if(mNameTable)
|
||||
PL_HashTableEnumerateEntries(mNameTable, xpti_Invalidator, nsnull);
|
||||
}
|
||||
|
||||
void
|
||||
xptiWorkingSet::ClearHashTables()
|
||||
{
|
||||
if(mNameTable)
|
||||
PL_HashTableEnumerateEntries(mNameTable, xpti_Remover, nsnull);
|
||||
|
||||
if(mIIDTable)
|
||||
PL_HashTableEnumerateEntries(mIIDTable, xpti_ReleaseAndRemover, nsnull);
|
||||
}
|
||||
|
||||
void
|
||||
xptiWorkingSet::ClearFiles()
|
||||
{
|
||||
if(mFileArray)
|
||||
delete [] mFileArray;
|
||||
mFileArray = nsnull;
|
||||
mMaxFileCount = 0;
|
||||
mFileCount = 0;
|
||||
}
|
||||
|
||||
void
|
||||
xptiWorkingSet::ClearZipItems()
|
||||
{
|
||||
if(mZipItemArray)
|
||||
delete [] mZipItemArray;
|
||||
mZipItemArray = nsnull;
|
||||
mMaxZipItemCount = 0;
|
||||
mZipItemCount = 0;
|
||||
}
|
||||
|
||||
xptiWorkingSet::~xptiWorkingSet()
|
||||
{
|
||||
ClearFiles();
|
||||
ClearZipItems();
|
||||
ClearHashTables();
|
||||
|
||||
if(mNameTable)
|
||||
PL_HashTableDestroy(mNameTable);
|
||||
|
||||
if(mIIDTable)
|
||||
PL_HashTableDestroy(mIIDTable);
|
||||
|
||||
if(mFileArray)
|
||||
delete [] mFileArray;
|
||||
|
||||
if(mZipItemArray)
|
||||
delete [] mZipItemArray;
|
||||
|
||||
// Destroy arenas last in case they are referenced in other members' dtors.
|
||||
|
||||
if(mStringArena)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
XPT_DumpStats(mStringArena);
|
||||
#endif
|
||||
XPT_DestroyArena(mStringArena);
|
||||
}
|
||||
|
||||
if(mStructArena)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
XPT_DumpStats(mStructArena);
|
||||
#endif
|
||||
XPT_DestroyArena(mStructArena);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
xptiWorkingSet::NewFileArray(PRUint32 count)
|
||||
{
|
||||
if(mFileArray)
|
||||
delete [] mFileArray;
|
||||
mFileCount = 0;
|
||||
mFileArray = new xptiFile[count];
|
||||
if(!mFileArray)
|
||||
{
|
||||
mMaxFileCount = 0;
|
||||
return PR_FALSE;
|
||||
}
|
||||
mMaxFileCount = count;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
xptiWorkingSet::ExtendFileArray(PRUint32 count)
|
||||
{
|
||||
if(mFileArray && count < mMaxFileCount)
|
||||
return PR_TRUE;
|
||||
|
||||
xptiFile* newArray = new xptiFile[count];
|
||||
if(!newArray)
|
||||
return PR_FALSE;
|
||||
|
||||
if(mFileArray)
|
||||
{
|
||||
for(PRUint32 i = 0; i < mFileCount; ++i)
|
||||
newArray[i] = mFileArray[i];
|
||||
delete [] mFileArray;
|
||||
}
|
||||
mFileArray = newArray;
|
||||
mMaxFileCount = count;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
xptiWorkingSet::NewZipItemArray(PRUint32 count)
|
||||
{
|
||||
if(mZipItemArray)
|
||||
delete [] mZipItemArray;
|
||||
mZipItemCount = 0;
|
||||
mZipItemArray = new xptiZipItem[count];
|
||||
if(!mZipItemArray)
|
||||
{
|
||||
mMaxZipItemCount = 0;
|
||||
return PR_FALSE;
|
||||
}
|
||||
mMaxZipItemCount = count;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
xptiWorkingSet::ExtendZipItemArray(PRUint32 count)
|
||||
{
|
||||
if(mZipItemArray && count < mMaxZipItemCount)
|
||||
return PR_TRUE;
|
||||
|
||||
xptiZipItem* newArray = new xptiZipItem[count];
|
||||
if(!newArray)
|
||||
return PR_FALSE;
|
||||
|
||||
if(mZipItemArray)
|
||||
{
|
||||
for(PRUint32 i = 0; i < mZipItemCount; ++i)
|
||||
newArray[i] = mZipItemArray[i];
|
||||
delete [] mZipItemArray;
|
||||
}
|
||||
mZipItemArray = newArray;
|
||||
mMaxZipItemCount = count;
|
||||
return PR_TRUE;
|
||||
}
|
||||
80
mozilla/xpcom/reflect/xptinfo/src/xptiZipItem.cpp
Normal file
80
mozilla/xpcom/reflect/xptinfo/src/xptiZipItem.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* Implementation of xptiZipItem. */
|
||||
|
||||
#include "xptiprivate.h"
|
||||
|
||||
|
||||
xptiZipItem::xptiZipItem()
|
||||
: mName(nsnull),
|
||||
mGuts(nsnull)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
xptiZipItem::xptiZipItem(const char* aName,
|
||||
xptiWorkingSet* aWorkingSet,
|
||||
XPTHeader* aHeader /*= nsnull */)
|
||||
|
||||
: mName(aName),
|
||||
mGuts(nsnull)
|
||||
{
|
||||
NS_ASSERTION(aWorkingSet,"bad param");
|
||||
mName = XPT_STRDUP(aWorkingSet->GetStringArena(), aName);
|
||||
|
||||
if(aHeader)
|
||||
SetHeader(aHeader);
|
||||
}
|
||||
|
||||
xptiZipItem::xptiZipItem(const xptiZipItem& r, xptiWorkingSet* aWorkingSet,
|
||||
PRBool cloneGuts)
|
||||
: mName(nsnull),
|
||||
mGuts(nsnull)
|
||||
{
|
||||
NS_ASSERTION(aWorkingSet,"bad param");
|
||||
mName = XPT_STRDUP(aWorkingSet->GetStringArena(), r.mName);
|
||||
|
||||
if(cloneGuts && r.mGuts)
|
||||
mGuts = r.mGuts->Clone();
|
||||
}
|
||||
|
||||
xptiZipItem::~xptiZipItem()
|
||||
{
|
||||
if(mGuts)
|
||||
delete mGuts;
|
||||
}
|
||||
|
||||
PRBool
|
||||
xptiZipItem::SetHeader(XPTHeader* aHeader)
|
||||
{
|
||||
NS_ASSERTION(!mGuts,"bad state");
|
||||
NS_ASSERTION(aHeader,"bad param");
|
||||
|
||||
mGuts = new xptiTypelibGuts(aHeader);
|
||||
if(mGuts && !mGuts->IsValid())
|
||||
{
|
||||
delete mGuts;
|
||||
mGuts = nsnull;
|
||||
}
|
||||
return mGuts != nsnull;
|
||||
}
|
||||
536
mozilla/xpcom/reflect/xptinfo/src/xptiprivate.h
Normal file
536
mozilla/xpcom/reflect/xptinfo/src/xptiprivate.h
Normal file
@@ -0,0 +1,536 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* Library-private header for Interface Info system. */
|
||||
|
||||
#ifndef xptiprivate_h___
|
||||
#define xptiprivate_h___
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
// this after nsISupports, to pick up IID
|
||||
// so that xpt stuff doesn't try to define it itself...
|
||||
#include "xpt_struct.h"
|
||||
#include "xpt_xdr.h"
|
||||
|
||||
#include "nsIInterfaceInfo.h"
|
||||
#include "nsIInterfaceInfoManager.h"
|
||||
#include "xptinfo.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsSpecialSystemDirectory.h"
|
||||
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsInt64.h"
|
||||
|
||||
#include "nsQuickSort.h"
|
||||
#include "nsIZipReader.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
#include "plstr.h"
|
||||
#include "prprf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class xptiFile;
|
||||
class xptiInterfaceInfo;
|
||||
class xptiInterfaceInfoManager;
|
||||
class xptiInterfaceGuts;
|
||||
class xptiTypelibGuts;
|
||||
class xptiWorkingSet;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class xptiTypelib
|
||||
{
|
||||
public:
|
||||
// No ctors or dtors so that we can be in a union in xptiInterfaceInfo.
|
||||
// Allow automatic shallow copies.
|
||||
|
||||
uint16 GetFileIndex() const {return mFileIndex;}
|
||||
uint16 GetZipItemIndex() const {return mZipItemIndex;}
|
||||
|
||||
enum {NOT_ZIP = 0xffff};
|
||||
|
||||
PRBool IsZip() const {return mZipItemIndex != NOT_ZIP;}
|
||||
|
||||
void Init(uint16 aFileIndex, uint16 aZipItemIndex = NOT_ZIP)
|
||||
{mFileIndex = aFileIndex; mZipItemIndex = aZipItemIndex;}
|
||||
|
||||
PRBool Equals(const xptiTypelib& r) const
|
||||
{return mFileIndex == r.mFileIndex &&
|
||||
mZipItemIndex == r.mZipItemIndex;}
|
||||
|
||||
private:
|
||||
uint16 mFileIndex;
|
||||
uint16 mZipItemIndex;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class xptiTypelibGuts
|
||||
{
|
||||
public:
|
||||
xptiTypelibGuts(); // not implemented
|
||||
xptiTypelibGuts(XPTHeader* aHeader);
|
||||
~xptiTypelibGuts();
|
||||
|
||||
PRBool IsValid() const {return mHeader != nsnull;}
|
||||
XPTHeader* GetHeader() {return mHeader;}
|
||||
PRUint16 GetInfoCount() const {return mHeader->num_interfaces;}
|
||||
nsresult SetInfoAt(PRUint16 i, xptiInterfaceInfo* ptr);
|
||||
nsresult GetInfoAt(PRUint16 i, xptiInterfaceInfo** ptr);
|
||||
xptiInterfaceInfo* GetInfoAtNoAddRef(PRUint16 i);
|
||||
xptiTypelibGuts* Clone();
|
||||
|
||||
private:
|
||||
XPTHeader* mHeader; // hold pointer into arena
|
||||
xptiInterfaceInfo** mInfoArray;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class xptiFile
|
||||
{
|
||||
public:
|
||||
const nsInt64& GetSize() const {return mSize;}
|
||||
const nsInt64& GetDate() const {return mDate;}
|
||||
const char* GetName() const {return mName;}
|
||||
xptiTypelibGuts* GetGuts() {return mGuts;}
|
||||
|
||||
xptiFile();
|
||||
|
||||
xptiFile(const nsInt64& aSize,
|
||||
const nsInt64& aDate,
|
||||
const char* aName,
|
||||
xptiWorkingSet* aWorkingSet,
|
||||
XPTHeader* aHeader = nsnull);
|
||||
|
||||
xptiFile(const xptiFile& r, xptiWorkingSet* aWorkingSet,
|
||||
PRBool cloneGuts);
|
||||
|
||||
~xptiFile();
|
||||
|
||||
PRBool SetHeader(XPTHeader* aHeader);
|
||||
|
||||
PRBool Equals(const xptiFile& r) const
|
||||
{
|
||||
return mSize == r.mSize &&
|
||||
mDate == r.mDate &&
|
||||
0 == PL_strcmp(mName, r.mName);
|
||||
}
|
||||
|
||||
xptiFile(const xptiFile& r) {CopyFields(r);}
|
||||
xptiFile& operator= (const xptiFile& r)
|
||||
{
|
||||
if(this != &r)
|
||||
CopyFields(r);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
void CopyFields(const xptiFile& r)
|
||||
{
|
||||
mSize = r.mSize;
|
||||
mDate = r.mDate;
|
||||
mName = r.mName;
|
||||
if(mGuts)
|
||||
delete mGuts;
|
||||
if(r.mGuts)
|
||||
mGuts = r.mGuts->Clone();
|
||||
else
|
||||
mGuts = nsnull;
|
||||
}
|
||||
|
||||
private:
|
||||
nsInt64 mSize;
|
||||
nsInt64 mDate;
|
||||
const char* mName; // hold pointer into arena from initializer
|
||||
xptiTypelibGuts* mGuts; // new/delete
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class xptiZipItem
|
||||
{
|
||||
public:
|
||||
const char* GetName() const {return mName;}
|
||||
xptiTypelibGuts* GetGuts() {return mGuts;}
|
||||
|
||||
xptiZipItem();
|
||||
|
||||
xptiZipItem(const char* aName,
|
||||
xptiWorkingSet* aWorkingSet,
|
||||
XPTHeader* aHeader = nsnull);
|
||||
|
||||
xptiZipItem(const xptiZipItem& r, xptiWorkingSet* aWorkingSet,
|
||||
PRBool cloneGuts);
|
||||
|
||||
~xptiZipItem();
|
||||
|
||||
PRBool SetHeader(XPTHeader* aHeader);
|
||||
|
||||
PRBool Equals(const xptiZipItem& r) const
|
||||
{
|
||||
return 0 == PL_strcmp(mName, r.mName);
|
||||
}
|
||||
|
||||
xptiZipItem(const xptiZipItem& r) {CopyFields(r);}
|
||||
xptiZipItem& operator= (const xptiZipItem& r)
|
||||
{
|
||||
if(this != &r)
|
||||
CopyFields(r);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
void CopyFields(const xptiZipItem& r)
|
||||
{
|
||||
mName = r.mName;
|
||||
if(mGuts)
|
||||
delete mGuts;
|
||||
if(r.mGuts)
|
||||
mGuts = r.mGuts->Clone();
|
||||
else
|
||||
mGuts = nsnull;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* mName; // hold pointer into arena from initializer
|
||||
xptiTypelibGuts* mGuts; // new/delete
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class xptiWorkingSet
|
||||
{
|
||||
public:
|
||||
xptiWorkingSet();
|
||||
~xptiWorkingSet();
|
||||
|
||||
PRBool IsValid() const;
|
||||
|
||||
void InvalidateInterfaceInfos();
|
||||
void ClearHashTables();
|
||||
void ClearFiles();
|
||||
void ClearZipItems();
|
||||
|
||||
// utility methods...
|
||||
|
||||
xptiTypelibGuts* GetTypelibGuts(const xptiTypelib& typelib)
|
||||
{
|
||||
return typelib.IsZip() ?
|
||||
GetZipItemAt(typelib.GetZipItemIndex()).GetGuts() :
|
||||
GetFileAt(typelib.GetFileIndex()).GetGuts();
|
||||
}
|
||||
|
||||
// FileArray stuff...
|
||||
|
||||
PRUint32 GetFileCount() const {return mFileCount;}
|
||||
PRUint32 GetFileFreeSpace()
|
||||
{return mFileArray ? mMaxFileCount - mFileCount : 0;}
|
||||
|
||||
xptiFile& GetFileAt(PRUint32 i) const
|
||||
{
|
||||
NS_ASSERTION(mFileArray, "bad state!");
|
||||
NS_ASSERTION(i < mFileCount, "bad param!");
|
||||
return mFileArray[i];
|
||||
}
|
||||
|
||||
void SetFileAt(PRUint32 i, const xptiFile& r)
|
||||
{
|
||||
NS_ASSERTION(mFileArray, "bad state!");
|
||||
NS_ASSERTION(i < mFileCount, "bad param!");
|
||||
mFileArray[i] = r;
|
||||
}
|
||||
|
||||
void AppendFile(const xptiFile& r)
|
||||
{
|
||||
NS_ASSERTION(mFileArray, "bad state!");
|
||||
NS_ASSERTION(mFileCount < mMaxFileCount, "bad param!");
|
||||
mFileArray[mFileCount++] = r;
|
||||
}
|
||||
|
||||
PRBool NewFileArray(PRUint32 count);
|
||||
PRBool ExtendFileArray(PRUint32 count);
|
||||
|
||||
// ZipItemArray stuff...
|
||||
|
||||
PRUint32 GetZipItemCount() const {return mZipItemCount;}
|
||||
PRUint32 GetZipItemFreeSpace()
|
||||
{return mZipItemArray ? mMaxZipItemCount - mZipItemCount : 0;}
|
||||
|
||||
xptiZipItem& GetZipItemAt(PRUint32 i) const
|
||||
{
|
||||
NS_ASSERTION(mZipItemArray, "bad state!");
|
||||
NS_ASSERTION(i < mZipItemCount, "bad param!");
|
||||
return mZipItemArray[i];
|
||||
}
|
||||
|
||||
void SetZipItemAt(PRUint32 i, const xptiZipItem& r)
|
||||
{
|
||||
NS_ASSERTION(mZipItemArray, "bad state!");
|
||||
NS_ASSERTION(i < mZipItemCount, "bad param!");
|
||||
mZipItemArray[i] = r;
|
||||
}
|
||||
|
||||
void AppendZipItem(const xptiZipItem& r)
|
||||
{
|
||||
NS_ASSERTION(mZipItemArray, "bad state!");
|
||||
NS_ASSERTION(mZipItemCount < mMaxZipItemCount, "bad param!");
|
||||
mZipItemArray[mZipItemCount++] = r;
|
||||
}
|
||||
|
||||
PRBool NewZipItemArray(PRUint32 count);
|
||||
PRBool ExtendZipItemArray(PRUint32 count);
|
||||
|
||||
// Arena stuff...
|
||||
|
||||
XPTArena* GetStringArena() {return mStringArena;}
|
||||
XPTArena* GetStructArena() {return mStructArena;}
|
||||
|
||||
|
||||
private:
|
||||
PRUint32 mFileCount;
|
||||
PRUint32 mMaxFileCount;
|
||||
xptiFile* mFileArray; // using new[] and delete[]
|
||||
|
||||
PRUint32 mZipItemCount;
|
||||
PRUint32 mMaxZipItemCount;
|
||||
xptiZipItem* mZipItemArray; // using new[] and delete[]
|
||||
|
||||
XPTArena* mStringArena;
|
||||
XPTArena* mStructArena;
|
||||
|
||||
public:
|
||||
// XXX make these private with accessors
|
||||
PLHashTable* mNameTable;
|
||||
PLHashTable* mIIDTable;
|
||||
PRUint32* mMergeOffsetMap; // always in an arena
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// XXX could move this class to xptiInterfaceInfo.cpp.
|
||||
|
||||
class xptiInterfaceGuts
|
||||
{
|
||||
public:
|
||||
|
||||
uint16 mMethodBaseIndex;
|
||||
uint16 mConstantBaseIndex;
|
||||
nsIInterfaceInfo* mParent;
|
||||
XPTInterfaceDescriptor* mDescriptor;
|
||||
xptiTypelib mTypelib;
|
||||
xptiWorkingSet* mWorkingSet;
|
||||
|
||||
xptiInterfaceGuts(XPTInterfaceDescriptor* aDescriptor,
|
||||
const xptiTypelib& aTypelib,
|
||||
xptiWorkingSet* aWorkingSet)
|
||||
: mMethodBaseIndex(0),
|
||||
mConstantBaseIndex(0),
|
||||
mParent(nsnull),
|
||||
mDescriptor(aDescriptor),
|
||||
mTypelib(aTypelib),
|
||||
mWorkingSet(aWorkingSet) {}
|
||||
|
||||
~xptiInterfaceGuts() {NS_IF_RELEASE(mParent);}
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class xptiInterfaceInfo : public nsIInterfaceInfo
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIINTERFACEINFO
|
||||
|
||||
public:
|
||||
xptiInterfaceInfo(); // not implemented
|
||||
|
||||
xptiInterfaceInfo(const char* name,
|
||||
const nsID& iid,
|
||||
const xptiTypelib& typelib,
|
||||
xptiWorkingSet& aWorkingSet);
|
||||
|
||||
virtual ~xptiInterfaceInfo();
|
||||
|
||||
enum {
|
||||
NOT_RESOLVED = 0,
|
||||
PARTIALLY_RESOLVED = 1,
|
||||
FULLY_RESOLVED = 2,
|
||||
RESOLVE_FAILED = 3
|
||||
};
|
||||
|
||||
PRBool IsValid() const
|
||||
{return mName != nsnull;}
|
||||
|
||||
char GetResolveState() const
|
||||
{return IsValid() ? mName[-1] : (char) RESOLVE_FAILED;}
|
||||
|
||||
PRBool IsFullyResolved() const
|
||||
{return GetResolveState() == (char) FULLY_RESOLVED;}
|
||||
|
||||
PRBool HasInterfaceRecord() const
|
||||
{int s = (int) GetResolveState();
|
||||
return
|
||||
(s == PARTIALLY_RESOLVED || s == FULLY_RESOLVED) && mInterface;
|
||||
}
|
||||
|
||||
const xptiTypelib& GetTypelibRecord() const
|
||||
{return HasInterfaceRecord() ? mInterface->mTypelib : mTypelib;}
|
||||
|
||||
const nsID* GetTheIID() const {return &mIID;}
|
||||
const char* GetTheName() const {return mName;}
|
||||
|
||||
PRBool PartiallyResolve(XPTInterfaceDescriptor* aDescriptor,
|
||||
xptiWorkingSet* aWorkingSet);
|
||||
|
||||
void Invalidate()
|
||||
{
|
||||
if(IsValid())
|
||||
{
|
||||
xptiTypelib typelib = GetTypelibRecord();
|
||||
mTypelib = typelib;
|
||||
mName = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void SetResolvedState(int state)
|
||||
{NS_ASSERTION(IsValid(),"bad state"); mName[-1] = (char) state;}
|
||||
|
||||
PRBool Resolve(xptiWorkingSet* aWorkingSet = nsnull);
|
||||
|
||||
PRBool EnsureResolved(xptiWorkingSet* aWorkingSet = nsnull)
|
||||
{return IsFullyResolved() ? PR_TRUE : Resolve(aWorkingSet);}
|
||||
|
||||
NS_IMETHOD GetTypeInArray(const nsXPTParamInfo* param,
|
||||
uint16 dimension,
|
||||
const XPTTypeDescriptor** type);
|
||||
private:
|
||||
nsID mIID;
|
||||
char* mName; // This is in arena (not free'd) and mName[-1] is a flag.
|
||||
|
||||
union {
|
||||
xptiTypelib mTypelib; // Valid only until resolved.
|
||||
xptiInterfaceGuts* mInterface; // Valid only after resolved.
|
||||
};
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class xptiManifest
|
||||
{
|
||||
public:
|
||||
static PRBool Read(xptiInterfaceInfoManager* aMgr,
|
||||
xptiWorkingSet& aWorkingSet);
|
||||
|
||||
static PRBool Write(xptiInterfaceInfoManager* aMgr,
|
||||
xptiWorkingSet& aWorkingSet);
|
||||
|
||||
xptiManifest(); // no implementation
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class xptiInterfaceInfoManager : public nsIInterfaceInfoManager
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIINTERFACEINFOMANAGER
|
||||
|
||||
public:
|
||||
virtual ~xptiInterfaceInfoManager();
|
||||
static xptiInterfaceInfoManager* GetInterfaceInfoManager();
|
||||
static void FreeInterfaceInfoManager();
|
||||
|
||||
xptiWorkingSet* GetWorkingSet() {return &mWorkingSet;}
|
||||
|
||||
PRBool LoadFile(const xptiTypelib& aTypelibRecord,
|
||||
xptiWorkingSet* aWorkingSet = nsnull);
|
||||
|
||||
PRBool GetComponentsDir(nsILocalFile** aDir);
|
||||
|
||||
private:
|
||||
xptiInterfaceInfoManager();
|
||||
|
||||
enum AutoRegMode {
|
||||
NO_FILES_CHANGED = 0,
|
||||
MAYBE_ONLY_ADDITIONS,
|
||||
FULL_VALIDATION_REQUIRED
|
||||
};
|
||||
|
||||
PRBool BuildFileList(nsISupportsArray** aFileList);
|
||||
|
||||
PRBool PopulateWorkingSetFromManifest(xptiWorkingSet& aWorkingSet);
|
||||
PRBool WriteManifest(xptiWorkingSet& aWorkingSet);
|
||||
|
||||
XPTHeader* ReadXPTFile(nsILocalFile* aFile, xptiWorkingSet& aWorkingSet);
|
||||
|
||||
XPTHeader* ReadXPTFileFromZip(nsILocalFile* file,
|
||||
const char* itemName,
|
||||
xptiWorkingSet& aWorkingSet);
|
||||
|
||||
XPTHeader* ReadXPTFileFromOpenZip(nsIZipReader * zip,
|
||||
nsIZipEntry* entry,
|
||||
const char* itemName,
|
||||
xptiWorkingSet& aWorkingSet);
|
||||
|
||||
AutoRegMode DetermineAutoRegStrategy(nsISupportsArray* aFileList,
|
||||
xptiWorkingSet& aWorkingSet);
|
||||
|
||||
PRBool AttemptAddOnlyFromFileList(nsISupportsArray* aFileList,
|
||||
xptiWorkingSet& aWorkingSet,
|
||||
AutoRegMode* pmode);
|
||||
|
||||
PRBool DoFullValidationMergeFromFileList(nsISupportsArray* aFileList,
|
||||
xptiWorkingSet& aWorkingSet);
|
||||
|
||||
PRBool VerifyAndAddInterfaceIfNew(xptiWorkingSet& aWorkingSet,
|
||||
XPTInterfaceDirectoryEntry* iface,
|
||||
const xptiTypelib& typelibRecord,
|
||||
xptiInterfaceInfo** infoAdded);
|
||||
|
||||
PRBool MergeWorkingSets(xptiWorkingSet& aDestWorkingSet,
|
||||
xptiWorkingSet& aSrcWorkingSet);
|
||||
|
||||
PRBool DEBUG_DumpFileList(nsISupportsArray* aFileList);
|
||||
PRBool DEBUG_DumpFileListInWorkingSet(xptiWorkingSet& aWorkingSet);
|
||||
|
||||
private:
|
||||
xptiWorkingSet mWorkingSet;
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* xptiprivate_h___ */
|
||||
113
mozilla/xpcom/typelib/xpt/public/xpt_arena.h
Normal file
113
mozilla/xpcom/typelib/xpt/public/xpt_arena.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/*
|
||||
* Simple arena allocator for xpt (which avoids using NSPR).
|
||||
*/
|
||||
|
||||
#ifndef __xpt_arena_h__
|
||||
#define __xpt_arena_h__
|
||||
|
||||
#include "prtypes.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/*
|
||||
* The linkage of XPT API functions differs depending on whether the file is
|
||||
* used within the XPT library or not. Any source file within the XPT
|
||||
* library should define EXPORT_XPT_API whereas any client of the library
|
||||
* should not.
|
||||
*/
|
||||
#ifdef EXPORT_XPT_API
|
||||
#define XPT_PUBLIC_API(t) PR_IMPLEMENT(t)
|
||||
#define XPT_PUBLIC_DATA(t) PR_IMPLEMENT_DATA(t)
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
# define XPT_PUBLIC_API(t) _declspec(dllimport) t
|
||||
# define XPT_PUBLIC_DATA(t) _declspec(dllimport) t
|
||||
#else
|
||||
# define XPT_PUBLIC_API(t) PR_IMPLEMENT(t)
|
||||
# define XPT_PUBLIC_DATA(t) t
|
||||
#endif
|
||||
#endif
|
||||
#define XPT_FRIEND_API(t) XPT_PUBLIC_API(t)
|
||||
#define XPT_FRIEND_DATA(t) XPT_PUBLIC_DATA(t)
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
/*
|
||||
* Simple Arena support. Use with caution!
|
||||
*/
|
||||
|
||||
typedef struct XPTArena XPTArena;
|
||||
|
||||
XPT_PUBLIC_API(XPTArena *)
|
||||
XPT_NewArena(PRUint32 block_size, size_t alignment, const char* name);
|
||||
|
||||
XPT_PUBLIC_API(void)
|
||||
XPT_DestroyArena(XPTArena *arena);
|
||||
|
||||
XPT_PUBLIC_API(void)
|
||||
XPT_DumpStats(XPTArena *arena);
|
||||
|
||||
XPT_PUBLIC_API(void *)
|
||||
XPT_ArenaMalloc(XPTArena *arena, size_t size);
|
||||
|
||||
XPT_PUBLIC_API(char *)
|
||||
XPT_ArenaStrDup(XPTArena *arena, const char * s);
|
||||
|
||||
XPT_PUBLIC_API(void)
|
||||
XPT_NotifyDoneLoading(XPTArena *arena);
|
||||
|
||||
XPT_PUBLIC_API(void)
|
||||
XPT_ArenaFree(XPTArena *arena, void* block);
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
|
||||
#define XPT_MALLOC(_arena, _bytes) \
|
||||
XPT_ArenaMalloc((_arena), (_bytes))
|
||||
|
||||
#ifdef DEBUG
|
||||
#define XPT_FREE(_arena, _ptr) \
|
||||
XPT_ArenaFree((_arena), (_ptr))
|
||||
#else
|
||||
#define XPT_FREE(_arena, _ptr) \
|
||||
((void)0)
|
||||
#endif
|
||||
|
||||
#define XPT_STRDUP(_arena, _s) \
|
||||
XPT_ArenaStrDup((_arena), (_s))
|
||||
|
||||
#define XPT_CALLOC(_arena, _size) XPT_MALLOC((_arena), (_size))
|
||||
#define XPT_NEW(_arena, _struct) ((_struct *) XPT_MALLOC((_arena), sizeof(_struct)))
|
||||
#define XPT_NEWZAP(_arena, _struct) XPT_NEW((_arena), _struct)
|
||||
#define XPT_DELETE(_arena, _ptr) do{XPT_FREE((_arena), (_ptr)); ((_ptr)) = NULL;}while(0)
|
||||
#define XPT_FREEIF(_arena, _ptr) do{if ((_ptr)) XPT_FREE((_arena), (_ptr));}while(0)
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
|
||||
#define XPT_ASSERT(_expr) assert(_expr)
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* __xpt_arena_h__ */
|
||||
315
mozilla/xpcom/typelib/xpt/src/xpt_arena.c
Normal file
315
mozilla/xpcom/typelib/xpt/src/xpt_arena.c
Normal file
@@ -0,0 +1,315 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* Quick arena hack for xpt. */
|
||||
|
||||
/* XXX This exists because we don't want to drag in NSPR. It *seemed*
|
||||
* to make more sense to write a quick and dirty arena than to clone
|
||||
* plarena (like js/src did). This is not optimal, but it works.
|
||||
* Half of the code here is instrumentation.
|
||||
*/
|
||||
|
||||
#include "xpt_arena.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*************************/
|
||||
/* logging stats support */
|
||||
|
||||
#ifdef DEBUG_jband
|
||||
#define XPT_ARENA_LOGGING 1
|
||||
#endif
|
||||
|
||||
#ifdef XPT_ARENA_LOGGING
|
||||
|
||||
#define LOG_MALLOC(_a, _req, _used) \
|
||||
do{ \
|
||||
XPT_ASSERT((_a)); \
|
||||
++(_a)->LOG_MallocCallCount; \
|
||||
(_a)->LOG_MallocTotalBytesRequested += (_req); \
|
||||
(_a)->LOG_MallocTotalBytesUsed += (_used); \
|
||||
} while(0)
|
||||
|
||||
#define LOG_REAL_MALLOC(_a, _size) \
|
||||
do{ \
|
||||
XPT_ASSERT((_a)); \
|
||||
++(_a)->LOG_RealMallocCallCount; \
|
||||
(_a)->LOG_RealMallocTotalBytesRequested += (_size); \
|
||||
} while(0)
|
||||
|
||||
#define LOG_FREE(_a) \
|
||||
do{ \
|
||||
XPT_ASSERT((_a)); \
|
||||
++(_a)->LOG_FreeCallCount; \
|
||||
} while(0)
|
||||
|
||||
#define LOG_DONE_LOADING(_a) \
|
||||
do{ \
|
||||
XPT_ASSERT((_a)); \
|
||||
(_a)->LOG_LoadingFreeCallCount = (_a)->LOG_FreeCallCount; \
|
||||
} while(0)
|
||||
|
||||
#define PRINT_STATS(_a) xpt_DebugPrintArenaStats((_a))
|
||||
static void xpt_DebugPrintArenaStats(XPTArena *arena);
|
||||
|
||||
#else /* !XPT_ARENA_LOGGING */
|
||||
|
||||
#define LOG_MALLOC(_a, _req, _used) ((void)0)
|
||||
#define LOG_REAL_MALLOC(_a, _size) ((void)0)
|
||||
#define LOG_FREE(_a) ((void)0)
|
||||
|
||||
#define LOG_DONE_LOADING(_a) ((void)0)
|
||||
#define PRINT_STATS(_a) ((void)0)
|
||||
|
||||
#endif /* XPT_ARENA_LOGGING */
|
||||
|
||||
/****************************************************/
|
||||
|
||||
/* Block header for each block in the arena */
|
||||
typedef struct BLK_HDR BLK_HDR;
|
||||
struct BLK_HDR
|
||||
{
|
||||
BLK_HDR *next;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
#define XPT_MIN_BLOCK_SIZE 32
|
||||
|
||||
/* XXX this is lame. Should clone the code to do this bitwise */
|
||||
#define ALIGN_RND(s,a) ((a)==1?(s):((((s)+(a)-1)/(a))*(a)))
|
||||
|
||||
struct XPTArena
|
||||
{
|
||||
BLK_HDR *first;
|
||||
PRUint8 *next;
|
||||
size_t space;
|
||||
size_t alignment;
|
||||
size_t block_size;
|
||||
char *name;
|
||||
|
||||
#ifdef XPT_ARENA_LOGGING
|
||||
PRUint32 LOG_MallocCallCount;
|
||||
PRUint32 LOG_MallocTotalBytesRequested;
|
||||
PRUint32 LOG_MallocTotalBytesUsed;
|
||||
PRUint32 LOG_FreeCallCount;
|
||||
PRUint32 LOG_LoadingFreeCallCount;
|
||||
PRUint32 LOG_RealMallocCallCount;
|
||||
PRUint32 LOG_RealMallocTotalBytesRequested;
|
||||
#endif /* XPT_ARENA_LOGGING */
|
||||
};
|
||||
|
||||
XPT_PUBLIC_API(XPTArena *)
|
||||
XPT_NewArena(PRUint32 block_size, size_t alignment, const char* name)
|
||||
{
|
||||
XPTArena *arena = calloc(1, sizeof(XPTArena));
|
||||
if (arena) {
|
||||
XPT_ASSERT(alignment);
|
||||
if (alignment > sizeof(double))
|
||||
alignment = sizeof(double);
|
||||
arena->alignment = alignment;
|
||||
|
||||
if (block_size < XPT_MIN_BLOCK_SIZE)
|
||||
block_size = XPT_MIN_BLOCK_SIZE;
|
||||
arena->block_size = ALIGN_RND(block_size, alignment);
|
||||
|
||||
/* must have room for at least one item! */
|
||||
XPT_ASSERT(arena->block_size >=
|
||||
ALIGN_RND(sizeof(BLK_HDR), alignment) +
|
||||
ALIGN_RND(1, alignment));
|
||||
|
||||
if (name) {
|
||||
arena->name = XPT_STRDUP(arena, name);
|
||||
#ifdef XPT_ARENA_LOGGING
|
||||
/* fudge the stats since we are using space in the arena */
|
||||
arena->LOG_MallocCallCount = 0;
|
||||
arena->LOG_MallocTotalBytesRequested = 0;
|
||||
arena->LOG_MallocTotalBytesUsed = 0;
|
||||
#endif /* XPT_ARENA_LOGGING */
|
||||
}
|
||||
}
|
||||
return arena;
|
||||
}
|
||||
|
||||
XPT_PUBLIC_API(void)
|
||||
XPT_DestroyArena(XPTArena *arena)
|
||||
{
|
||||
BLK_HDR* cur;
|
||||
BLK_HDR* next;
|
||||
|
||||
cur = arena->first;
|
||||
while (cur) {
|
||||
next = cur->next;
|
||||
free(cur);
|
||||
cur = next;
|
||||
}
|
||||
free(arena);
|
||||
}
|
||||
|
||||
XPT_PUBLIC_API(void)
|
||||
XPT_DumpStats(XPTArena *arena)
|
||||
{
|
||||
PRINT_STATS(arena);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Our alignment rule is that we always round up the size of each allocation
|
||||
* so that the 'arena->next' pointer one will point to properly aligned space.
|
||||
*/
|
||||
|
||||
XPT_PUBLIC_API(void *)
|
||||
XPT_ArenaMalloc(XPTArena *arena, size_t size)
|
||||
{
|
||||
PRUint8 *cur;
|
||||
size_t bytes;
|
||||
|
||||
if (!size)
|
||||
return NULL;
|
||||
|
||||
if (!arena) {
|
||||
XPT_ASSERT(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bytes = ALIGN_RND(size, arena->alignment);
|
||||
|
||||
LOG_MALLOC(arena, size, bytes);
|
||||
|
||||
if (bytes > arena->space) {
|
||||
BLK_HDR* new_block;
|
||||
size_t block_header_size = ALIGN_RND(sizeof(BLK_HDR), arena->alignment);
|
||||
size_t new_space = arena->block_size;
|
||||
|
||||
if (bytes > new_space - block_header_size)
|
||||
new_space += bytes;
|
||||
|
||||
new_block = (BLK_HDR*) calloc(new_space/arena->alignment,
|
||||
arena->alignment);
|
||||
if (!new_block) {
|
||||
arena->next = NULL;
|
||||
arena->space = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LOG_REAL_MALLOC(arena, new_space);
|
||||
|
||||
/* link block into the list of blocks for use when we destroy */
|
||||
new_block->next = arena->first;
|
||||
arena->first = new_block;
|
||||
|
||||
/* save other block header info */
|
||||
new_block->size = new_space;
|
||||
|
||||
/* set info for current block */
|
||||
arena->next = ((PRUint8*)new_block) + block_header_size;
|
||||
arena->space = new_space - block_header_size;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* mark block for corruption check */
|
||||
memset(arena->next, 0xcd, arena->space);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
/* do corruption check */
|
||||
size_t i;
|
||||
for (i = 0; i < bytes; ++i) {
|
||||
XPT_ASSERT(arena->next[i] == 0xcd);
|
||||
}
|
||||
/* we guarantee that the block will be filled with zeros */
|
||||
memset(arena->next, 0, bytes);
|
||||
}
|
||||
#endif
|
||||
|
||||
cur = arena->next;
|
||||
arena->next += bytes;
|
||||
arena->space -= bytes;
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
|
||||
XPT_PUBLIC_API(char *)
|
||||
XPT_ArenaStrDup(XPTArena *arena, const char * s)
|
||||
{
|
||||
size_t len;
|
||||
char* cur;
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
len = strlen(s)+1;
|
||||
cur = XPT_ArenaMalloc(arena, len);
|
||||
memcpy(cur, s, len);
|
||||
return cur;
|
||||
}
|
||||
|
||||
XPT_PUBLIC_API(void)
|
||||
XPT_NotifyDoneLoading(XPTArena *arena)
|
||||
{
|
||||
#ifdef XPT_ARENA_LOGGING
|
||||
if (arena) {
|
||||
LOG_DONE_LOADING(arena);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
XPT_PUBLIC_API(void)
|
||||
XPT_ArenaFree(XPTArena *arena, void *block)
|
||||
{
|
||||
LOG_FREE(arena);
|
||||
}
|
||||
|
||||
#ifdef XPT_ARENA_LOGGING
|
||||
static void xpt_DebugPrintArenaStats(XPTArena *arena)
|
||||
{
|
||||
printf("()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()\n");
|
||||
printf("Start xpt arena stats for \"%s\"\n",
|
||||
arena->name ? arena->name : "unnamed arena");
|
||||
printf("\n");
|
||||
printf("%d times arena malloc called\n", (int) arena->LOG_MallocCallCount);
|
||||
printf("%d total bytes requested from arena malloc\n", (int) arena->LOG_MallocTotalBytesRequested);
|
||||
printf("%d average bytes requested per call to arena malloc\n", (int)arena->LOG_MallocCallCount ? (arena->LOG_MallocTotalBytesRequested/arena->LOG_MallocCallCount) : 0);
|
||||
printf("%d average bytes used per call (accounts for alignment overhead)\n", (int)arena->LOG_MallocCallCount ? (arena->LOG_MallocTotalBytesUsed/arena->LOG_MallocCallCount) : 0);
|
||||
printf("%d average bytes used per call (accounts for all overhead and waste)\n", (int)arena->LOG_MallocCallCount ? (arena->LOG_RealMallocTotalBytesRequested/arena->LOG_MallocCallCount) : 0);
|
||||
printf("\n");
|
||||
printf("%d during loading times arena free called\n", (int) arena->LOG_LoadingFreeCallCount);
|
||||
printf("%d during loading approx total bytes not freed\n", (int) arena->LOG_LoadingFreeCallCount * (int) (arena->LOG_MallocCallCount ? (arena->LOG_MallocTotalBytesUsed/arena->LOG_MallocCallCount) : 0));
|
||||
printf("\n");
|
||||
printf("%d total times arena free called\n", (int) arena->LOG_FreeCallCount);
|
||||
printf("%d approx total bytes not freed until arena destruction\n", (int) arena->LOG_FreeCallCount * (int) (arena->LOG_MallocCallCount ? (arena->LOG_MallocTotalBytesUsed/arena->LOG_MallocCallCount) : 0 ));
|
||||
printf("\n");
|
||||
printf("%d times arena called system malloc\n", (int) arena->LOG_RealMallocCallCount);
|
||||
printf("%d total bytes arena requested from system\n", (int) arena->LOG_RealMallocTotalBytesRequested);
|
||||
printf("%d byte block size specified at arena creation time\n", (int) arena->block_size);
|
||||
printf("%d byte block alignment specified at arena creation time\n", (int) arena->alignment);
|
||||
printf("\n");
|
||||
printf("End xpt arena stats\n");
|
||||
printf("()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user