mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-26 23:23:33 +00:00
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:
parent
83b3ac8f23
commit
7aa3564a28
@ -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) {
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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 =
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)) {
|
||||
|
||||
|
@ -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()));
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
%}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
Loading…
x
Reference in New Issue
Block a user