зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
dd3f1e0231
Коммит
1fc4de7aed
|
@ -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 = ¶m->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 = ¶m->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 = ¶m->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;
|
||||
}
|
Загрузка…
Ссылка в новой задаче