Bug 695843 part 9 - Use FileLocations in the component manager. r=bsmedberg

This commit is contained in:
Mike Hommey 2011-11-08 18:10:51 +01:00
parent 96e4d7b9da
commit 9b0673934e
13 changed files with 181 additions and 638 deletions

View File

@ -62,6 +62,7 @@
#include "nsIXPConnect.h"
#include "mozilla/Omnijar.h"
#include "mozilla/FileLocation.h"
class nsIDOMWindow;
class nsIURL;
@ -139,16 +140,9 @@ public:
struct ManifestProcessingContext
{
ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile)
ManifestProcessingContext(NSLocationType aType, mozilla::FileLocation &aFile)
: mType(aType)
, mFile(aFile)
, mPath(NULL)
{ }
ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile, const char* aPath)
: mType(aType)
, mFile(aFile)
, mPath(aPath)
{ }
~ManifestProcessingContext()
@ -160,8 +154,7 @@ public:
already_AddRefed<nsIURI> ResolveURI(const char* uri);
NSLocationType mType;
nsILocalFile* mFile;
const char* mPath;
mozilla::FileLocation mFile;
nsCOMPtr<nsIURI> mManifestURI;
nsCOMPtr<nsIXPConnect> mXPConnect;
};

View File

@ -788,27 +788,9 @@ nsIURI*
nsChromeRegistry::ManifestProcessingContext::GetManifestURI()
{
if (!mManifestURI) {
nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
if (!io) {
NS_WARNING("No IO service trying to process chrome manifests");
return NULL;
}
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 {
io->NewFileURI(mFile, getter_AddRefs(mManifestURI));
}
nsCString uri;
mFile.GetURIString(uri);
NS_NewURI(getter_AddRefs(mManifestURI), uri);
}
return mManifestURI;
}

View File

@ -98,6 +98,7 @@
#include "mozilla/FunctionTimer.h"
using namespace mozilla;
using namespace mozilla::scache;
static const char kJSRuntimeServiceContractID[] = "@mozilla.org/js/xpc/RuntimeService;1";
@ -486,56 +487,21 @@ mozJSComponentLoader::ReallyInit()
}
const mozilla::Module*
mozJSComponentLoader::LoadModule(nsILocalFile* aComponentFile)
mozJSComponentLoader::LoadModule(FileLocation &aFile)
{
nsCOMPtr<nsIURI> uri;
nsCAutoString spec;
NS_GetURLSpecFromActualFile(aComponentFile, spec);
nsCOMPtr<nsILocalFile> file = aFile.GetBaseFile();
nsCString spec;
aFile.GetURIString(spec);
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri), spec);
if (NS_FAILED(rv))
return NULL;
return LoadModuleImpl(aComponentFile,
spec,
uri);
}
const mozilla::Module*
mozJSComponentLoader::LoadModuleFromJAR(nsILocalFile *aJarFile,
const nsACString &aComponentPath)
{
nsresult rv;
nsCAutoString fullSpec, fileSpec;
NS_GetURLSpecFromActualFile(aJarFile, fileSpec);
fullSpec = "jar:";
fullSpec += fileSpec;
fullSpec += "!/";
fullSpec += aComponentPath;
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), fullSpec);
if (NS_FAILED(rv))
return NULL;
return LoadModuleImpl(aJarFile,
fullSpec,
uri);
}
const mozilla::Module*
mozJSComponentLoader::LoadModuleImpl(nsILocalFile* aSourceFile,
nsACString &aKey,
nsIURI* aComponentURI)
{
nsresult rv;
#ifdef NS_FUNCTION_TIMER
nsCAutoString spec__("N/A");
aComponentURI->GetSpec(spec__);
NS_TIME_FUNCTION_FMT("%s (line %d) (file: %s)", MOZ_FUNCTION_NAME,
__LINE__, spec__.get());
__LINE__, spec.get());
#endif
if (!mInitialized) {
@ -545,14 +511,14 @@ mozJSComponentLoader::LoadModuleImpl(nsILocalFile* aSourceFile,
}
ModuleEntry* mod;
if (mModules.Get(aKey, &mod))
if (mModules.Get(spec, &mod))
return mod;
nsAutoPtr<ModuleEntry> entry(new ModuleEntry);
if (!entry)
return NULL;
rv = GlobalForLocation(aSourceFile, aComponentURI, &entry->global,
rv = GlobalForLocation(file, uri, &entry->global,
&entry->location, nsnull);
if (NS_FAILED(rv)) {
#ifdef DEBUG_shaver
@ -600,7 +566,7 @@ mozJSComponentLoader::LoadModuleImpl(nsILocalFile* aSourceFile,
JSObject* file_jsobj;
nsCOMPtr<nsIXPConnectJSObjectHolder> file_holder;
rv = xpc->WrapNative(cx, entry->global, aSourceFile,
rv = xpc->WrapNative(cx, entry->global, file,
NS_GET_IID(nsIFile),
getter_AddRefs(file_holder));
@ -624,7 +590,7 @@ mozJSComponentLoader::LoadModuleImpl(nsILocalFile* aSourceFile,
if (JS_TypeOfValue(cx, NSGetFactory_val) != JSTYPE_FUNCTION) {
nsCAutoString spec;
aComponentURI->GetSpec(spec);
uri->GetSpec(spec);
JS_ReportError(cx, "%s has NSGetFactory property that is not a function",
spec.get());
return NULL;
@ -648,7 +614,7 @@ mozJSComponentLoader::LoadModuleImpl(nsILocalFile* aSourceFile,
}
// Cache this module for later
if (!mModules.Put(aKey, entry))
if (!mModules.Put(spec, entry))
return NULL;
// The hash owns the ModuleEntry now, forget about it

View File

@ -79,9 +79,7 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
virtual ~mozJSComponentLoader();
// ModuleLoader
const mozilla::Module* LoadModule(nsILocalFile* aFile);
const mozilla::Module* LoadModuleFromJAR(nsILocalFile* aJARFile,
const nsACString& aPath);
const mozilla::Module* LoadModule(mozilla::FileLocation &aFile);
protected:
static mozJSComponentLoader* sSelf;
@ -89,10 +87,6 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
nsresult ReallyInit();
void UnloadModules();
const mozilla::Module* LoadModuleImpl(nsILocalFile* aSourceFile,
nsACString &aKey,
nsIURI* aComponentURI);
nsresult GlobalForLocation(nsILocalFile* aComponentFile,
nsIURI *aComponent,
JSObject **aGlobal,

View File

@ -174,7 +174,7 @@ void LogMessage(const char* aMsg, ...)
console->LogMessage(error);
}
void LogMessageWithContext(nsILocalFile* aFile, const char* aPath,
void LogMessageWithContext(FileLocation &aFile,
PRUint32 aLineNumber, const char* aMsg, ...)
{
va_list args;
@ -184,20 +184,15 @@ void LogMessageWithContext(nsILocalFile* aFile, const char* aPath,
if (!formatted)
return;
nsString file;
aFile->GetPath(file);
if (aPath) {
file.Append(':');
file.Append(NS_ConvertUTF8toUTF16(aPath));
}
nsCString file;
aFile.GetURIString(file);
nsCOMPtr<nsIScriptError> error =
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
if (!error) {
// This can happen early in component registration. Fall back to a
// generic console message.
LogMessage("Warning: in file '%s', line %i: %s",
NS_ConvertUTF16toUTF8(file).get(),
LogMessage("Warning: in '%s', line %i: %s", file.get(),
aLineNumber, (char*) formatted);
return;
}
@ -208,7 +203,7 @@ void LogMessageWithContext(nsILocalFile* aFile, const char* aPath,
return;
nsresult rv = error->Init(NS_ConvertUTF8toUTF16(formatted).get(),
file.get(), NULL,
NS_ConvertUTF8toUTF16(file).get(), NULL,
aLineNumber, 0, nsIScriptError::warningFlag,
"chrome registration");
if (NS_FAILED(rv))
@ -423,12 +418,12 @@ struct CachedDirective
} // anonymous namespace
static void
ParseManifestCommon(NSLocationType aType, nsILocalFile* aFile,
nsComponentManagerImpl::ManifestProcessingContext& mgrcx,
nsChromeRegistry::ManifestProcessingContext& chromecx,
const char* aPath, char* buf, bool aChromeOnly)
void
ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOnly)
{
nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, file, aChromeOnly);
nsChromeRegistry::ManifestProcessingContext chromecx(type, file);
nsresult rv;
NS_NAMED_LITERAL_STRING(kPlatform, "platform");
@ -553,21 +548,21 @@ ParseManifestCommon(NSLocationType aType, nsILocalFile* aFile,
}
if (!directive) {
LogMessageWithContext(aFile, aPath, line,
LogMessageWithContext(file, line,
"Ignoring unrecognized chrome manifest directive '%s'.",
token);
continue;
}
if (!directive->allowbootstrap && NS_BOOTSTRAPPED_LOCATION == aType) {
LogMessageWithContext(aFile, aPath, line,
if (!directive->allowbootstrap && NS_BOOTSTRAPPED_LOCATION == type) {
LogMessageWithContext(file, line,
"Bootstrapped manifest not allowed to use '%s' directive.",
token);
continue;
}
if (directive->componentonly && NS_SKIN_LOCATION == aType) {
LogMessageWithContext(aFile, aPath, line,
if (directive->componentonly && NS_SKIN_LOCATION == type) {
LogMessageWithContext(file, line,
"Skin manifest not allowed to use '%s' directive.",
token);
continue;
@ -579,7 +574,7 @@ ParseManifestCommon(NSLocationType aType, nsILocalFile* aFile,
argv[i] = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
if (!argv[directive->argc - 1]) {
LogMessageWithContext(aFile, aPath, line,
LogMessageWithContext(file, line,
"Not enough arguments for chrome manifest directive '%s', expected %i.",
token, directive->argc);
continue;
@ -614,13 +609,13 @@ ParseManifestCommon(NSLocationType aType, nsILocalFile* aFile,
bool xpcNativeWrappers = true; // Dummy for CheckFlag.
if (CheckFlag(kXPCNativeWrappers, wtoken, xpcNativeWrappers)) {
LogMessageWithContext(aFile, aPath, line,
LogMessageWithContext(file, line,
"Warning: Ignoring obsolete chrome registration modifier '%s'.",
token);
continue;
}
LogMessageWithContext(aFile, aPath, line,
LogMessageWithContext(file, line,
"Unrecognized chrome manifest modifier '%s'.",
token);
ok = false;
@ -643,7 +638,7 @@ ParseManifestCommon(NSLocationType aType, nsILocalFile* aFile,
nsCOMPtr<nsIChromeRegistry> cr =
mozilla::services::GetChromeRegistryService();
if (!nsChromeRegistry::gChromeRegistry) {
LogMessageWithContext(aFile, aPath, line,
LogMessageWithContext(file, line,
"Chrome registry isn't available yet.");
continue;
}
@ -671,22 +666,3 @@ ParseManifestCommon(NSLocationType aType, nsILocalFile* aFile,
(mgrcx, d.lineno, d.argv);
}
}
void
ParseManifest(NSLocationType type, nsILocalFile* file,
char* buf, bool aChromeOnly)
{
nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, file, aChromeOnly);
nsChromeRegistry::ManifestProcessingContext chromecx(type, file);
ParseManifestCommon(type, file, mgrcx, chromecx, NULL, buf, aChromeOnly);
}
void
ParseManifest(NSLocationType type, nsIZipReader* reader, const char* jarPath,
char* buf, bool aChromeOnly)
{
nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, reader, jarPath, aChromeOnly);
nsChromeRegistry::ManifestProcessingContext chromecx(type, mgrcx.mFile, jarPath);
ParseManifestCommon(type, mgrcx.mFile, mgrcx, chromecx, jarPath,
buf, aChromeOnly);
}

View File

@ -40,19 +40,16 @@
#include "nsComponentManager.h"
#include "nsChromeRegistry.h"
#include "mozilla/FileLocation.h"
class nsILocalFile;
class nsIZipReader;
void ParseManifest(NSLocationType type, nsILocalFile* file,
void ParseManifest(NSLocationType type, mozilla::FileLocation &file,
char* buf, bool aChromeOnly);
void ParseManifest(NSLocationType type, nsIZipReader* reader,
const char* jarPath, char* buf, bool aChromeOnly);
void LogMessage(const char* aMsg, ...);
void LogMessageWithContext(nsILocalFile* aFile, const char* aPath,
void LogMessageWithContext(mozilla::FileLocation &aFile,
PRUint32 aLineNumber, const char* aMsg, ...);
#endif // ManifestParser_h

View File

@ -41,6 +41,7 @@
#include "nsISupports.h"
#include "mozilla/Module.h"
#include "mozilla/FileLocation.h"
#define MOZILLA_MODULELOADER_PSEUDO_IID \
{ 0xD951A8CE, 0x6E9F, 0x464F, \
@ -66,13 +67,7 @@ public:
* 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;
/**
* Return the module for a file located within a JAR.
*/
virtual const Module* LoadModuleFromJAR(nsILocalFile* aJARFile,
const nsACString& aPath) = 0;
virtual const Module* LoadModule(mozilla::FileLocation &aFile) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(ModuleLoader, MOZILLA_MODULELOADER_PSEUDO_IID)

View File

@ -99,13 +99,10 @@
#include "nsArrayEnumerator.h"
#include "nsStringEnumerator.h"
#include "mozilla/FileUtils.h"
#include "nsURLHelper.h"
#include NEW_H // for placement new
#include "mozilla/Omnijar.h"
#include "nsJAR.h"
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
#include "prlog.h"
@ -357,17 +354,17 @@ nsresult nsComponentManagerImpl::Init()
InitializeModuleLocations();
ComponentLocation* cl = sModuleLocations->InsertElementAt(0);
nsCOMPtr<nsILocalFile> lf = CloneAndAppend(appDir, NS_LITERAL_CSTRING("chrome.manifest"));
cl->type = NS_COMPONENT_LOCATION;
cl->location = CloneAndAppend(appDir, NS_LITERAL_CSTRING("chrome.manifest"));
cl->jar = false;
cl->location.Init(lf);
bool equals = false;
appDir->Equals(greDir, &equals);
if (!equals) {
cl = sModuleLocations->InsertElementAt(0);
cl->type = NS_COMPONENT_LOCATION;
cl->location = CloneAndAppend(greDir, NS_LITERAL_CSTRING("chrome.manifest"));
cl->jar = false;
lf = CloneAndAppend(greDir, NS_LITERAL_CSTRING("chrome.manifest"));
cl->location.Init(lf);
}
PR_LOG(nsComponentManagerLog, PR_LOG_DEBUG,
@ -385,19 +382,17 @@ nsresult nsComponentManagerImpl::Init()
for (PRUint32 i = 0; i < sStaticModules->Length(); ++i)
RegisterModule((*sStaticModules)[i], NULL);
nsCOMPtr<nsIFile> appOmnijar = mozilla::Omnijar::GetPath(mozilla::Omnijar::APP);
nsRefPtr<nsZipArchive> appOmnijar = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP);
if (appOmnijar) {
cl = sModuleLocations->InsertElementAt(1); // Insert after greDir
cl->type = NS_COMPONENT_LOCATION;
cl->location = do_QueryInterface(appOmnijar);
cl->jar = true;
cl->location.Init(appOmnijar, "chrome.manifest");
}
nsCOMPtr<nsIFile> greOmnijar = mozilla::Omnijar::GetPath(mozilla::Omnijar::GRE);
nsRefPtr<nsZipArchive> greOmnijar = mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
if (greOmnijar) {
cl = sModuleLocations->InsertElementAt(0);
cl->type = NS_COMPONENT_LOCATION;
cl->location = do_QueryInterface(greOmnijar);
cl->jar = true;
cl->location.Init(greOmnijar, "chrome.manifest");
}
RereadChromeManifests(false);
@ -411,25 +406,23 @@ nsresult nsComponentManagerImpl::Init()
void
nsComponentManagerImpl::RegisterModule(const mozilla::Module* aModule,
nsILocalFile* aFile)
FileLocation* aFile)
{
ReentrantMonitorAutoEnter mon(mMon);
KnownModule* m = new KnownModule(aModule, aFile);
KnownModule* m;
if (aFile) {
nsCAutoString uri;
nsresult rv = net_GetURLSpecFromActualFile(aFile, uri);
if (NS_FAILED(rv)) {
NS_WARNING("net_GetURLSpecFromActualFile failed");
return;
}
nsCString uri;
aFile->GetURIString(uri);
NS_ASSERTION(!mKnownModules.Get(uri),
"Must not register a binary module twice.");
m = new KnownModule(aModule, *aFile);
mKnownModules.Put(uri, m);
}
else
} else {
m = new KnownModule(aModule);
mKnownStaticModules.AppendElement(m);
}
if (aModule->mCIDs) {
const mozilla::Module::CIDEntry* entry;
@ -516,242 +509,91 @@ CutExtension(nsCString& path)
path.Cut(0, dotPos + 1);
}
static nsCString
GetExtension(nsILocalFile* file)
{
nsCString extension;
file->GetNativePath(extension);
CutExtension(extension);
return extension;
}
static already_AddRefed<nsIInputStream>
LoadEntry(nsIZipReader* aReader, const char* aName)
{
if (!aReader)
return NULL;
nsCOMPtr<nsIInputStream> is;
nsresult rv = aReader->GetInputStream(nsDependentCString(aName), getter_AddRefs(is));
if (NS_FAILED(rv))
return NULL;
return is.forget();
}
void
nsComponentManagerImpl::RegisterJarManifest(NSLocationType aType, nsIZipReader* aReader,
const char* aPath, bool aChromeOnly)
nsComponentManagerImpl::RegisterManifest(NSLocationType aType,
FileLocation &aFile,
bool aChromeOnly)
{
nsCOMPtr<nsIInputStream> is = LoadEntry(aReader, aPath);
if (!is) {
if (NS_BOOTSTRAPPED_LOCATION != aType)
LogMessage("Could not find jar manifest entry '%s'.", aPath);
return;
PRUint32 len;
FileLocation::Data data;
nsAutoArrayPtr<char> buf;
nsresult rv = aFile.GetData(data);
if (NS_SUCCEEDED(rv)) {
rv = data.GetSize(&len);
}
PRUint32 flen;
is->Available(&flen);
nsAutoArrayPtr<char> whole(new char[flen + 1]);
if (!whole)
return;
for (PRUint32 totalRead = 0; totalRead < flen; ) {
PRUint32 avail;
PRUint32 read;
if (NS_FAILED(is->Available(&avail)))
return;
if (avail > flen)
return;
if (NS_FAILED(is->Read(whole + totalRead, avail, &read)))
return;
totalRead += read;
if (NS_SUCCEEDED(rv)) {
buf = new char[len + 1];
rv = data.Copy(buf, len);
}
whole[flen] = '\0';
ParseManifest(aType, aReader, aPath,
whole, aChromeOnly);
}
void
nsComponentManagerImpl::RegisterManifestFile(NSLocationType aType,
nsILocalFile* aFile,
bool aChromeOnly)
{
nsresult rv;
mozilla::AutoFDClose fd;
rv = aFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd);
if (NS_FAILED(rv)) {
nsCAutoString path;
aFile->GetNativePath(path);
if (NS_BOOTSTRAPPED_LOCATION != aType)
LogMessage("Could not read chrome manifest file '%s'.", path.get());
return;
if (NS_SUCCEEDED(rv)) {
buf[len] = '\0';
ParseManifest(aType, aFile, buf, aChromeOnly);
} else if (NS_BOOTSTRAPPED_LOCATION != aType) {
nsCString uri;
aFile.GetURIString(uri);
LogMessage("Could not read chrome manifest '%s'.", uri.get());
}
PRFileInfo64 fileInfo;
if (PR_SUCCESS != PR_GetOpenFileInfo64(fd, &fileInfo))
return;
if (fileInfo.size > PRInt64(PR_INT32_MAX))
return;
nsAutoArrayPtr<char> data(new char[PRInt32(fileInfo.size + 1)]);
for (PRInt32 totalRead = 0; totalRead < fileInfo.size; ) {
PRInt32 read = PR_Read(fd, data + totalRead, PRInt32(fileInfo.size));
if (read < 0)
return;
totalRead += read;
}
data[fileInfo.size] = '\0';
ParseManifest(aType, aFile, data, aChromeOnly);
}
#if defined(XP_WIN) || defined(XP_OS2)
#define TRANSLATE_SLASHES
static void
TranslateSlashes(char* path)
{
for (; *path; ++path) {
if ('/' == *path)
*path = '\\';
}
}
#endif
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);
}
void
nsComponentManagerImpl::ManifestManifest(ManifestProcessingContext& cx, int lineno, char *const * argv)
{
char* file = argv[0];
if (cx.mPath) {
nsCAutoString manifest(cx.mPath);
AppendFileToManifestPath(manifest, file);
RegisterJarManifest(cx.mType, cx.mReader, manifest.get(), cx.mChromeOnly);
}
else {
#ifdef TRANSLATE_SLASHES
TranslateSlashes(file);
#endif
nsCOMPtr<nsIFile> cfile;
cx.mFile->GetParent(getter_AddRefs(cfile));
nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
nsresult rv = clfile->AppendRelativeNativePath(nsDependentCString(file));
if (NS_FAILED(rv)) {
NS_WARNING("Couldn't append relative path?");
return;
}
RegisterManifestFile(cx.mType, clfile, cx.mChromeOnly);
}
FileLocation f(cx.mFile, file);
RegisterManifest(cx.mType, f, cx.mChromeOnly);
}
void
nsComponentManagerImpl::ManifestBinaryComponent(ManifestProcessingContext& cx, int lineno, char *const * argv)
{
if (cx.mPath) {
if (cx.mFile.IsZip()) {
NS_WARNING("Cannot load binary components from a jar.");
LogMessageWithContext(cx.mFile, cx.mPath, lineno,
LogMessageWithContext(cx.mFile, lineno,
"Cannot load binary components from a jar.");
return;
}
char* file = argv[0];
FileLocation f(cx.mFile, argv[0]);
nsCString uri;
f.GetURIString(uri);
#ifdef TRANSLATE_SLASHES
TranslateSlashes(file);
#endif
nsCOMPtr<nsIFile> cfile;
cx.mFile->GetParent(getter_AddRefs(cfile));
nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
nsresult rv = clfile->AppendRelativeNativePath(nsDependentCString(file));
if (NS_FAILED(rv)) {
NS_WARNING("Couldn't append relative path?");
return;
}
nsCAutoString uri;
rv = net_GetURLSpecFromActualFile(clfile, uri);
if (NS_FAILED(rv)) {
NS_WARNING("net_GetURLSpecFromActualFile failed");
return;
}
if (mKnownModules.Get(uri)) {
NS_WARNING("Attempting to register a binary component twice.");
LogMessageWithContext(cx.mFile, cx.mPath, lineno,
LogMessageWithContext(cx.mFile, lineno,
"Attempting to register a binary component twice.");
return;
}
const mozilla::Module* m = mNativeModuleLoader.LoadModule(clfile);
const mozilla::Module* m = mNativeModuleLoader.LoadModule(f);
// The native module loader should report an error here, we don't have to
if (!m)
return;
RegisterModule(m, clfile);
RegisterModule(m, &f);
}
void
nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& cx, int lineno, char *const * argv)
{
char* file = argv[0];
if (cx.mPath) {
nsCAutoString manifest(cx.mPath);
AppendFileToManifestPath(manifest, file);
nsCOMPtr<nsIInputStream> stream =
LoadEntry(cx.mReader, manifest.get());
if (!stream) {
NS_WARNING("Failed to load XPT file in a jar.");
return;
}
xptiInterfaceInfoManager::GetSingleton()
->RegisterInputStream(stream);
FileLocation f(cx.mFile, argv[0]);
PRUint32 len;
FileLocation::Data data;
nsAutoArrayPtr<char> buf;
nsresult rv = f.GetData(data);
if (NS_SUCCEEDED(rv)) {
rv = data.GetSize(&len);
}
else {
#ifdef TRANSLATE_SLASHES
TranslateSlashes(file);
#endif
nsCOMPtr<nsIFile> cfile;
cx.mFile->GetParent(getter_AddRefs(cfile));
nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
nsresult rv = clfile->AppendRelativeNativePath(nsDependentCString(file));
if (NS_FAILED(rv)) {
NS_WARNING("Couldn't append relative path?");
return;
}
if (NS_SUCCEEDED(rv)) {
buf = new char[len];
rv = data.Copy(buf, len);
}
if (NS_SUCCEEDED(rv)) {
xptiInterfaceInfoManager::GetSingleton()
->RegisterFile(clfile);
->RegisterBuffer(buf, len);
} else {
nsCString uri;
f.GetURIString(uri);
LogMessage("Could not read '%s'.", uri.get());
}
}
@ -763,7 +605,7 @@ nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& cx, int lin
nsID cid;
if (!cid.Parse(id)) {
LogMessageWithContext(cx.mFile, cx.mPath, lineno,
LogMessageWithContext(cx.mFile, lineno,
"Malformed CID: '%s'.", id);
return;
}
@ -780,7 +622,7 @@ nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& cx, int lin
else
existing = "<unknown module>";
LogMessageWithContext(cx.mFile, cx.mPath, lineno,
LogMessageWithContext(cx.mFile, lineno,
"Trying to re-register CID '%s' already registered by %s.",
idstr,
existing.get());
@ -788,52 +630,14 @@ nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& cx, int lin
}
KnownModule* km;
FileLocation fl(cx.mFile, file);
if (cx.mPath) {
nsCAutoString manifest(cx.mPath);
AppendFileToManifestPath(manifest, file);
nsCAutoString hash;
nsresult rv = net_GetURLSpecFromActualFile(cx.mFile, hash);
if (NS_FAILED(rv)) {
NS_WARNING("net_GetURLSpecFromActualFile failed");
return;
}
hash.Insert("jar:", 0);
hash.Append("!/");
hash.Append(manifest);
km = mKnownModules.Get(hash);
if (!km) {
km = new KnownModule(cx.mFile, manifest);
mKnownModules.Put(hash, km);
}
}
else {
#ifdef TRANSLATE_SLASHES
TranslateSlashes(file);
#endif
nsCOMPtr<nsIFile> cfile;
cx.mFile->GetParent(getter_AddRefs(cfile));
nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
nsresult rv = clfile->AppendRelativeNativePath(nsDependentCString(file));
if (NS_FAILED(rv)) {
NS_WARNING("Couldn't append relative path?");
return;
}
nsCAutoString hash;
rv = net_GetURLSpecFromActualFile(clfile, hash);
if (NS_FAILED(rv)) {
NS_WARNING("net_GetURLSpecFromActualFile failed");
return;
}
km = mKnownModules.Get(hash);
if (!km) {
km = new KnownModule(clfile);
mKnownModules.Put(hash, km);
}
nsCString hash;
fl.GetURIString(hash);
km = mKnownModules.Get(hash);
if (!km) {
km = new KnownModule(fl);
mKnownModules.Put(hash, km);
}
void* place;
@ -858,7 +662,7 @@ nsComponentManagerImpl::ManifestContract(ManifestProcessingContext& cx, int line
nsID cid;
if (!cid.Parse(id)) {
LogMessageWithContext(cx.mFile, cx.mPath, lineno,
LogMessageWithContext(cx.mFile, lineno,
"Malformed CID: '%s'.", id);
return;
}
@ -866,7 +670,7 @@ nsComponentManagerImpl::ManifestContract(ManifestProcessingContext& cx, int line
ReentrantMonitorAutoEnter mon(mMon);
nsFactoryEntry* f = mFactories.Get(cid);
if (!f) {
LogMessageWithContext(cx.mFile, cx.mPath, lineno,
LogMessageWithContext(cx.mFile, lineno,
"Could not map contract ID '%s' to CID %s because no implementation of the CID is registered.",
contract, id);
return;
@ -891,17 +695,7 @@ nsComponentManagerImpl::RereadChromeManifests(bool aChromeOnly)
{
for (PRUint32 i = 0; i < sModuleLocations->Length(); ++i) {
ComponentLocation& l = sModuleLocations->ElementAt(i);
if (!l.jar) {
RegisterManifestFile(l.type, l.location, aChromeOnly);
continue;
}
nsresult rv;
nsCOMPtr<nsIZipReader> reader = do_CreateInstance(kZipReaderCID, &rv);
if (NS_SUCCEEDED(rv))
rv = reader->Open(l.location);
if (NS_SUCCEEDED(rv))
RegisterJarManifest(l.type, reader, "chrome.manifest", aChromeOnly);
RegisterManifest(l.type, l.location, aChromeOnly);
}
}
@ -910,14 +704,8 @@ nsComponentManagerImpl::KnownModule::EnsureLoader()
{
if (!mLoader) {
nsCString extension;
if (!mPath.IsEmpty()) {
extension = mPath;
CutExtension(extension);
}
else {
extension = GetExtension(mFile);
}
mFile.GetURIString(extension);
CutExtension(extension);
mLoader = nsComponentManagerImpl::gComponentManager->LoaderForExtension(extension);
}
return !!mLoader;
@ -932,10 +720,7 @@ nsComponentManagerImpl::KnownModule::Load()
if (!EnsureLoader())
return false;
if (!mPath.IsEmpty())
mModule = mLoader->LoadModuleFromJAR(mFile, mPath);
else
mModule = mLoader->LoadModule(mFile);
mModule = mLoader->LoadModule(mFile);
if (!mModule) {
mFailed = true;
@ -959,14 +744,8 @@ nsCString
nsComponentManagerImpl::KnownModule::Description() const
{
nsCString s;
if (!mPath.IsEmpty()) {
mFile->GetNativePath(s);
s.Insert(NS_LITERAL_CSTRING("jar:"), 0);
s.AppendLiteral("!/");
s.Append(mPath);
}
else if (mFile)
mFile->GetNativePath(s);
if (mFile)
mFile.GetURIString(s);
else
s = "<static module>";
return s;
@ -2050,25 +1829,21 @@ nsComponentManagerImpl::RemoveBootstrappedManifestLocation(nsILocalFile* aLocati
if (!cr)
return NS_ERROR_FAILURE;
bool isJar = false;
nsCOMPtr<nsILocalFile> manifest;
nsString path;
nsresult rv = aLocation->GetPath(path);
if (NS_FAILED(rv))
return rv;
if (Substring(path, path.Length() - 4).Equals(NS_LITERAL_STRING(".xpi"))) {
isJar = true;
manifest = aLocation;
} else {
manifest = CloneAndAppend(aLocation, NS_LITERAL_CSTRING("chrome.manifest"));
}
nsComponentManagerImpl::ComponentLocation elem;
elem.type = NS_BOOTSTRAPPED_LOCATION;
nsComponentManagerImpl::ComponentLocation elem = {
NS_BOOTSTRAPPED_LOCATION,
manifest,
isJar
};
if (Substring(path, path.Length() - 4).Equals(NS_LITERAL_STRING(".xpi"))) {
elem.location.Init(aLocation, "chrome.manifest");
} else {
nsCOMPtr<nsILocalFile> lf = CloneAndAppend(aLocation, NS_LITERAL_CSTRING("chrome.manifest"));
elem.location.Init(lf);
}
// Remove reference.
nsComponentManagerImpl::sModuleLocations->RemoveElement(elem, ComponentLocationComparator());
@ -2084,12 +1859,11 @@ XRE_AddManifestLocation(NSLocationType aType, nsILocalFile* aLocation)
nsComponentManagerImpl::ComponentLocation* c =
nsComponentManagerImpl::sModuleLocations->AppendElement();
c->type = aType;
c->location = aLocation;
c->jar = false;
c->location.Init(aLocation);
if (nsComponentManagerImpl::gComponentManager &&
nsComponentManagerImpl::NORMAL == nsComponentManagerImpl::gComponentManager->mStatus)
nsComponentManagerImpl::gComponentManager->RegisterManifestFile(aType, aLocation, false);
nsComponentManagerImpl::gComponentManager->RegisterManifest(aType, c->location, false);
return NS_OK;
}
@ -2100,21 +1874,13 @@ XRE_AddJarManifestLocation(NSLocationType aType, nsILocalFile* aLocation)
nsComponentManagerImpl::InitializeModuleLocations();
nsComponentManagerImpl::ComponentLocation* c =
nsComponentManagerImpl::sModuleLocations->AppendElement();
c->type = aType;
c->location = aLocation;
c->jar = true;
c->location.Init(aLocation, "chrome.manifest");
if (!nsComponentManagerImpl::gComponentManager ||
nsComponentManagerImpl::NORMAL != nsComponentManagerImpl::gComponentManager->mStatus)
return NS_OK;
nsresult rv;
nsCOMPtr<nsIZipReader> reader = do_CreateInstance(kZipReaderCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = reader->Open(c->location);
if (NS_SUCCEEDED(rv))
nsComponentManagerImpl::gComponentManager->RegisterJarManifest(aType, reader, "chrome.manifest", false);
if (nsComponentManagerImpl::gComponentManager &&
nsComponentManagerImpl::NORMAL == nsComponentManagerImpl::gComponentManager->mStatus)
nsComponentManagerImpl::gComponentManager->RegisterManifest(aType, c->location, false);
return NS_OK;
}

View File

@ -67,7 +67,6 @@
#include "nsTArray.h"
#include "mozilla/Omnijar.h"
#include "nsIZipReader.h"
struct nsFactoryEntry;
class nsIServiceManager;
@ -158,8 +157,7 @@ public:
struct ComponentLocation
{
NSLocationType type;
nsCOMPtr<nsILocalFile> location;
bool jar;
mozilla::FileLocation location;
};
class ComponentLocationComparator
@ -167,14 +165,7 @@ public:
public:
bool Equals(const ComponentLocation& a, const ComponentLocation& b) const
{
if (a.type == b.type && a.jar == b.jar) {
bool res;
nsresult rv = a.location->Equals(b.location, &res);
NS_ASSERTION(NS_SUCCEEDED(rv), "Error comparing locations");
return res;
}
return false;
return (a.type == b.type && a.location.Equals(b.location));
}
};
@ -189,25 +180,22 @@ public:
/**
* Static or binary module.
*/
KnownModule(const mozilla::Module* aModule, nsILocalFile* aFile)
KnownModule(const mozilla::Module* aModule, mozilla::FileLocation &aFile)
: mModule(aModule)
, mFile(aFile)
, mLoaded(false)
, mFailed(false)
{ }
KnownModule(nsILocalFile* aFile)
: mModule(NULL)
, mFile(aFile)
, mLoader(NULL)
KnownModule(const mozilla::Module* aModule)
: mModule(aModule)
, mLoaded(false)
, mFailed(false)
{ }
KnownModule(nsILocalFile* aFile, const nsACString& aPath)
KnownModule(mozilla::FileLocation &aFile)
: mModule(NULL)
, mFile(aFile)
, mPath(aPath)
, mLoader(NULL)
, mLoaded(false)
, mFailed(false)
@ -235,8 +223,7 @@ public:
private:
const mozilla::Module* mModule;
nsCOMPtr<nsILocalFile> mFile;
nsCString mPath;
mozilla::FileLocation mFile;
nsCOMPtr<mozilla::ModuleLoader> mLoader;
bool mLoaded;
bool mFailed;
@ -249,44 +236,26 @@ public:
nsClassHashtable<nsCStringHashKey, KnownModule> mKnownModules;
void RegisterModule(const mozilla::Module* aModule,
nsILocalFile* aFile);
mozilla::FileLocation* aFile);
void RegisterCIDEntry(const mozilla::Module::CIDEntry* aEntry,
KnownModule* aModule);
void RegisterContractID(const mozilla::Module::ContractIDEntry* aEntry);
void RegisterJarManifest(NSLocationType aType, nsIZipReader* aReader,
const char* aPath, bool aChromeOnly);
void RegisterManifestFile(NSLocationType aType, nsILocalFile* aFile,
bool aChromeOnly);
void RegisterManifest(NSLocationType aType, mozilla::FileLocation &aFile,
bool aChromeOnly);
struct ManifestProcessingContext
{
ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile, bool aChromeOnly)
ManifestProcessingContext(NSLocationType aType, mozilla::FileLocation &aFile, bool aChromeOnly)
: mType(aType)
, mFile(aFile)
, mPath(NULL)
, mChromeOnly(aChromeOnly)
{ }
ManifestProcessingContext(NSLocationType aType, nsIZipReader* aReader, const char* aPath, bool aChromeOnly)
: mType(aType)
, mReader(aReader)
, mPath(aPath)
, mChromeOnly(aChromeOnly)
{
nsCOMPtr<nsIFile> file;
aReader->GetFile(getter_AddRefs(file));
nsCOMPtr<nsILocalFile> localfile = do_QueryInterface(file);
mFile = localfile;
}
~ManifestProcessingContext() { }
NSLocationType mType;
nsILocalFile* mFile;
nsIZipReader* mReader;
const char* mPath;
mozilla::FileLocation mFile;
bool mChromeOnly;
};

View File

@ -83,6 +83,8 @@
#define IMPLEMENT_BREAK_AFTER_LOAD
#endif
using namespace mozilla;
static PRLogModuleInfo *nsNativeModuleLoaderLog =
PR_NewLogModule("nsNativeModuleLoader");
@ -110,7 +112,7 @@ class LoadModuleMainThreadRunnable : public nsRunnable
{
public:
LoadModuleMainThreadRunnable(nsNativeModuleLoader* loader,
nsILocalFile* file)
FileLocation &file)
: mLoader(loader)
, mFile(file)
, mResult(NULL)
@ -123,13 +125,18 @@ public:
}
nsRefPtr<nsNativeModuleLoader> mLoader;
nsCOMPtr<nsILocalFile> mFile;
FileLocation mFile;
const mozilla::Module* mResult;
};
const mozilla::Module*
nsNativeModuleLoader::LoadModule(nsILocalFile* aFile)
nsNativeModuleLoader::LoadModule(FileLocation &aFile)
{
if (aFile.IsZip()) {
NS_ERROR("Binary components cannot be loaded from JARs");
return NULL;
}
nsCOMPtr<nsILocalFile> file = aFile.GetBaseFile();
nsresult rv;
if (!NS_IsMainThread()) {
@ -140,14 +147,14 @@ nsNativeModuleLoader::LoadModule(nsILocalFile* aFile)
return r->mResult;
}
nsCOMPtr<nsIHashable> hashedFile(do_QueryInterface(aFile));
nsCOMPtr<nsIHashable> hashedFile(do_QueryInterface(file));
if (!hashedFile) {
NS_ERROR("nsIFile is not nsIHashable");
return NULL;
}
nsCAutoString filePath;
aFile->GetNativePath(filePath);
file->GetNativePath(filePath);
NativeLoadData data;
@ -161,7 +168,7 @@ nsNativeModuleLoader::LoadModule(nsILocalFile* aFile)
// We haven't loaded this module before
rv = aFile->Load(&data.library);
rv = file->Load(&data.library);
if (NS_FAILED(rv)) {
char errorMsg[1024] = "<unknown; can't get error from NSPR>";
@ -177,7 +184,7 @@ nsNativeModuleLoader::LoadModule(nsILocalFile* aFile)
#ifdef IMPLEMENT_BREAK_AFTER_LOAD
nsCAutoString leafName;
aFile->GetNativeLeafName(leafName);
file->GetNativeLeafName(leafName);
char *env = getenv("XPCOM_BREAK_ON_LOAD");
char *blist;
@ -214,13 +221,6 @@ nsNativeModuleLoader::LoadModule(nsILocalFile* aFile)
return data.module;
}
const mozilla::Module*
nsNativeModuleLoader::LoadModuleFromJAR(nsILocalFile* aJARFile, const nsACString &aPath)
{
NS_ERROR("Binary components cannot be loaded from JARs");
return NULL;
}
PLDHashOperator
nsNativeModuleLoader::ReleaserFunc(nsIHashable* aHashedFile,
NativeLoadData& aLoadData, void*)

View File

@ -53,9 +53,7 @@ class nsNativeModuleLoader : public mozilla::ModuleLoader
nsNativeModuleLoader() {}
~nsNativeModuleLoader() {}
NS_OVERRIDE virtual const mozilla::Module* LoadModule(nsILocalFile* aFile);
NS_OVERRIDE virtual const mozilla::Module* LoadModuleFromJAR(nsILocalFile* aJARFile,
const nsACString& aPath);
NS_OVERRIDE virtual const mozilla::Module* LoadModule(mozilla::FileLocation &aFile);
nsresult Init();

View File

@ -97,106 +97,25 @@ xptiInterfaceInfoManager::~xptiInterfaceInfoManager()
#endif
}
XPTHeader*
xptiInterfaceInfoManager::ReadXPTFile(nsILocalFile* aFile)
{
mozilla::AutoFDClose fd;
if (NS_FAILED(aFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd)) || !fd)
return NULL;
PRFileInfo64 fileInfo;
if (PR_SUCCESS != PR_GetOpenFileInfo64(fd, &fileInfo))
return NULL;
if (fileInfo.size > PRInt64(PR_INT32_MAX))
return NULL;
nsAutoArrayPtr<char> whole(new char[PRInt32(fileInfo.size)]);
if (!whole)
return nsnull;
for (PRInt32 totalRead = 0; totalRead < fileInfo.size; ) {
PRInt32 read = PR_Read(fd, whole + totalRead, PRInt32(fileInfo.size));
if (read < 0)
return NULL;
totalRead += read;
}
XPTState* state = XPT_NewXDRState(XPT_DECODE, whole,
PRInt32(fileInfo.size));
XPTCursor cursor;
if (!XPT_MakeCursor(state, XPT_HEADER, 0, &cursor)) {
XPT_DestroyXDRState(state);
return NULL;
}
XPTHeader *header = nsnull;
if (!XPT_DoHeader(gXPTIStructArena, &cursor, &header)) {
XPT_DestroyXDRState(state);
return NULL;
}
XPT_DestroyXDRState(state);
return header;
}
XPTHeader*
xptiInterfaceInfoManager::ReadXPTFileFromInputStream(nsIInputStream *stream)
{
PRUint32 flen;
stream->Available(&flen);
nsAutoArrayPtr<char> whole(new char[flen]);
if (!whole)
return nsnull;
for (PRUint32 totalRead = 0; totalRead < flen; ) {
PRUint32 avail;
PRUint32 read;
if (NS_FAILED(stream->Available(&avail)))
return NULL;
if (avail > flen)
return NULL;
if (NS_FAILED(stream->Read(whole+totalRead, avail, &read)))
return NULL;
totalRead += read;
}
XPTState *state = XPT_NewXDRState(XPT_DECODE, whole, flen);
if (!state)
return NULL;
XPTCursor cursor;
if (!XPT_MakeCursor(state, XPT_HEADER, 0, &cursor)) {
XPT_DestroyXDRState(state);
return NULL;
}
XPTHeader *header = nsnull;
if (!XPT_DoHeader(gXPTIStructArena, &cursor, &header)) {
XPT_DestroyXDRState(state);
return NULL;
}
XPT_DestroyXDRState(state);
return header;
}
void
xptiInterfaceInfoManager::RegisterFile(nsILocalFile* aFile)
xptiInterfaceInfoManager::RegisterBuffer(char *buf, PRUint32 length)
{
XPTHeader* header = ReadXPTFile(aFile);
if (!header)
XPTState *state = XPT_NewXDRState(XPT_DECODE, buf, length);
if (!state)
return;
RegisterXPTHeader(header);
XPTCursor cursor;
if (!XPT_MakeCursor(state, XPT_HEADER, 0, &cursor)) {
XPT_DestroyXDRState(state);
return;
}
XPTHeader *header = nsnull;
if (XPT_DoHeader(gXPTIStructArena, &cursor, &header)) {
RegisterXPTHeader(header);
}
XPT_DestroyXDRState(state);
}
void
@ -214,14 +133,6 @@ xptiInterfaceInfoManager::RegisterXPTHeader(XPTHeader* aHeader)
VerifyAndAddEntryIfNew(aHeader->interface_directory + k, k, typelib);
}
void
xptiInterfaceInfoManager::RegisterInputStream(nsIInputStream* aStream)
{
XPTHeader* header = ReadXPTFileFromInputStream(aStream);
if (header)
RegisterXPTHeader(header);
}
void
xptiInterfaceInfoManager::VerifyAndAddEntryIfNew(XPTInterfaceDirectoryEntry* iface,
PRUint16 idx,

View File

@ -444,8 +444,7 @@ public:
static xptiInterfaceInfoManager* GetSingleton();
static void FreeInterfaceInfoManager();
void RegisterFile(nsILocalFile* aFile);
void RegisterInputStream(nsIInputStream* aStream);
void RegisterBuffer(char *buf, PRUint32 length);
xptiWorkingSet* GetWorkingSet() {return &mWorkingSet;}
@ -463,9 +462,6 @@ private:
void RegisterXPTHeader(XPTHeader* aHeader);
XPTHeader* ReadXPTFile(nsILocalFile* aFile);
XPTHeader* ReadXPTFileFromInputStream(nsIInputStream *stream);
// idx is the index of this interface in the XPTHeader
void VerifyAndAddEntryIfNew(XPTInterfaceDirectoryEntry* iface,
PRUint16 idx,