Bug 568691 - Fix MOZ_OMNIJAR registration, r=mwu

This commit is contained in:
Benjamin Smedberg
2010-07-02 09:53:19 -04:00
parent 58e60422d9
commit c3f5b450d3
16 changed files with 400 additions and 196 deletions

View File

@@ -61,6 +61,8 @@
#include "nsIResProtocolHandler.h"
#include "nsIXPConnect.h"
#include "mozilla/Omnijar.h"
class nsIDOMWindowInternal;
class nsIURL;
@@ -137,7 +139,17 @@ public:
ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile)
: mType(aType)
, mFile(aFile)
, mPath(NULL)
{ }
#ifdef MOZ_OMNIJAR
ManifestProcessingContext(NSLocationType aType, const char* aPath)
: mType(aType)
, mFile(mozilla::OmnijarPath())
, mPath(aPath)
{ }
#endif
~ManifestProcessingContext()
{ }
@@ -147,7 +159,8 @@ public:
already_AddRefed<nsIURI> ResolveURI(const char* uri);
NSLocationType mType;
nsCOMPtr<nsILocalFile> mFile;
nsILocalFile* mFile;
const char* mPath;
nsCOMPtr<nsIURI> mManifestURI;
nsCOMPtr<nsIXPConnect> mXPConnect;
};

View File

@@ -413,48 +413,6 @@ nsChromeRegistryChrome::Observe(nsISupports *aSubject, const char *aTopic,
return rv;
}
#ifdef MOZ_OMNIJAR
nsresult
nsChromeRegistryChrome::CheckOmnijarChrome()
{
nsresult rv;
nsZipArchive* jarReader = mozilla::OmnijarReader();
// just proceed normally if there is no omnijar
if (!jarReader)
return NS_OK;
nsZipItem* manifest = jarReader->GetItem("chrome/chrome.manifest");
NS_ENSURE_TRUE(manifest, NS_ERROR_NOT_AVAILABLE);
nsCAutoString omniJarSpec;
rv = NS_GetURLSpecFromActualFile(mozilla::OmnijarPath(), omniJarSpec);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 len = manifest->RealSize();
nsAutoArrayPtr<PRUint8> outbuf(new PRUint8[len]);
NS_ENSURE_TRUE(outbuf, NS_ERROR_OUT_OF_MEMORY);
nsZipCursor cursor(manifest, jarReader, outbuf, len);
PRUint32 readlen;
PRUint8* buf = cursor.Read(&readlen);
NS_ENSURE_TRUE(buf, NS_ERROR_FILE_CORRUPTED);
nsAutoString jarString(NS_LITERAL_STRING("jar:"));
AppendUTF8toUTF16(omniJarSpec, jarString);
jarString += NS_LITERAL_STRING("!/chrome/chrome.manifest");
nsCOMPtr<nsIURI> manifestURI;
rv = NS_NewURI(getter_AddRefs(manifestURI), jarString);
NS_ENSURE_SUCCESS(rv, rv);
rv = ProcessManifestBuffer((char *)buf, readlen, manifestURI, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
return rv;
}
#endif /* MOZ_OMNIJAR */
NS_IMETHODIMP
nsChromeRegistryChrome::CheckForNewChrome()
{
@@ -830,8 +788,25 @@ nsChromeRegistry::ManifestProcessingContext::GetManifestURI()
return NULL;
}
#ifdef MOZ_OMNIJAR
if (mPath) {
nsCOMPtr<nsIURI> fileURI;
io->NewFileURI(mFile, getter_AddRefs(fileURI));
nsCAutoString spec;
fileURI->GetSpec(spec);
spec.Insert(NS_LITERAL_CSTRING("jar:"), 0);
spec.AppendLiteral("!/");
spec.Append(mPath);
NS_NewURI(getter_AddRefs(mManifestURI), spec, NULL, NULL, io);
}
else
#endif
{
io->NewFileURI(mFile, getter_AddRefs(mManifestURI));
}
}
return mManifestURI;
}

View File

@@ -38,18 +38,18 @@
* ***** END LICENSE BLOCK ***** */
#include "nsXPTZipLoader.h"
#include "nsManifestZIPLoader.h"
#include "nsJAR.h"
#include "nsString.h"
#include "nsStringEnumerator.h"
nsXPTZipLoader::nsXPTZipLoader() {
nsManifestZIPLoader::nsManifestZIPLoader() {
}
NS_IMPL_ISUPPORTS1(nsXPTZipLoader, nsIXPTLoader)
NS_IMPL_ISUPPORTS1(nsManifestZIPLoader, nsIManifestLoader)
nsresult
nsXPTZipLoader::LoadEntry(nsILocalFile* aFile,
nsManifestZIPLoader::LoadEntry(nsILocalFile* aFile,
const char* aName,
nsIInputStream** aResult)
{
@@ -61,9 +61,35 @@ nsXPTZipLoader::LoadEntry(nsILocalFile* aFile,
return zip->GetInputStream(aName, aResult);
}
static void
EnumerateEntriesForPattern(nsIZipReader* zip, const char* pattern,
nsIManifestLoaderSink* aSink)
{
nsCOMPtr<nsIUTF8StringEnumerator> entries;
if (NS_FAILED(zip->FindEntries(pattern, getter_AddRefs(entries))) ||
!entries) {
return;
}
PRBool hasMore;
int index = 0;
while (NS_SUCCEEDED(entries->HasMore(&hasMore)) && hasMore) {
nsCAutoString itemName;
if (NS_FAILED(entries->GetNext(itemName)))
return;
nsCOMPtr<nsIInputStream> stream;
if (NS_FAILED(zip->GetInputStream(itemName.get(), getter_AddRefs(stream))))
continue;
// ignore the result
aSink->FoundEntry(itemName.get(), index++, stream);
}
}
nsresult
nsXPTZipLoader::EnumerateEntries(nsILocalFile* aFile,
nsIXPTLoaderSink* aSink)
nsManifestZIPLoader::EnumerateEntries(nsILocalFile* aFile,
nsIManifestLoaderSink* aSink)
{
nsCOMPtr<nsIZipReader> zip = dont_AddRef(GetZipReader(aFile));
@@ -72,33 +98,14 @@ nsXPTZipLoader::EnumerateEntries(nsILocalFile* aFile,
return NS_OK;
}
nsCOMPtr<nsIUTF8StringEnumerator> entries;
if (NS_FAILED(zip->FindEntries("*.xpt", getter_AddRefs(entries))) ||
!entries) {
// no problem, just no .xpt files in this archive
return NS_OK;
}
PRBool hasMore;
int index = 0;
while (NS_SUCCEEDED(entries->HasMore(&hasMore)) && hasMore) {
nsCAutoString itemName;
if (NS_FAILED(entries->GetNext(itemName)))
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIInputStream> stream;
if (NS_FAILED(zip->GetInputStream(itemName.get(), getter_AddRefs(stream))))
return NS_ERROR_FAILURE;
// ignore the result
aSink->FoundEntry(itemName.get(), index++, stream);
}
EnumerateEntriesForPattern(zip, "components/*.manifest$", aSink);
EnumerateEntriesForPattern(zip, "chrome/*.manifest$", aSink);
return NS_OK;
}
already_AddRefed<nsIZipReader>
nsXPTZipLoader::GetZipReader(nsILocalFile* file)
nsManifestZIPLoader::GetZipReader(nsILocalFile* file)
{
NS_ASSERTION(file, "bad file");

View File

@@ -38,18 +38,18 @@
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.h"
#include "nsIXPTLoader.h"
#include "nsIManifestLoader.h"
#include "nsIZipReader.h"
class nsXPTZipLoader : public nsIXPTLoader
class nsManifestZIPLoader : public nsIManifestLoader
{
public:
nsXPTZipLoader();
virtual ~nsXPTZipLoader() {}
nsManifestZIPLoader();
virtual ~nsManifestZIPLoader() {}
NS_DECL_ISUPPORTS
NS_DECL_NSIXPTLOADER
NS_DECL_NSIMANIFESTLOADER
private:
already_AddRefed<nsIZipReader> GetZipReader(nsILocalFile* aFile);

View File

@@ -40,7 +40,7 @@ MODULES_LIBJAR_LCPPSRCS = \
nsJARInputStream.cpp \
nsJAR.cpp \
nsJARFactory.cpp \
nsXPTZipLoader.cpp \
nsManifestZIPLoader.cpp \
nsJARProtocolHandler.cpp \
nsJARChannel.cpp \
nsJARURI.cpp \
@@ -49,7 +49,7 @@ MODULES_LIBJAR_LCPPSRCS = \
MODULES_LIBJAR_LEXPORTS = \
zipstruct.h \
nsZipArchive.h \
nsXPTZipLoader.h \
nsManifestZIPLoader.h \
$(NULL)
MODULES_LIBJAR_LXPIDLSRCS = \

View File

@@ -76,6 +76,7 @@ SDK_XPIDLSRCS = \
nsIServiceManager.idl \
nsIComponentManager.idl \
nsICategoryManager.idl \
nsIManifestLoader.idl \
$(NULL)
LOCAL_INCLUDES = \

View File

@@ -162,7 +162,8 @@ void LogMessage(const char* aMsg, ...)
console->LogMessage(error);
}
void LogMessageWithContext(nsILocalFile* aFile, PRUint32 aLineNumber, const char* aMsg, ...)
void LogMessageWithContext(nsILocalFile* aFile, const char* aPath,
PRUint32 aLineNumber, const char* aMsg, ...)
{
va_list args;
va_start(args, aMsg);
@@ -173,6 +174,10 @@ void LogMessageWithContext(nsILocalFile* aFile, PRUint32 aLineNumber, const char
nsString file;
aFile->GetPath(file);
if (aPath) {
file.Append(':');
file.Append(NS_ConvertUTF8toUTF16(aPath));
}
nsCOMPtr<nsIScriptError> error =
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
@@ -398,15 +403,14 @@ struct CachedDirective
} // anonymous namespace
void
ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf,
bool aChromeOnly)
static void
ParseManifestCommon(NSLocationType aType, nsILocalFile* aFile,
nsComponentManagerImpl::ManifestProcessingContext& mgrcx,
nsChromeRegistry::ManifestProcessingContext& chromecx,
const char* aPath, char* buf, bool aChromeOnly)
{
nsresult rv;
nsComponentManagerImpl::ManifestProcessingContext mgrcx(aType, aFile);
nsChromeRegistry::ManifestProcessingContext chromecx(aType, aFile);
NS_NAMED_LITERAL_STRING(kPlatform, "platform");
NS_NAMED_LITERAL_STRING(kContentAccessible, "contentaccessible");
NS_NAMED_LITERAL_STRING(kApplication, "application");
@@ -515,11 +519,15 @@ ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf,
}
}
if (!directive) {
LogMessageWithContext(aFile, line, "Ignoring unrecognized chrome manifest directive '%s'.", token);
LogMessageWithContext(aFile, aPath, line,
"Ignoring unrecognized chrome manifest directive '%s'.",
token);
continue;
}
if (directive->componentonly && NS_COMPONENT_LOCATION != aType) {
LogMessageWithContext(aFile, line, "Skin manifest not allowed to use '%s' directive.", token);
LogMessageWithContext(aFile, aPath, line,
"Skin manifest not allowed to use '%s' directive.",
token);
continue;
}
@@ -529,7 +537,9 @@ ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf,
argv[i] = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
if (!argv[directive->argc - 1]) {
LogMessageWithContext(aFile, line, "Not enough arguments for chrome manifest directive '%s', expected %i.", token, directive->argc);
LogMessageWithContext(aFile, aPath, line,
"Not enough arguments for chrome manifest directive '%s', expected %i.",
token, directive->argc);
continue;
}
@@ -558,7 +568,9 @@ ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf,
CheckFlag(kContentAccessible, wtoken, contentAccessible)))
continue;
LogMessageWithContext(aFile, line, "Unrecognized chrome manifest modifier '%s'.", token);
LogMessageWithContext(aFile, aPath, line,
"Unrecognized chrome manifest modifier '%s'.",
token);
ok = false;
}
@@ -580,7 +592,8 @@ ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf,
nsCOMPtr<nsIChromeRegistry> cr =
mozilla::services::GetChromeRegistryService();
if (!nsChromeRegistry::gChromeRegistry) {
LogMessageWithContext(aFile, line, "Chrome registry isn't available yet.");
LogMessageWithContext(aFile, aPath, line,
"Chrome registry isn't available yet.");
continue;
}
}
@@ -607,3 +620,24 @@ ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf,
(mgrcx, d.lineno, d.argv);
}
}
void
ParseManifest(NSLocationType type, nsILocalFile* file,
char* buf, bool aChromeOnly)
{
nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, file);
nsChromeRegistry::ManifestProcessingContext chromecx(type, file);
ParseManifestCommon(type, file, mgrcx, chromecx, NULL, buf, aChromeOnly);
}
#ifdef MOZ_OMNIJAR
void
ParseManifest(NSLocationType type, const char* jarPath,
char* buf, bool aChromeOnly)
{
nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, jarPath);
nsChromeRegistry::ManifestProcessingContext chromecx(type, jarPath);
ParseManifestCommon(type, mozilla::OmnijarPath(), mgrcx, chromecx, jarPath,
buf, aChromeOnly);
}
#endif

View File

@@ -43,11 +43,17 @@
class nsILocalFile;
void ParseManifest(NSLocationType type, nsILocalFile* file, char* buf,
bool aChromeOnly);
void ParseManifest(NSLocationType type, nsILocalFile* file,
char* buf, bool aChromeOnly);
#ifdef MOZ_OMNIJAR
void ParseManifest(NSLocationType type, const char* jarPath,
char* buf, bool aChromeOnly);
#endif
void LogMessage(const char* aMsg, ...);
void LogMessageWithContext(nsILocalFile* aFile, PRUint32 aLineNumber, const char* aMsg, ...);
void LogMessageWithContext(nsILocalFile* aFile, const char* aPath,
PRUint32 aLineNumber, const char* aMsg, ...);
#endif // ManifestParser_h

View File

@@ -61,10 +61,10 @@ public:
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_MODULELOADER_PSEUDO_IID)
/**
* Return the module for a specified file. The loader should cache
* the module and return the same module in future calls. The Module
* should either be statically or permanently allocated, it will not
* be freed.
* Return the module for a specified file. The caller should cache
* the module: the implementer should not expect for the same file
* to be loaded multiple times. The Module object should either be
* statically or permanently allocated; it will not be freed.
*/
virtual const Module* LoadModule(nsILocalFile* aFile) = 0;

View File

@@ -107,7 +107,7 @@
#endif
#ifdef MOZ_OMNIJAR
#include "nsIZipReader.h"
#include "nsManifestZIPLoader.h"
#include "mozilla/Omnijar.h"
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
#endif
@@ -352,6 +352,9 @@ nsresult nsComponentManagerImpl::Init()
mContractIDs.Init(CONTRACTID_HASHTABLE_INITIAL_SIZE);
mLoaderMap.Init();
mKnownFileModules.Init();
#ifdef MOZ_OMNIJAR
mKnownJARModules.Init();
#endif
mMon = nsAutoMonitor::NewMonitor("nsComponentManagerImpl");
if (mMon == nsnull)
@@ -401,6 +404,10 @@ nsresult nsComponentManagerImpl::Init()
for (PRUint32 i = 0; i < sStaticModules->Length(); ++i)
RegisterModule((*sStaticModules)[i], NULL);
#ifdef MOZ_OMNIJAR
RegisterOmnijar(false);
#endif
for (PRUint32 i = 0; i < sModuleLocations->Length(); ++i) {
ComponentLocation& l = sModuleLocations->ElementAt(i);
RegisterLocation(l.type, l.location, false);
@@ -502,18 +509,22 @@ nsComponentManagerImpl::RegisterContractID(const mozilla::Module::ContractIDEntr
mContractIDs.Put(nsDependentCString(aEntry->contractid), f);
}
static void
CutExtension(nsCString& path)
{
PRInt32 dotPos = path.RFindChar('.');
if (kNotFound == dotPos)
path.Truncate();
else
path.Cut(0, dotPos + 1);
}
static nsCString
GetExtension(nsILocalFile* file)
{
nsCString extension;
file->GetNativePath(extension);
PRInt32 dotPos = extension.RFindChar('.');
if (kNotFound == dotPos)
extension.Truncate();
else
extension.Cut(0, dotPos + 1);
CutExtension(extension);
return extension;
}
@@ -535,6 +546,57 @@ nsComponentManagerImpl::RegisterLocation(NSLocationType aType,
RegisterManifestFile(aType, manifests[i], aChromeOnly);
}
#ifdef MOZ_OMNIJAR
void
nsComponentManagerImpl::RegisterOmnijar(bool aChromeOnly)
{
nsCOMPtr<nsIManifestLoader> loader = new nsManifestZIPLoader();
mManifestLoader = loader;
mRegisterJARChromeOnly = aChromeOnly;
loader->EnumerateEntries(mozilla::OmnijarPath(), this);
mManifestLoader = NULL;
}
NS_IMETHODIMP
nsComponentManagerImpl::FoundEntry(const char* aPath,
PRInt32 aIndex,
nsIInputStream* aStream)
{
NS_ASSERTION(mManifestLoader, "Not registering a JAR.");
PRUint32 flen;
aStream->Available(&flen);
nsAutoArrayPtr<char> whole(new char[flen + 1]);
if (!whole)
return NS_ERROR_OUT_OF_MEMORY;
for (PRUint32 totalRead = 0; totalRead < flen; ) {
PRUint32 avail;
PRUint32 read;
if (NS_FAILED(aStream->Available(&avail)))
return NS_ERROR_FAILURE;
if (avail > flen)
return NS_ERROR_FAILURE;
if (NS_FAILED(aStream->Read(whole + totalRead, avail, &read)))
return NS_ERROR_FAILURE;
totalRead += read;
}
whole[flen] = '\0';
ParseManifest(NS_COMPONENT_LOCATION, aPath, whole, mRegisterJARChromeOnly);
return NS_OK;
}
#endif // MOZ_OMNIJAR
void
nsComponentManagerImpl::GetManifestsInDirectory(nsILocalFile* aDirectory,
nsCOMArray<nsILocalFile>& aManifests)
@@ -628,6 +690,15 @@ TranslateSlashes(char* path)
void
nsComponentManagerImpl::ManifestBinaryComponent(ManifestProcessingContext& cx, int lineno, char *const * argv)
{
#ifdef MOZ_OMNIJAR
if (cx.mPath) {
NS_WARNING("Cannot load binary components from the omnijar.");
LogMessageWithContext(cx.mFile, cx.mPath, lineno,
"Cannot load binary components from the omnijar.");
return;
}
#endif
char* file = argv[0];
#ifdef TRANSLATE_SLASHES
@@ -651,6 +722,21 @@ nsComponentManagerImpl::ManifestBinaryComponent(ManifestProcessingContext& cx, i
RegisterModule(m, clfile);
}
#ifdef MOZ_OMNIJAR
static void
AppendFileToManifestPath(nsCString& path,
const char* file)
{
PRInt32 i = path.RFindChar('/');
if (kNotFound == i)
path.Truncate(0);
else
path.Truncate(i + 1);
path.Append(file);
}
#endif
void
nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& cx, int lineno, char *const * argv)
{
@@ -660,6 +746,25 @@ nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& cx, int lineno, c
TranslateSlashes(file);
#endif
#ifdef MOZ_OMNIJAR
if (cx.mPath) {
nsCAutoString manifest(cx.mPath);
AppendFileToManifestPath(manifest, file);
nsCOMPtr<nsIInputStream> stream;
nsresult rv = mManifestLoader->LoadEntry(cx.mFile, manifest.get(),
getter_AddRefs(stream));
if (NS_FAILED(rv)) {
NS_WARNING("Failed to load omnijar XPT file.");
return;
}
xptiInterfaceInfoManager::GetSingleton()
->RegisterInputStream(stream);
}
else
#endif
{
nsCOMPtr<nsIFile> cfile;
cx.mFile->GetParent(getter_AddRefs(cfile));
nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
@@ -671,7 +776,8 @@ nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& cx, int lineno, c
}
xptiInterfaceInfoManager::GetSingleton()
->RegisterFile(clfile, xptiInterfaceInfoManager::XPT);
->RegisterFile(clfile);
}
}
void
@@ -686,7 +792,8 @@ nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& cx, int lin
nsID cid;
if (!cid.Parse(id)) {
LogMessageWithContext(cx.mFile, lineno, "Malformed CID: '%s'.", id);
LogMessageWithContext(cx.mFile, cx.mPath, lineno,
"Malformed CID: '%s'.", id);
return;
}
@@ -702,12 +809,29 @@ nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& cx, int lin
else
existing = "<unknown module>";
LogMessageWithContext(cx.mFile, lineno, "Trying to re-register CID '%s' already registered by %s.",
LogMessageWithContext(cx.mFile, cx.mPath, lineno,
"Trying to re-register CID '%s' already registered by %s.",
idstr,
existing.get());
return;
}
KnownModule* km;
#ifdef MOZ_OMNIJAR
if (cx.mPath) {
nsCAutoString manifest(cx.mPath);
AppendFileToManifestPath(manifest, file);
km = mKnownJARModules.Get(manifest);
if (!km) {
km = new KnownModule(manifest);
mKnownJARModules.Put(manifest, km);
}
}
else
#endif
{
nsCOMPtr<nsIFile> cfile;
cx.mFile->GetParent(getter_AddRefs(cfile));
nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
@@ -719,11 +843,12 @@ nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& cx, int lin
}
nsCOMPtr<nsIHashable> h = do_QueryInterface(clfile);
KnownModule* km = mKnownFileModules.Get(h);
km = mKnownFileModules.Get(h);
if (!km) {
km = new KnownModule(clfile);
mKnownFileModules.Put(h, km);
}
}
void* place;
@@ -747,14 +872,16 @@ nsComponentManagerImpl::ManifestContract(ManifestProcessingContext& cx, int line
nsID cid;
if (!cid.Parse(id)) {
LogMessageWithContext(cx.mFile, lineno, "Malformed CID: '%s'.", id);
LogMessageWithContext(cx.mFile, cx.mPath, lineno,
"Malformed CID: '%s'.", id);
return;
}
nsAutoMonitor mon(mMon);
nsFactoryEntry* f = mFactories.Get(cid);
if (!f) {
LogMessageWithContext(cx.mFile, lineno, "Could not map contract ID '%s' to CID %s because no implementation of the CID is registered.",
LogMessageWithContext(cx.mFile, cx.mPath, lineno,
"Could not map contract ID '%s' to CID %s because no implementation of the CID is registered.",
contract, id);
return;
}
@@ -776,6 +903,10 @@ nsComponentManagerImpl::ManifestCategory(ManifestProcessingContext& cx, int line
void
nsComponentManagerImpl::RereadChromeManifests()
{
#ifdef MOZ_OMNIJAR
RegisterOmnijar(true);
#endif
for (PRUint32 i = 0; i < sModuleLocations->Length(); ++i) {
ComponentLocation& l = sModuleLocations->ElementAt(i);
RegisterLocation(l.type, l.location, true);
@@ -786,7 +917,17 @@ bool
nsComponentManagerImpl::KnownModule::EnsureLoader()
{
if (!mLoader) {
nsCString extension = GetExtension(mFile);
nsCString extension;
#if MOZ_OMNIJAR
if (!mPath.IsEmpty()) {
extension = mPath;
CutExtension(extension);
}
else
#endif
{
extension = GetExtension(mFile);
}
mLoader = nsComponentManagerImpl::gComponentManager->LoaderForExtension(extension);
}
@@ -801,7 +942,14 @@ nsComponentManagerImpl::KnownModule::Load()
if (!mModule) {
if (!EnsureLoader())
return false;
#ifdef MOZ_OMNIJAR
if (!mPath.IsEmpty())
mModule = mLoader->LoadModuleFromJAR(mozilla::OmnijarPath(), mPath);
else
#endif
mModule = mLoader->LoadModule(mFile);
if (!mModule) {
mFailed = true;
return false;
@@ -824,6 +972,13 @@ nsCString
nsComponentManagerImpl::KnownModule::Description() const
{
nsCString s;
#ifdef MOZ_OMNIJAR
if (!mPath.IsEmpty()) {
s.AssignLiteral("omnijar:");
s.Append(mPath);
}
else
#endif
if (mFile)
mFile->GetNativePath(s);
else
@@ -846,6 +1001,9 @@ nsresult nsComponentManagerImpl::Shutdown(void)
mContractIDs.Clear();
mFactories.Clear(); // XXX release the objects, don't just clear
mLoaderMap.Clear();
#ifdef MOZ_OMNIJAR
mKnownJARModules.Clear();
#endif
mKnownFileModules.Clear();
mKnownStaticModules.Clear();

View File

@@ -66,6 +66,11 @@
#include "nsClassHashtable.h"
#include "nsTArray.h"
#ifdef MOZ_OMNIJAR
#include "mozilla/Omnijar.h"
#include "nsIManifestLoader.h"
#endif
struct nsFactoryEntry;
class nsIServiceManager;
struct PRThread;
@@ -108,17 +113,23 @@ struct nsLoaderdata {
};
class nsComponentManagerImpl
: public nsIComponentManager,
public nsIServiceManager,
public nsSupportsWeakReference,
public nsIComponentRegistrar,
public nsIInterfaceRequestor
: public nsIComponentManager
, public nsIServiceManager
, public nsSupportsWeakReference
, public nsIComponentRegistrar
, public nsIInterfaceRequestor
#ifdef MOZ_OMNIJAR
, public nsIManifestLoaderSink
#endif
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICOMPONENTMANAGER
NS_DECL_NSICOMPONENTREGISTRAR
#ifdef MOZ_OMNIJAR
NS_DECL_NSIMANIFESTLOADERSINK
#endif
static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
@@ -192,6 +203,17 @@ public:
, mFailed(false)
{ }
#ifdef MOZ_OMNIJAR
KnownModule(const nsACString& aPath)
: mModule(NULL)
, mFile(NULL)
, mPath(aPath)
, mLoader(NULL)
, mLoaded(false)
, mFailed(false)
{ }
#endif
~KnownModule()
{
if (mLoaded && mModule->unloadProc)
@@ -215,15 +237,21 @@ public:
private:
const mozilla::Module* mModule;
nsCOMPtr<nsILocalFile> mFile;
#ifdef MOZ_OMNIJAR
nsCString mPath;
#endif
nsCOMPtr<mozilla::ModuleLoader> mLoader;
bool mLoaded;
bool mFailed;
};
// The KnownModule is kept alive by these members, it is referenced by pointer
// from the factory entries.
// The KnownModule is kept alive by these members, it is
// referenced by pointer from the factory entries.
nsTArray< nsAutoPtr<KnownModule> > mKnownStaticModules;
nsClassHashtable<nsHashableHashKey, KnownModule> mKnownFileModules;
#ifdef MOZ_OMNIJAR
nsClassHashtable<nsCStringHashKey, KnownModule> mKnownJARModules;
#endif
void RegisterModule(const mozilla::Module* aModule,
nsILocalFile* aFile);
@@ -234,6 +262,10 @@ public:
void RegisterLocation(NSLocationType aType, nsILocalFile* aLocation,
bool aChromeOnly);
#ifdef MOZ_OMNIJAR
void RegisterOmnijar(bool aChromeOnly);
#endif
void GetManifestsInDirectory(nsILocalFile* aDirectory,
nsCOMArray<nsILocalFile>& aManifests);
@@ -245,11 +277,22 @@ public:
ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile)
: mType(aType)
, mFile(aFile)
, mPath(NULL)
{ }
#ifdef MOZ_OMNIJAR
ManifestProcessingContext(NSLocationType aType, const char* aPath)
: mType(aType)
, mFile(mozilla::OmnijarPath())
, mPath(aPath)
{ }
#endif
~ManifestProcessingContext() { }
NSLocationType mType;
nsCOMPtr<nsILocalFile> mFile;
nsILocalFile* mFile;
const char* mPath;
};
void ManifestBinaryComponent(ManifestProcessingContext& cx, int lineno, char *const * argv);
@@ -286,6 +329,11 @@ public:
private:
~nsComponentManagerImpl();
#ifdef MOZ_OMNIJAR
nsIManifestLoader* mManifestLoader;
bool mRegisterJARChromeOnly;
#endif
};

View File

@@ -47,10 +47,11 @@
* an XPT archive of some kind
*/
[scriptable, uuid(6E48C500-8682-4730-ADD6-7DB693B9E7BA)]
interface nsIXPTLoaderSink : nsISupports {
interface nsIManifestLoaderSink : nsISupports
{
/**
* called by the loader for each entry in the archive
* Called by the loader for each components / *.manifest and
* chrome / *.manifest in the archive.
* @param itemName the name of this particular item in the archive
* @param index the index of the item inthe archive
* @param stream contains the contents of the xpt file
@@ -65,7 +66,7 @@ interface nsIXPTLoaderSink : nsISupports {
* stream which will be consumed by the interface loader.
*/
[scriptable, uuid(368A15D9-17A9-4c2b-AC3D-A35B3A22B876)]
interface nsIXPTLoader : nsISupports {
interface nsIManifestLoader : nsISupports {
/**
* enumerate entries in the given archive
* for each entry found, the loader will call the sink's
@@ -76,7 +77,7 @@ interface nsIXPTLoader : nsISupports {
* in the file
*/
void enumerateEntries(in nsILocalFile file,
in nsIXPTLoaderSink sink );
in nsIManifestLoaderSink sink );
/**
* Load a specific entry from the archive
@@ -88,13 +89,3 @@ interface nsIXPTLoader : nsISupports {
nsIInputStream loadEntry(in nsILocalFile file,
in string name);
};
%{C++
// the first part of the contractID for any loader
// append the type of loader that you need, such as "zip"
#define NS_XPTLOADER_CONTRACTID_PREFIX \
"@mozilla.org/xptinfo/loader;1&type="
%}

View File

@@ -55,7 +55,6 @@ EXPORTS = \
XPIDLSRCS = \
nsIInterfaceInfo.idl \
nsIInterfaceInfoManager.idl \
nsIXPTLoader.idl \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))

View File

@@ -115,9 +115,6 @@ xptiInterfaceEntry::ResolveLocked()
if(resolvedState == RESOLVE_FAILED)
return PR_FALSE;
xptiInterfaceInfoManager* mgr = xptiInterfaceInfoManager::GetSingleton();
NS_ASSERTION(GetResolveState() == PARTIALLY_RESOLVED, "bad state!");
// Finish out resolution by finding parent and Resolving it so

View File

@@ -45,11 +45,8 @@
#include "nsISupportsArray.h"
#include "nsArrayEnumerator.h"
#include "mozilla/FunctionTimer.h"
#include "nsXPTZipLoader.h"
#include "nsDirectoryService.h"
#define NS_ZIPLOADER_CONTRACTID NS_XPTLOADER_CONTRACTID_PREFIX "zip"
NS_IMPL_THREADSAFE_ISUPPORTS2(xptiInterfaceInfoManager,
nsIInterfaceInfoManager,
nsIInterfaceInfoSuperManager)
@@ -225,31 +222,13 @@ xptiInterfaceInfoManager::ReadXPTFileFromInputStream(nsIInputStream *stream)
}
void
xptiInterfaceInfoManager::RegisterFile(nsILocalFile* aFile, Type aType)
xptiInterfaceInfoManager::RegisterFile(nsILocalFile* aFile)
{
switch (aType) {
case XPT: {
XPTHeader* header = ReadXPTFile(aFile);
if (!header)
return;
RegisterXPTHeader(header);
break;
}
case ZIP: {
#ifndef MOZ_ENABLE_LIBXUL
NS_WARNING("Trying to register XPTs in a JAR in a non-libxul build");
#else
nsCOMPtr<nsIXPTLoader> loader = new nsXPTZipLoader();
loader->EnumerateEntries(aFile, this);
#endif
break;
}
default:
NS_ERROR("Unexpected enumeration value");
}
}
void
@@ -266,13 +245,12 @@ xptiInterfaceInfoManager::RegisterXPTHeader(XPTHeader* aHeader)
VerifyAndAddEntryIfNew(aHeader->interface_directory + k, k, typelib);
}
NS_IMETHODIMP
xptiInterfaceInfoManager::FoundEntry(const char* entryName, PRInt32 index, nsIInputStream* aStream)
void
xptiInterfaceInfoManager::RegisterInputStream(nsIInputStream* aStream)
{
XPTHeader* header = ReadXPTFileFromInputStream(aStream);
if (header)
RegisterXPTHeader(header);
return NS_OK;
}
void

View File

@@ -54,7 +54,6 @@
#include "nsIInterfaceInfo.h"
#include "nsIInterfaceInfoManager.h"
#include "xptinfo.h"
#include "nsIXPTLoader.h"
#include "nsIServiceManager.h"
#include "nsILocalFile.h"
@@ -428,19 +427,17 @@ private:
class xptiInterfaceInfoManager
: public nsIInterfaceInfoSuperManager
, public nsIXPTLoaderSink
{
NS_DECL_ISUPPORTS
NS_DECL_NSIINTERFACEINFOMANAGER
NS_DECL_NSIINTERFACEINFOSUPERMANAGER
NS_DECL_NSIXPTLOADERSINK
public:
static xptiInterfaceInfoManager* GetSingleton();
static void FreeInterfaceInfoManager();
enum Type { XPT = 0, ZIP = 1 };
void RegisterFile(nsILocalFile* aFile, Type type);
void RegisterFile(nsILocalFile* aFile);
void RegisterInputStream(nsIInputStream* aStream);
xptiWorkingSet* GetWorkingSet() {return &mWorkingSet;}