diff --git a/mozilla/xpcom/components/nsCategoryManager.cpp b/mozilla/xpcom/components/nsCategoryManager.cpp index be90fe518b5..6c2e2ddac1e 100644 --- a/mozilla/xpcom/components/nsCategoryManager.cpp +++ b/mozilla/xpcom/components/nsCategoryManager.cpp @@ -44,22 +44,20 @@ */ - - - - - - static NS_IMETHODIMP ExtractKeyString( nsHashKey* key, void*, void*, nsISupports** _retval ) + /* + ...works with |nsHashtableEnumerator| to make the hash keys enumerable. + */ { nsresult status; nsCOMPtr obj = do_CreateInstance(NS_SUPPORTS_STRING_PROGID, &status); if ( obj ) { + // BULLSHIT ALERT: use |nsCAutoString| to deflate to single-byte until I can add, e.g., + // |nsCStringKey| to hashtable const nsString& s = NS_STATIC_CAST(nsStringKey*, key)->GetString(); - // BULLSHIT ALERT: deflate to single byte until I can add, e.g., |nsCStringKey| to hashtable status = obj->SetDataWithLength(s.Length(), nsCAutoString(s)); } @@ -150,25 +148,71 @@ class nsCategoryManager NS_IMPL_ISUPPORTS1(nsCategoryManager, nsICategoryManager) nsCategoryManager::nsCategoryManager() - : nsObjectHashtable(0, 0, Destroy_CategoryNode, 0), - mRegistry( do_GetService(NS_REGISTRY_PROGID) ) + : nsObjectHashtable(0, 0, Destroy_CategoryNode, 0) { - // assert(mRegistry); - + // Nothing else to do here... } nsresult nsCategoryManager::initialize() { + // BULLSHIT ALERT: need more consistent error handling in this routine + + const char* kCategoriesRegistryPath = "Software/Mozilla/XPCOM/Categories"; // Alas, this is kind of buried down here, but you can't put constant strings in a class declaration... oh, well + + // Get a pointer to the registry, and get it open and ready for us + nsresult rv; if ( mRegistry = do_GetService(NS_REGISTRY_PROGID, &rv) ) if ( NS_SUCCEEDED(rv = mRegistry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry)) ) if ( (rv = mRegistry->GetSubtree(nsIRegistry::Common, kCategoriesRegistryPath, &mCategoriesRegistryKey)) == NS_ERROR_REG_NOT_FOUND ) rv = mRegistry->AddSubtree(nsIRegistry::Common, kCategoriesRegistryPath, &mCategoriesRegistryKey); + + // Now load the registry data + + if ( NS_SUCCEEDED(rv) ) + { + nsCOMPtr keys; + rv = mRegistry->EnumerateSubtrees(mCategoriesRegistryKey, getter_AddRefs(keys)); + for ( keys->First(); keys->IsDone() == NS_ENUMERATOR_FALSE; keys->Next() ) + { + nsXPIDLCString categoryName; + nsRegistryKey categoryKey; + + { + nsCOMPtr supportsNode; + keys->CurrentItem(getter_AddRefs(supportsNode)); + + nsCOMPtr registryNode = do_QueryInterface(supportsNode); + registryNode->GetName(getter_Copies(categoryName)); + registryNode->GetKey(&categoryKey); + } + + nsCOMPtr values; + mRegistry->EnumerateValues(categoryKey, getter_AddRefs(values)); + for ( values->First(); values->IsDone() == NS_ENUMERATOR_FALSE; values->Next() ) + { + nsXPIDLCString entryName; + + { + nsCOMPtr supportsValue; + values->CurrentItem(getter_AddRefs(supportsValue)); + + nsCOMPtr registryValue = do_QueryInterface(supportsValue); + registryValue->GetName(getter_Copies(entryName)); + } + + nsXPIDLCString value; + mRegistry->GetString(categoryKey, entryName, getter_Copies(value)); + AddCategoryEntry(categoryName, entryName, value, PR_FALSE, PR_FALSE, 0); + } + } + } + return rv; } @@ -188,7 +232,7 @@ nsCategoryManager::find_category( const char* aCategoryName ) nsresult nsCategoryManager::persist( const char* aCategoryName, const char* aKey, const char* aValue ) { - // assert(mRegistry); + NS_ASSERTION(mRegistry, "mRegistry is NULL!"); nsRegistryKey categoryRegistryKey; nsresult status = mRegistry->GetSubtreeRaw(mCategoriesRegistryKey, aCategoryName, &categoryRegistryKey); @@ -205,7 +249,9 @@ nsCategoryManager::persist( const char* aCategoryName, const char* aKey, const c nsresult nsCategoryManager::dont_persist( const char* aCategoryName, const char* aKey ) { - // assert(mRegistry); + NS_ASSERTION(aCategoryName, "aCategoryName is NULL!"); + NS_ASSERTION(aKey, "aKey is NULL!"); + NS_ASSERTION(mRegistry, "mRegistry is NULL!"); nsRegistryKey categoryRegistryKey; nsresult status = mRegistry->GetSubtreeRaw(mCategoriesRegistryKey, aCategoryName, &categoryRegistryKey); @@ -223,7 +269,7 @@ nsCategoryManager::GetCategoryEntry( const char *aCategoryName, const char *aEntryName, char **_retval ) { - // Category `handler's currently not implemented, so just call through + // BULLSHIT ALERT: Category `handler's currently not implemented, so just call through return GetCategoryEntryRaw(aCategoryName, aEntryName, _retval); } @@ -234,7 +280,9 @@ nsCategoryManager::GetCategoryEntryRaw( const char *aCategoryName, const char *aEntryName, char **_retval ) { - // assert(_retval); + NS_ASSERTION(aCategoryName, "aCategoryName is NULL!"); + NS_ASSERTION(aEntryName, "aEntryName is NULL!"); + NS_ASSERTION(_retval, "_retval is NULL!"); nsresult status = NS_ERROR_NOT_AVAILABLE; if ( CategoryNode* category = find_category(aCategoryName) ) @@ -257,7 +305,20 @@ nsCategoryManager::AddCategoryEntry( const char *aCategoryName, PRBool aReplace, char **_retval ) { - // assert(_retval); + NS_ASSERTION(aCategoryName, "aCategoryName is NULL!"); + NS_ASSERTION(aEntryName, "aEntryName is NULL!"); + NS_ASSERTION(aValue, "aValue is NULL!"); + + + /* + Note: if |_retval| is |NULL|, I won't bother returning a copy + of the replaced value. + */ + + if ( _retval ) + *_retval = 0; + + nsresult status; @@ -285,20 +346,27 @@ nsCategoryManager::DeleteCategoryEntry( const char *aCategoryName, PRBool aDontPersist, char **_retval ) { - // BULLSHIT ALERT: consider whether this should be an error - nsresult status = NS_ERROR_NOT_AVAILABLE; + NS_ASSERTION(aCategoryName, "aCategoryName is NULL!"); + NS_ASSERTION(aEntryName, "aEntryName is NULL!"); + NS_ASSERTION(_retval, "_retval is NULL!"); + + + /* + Note: no errors are reported since failure to delete + probably won't hurt you, and returning errors seriously + inconveniences JS clients + */ if ( CategoryNode* category = find_category(aCategoryName) ) { nsStringKey entryKey(aEntryName); - if ( category->RemoveAndDelete(&entryKey) ) - status = NS_OK; + category->RemoveAndDelete(&entryKey); } if ( aDontPersist ) dont_persist(aCategoryName, aEntryName); - return status; + return NS_OK; } @@ -306,7 +374,9 @@ nsCategoryManager::DeleteCategoryEntry( const char *aCategoryName, NS_IMETHODIMP nsCategoryManager::DeleteCategory( const char *aCategoryName ) { - // BULLSHIT ALERT: consider whether this should be an error + NS_ASSERTION(aCategoryName, "aCategoryName is NULL!"); + + // QUESTION: consider whether this should be an error nsStringKey categoryKey(aCategoryName); return RemoveAndDelete(&categoryKey) ? NS_OK : NS_ERROR_NOT_AVAILABLE; } @@ -319,10 +389,9 @@ NS_IMETHODIMP nsCategoryManager::EnumerateCategory( const char *aCategoryName, nsISimpleEnumerator **_retval ) { - // BULLSHIT ALERT: consider whether this should be an error - // NS_NewEmptyEnumerator()? + NS_ASSERTION(aCategoryName, "aCategoryName is NULL!"); + NS_ASSERTION(_retval, "_retval is NULL!"); - // assert(_retval); *_retval = 0; nsresult status = NS_ERROR_NOT_AVAILABLE; @@ -333,6 +402,9 @@ nsCategoryManager::EnumerateCategory( const char *aCategoryName, status = NS_NewAdapterEnumerator(_retval, innerEnumerator); } + if ( !NS_SUCCEEDED(status) ) + status = NS_NewEmptyEnumerator(_retval); + return status; } @@ -344,8 +416,8 @@ nsCategoryManager::GetCategoryContents( const char *category, char ***values, PRInt32 *count ) { - // Wasn't implemented in JS either. Will people use this? - // If not, let's get rid of it + // BULLSHIT ALERT: Wasn't implemented in JS either. + // Will people use this? If not, let's get rid of it return NS_ERROR_NOT_IMPLEMENTED; } @@ -357,7 +429,7 @@ nsCategoryManager::RegisterCategoryHandler( const char* /* aCategoryNam PRInt32 /* aMode */, nsICategoryHandler** /* _retval */ ) { - // Category `handler's currently not implemented + // BULLSHIT ALERT: Category `handler's currently not implemented return NS_ERROR_NOT_IMPLEMENTED; } @@ -368,7 +440,7 @@ nsCategoryManager::UnregisterCategoryHandler( const char *category, nsICategoryHandler *handler, nsICategoryHandler *previous ) { - // Category `handler's currently not implemented. + // BULLSHIT ALERT: Category `handler's currently not implemented. // Wasn't implemented in the JS version either. return NS_ERROR_NOT_IMPLEMENTED; }