Bug 570488 - Stop reading/writing xpti.dat and incrementally loading XPT files [1/2] r=Mossop

--HG--
extra : rebase_source : 9f28729c1032b516e8b950d29d80402e87759fda
This commit is contained in:
Benjamin Smedberg 2010-06-14 16:05:48 -07:00
Родитель dd3f1e0231
Коммит 1fc4de7aed
24 изменённых файлов: 455 добавлений и 4427 удалений

Просмотреть файл

@ -2479,9 +2479,6 @@ static void RemoveComponentRegistries(nsIFile* aProfileDir, nsIFile* aLocalProfi
file->AppendNative(NS_LITERAL_CSTRING("compreg.dat"));
file->Remove(PR_FALSE);
file->SetNativeLeafName(NS_LITERAL_CSTRING("xpti.dat"));
file->Remove(PR_FALSE);
if (aRemoveEMFiles) {
file->SetNativeLeafName(NS_LITERAL_CSTRING("extensions.ini"));
file->Remove(PR_FALSE);
@ -3327,7 +3324,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
}
else if (versionOK) {
if (!cachesOK) {
// Remove compreg.dat and xpti.dat, forcing component re-registration.
// Remove compreg.dat, forcing component re-registration.
// The new list of additional components directories is derived from
// information in "extensions.ini".
RemoveComponentRegistries(profD, profLD, PR_FALSE);
@ -3339,7 +3336,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
// Nothing need be done for the normal startup case.
}
else {
// Remove compreg.dat and xpti.dat, forcing component re-registration
// Remove compreg.dat, forcing component re-registration
// with the default set of components (this disables any potentially
// troublesome incompatible XPCOM components).
RemoveComponentRegistries(profD, profLD, PR_TRUE);

Просмотреть файл

@ -337,9 +337,6 @@ nsXREDirProvider::GetFile(const char* aProperty, PRBool* aPersistent,
if (!strcmp(aProperty, NS_XPCOM_COMPONENT_REGISTRY_FILE)) {
rv = file->AppendNative(NS_LITERAL_CSTRING("compreg.dat"));
}
else if (!strcmp(aProperty, NS_XPCOM_XPTI_REGISTRY_FILE)) {
rv = file->AppendNative(NS_LITERAL_CSTRING("xpti.dat"));
}
else if (!strcmp(aProperty, NS_APP_USER_CHROME_DIR)) {
rv = file->AppendNative(NS_LITERAL_CSTRING("chrome"));
}

Просмотреть файл

@ -64,10 +64,6 @@ ifndef MOZ_ENABLE_LIBXUL
DIRS += stub
endif
TOOL_DIRS = \
tools \
$(NULL)
ifeq ($(OS_ARCH),WINNT)
ifdef MOZ_DEBUG
DIRS += windbgdlg

Просмотреть файл

@ -281,7 +281,7 @@ nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer,
NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
nsCOMPtr<nsIInterfaceInfoManager> iim
(xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef());
(xptiInterfaceInfoManager::GetSingleton());
if (!iim)
return NS_ERROR_FAILURE;
@ -698,18 +698,21 @@ NS_InitXPCOM3(nsIServiceManager* *result,
// Pay the cost at startup time of starting this singleton.
nsIInterfaceInfoManager* iim =
xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
xptiInterfaceInfoManager::GetSingleton();
NS_TIME_FUNCTION_MARK("Next: try to load compreg.dat");
#if 0 // The constructor does this, don't do it twice!
// If the component registry is out of date, malformed, or incomplete,
// autoregister the default component directories.
(void) iim->AutoRegisterInterfaces();
#endif,
// "Re-register the world" if compreg.dat doesn't exist
rv = nsComponentManagerImpl::gComponentManager->ReadPersistentRegistry();
if (NS_FAILED(rv)) {
NS_TIME_FUNCTION_MARK("Next: try to register all components (compreg.dat not found)");
// If the component registry is out of date, malformed, or incomplete,
// autoregister the default component directories.
(void) iim->AutoRegisterInterfaces();
nsComponentManagerImpl::gComponentManager->AutoRegister(nsnull);
}

Просмотреть файл

@ -134,6 +134,24 @@ public:
return PR_TRUE;
}
/**
* For pointer types, get the value, returning NULL if the entry is not
* present in the table.
*
* @param aKey the key to retrieve
* @return The found value, or NULL if no entry was found with the given key.
* @note If NULL values are stored in the table, it is not possible to
* distinguish between a NULL value and a missing entry.
*/
UserDataType Get(KeyType aKey) const
{
EntryType* ent = GetEntry(aKey);
if (!ent)
return NULL;
return ent->mData;
}
/**
* put a new value for the associated key
* @param aKey the key to put

Просмотреть файл

@ -84,8 +84,6 @@
#define COMPONENT_REGISTRY_NAME NS_LITERAL_CSTRING("compreg.dat")
#define COMPONENT_DIRECTORY NS_LITERAL_CSTRING("components")
#define XPTI_REGISTRY_NAME NS_LITERAL_CSTRING("xpti.dat")
// define home directory
// For Windows platform, We are choosing Appdata folder as HOME
#if defined (XP_WIN)
@ -633,15 +631,6 @@ nsDirectoryService::GetFile(const char *prop, PRBool *persistent, nsIFile **_ret
localFile->AppendNative(COMPONENT_DIRECTORY);
localFile->AppendNative(COMPONENT_REGISTRY_NAME);
}
else if (inAtom == nsDirectoryService::sXPTIRegistry)
{
rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
if (!localFile)
return NS_ERROR_FAILURE;
localFile->AppendNative(COMPONENT_DIRECTORY);
localFile->AppendNative(XPTI_REGISTRY_NAME);
}
// Unless otherwise set, the core pieces of the GRE exist
// in the current process directory.

Просмотреть файл

@ -39,7 +39,6 @@
DIR_ATOM(sCurrentProcess, NS_XPCOM_CURRENT_PROCESS_DIR)
DIR_ATOM(sComponentRegistry, NS_XPCOM_COMPONENT_REGISTRY_FILE)
DIR_ATOM(sComponentDirectory, NS_XPCOM_COMPONENT_DIR)
DIR_ATOM(sXPTIRegistry, NS_XPCOM_XPTI_REGISTRY_FILE)
DIR_ATOM(sGRE_Directory, NS_GRE_DIR)
DIR_ATOM(sGRE_ComponentDirectory, NS_GRE_COMPONENT_DIR)
DIR_ATOM(sOS_DriveDirectory, NS_OS_DRIVE_DIR)

Просмотреть файл

@ -90,11 +90,6 @@
*/
#define NS_XPCOM_COMPONENT_REGISTRY_FILE "ComRegF"
/* Property will return the location of the application XPTI
* registry file.
*/
#define NS_XPCOM_XPTI_REGISTRY_FILE "XptiRegF"
/* Property will return the location of the the XPCOM Shared Library.
*/
#define NS_XPCOM_LIBRARY_FILE "XpcomLib"

Просмотреть файл

@ -290,7 +290,7 @@ nsProxyObjectManager::GetClass(REFNSIID aIID, nsProxyEventClass **aResult)
}
nsIInterfaceInfoManager *iim =
xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
xptiInterfaceInfoManager::GetSingleton();
if (!iim)
return NS_ERROR_FAILURE;

Просмотреть файл

@ -44,7 +44,7 @@ NS_IMETHODIMP
nsXPTCStubBase::QueryInterface(REFNSIID aIID,
void **aInstancePtr)
{
if (aIID.Equals(mEntry->mIID)) {
if (aIID.Equals(mEntry->IID())) {
NS_ADDREF_THIS();
*aInstancePtr = static_cast<nsISupports*>(this);
return NS_OK;
@ -72,7 +72,7 @@ NS_GetXPTCallStub(REFNSIID aIID, nsIXPTCProxy* aOuter,
NS_ENSURE_ARG(aOuter && aResult);
xptiInterfaceInfoManager *iim =
xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
xptiInterfaceInfoManager::GetSingleton();
NS_ENSURE_TRUE(iim, NS_ERROR_NOT_INITIALIZED);
xptiInterfaceEntry *iie = iim->GetInterfaceEntryForIID(&aIID);

Просмотреть файл

@ -48,15 +48,11 @@ MOZILLA_INTERNAL_API = 1
CPPSRCS = \
xptiFile.cpp \
xptiInterfaceInfo.cpp \
xptiInterfaceInfoManager.cpp \
xptiManifest.cpp \
xptiMisc.cpp \
xptiTypelibGuts.cpp \
xptiWorkingSet.cpp \
xptiZipItem.cpp \
xptiZipLoader.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.

Просмотреть файл

@ -1,111 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla 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/MPL/
*
* 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 the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mike McCabe <mccabe@netscape.com>
* John Bandhauer <jband@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* Implementation of xptiFile. */
#include "xptiprivate.h"
xptiFile::xptiFile()
:
#ifdef DEBUG
mDEBUG_WorkingSet(nsnull),
#endif
mSize(),
mDate(),
mName(nsnull),
mGuts(nsnull),
mDirectory(0)
{
// empty
MOZ_COUNT_CTOR(xptiFile);
}
xptiFile::xptiFile(const nsInt64& aSize,
const nsInt64& aDate,
PRUint32 aDirectory,
const char* aName,
xptiWorkingSet* aWorkingSet)
:
#ifdef DEBUG
mDEBUG_WorkingSet(aWorkingSet),
#endif
mSize(aSize),
mDate(aDate),
mName(aName),
mGuts(nsnull),
mDirectory(aDirectory)
{
NS_ASSERTION(aWorkingSet,"bad param");
mName = XPT_STRDUP(aWorkingSet->GetStringArena(), aName);
MOZ_COUNT_CTOR(xptiFile);
}
xptiFile::xptiFile(const xptiFile& r, xptiWorkingSet* aWorkingSet)
:
#ifdef DEBUG
mDEBUG_WorkingSet(aWorkingSet),
#endif
mSize(r.mSize),
mDate(r.mDate),
mName(nsnull),
mGuts(nsnull),
mDirectory(r.mDirectory)
{
NS_ASSERTION(aWorkingSet,"bad param");
mName = XPT_STRDUP(aWorkingSet->GetStringArena(), r.mName);
MOZ_COUNT_CTOR(xptiFile);
}
xptiFile::~xptiFile()
{
MOZ_COUNT_DTOR(xptiFile);
}
PRBool
xptiFile::SetHeader(XPTHeader* aHeader, xptiWorkingSet* aWorkingSet)
{
NS_ASSERTION(!mGuts,"bad state");
NS_ASSERTION(aHeader,"bad param");
NS_ASSERTION(aWorkingSet,"bad param");
mGuts = xptiTypelibGuts::NewGuts(aHeader, aWorkingSet);
return mGuts != nsnull;
}

Просмотреть файл

@ -69,84 +69,44 @@ static int DEBUG_MonitorEntryCount = 0;
#define LOG_INFO_MONITOR_ENTRY ((void)0)
#endif /* SHOW_INFO_COUNT_STATS */
#ifdef DEBUG
// static
void xptiInterfaceInfo::DEBUG_ShutdownNotification()
/* static */ xptiInterfaceEntry*
xptiInterfaceEntry::Create(const char* name, const nsID& iid,
XPTInterfaceDescriptor* aDescriptor,
xptiTypelibGuts* aTypelib)
{
#ifdef SHOW_INFO_COUNT_STATS
printf("iiii %d total xptiInterfaceInfos created\n", DEBUG_TotalInfos);
printf("iiii %d max xptiInterfaceInfos alive at one time\n", DEBUG_MaxInfos);
printf("iiii %d xptiInterfaceInfos still alive\n", DEBUG_CurrentInfos);
printf("iiii %d times locked\n", DEBUG_MonitorEntryCount);
#endif
int namelen = strlen(name);
return new (XPT_MALLOC(gXPTIStructArena,
sizeof(xptiInterfaceEntry) + namelen))
xptiInterfaceEntry(name, namelen, iid, aDescriptor, aTypelib);
}
#endif /* DEBUG */
/***************************************************************************/
// static
xptiInterfaceEntry*
xptiInterfaceEntry::NewEntry(const char* name,
int nameLength,
const nsID& iid,
const xptiTypelib& typelib,
xptiWorkingSet* aWorkingSet)
{
void* place = XPT_MALLOC(aWorkingSet->GetStructArena(),
sizeof(xptiInterfaceEntry) + nameLength);
if(!place)
return nsnull;
return new(place) xptiInterfaceEntry(name, nameLength, iid, typelib);
}
// static
xptiInterfaceEntry*
xptiInterfaceEntry::NewEntry(const xptiInterfaceEntry& r,
const xptiTypelib& typelib,
xptiWorkingSet* aWorkingSet)
{
size_t nameLength = PL_strlen(r.mName);
void* place = XPT_MALLOC(aWorkingSet->GetStructArena(),
sizeof(xptiInterfaceEntry) + nameLength);
if(!place)
return nsnull;
return new(place) xptiInterfaceEntry(r, nameLength, typelib);
}
xptiInterfaceEntry::xptiInterfaceEntry(const char* name,
size_t nameLength,
const nsID& iid,
const xptiTypelib& typelib)
: mIID(iid),
mTypelib(typelib),
mInfo(nsnull),
mFlags(uint8(0))
XPTInterfaceDescriptor* aDescriptor,
xptiTypelibGuts* aTypelib)
: mIID(iid)
, mDescriptor(aDescriptor)
, mMethodBaseIndex(0)
, mConstantBaseIndex(0)
, mTypelib(aTypelib)
, mParent(NULL)
, mInfo(NULL)
, mFlags(0)
{
memcpy(mName, name, nameLength);
}
xptiInterfaceEntry::xptiInterfaceEntry(const xptiInterfaceEntry& r,
size_t nameLength,
const xptiTypelib& typelib)
: mIID(r.mIID),
mTypelib(typelib),
mInfo(nsnull),
mFlags(r.mFlags)
{
SetResolvedState(NOT_RESOLVED);
memcpy(mName, r.mName, nameLength);
SetResolvedState(PARTIALLY_RESOLVED);
}
PRBool
xptiInterfaceEntry::Resolve(xptiWorkingSet* aWorkingSet /* = nsnull */)
xptiInterfaceEntry::Resolve()
{
nsAutoLock lock(xptiInterfaceInfoManager::GetResolveLock());
return ResolveLocked(aWorkingSet);
return ResolveLocked();
}
PRBool
xptiInterfaceEntry::ResolveLocked(xptiWorkingSet* aWorkingSet /* = nsnull */)
xptiInterfaceEntry::ResolveLocked()
{
int resolvedState = GetResolveState();
@ -155,65 +115,36 @@ xptiInterfaceEntry::ResolveLocked(xptiWorkingSet* aWorkingSet /* = nsnull */)
if(resolvedState == RESOLVE_FAILED)
return PR_FALSE;
xptiInterfaceInfoManager* mgr =
xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
xptiInterfaceInfoManager* mgr = xptiInterfaceInfoManager::GetSingleton();
if(!mgr)
return PR_FALSE;
if(!aWorkingSet)
{
aWorkingSet = mgr->GetWorkingSet();
}
if(resolvedState == NOT_RESOLVED)
{
LOG_RESOLVE(("! begin resolve of %s\n", mName));
// Make a copy of mTypelib because the underlying memory will change!
xptiTypelib typelib = mTypelib;
// We expect our PartiallyResolveLocked() to get called before
// this returns.
if(!mgr->LoadFile(typelib, aWorkingSet))
{
SetResolvedState(RESOLVE_FAILED);
return PR_FALSE;
}
// The state was changed by LoadFile to PARTIALLY_RESOLVED, so this
// ...falls through...
}
NS_ASSERTION(GetResolveState() == PARTIALLY_RESOLVED, "bad state!");
// 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;
PRUint16 parent_index = mDescriptor->parent_interface;
if(parent_index)
{
xptiInterfaceEntry* parent =
aWorkingSet->GetTypelibGuts(mInterface->mTypelib)->
GetEntryAt(parent_index - 1);
mTypelib->GetEntryAt(parent_index - 1);
if(!parent || !parent->EnsureResolvedLocked())
{
xptiTypelib aTypelib = mInterface->mTypelib;
mInterface = nsnull;
mTypelib = aTypelib;
SetResolvedState(RESOLVE_FAILED);
return PR_FALSE;
}
mInterface->mParent = parent;
mParent = parent;
mInterface->mMethodBaseIndex =
parent->mInterface->mMethodBaseIndex +
parent->mInterface->mDescriptor->num_methods;
mMethodBaseIndex =
parent->mMethodBaseIndex +
parent->mDescriptor->num_methods;
mInterface->mConstantBaseIndex =
parent->mInterface->mConstantBaseIndex +
parent->mInterface->mDescriptor->num_constants;
mConstantBaseIndex =
parent->mConstantBaseIndex +
parent->mDescriptor->num_constants;
}
LOG_RESOLVE(("+ complete resolve of %s\n", mName));
@ -222,35 +153,6 @@ xptiInterfaceEntry::ResolveLocked(xptiWorkingSet* aWorkingSet /* = nsnull */)
return PR_TRUE;
}
// This *only* gets called by xptiInterfaceInfoManager::LoadFile (while locked).
PRBool
xptiInterfaceEntry::PartiallyResolveLocked(XPTInterfaceDescriptor* aDescriptor,
xptiWorkingSet* aWorkingSet)
{
NS_ASSERTION(GetResolveState() == NOT_RESOLVED, "bad state");
LOG_RESOLVE(("~ partial resolve of %s\n", mName));
xptiInterfaceGuts* iface =
xptiInterfaceGuts::NewGuts(aDescriptor, mTypelib, aWorkingSet);
if(!iface)
return PR_FALSE;
mInterface = iface;
#ifdef DEBUG
if(!DEBUG_ScriptableFlagIsValid())
{
NS_ERROR("unexpected scriptable flag!");
SetScriptableFlag(XPT_ID_IS_SCRIPTABLE(mInterface->mDescriptor->flags));
}
#endif
SetResolvedState(PARTIALLY_RESOLVED);
return PR_TRUE;
}
/**************************************************/
// These non-virtual methods handle the delegated nsIInterfaceInfo methods.
@ -274,7 +176,6 @@ nsresult
xptiInterfaceEntry::IsScriptable(PRBool* result)
{
// It is not necessary to Resolve because this info is read from manifest.
NS_ASSERTION(DEBUG_ScriptableFlagIsValid(), "scriptable flag out of sync!");
*result = GetScriptableFlag();
return NS_OK;
}
@ -285,7 +186,7 @@ xptiInterfaceEntry::IsFunction(PRBool* result)
if(!EnsureResolved())
return NS_ERROR_UNEXPECTED;
*result = XPT_ID_IS_FUNCTION(GetInterfaceGuts()->mDescriptor->flags);
*result = XPT_ID_IS_FUNCTION(mDescriptor->flags);
return NS_OK;
}
@ -295,8 +196,8 @@ xptiInterfaceEntry::GetMethodCount(uint16* count)
if(!EnsureResolved())
return NS_ERROR_UNEXPECTED;
*count = mInterface->mMethodBaseIndex +
mInterface->mDescriptor->num_methods;
*count = mMethodBaseIndex +
mDescriptor->num_methods;
return NS_OK;
}
@ -306,8 +207,8 @@ xptiInterfaceEntry::GetConstantCount(uint16* count)
if(!EnsureResolved())
return NS_ERROR_UNEXPECTED;
*count = mInterface->mConstantBaseIndex +
mInterface->mDescriptor->num_constants;
*count = mConstantBaseIndex +
mDescriptor->num_constants;
return NS_OK;
}
@ -317,11 +218,11 @@ xptiInterfaceEntry::GetMethodInfo(uint16 index, const nsXPTMethodInfo** info)
if(!EnsureResolved())
return NS_ERROR_UNEXPECTED;
if(index < mInterface->mMethodBaseIndex)
return mInterface->mParent->GetMethodInfo(index, info);
if(index < mMethodBaseIndex)
return mParent->GetMethodInfo(index, info);
if(index >= mInterface->mMethodBaseIndex +
mInterface->mDescriptor->num_methods)
if(index >= mMethodBaseIndex +
mDescriptor->num_methods)
{
NS_ERROR("bad param");
*info = NULL;
@ -330,9 +231,7 @@ xptiInterfaceEntry::GetMethodInfo(uint16 index, const nsXPTMethodInfo** info)
// else...
*info = reinterpret_cast<nsXPTMethodInfo*>
(&mInterface->mDescriptor->
method_descriptors[index -
mInterface->mMethodBaseIndex]);
(&mDescriptor->method_descriptors[index - mMethodBaseIndex]);
return NS_OK;
}
@ -344,21 +243,21 @@ xptiInterfaceEntry::GetMethodInfoForName(const char* methodName, uint16 *index,
return NS_ERROR_UNEXPECTED;
// This is a slow algorithm, but this is not expected to be called much.
for(uint16 i = 0; i < mInterface->mDescriptor->num_methods; ++i)
for(uint16 i = 0; i < mDescriptor->num_methods; ++i)
{
const nsXPTMethodInfo* info;
info = reinterpret_cast<nsXPTMethodInfo*>
(&mInterface->mDescriptor->
(&mDescriptor->
method_descriptors[i]);
if (PL_strcmp(methodName, info->GetName()) == 0) {
*index = i + mInterface->mMethodBaseIndex;
*index = i + mMethodBaseIndex;
*result = info;
return NS_OK;
}
}
if(mInterface->mParent)
return mInterface->mParent->GetMethodInfoForName(methodName, index, result);
if(mParent)
return mParent->GetMethodInfoForName(methodName, index, result);
else
{
*index = 0;
@ -373,11 +272,11 @@ xptiInterfaceEntry::GetConstant(uint16 index, const nsXPTConstant** constant)
if(!EnsureResolved())
return NS_ERROR_UNEXPECTED;
if(index < mInterface->mConstantBaseIndex)
return mInterface->mParent->GetConstant(index, constant);
if(index < mConstantBaseIndex)
return mParent->GetConstant(index, constant);
if(index >= mInterface->mConstantBaseIndex +
mInterface->mDescriptor->num_constants)
if(index >= mConstantBaseIndex +
mDescriptor->num_constants)
{
NS_PRECONDITION(0, "bad param");
*constant = NULL;
@ -387,9 +286,9 @@ xptiInterfaceEntry::GetConstant(uint16 index, const nsXPTConstant** constant)
// else...
*constant =
reinterpret_cast<nsXPTConstant*>
(&mInterface->mDescriptor->
(&mDescriptor->
const_descriptors[index -
mInterface->mConstantBaseIndex]);
mConstantBaseIndex]);
return NS_OK;
}
@ -403,11 +302,11 @@ xptiInterfaceEntry::GetEntryForParam(PRUint16 methodIndex,
if(!EnsureResolved())
return NS_ERROR_UNEXPECTED;
if(methodIndex < mInterface->mMethodBaseIndex)
return mInterface->mParent->GetEntryForParam(methodIndex, param, entry);
if(methodIndex < mMethodBaseIndex)
return mParent->GetEntryForParam(methodIndex, param, entry);
if(methodIndex >= mInterface->mMethodBaseIndex +
mInterface->mDescriptor->num_methods)
if(methodIndex >= mMethodBaseIndex +
mDescriptor->num_methods)
{
NS_ERROR("bad param");
return NS_ERROR_INVALID_ARG;
@ -416,7 +315,7 @@ xptiInterfaceEntry::GetEntryForParam(PRUint16 methodIndex,
const XPTTypeDescriptor *td = &param->type;
while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
td = &mInterface->mDescriptor->additional_types[td->type.additional_type];
td = &mDescriptor->additional_types[td->type.additional_type];
}
if(XPT_TDP_TAG(td->prefix) != TD_INTERFACE_TYPE) {
@ -424,9 +323,8 @@ xptiInterfaceEntry::GetEntryForParam(PRUint16 methodIndex,
return NS_ERROR_INVALID_ARG;
}
xptiInterfaceEntry* theEntry =
mInterface->mWorkingSet->GetTypelibGuts(mInterface->mTypelib)->
GetEntryAt(td->type.iface - 1);
xptiInterfaceEntry* theEntry = mTypelib->
GetEntryAt(td->type.iface - 1);
// This can happen if a declared interface is not available at runtime.
if(!theEntry)
@ -493,7 +391,7 @@ xptiInterfaceEntry::GetTypeInArray(const nsXPTParamInfo* param,
const XPTTypeDescriptor *td = &param->type;
const XPTTypeDescriptor *additional_types =
mInterface->mDescriptor->additional_types;
mDescriptor->additional_types;
for (uint16 i = 0; i < dimension; i++) {
if(XPT_TDP_TAG(td->prefix) != TD_ARRAY) {
@ -516,12 +414,12 @@ xptiInterfaceEntry::GetTypeForParam(uint16 methodIndex,
if(!EnsureResolved())
return NS_ERROR_UNEXPECTED;
if(methodIndex < mInterface->mMethodBaseIndex)
return mInterface->mParent->
if(methodIndex < mMethodBaseIndex)
return mParent->
GetTypeForParam(methodIndex, param, dimension, type);
if(methodIndex >= mInterface->mMethodBaseIndex +
mInterface->mDescriptor->num_methods)
if(methodIndex >= mMethodBaseIndex +
mDescriptor->num_methods)
{
NS_ERROR("bad index");
return NS_ERROR_INVALID_ARG;
@ -550,12 +448,12 @@ xptiInterfaceEntry::GetSizeIsArgNumberForParam(uint16 methodIndex,
if(!EnsureResolved())
return NS_ERROR_UNEXPECTED;
if(methodIndex < mInterface->mMethodBaseIndex)
return mInterface->mParent->
if(methodIndex < mMethodBaseIndex)
return mParent->
GetSizeIsArgNumberForParam(methodIndex, param, dimension, argnum);
if(methodIndex >= mInterface->mMethodBaseIndex +
mInterface->mDescriptor->num_methods)
if(methodIndex >= mMethodBaseIndex +
mDescriptor->num_methods)
{
NS_ERROR("bad index");
return NS_ERROR_INVALID_ARG;
@ -595,12 +493,12 @@ xptiInterfaceEntry::GetLengthIsArgNumberForParam(uint16 methodIndex,
if(!EnsureResolved())
return NS_ERROR_UNEXPECTED;
if(methodIndex < mInterface->mMethodBaseIndex)
return mInterface->mParent->
if(methodIndex < mMethodBaseIndex)
return mParent->
GetLengthIsArgNumberForParam(methodIndex, param, dimension, argnum);
if(methodIndex >= mInterface->mMethodBaseIndex +
mInterface->mDescriptor->num_methods)
if(methodIndex >= mMethodBaseIndex +
mDescriptor->num_methods)
{
NS_ERROR("bad index");
return NS_ERROR_INVALID_ARG;
@ -640,12 +538,12 @@ xptiInterfaceEntry::GetInterfaceIsArgNumberForParam(uint16 methodIndex,
if(!EnsureResolved())
return NS_ERROR_UNEXPECTED;
if(methodIndex < mInterface->mMethodBaseIndex)
return mInterface->mParent->
if(methodIndex < mMethodBaseIndex)
return mParent->
GetInterfaceIsArgNumberForParam(methodIndex, param, argnum);
if(methodIndex >= mInterface->mMethodBaseIndex +
mInterface->mDescriptor->num_methods)
if(methodIndex >= mMethodBaseIndex +
mDescriptor->num_methods)
{
NS_ERROR("bad index");
return NS_ERROR_INVALID_ARG;
@ -654,7 +552,7 @@ xptiInterfaceEntry::GetInterfaceIsArgNumberForParam(uint16 methodIndex,
const XPTTypeDescriptor *td = &param->type;
while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
td = &mInterface->mDescriptor->
td = &mDescriptor->
additional_types[td->type.additional_type];
}
@ -702,7 +600,7 @@ xptiInterfaceEntry::HasAncestor(const nsIID * iid, PRBool *_retval)
for(xptiInterfaceEntry* current = this;
current;
current = current->mInterface->mParent)
current = current->mParent)
{
if(current->mIID.Equals(*iid))
{
@ -724,12 +622,6 @@ xptiInterfaceEntry::GetInterfaceInfo(xptiInterfaceInfo** info)
nsAutoMonitor lock(xptiInterfaceInfoManager::GetInfoMonitor());
LOG_INFO_MONITOR_ENTRY;
#ifdef SHOW_INFO_COUNT_STATS
static int callCount = 0;
if(!(++callCount%100))
printf("iiii %d xptiInterfaceInfos currently alive\n", DEBUG_CurrentInfos);
#endif
if(!mInfo)
{
mInfo = new xptiInterfaceInfo(this);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,694 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla 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/MPL/
*
* 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 the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mike McCabe <mccabe@netscape.com>
* John Bandhauer <jband@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* Implementation of xptiManifest. */
#include "xptiprivate.h"
#include "nsManifestLineReader.h"
#include "nsString.h"
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 char g_TOKEN_AppDir[] = "AppDir";
static const char g_TOKEN_Directories[] = "Directories";
static const int g_VERSION_MAJOR = 2;
static const int g_VERSION_MINOR = 0;
/***************************************************************************/
static PRBool
GetCurrentAppDirString(xptiInterfaceInfoManager* aMgr, nsACString &aStr)
{
nsCOMPtr<nsILocalFile> appDir;
aMgr->GetApplicationDir(getter_AddRefs(appDir));
if(appDir)
return NS_SUCCEEDED(appDir->GetPersistentDescriptor(aStr));
return PR_FALSE;
}
static PRBool
CurrentAppDirMatchesPersistentDescriptor(xptiInterfaceInfoManager* aMgr,
const char *inStr)
{
nsCOMPtr<nsILocalFile> appDir;
aMgr->GetApplicationDir(getter_AddRefs(appDir));
nsCOMPtr<nsILocalFile> descDir;
nsresult rv = NS_NewNativeLocalFile(EmptyCString(), PR_FALSE, getter_AddRefs(descDir));
if(NS_FAILED(rv))
return PR_FALSE;
rv = descDir->SetPersistentDescriptor(nsDependentCString(inStr));
if(NS_FAILED(rv))
return PR_FALSE;
PRBool matches;
rv = appDir->Equals(descDir, &matches);
return NS_SUCCEEDED(rv) && matches;
}
static PLDHashOperator
xpti_InterfaceWriter(PLDHashTable *table, PLDHashEntryHdr *hdr,
PRUint32 number, void *arg)
{
xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value;
PRFileDesc* fd = (PRFileDesc*) arg;
char iidStr[NSID_LENGTH];
entry->GetTheIID()->ToProvidedString(iidStr);
const xptiTypelib& typelib = entry->GetTypelibRecord();
PRBool success = !!PR_fprintf(fd, "%d,%s,%s,%d,%d,%d\n",
(int) number,
entry->GetTheName(),
iidStr,
(int) typelib.GetFileIndex(),
(int) (typelib.IsZip() ?
typelib.GetZipItemIndex() : -1),
(int) entry->GetScriptableFlag());
return success ? PL_DHASH_NEXT : PL_DHASH_STOP;
}
// static
PRBool xptiManifest::Write(xptiInterfaceInfoManager* aMgr,
xptiWorkingSet* aWorkingSet)
{
PRBool succeeded = PR_FALSE;
PRFileDesc* fd = nsnull;
PRUint32 i;
PRUint32 size32;
PRIntn interfaceCount = 0;
nsCAutoString appDirString;
nsCOMPtr<nsILocalFile> tempFile;
if(!aMgr->GetCloneOfManifestLocation(getter_AddRefs(tempFile)) || !tempFile)
return PR_FALSE;
nsCAutoString originalLeafName;
tempFile->GetNativeLeafName(originalLeafName);
nsCAutoString leafName;
leafName.Assign(originalLeafName + NS_LITERAL_CSTRING(".tmp"));
tempFile->SetNativeLeafName(leafName);
// All exits via "goto out;" from here on...
if(NS_FAILED(tempFile->
OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
0666, &fd)) || !fd)
{
goto out;
}
// write file header comments
if(!PR_fprintf(fd, "%s\n", g_Disclaimer))
goto out;
// write the [Header] block, version number, and appdir.
if(!PR_fprintf(fd, "\n[%s,%d]\n", g_TOKEN_Header, 2))
goto out;
if(!PR_fprintf(fd, "%d,%s,%d,%d\n",
0, g_TOKEN_Version, g_VERSION_MAJOR, g_VERSION_MINOR))
goto out;
GetCurrentAppDirString(aMgr, appDirString);
if(appDirString.IsEmpty())
goto out;
if(!PR_fprintf(fd, "%d,%s,%s\n",
1, g_TOKEN_AppDir, appDirString.get()))
goto out;
// write Directories list
if(!PR_fprintf(fd, "\n[%s,%d]\n",
g_TOKEN_Directories,
(int) aWorkingSet->GetDirectoryCount()))
goto out;
for(i = 0; i < aWorkingSet->GetDirectoryCount(); i++)
{
nsCOMPtr<nsILocalFile> dir;
nsCAutoString str;
aWorkingSet->GetDirectoryAt(i, getter_AddRefs(dir));
if(!dir)
goto out;
dir->GetPersistentDescriptor(str);
if(str.IsEmpty())
goto out;
if(!PR_fprintf(fd, "%d,%s\n", (int) i, str.get()))
goto out;
}
// write Files list
if(!PR_fprintf(fd, "\n[%s,%d]\n",
g_TOKEN_Files,
(int) aWorkingSet->GetFileCount()))
goto out;
for(i = 0; i < aWorkingSet->GetFileCount(); i++)
{
const xptiFile& file = aWorkingSet->GetFileAt(i);
LL_L2UI(size32, file.GetSize());
if(!PR_fprintf(fd, "%d,%s,%d,%u,%lld\n",
(int) i,
file.GetName(),
(int) file.GetDirectory(),
size32, PRInt64(file.GetDate())))
goto out;
}
// write ArchiveItems list
if(!PR_fprintf(fd, "\n[%s,%d]\n",
g_TOKEN_ArchiveItems,
(int) aWorkingSet->GetZipItemCount()))
goto out;
for(i = 0; i < aWorkingSet->GetZipItemCount(); i++)
{
if(!PR_fprintf(fd, "%d,%s\n",
(int) i,
aWorkingSet->GetZipItemAt(i).GetName()))
goto out;
}
// write the Interfaces list
interfaceCount = aWorkingSet->mNameTable->entryCount;
if(!PR_fprintf(fd, "\n[%s,%d]\n",
g_TOKEN_Interfaces,
(int) interfaceCount))
goto out;
if(interfaceCount != (PRIntn)
PL_DHashTableEnumerate(aWorkingSet->mNameTable,
xpti_InterfaceWriter, fd))
goto out;
if(PR_SUCCESS == PR_Close(fd))
{
succeeded = PR_TRUE;
}
fd = nsnull;
out:
if(fd)
PR_Close(fd);
if(succeeded)
{
// delete the old file and rename this
nsCOMPtr<nsILocalFile> mainFile;
if(!aMgr->GetCloneOfManifestLocation(getter_AddRefs(mainFile)) || !mainFile)
return PR_FALSE;
PRBool exists;
if(NS_FAILED(mainFile->Exists(&exists)))
return PR_FALSE;
if(exists && NS_FAILED(mainFile->Remove(PR_FALSE)))
return PR_FALSE;
nsCOMPtr<nsIFile> parent;
mainFile->GetParent(getter_AddRefs(parent));
// MoveTo means rename.
if(NS_FAILED(tempFile->MoveToNative(parent, originalLeafName)))
return PR_FALSE;
}
return succeeded;
}
/***************************************************************************/
/***************************************************************************/
static char*
ReadManifestIntoMemory(xptiInterfaceInfoManager* aMgr,
PRUint32* pLength)
{
PRFileDesc* fd = nsnull;
PRInt32 flen;
PRInt64 fileSize;
char* whole = nsnull;
PRBool success = PR_FALSE;
nsCOMPtr<nsILocalFile> aFile;
if(!aMgr->GetCloneOfManifestLocation(getter_AddRefs(aFile)) || !aFile)
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->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd)) || !fd)
goto out;
if(flen > PR_Read(fd, whole, flen))
goto out;
success = PR_TRUE;
out:
if(fd)
PR_Close(fd);
if(!success)
{
delete [] whole;
return nsnull;
}
*pLength = flen;
return whole;
}
static
PRBool ReadSectionHeader(nsManifestLineReader& reader,
const char *token, int minCount, int* count)
{
while(1)
{
if(!reader.NextLine())
break;
if(*reader.LinePtr() == '[')
{
char* p = reader.LinePtr() + (reader.LineLength() - 1);
if(*p != ']')
break;
*p = 0;
char* values[2];
int lengths[2];
if(2 != reader.ParseLine(values, lengths, 2))
break;
// ignore the leading '['
if(0 != PL_strcmp(values[0]+1, token))
break;
if((*count = atoi(values[1])) < minCount)
break;
return PR_TRUE;
}
}
return PR_FALSE;
}
// static
PRBool xptiManifest::Read(xptiInterfaceInfoManager* aMgr,
xptiWorkingSet* aWorkingSet)
{
int i;
char* whole = nsnull;
PRBool succeeded = PR_FALSE;
PRUint32 flen;
nsManifestLineReader reader;
xptiHashEntry* hashEntry;
int headerCount = 0;
int dirCount = 0;
int fileCount = 0;
int zipItemCount = -1;
int interfaceCount = 0;
int dir;
int flags;
char* values[6]; // 6 is currently the max items we need to parse
int lengths[6];
PRUint32 size32;
PRInt64 size;
PRInt64 date;
whole = ReadManifestIntoMemory(aMgr, &flen);
if(!whole)
return PR_FALSE;
reader.Init(whole, flen);
// All exits from here on should be via '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, 2, &headerCount))
goto out;
if(headerCount != 2)
goto out;
// Verify the version number
if(!reader.NextLine())
goto out;
// index,VersionLiteral,major,minor
if(4 != reader.ParseLine(values, lengths, 4))
goto out;
// index
if(0 != atoi(values[0]))
goto out;
// VersionLiteral
if(0 != PL_strcmp(values[1], g_TOKEN_Version))
goto out;
// major
if(g_VERSION_MAJOR != atoi(values[2]))
goto out;
// minor
if(g_VERSION_MINOR != atoi(values[3]))
goto out;
// Verify the application directory
if(!reader.NextLine())
goto out;
// index,AppDirLiteral,directoryname
if(3 != reader.ParseLine(values, lengths, 3))
goto out;
// index
if(1 != atoi(values[0]))
goto out;
// AppDirLiteral
if(0 != PL_strcmp(values[1], g_TOKEN_AppDir))
goto out;
if(!CurrentAppDirMatchesPersistentDescriptor(aMgr, values[2]))
goto out;
// Look for "Directories" section
if(!ReadSectionHeader(reader, g_TOKEN_Directories, 1, &dirCount))
goto out;
else
{
// To validate that the directory list matches the current search path
// we first confirm that the list lengths match.
nsCOMPtr<nsISupportsArray> searchPath;
aMgr->GetSearchPath(getter_AddRefs(searchPath));
PRUint32 searchPathCount;
searchPath->Count(&searchPathCount);
if(dirCount != (int) searchPathCount)
goto out;
}
// Read the directory records
for(i = 0; i < dirCount; ++i)
{
if(!reader.NextLine())
goto out;
// index,directoryname
if(2 != reader.ParseLine(values, lengths, 2))
goto out;
// index
if(i != atoi(values[0]))
goto out;
// directoryname
if(!aWorkingSet->DirectoryAtMatchesPersistentDescriptor(i, values[1]))
goto out;
}
// Look for "Files" section
if(!ReadSectionHeader(reader, g_TOKEN_Files, 1, &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;
// index,filename,dirIndex,dilesSize,filesDate
if(5 != reader.ParseLine(values, lengths, 5))
goto out;
// index
if(i != atoi(values[0]))
goto out;
// filename
if(!*values[1])
goto out;
// dirIndex
dir = atoi(values[2]);
if(dir < 0 || dir > dirCount)
goto out;
// fileSize
size32 = atoi(values[3]);
if(size32 <= 0)
goto out;
LL_UI2L(size, size32);
// fileDate
date = nsCRT::atoll(values[4]);
if(LL_IS_ZERO(date))
goto out;
// Append a new file record to the array.
aWorkingSet->AppendFile(
xptiFile(nsInt64(size), nsInt64(date), dir, values[1], aWorkingSet));
}
// Look for "ZipItems" section
if(!ReadSectionHeader(reader, g_TOKEN_ArchiveItems, 0, &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;
// index,filename
if(2 != reader.ParseLine(values, lengths, 2))
goto out;
// index
if(i != atoi(values[0]))
goto out;
// filename
if(!*values[1])
goto out;
// Append a new zipItem record to the array.
aWorkingSet->AppendZipItem(xptiZipItem(values[1], aWorkingSet));
}
// Look for "Interfaces" section
if(!ReadSectionHeader(reader, g_TOKEN_Interfaces, 1, &interfaceCount))
goto out;
// Read the interface records
for(i = 0; i < interfaceCount; ++i)
{
int fileIndex;
int zipItemIndex;
nsIID iid;
xptiInterfaceEntry* entry;
xptiTypelib typelibRecord;
if(!reader.NextLine())
goto out;
// index,interfaceName,iid,fileIndex,zipIndex,flags
if(6 != reader.ParseLine(values, lengths, 6))
goto out;
// index
if(i != atoi(values[0]))
goto out;
// interfaceName
if(!*values[1])
goto out;
// iid
if(!iid.Parse(values[2]))
goto out;
// fileIndex
fileIndex = atoi(values[3]);
if(fileIndex < 0 || fileIndex >= fileCount)
goto out;
// zipIndex (NOTE: -1 is a valid value)
zipItemIndex = atoi(values[4]);
if(zipItemIndex < -1 || zipItemIndex >= zipItemCount)
goto out;
// flags
flags = atoi(values[5]);
if(flags != 0 && flags != 1)
goto out;
// Build an InterfaceInfo and hook it in.
if(zipItemIndex == -1)
typelibRecord.Init(fileIndex);
else
typelibRecord.Init(fileIndex, zipItemIndex);
entry = xptiInterfaceEntry::NewEntry(values[1], lengths[1],
iid, typelibRecord,
aWorkingSet);
if(!entry)
goto out;
entry->SetScriptableFlag(flags==1);
// Add our entry to the iid hashtable.
hashEntry = (xptiHashEntry*)
PL_DHashTableOperate(aWorkingSet->mNameTable,
entry->GetTheName(), PL_DHASH_ADD);
if(hashEntry)
hashEntry->value = entry;
// Add our entry to the name hashtable.
hashEntry = (xptiHashEntry*)
PL_DHashTableOperate(aWorkingSet->mIIDTable,
entry->GetTheIID(), PL_DHASH_ADD);
if(hashEntry)
hashEntry->value = entry;
}
// success!
succeeded = PR_TRUE;
out:
if(whole)
delete [] whole;
if(!succeeded)
{
// Cleanup the WorkingSet on failure.
aWorkingSet->InvalidateInterfaceInfos();
aWorkingSet->ClearHashTables();
aWorkingSet->ClearFiles();
}
return succeeded;
}
// static
PRBool xptiManifest::Delete(xptiInterfaceInfoManager* aMgr)
{
nsCOMPtr<nsILocalFile> aFile;
if(!aMgr->GetCloneOfManifestLocation(getter_AddRefs(aFile)) || !aFile)
return PR_FALSE;
PRBool exists;
if(NS_FAILED(aFile->Exists(&exists)))
return PR_FALSE;
if(exists && NS_FAILED(aFile->Remove(PR_FALSE)))
return PR_FALSE;
return PR_TRUE;
}

Просмотреть файл

@ -57,106 +57,12 @@ static const xptiFileTypeEntry g_Entries[] =
};
// static
xptiFileType::Type xptiFileType::GetType(const char* name)
xptiFileType::Type xptiFileType::GetType(const nsACString& aType)
{
NS_ASSERTION(name, "loser!");
int len = PL_strlen(name);
for(const xptiFileTypeEntry* p = g_Entries; p->name; p++)
{
if(len > p->len && 0 == PL_strcasecmp(p->name, &(name[len - p->len])))
if (StringEndsWith(aType, nsDependentCString(p->name, p->len)))
return p->type;
}
return UNKNOWN;
}
/***************************************************************************/
xptiAutoLog::xptiAutoLog(xptiInterfaceInfoManager* mgr,
nsILocalFile* logfile, PRBool append)
: mMgr(nsnull), mOldFileDesc(nsnull)
{
MOZ_COUNT_CTOR(xptiAutoLog);
if(mgr && logfile)
{
PRFileDesc* fd;
if(NS_SUCCEEDED(logfile->
OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | PR_APPEND |
(append ? 0 : PR_TRUNCATE),
0666, &fd)) && fd)
{
#ifdef DEBUG
m_DEBUG_FileDesc = fd;
#endif
mMgr = mgr;
mOldFileDesc = mMgr->SetOpenLogFile(fd);
if(append)
PR_Seek(fd, 0, PR_SEEK_END);
WriteTimestamp(fd, "++++ start logging ");
}
else
{
#ifdef DEBUG
printf("xpti failed to open log file for writing\n");
#endif
}
}
}
xptiAutoLog::~xptiAutoLog()
{
MOZ_COUNT_DTOR(xptiAutoLog);
if(mMgr)
{
PRFileDesc* fd = mMgr->SetOpenLogFile(mOldFileDesc);
NS_ASSERTION(fd == m_DEBUG_FileDesc, "bad unravel");
if(fd)
{
WriteTimestamp(fd, "---- end logging ");
PR_Close(fd);
}
}
}
void xptiAutoLog::WriteTimestamp(PRFileDesc* fd, const char* msg)
{
PRExplodedTime expTime;
PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &expTime);
char time[128];
PR_FormatTimeUSEnglish(time, 128, "%Y-%m-%d-%H:%M:%S", &expTime);
PR_fprintf(fd, "\n%s %s\n\n", msg, time);
}
/***************************************************************************/
nsresult
xptiCloneLocalFile(nsILocalFile* aLocalFile,
nsILocalFile** aCloneLocalFile)
{
nsresult rv;
nsCOMPtr<nsIFile> cloneRaw;
rv = aLocalFile->Clone(getter_AddRefs(cloneRaw));
if(NS_FAILED(rv))
return rv;
return CallQueryInterface(cloneRaw, aCloneLocalFile);
}
nsresult
xptiCloneElementAsLocalFile(nsISupportsArray* aArray, PRUint32 aIndex,
nsILocalFile** aLocalFile)
{
nsresult rv;
nsCOMPtr<nsILocalFile> original;
rv = aArray->QueryElementAt(aIndex, NS_GET_IID(nsILocalFile),
getter_AddRefs(original));
if(NS_FAILED(rv))
return rv;
return xptiCloneLocalFile(original, aLocalFile);
}

Просмотреть файл

@ -43,11 +43,10 @@
// static
xptiTypelibGuts*
xptiTypelibGuts::NewGuts(XPTHeader* aHeader,
xptiWorkingSet* aWorkingSet)
xptiTypelibGuts::Create(XPTHeader* aHeader)
{
NS_ASSERTION(aHeader, "bad param");
void* place = XPT_MALLOC(aWorkingSet->GetStructArena(),
void* place = XPT_MALLOC(gXPTIStructArena,
sizeof(xptiTypelibGuts) +
(sizeof(xptiInterfaceEntry*) *
(aHeader->num_interfaces - 1)));
@ -56,8 +55,31 @@ xptiTypelibGuts::NewGuts(XPTHeader* aHeader,
return new(place) xptiTypelibGuts(aHeader);
}
xptiTypelibGuts::xptiTypelibGuts(XPTHeader* aHeader)
: mHeader(aHeader)
xptiInterfaceEntry*
xptiTypelibGuts::GetEntryAt(PRUint16 i)
{
// empty
static const nsID zeroIID =
{ 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } };
NS_ASSERTION(mHeader, "bad state");
NS_ASSERTION(i < GetEntryCount(), "bad index");
xptiInterfaceEntry* r = mEntryArray[i];
if (r)
return r;
XPTInterfaceDirectoryEntry* iface = mHeader->interface_directory + i;
xptiWorkingSet* set =
xptiInterfaceInfoManager::GetSingleton()->GetWorkingSet();
if (iface->iid.Equals(zeroIID))
r = set->mNameTable.Get(iface->name);
else
r = set->mIIDTable.Get(iface->iid);
if (r)
SetEntryAt(i, r);
return r;
}

Просмотреть файл

@ -42,111 +42,23 @@
#include "xptiprivate.h"
#include "nsString.h"
#define XPTI_STRING_ARENA_BLOCK_SIZE (1024 * 1)
#define XPTI_STRUCT_ARENA_BLOCK_SIZE (1024 * 1)
#define XPTI_HASHTABLE_SIZE 2048
/***************************************************************************/
static PLDHashNumber
IIDHash(PLDHashTable *table, const void *key)
{
return (PLDHashNumber) ((const nsIID*)key)->m0;
}
static PRBool
IIDMatch(PLDHashTable *table,
const PLDHashEntryHdr *entry,
const void *key)
{
const nsIID* iid1 = ((xptiHashEntry*)entry)->value->GetTheIID();
const nsIID* iid2 = (const nsIID*)key;
return iid1 == iid2 || iid1->Equals(*iid2);
}
const static struct PLDHashTableOps IIDTableOps =
{
PL_DHashAllocTable,
PL_DHashFreeTable,
IIDHash,
IIDMatch,
PL_DHashMoveEntryStub,
PL_DHashClearEntryStub,
PL_DHashFinalizeStub
};
/***************************************************************************/
static PRBool
NameMatch(PLDHashTable *table,
const PLDHashEntryHdr *entry,
const void *key)
{
const char* str1 = ((xptiHashEntry*)entry)->value->GetTheName();
const char* str2 = (const char*) key;
return str1 == str2 || 0 == PL_strcmp(str1, str2);
}
static const struct PLDHashTableOps NameTableOps =
{
PL_DHashAllocTable,
PL_DHashFreeTable,
PL_DHashStringKey,
NameMatch,
PL_DHashMoveEntryStub,
PL_DHashClearEntryStub,
PL_DHashFinalizeStub
};
/***************************************************************************/
xptiWorkingSet::xptiWorkingSet(nsISupportsArray* aDirectories)
: 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")),
mDirectories(aDirectories),
mNameTable(PL_NewDHashTable(&NameTableOps, nsnull, sizeof(xptiHashEntry),
XPTI_HASHTABLE_SIZE)),
mIIDTable(PL_NewDHashTable(&IIDTableOps, nsnull, sizeof(xptiHashEntry),
XPTI_HASHTABLE_SIZE)),
mFileMergeOffsetMap(nsnull),
mZipItemMergeOffsetMap(nsnull)
xptiWorkingSet::xptiWorkingSet()
{
MOZ_COUNT_CTOR(xptiWorkingSet);
// do nothing else...
}
PRBool
xptiWorkingSet::IsValid() const
{
return (mFileCount == 0 || mFileArray) &&
(mZipItemCount == 0 || mZipItemArray) &&
mStringArena &&
mStructArena &&
mNameTable &&
mIIDTable;
mIIDTable.Init(XPTI_HASHTABLE_SIZE);
mNameTable.Init(XPTI_HASHTABLE_SIZE);
gXPTIStructArena = XPT_NewArena(XPTI_STRUCT_ARENA_BLOCK_SIZE, sizeof(double),
"xptiWorkingSet structs");
}
static PLDHashOperator
xpti_Remover(PLDHashTable *table, PLDHashEntryHdr *hdr,
PRUint32 number, void *arg)
xpti_Invalidator(const char* keyname, xptiInterfaceEntry* entry, void* arg)
{
return PL_DHASH_REMOVE;
}
static PLDHashOperator
xpti_Invalidator(PLDHashTable *table, PLDHashEntryHdr *hdr,
PRUint32 number, void *arg)
{
xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value;
entry->LockedInvalidateInterfaceInfo();
return PL_DHASH_NEXT;
}
@ -154,263 +66,16 @@ xpti_Invalidator(PLDHashTable *table, PLDHashEntryHdr *hdr,
void
xptiWorkingSet::InvalidateInterfaceInfos()
{
if(mNameTable)
{
nsAutoMonitor lock(xptiInterfaceInfoManager::GetInfoMonitor());
PL_DHashTableEnumerate(mNameTable, xpti_Invalidator, nsnull);
}
}
void
xptiWorkingSet::ClearHashTables()
{
if(mNameTable)
PL_DHashTableEnumerate(mNameTable, xpti_Remover, nsnull);
if(mIIDTable)
PL_DHashTableEnumerate(mIIDTable, xpti_Remover, 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;
nsAutoMonitor lock(xptiInterfaceInfoManager::GetInfoMonitor());
mNameTable.EnumerateRead(xpti_Invalidator, NULL);
}
xptiWorkingSet::~xptiWorkingSet()
{
MOZ_COUNT_DTOR(xptiWorkingSet);
ClearFiles();
ClearZipItems();
ClearHashTables();
if(mNameTable)
PL_DHashTableDestroy(mNameTable);
if(mIIDTable)
PL_DHashTableDestroy(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);
}
}
PRUint32
xptiWorkingSet::FindFile(PRUint32 dir, const char* name)
{
if(mFileArray)
{
for(PRUint32 i = 0; i < mFileCount;++i)
{
xptiFile& file = mFileArray[i];
if(file.GetDirectory() == dir &&
0 == PL_strcmp(name, file.GetName()))
{
return i;
}
}
}
return NOT_FOUND;
}
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;
}
/***************************************************************************/
PRUint32
xptiWorkingSet::FindZipItemWithName(const char* name)
{
if(mZipItemArray)
{
for(PRUint32 i = 0; i < mZipItemCount;++i)
if(0 == PL_strcmp(name, mZipItemArray[i].GetName()))
return i;
}
return NOT_FOUND;
}
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;
}
/***************************************************************************/
// Directory stuff...
PRUint32 xptiWorkingSet::GetDirectoryCount()
{
PRUint32 count = 0;
mDirectories->Count(&count);
return count;
}
nsresult xptiWorkingSet::GetCloneOfDirectoryAt(PRUint32 i, nsILocalFile** dir)
{
return xptiCloneElementAsLocalFile(mDirectories, i, dir);
}
nsresult xptiWorkingSet::GetDirectoryAt(PRUint32 i, nsILocalFile** dir)
{
return mDirectories->QueryElementAt(i, NS_GET_IID(nsILocalFile), (void**)dir);
}
PRBool xptiWorkingSet::FindDirectory(nsILocalFile* dir, PRUint32* index)
{
PRUint32 count;
nsresult rv = mDirectories->Count(&count);
if(NS_FAILED(rv))
return PR_FALSE;
for(PRUint32 i = 0; i < count; i++)
{
PRBool same;
nsCOMPtr<nsILocalFile> current;
mDirectories->QueryElementAt(i, NS_GET_IID(nsILocalFile),
getter_AddRefs(current));
if(!current || NS_FAILED(current->Equals(dir, &same)))
break;
if(same)
{
*index = i;
return PR_TRUE;
}
}
return PR_FALSE;
}
PRBool xptiWorkingSet::FindDirectoryOfFile(nsILocalFile* file, PRUint32* index)
{
nsCOMPtr<nsIFile> dirAbstract;
file->GetParent(getter_AddRefs(dirAbstract));
if(!dirAbstract)
return PR_FALSE;
nsCOMPtr<nsILocalFile> dir = do_QueryInterface(dirAbstract);
if(!dir)
return PR_FALSE;
return FindDirectory(dir, index);
}
PRBool xptiWorkingSet::DirectoryAtMatchesPersistentDescriptor(PRUint32 i,
const char* inDesc)
{
nsCOMPtr<nsILocalFile> dir;
GetDirectoryAt(i, getter_AddRefs(dir));
if(!dir)
return PR_FALSE;
nsCOMPtr<nsILocalFile> descDir;
nsresult rv = NS_NewNativeLocalFile(EmptyCString(), PR_FALSE, getter_AddRefs(descDir));
if(NS_FAILED(rv))
return PR_FALSE;
rv = descDir->SetPersistentDescriptor(nsDependentCString(inDesc));
if(NS_FAILED(rv))
return PR_FALSE;
PRBool matches;
rv = dir->Equals(descDir, &matches);
return NS_SUCCEEDED(rv) && matches;
// Don't destroy the arena; we're shutting down, why touch the
// memory when we don't have to?
}
XPTArena* gXPTIStructArena;

Просмотреть файл

@ -1,100 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla 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/MPL/
*
* 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 the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mike McCabe <mccabe@netscape.com>
* John Bandhauer <jband@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* Implementation of xptiZipItem. */
#include "xptiprivate.h"
xptiZipItem::xptiZipItem()
:
#ifdef DEBUG
mDEBUG_WorkingSet(nsnull),
#endif
mName(nsnull),
mGuts(nsnull)
{
MOZ_COUNT_CTOR(xptiZipItem);
// empty
}
xptiZipItem::xptiZipItem(const char* aName,
xptiWorkingSet* aWorkingSet)
:
#ifdef DEBUG
mDEBUG_WorkingSet(aWorkingSet),
#endif
mName(aName),
mGuts(nsnull)
{
MOZ_COUNT_CTOR(xptiZipItem);
NS_ASSERTION(aWorkingSet,"bad param");
mName = XPT_STRDUP(aWorkingSet->GetStringArena(), aName);
}
xptiZipItem::xptiZipItem(const xptiZipItem& r, xptiWorkingSet* aWorkingSet)
:
#ifdef DEBUG
mDEBUG_WorkingSet(aWorkingSet),
#endif
mName(nsnull),
mGuts(nsnull)
{
MOZ_COUNT_CTOR(xptiZipItem);
NS_ASSERTION(aWorkingSet,"bad param");
mName = XPT_STRDUP(aWorkingSet->GetStringArena(), r.mName);
}
xptiZipItem::~xptiZipItem()
{
MOZ_COUNT_DTOR(xptiZipItem);
}
PRBool
xptiZipItem::SetHeader(XPTHeader* aHeader, xptiWorkingSet* aWorkingSet)
{
NS_ASSERTION(!mGuts,"bad state");
NS_ASSERTION(aHeader,"bad param");
NS_ASSERTION(aWorkingSet,"bad param");
mGuts = xptiTypelibGuts::NewGuts(aHeader, aWorkingSet);
return mGuts != nsnull;
}

Просмотреть файл

@ -1,113 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla 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/MPL/
*
* 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 the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mike McCabe <mccabe@netscape.com>
* John Bandhauer <jband@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* Implementation of xptiZipLoader. */
#include "xptiprivate.h"
XPTHeader*
xptiZipLoader::ReadXPTFileFromInputStream(nsIInputStream *stream,
xptiWorkingSet* aWorkingSet)
{
XPTCursor cursor;
PRUint32 totalRead = 0;
XPTState *state = nsnull;
XPTHeader *header = nsnull;
PRUint32 flen;
stream->Available(&flen);
char *whole = new char[flen];
if (!whole)
{
return nsnull;
}
// all exits from on here should be via 'goto out'
while(flen - totalRead)
{
PRUint32 avail;
PRUint32 read;
if(NS_FAILED(stream->Available(&avail)))
{
goto out;
}
if(avail > flen)
{
goto out;
}
if(NS_FAILED(stream->Read(whole+totalRead, avail, &read)))
{
goto out;
}
totalRead += read;
}
// Go ahead and close the stream now.
stream = nsnull;
if(!(state = XPT_NewXDRState(XPT_DECODE, whole, flen)))
{
goto out;
}
if(!XPT_MakeCursor(state, XPT_HEADER, 0, &cursor))
{
goto out;
}
if (!XPT_DoHeader(aWorkingSet->GetStructArena(), &cursor, &header))
{
header = nsnull;
goto out;
}
out:
if(state)
XPT_DestroyXDRState(state);
if(whole)
delete [] whole;
return header;
}

Просмотреть файл

@ -43,6 +43,7 @@
#define xptiprivate_h___
#include "nscore.h"
#include NEW_H
#include "nsISupports.h"
// this after nsISupports, to pick up IID
@ -65,7 +66,6 @@
#include "nsCRT.h"
#include "nsMemory.h"
#include "nsISupportsArray.h"
#include "nsCOMArray.h"
#include "nsInt64.h"
#include "nsQuickSort.h"
@ -76,7 +76,8 @@
#include "nsAutoLock.h"
#include "pldhash.h"
#include "nsHashKeys.h"
#include "nsDataHashtable.h"
#include "plstr.h"
#include "prprf.h"
#include "prio.h"
@ -95,7 +96,7 @@
#else
#define LOG_RESOLVE(x) ((void)0)
#define LOG_LOAD(x) ((void)0)
#define LOG_AUTOREG(x) xptiInterfaceInfoManager::WriteToLog x
#define LOG_AUTOREG(x) ((void)0)
#endif
#if 1 && defined(DEBUG_jband)
@ -104,41 +105,16 @@
/***************************************************************************/
class xptiFile;
class xptiInterfaceInfo;
class xptiInterfaceInfoManager;
class xptiInterfaceEntry;
class xptiInterfaceGuts;
class xptiTypelibGuts;
class xptiWorkingSet;
extern XPTArena* gXPTIStructArena;
/***************************************************************************/
class xptiTypelib
{
public:
// No ctors or dtors so that we can be in a union in xptiInterfaceInfo.
// Allow automatic shallow copies.
PRUint16 GetFileIndex() const {return mFileIndex;}
PRUint16 GetZipItemIndex() const {return mZipItemIndex;}
enum {NOT_ZIP = 0xffff};
PRBool IsZip() const {return mZipItemIndex != NOT_ZIP;}
void Init(PRUint16 aFileIndex, PRUint16 aZipItemIndex = NOT_ZIP)
{mFileIndex = aFileIndex; mZipItemIndex = aZipItemIndex;}
PRBool Equals(const xptiTypelib& r) const
{return mFileIndex == r.mFileIndex &&
mZipItemIndex == r.mZipItemIndex;}
private:
PRUint16 mFileIndex;
PRUint16 mZipItemIndex;
};
/***************************************************************************/
// No virtuals.
@ -148,8 +124,7 @@ private:
class xptiTypelibGuts
{
public:
static xptiTypelibGuts* NewGuts(XPTHeader* aHeader,
xptiWorkingSet* aWorkingSet);
static xptiTypelibGuts* Create(XPTHeader* aHeader);
XPTHeader* GetHeader() {return mHeader;}
PRUint16 GetEntryCount() const {return mHeader->num_interfaces;}
@ -161,18 +136,13 @@ public:
mEntryArray[i] = ptr;
}
xptiInterfaceEntry* GetEntryAt(PRUint16 i) const
{
NS_ASSERTION(mHeader,"bad state!");
NS_ASSERTION(i < GetEntryCount(),"bad param!");
return mEntryArray[i];
}
xptiInterfaceEntry* GetEntryAt(PRUint16 i);
private:
xptiTypelibGuts(); // not implemented
xptiTypelibGuts(XPTHeader* aHeader);
~xptiTypelibGuts() {}
void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
xptiTypelibGuts(XPTHeader* aHeader)
: mHeader(aHeader)
{ }
~xptiTypelibGuts();
private:
XPTHeader* mHeader; // hold pointer into arena
@ -181,230 +151,21 @@ private:
/***************************************************************************/
class xptiFile
{
public:
const nsInt64& GetSize() const {return mSize;}
const nsInt64& GetDate() const {return mDate;}
const char* GetName() const {return mName;}
const PRUint32 GetDirectory() const {return mDirectory;}
xptiTypelibGuts* GetGuts() {return mGuts;}
xptiFile();
xptiFile(const nsInt64& aSize,
const nsInt64& aDate,
PRUint32 aDirectory,
const char* aName,
xptiWorkingSet* aWorkingSet);
xptiFile(const xptiFile& r, xptiWorkingSet* aWorkingSet);
~xptiFile();
PRBool SetHeader(XPTHeader* aHeader, xptiWorkingSet* aWorkingSet);
PRBool Equals(const xptiFile& r) const
{
return mDirectory == r.mDirectory &&
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)
{
#ifdef DEBUG
// If 'this' has a workingset then it better match that of the assigner.
NS_ASSERTION(!mDEBUG_WorkingSet ||
mDEBUG_WorkingSet == r.mDEBUG_WorkingSet,
"illegal xptiFile assignment");
mDEBUG_WorkingSet = r.mDEBUG_WorkingSet;
#endif
mSize = r.mSize;
mDate = r.mDate;
mName = r.mName;
mDirectory = r.mDirectory;
mGuts = r.mGuts;
}
private:
#ifdef DEBUG
xptiWorkingSet* mDEBUG_WorkingSet;
#endif
nsInt64 mSize;
nsInt64 mDate;
const char* mName; // hold pointer into arena from initializer
xptiTypelibGuts* mGuts; // hold pointer into arena
PRUint32 mDirectory;
};
/***************************************************************************/
class xptiZipItem
{
public:
const char* GetName() const {return mName;}
xptiTypelibGuts* GetGuts() {return mGuts;}
xptiZipItem();
xptiZipItem(const char* aName,
xptiWorkingSet* aWorkingSet);
xptiZipItem(const xptiZipItem& r, xptiWorkingSet* aWorkingSet);
~xptiZipItem();
PRBool SetHeader(XPTHeader* aHeader, xptiWorkingSet* aWorkingSet);
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)
{
#ifdef DEBUG
// If 'this' has a workingset then it better match that of the assigner.
NS_ASSERTION(!mDEBUG_WorkingSet ||
mDEBUG_WorkingSet == r.mDEBUG_WorkingSet,
"illegal xptiFile assignment");
mDEBUG_WorkingSet = r.mDEBUG_WorkingSet;
#endif
mName = r.mName;
mGuts = r.mGuts;
}
private:
#ifdef DEBUG
xptiWorkingSet* mDEBUG_WorkingSet;
#endif
const char* mName; // hold pointer into arena from initializer
xptiTypelibGuts* mGuts; // hold pointer into arena
};
/***************************************************************************/
class xptiWorkingSet
{
public:
xptiWorkingSet(); // not implemented
xptiWorkingSet(nsISupportsArray* aDirectories);
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();
}
enum {NOT_FOUND = 0xffffffff};
// FileArray stuff...
PRUint32 GetFileCount() const {return mFileCount;}
PRUint32 GetFileFreeSpace()
{return mFileArray ? mMaxFileCount - mFileCount : 0;}
PRUint32 FindFile(PRUint32 dir, const char* name);
PRUint32 GetTypelibDirectoryIndex(const xptiTypelib& typelib)
{
return GetFileAt(typelib.GetFileIndex()).GetDirectory();
}
const char* GetTypelibFileName(const xptiTypelib& typelib)
{
return GetFileAt(typelib.GetFileIndex()).GetName();
}
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;}
PRUint32 FindZipItemWithName(const char* name);
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);
// Directory stuff...
PRUint32 GetDirectoryCount();
@ -414,70 +175,14 @@ public:
PRBool FindDirectoryOfFile(nsILocalFile* file, PRUint32* index);
PRBool DirectoryAtMatchesPersistentDescriptor(PRUint32 i, const char* desc);
// 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;
nsCOMPtr<nsISupportsArray> mDirectories;
public:
// XXX make these private with accessors
PLDHashTable* mNameTable;
PLDHashTable* mIIDTable;
PRUint32* mFileMergeOffsetMap; // always in an arena
PRUint32* mZipItemMergeOffsetMap; // always in an arena
};
/***************************************************************************/
class xptiInterfaceGuts
{
public:
PRUint16 mMethodBaseIndex;
PRUint16 mConstantBaseIndex;
xptiInterfaceEntry* mParent;
XPTInterfaceDescriptor* mDescriptor;
xptiTypelib mTypelib;
xptiWorkingSet* mWorkingSet;
static xptiInterfaceGuts* NewGuts(XPTInterfaceDescriptor* aDescriptor,
const xptiTypelib& aTypelib,
xptiWorkingSet* aWorkingSet)
{
void* place = XPT_MALLOC(aWorkingSet->GetStructArena(),
sizeof(xptiInterfaceGuts));
if(!place)
return nsnull;
return new(place) xptiInterfaceGuts(aDescriptor, aTypelib, aWorkingSet);
}
private:
void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
xptiInterfaceGuts(XPTInterfaceDescriptor* aDescriptor,
const xptiTypelib& aTypelib,
xptiWorkingSet* aWorkingSet)
: mMethodBaseIndex(0),
mConstantBaseIndex(0),
mParent(nsnull),
mDescriptor(aDescriptor),
mTypelib(aTypelib),
mWorkingSet(aWorkingSet) {}
~xptiInterfaceGuts() {}
nsDataHashtable<nsIDHashKey, xptiInterfaceEntry*> mIIDTable;
nsDataHashtable<nsDepCharHashKey, xptiInterfaceEntry*> mNameTable;
};
/***************************************************************************/
@ -529,18 +234,12 @@ private:
class xptiInterfaceEntry
{
public:
static xptiInterfaceEntry* NewEntry(const char* name,
int nameLength,
const nsID& iid,
const xptiTypelib& typelib,
xptiWorkingSet* aWorkingSet);
static xptiInterfaceEntry* NewEntry(const xptiInterfaceEntry& r,
const xptiTypelib& typelib,
xptiWorkingSet* aWorkingSet);
static xptiInterfaceEntry* Create(const char* name,
const nsID& iid,
XPTInterfaceDescriptor* aDescriptor,
xptiTypelibGuts* aTypelib);
enum {
NOT_RESOLVED = 0,
PARTIALLY_RESOLVED = 1,
FULLY_RESOLVED = 2,
RESOLVE_FAILED = 3
@ -554,29 +253,6 @@ public:
PRBool IsFullyResolved() const
{return GetResolveState() == (PRUint8) 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;}
xptiInterfaceGuts* GetInterfaceGuts() const
{return HasInterfaceRecord() ? mInterface : nsnull;}
#ifdef DEBUG
PRBool DEBUG_ScriptableFlagIsValid() const
{int s = (int) GetResolveState();
if((s == PARTIALLY_RESOLVED || s == FULLY_RESOLVED) && mInterface)
{
if(XPT_ID_IS_SCRIPTABLE(mInterface->mDescriptor->flags))
return GetScriptableFlag();
return !GetScriptableFlag();
}
return PR_TRUE;
}
#endif
void SetScriptableFlag(PRBool on)
{mFlags.SetFlagBit(PRUint8(SCRIPTABLE),on);}
PRBool GetScriptableFlag() const
@ -585,11 +261,8 @@ public:
const nsID* GetTheIID() const {return &mIID;}
const char* GetTheName() const {return mName;}
PRBool EnsureResolved(xptiWorkingSet* aWorkingSet = nsnull)
{return IsFullyResolved() ? PR_TRUE : Resolve(aWorkingSet);}
PRBool PartiallyResolveLocked(XPTInterfaceDescriptor* aDescriptor,
xptiWorkingSet* aWorkingSet);
PRBool EnsureResolved()
{return IsFullyResolved() ? PR_TRUE : Resolve();}
nsresult GetInterfaceInfo(xptiInterfaceInfo** info);
PRBool InterfaceInfoEquals(const xptiInterfaceInfo* info) const
@ -598,6 +271,13 @@ public:
void LockedInvalidateInterfaceInfo();
void LockedInterfaceInfoDeathNotification() {mInfo = nsnull;}
xptiInterfaceEntry* Parent() const {
NS_ASSERTION(IsFullyResolved(), "Parent() called while not resolved?");
return mParent;
}
const nsID& IID() const { return mIID; }
//////////////////////
// These non-virtual methods handle the delegated nsIInterfaceInfo methods.
@ -624,37 +304,26 @@ public:
nsresult HasAncestor(const nsIID * iid, PRBool *_retval);
nsresult GetIIDForParamNoAlloc(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID *iid);
//////////////////////
nsID mIID;
private:
xptiInterfaceEntry(); // not implemented
xptiInterfaceEntry(const char* name,
size_t nameLength,
const nsID& iid,
const xptiTypelib& typelib);
xptiInterfaceEntry(const xptiInterfaceEntry& r,
size_t nameLength,
const xptiTypelib& typelib);
XPTInterfaceDescriptor* aDescriptor,
xptiTypelibGuts* aTypelib);
~xptiInterfaceEntry();
void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
void SetResolvedState(int state)
{mFlags.SetState(PRUint8(state));}
PRBool Resolve(xptiWorkingSet* aWorkingSet = nsnull);
PRBool Resolve();
// We only call these "*Locked" variants after locking. This is done to
// allow reentrace as files are loaded and various interfaces resolved
// without having to worry about the locked state.
PRBool EnsureResolvedLocked(xptiWorkingSet* aWorkingSet = nsnull)
{return IsFullyResolved() ? PR_TRUE : ResolveLocked(aWorkingSet);}
PRBool ResolveLocked(xptiWorkingSet* aWorkingSet = nsnull);
PRBool EnsureResolvedLocked()
{return IsFullyResolved() ? PR_TRUE : ResolveLocked();}
PRBool ResolveLocked();
// private helpers
@ -667,22 +336,20 @@ private:
const XPTTypeDescriptor** type);
private:
union {
xptiTypelib mTypelib; // Valid only until resolved.
xptiInterfaceGuts* mInterface; // Valid only after resolved.
};
nsID mIID;
XPTInterfaceDescriptor* mDescriptor;
PRUint16 mMethodBaseIndex;
PRUint16 mConstantBaseIndex;
xptiTypelibGuts* mTypelib;
xptiInterfaceEntry* mParent; // Valid only when fully resolved
xptiInterfaceInfo* mInfo; // May come and go.
xptiInfoFlags mFlags;
char mName[1]; // Always last. Sized to fit.
};
struct xptiHashEntry : public PLDHashEntryHdr
{
xptiInterfaceEntry* value;
};
/****************************************************/
class xptiInterfaceInfo : public nsIInterfaceInfo
{
public:
@ -724,24 +391,20 @@ public:
void Invalidate()
{NS_IF_RELEASE(mParent); mEntry = nsnull;}
#ifdef DEBUG
static void DEBUG_ShutdownNotification();
#endif
private:
~xptiInterfaceInfo();
// Note that mParent might still end up as nsnull if we don't have one.
PRBool EnsureParent(xptiWorkingSet* aWorkingSet = nsnull)
PRBool EnsureParent()
{
NS_ASSERTION(mEntry && mEntry->IsFullyResolved(), "bad EnsureParent call");
return mParent || !mEntry->GetInterfaceGuts()->mParent || BuildParent();
return mParent || !mEntry->Parent() || BuildParent();
}
PRBool EnsureResolved(xptiWorkingSet* aWorkingSet = nsnull)
PRBool EnsureResolved()
{
return mEntry && mEntry->EnsureResolved(aWorkingSet);
return mEntry && mEntry->EnsureResolved();
}
PRBool BuildParent()
@ -749,10 +412,9 @@ private:
NS_ASSERTION(mEntry &&
mEntry->IsFullyResolved() &&
!mParent &&
mEntry->GetInterfaceGuts()->mParent,
mEntry->Parent(),
"bad BuildParent call");
return NS_SUCCEEDED(mEntry->GetInterfaceGuts()->mParent->
GetInterfaceInfo(&mParent));
return NS_SUCCEEDED(mEntry->Parent()->GetInterfaceInfo(&mParent));
}
xptiInterfaceInfo(); // not implemented
@ -762,56 +424,6 @@ private:
xptiInterfaceInfo* mParent;
};
/***************************************************************************/
class xptiManifest
{
public:
static PRBool Read(xptiInterfaceInfoManager* aMgr,
xptiWorkingSet* aWorkingSet);
static PRBool Write(xptiInterfaceInfoManager* aMgr,
xptiWorkingSet* aWorkingSet);
static PRBool Delete(xptiInterfaceInfoManager* aMgr);
private:
xptiManifest(); // no implementation
};
/***************************************************************************/
class xptiZipLoaderSink : public nsIXPTLoaderSink
{
public:
xptiZipLoaderSink(xptiInterfaceInfoManager* aMgr,
xptiWorkingSet* aWorkingSet) :
mManager(aMgr),
mWorkingSet(aWorkingSet) {}
NS_DECL_ISUPPORTS
NS_DECL_NSIXPTLOADERSINK
private:
~xptiZipLoaderSink() {}
xptiInterfaceInfoManager* mManager;
xptiWorkingSet* mWorkingSet;
};
class xptiZipLoader
{
public:
xptiZipLoader(); // not implemented
static XPTHeader*
ReadXPTFileFromInputStream(nsIInputStream *stream,
xptiWorkingSet* aWorkingSet);
};
/***************************************************************************/
class xptiFileType
@ -819,165 +431,71 @@ class xptiFileType
public:
enum Type {UNKNOWN = -1, XPT = 0, ZIP = 1 };
static Type GetType(const char* name);
static PRBool IsUnknown(const char* name)
{return GetType(name) == UNKNOWN;}
static PRBool IsXPT(const char* name)
{return GetType(name) == XPT;}
static PRBool IsZip(const char* name)
{return GetType(name) == ZIP;}
static Type GetType(const nsACString& name);
private:
xptiFileType(); // no implementation
};
/***************************************************************************/
// We use this is as a fancy way to open a logfile to be used within the scope
// of some given function where it is instantiated.
class xptiAutoLog
{
public:
xptiAutoLog(); // not implemented
xptiAutoLog(xptiInterfaceInfoManager* mgr,
nsILocalFile* logfile, PRBool append);
~xptiAutoLog();
private:
void WriteTimestamp(PRFileDesc* fd, const char* msg);
xptiInterfaceInfoManager* mMgr;
PRFileDesc* mOldFileDesc;
#ifdef DEBUG
PRFileDesc* m_DEBUG_FileDesc;
#endif
};
/***************************************************************************/
class xptiInterfaceInfoManager
: public nsIInterfaceInfoSuperManager
, public nsIXPTLoaderSink
{
NS_DECL_ISUPPORTS
NS_DECL_NSIINTERFACEINFOMANAGER
NS_DECL_NSIINTERFACEINFOSUPERMANAGER
// helper
PRBool
FoundZipEntry(const char* entryName,
int index,
XPTHeader* header,
xptiWorkingSet* aWorkingSet);
NS_DECL_NSIXPTLOADERSINK
public:
static xptiInterfaceInfoManager* GetInterfaceInfoManagerNoAddRef();
static xptiInterfaceInfoManager* GetSingleton();
static void FreeInterfaceInfoManager();
xptiWorkingSet* GetWorkingSet() {return &mWorkingSet;}
PRFileDesc* GetOpenLogFile() {return mOpenLogFile;}
PRFileDesc* SetOpenLogFile(PRFileDesc* fd)
{PRFileDesc* temp = mOpenLogFile; mOpenLogFile = fd; return temp;}
PRBool LoadFile(const xptiTypelib& aTypelibRecord,
xptiWorkingSet* aWorkingSet = nsnull);
PRBool GetApplicationDir(nsILocalFile** aDir);
PRBool GetCloneOfManifestLocation(nsILocalFile** aDir);
void GetSearchPath(nsISupportsArray** aSearchPath)
{NS_ADDREF(*aSearchPath = mSearchPath);}
static PRLock* GetResolveLock(xptiInterfaceInfoManager* self = nsnull)
{if(!self && !(self = GetInterfaceInfoManagerNoAddRef()))
{if(!self && !(self = GetSingleton()))
return nsnull;
return self->mResolveLock;}
static PRLock* GetAutoRegLock(xptiInterfaceInfoManager* self = nsnull)
{if(!self && !(self = GetInterfaceInfoManagerNoAddRef()))
{if(!self && !(self = GetSingleton()))
return nsnull;
return self->mAutoRegLock;}
static PRMonitor* GetInfoMonitor(xptiInterfaceInfoManager* self = nsnull)
{if(!self && !(self = GetInterfaceInfoManagerNoAddRef()))
{if(!self && !(self = GetSingleton()))
return nsnull;
return self->mInfoMonitor;}
static void WriteToLog(const char *fmt, ...);
xptiInterfaceEntry* GetInterfaceEntryForIID(const nsIID *iid);
private:
xptiInterfaceInfoManager();
~xptiInterfaceInfoManager();
xptiInterfaceInfoManager(); // not implemented
xptiInterfaceInfoManager(nsISupportsArray* aSearchPath);
enum AutoRegMode {
NO_FILES_CHANGED = 0,
FILES_ADDED_ONLY,
FULL_VALIDATION_REQUIRED
};
void RegisterDirectory(nsILocalFile* aDirectory);
void RegisterFile(nsILocalFile* aFile, xptiFileType::Type type);
void RegisterXPTHeader(XPTHeader* aHeader);
PRBool IsValid();
XPTHeader* ReadXPTFile(nsILocalFile* aFile);
XPTHeader* ReadXPTFileFromInputStream(nsIInputStream *stream);
PRBool BuildFileList(nsISupportsArray* aSearchPath,
nsISupportsArray** aFileList);
nsILocalFile** BuildOrderedFileArray(nsISupportsArray* aSearchPath,
nsISupportsArray* aFileList,
xptiWorkingSet* aWorkingSet);
XPTHeader* ReadXPTFile(nsILocalFile* aFile, xptiWorkingSet* aWorkingSet);
AutoRegMode DetermineAutoRegStrategy(nsISupportsArray* aSearchPath,
nsISupportsArray* aFileList,
xptiWorkingSet* aWorkingSet);
PRBool AddOnlyNewFilesFromFileList(nsISupportsArray* aSearchPath,
nsISupportsArray* aFileList,
xptiWorkingSet* aWorkingSet);
PRBool DoFullValidationMergeFromFileList(nsISupportsArray* aSearchPath,
nsISupportsArray* aFileList,
xptiWorkingSet* aWorkingSet);
PRBool VerifyAndAddEntryIfNew(xptiWorkingSet* aWorkingSet,
XPTInterfaceDirectoryEntry* iface,
const xptiTypelib& typelibRecord,
xptiInterfaceEntry** entryAdded);
PRBool MergeWorkingSets(xptiWorkingSet* aDestWorkingSet,
xptiWorkingSet* aSrcWorkingSet);
void LogStats();
PRBool DEBUG_DumpFileList(nsISupportsArray* aFileList);
PRBool DEBUG_DumpFileArray(nsILocalFile** aFileArray, PRUint32 count);
PRBool DEBUG_DumpFileListInWorkingSet(xptiWorkingSet* aWorkingSet);
static PRBool BuildFileSearchPath(nsISupportsArray** aPath);
// idx is the index of this interface in the XPTHeader
void VerifyAndAddEntryIfNew(XPTInterfaceDirectoryEntry* iface,
PRUint16 idx,
xptiTypelibGuts* typelib);
private:
xptiWorkingSet mWorkingSet;
nsCOMPtr<nsILocalFile> mStatsLogFile;
nsCOMPtr<nsILocalFile> mAutoRegLogFile;
PRFileDesc* mOpenLogFile;
PRLock* mResolveLock;
PRLock* mAutoRegLock;
PRMonitor* mInfoMonitor;
PRLock* mAdditionalManagersLock;
nsCOMArray<nsISupports> mAdditionalManagers;
nsCOMPtr<nsISupportsArray> mSearchPath;
};
/***************************************************************************/
// utilities...
nsresult xptiCloneLocalFile(nsILocalFile* aLocalFile,
nsILocalFile** aCloneLocalFile);
nsresult xptiCloneElementAsLocalFile(nsISupportsArray* aArray, PRUint32 aIndex,
nsILocalFile** aLocalFile);
#endif /* xptiprivate_h___ */

Просмотреть файл

@ -1,49 +0,0 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla 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/MPL/
#
# 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 the Initial Developer are Copyright (C) 1998
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = xpcom
DIRS = registry
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -1,73 +0,0 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla 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/MPL/
#
# 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 the Initial Developer are Copyright (C) 1998
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = xpcom
CPPSRCS = regxpcom.cpp
DEFINES += -DXPCOM_GLUE
STL_FLAGS =
LOCAL_INCLUDES = \
-I$(srcdir)/../../build \
$(NULL)
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
LIBS = \
$(XPCOM_STANDALONE_GLUE_LDOPTS) \
$(NULL)
# Need to link with CoreFoundation on Mac
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
LIBS += \
$(TK_LIBS) \
$(NULL)
endif
SDK_BINARY = \
$(SIMPLE_PROGRAMS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -1,390 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla 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/MPL/
*
* 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 the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Mike Shaver <shaver@mozilla.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "stdlib.h"
#include "prenv.h"
#include "nspr.h"
#include "nsXPCOMPrivate.h" // for XPCOM_DLL defines.
#include "nsXPCOMGlue.h"
#include "nsIComponentManager.h"
#include "nsIComponentRegistrar.h"
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
#include "nsILocalFile.h"
#include "nsEmbedString.h"
#include "nsIDirectoryService.h"
#include "nsDirectoryServiceDefs.h"
static PRBool gUnreg = PR_FALSE, gQuiet = PR_FALSE;
static const char* gXPCOMLocation = nsnull;
static const char* gCompRegLocation = nsnull;
static const char* gXPTIDatLocation = nsnull;
class DirectoryServiceProvider : public nsIDirectoryServiceProvider
{
public:
DirectoryServiceProvider() {}
NS_DECL_ISUPPORTS
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
private:
~DirectoryServiceProvider() {}
};
NS_IMPL_ISUPPORTS1(DirectoryServiceProvider, nsIDirectoryServiceProvider)
NS_IMETHODIMP
DirectoryServiceProvider::GetFile(const char *prop, PRBool *persistent, nsIFile **_retval)
{
nsCOMPtr<nsILocalFile> localFile;
nsresult rv = NS_ERROR_FAILURE;
*_retval = nsnull;
*persistent = PR_TRUE;
const char* fileLocation = nsnull;
if(strcmp(prop, NS_XPCOM_CURRENT_PROCESS_DIR) == 0 && gXPCOMLocation)
{
fileLocation = gXPCOMLocation;
}
else if(strcmp(prop, NS_XPCOM_COMPONENT_REGISTRY_FILE) == 0 && gCompRegLocation)
{
fileLocation = gCompRegLocation;
}
else if(strcmp(prop, NS_XPCOM_XPTI_REGISTRY_FILE) == 0 && gXPTIDatLocation)
{
fileLocation = gXPTIDatLocation;
}
else
return NS_ERROR_FAILURE;
rv = NS_NewNativeLocalFile(nsEmbedCString(fileLocation), PR_TRUE, getter_AddRefs(localFile));
if (NS_FAILED(rv)) return rv;
return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
}
int startup_xpcom()
{
nsresult rv;
if (gXPCOMLocation) {
int len = strlen(gXPCOMLocation);
char* xpcomPath = (char*) malloc(len + sizeof(XPCOM_DLL) + sizeof(XPCOM_FILE_PATH_SEPARATOR) + 1);
sprintf(xpcomPath, "%s" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, gXPCOMLocation);
rv = XPCOMGlueStartup(xpcomPath);
free(xpcomPath);
const char* path = getenv(XPCOM_SEARCH_KEY);
if (!path) {
path = "";
}
}
else
{
rv = XPCOMGlueStartup(nsnull);
}
if (NS_FAILED(rv))
{
printf("Can not initialize XPCOM Glue\n");
return -1;
}
DirectoryServiceProvider *provider = new DirectoryServiceProvider();
if ( !provider )
{
NS_WARNING("GRE_Startup failed");
XPCOMGlueShutdown();
return -1;
}
nsCOMPtr<nsILocalFile> file;
if (gXPCOMLocation)
{
rv = NS_NewNativeLocalFile(nsEmbedCString(gXPCOMLocation),
PR_TRUE,
getter_AddRefs(file));
}
NS_ADDREF(provider);
rv = NS_InitXPCOM2(nsnull, file, provider);
NS_RELEASE(provider);
if (NS_FAILED(rv)) {
printf("Can not initialize XPCOM\n");
XPCOMGlueShutdown();
return -1;
}
return 0;
}
void shutdown_xpcom()
{
nsresult rv;
rv = NS_ShutdownXPCOM(nsnull);
if (NS_FAILED(rv)) {
printf("Can not shutdown XPCOM cleanly\n");
}
rv = XPCOMGlueShutdown();
if (NS_FAILED(rv)) {
printf("Can not shutdown XPCOM Glue cleanly\n");
}
}
nsresult Register(const char *path)
{
startup_xpcom();
nsresult rv;
nsCOMPtr<nsILocalFile> spec;
if (path) {
rv = NS_NewNativeLocalFile(nsEmbedCString(path),
PR_TRUE,
getter_AddRefs(spec));
}
nsCOMPtr<nsIComponentRegistrar> registrar;
rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
if (NS_FAILED(rv)) {
printf("Can not acquire component registrar\n");
return rv;
}
if (gUnreg)
rv = registrar->AutoUnregister(spec);
else
rv = registrar->AutoRegister(spec);
spec = 0;
registrar = 0;
shutdown_xpcom();
return rv;
}
void ReportSuccess(const char *file)
{
if (gQuiet)
return;
if (gUnreg)
printf("Unregistration successful for %s\n", file);
else
printf("Registration successful for %s\n", file);
}
void ReportError(nsresult err, const char *file)
{
if (gUnreg)
printf("Unregistration failed: (");
else
printf("Registration failed: (");
switch (err)
{
case NS_ERROR_FACTORY_NOT_LOADED:
printf("Factory not loaded");
break;
case NS_NOINTERFACE:
printf("No Interface");
break;
case NS_ERROR_NULL_POINTER:
printf("Null pointer");
break;
case NS_ERROR_OUT_OF_MEMORY:
printf("Out of memory");
break;
default:
printf("%x", (unsigned)err);
}
printf(") %s\n", file);
}
void printHelp()
{
printf(
"Mozilla regxpcom - a registration tool for xpcom components \n"
" \n"
"Usage: regxpcom [options] [file-or-directory] \n"
" \n"
"Options: \n"
" -x path Specifies the location of a directory containing the \n"
" xpcom library which will be used when registering new \n"
" component libraries. This path will also be added to \n"
" the \"load library\" path. If not specified, the \n"
" current working directory will be used. \n"
" -c path Specifies the location of the compreg.dat file. If \n"
" not specified, the compreg.dat file will be in its \n"
" default location. \n"
" -d path Specifies the location of the xpti.dat file. If not \n"
" specified, the xpti.dat file will be in its default \n"
" location. \n"
" -a Option to register all files in the default component \n"
" directories. This is the default behavior if regxpcom \n"
" is called without any arguments. \n"
" -h Displays this help screen. Must be the only option \n"
" specified. \n"
" -u Option to uninstall the files-or-directory instead of \n"
" registering them. \n"
" -q Quiets some of the output of regxpcom. \n\n");
}
int ProcessArgs(int argc, char *argv[])
{
int i = 1, result = 0;
nsresult res;
while (i < argc)
{
if (argv[i][0] == '-')
{
int j;
for (j = 1; argv[i][j] != '\0'; j++)
{
switch (argv[i][j])
{
case 'h':
printHelp();
return 0; // we are all done!
case 'u':
gUnreg = PR_TRUE;
break;
case 'q':
gQuiet = PR_TRUE;
break;
case 'a':
{
res = Register(nsnull);
if (NS_FAILED(res))
{
ReportError(res, "component directory");
result = -1;
}
else
{
ReportSuccess("component directory");
}
}
break;
case 'x':
gXPCOMLocation = argv[++i];
j = strlen(gXPCOMLocation) - 1;
break;
case 'c':
gCompRegLocation = argv[++i];
j = strlen(gCompRegLocation) - 1;
break;
case 'd':
gXPTIDatLocation = argv[++i];
j = strlen(gXPTIDatLocation) - 1;
break;
default:
printf("Unknown option '%c'\n", argv[i][j]);
}
}
}
else
{
res = Register(argv[i]);
if (NS_FAILED(res))
{
ReportError(res, argv[i]);
result = -1;
}
else
{
ReportSuccess(argv[i]);
}
}
i++;
}
return result;
}
int main(int argc, char *argv[])
{
int ret;
nsresult rv;
/* With no arguments, regxpcom will autoregister */
if (argc <= 1)
{
startup_xpcom();
nsCOMPtr<nsIComponentRegistrar> registrar;
rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
if (NS_FAILED(rv)) {
printf("Can not acquire component registrar\n");
return -1;
}
rv = registrar->AutoRegister(nsnull);
ret = (NS_FAILED(rv)) ? -1 : 0;
registrar = 0;
shutdown_xpcom();
} else
ret = ProcessArgs(argc, argv);
return ret;
}