diff --git a/xpcom/reflect/xptinfo/src/Makefile.in b/xpcom/reflect/xptinfo/src/Makefile.in index 16c5a639038..9b148614c4b 100644 --- a/xpcom/reflect/xptinfo/src/Makefile.in +++ b/xpcom/reflect/xptinfo/src/Makefile.in @@ -28,7 +28,7 @@ include $(DEPTH)/config/autoconf.mk MODULE = xpcom LIBRARY_NAME = xptinfo -REQUIRES = jar \ +REQUIRES = \ string \ $(NULL) diff --git a/xpcom/reflect/xptinfo/src/makefile.win b/xpcom/reflect/xptinfo/src/makefile.win index 70c093bec6e..eeaa5c5c2a4 100644 --- a/xpcom/reflect/xptinfo/src/makefile.win +++ b/xpcom/reflect/xptinfo/src/makefile.win @@ -22,7 +22,7 @@ DEPTH=..\..\..\.. MODULE = xpcom -REQUIRES = jar \ +REQUIRES = \ string \ $(NULL) diff --git a/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp b/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp index f23182e0dd0..c8bb7ce9392 100644 --- a/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp +++ b/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp @@ -41,6 +41,8 @@ #include "xptiprivate.h" +#define NS_ZIPLOADER_CONTRACTID NS_XPTLOADER_CONTRACTID_PREFIX "zip" + NS_IMPL_THREADSAFE_ISUPPORTS2(xptiInterfaceInfoManager, nsIInterfaceInfoManager, nsIInterfaceInfoSuperManager) @@ -158,10 +160,6 @@ xptiInterfaceInfoManager::~xptiInterfaceInfoManager() // We only do this on shutdown of the service. mWorkingSet.InvalidateInterfaceInfos(); -#ifdef XPTI_HAS_ZIP_SUPPORT - xptiZipLoader::Shutdown(); -#endif /* XPTI_HAS_ZIP_SUPPORT */ - if(mResolveLock) PR_DestroyLock(mResolveLock); if(mAutoRegLock) @@ -437,7 +435,6 @@ xptiInterfaceInfoManager::LoadFile(const xptiTypelib& aTypelibRecord, if(aTypelibRecord.IsZip()) { -#ifdef XPTI_HAS_ZIP_SUPPORT zipItem = &aWorkingSet->GetZipItemAt(aTypelibRecord.GetZipItemIndex()); // See the big comment below in the 'non-zip' case... @@ -452,10 +449,26 @@ xptiInterfaceInfoManager::LoadFile(const xptiTypelib& aTypelibRecord, } LOG_LOAD(("# loading zip item %s::%s\n", fileRecord->GetName(), zipItem->GetName())); - header = xptiZipLoader::ReadXPTFileFromZip(file, zipItem->GetName(), aWorkingSet); -#else - header = nsnull; -#endif /* XPTI_HAS_ZIP_SUPPORT */ + + nsCOMPtr loader = + do_GetService(NS_ZIPLOADER_CONTRACTID); + + if (loader) { + nsresult rv; + + nsCOMPtr stream; + rv = loader->LoadEntry(file, zipItem->GetName(), + getter_AddRefs(stream)); + + if (NS_FAILED(rv)) + return PR_FALSE; + + header = + xptiZipLoader::ReadXPTFileFromInputStream(stream, aWorkingSet); + } else { + header = nsnull; + NS_WARNING("Could not load XPT Zip loader"); + } } else { @@ -964,20 +977,29 @@ xptiInterfaceInfoManager::AddOnlyNewFilesFromFileList(nsISupportsArray* aSearchP // This will correspond to typelibRecord above. aWorkingSet->AppendFile(fileRecord); } -#ifdef XPTI_HAS_ZIP_SUPPORT - else // It is a zip file, Oh boy! + else // its another kind of archive { - if(!xptiZipLoader::EnumerateZipEntries(file, - NS_STATIC_CAST(xptiEntrySink*, this), - aWorkingSet)) - { - return PR_FALSE; + nsCOMPtr loader = + do_GetService(NS_ZIPLOADER_CONTRACTID); + + if (loader) { + nsresult rv; + + nsCOMPtr sink = + new xptiZipLoaderSink(this, aWorkingSet); + if (!sink) + return PR_FALSE; + + rv = loader->EnumerateEntries(file, sink); + if (NS_FAILED(rv)) + return PR_FALSE; + } else { + NS_WARNING("Could not load XPT Zip loader"); } // This will correspond to typelibRecord used in // xptiInterfaceInfoManager::FoundEntry. aWorkingSet->AppendFile(fileRecord); } -#endif /* XPTI_HAS_ZIP_SUPPORT */ } return PR_TRUE; @@ -1101,30 +1123,59 @@ xptiInterfaceInfoManager::DoFullValidationMergeFromFileList(nsISupportsArray* aS // This will correspond to typelibRecord above. aWorkingSet->AppendFile(fileRecord); } -#ifdef XPTI_HAS_ZIP_SUPPORT - else // It is a zip file, Oh boy! + + else { - if(!xptiZipLoader::EnumerateZipEntries(file, - NS_STATIC_CAST(xptiEntrySink*, this), - aWorkingSet)) - { - return PR_FALSE; + nsCOMPtr loader = + do_GetService(NS_ZIPLOADER_CONTRACTID); + + if (loader) { + nsresult rv; + + nsCOMPtr sink = + new xptiZipLoaderSink(this, aWorkingSet); + if (!sink) + return PR_FALSE; + + rv = loader->EnumerateEntries(file, sink); + if (NS_FAILED(rv)) + return PR_FALSE; + } else { + NS_WARNING("Could not load XPT Zip loader"); } // This will correspond to typelibRecord used in // xptiInterfaceInfoManager::FoundEntry. aWorkingSet->AppendFile(fileRecord); } -#endif /* XPTI_HAS_ZIP_SUPPORT */ } return PR_TRUE; } +NS_IMPL_ISUPPORTS1(xptiZipLoaderSink, nsIXPTLoaderSink) + +// implement nsIXPTLoader +NS_IMETHODIMP +xptiZipLoaderSink::FoundEntry(const char* entryName, + PRInt32 index, + nsIInputStream *aStream) +{ + XPTHeader *header = + xptiZipLoader::ReadXPTFileFromInputStream(aStream, mWorkingSet); + if (!header) + return NS_ERROR_OUT_OF_MEMORY; + + if (!mManager->FoundZipEntry(entryName, index, header, mWorkingSet)) + return NS_ERROR_FAILURE; + + return NS_OK; +} + // implement xptiEntrySink PRBool -xptiInterfaceInfoManager::FoundEntry(const char* entryName, - int index, - XPTHeader* header, - xptiWorkingSet* aWorkingSet) +xptiInterfaceInfoManager::FoundZipEntry(const char* entryName, + int index, + XPTHeader* header, + xptiWorkingSet* aWorkingSet) { NS_ASSERTION(entryName, "loser!"); diff --git a/xpcom/reflect/xptinfo/src/xptiZipLoader.cpp b/xpcom/reflect/xptinfo/src/xptiZipLoader.cpp index 99852109040..8f57340cb45 100644 --- a/xpcom/reflect/xptinfo/src/xptiZipLoader.cpp +++ b/xpcom/reflect/xptinfo/src/xptiZipLoader.cpp @@ -41,165 +41,19 @@ #include "xptiprivate.h" -#ifdef XPTI_HAS_ZIP_SUPPORT - -static const char gCacheContractID[] = "@mozilla.org/libjar/zip-reader-cache;1"; - -static const PRUint32 gCacheSize = 1; - -nsCOMPtr xptiZipLoader::gCache = nsnull; - -// static -nsIZipReader* -xptiZipLoader::GetZipReader(nsILocalFile* file) +XPTHeader* +xptiZipLoader::ReadXPTFileFromInputStream(nsIInputStream *stream, + xptiWorkingSet* aWorkingSet) { - NS_ASSERTION(file, "bad file"); - - if(!gCache) - { - gCache = do_CreateInstance(gCacheContractID); - if(!gCache || NS_FAILED(gCache->Init(gCacheSize))) - return nsnull; - } - - nsIZipReader* reader = nsnull; - - if(NS_FAILED(gCache->GetZip(file, &reader))) - return nsnull; - - return reader; -} - -// static -void -xptiZipLoader::Shutdown() -{ - gCache = nsnull; -} - -// static -PRBool -xptiZipLoader::EnumerateZipEntries(nsILocalFile* file, - xptiEntrySink* sink, - xptiWorkingSet* aWorkingSet) -{ - NS_ASSERTION(file, "loser!"); - NS_ASSERTION(sink, "loser!"); - NS_ASSERTION(aWorkingSet, "loser!"); - - nsCOMPtr zip = dont_AddRef(GetZipReader(file)); - if(!zip) - { - // XXX We are going to say that failure to open a zip/jar is OK. - // We have at least one case where a jar file exists but is not - // available to us to read (MRJPlugin.jar on Mac - bug 109893). - // We TRUST that such files are not going to have xpt files that we - // need to see. - LOG_AUTOREG((" FAILED to open file! Skipping.\n")); - return PR_TRUE; - } - - nsCOMPtr entries; - if(NS_FAILED(zip->FindEntries("*.xpt", getter_AddRefs(entries))) || - !entries) - { - // XXX We TRUST that this means there are no .xpt files. - return PR_TRUE; - } - - do - { - PRBool result = PR_FALSE; - int index = 0; - PRBool hasMore; - - if(NS_FAILED(entries->HasMoreElements(&hasMore))) - return PR_FALSE; - if(!hasMore) - break; - - nsCOMPtr sup; - if(NS_FAILED(entries->GetNext(getter_AddRefs(sup))) ||!sup) - return PR_FALSE; - - nsCOMPtr entry = do_QueryInterface(sup); - if(!entry) - return PR_FALSE; - - // we have a zip entry! - - char* itemName = nsnull; - - if(NS_FAILED(entry->GetName(&itemName)) || !itemName) - return PR_FALSE; - - XPTHeader* header = - ReadXPTFileFromOpenZip(zip, entry, itemName, aWorkingSet); - - if(header) - result = sink->FoundEntry(itemName, index++, header, aWorkingSet); - nsMemory::Free(itemName); - - if(!header) - return PR_FALSE; - - if(result != PR_TRUE) - return result; - } while(1); - - return PR_TRUE; -} - -// static -XPTHeader* -xptiZipLoader::ReadXPTFileFromZip(nsILocalFile* file, - const char* entryName, - xptiWorkingSet* aWorkingSet) -{ - nsCOMPtr zip = dont_AddRef(GetZipReader(file)); - if(!zip) - return nsnull; - - nsCOMPtr entry; - if(NS_FAILED(zip->GetEntry(entryName, getter_AddRefs(entry))) || !entry) - { - return nsnull; - } - - return ReadXPTFileFromOpenZip(zip, entry, entryName, aWorkingSet); -} - -// static -XPTHeader* -xptiZipLoader::ReadXPTFileFromOpenZip(nsIZipReader* zip, - nsIZipEntry* entry, - const char* entryName, - xptiWorkingSet* aWorkingSet) -{ - NS_ASSERTION(zip, "loser!"); - NS_ASSERTION(entry, "loser!"); - NS_ASSERTION(entryName, "loser!"); - - XPTHeader *header = nsnull; - char *whole = nsnull; - XPTState *state = nsnull; XPTCursor cursor; - PRUint32 flen; PRUint32 totalRead = 0; + XPTState *state = nsnull; + XPTHeader *header = nsnull; - if(NS_FAILED(entry->GetRealSize(&flen)) || !flen) - { - return nsnull; - } - - nsCOMPtr stream; - if(NS_FAILED(zip->GetInputStream(entryName, getter_AddRefs(stream))) || - !stream) - { - return nsnull; - } - - whole = new char[flen]; + PRUint32 flen; + stream->Available(&flen); + + char *whole = new char[flen]; if (!whole) { return nsnull; @@ -257,4 +111,3 @@ xptiZipLoader::ReadXPTFileFromOpenZip(nsIZipReader* zip, return header; } -#endif /* XPTI_HAS_ZIP_SUPPORT */ diff --git a/xpcom/reflect/xptinfo/src/xptiprivate.h b/xpcom/reflect/xptinfo/src/xptiprivate.h index 398255c6dfd..b8cb7a7a104 100644 --- a/xpcom/reflect/xptinfo/src/xptiprivate.h +++ b/xpcom/reflect/xptinfo/src/xptiprivate.h @@ -42,10 +42,6 @@ #ifndef xptiprivate_h___ #define xptiprivate_h___ -#ifndef XPCOM_STANDALONE -#define XPTI_HAS_ZIP_SUPPORT 1 -#endif /* XPCOM_STANDALONE */ - #include "nscore.h" #include "nsISupports.h" @@ -57,6 +53,7 @@ #include "nsIInterfaceInfo.h" #include "nsIInterfaceInfoManager.h" #include "xptinfo.h" +#include "nsIXPTLoader.h" #include "nsIServiceManager.h" #include "nsIFile.h" @@ -77,10 +74,6 @@ #include "nsXPIDLString.h" -#ifdef XPTI_HAS_ZIP_SUPPORT -#include "nsIZipReader.h" -#endif /* XPTI_HAS_ZIP_SUPPORT */ - #include "nsIInputStream.h" #include "nsAutoLock.h" @@ -788,51 +781,35 @@ private: /***************************************************************************/ -class xptiEntrySink +class xptiZipLoaderSink : public nsIXPTLoaderSink { public: + xptiZipLoaderSink(xptiInterfaceInfoManager* aMgr, + xptiWorkingSet* aWorkingSet) : + mManager(aMgr), + mWorkingSet(aWorkingSet) { NS_INIT_REFCNT(); } + virtual ~xptiZipLoaderSink() {}; + + NS_DECL_ISUPPORTS + NS_DECL_NSIXPTLOADERSINK + +private: + xptiInterfaceInfoManager* mManager; + xptiWorkingSet* mWorkingSet; - virtual PRBool - FoundEntry(const char* entryName, - int index, - XPTHeader* header, - xptiWorkingSet* aWorkingSet) = 0; }; -#ifdef XPTI_HAS_ZIP_SUPPORT - class xptiZipLoader { public: xptiZipLoader(); // not implemented - static PRBool - EnumerateZipEntries(nsILocalFile* file, - xptiEntrySink* sink, - xptiWorkingSet* aWorkingSet); + static XPTHeader* + ReadXPTFileFromInputStream(nsIInputStream *stream, + xptiWorkingSet* aWorkingSet); - static XPTHeader* - ReadXPTFileFromZip(nsILocalFile* file, - const char* entryName, - xptiWorkingSet* aWorkingSet); - - static void - Shutdown(); - -private: - static XPTHeader* - ReadXPTFileFromOpenZip(nsIZipReader* zip, - nsIZipEntry* entry, - const char* entryName, - xptiWorkingSet* aWorkingSet); - - static nsIZipReader* - GetZipReader(nsILocalFile* file); - - static nsCOMPtr gCache; }; -#endif /* XPTI_HAS_ZIP_SUPPORT */ /***************************************************************************/ @@ -880,19 +857,18 @@ private: /***************************************************************************/ class xptiInterfaceInfoManager - : public nsIInterfaceInfoSuperManager, - public xptiEntrySink + : public nsIInterfaceInfoSuperManager { NS_DECL_ISUPPORTS NS_DECL_NSIINTERFACEINFOMANAGER NS_DECL_NSIINTERFACEINFOSUPERMANAGER - // implement xptiEntrySink + // helper PRBool - FoundEntry(const char* entryName, - int index, - XPTHeader* header, - xptiWorkingSet* aWorkingSet); + FoundZipEntry(const char* entryName, + int index, + XPTHeader* header, + xptiWorkingSet* aWorkingSet); public: virtual ~xptiInterfaceInfoManager();