--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -6947,18 +6947,17 @@ nsContentUtils::FindInternalContentViewe
nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
if (!catMan)
return nullptr;
nsCOMPtr<nsIDocumentLoaderFactory> docFactory;
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) {
if (contractID.EqualsLiteral(CONTENT_DLF_CONTRACTID))
*aLoaderType = TYPE_CONTENT;
else if (contractID.EqualsLiteral(PLUGIN_DLF_CONTRACTID))
*aLoaderType = TYPE_PLUGIN;
else
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1083,18 +1083,18 @@ nsExternalResourceMap::PendingLoad::Setu
new LoadgroupCallbacks(callbacks);
newLoadGroup->SetNotificationCallbacks(newCallbacks);
// This is some serious hackery cribbed from docshell
nsCOMPtr<nsICategoryManager> catMan =
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());
NS_ENSURE_TRUE(docLoaderFactory, NS_ERROR_NOT_AVAILABLE);
nsCOMPtr<nsIContentViewer> viewer;
nsCOMPtr<nsIStreamListener> listener;
rv = docLoaderFactory->CreateInstance("external-resource", chan, newLoadGroup,
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -2766,45 +2766,42 @@ nsPluginHost::RegisterWithCategoryManage
aMimeType.get(), aType == ePluginUnregister ? "yes" : "no"));
nsCOMPtr<nsICategoryManager> catMan =
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
if (!catMan) {
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
if (HavePluginForType(aMimeType)) {
return;
}
} else {
MOZ_ASSERT(aType == ePluginUnregister, "Unknown nsRegisterType");
}
// 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);
}
}
}
nsresult
nsPluginHost::WritePluginInfo()
{
MOZ_ASSERT(XRE_IsParentProcess());
--- a/dom/push/PushNotifier.cpp
+++ b/dom/push/PushNotifier.cpp
@@ -315,19 +315,17 @@ PushDispatcher::DoNotifyObservers(nsISup
if (!obsService) {
return NS_ERROR_FAILURE;
}
// If there's a service for this push category, make sure it is alive.
nsCOMPtr<nsICategoryManager> catMan =
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.
nsCOMPtr<nsISupports> service = do_GetService(contractId.get());
}
}
return obsService->NotifyObservers(aSubject, aTopic,
NS_ConvertUTF8toUTF16(mScope).get());
--- a/gfx/thebes/gfxSVGGlyphs.cpp
+++ b/gfx/thebes/gfxSVGGlyphs.cpp
@@ -132,17 +132,17 @@ gfxSVGGlyphs::FindOrCreateGlyphsDocument
return result;
}
nsresult
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 =
do_GetService(contractId.get());
NS_ASSERTION(docLoaderFactory, "Couldn't get DocumentLoaderFactory");
nsCOMPtr<nsIContentViewer> viewer;
rv = docLoaderFactory->CreateInstanceForDocument(nullptr, mDocument, nullptr, getter_AddRefs(viewer));
--- a/image/SVGDocumentWrapper.cpp
+++ b/image/SVGDocumentWrapper.cpp
@@ -327,17 +327,17 @@ SVGDocumentWrapper::SetupViewer(nsIReque
NS_ENSURE_TRUE(newLoadGroup, NS_ERROR_OUT_OF_MEMORY);
newLoadGroup->SetLoadGroup(loadGroup);
nsCOMPtr<nsICategoryManager> catMan =
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
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());
NS_ENSURE_TRUE(docLoaderFactory, NS_ERROR_NOT_AVAILABLE);
nsCOMPtr<nsIContentViewer> viewer;
nsCOMPtr<nsIStreamListener> listener;
rv = docLoaderFactory->CreateInstance("external-resource", chan,
--- a/layout/base/nsStyleSheetService.cpp
+++ b/layout/base/nsStyleSheetService.cpp
@@ -69,17 +69,17 @@ nsStyleSheetService::RegisterFromEnumera
nsCOMPtr<nsISupportsCString> icStr = do_QueryInterface(element);
NS_ASSERTION(icStr,
"category manager entries must be nsISupportsCStrings");
nsAutoCString name;
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);
if (uri)
LoadAndRegisterSheetInternal(uri, aSheetType);
}
}
--- a/toolkit/components/commandlines/nsCommandLine.cpp
+++ b/toolkit/components/commandlines/nsCommandLine.cpp
@@ -510,19 +510,18 @@ nsCommandLine::EnumerateHandlers(Enumera
NS_ENSURE_TRUE(strenum, NS_ERROR_UNEXPECTED);
nsAutoCString entry;
bool hasMore;
while (NS_SUCCEEDED(strenum->HasMore(&hasMore)) && hasMore) {
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;
nsCOMPtr<nsICommandLineHandler> clh(do_GetService(contractID.get()));
if (!clh) {
LogConsoleMessage(u"Contract ID '%s' was registered as a command line handler for entry '%s', but could not be created.",
contractID.get(), entry.get());
continue;
@@ -557,18 +556,17 @@ nsCommandLine::EnumerateValidators(Enume
nsAutoCString entry;
bool hasMore;
while (NS_SUCCEEDED(strenum->HasMore(&hasMore)) && hasMore) {
strenum->GetNext(entry);
nsCString contractID;
rv = catman->GetCategoryEntry("command-line-validator",
- entry.get(),
- getter_Copies(contractID));
+ entry, contractID);
if (contractID.IsVoid())
continue;
nsCOMPtr<nsICommandLineValidator> clv(do_GetService(contractID.get()));
if (!clv)
continue;
rv = (aCallback)(clv, this, aClosure);
--- a/toolkit/xre/nsAppStartupNotifier.cpp
+++ b/toolkit/xre/nsAppStartupNotifier.cpp
@@ -25,33 +25,34 @@ NS_IMETHODIMP nsAppStartupNotifier::Obse
NS_ENSURE_ARG(aTopic);
nsresult rv;
// now initialize all startup listeners
nsCOMPtr<nsICategoryManager> categoryManager =
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;
nsCOMPtr<nsISupports> entry;
while (NS_SUCCEEDED(enumerator->GetNext(getter_AddRefs(entry)))) {
nsCOMPtr<nsISupportsCString> category = do_QueryInterface(entry, &rv);
if (NS_SUCCEEDED(rv)) {
nsAutoCString categoryEntry;
rv = category->GetData(categoryEntry);
nsCString contractId;
- categoryManager->GetCategoryEntry(aTopic,
- categoryEntry.get(),
- getter_Copies(contractId));
+ categoryManager->GetCategoryEntry(topic, categoryEntry,
+ contractId);
if (NS_SUCCEEDED(rv)) {
// If we see the word "service," in the beginning
// of the contractId then we create it as a service
// if not we do a createInstance
nsCOMPtr<nsISupports> startupInstance;
--- a/uriloader/base/nsURILoader.cpp
+++ b/uriloader/base/nsURILoader.cpp
@@ -460,18 +460,17 @@ nsresult nsDocumentOpenInfo::DispatchCon
// the chance to register, as it is contained in a not-yet-loaded
// module, but which has registered a contract ID.
//
nsCOMPtr<nsICategoryManager> catman =
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
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()));
listener = do_CreateInstance(contractidString.get());
LOG((" Listener from category manager: 0x%p", listener.get()));
if (listener && TryContentListener(listener, aChannel)) {
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -2693,18 +2693,17 @@ nsExternalHelperAppService::GetTypeFromE
do_GetService("@mozilla.org/categorymanager;1"));
if (catMan) {
// The extension in the category entry is always stored as lowercase
nsAutoCString lowercaseFileExt(aFileExt);
ToLowerCase(lowercaseFileExt);
// 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;
}
}
return NS_ERROR_NOT_AVAILABLE;
}
--- a/xpcom/components/nsCategoryCache.cpp
+++ b/xpcom/components/nsCategoryCache.cpp
@@ -8,17 +8,17 @@
#include "mozilla/Services.h"
#include "nsISupportsPrimitives.h"
#include "nsIStringEnumerator.h"
#include "nsXPCOMCID.h"
#include "nsCategoryCache.h"
-nsCategoryObserver::nsCategoryObserver(const char* aCategory)
+nsCategoryObserver::nsCategoryObserver(const nsACString& aCategory)
: mCategory(aCategory)
, mCallback(nullptr)
, mClosure(nullptr)
, mObserversRemoved(false)
{
MOZ_ASSERT(NS_IsMainThread());
// First, enumerate the currently existing entries
nsCOMPtr<nsICategoryManager> catMan =
@@ -38,19 +38,17 @@ nsCategoryObserver::nsCategoryObserver(c
MOZ_ASSERT(strings);
bool more;
while (NS_SUCCEEDED(strings->HasMore(&more)) && more) {
nsAutoCString entryName;
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) {
mHash.Put(entryName, service);
}
}
}
@@ -146,19 +144,17 @@ nsCategoryObserver::Observe(nsISupports*
nsCOMPtr<nsICategoryManager> catMan =
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
if (!catMan) {
return NS_OK;
}
nsCString entryValue;
- catMan->GetCategoryEntry(mCategory.get(),
- str.get(),
- getter_Copies(entryValue));
+ catMan->GetCategoryEntry(mCategory, str, entryValue);
nsCOMPtr<nsISupports> service = do_GetService(entryValue.get());
if (service) {
mHash.Put(str, service);
}
if (mCallback) {
mCallback(mClosure);
--- a/xpcom/components/nsCategoryCache.h
+++ b/xpcom/components/nsCategoryCache.h
@@ -23,17 +23,17 @@
#include "nsXPCOM.h"
#include "MainThreadUtils.h"
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);
nsInterfaceHashtable<nsCStringHashKey, nsISupports>& GetHash()
{
return mHash;
}
@@ -99,17 +99,17 @@ public:
}
private:
void LazyInit()
{
// 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);
}
}
void AddEntries(nsCOMArray<T>& aResult)
{
for (auto iter = mObserver->GetHash().Iter(); !iter.Done(); iter.Next()) {
nsISupports* entry = iter.UserData();
--- a/xpcom/components/nsCategoryManager.cpp
+++ b/xpcom/components/nsCategoryManager.cpp
@@ -201,89 +201,84 @@ CategoryNode::Create(CategoryAllocator*
CategoryNode::~CategoryNode() = default;
void*
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;
}
}
if (leaf->value && !aReplace) {
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
CategoryNode::Enumerate(nsISimpleEnumerator** aResult)
{
if (NS_WARN_IF(!aResult)) {
return NS_ERROR_INVALID_ARG;
}
@@ -334,18 +329,17 @@ CategoryEnumerator::Create(nsClassHashta
delete enumObj;
return nullptr;
}
for (auto iter = aTable.Iter(); !iter.Done(); iter.Next()) {
// 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();
}
}
return enumObj;
}
//
@@ -418,20 +412,20 @@ nsCategoryManager::~nsCategoryManager()
{
// the hashtable contains entries that must be deleted before the arena is
// destroyed, or else you will have PRLocks undestroyed and other Really
// Bad Stuff (TM)
mTable.Clear();
}
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;
}
MOZ_DEFINE_MALLOC_SIZE_OF(CategoryManagerMallocSizeOf)
NS_IMETHODIMP
@@ -464,17 +458,17 @@ nsCategoryManager::SizeOfIncludingThis(m
namespace {
class CategoryNotificationRunnable : public Runnable
{
public:
CategoryNotificationRunnable(nsISupports* aSubject,
const char* aTopic,
- const char* aData)
+ const nsACString& aData)
: Runnable("CategoryNotificationRunnable")
, mSubject(aSubject)
, mTopic(aTopic)
, mData(aData)
{
}
NS_DECL_NSIRUNNABLE
@@ -497,156 +491,135 @@ CategoryNotificationRunnable::Run()
return NS_OK;
}
} // namespace
void
nsCategoryManager::NotifyObservers(const char* aTopic,
- const char* aCategoryName,
- const char* aEntryName)
+ const nsACString& aCategoryName,
+ const nsACString& aEntryName)
{
if (mSuppressNotifications) {
return;
}
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;
}
r = new CategoryNotificationRunnable(entry, aTopic, aCategoryName);
} else {
r = new CategoryNotificationRunnable(NS_ISUPPORTS_CAST(nsICategoryManager*,
this),
aTopic, aCategoryName);
}
NS_DispatchToMainThread(r);
}
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;
{
MutexAutoLock lock(mLock);
category = get_category(aCategoryName);
}
if (category) {
status = category->GetLeaf(aEntryName, aResult);
}
return status;
}
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.");
return NS_ERROR_INVALID_ARG;
}
AddCategoryEntry(aCategoryName, aEntryName, aValue, aReplace, aResult);
return NS_OK;
}
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...
CategoryNode* category;
{
MutexAutoLock lock(mLock);
category = get_category(aCategoryName);
if (!category) {
// 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);
}
}
if (!category) {
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
inconveniences JS clients
*/
CategoryNode* category;
{
@@ -660,50 +633,41 @@ nsCategoryManager::DeleteCategoryEntry(c
NotifyObservers(NS_XPCOM_CATEGORY_ENTRY_REMOVED_OBSERVER_ID,
aCategoryName, aEntryName);
}
return NS_OK;
}
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.
CategoryNode* category;
{
MutexAutoLock lock(mLock);
category = get_category(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);
category = get_category(aCategoryName);
}
if (!category) {
return NS_NewEmptyEnumerator(aResult);
@@ -762,18 +726,20 @@ NS_CreateServicesFromCategory(const char
nsresult rv;
nsCOMPtr<nsICategoryManager> categoryManager =
do_GetService("@mozilla.org/categorymanager;1");
if (!categoryManager) {
return;
}
+ nsDependentCString category(aCategory);
+
nsCOMPtr<nsISimpleEnumerator> enumerator;
- rv = categoryManager->EnumerateCategory(aCategory,
+ rv = categoryManager->EnumerateCategory(category,
getter_AddRefs(enumerator));
if (NS_FAILED(rv)) {
return;
}
nsCOMPtr<nsIUTF8StringEnumerator> senumerator =
do_QueryInterface(enumerator);
if (!senumerator) {
@@ -785,18 +751,17 @@ NS_CreateServicesFromCategory(const char
while (NS_SUCCEEDED(senumerator->HasMore(&hasMore)) && hasMore) {
// From here on just skip any error we get.
nsAutoCString entryString;
if (NS_FAILED(senumerator->GetNext(entryString))) {
continue;
}
nsCString contractID;
- rv = categoryManager->GetCategoryEntry(aCategory, entryString.get(),
- getter_Copies(contractID));
+ rv = categoryManager->GetCategoryEntry(category, entryString, contractID);
if (NS_FAILED(rv)) {
continue;
}
nsCOMPtr<nsISupports> instance = do_GetService(contractID.get());
if (!instance) {
LogMessage("While creating services from category '%s', could not create service for entry '%s', contract ID '%s'",
aCategory, entryString.get(), contractID.get());
--- a/xpcom/components/nsCategoryManager.h
+++ b/xpcom/components/nsCategoryManager.h
@@ -45,26 +45,26 @@ public:
/**
* CategoryNode keeps a hashtable of its entries.
* the CategoryNode itself is permanently allocated in
* the arena.
*/
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()
{
mozilla::MutexAutoLock lock(mLock);
mTable.Clear();
}
uint32_t Count()
@@ -109,40 +109,49 @@ public:
/**
* Suppress or unsuppress notifications of category changes to the
* observer service. This is to be used by nsComponentManagerImpl
* on startup while reading the stored category list.
*/
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();
static nsCategoryManager* GetSingleton();
static void Destroy();
private:
static nsCategoryManager* gCategoryManager;
nsCategoryManager();
~nsCategoryManager();
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;
mozilla::Mutex mLock;
bool mSuppressNotifications;
};
#endif
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -97,32 +97,25 @@ nsGetServiceFromCategory::operator()(con
nsCString value;
nsCOMPtr<nsICategoryManager> catman;
nsComponentManagerImpl* compMgr = nsComponentManagerImpl::gComponentManager;
if (!compMgr) {
rv = NS_ERROR_NOT_INITIALIZED;
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));
if (NS_FAILED(rv)) {
goto error;
}
/* 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;
}
if (value.IsVoid()) {
rv = NS_ERROR_SERVICE_NOT_AVAILABLE;
goto error;
}
@@ -550,19 +543,20 @@ nsComponentManagerImpl::RegisterModule(c
}
MOZ_ASSERT(!entry->cid, "Incorrectly terminated contract list");
}
}
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));
}
}
void
nsComponentManagerImpl::RegisterCIDEntryLocked(
const mozilla::Module::CIDEntry* aEntry,
KnownModule* aModule)
{
@@ -772,17 +766,18 @@ void
nsComponentManagerImpl::ManifestCategory(ManifestProcessingContext& aCx,
int aLineNo, char* const* aArgv)
{
char* category = aArgv[0];
char* key = aArgv[1];
char* value = aArgv[2];
nsCategoryManager::GetSingleton()->
- AddCategoryEntry(category, key, value);
+ AddCategoryEntry(nsDependentCString(category), nsDependentCString(key),
+ nsDependentCString(value));
}
void
nsComponentManagerImpl::RereadChromeManifests(bool aChromeOnly)
{
for (uint32_t i = 0; i < sModuleLocations->Length(); ++i) {
ComponentLocation& l = sModuleLocations->ElementAt(i);
RegisterManifest(l.type, l.location, aChromeOnly);
@@ -1542,18 +1537,18 @@ nsComponentManagerImpl::GetServiceByCont
return NS_OK;
}
already_AddRefed<mozilla::ModuleLoader>
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;
}
mLoaderMap.Put(aExt, loader);
}
return loader.forget();
--- a/xpcom/components/nsICategoryManager.idl
+++ b/xpcom/components/nsICategoryManager.idl
@@ -2,68 +2,127 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsISimpleEnumerator;
+%{C++
+#include "nsString.h"
+%}
+
/*
* nsICategoryManager
*/
[scriptable, uuid(3275b2cd-af6d-429a-80d7-f0c5120342ac)]
interface nsICategoryManager : nsISupports
{
/**
* Get the value for the given category's entry.
* @param aCategory The name of the category ("protocol")
* @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.
* @param aCategory The name of the category ("protocol")
* @param aEntry The entry to be added ("http")
* @param aValue The value for the entry ("moz.httprulez.1")
* @param aPersist Should this data persist between invocations?
* @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.
* @param aCategory The name of the category ("protocol")
* @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.
* @param aCategory The category to be enumerated.
* @return a simple enumerator, each result QIs to
* nsISupportsCString.
*/
- nsISimpleEnumerator enumerateCategory(in string aCategory);
+ nsISimpleEnumerator enumerateCategory(in ACString aCategory);
/**
* Enumerate all existing categories
* @param aCategory The category to be enumerated.
* @return a simple enumerator, each result QIs to
* nsISupportsCString.
*/
nsISimpleEnumerator enumerateCategories();
+
+ %{C++
+ template<int N>
+ nsresult
+ GetCategoryEntry(const char (&aCategory)[N], const nsACString& aEntry,
+ nsACString& aResult)
+ {
+ return GetCategoryEntry(nsLiteralCString(aCategory),
+ aEntry, aResult);
+ }
+
+ template<int N, int 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<int 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<int N>
+ nsresult
+ DeleteCategoryEntry(const char (&aCategory)[N], const nsACString& aEntry, bool aPersist)
+ {
+ return DeleteCategoryEntry(nsLiteralCString(aCategory), aEntry, aPersist);
+ }
+
+
+ template<int N>
+ nsresult
+ EnumerateCategory(const char (&aCategory)[N], nsISimpleEnumerator** aResult)
+ {
+ return EnumerateCategory(nsLiteralCString(aCategory), aResult);
+ }
+ %}
};
--- a/xpcom/components/nsServiceManagerUtils.h
+++ b/xpcom/components/nsServiceManagerUtils.h
@@ -4,16 +4,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsServiceManagerUtils_h__
#define nsServiceManagerUtils_h__
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
+#include "nsString.h"
inline const nsGetServiceByCID
do_GetService(const nsCID& aCID)
{
return nsGetServiceByCID(aCID);
}
inline const nsGetServiceByCIDWithError
@@ -32,34 +33,34 @@ inline const nsGetServiceByContractIDWit
do_GetService(const char* aContractID, nsresult* aError)
{
return nsGetServiceByContractIDWithError(aContractID, 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)
, mErrorPtr(aErrorPtr)
{
}
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);
}
nsresult CallGetService(const nsCID& aClass, const nsIID& aIID, void** aResult);
nsresult CallGetService(const char* aContractID, const nsIID& aIID,
--- a/xpcom/io/nsDirectoryService.cpp
+++ b/xpcom/io/nsDirectoryService.cpp
@@ -353,18 +353,18 @@ nsDirectoryService::RegisterCategoryProv
}
bool more;
while (NS_SUCCEEDED(strings->HasMore(&more)) && more) {
nsAutoCString entry;
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());
if (provider) {
RegisterProvider(provider);
}
}
}