Bug 1477579: Part 3 - Avoid duplicating static strings in category manager entries. r=froydnj

Much like the component manager, many of the strings that we use for category
manager entries are statically allocated. There's no need to duplicate these
strings.

This patch changes the category manager APIs to take nsACStrings rather than
raw pointers, and to pass literal nsCStrings when we know we have a literal
string to begin with. When adding the category entry, it then skips making
copies of any strings with the LITERAL flag.

MozReview-Commit-ID: EJEcYSdNMWs
***
amend-catman

--HG--
extra : source : aa9a8f18e98f930a3d8359565eef02f3f6efc5f9
extra : absorb_source : 81a22ab26ee8017ac43321ff2c987d8096182d37
This commit is contained in:
Kris Maglione 2018-07-23 17:41:06 -07:00
parent 83b3ac8f23
commit 7aa3564a28
19 changed files with 198 additions and 182 deletions

View File

@ -6952,8 +6952,7 @@ nsContentUtils::FindInternalContentViewer(const nsACString& aType,
nsCString contractID;
nsresult rv = catMan->GetCategoryEntry("Gecko-Content-Viewers",
PromiseFlatCString(aType).get(),
getter_Copies(contractID));
aType, contractID);
if (NS_SUCCEEDED(rv)) {
docFactory = do_GetService(contractID.get());
if (docFactory && aLoaderType) {

View File

@ -1089,8 +1089,8 @@ nsExternalResourceMap::PendingLoad::SetupViewer(nsIRequest* aRequest,
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
NS_ENSURE_TRUE(catMan, NS_ERROR_NOT_AVAILABLE);
nsCString contractId;
nsresult rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", type.get(),
getter_Copies(contractId));
nsresult rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", type,
contractId);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
do_GetService(contractId.get());

View File

@ -2771,16 +2771,15 @@ nsPluginHost::RegisterWithCategoryManager(const nsCString& aMimeType,
return;
}
const char *contractId =
"@mozilla.org/content/plugin/document-loader-factory;1";
NS_NAMED_LITERAL_CSTRING(contractId,
"@mozilla.org/content/plugin/document-loader-factory;1");
if (aType == ePluginRegister) {
catMan->AddCategoryEntry("Gecko-Content-Viewers",
aMimeType.get(),
aMimeType,
contractId,
false, /* persist: broken by bug 193031 */
mOverrideInternalTypes,
nullptr);
mOverrideInternalTypes);
} else {
if (aType == ePluginMaybeUnregister) {
// Bail out if this type is still used by an enabled plugin
@ -2794,12 +2793,10 @@ nsPluginHost::RegisterWithCategoryManager(const nsCString& aMimeType,
// Only delete the entry if a plugin registered for it
nsCString value;
nsresult rv = catMan->GetCategoryEntry("Gecko-Content-Viewers",
aMimeType.get(),
getter_Copies(value));
if (NS_SUCCEEDED(rv) && strcmp(value.get(), contractId) == 0) {
aMimeType, value);
if (NS_SUCCEEDED(rv) && value == contractId) {
catMan->DeleteCategoryEntry("Gecko-Content-Viewers",
aMimeType.get(),
true);
aMimeType, true);
}
}
}

View File

@ -320,9 +320,7 @@ PushDispatcher::DoNotifyObservers(nsISupports *aSubject, const char *aTopic,
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
if (catMan) {
nsCString contractId;
nsresult rv = catMan->GetCategoryEntry("push",
mScope.BeginReading(),
getter_Copies(contractId));
nsresult rv = catMan->GetCategoryEntry("push", mScope, contractId);
if (NS_SUCCEEDED(rv)) {
// Ensure the service is created - we don't need to do anything with
// it though - we assume the service constructor attaches a listener.

View File

@ -137,7 +137,7 @@ gfxSVGGlyphsDocument::SetupPresentation()
{
nsCOMPtr<nsICategoryManager> catMan = do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
nsCString contractId;
nsresult rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "image/svg+xml", getter_Copies(contractId));
nsresult rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "image/svg+xml", contractId);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =

View File

@ -332,7 +332,7 @@ SVGDocumentWrapper::SetupViewer(nsIRequest* aRequest,
NS_ENSURE_TRUE(catMan, NS_ERROR_NOT_AVAILABLE);
nsCString contractId;
nsresult rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", IMAGE_SVG_XML,
getter_Copies(contractId));
contractId);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
do_GetService(contractId.get());

View File

@ -74,7 +74,7 @@ nsStyleSheetService::RegisterFromEnumerator(nsICategoryManager *aManager,
icStr->GetData(name);
nsCString spec;
aManager->GetCategoryEntry(aCategory, name.get(), getter_Copies(spec));
aManager->GetCategoryEntry(nsDependentCString(aCategory), name, spec);
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), spec);

View File

@ -515,9 +515,8 @@ nsCommandLine::EnumerateHandlers(EnumerateHandlersCallback aCallback, void *aClo
strenum->GetNext(entry);
nsCString contractID;
rv = catman->GetCategoryEntry("command-line-handler",
entry.get(),
getter_Copies(contractID));
rv = catman->GetCategoryEntry("command-line-handler", entry,
contractID);
if (NS_FAILED(rv))
continue;
@ -562,8 +561,7 @@ nsCommandLine::EnumerateValidators(EnumerateValidatorsCallback aCallback, void *
nsCString contractID;
rv = catman->GetCategoryEntry("command-line-validator",
entry.get(),
getter_Copies(contractID));
entry, contractID);
if (contractID.IsVoid())
continue;

View File

@ -30,8 +30,10 @@ NS_IMETHODIMP nsAppStartupNotifier::Observe(nsISupports *aSubject, const char *a
do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsDependentCString topic(aTopic);
nsCOMPtr<nsISimpleEnumerator> enumerator;
rv = categoryManager->EnumerateCategory(aTopic,
rv = categoryManager->EnumerateCategory(topic,
getter_AddRefs(enumerator));
if (NS_FAILED(rv)) return rv;
@ -44,9 +46,8 @@ NS_IMETHODIMP nsAppStartupNotifier::Observe(nsISupports *aSubject, const char *a
rv = category->GetData(categoryEntry);
nsCString contractId;
categoryManager->GetCategoryEntry(aTopic,
categoryEntry.get(),
getter_Copies(contractId));
categoryManager->GetCategoryEntry(topic, categoryEntry,
contractId);
if (NS_SUCCEEDED(rv)) {

View File

@ -465,8 +465,7 @@ nsresult nsDocumentOpenInfo::DispatchContent(nsIRequest *request, nsISupports *
if (catman) {
nsCString contractidString;
rv = catman->GetCategoryEntry(NS_CONTENT_LISTENER_CATEGORYMANAGER_ENTRY,
mContentType.get(),
getter_Copies(contractidString));
mContentType, contractidString);
if (NS_SUCCEEDED(rv) && !contractidString.IsEmpty()) {
LOG((" Listener contractid for '%s' is '%s'",
mContentType.get(), contractidString.get()));

View File

@ -2693,8 +2693,7 @@ nsExternalHelperAppService::GetTypeFromExtension(const nsACString& aFileExt,
// Read the MIME type from the category entry, if available
nsCString type;
nsresult rv = catMan->GetCategoryEntry("ext-to-type-mapping",
lowercaseFileExt.get(),
getter_Copies(type));
lowercaseFileExt, type);
if (NS_SUCCEEDED(rv)) {
aContentType = type;
return NS_OK;

View File

@ -13,7 +13,7 @@
#include "nsCategoryCache.h"
nsCategoryObserver::nsCategoryObserver(const char* aCategory)
nsCategoryObserver::nsCategoryObserver(const nsACString& aCategory)
: mCategory(aCategory)
, mCallback(nullptr)
, mClosure(nullptr)
@ -43,9 +43,7 @@ nsCategoryObserver::nsCategoryObserver(const char* aCategory)
strings->GetNext(entryName);
nsCString entryValue;
rv = catMan->GetCategoryEntry(aCategory,
entryName.get(),
getter_Copies(entryValue));
rv = catMan->GetCategoryEntry(aCategory, entryName, entryValue);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsISupports> service = do_GetService(entryValue.get());
if (service) {
@ -151,9 +149,7 @@ nsCategoryObserver::Observe(nsISupports* aSubject, const char* aTopic,
}
nsCString entryValue;
catMan->GetCategoryEntry(mCategory.get(),
str.get(),
getter_Copies(entryValue));
catMan->GetCategoryEntry(mCategory, str, entryValue);
nsCOMPtr<nsISupports> service = do_GetService(entryValue.get());

View File

@ -28,7 +28,7 @@ class nsCategoryObserver final : public nsIObserver
~nsCategoryObserver();
public:
explicit nsCategoryObserver(const char* aCategory);
explicit nsCategoryObserver(const nsACString& aCategory);
void ListenerDied();
void SetListener(void(aCallback)(void*), void* aClosure);
@ -104,7 +104,7 @@ private:
// Lazy initialization, so that services in this category can't
// cause reentrant getService (bug 386376)
if (!mObserver) {
mObserver = new nsCategoryObserver(mCategoryName.get());
mObserver = new nsCategoryObserver(mCategoryName);
mObserver->SetListener(nsCategoryCache<T>::OnCategoryChanged, this);
}
}

View File

@ -206,45 +206,47 @@ CategoryNode::operator new(size_t aSize, CategoryAllocator* aArena)
return aArena->Allocate(aSize, mozilla::fallible);
}
static inline const char*
MaybeStrdup(const nsACString& aStr, CategoryAllocator* aArena)
{
if (aStr.IsLiteral()) {
return aStr.BeginReading();
}
return ArenaStrdup(PromiseFlatCString(aStr).get(), *aArena);
}
nsresult
CategoryNode::GetLeaf(const char* aEntryName,
char** aResult)
CategoryNode::GetLeaf(const nsACString& aEntryName,
nsACString& aResult)
{
MutexAutoLock lock(mLock);
nsresult rv = NS_ERROR_NOT_AVAILABLE;
CategoryLeaf* ent = mTable.GetEntry(aEntryName);
CategoryLeaf* ent = mTable.GetEntry(PromiseFlatCString(aEntryName).get());
if (ent && ent->value) {
*aResult = NS_strdup(ent->value);
if (*aResult) {
rv = NS_OK;
}
aResult.Assign(ent->value);
return NS_OK;
}
return rv;
}
nsresult
CategoryNode::AddLeaf(const char* aEntryName,
const char* aValue,
CategoryNode::AddLeaf(const nsACString& aEntryName,
const nsACString& aValue,
bool aReplace,
char** aResult,
nsACString& aResult,
CategoryAllocator* aArena)
{
if (aResult) {
*aResult = nullptr;
}
aResult.SetIsVoid(true);
auto entryName = PromiseFlatCString(aEntryName);
MutexAutoLock lock(mLock);
CategoryLeaf* leaf = mTable.GetEntry(aEntryName);
CategoryLeaf* leaf = mTable.GetEntry(entryName.get());
if (!leaf) {
const char* arenaEntryName = ArenaStrdup(aEntryName, *aArena);
if (!arenaEntryName) {
return NS_ERROR_OUT_OF_MEMORY;
}
leaf = mTable.PutEntry(arenaEntryName);
leaf = mTable.PutEntry(MaybeStrdup(aEntryName, aArena));
if (!leaf) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -254,31 +256,24 @@ CategoryNode::AddLeaf(const char* aEntryName,
return NS_ERROR_INVALID_ARG;
}
const char* arenaValue = ArenaStrdup(aValue, *aArena);
if (!arenaValue) {
return NS_ERROR_OUT_OF_MEMORY;
if (leaf->value) {
aResult.AssignLiteral(leaf->value, strlen(leaf->value));
} else {
aResult.SetIsVoid(true);
}
if (aResult && leaf->value) {
*aResult = ToNewCString(nsDependentCString(leaf->value));
if (!*aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
leaf->value = arenaValue;
leaf->value = MaybeStrdup(aValue, aArena);
return NS_OK;
}
void
CategoryNode::DeleteLeaf(const char* aEntryName)
CategoryNode::DeleteLeaf(const nsACString& aEntryName)
{
// we don't throw any errors, because it normally doesn't matter
// and it makes JS a lot cleaner
MutexAutoLock lock(mLock);
// we can just remove the entire hash entry without introspection
mTable.RemoveEntry(aEntryName);
mTable.RemoveEntry(PromiseFlatCString(aEntryName).get());
}
nsresult
@ -339,8 +334,7 @@ CategoryEnumerator::Create(nsClassHashtable<nsDepCharHashKey, CategoryNode>&
// if a category has no entries, we pretend it doesn't exist
CategoryNode* aNode = iter.UserData();
if (aNode->Count()) {
const char* str = iter.Key();
enumObj->mArray[enumObj->mCount++] = str;
enumObj->mArray[enumObj->mCount++] = iter.Key();
}
}
@ -423,10 +417,10 @@ nsCategoryManager::~nsCategoryManager()
}
inline CategoryNode*
nsCategoryManager::get_category(const char* aName)
nsCategoryManager::get_category(const nsACString& aName)
{
CategoryNode* node;
if (!mTable.Get(aName, &node)) {
if (!mTable.Get(PromiseFlatCString(aName).get(), &node)) {
return nullptr;
}
return node;
@ -469,7 +463,7 @@ class CategoryNotificationRunnable : public Runnable
public:
CategoryNotificationRunnable(nsISupports* aSubject,
const char* aTopic,
const char* aData)
const nsACString& aData)
: Runnable("CategoryNotificationRunnable")
, mSubject(aSubject)
, mTopic(aTopic)
@ -502,8 +496,8 @@ CategoryNotificationRunnable::Run()
void
nsCategoryManager::NotifyObservers(const char* aTopic,
const char* aCategoryName,
const char* aEntryName)
const nsACString& aCategoryName,
const nsACString& aEntryName)
{
if (mSuppressNotifications) {
return;
@ -511,14 +505,14 @@ nsCategoryManager::NotifyObservers(const char* aTopic,
RefPtr<CategoryNotificationRunnable> r;
if (aEntryName) {
if (aEntryName.Length()) {
nsCOMPtr<nsISupportsCString> entry =
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID);
if (!entry) {
return;
}
nsresult rv = entry->SetData(nsDependentCString(aEntryName));
nsresult rv = entry->SetData(aEntryName);
if (NS_FAILED(rv)) {
return;
}
@ -534,16 +528,10 @@ nsCategoryManager::NotifyObservers(const char* aTopic,
}
NS_IMETHODIMP
nsCategoryManager::GetCategoryEntry(const char* aCategoryName,
const char* aEntryName,
char** aResult)
nsCategoryManager::GetCategoryEntry(const nsACString& aCategoryName,
const nsACString& aEntryName,
nsACString& aResult)
{
if (NS_WARN_IF(!aCategoryName) ||
NS_WARN_IF(!aEntryName) ||
NS_WARN_IF(!aResult)) {
return NS_ERROR_INVALID_ARG;
}
nsresult status = NS_ERROR_NOT_AVAILABLE;
CategoryNode* category;
@ -560,12 +548,12 @@ nsCategoryManager::GetCategoryEntry(const char* aCategoryName,
}
NS_IMETHODIMP
nsCategoryManager::AddCategoryEntry(const char* aCategoryName,
const char* aEntryName,
const char* aValue,
nsCategoryManager::AddCategoryEntry(const nsACString& aCategoryName,
const nsACString& aEntryName,
const nsACString& aValue,
bool aPersist,
bool aReplace,
char** aResult)
nsACString& aResult)
{
if (aPersist) {
NS_ERROR("Category manager doesn't support persistence.");
@ -577,15 +565,13 @@ nsCategoryManager::AddCategoryEntry(const char* aCategoryName,
}
void
nsCategoryManager::AddCategoryEntry(const char* aCategoryName,
const char* aEntryName,
const char* aValue,
nsCategoryManager::AddCategoryEntry(const nsACString& aCategoryName,
const nsACString& aEntryName,
const nsACString& aValue,
bool aReplace,
char** aOldValue)
nsACString& aOldValue)
{
if (aOldValue) {
*aOldValue = nullptr;
}
aOldValue.SetIsVoid(true);
// Before we can insert a new entry, we'll need to
// find the |CategoryNode| to put it in...
@ -598,8 +584,8 @@ nsCategoryManager::AddCategoryEntry(const char* aCategoryName,
// That category doesn't exist yet; let's make it.
category = CategoryNode::Create(&mArena);
char* categoryName = ArenaStrdup(aCategoryName, mArena);
mTable.Put(categoryName, category);
mTable.Put(MaybeStrdup(aCategoryName, &mArena),
category);
}
}
@ -607,41 +593,28 @@ nsCategoryManager::AddCategoryEntry(const char* aCategoryName,
return;
}
// We will need the return value of AddLeaf even if the called doesn't want it
char* oldEntry = nullptr;
nsresult rv = category->AddLeaf(aEntryName,
aValue,
aReplace,
&oldEntry,
aOldValue,
&mArena);
if (NS_SUCCEEDED(rv)) {
if (oldEntry) {
if (!aOldValue.IsEmpty()) {
NotifyObservers(NS_XPCOM_CATEGORY_ENTRY_REMOVED_OBSERVER_ID,
aCategoryName, aEntryName);
}
NotifyObservers(NS_XPCOM_CATEGORY_ENTRY_ADDED_OBSERVER_ID,
aCategoryName, aEntryName);
if (aOldValue) {
*aOldValue = oldEntry;
} else {
free(oldEntry);
}
}
}
NS_IMETHODIMP
nsCategoryManager::DeleteCategoryEntry(const char* aCategoryName,
const char* aEntryName,
nsCategoryManager::DeleteCategoryEntry(const nsACString& aCategoryName,
const nsACString& aEntryName,
bool aDontPersist)
{
if (NS_WARN_IF(!aCategoryName) ||
NS_WARN_IF(!aEntryName)) {
return NS_ERROR_INVALID_ARG;
}
/*
Note: no errors are reported since failure to delete
probably won't hurt you, and returning errors seriously
@ -665,12 +638,8 @@ nsCategoryManager::DeleteCategoryEntry(const char* aCategoryName,
}
NS_IMETHODIMP
nsCategoryManager::DeleteCategory(const char* aCategoryName)
nsCategoryManager::DeleteCategory(const nsACString& aCategoryName)
{
if (NS_WARN_IF(!aCategoryName)) {
return NS_ERROR_INVALID_ARG;
}
// the categories are arena-allocated, so we don't
// actually delete them. We just remove all of the
// leaf nodes.
@ -684,21 +653,16 @@ nsCategoryManager::DeleteCategory(const char* aCategoryName)
if (category) {
category->Clear();
NotifyObservers(NS_XPCOM_CATEGORY_CLEARED_OBSERVER_ID,
aCategoryName, nullptr);
aCategoryName, VoidCString());
}
return NS_OK;
}
NS_IMETHODIMP
nsCategoryManager::EnumerateCategory(const char* aCategoryName,
nsCategoryManager::EnumerateCategory(const nsACString& aCategoryName,
nsISimpleEnumerator** aResult)
{
if (NS_WARN_IF(!aCategoryName) ||
NS_WARN_IF(!aResult)) {
return NS_ERROR_INVALID_ARG;
}
CategoryNode* category;
{
MutexAutoLock lock(mLock);
@ -767,8 +731,10 @@ NS_CreateServicesFromCategory(const char* aCategory,
return;
}
nsDependentCString category(aCategory);
nsCOMPtr<nsISimpleEnumerator> enumerator;
rv = categoryManager->EnumerateCategory(aCategory,
rv = categoryManager->EnumerateCategory(category,
getter_AddRefs(enumerator));
if (NS_FAILED(rv)) {
return;
@ -790,8 +756,7 @@ NS_CreateServicesFromCategory(const char* aCategory,
}
nsCString contractID;
rv = categoryManager->GetCategoryEntry(aCategory, entryString.get(),
getter_Copies(contractID));
rv = categoryManager->GetCategoryEntry(category, entryString, contractID);
if (NS_FAILED(rv)) {
continue;
}

View File

@ -50,16 +50,16 @@ public:
class CategoryNode
{
public:
nsresult GetLeaf(const char* aEntryName,
char** aResult);
nsresult GetLeaf(const nsACString& aEntryName,
nsACString& aResult);
nsresult AddLeaf(const char* aEntryName,
const char* aValue,
nsresult AddLeaf(const nsACString& aEntryName,
const nsACString& aValue,
bool aReplace,
char** aResult,
nsACString& aResult,
CategoryAllocator* aArena);
void DeleteLeaf(const char* aEntryName);
void DeleteLeaf(const nsACString& aEntryName);
void Clear()
{
@ -114,11 +114,20 @@ public:
*/
nsresult SuppressNotifications(bool aSuppress);
void AddCategoryEntry(const char* aCategory,
const char* aKey,
const char* aValue,
bool aReplace = true,
char** aOldValue = nullptr);
void AddCategoryEntry(const nsACString& aCategory,
const nsACString& aKey,
const nsACString& aValue,
bool aReplace,
nsACString& aOldValue);
void AddCategoryEntry(const nsACString& aCategory,
const nsACString& aKey,
const nsACString& aValue,
bool aReplace = true)
{
nsCString oldValue;
return AddCategoryEntry(aCategory, aKey, aValue, aReplace, oldValue);
}
static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
void InitMemoryReporter();
@ -134,10 +143,10 @@ private:
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
CategoryNode* get_category(const char* aName);
CategoryNode* get_category(const nsACString& aName);
void NotifyObservers(const char* aTopic,
const char* aCategoryName, // must be a static string
const char* aEntryName);
const nsACString& aCategoryName, // must be a static string
const nsACString& aEntryName);
CategoryAllocator mArena;
nsClassHashtable<nsDepCharHashKey, CategoryNode> mTable;

View File

@ -102,12 +102,6 @@ nsGetServiceFromCategory::operator()(const nsIID& aIID,
goto error;
}
if (!mCategory || !mEntry) {
// when categories have defaults, use that for null mEntry
rv = NS_ERROR_NULL_POINTER;
goto error;
}
rv = compMgr->nsComponentManagerImpl::GetService(kCategoryManagerCID,
NS_GET_IID(nsICategoryManager),
getter_AddRefs(catman));
@ -116,8 +110,7 @@ nsGetServiceFromCategory::operator()(const nsIID& aIID,
}
/* find the contractID for category.entry */
rv = catman->GetCategoryEntry(mCategory, mEntry,
getter_Copies(value));
rv = catman->GetCategoryEntry(mCategory, mEntry, value);
if (NS_FAILED(rv)) {
goto error;
}
@ -558,9 +551,10 @@ nsComponentManagerImpl::RegisterModule(const mozilla::Module* aModule,
if (aModule->mCategoryEntries) {
const mozilla::Module::CategoryEntry* entry;
for (entry = aModule->mCategoryEntries; entry->category; ++entry)
nsCategoryManager::GetSingleton()->AddCategoryEntry(entry->category,
entry->entry,
entry->value);
nsCategoryManager::GetSingleton()->AddCategoryEntry(
AsLiteralCString(entry->category),
AsLiteralCString(entry->entry),
AsLiteralCString(entry->value));
}
}
@ -780,7 +774,8 @@ nsComponentManagerImpl::ManifestCategory(ManifestProcessingContext& aCx,
char* value = aArgv[2];
nsCategoryManager::GetSingleton()->
AddCategoryEntry(category, key, value);
AddCategoryEntry(nsDependentCString(category), nsDependentCString(key),
nsDependentCString(value));
}
void
@ -1550,8 +1545,8 @@ nsComponentManagerImpl::LoaderForExtension(const nsACString& aExt)
{
nsCOMPtr<mozilla::ModuleLoader> loader = mLoaderMap.Get(aExt);
if (!loader) {
loader = do_GetServiceFromCategory("module-loader",
PromiseFlatCString(aExt).get());
loader = do_GetServiceFromCategory(NS_LITERAL_CSTRING("module-loader"),
aExt);
if (!loader) {
return nullptr;
}

View File

@ -7,11 +7,15 @@
interface nsISimpleEnumerator;
%{C++
#include "nsString.h"
%}
/*
* nsICategoryManager
*/
[scriptable, uuid(3275b2cd-af6d-429a-80d7-f0c5120342ac)]
[builtinclass, scriptable, uuid(3275b2cd-af6d-429a-80d7-f0c5120342ac)]
interface nsICategoryManager : nsISupports
{
/**
@ -20,7 +24,7 @@ interface nsICategoryManager : nsISupports
* @param aEntry The entry you're looking for ("http")
* @return The value.
*/
string getCategoryEntry(in string aCategory, in string aEntry);
ACString getCategoryEntry(in ACString aCategory, in ACString aEntry);
/**
* Add an entry to a category.
@ -31,9 +35,9 @@ interface nsICategoryManager : nsISupports
* @param aReplace Should we replace an existing entry?
* @return Previous entry, if any
*/
string addCategoryEntry(in string aCategory, in string aEntry,
in string aValue, in boolean aPersist,
in boolean aReplace);
ACString addCategoryEntry(in ACString aCategory, in ACString aEntry,
in ACString aValue, in boolean aPersist,
in boolean aReplace);
/**
* Delete an entry from the category.
@ -41,14 +45,14 @@ interface nsICategoryManager : nsISupports
* @param aEntry The entry to be added ("http")
* @param aPersist Delete persistent data from registry, if present?
*/
void deleteCategoryEntry(in string aCategory, in string aEntry,
in boolean aPersist);
void deleteCategoryEntry(in ACString aCategory, in ACString aEntry,
in boolean aPersist);
/**
* Delete a category and all entries.
* @param aCategory The category to be deleted.
*/
void deleteCategory(in string aCategory);
void deleteCategory(in ACString aCategory);
/**
* Enumerate the entries in a category.
@ -56,7 +60,7 @@ interface nsICategoryManager : nsISupports
* @return a simple enumerator, each result QIs to
* nsISupportsCString.
*/
nsISimpleEnumerator enumerateCategory(in string aCategory);
nsISimpleEnumerator enumerateCategory(in ACString aCategory);
/**
* Enumerate all existing categories
@ -65,5 +69,60 @@ interface nsICategoryManager : nsISupports
* nsISupportsCString.
*/
nsISimpleEnumerator enumerateCategories();
%{C++
template<size_t N>
nsresult
GetCategoryEntry(const char (&aCategory)[N], const nsACString& aEntry,
nsACString& aResult)
{
return GetCategoryEntry(nsLiteralCString(aCategory),
aEntry, aResult);
}
template<size_t N, size_t M>
nsresult
GetCategoryEntry(const char (&aCategory)[N], const char (&aEntry)[M],
nsACString& aResult)
{
return GetCategoryEntry(nsLiteralCString(aCategory),
nsLiteralCString(aEntry),
aResult);
}
nsresult
AddCategoryEntry(const nsACString& aCategory, const nsACString& aEntry,
const nsACString& aValue, bool aPersist, bool aReplace)
{
nsCString oldValue;
return AddCategoryEntry(aCategory, aEntry, aValue, aPersist, aReplace,
oldValue);
}
template<size_t N>
nsresult
AddCategoryEntry(const char (&aCategory)[N], const nsACString& aEntry,
const nsACString& aValue, bool aPersist, bool aReplace)
{
nsCString oldValue;
return AddCategoryEntry(nsLiteralCString(aCategory), aEntry, aValue,
aPersist, aReplace, oldValue);
}
template<size_t N>
nsresult
DeleteCategoryEntry(const char (&aCategory)[N], const nsACString& aEntry, bool aPersist)
{
return DeleteCategoryEntry(nsLiteralCString(aCategory), aEntry, aPersist);
}
template<size_t N>
nsresult
EnumerateCategory(const char (&aCategory)[N], nsISimpleEnumerator** aResult)
{
return EnumerateCategory(nsLiteralCString(aCategory), aResult);
}
%}
};

View File

@ -9,6 +9,7 @@
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
#include "nsString.h"
inline const nsGetServiceByCID
do_GetService(const nsCID& aCID)
@ -37,7 +38,7 @@ do_GetService(const char* aContractID, nsresult* aError)
class MOZ_STACK_CLASS nsGetServiceFromCategory final : public nsCOMPtr_helper
{
public:
nsGetServiceFromCategory(const char* aCategory, const char* aEntry,
nsGetServiceFromCategory(const nsACString& aCategory, const nsACString& aEntry,
nsresult* aErrorPtr)
: mCategory(aCategory)
, mEntry(aEntry)
@ -48,13 +49,13 @@ public:
virtual nsresult NS_FASTCALL operator()(const nsIID&, void**) const
override;
protected:
const char* mCategory;
const char* mEntry;
const nsCString mCategory;
const nsCString mEntry;
nsresult* mErrorPtr;
};
inline const nsGetServiceFromCategory
do_GetServiceFromCategory(const char* aCategory, const char* aEntry,
do_GetServiceFromCategory(const nsACString& aCategory, const nsACString& aEntry,
nsresult* aError = 0)
{
return nsGetServiceFromCategory(aCategory, aEntry, aError);

View File

@ -358,8 +358,8 @@ nsDirectoryService::RegisterCategoryProviders()
strings->GetNext(entry);
nsCString contractID;
catman->GetCategoryEntry(XPCOM_DIRECTORY_PROVIDER_CATEGORY, entry.get(),
getter_Copies(contractID));
catman->GetCategoryEntry(XPCOM_DIRECTORY_PROVIDER_CATEGORY, entry,
contractID);
if (!contractID.IsVoid()) {
nsCOMPtr<nsIDirectoryServiceProvider> provider = do_GetService(contractID.get());