diff --git a/mozilla/xpcom/components/nsComponentManager.cpp b/mozilla/xpcom/components/nsComponentManager.cpp index 03168445f53..e42a2c98ddf 100644 --- a/mozilla/xpcom/components/nsComponentManager.cpp +++ b/mozilla/xpcom/components/nsComponentManager.cpp @@ -60,6 +60,7 @@ const char mozillaKeyName[]="Software/Mozilla"; const char classesKeyName[]="Classes"; const char classIDKeyName[]="CLSID"; const char classesClassIDKeyName[]="Classes/CLSID"; +const char componentLoadersKeyName[]="ComponentLoaders"; // Common Value Names const char classIDValueName[]="CLSID"; @@ -71,9 +72,7 @@ const char progIDValueName[]="ProgID"; const char classNameValueName[]="ClassName"; const char inprocServerValueName[]="InprocServer"; const char componentTypeValueName[]="ComponentType"; -const char nativeComponentType[]="application/x-moz-native"; -const char componentLoaderProgIDPrefix[]= - "component://mozilla/xpcom/component-loader?type="; +const char nativeComponentType[]="application/x-mozilla-native"; // We define a CID that is used to indicate the non-existence of a // progid in the hash table. @@ -279,7 +278,7 @@ nsComponentManagerImpl::~nsComponentManagerImpl() } -NS_IMPL_ISUPPORTS(nsComponentManagerImpl, nsIComponentManager::GetIID()); +NS_IMPL_ISUPPORTS(nsComponentManagerImpl, NS_GET_IID(nsIComponentManager)); //////////////////////////////////////////////////////////////////////////////// // nsComponentManagerImpl: Platform methods @@ -485,6 +484,10 @@ nsComponentManagerImpl::PlatformVersionCheck() ("nsComponentManager: platformVersionCheck() passed.")); } + rv = mRegistry->GetSubtree(mXPCOMKey, componentLoadersKeyName, &mLoadersKey); + if (NS_FAILED(rv)) + return rv; + return NS_OK; } @@ -656,7 +659,9 @@ nsComponentManagerImpl::PlatformFind(const nsCID &aCID, nsFactoryEntry* *result) nsCOMPtr loader; - GetLoaderForType(componentType, getter_AddRefs(loader)); + rv = GetLoaderForType(componentType, getter_AddRefs(loader)); + if (NS_FAILED(rv)) + return rv; nsFactoryEntry *res = new nsFactoryEntry(aCID, library, componentType, loader); @@ -1116,7 +1121,7 @@ nsComponentManagerImpl::ProgIDToCLSID(const char *aProgID, nsCID *aClass) #endif /* USE_REGISTRY */ if (PR_LOG_TEST(nsComponentManagerLog, PR_LOG_ALWAYS)) { - char *buf; + char *buf = 0; if (NS_SUCCEEDED(res)) buf = aClass->ToString(); PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, @@ -1509,16 +1514,23 @@ nsComponentManagerImpl::GetLoaderForType(const char *aType, return NS_OK; } + nsIRegistry::Key loaderKey; + rv = mRegistry->GetSubtreeRaw(mLoadersKey, aType, &loaderKey); + if (NS_FAILED(rv)) + return rv; + + char *progID; + rv = mRegistry->GetString(loaderKey, progIDValueName, &progID); + if (NS_FAILED(rv)) + return rv; + #ifdef DEBUG_shaver - fprintf(stderr, "nCMI: constructing loader for type %s\n", aType); + fprintf(stderr, "nCMI: constructing loader for type %s = %s\n", aType, progID); #endif - /* how many copies am I doing here? I don't really know. */ - nsString progID(componentLoaderProgIDPrefix, eOneByte); - progID += aType; + rv = CreateInstance(progID, nsnull, NS_GET_IID(nsIComponentLoader), (void **)&loader); + PR_FREEIF(progID); - rv = CreateInstance(progID.mStr, nsnull, NS_GET_IID(nsIComponentLoader), - (void **)&loader); if (NS_SUCCEEDED(rv)) { mLoaders->Put(&typeKey, loader); *aLoader = loader; @@ -1526,6 +1538,26 @@ nsComponentManagerImpl::GetLoaderForType(const char *aType, return rv; } +nsresult +nsComponentManagerImpl::RegisterComponentLoader(const char *aType, const char *aProgID, + PRBool aReplace) +{ + nsIRegistry::Key loaderKey; + nsresult rv = mRegistry->GetSubtreeRaw(mLoadersKey, aType, &loaderKey); + if (NS_FAILED(rv)) + return rv; + + /* XXX honour aReplace */ + + rv = mRegistry->SetString(loaderKey, progIDValueName, aProgID); + +#ifdef DEBUG_shaver + fprintf(stderr, "nNCI: registered %s as component loader for %s\n", + aProgID, aType); +#endif + return rv; +} + nsresult nsComponentManagerImpl::AddComponentToRegistry(const nsCID &aClass, const char *aClassName, @@ -1796,6 +1828,50 @@ nsComponentManagerImpl::AutoRegister(RegistrationTime when, nsIFileSpec *inDirSp if (NS_FAILED(rv)) return rv; + /* XXX eagerly instantiate all known loaders */ + nsCOMPtr loaderEnum; + rv = mRegistry->EnumerateSubtrees(mLoadersKey, getter_AddRefs(loaderEnum)); + if (NS_FAILED(rv)) + return rv; + + rv = loaderEnum->First(); + if (NS_FAILED(rv)) + return rv; + + for (; NS_SUCCEEDED(rv) && !loaderEnum->IsDone(); + (rv = loaderEnum->Next())) { + nsCOMPtr base; + rv = loaderEnum->CurrentItem(getter_AddRefs(base)); + if (NS_FAILED(rv)) + return rv; + + // Narrow + nsCOMPtr node; + node = do_QueryInterface(base, &rv); + if (NS_FAILED(rv)) + continue; + + char *type; + rv = node->GetName(&type); + if (NS_FAILED(rv)) + continue; + autoStringFree del_type(type, autoStringFree::nsCRT_String_Delete); + + nsStringKey typeKey(type); + nsCOMPtr loader = + (nsIComponentLoader *)mLoaders->Get(&typeKey); + if (loader.get()) + continue; + +#ifdef DEBUG_shaver + fprintf(stderr, "nCMI: creating %s loader for enumeration\n", + type); +#endif + /* this will get it added to the hashtable and stuff */ + GetLoaderForType(type, getter_AddRefs(loader)); + continue; + } + /* iterate over all known loaders and ask them to autoregister. */ struct AutoReg_closure closure; /* XXX convert when to nsIComponentLoader::(when) properly */