Add shared DHashTableOps for [const] char *key use-cases, clean up dhash API abusages (214839, r=dougt, sr=dbaron).

This commit is contained in:
brendan%mozilla.org 2003-08-05 20:09:21 +00:00
parent 0cbbeb36cd
commit b7cdb7debb
31 changed files with 376 additions and 470 deletions

View File

@ -180,7 +180,7 @@ struct PropertyPolicy : public PLDHashEntryHdr
SecurityLevel mSet;
};
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
InitPropertyPolicyEntry(PLDHashTable *table,
PLDHashEntryHdr *entry,
const void *key)
@ -189,6 +189,7 @@ InitPropertyPolicyEntry(PLDHashTable *table,
pp->key = (jsval)key;
pp->mGet.level = SCRIPT_SECURITY_UNDEFINED_ACCESS;
pp->mSet.level = SCRIPT_SECURITY_UNDEFINED_ACCESS;
return PR_TRUE;
}
PR_STATIC_CALLBACK(void)
@ -203,19 +204,10 @@ ClearPropertyPolicyEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
struct ClassPolicy : public PLDHashEntryHdr
{
char* key;
char* key;
PLDHashTable* mPolicy;
};
PR_STATIC_CALLBACK(PRBool)
MatchClassPolicyKey(PLDHashTable *table,
const PLDHashEntryHdr *entry,
const void *key)
{
ClassPolicy* cp = (ClassPolicy *)entry;
return (cp->key == (char*)key) || (PL_strcmp(cp->key, (char*)key) == 0);
}
PR_STATIC_CALLBACK(void)
ClearClassPolicyEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
{
@ -228,7 +220,7 @@ ClearClassPolicyEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
PL_DHashTableDestroy(cp->mPolicy);
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
InitClassPolicyEntry(PLDHashTable *table,
PLDHashEntryHdr *entry,
const void *key)
@ -248,9 +240,16 @@ InitClassPolicyEntry(PLDHashTable *table,
ClassPolicy* cp = (ClassPolicy*)entry;
cp->key = PL_strdup((const char*)key);
if (!cp->key)
return PR_FALSE;
cp->mPolicy = PL_NewDHashTable(&classPolicyOps, nsnull,
sizeof(PropertyPolicy), 16);
NS_ASSERTION(cp->mPolicy, "Failed to create hashtable - out of memory?");
sizeof(PropertyPolicy), 16);
if (!cp->mPolicy) {
PL_strfree(cp->key);
cp->key = nsnull;
return PR_FALSE;
}
return PR_TRUE;
}
// Domain Policy
@ -270,7 +269,7 @@ public:
PL_DHashFreeTable,
PL_DHashGetKeyStub,
PL_DHashStringKey,
MatchClassPolicyKey,
PL_DHashMatchStringKey,
PL_DHashMoveEntryStub,
ClearClassPolicyEntry,
PL_DHashFinalizeStub,

View File

@ -990,12 +990,12 @@ nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
printf("ClassLookup ");
#endif
cpolicy = NS_REINTERPRET_CAST(ClassPolicy*,
PL_DHashTableOperate(dpolicy,
aClassName,
PL_DHASH_LOOKUP));
cpolicy = NS_STATIC_CAST(ClassPolicy*,
PL_DHashTableOperate(dpolicy,
aClassName,
PL_DHASH_LOOKUP));
if (!PL_DHASH_ENTRY_IS_LIVE(cpolicy))
if (PL_DHASH_ENTRY_IS_FREE(cpolicy))
cpolicy = NO_POLICY_FOR_CLASS;
if ((dpolicy == mDefaultPolicy) && aCachedClassPolicy)
@ -1004,10 +1004,10 @@ nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
PropertyPolicy* ppolicy = nsnull;
if (cpolicy != NO_POLICY_FOR_CLASS)
{
ppolicy =
(PropertyPolicy*) PL_DHashTableOperate(cpolicy->mPolicy,
(void*)aProperty,
PL_DHASH_LOOKUP);
ppolicy = NS_STATIC_CAST(PropertyPolicy*,
PL_DHashTableOperate(cpolicy->mPolicy,
(void*)aProperty,
PL_DHASH_LOOKUP));
}
else
{
@ -1018,30 +1018,33 @@ nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
// This class is not present in the domain policy, check its wildcard policy
if (dpolicy->mWildcardPolicy)
{
ppolicy =
(PropertyPolicy*) PL_DHashTableOperate(dpolicy->mWildcardPolicy->mPolicy,
(void*)aProperty, PL_DHASH_LOOKUP);
ppolicy =
NS_STATIC_CAST(PropertyPolicy*,
PL_DHashTableOperate(dpolicy->mWildcardPolicy->mPolicy,
(void*)aProperty,
PL_DHASH_LOOKUP));
}
// If there's no wildcard policy, check the default policy for this class
if (!ppolicy || !PL_DHASH_ENTRY_IS_LIVE(ppolicy))
if (!ppolicy || PL_DHASH_ENTRY_IS_FREE(ppolicy))
{
cpolicy = NS_REINTERPRET_CAST(ClassPolicy*,
PL_DHashTableOperate(mDefaultPolicy,
aClassName,
PL_DHASH_LOOKUP));
cpolicy = NS_STATIC_CAST(ClassPolicy*,
PL_DHashTableOperate(mDefaultPolicy,
aClassName,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_LIVE(cpolicy))
if (PL_DHASH_ENTRY_IS_BUSY(cpolicy))
{
ppolicy =
(PropertyPolicy*) PL_DHashTableOperate(cpolicy->mPolicy,
(void*)aProperty,
PL_DHASH_LOOKUP);
ppolicy =
NS_STATIC_CAST(PropertyPolicy*,
PL_DHashTableOperate(cpolicy->mPolicy,
(void*)aProperty,
PL_DHASH_LOOKUP));
}
}
}
if (!ppolicy || !PL_DHASH_ENTRY_IS_LIVE(ppolicy))
if (!ppolicy || PL_DHASH_ENTRY_IS_FREE(ppolicy))
return NS_OK;
// Get the correct security level from the property policy
@ -2928,11 +2931,9 @@ nsScriptSecurityManager::InitDomainPolicy(JSContext* cx,
*end = '\0';
// Find or store this class in the classes table
ClassPolicy* cpolicy =
NS_REINTERPRET_CAST(ClassPolicy*,
PL_DHashTableOperate(aDomainPolicy,
start,
PL_DHASH_ADD));
NS_STATIC_CAST(ClassPolicy*,
PL_DHashTableOperate(aDomainPolicy, start,
PL_DHASH_ADD));
if (!cpolicy)
break;
@ -2952,10 +2953,12 @@ nsScriptSecurityManager::InitDomainPolicy(JSContext* cx,
return NS_ERROR_OUT_OF_MEMORY;
// Store this property in the class policy
const void* ppkey =
NS_REINTERPRET_CAST(const void*, STRING_TO_JSVAL(propertyKey));
PropertyPolicy* ppolicy =
(PropertyPolicy*) PL_DHashTableOperate(cpolicy->mPolicy,
(void*)STRING_TO_JSVAL(propertyKey),
PL_DHASH_ADD);
NS_STATIC_CAST(PropertyPolicy*,
PL_DHashTableOperate(cpolicy->mPolicy, ppkey,
PL_DHASH_ADD));
if (!ppolicy)
break;

View File

@ -130,21 +130,12 @@ struct ModulesEntry {
Node* byCount;
};
BOOL PR_CALLBACK
ModuleMatchEntry(PLDHashTable* aTable,
const PLDHashEntryHdr* aEntry,
const void* aKey)
{
ModulesEntry* mod = (ModulesEntry*) aEntry;
return ( !strcmp(mod->moduleName,(char*)aKey) );
}
static PLDHashTableOps ModOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
PL_DHashGetKeyStub,
PL_DHashStringKey,
ModuleMatchEntry, // PL_DHashMatchEntryStub,
PL_DHashMatchStringKey,
PL_DHashMoveEntryStub,
PL_DHashClearEntryStub,
PL_DHashFinalizeStub
@ -168,15 +159,12 @@ static int initialized = 0;
return;
}
CallEntry* entry
= (CallEntry*) PL_DHashTableOperate(&Calls, addr, PL_DHASH_LOOKUP);
if (PL_DHASH_ENTRY_IS_FREE(&entry->hdr)) {
entry = (CallEntry*) PL_DHashTableOperate(&Calls, addr, PL_DHASH_ADD);
entry = (CallEntry*) PL_DHashTableOperate(&Calls, addr, PL_DHASH_ADD);
if (!entry)
return; // OOM
if (!entry->addr)
entry->addr = addr;
entry->count = 0;
entry->hits = 0;
entry->tick = 0;
}
//
// Another call recorded.
@ -298,14 +286,13 @@ ListCounts(PLDHashTable* table, PLDHashEntryHdr* hdr,
}
ModulesEntry* mod
= (ModulesEntry*) PL_DHashTableOperate(&Modules,
module.ModuleName,
PL_DHASH_LOOKUP);
= (ModulesEntry*) PL_DHashTableOperate(&Modules,
module.ModuleName,
PL_DHASH_ADD);
if (!mod)
return PL_DHASH_STOP; // OOM
if (PL_DHASH_ENTRY_IS_FREE(&mod->hdr)) {
mod = (ModulesEntry*) PL_DHashTableOperate(&Modules,
module.ModuleName,
PL_DHASH_ADD);
if (!mod->moduleName) {
mod->moduleName = strdup(module.ModuleName);
mod->byCount = new Node();
mod->byCount->function = strdup(symbol->Name);

View File

@ -1241,7 +1241,7 @@ SubDocClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
NS_IF_RELEASE(e->mSubDocument);
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
SubDocInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry, const void *key)
{
SubDocMapEntry *e =
@ -1253,6 +1253,7 @@ SubDocInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry, const void *key)
NS_ADDREF(e->mKey);
e->mSubDocument = nsnull;
return PR_TRUE;
}
NS_IMETHODIMP
@ -1269,7 +1270,7 @@ nsDocument::SetSubDocumentFor(nsIContent *aContent, nsIDocument* aSubDoc)
PL_DHashTableOperate(mSubDocuments, aContent,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_LIVE(entry)) {
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
entry->mSubDocument->SetParentDocument(nsnull);
PL_DHashTableRawRemove(mSubDocuments, entry);
@ -1336,7 +1337,7 @@ nsDocument::GetSubDocumentFor(nsIContent *aContent, nsIDocument** aSubDoc)
PL_DHashTableOperate(mSubDocuments, aContent,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_LIVE(entry)) {
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
*aSubDoc = entry->mSubDocument;
NS_ADDREF(*aSubDoc);
}

View File

@ -898,12 +898,13 @@ nsGenericElement::~nsGenericElement()
// No calling GetFlags() beyond this point...
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
RangeListHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
const void *key)
{
// Initialize the entry with placement new
new (entry) RangeListMapEntry(key);
return PR_TRUE;
}
PR_STATIC_CALLBACK(void)
@ -915,12 +916,13 @@ RangeListHashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
r->~RangeListMapEntry();
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
EventListenerManagerHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
const void *key)
{
// Initialize the entry with placement new
new (entry) EventListenerManagerMapEntry(key);
return PR_TRUE;
}
PR_STATIC_CALLBACK(void)

View File

@ -281,7 +281,7 @@ IdAndNameHashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
e->~IdAndNameMapEntry();
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
IdAndNameHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
const void *key)
{
@ -289,6 +289,7 @@ IdAndNameHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
// Inititlize the entry with placement new
new (entry) IdAndNameMapEntry(*keyStr);
return PR_TRUE;
}
// NOTE! nsDocument::operator new() zeroes out all members, so don't
@ -3421,7 +3422,7 @@ nsHTMLDocument::UpdateNameTableEntry(const nsAString& aName,
PL_DHashTableOperate(&mIdAndNameHashTable, &aName,
PL_DHASH_LOOKUP));
if (!PL_DHASH_ENTRY_IS_LIVE(entry)) {
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
return NS_OK;
}
@ -3468,7 +3469,7 @@ nsHTMLDocument::UpdateIdTableEntry(const nsAString& aId, nsIContent *aContent)
PL_DHashTableOperate(&mIdAndNameHashTable, &aId,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_LIVE(entry)) {
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
entry->mIdContent = aContent;
}
@ -3486,7 +3487,7 @@ nsHTMLDocument::RemoveFromNameTable(const nsAString& aName,
PL_DHashTableOperate(&mIdAndNameHashTable, &aName,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_LIVE(entry) && entry->mContentList) {
if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->mContentList) {
entry->mContentList->RemoveElement(aContent);
}
@ -3514,7 +3515,7 @@ nsHTMLDocument::RemoveFromIdTable(nsIContent *aContent)
&value),
PL_DHASH_LOOKUP));
if (!PL_DHASH_ENTRY_IS_LIVE(entry) || entry->mIdContent != aContent) {
if (PL_DHASH_ENTRY_IS_FREE(entry) || entry->mIdContent != aContent) {
return NS_OK;
}

View File

@ -228,10 +228,11 @@ ClearObjectEntry(PLDHashTable* table, PLDHashEntryHdr *entry)
objEntry->~ObjectEntry();
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
InitObjectEntry(PLDHashTable* table, PLDHashEntryHdr* entry, const void* key)
{
new (entry) ObjectEntry;
return PR_TRUE;
}

View File

@ -123,7 +123,7 @@ GlobalNameHashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
memset(&e->mGlobalName, 0, sizeof(nsGlobalNameStruct));
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
GlobalNameHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
const void *key)
{
@ -136,6 +136,7 @@ GlobalNameHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
// This will set e->mGlobalName.mType to
// nsGlobalNameStruct::eTypeNotInitialized
memset(&e->mGlobalName, 0, sizeof(nsGlobalNameStruct));
return PR_TRUE;
}
nsScriptNameSpaceManager::nsScriptNameSpaceManager()
@ -177,7 +178,7 @@ nsScriptNameSpaceManager::GetConstructorProto(const nsGlobalNameStruct* aStruct)
&aStruct->mAlias->mProtoName,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_LIVE(proto)) {
if (PL_DHASH_ENTRY_IS_BUSY(proto)) {
aStruct->mAlias->mProto = &proto->mGlobalName;
}
}

View File

@ -123,7 +123,7 @@ GlobalNameHashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
memset(&e->mGlobalName, 0, sizeof(nsGlobalNameStruct));
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
GlobalNameHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
const void *key)
{
@ -136,6 +136,7 @@ GlobalNameHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
// This will set e->mGlobalName.mType to
// nsGlobalNameStruct::eTypeNotInitialized
memset(&e->mGlobalName, 0, sizeof(nsGlobalNameStruct));
return PR_TRUE;
}
nsScriptNameSpaceManager::nsScriptNameSpaceManager()
@ -177,7 +178,7 @@ nsScriptNameSpaceManager::GetConstructorProto(const nsGlobalNameStruct* aStruct)
&aStruct->mAlias->mProtoName,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_LIVE(proto)) {
if (PL_DHASH_ENTRY_IS_BUSY(proto)) {
aStruct->mAlias->mProto = &proto->mGlobalName;
}
}

View File

@ -59,40 +59,19 @@ static PLDHashTable* gCharsetToCPMap = nsnull;
struct CodePageMapEntry : public PLDHashEntryHdr
{
const char* mCharset;
UINT mCodePage;
const char* mCharset; // xxx ownership?
};
PR_STATIC_CALLBACK(const void*)
GetCharsetName(PLDHashTable*, PLDHashEntryHdr* aHdr)
{
CodePageMapEntry* entry =
NS_STATIC_CAST(CodePageMapEntry*, aHdr);
return entry->mCharset;
}
PR_STATIC_CALLBACK(PRBool)
MatchCharsetName(PLDHashTable*, const PLDHashEntryHdr* aHdr,
const void* key)
{
const CodePageMapEntry* entry =
NS_STATIC_CAST(const CodePageMapEntry*, aHdr);
const char* keyString =
NS_STATIC_CAST(const char*, key);
return (strcmp(entry->mCharset, keyString) == 0);
}
static const struct PLDHashTableOps charsetMapOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
GetCharsetName,
PL_DHashGetKeyStub,
PL_DHashStringKey,
MatchCharsetName,
PL_DHashMatchStringKey,
PL_DHashMoveEntryStub,
PL_DHashClearEntryStub,
PL_DHashFreeStringKey,
PL_DHashFinalizeStub,
nsnull
};
@ -152,9 +131,10 @@ static UINT CharsetToCodePage(const char* aCharset)
{
CodePageMapEntry* entry =
NS_STATIC_CAST(CodePageMapEntry*,
PL_DHashTableOperate(gCharsetToCPMap, aCharset, PL_DHASH_LOOKUP));
PL_DHashTableOperate(gCharsetToCPMap, aCharset,
PL_DHASH_LOOKUP));
if (!entry || PL_DHASH_ENTRY_IS_FREE(entry))
if (PL_DHASH_ENTRY_IS_FREE(entry))
return 0;
return entry->mCodePage;

View File

@ -104,6 +104,18 @@ JS_DHashMatchEntryStub(JSDHashTable *table,
return stub->key == key;
}
JS_PUBLIC_API(JSBool)
JS_DHashMatchStringKey(JSDHashTable *table,
const JSDHashEntryHdr *entry,
const void *key)
{
const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry;
/* XXX tolerate null keys on account of sloppy Mozilla callers. */
return stub->key == key ||
(stub->key && key && strcmp(stub->key, key) == 0);
}
JS_PUBLIC_API(void)
JS_DHashMoveEntryStub(JSDHashTable *table,
const JSDHashEntryHdr *from,
@ -118,6 +130,15 @@ JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry)
memset(entry, 0, table->entrySize);
}
JS_PUBLIC_API(void)
JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry)
{
const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry;
free((void *) stub->key);
memset(entry, 0, table->entrySize);
}
JS_PUBLIC_API(void)
JS_DHashFinalizeStub(JSDHashTable *table)
{
@ -519,8 +540,12 @@ JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op)
table->removedCount--;
keyHash |= COLLISION_FLAG;
}
if (table->ops->initEntry)
table->ops->initEntry(table, entry, key);
if (table->ops->initEntry &&
!table->ops->initEntry(table, entry, key)) {
/* We haven't claimed entry yet; fail with null return. */
memset(entry + 1, 0, table->entrySize - sizeof *entry);
return NULL;
}
entry->keyHash = keyHash;
table->entryCount++;
}

View File

@ -295,7 +295,7 @@ typedef void
* set yet, to avoid claiming the last free entry in a severely overloaded
* table.
*/
typedef void
typedef JSBool
(* JS_DLL_CALLBACK JSDHashInitEntry)(JSDHashTable *table,
JSDHashEntryHdr *entry,
const void *key);
@ -309,6 +309,7 @@ typedef void
* allocTable Allocate raw bytes with malloc, no ctors run.
* freeTable Free raw bytes with free, no dtors run.
* initEntry Call placement new using default key-based ctor.
* Return JS_TRUE on success, JS_FALSE on error.
* moveEntry Call placement new using copy ctor, run dtor on old
* entry storage.
* clearEntry Run dtor on entry.
@ -370,6 +371,11 @@ JS_DHashMatchEntryStub(JSDHashTable *table,
const JSDHashEntryHdr *entry,
const void *key);
extern JS_PUBLIC_API(JSBool)
JS_DHashMatchStringKey(JSDHashTable *table,
const JSDHashEntryHdr *entry,
const void *key);
extern JS_PUBLIC_API(void)
JS_DHashMoveEntryStub(JSDHashTable *table,
const JSDHashEntryHdr *from,
@ -378,6 +384,9 @@ JS_DHashMoveEntryStub(JSDHashTable *table,
extern JS_PUBLIC_API(void)
JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry);
extern JS_PUBLIC_API(void)
JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry);
extern JS_PUBLIC_API(void)
JS_DHashFinalizeStub(JSDHashTable *table);
@ -473,8 +482,11 @@ typedef enum JSDHashOperator {
*
* entry = JS_DHashTableOperate(table, key, JS_DHASH_ADD);
*
* If entry is null upon return, the table is severely overloaded, and new
* memory can't be allocated for new entry storage via table->ops->allocTable.
* If entry is null upon return, then either the table is severely overloaded,
* and memory can't be allocated for entry storage via table->ops->allocTable;
* Or if table->ops->initEntry is non-null, the table->ops->initEntry op may
* have returned false.
*
* Otherwise, entry->keyHash has been set so that JS_DHASH_ENTRY_IS_BUSY(entry)
* is true, and it is up to the caller to initialize the key and value parts
* of the entry sub-type, if they have not been set already (i.e. if entry was

View File

@ -352,12 +352,6 @@ nsMsgDatabase::ClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
element->mKey = nsMsgKey_None; // eh?
}
extern PLDHashNumber PR_CALLBACK
PL_DHashStringKey(PLDHashTable *table, const void *key);
extern void PR_CALLBACK
PL_DHashFinalizeStub(PLDHashTable *table);
nsresult nsMsgDatabase::AddHdrToUseCache(nsIMsgDBHdr *hdr, nsMsgKey key)
{

View File

@ -99,39 +99,6 @@ inline Token* TokenEnumeration::nextToken()
return token;
}
// PLDHashTable operation callbacks
static const void* PR_CALLBACK GetKey(PLDHashTable* table, PLDHashEntryHdr* entry)
{
return NS_STATIC_CAST(Token*, entry)->mWord;
}
static PRBool PR_CALLBACK MatchEntry(PLDHashTable* table,
const PLDHashEntryHdr* entry,
const void* key)
{
const Token* token = NS_STATIC_CAST(const Token*, entry);
return (strcmp(token->mWord, NS_REINTERPRET_CAST(const char*, key)) == 0);
}
static void PR_CALLBACK MoveEntry(PLDHashTable* table,
const PLDHashEntryHdr* from,
PLDHashEntryHdr* to)
{
const Token* fromToken = NS_STATIC_CAST(const Token*, from);
Token* toToken = NS_STATIC_CAST(Token*, to);
NS_ASSERTION(fromToken->mLength != 0, "zero length token in table!");
*toToken = *fromToken;
}
static void PR_CALLBACK ClearEntry(PLDHashTable* table, PLDHashEntryHdr* entry)
{
// We use the mWord field to further indicate liveness when using PL_DHASH_ADD.
// So we simply clear it when an entry is removed.
Token* token = NS_STATIC_CAST(Token*, entry);
token->mWord = NULL;
}
struct VisitClosure {
PRBool (*f) (Token*, void*);
void* data;
@ -149,11 +116,11 @@ static PLDHashOperator PR_CALLBACK VisitEntry(PLDHashTable* table, PLDHashEntryH
static const PLDHashTableOps gTokenTableOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
GetKey,
PL_DHashStringKey, // Save the extra layer of function call to PL_DHashStringKey.
MatchEntry,
MoveEntry,
ClearEntry,
PL_DHashGetKeyStub,
PL_DHashStringKey,
PL_DHashMatchStringKey,
PL_DHashMoveEntryStub,
PL_DHashClearEntryStub,
PL_DHashFinalizeStub
};

View File

@ -109,7 +109,7 @@ RequestHashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
e->~RequestMapEntry();
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
RequestHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
const void *key)
{
@ -118,6 +118,7 @@ RequestHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
// Initialize the entry with placement new
new (entry) RequestMapEntry(request);
return PR_TRUE;
}
@ -349,7 +350,7 @@ nsLoadGroup::Cancel(nsresult status)
PL_DHashTableOperate(&mRequests, request,
PL_DHASH_LOOKUP));
if (!PL_DHASH_ENTRY_IS_LIVE(entry)) {
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
// |request| was removed already
NS_RELEASE(request);
@ -668,7 +669,7 @@ nsLoadGroup::RemoveRequest(nsIRequest *request, nsISupports* ctxt,
PL_DHashTableOperate(&mRequests, request,
PL_DHASH_LOOKUP));
if (!PL_DHASH_ENTRY_IS_LIVE(entry)) {
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
LOG(("LOADGROUP [%x]: Unable to remove request %x. Not in group!\n",
this, request));

View File

@ -363,36 +363,13 @@ PLDHashTableOps nsSocketTransportService::ops =
PL_DHashFreeTable,
PL_DHashGetKeyStub,
PL_DHashStringKey,
nsSocketTransportService::MatchEntry,
PL_DHashMatchStringKey,
PL_DHashMoveEntryStub,
nsSocketTransportService::ClearEntry,
PL_DHashFreeStringKey,
PL_DHashFinalizeStub,
nsnull
};
PRBool PR_CALLBACK
nsSocketTransportService::MatchEntry(PLDHashTable *table,
const PLDHashEntryHdr *entry,
const void *key)
{
const nsSocketTransportService::nsHostEntry *he =
NS_REINTERPRET_CAST(const nsSocketTransportService::nsHostEntry *, entry);
return !strcmp(he->hostport(), (const char *) key);
}
void PR_CALLBACK
nsSocketTransportService::ClearEntry(PLDHashTable *table,
PLDHashEntryHdr *entry)
{
nsSocketTransportService::nsHostEntry *he =
NS_REINTERPRET_CAST(nsSocketTransportService::nsHostEntry *, entry);
PL_strfree((char *) he->key);
he->key = nsnull;
memset(&he->addr, 0, sizeof(he->addr));
}
nsresult
nsSocketTransportService::LookupHost(const nsACString &host, PRUint16 port, PRIPv6Addr *addr)
{

View File

@ -790,7 +790,8 @@ nsDNSLookup::EnqueueRequest(nsDNSRequest * request)
mState = LOOKUP_PENDING;
rv = InitiateLookup();
if (NS_FAILED(rv)) MarkComplete(rv);
if (NS_FAILED(rv))
MarkComplete(rv);
}
return NS_OK;
}
@ -1550,12 +1551,15 @@ nsDNSLookup *
nsDNSService::FindOrCreateLookup(const char* hostName)
{
// find hostname in hashtable
PLDHashEntryHdr * hashEntry;
nsDNSLookup * lookup = nsnull;
PLDHashEntryHdr *hashEntry = PL_DHashTableOperate(&mHashTable, hostName,
PL_DHASH_ADD);
if (!hashEntry)
return nsnull;
hashEntry = PL_DHashTableOperate(&mHashTable, hostName, PL_DHASH_LOOKUP);
if (PL_DHASH_ENTRY_IS_BUSY(hashEntry)) {
lookup = ((DNSHashTableEntry *)hashEntry)->mLookup;
DNSHashTableEntry *dnsEntry = NS_STATIC_CAST(DNSHashTableEntry*, hashEntry);
nsDNSLookup *lookup = dnsEntry->mLookup;
if (lookup) {
// found an existing entry (PL_DHASH_ADD didn't have to add one)
if (lookup->IsComplete() && lookup->IsExpired() && lookup->IsNotProcessing()) {
lookup->Reset();
PR_REMOVE_AND_INIT_LINK(lookup); // remove us from eviction queue
@ -1567,16 +1571,13 @@ nsDNSService::FindOrCreateLookup(const char* hostName)
// no lookup entry exists for this request
lookup = nsDNSLookup::Create(hostName);
if (lookup == nsnull) return nsnull;
// insert in hash table
hashEntry = PL_DHashTableOperate(&mHashTable, lookup->HostName(), PL_DHASH_ADD);
if (!hashEntry) {
NS_RELEASE(lookup);
if (!lookup) {
PL_DHashTableRawRemove(&mHashTable, hashEntry);
return nsnull;
}
((DNSHashTableEntry *)hashEntry)->mLookup = lookup;
// insert lookup in hash table entry
dnsEntry->mLookup = lookup;
return lookup;
}

View File

@ -106,12 +106,13 @@ RequestMapMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
return entry->r == key;
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
RequestMapInitEntry(PLDHashTable *table, PLDHashEntryHdr *hdr,
const void *key)
{
RequestHashEntry *entry = NS_STATIC_CAST(RequestHashEntry*, hdr);
entry->r = (void*)key;
return PR_TRUE;
}
static PLDHashTableOps gMapOps = {

View File

@ -86,13 +86,14 @@ CompareCacheMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
return entry->key == key;
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
CompareCacheInitEntry(PLDHashTable *table, PLDHashEntryHdr *hdr,
const void *key)
{
new (hdr) CompareCacheHashEntry();
CompareCacheHashEntry *entry = NS_STATIC_CAST(CompareCacheHashEntry*, hdr);
entry->key = (void*)key;
return PR_TRUE;
}
PR_STATIC_CALLBACK(void)
@ -168,15 +169,9 @@ CompareCacheHashEntry *
nsCertTree::getCacheEntry(void *cache, void *aCert)
{
PLDHashTable &aCompareCache = *NS_REINTERPRET_CAST(PLDHashTable*, cache);
PLDHashEntryHdr *entry = PL_DHashTableOperate(&aCompareCache, aCert, PL_DHASH_LOOKUP);
if (PL_DHASH_ENTRY_IS_BUSY(entry))
{
return NS_STATIC_CAST(CompareCacheHashEntry*, entry);
}
else
{
return NS_STATIC_CAST(CompareCacheHashEntry*, PL_DHashTableOperate(&aCompareCache, aCert, PL_DHASH_ADD));
}
return NS_STATIC_CAST(CompareCacheHashEntry*,
PL_DHashTableOperate(&aCompareCache, aCert,
PL_DHASH_ADD));
}
void nsCertTree::RemoveCacheEntry(void *key)

View File

@ -61,12 +61,13 @@ ObjectSetMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
return entry->obj == NS_STATIC_CAST(const nsNSSShutDownObject*, key);
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
ObjectSetInitEntry(PLDHashTable *table, PLDHashEntryHdr *hdr,
const void *key)
{
ObjectHashEntry *entry = NS_STATIC_CAST(ObjectHashEntry*, hdr);
entry->obj = NS_CONST_CAST(nsNSSShutDownObject*, NS_STATIC_CAST(const nsNSSShutDownObject*, key));
return PR_TRUE;
}
static PLDHashTableOps gSetOps = {

View File

@ -107,12 +107,13 @@ struct nsRequestInfo : public PLDHashEntryHdr
};
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
RequestInfoHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
const void *key)
{
// Initialize the entry with placement new
new (entry) nsRequestInfo(key);
return PR_TRUE;
}

View File

@ -123,8 +123,6 @@ static PRBool gRaiseWindows = PR_TRUE;
/* cursors cache */
GdkCursor *nsWindow::gsGtkCursorCache[eCursorCount];
#define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
/* window icon cache */
struct IconEntry : public PLDHashEntryHdr {
const char* string;
@ -139,7 +137,7 @@ static PLDHashTableOps iconHashOps = {
PL_DHashFreeTable,
PL_DHashGetKeyStub,
PL_DHashStringKey,
nsWindow::IconEntryMatches,
PL_DHashMatchStringKey,
PL_DHashMoveEntryStub,
nsWindow::ClearIconEntry,
PL_DHashFinalizeStub,
@ -184,8 +182,7 @@ PRBool gJustGotActivate = PR_FALSE;
#ifdef USE_XIM
struct nsXICLookupEntry {
PLDHashEntryHdr mKeyHash;
struct nsXICLookupEntry : public PLDHashEntryHdr {
nsWindow* mShellWindow;
nsIMEGtkIC* mXIC;
};
@ -387,7 +384,7 @@ nsWindow::ReleaseGlobals()
gdk_font_unref(gStatusFontset);
gStatusFontset = nsnull;
}
for (int i = 0; i < ARRAY_LENGTH(gsGtkCursorCache); ++i) {
for (int i = 0, n = NS_ARRAY_LENGTH(gsGtkCursorCache); i < n; ++i) {
if (gsGtkCursorCache[i]) {
gdk_cursor_destroy(gsGtkCursorCache[i]);
gsGtkCursorCache[i] = nsnull;
@ -2389,12 +2386,20 @@ nsWindow::SetIcon(const nsAString& aIcon)
// Note that icon specs must be UTF8.
NS_ConvertUCS2toUTF8 iconKey(aIcon);
IconEntry* entry = NS_STATIC_CAST(IconEntry*,
PL_DHashTableOperate(sIconCache, iconKey.get(), PL_DHASH_LOOKUP));
if (!entry || PL_DHASH_ENTRY_IS_FREE(entry)) {
PL_DHashTableOperate(sIconCache,
iconKey.get(),
PL_DHASH_ADD));
if (!entry)
return NS_ERROR_OUT_OF_MEMORY;
if (!entry->string) {
// We'll need to create the pixmaps.
#ifdef NS_DEBUG
PRUint32 generation = sIconCache->generation;
#endif
// Have necko resolve this to a file for us.
nsCOMPtr<nsIIOService> ioService = do_GetService(NS_IOSERVICE_CONTRACTID);
nsCOMPtr<nsIIOService> ioService = do_GetIOService();
nsCOMPtr<nsIURI> iconURI;
NS_NewURI(getter_AddRefs(iconURI), aIcon);
nsCAutoString scheme;
@ -2460,11 +2465,7 @@ nsWindow::SetIcon(const nsAString& aIcon)
#endif
}
entry = NS_STATIC_CAST(IconEntry*, PL_DHashTableOperate(sIconCache, iconKey.get(),
PL_DHASH_ADD));
if (!entry)
return NS_ERROR_OUT_OF_MEMORY;
NS_ASSERTION(sIconCache->generation == generation, "sIconCache changed!");
entry->string = strdup(iconKey.get());
entry->w_pixmap = w_pixmap;
entry->w_mask = w_mask;
@ -3950,52 +3951,54 @@ nsWindow::IMEGetShellWindow(void)
nsIMEGtkIC*
nsWindow::IMEGetInputContext(PRBool aCreate)
{
PLDHashEntryHdr* hash_entry;
nsXICLookupEntry* entry;
if (!mIMEShellWindow) {
return nsnull;
}
hash_entry = PL_DHashTableOperate(&gXICLookupTable, mIMEShellWindow, PL_DHASH_LOOKUP);
nsXICLookupEntry* entry =
NS_STATIC_CAST(nsXICLookupEntry *,
PL_DHashTableOperate(&gXICLookupTable, mIMEShellWindow,
aCreate ? PL_DHASH_ADD
: PL_DHASH_LOOKUP));
if (hash_entry) {
entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry);
if (entry->mXIC) {
return entry->mXIC;
}
if (!entry) {
return nsnull;
}
if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->mXIC) {
return entry->mXIC;
}
// create new XIC
if (aCreate) {
// create XLFD, needs 3 arguments of height, see XIC_FONTSET definition
char *xlfdbase = PR_smprintf(XIC_FONTSET, mXICFontSize, mXICFontSize, mXICFontSize);
if (gPreeditFontset == nsnull) {
gPreeditFontset = gdk_fontset_load(xlfdbase);
}
if (gStatusFontset == nsnull) {
gStatusFontset = gdk_fontset_load(xlfdbase);
}
PR_smprintf_free(xlfdbase);
if (!gPreeditFontset || !gStatusFontset) {
return nsnull;
}
nsIMEGtkIC *xic = nsIMEGtkIC::GetXIC(mIMEShellWindow, gPreeditFontset,
gStatusFontset);
if (xic) {
xic->SetPreeditSpotLocation(0, 14);
hash_entry = PL_DHashTableOperate(&gXICLookupTable,
mIMEShellWindow,
PL_DHASH_ADD);
if (hash_entry) {
entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry);
entry->mShellWindow = mIMEShellWindow;
entry->mXIC = xic;
char *xlfdbase = PR_smprintf(XIC_FONTSET, mXICFontSize, mXICFontSize,
mXICFontSize);
if (xlfdbase) {
if (gPreeditFontset == nsnull) {
gPreeditFontset = gdk_fontset_load(xlfdbase);
}
if (gStatusFontset == nsnull) {
gStatusFontset = gdk_fontset_load(xlfdbase);
}
PR_smprintf_free(xlfdbase);
nsIMEGtkIC *xic = nsnull;
if (gPreeditFontset && gStatusFontset) {
xic = nsIMEGtkIC::GetXIC(mIMEShellWindow, gPreeditFontset,
gStatusFontset);
if (xic) {
xic->SetPreeditSpotLocation(0, 14);
entry->mShellWindow = mIMEShellWindow;
entry->mXIC = xic;
mIMEShellWindow->mIMEShellWindow = mIMEShellWindow;
return xic;
}
}
mIMEShellWindow->mIMEShellWindow = mIMEShellWindow;
return xic;
}
// ran out of memory somewhere in this block...
PL_DHashTableRawRemove(&gXICLookupTable, entry);
}
return nsnull;
}
@ -4496,17 +4499,6 @@ nsWindow::MakeFullScreen(PRBool aFullScreen)
}
#endif
PRBool PR_CALLBACK
nsWindow::IconEntryMatches(PLDHashTable* aTable,
const PLDHashEntryHdr* aHdr,
const void* aKey)
{
const IconEntry* entry = NS_STATIC_CAST(const IconEntry*, aHdr);
const char* string = NS_REINTERPRET_CAST(const char*, aKey);
return strcmp(entry->string, string) == 0;
}
void PR_CALLBACK
nsWindow::ClearIconEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr)
{

View File

@ -310,26 +310,6 @@ static const PLDHashTableOps factory_DHashTableOps = {
PL_DHashFinalizeStub,
};
PR_STATIC_CALLBACK(const void *)
contractID_GetKey(PLDHashTable *aTable, PLDHashEntryHdr *aHdr)
{
nsContractIDTableEntry* entry = NS_STATIC_CAST(nsContractIDTableEntry*, aHdr);
return entry->mContractID;
}
PR_STATIC_CALLBACK(PRBool)
contractID_MatchEntry(PLDHashTable *aTable, const PLDHashEntryHdr *aHdr,
const void *aKey)
{
const nsContractIDTableEntry* entry =
NS_STATIC_CAST(const nsContractIDTableEntry*, aHdr);
const char* contractID = NS_REINTERPRET_CAST(const char*, aKey);
return strcmp(entry->mContractID, contractID) == 0;
}
PR_STATIC_CALLBACK(void)
contractID_ClearEntry(PLDHashTable *aTable, PLDHashEntryHdr *aHdr)
{
@ -351,9 +331,9 @@ contractID_ClearEntry(PLDHashTable *aTable, PLDHashEntryHdr *aHdr)
static const PLDHashTableOps contractID_DHashTableOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
contractID_GetKey,
PL_DHashGetKeyStub,
PL_DHashStringKey,
contractID_MatchEntry,
PL_DHashMatchStringKey,
PL_DHashMoveEntryStub,
contractID_ClearEntry,
PL_DHashFinalizeStub,

View File

@ -50,23 +50,6 @@ protected:
static PLDHashTableOps sInfoHashOps;
};
PR_STATIC_CALLBACK(const void *)
info_GetKey(PLDHashTable *table, PLDHashEntryHdr *entry)
{
StaticModuleInfo *info = NS_STATIC_CAST(StaticModuleInfo *, entry);
return info->info.name;
}
PR_STATIC_CALLBACK(PRBool)
info_MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *entry,
const void *key)
{
const StaticModuleInfo *info = NS_STATIC_CAST(const StaticModuleInfo *,
entry);
const char *name = NS_STATIC_CAST(const char *, key);
return !strcmp(info->info.name, name);
}
PR_STATIC_CALLBACK(void)
info_ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
{
@ -75,16 +58,17 @@ info_ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
info->~StaticModuleInfo();
}
PR_STATIC_CALLBACK(void)
PR_STATIC_CALLBACK(PRBool)
info_InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry, const void *key)
{
// Construct so that our nsCOMPtr is zeroed, etc.
(void)new (NS_STATIC_CAST(void *, entry)) StaticModuleInfo();
new (NS_STATIC_CAST(void *, entry)) StaticModuleInfo();
return PR_TRUE;
}
/* static */ PLDHashTableOps nsStaticComponentLoader::sInfoHashOps = {
PL_DHashAllocTable, PL_DHashFreeTable,
info_GetKey, PL_DHashStringKey, info_MatchEntry,
PL_DHashGetKeyStub, PL_DHashStringKey, PL_DHashMatchStringKey,
PL_DHashMoveEntryStub, info_ClearEntry,
PL_DHashFinalizeStub, info_InitEntry
};

View File

@ -230,11 +230,12 @@ ENTRY_CLASS##ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry) \
ENTRY_CLASS* e = NS_STATIC_CAST(ENTRY_CLASS *, entry); \
e->~ENTRY_CLASS(); \
} \
PR_STATIC_CALLBACK(void) \
PR_STATIC_CALLBACK(PRBool) \
ENTRY_CLASS##InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry, \
const void *key) \
{ \
new (entry) ENTRY_CLASS(key); \
return PR_TRUE; \
}
//
@ -366,7 +367,7 @@ ENTRY_CLASS* CLASSNAME::GetEntry(const KEY_TYPE aKey) { \
ENTRY_CLASS* e = NS_STATIC_CAST(ENTRY_CLASS*, \
PL_DHashTableOperate(&mHashTable, &aKey, \
PL_DHASH_LOOKUP)); \
return PL_DHASH_ENTRY_IS_LIVE(e) ? e : nsnull; \
return PL_DHASH_ENTRY_IS_BUSY(e) ? e : nsnull; \
} \
ENTRY_CLASS* CLASSNAME::AddEntry(const KEY_TYPE aKey) { \
return NS_STATIC_CAST(ENTRY_CLASS*, \

View File

@ -14,7 +14,7 @@
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
@ -23,7 +23,7 @@
* Pierre Phaneuf <pp@ludusdesign.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
@ -51,114 +51,94 @@
#include "nsIProperties.h"
#include "nsProperties.h"
struct propertyTableEntry : public PLDHashEntryHdr
struct PropertyTableEntry : public PLDHashEntryHdr
{
// both of these are arena-allocated
const char *mKey;
const PRUnichar *mValue;
// both of these are arena-allocated
const char *mKey;
const PRUnichar *mValue;
};
static PRUnichar*
ArenaStrdup(const nsAFlatString& aString, PLArenaPool* aArena)
{
void *mem;
// add one to include the null terminator
PRInt32 len = (aString.Length()+1) * sizeof(PRUnichar);
PL_ARENA_ALLOCATE(mem, aArena, len);
NS_ASSERTION(mem, "Couldn't allocate space!\n");
if (mem) {
memcpy(mem, aString.get(), len);
}
return NS_STATIC_CAST(PRUnichar*, mem);
void *mem;
// add one to include the null terminator
PRInt32 len = (aString.Length()+1) * sizeof(PRUnichar);
PL_ARENA_ALLOCATE(mem, aArena, len);
NS_ASSERTION(mem, "Couldn't allocate space!\n");
if (mem) {
memcpy(mem, aString.get(), len);
}
return NS_STATIC_CAST(PRUnichar*, mem);
}
static char*
ArenaStrdup(const nsAFlatCString& aString, PLArenaPool* aArena)
{
void *mem;
// add one to include the null terminator
PRInt32 len = (aString.Length()+1) * sizeof(char);
PL_ARENA_ALLOCATE(mem, aArena, len);
NS_ASSERTION(mem, "Couldn't allocate space!\n");
if (mem)
memcpy(mem, aString.get(), len);
return NS_STATIC_CAST(char*, mem);
}
PR_STATIC_CALLBACK(PRBool)
matchPropertyKeys(PLDHashTable*, const PLDHashEntryHdr* aHdr,
const void *key)
{
const propertyTableEntry* entry =
NS_STATIC_CAST(const propertyTableEntry*,aHdr);
const char *keyValue = NS_STATIC_CAST(const char*,key);
return (strcmp(entry->mKey, keyValue)==0);
}
PR_STATIC_CALLBACK(const void*)
getPropertyKey(PLDHashTable*, PLDHashEntryHdr* aHdr)
{
propertyTableEntry* entry =
NS_STATIC_CAST(propertyTableEntry*, aHdr);
return entry->mKey;
void *mem;
// add one to include the null terminator
PRInt32 len = (aString.Length()+1) * sizeof(char);
PL_ARENA_ALLOCATE(mem, aArena, len);
NS_ASSERTION(mem, "Couldn't allocate space!\n");
if (mem)
memcpy(mem, aString.get(), len);
return NS_STATIC_CAST(char*, mem);
}
static const struct PLDHashTableOps property_HashTableOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
getPropertyKey,
PL_DHashStringKey,
matchPropertyKeys,
PL_DHashMoveEntryStub,
PL_DHashClearEntryStub,
PL_DHashFinalizeStub,
nsnull,
PL_DHashAllocTable,
PL_DHashFreeTable,
PL_DHashGetKeyStub,
PL_DHashStringKey,
PL_DHashMatchStringKey,
PL_DHashMoveEntryStub,
PL_DHashClearEntryStub,
PL_DHashFinalizeStub,
nsnull,
};
nsPersistentProperties::nsPersistentProperties()
: mIn(nsnull)
{
mSubclass = NS_STATIC_CAST(nsIPersistentProperties*, this);
mTable.ops = nsnull;
PL_INIT_ARENA_POOL(&mArena, "PersistentPropertyArena", 2048);
mSubclass = NS_STATIC_CAST(nsIPersistentProperties*, this);
mTable.ops = nsnull;
PL_INIT_ARENA_POOL(&mArena, "PersistentPropertyArena", 2048);
}
nsPersistentProperties::~nsPersistentProperties()
{
PL_FinishArenaPool(&mArena);
if (mTable.ops)
PL_DHashTableFinish(&mTable);
PL_FinishArenaPool(&mArena);
if (mTable.ops)
PL_DHashTableFinish(&mTable);
}
nsresult
nsPersistentProperties::Init()
{
if (!PL_DHashTableInit(&mTable, &property_HashTableOps, nsnull,
sizeof(propertyTableEntry), 20)) {
mTable.ops = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
if (!PL_DHashTableInit(&mTable, &property_HashTableOps, nsnull,
sizeof(PropertyTableEntry), 20)) {
mTable.ops = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
NS_METHOD
nsPersistentProperties::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsPersistentProperties* props = new nsPersistentProperties();
if (props == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsPersistentProperties* props = new nsPersistentProperties();
if (props == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(props);
nsresult rv = props->Init();
if (NS_SUCCEEDED(rv))
rv = props->QueryInterface(aIID, aResult);
NS_ADDREF(props);
nsresult rv = props->Init();
if (NS_SUCCEEDED(rv))
rv = props->QueryInterface(aIID, aResult);
NS_RELEASE(props);
return rv;
NS_RELEASE(props);
return rv;
}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsPersistentProperties, nsIPersistentProperties, nsIProperties)
@ -168,7 +148,7 @@ nsPersistentProperties::Load(nsIInputStream *aIn)
{
PRInt32 c;
nsresult ret = NS_NewUTF8ConverterStream(&mIn, aIn, 0);
if (ret != NS_OK) {
NS_WARNING("NS_NewUTF8ConverterStream failed");
return NS_ERROR_FAILURE;
@ -235,15 +215,15 @@ nsPersistentProperties::Load(nsIInputStream *aIn)
case 2:
case 3:
case 4:
if(('0' <= c) && (c <= '9')) {
if (('0' <= c) && (c <= '9')) {
uchar = (uchar << 4) | (c - '0');
state++;
c = Read();
} else if(('a' <= c) && (c <= 'f')) {
} else if (('a' <= c) && (c <= 'f')) {
uchar = (uchar << 4) | (c - 'a' + 0x0a);
state++;
c = Read();
} else if(('A' <= c) && (c <= 'F')) {
} else if (('A' <= c) && (c <= 'F')) {
uchar = (uchar << 4) | (c - 'A' + 0x0a);
state++;
c = Read();
@ -257,7 +237,7 @@ nsPersistentProperties::Load(nsIInputStream *aIn)
state = 0;
}
}
if(state != 0) {
if (state != 0) {
value.Append((PRUnichar) uchar);
state = 0;
}
@ -284,20 +264,20 @@ nsPersistentProperties::SetStringProperty(const nsACString& aKey,
#endif
const nsAFlatCString& flatKey = PromiseFlatCString(aKey);
propertyTableEntry *entry =
NS_STATIC_CAST(propertyTableEntry*,
PL_DHashTableOperate(&mTable, flatKey.get(), PL_DHASH_ADD));
PropertyTableEntry *entry =
NS_STATIC_CAST(PropertyTableEntry*,
PL_DHashTableOperate(&mTable, flatKey.get(), PL_DHASH_ADD));
if (entry->mKey) {
aOldValue = entry->mValue;
NS_WARNING(nsPrintfCString(aKey.Length() + 30,
"the property %s already exists\n",
flatKey.get()).get());
aOldValue = entry->mValue;
NS_WARNING(nsPrintfCString(aKey.Length() + 30,
"the property %s already exists\n",
flatKey.get()).get());
}
entry->mKey = ArenaStrdup(flatKey, &mArena);
entry->mValue = ArenaStrdup(PromiseFlatString(aNewValue), &mArena);
return NS_OK;
}
@ -323,8 +303,8 @@ nsPersistentProperties::GetStringProperty(const nsACString& aKey,
{
const nsAFlatCString& flatKey = PromiseFlatCString(aKey);
propertyTableEntry *entry =
NS_STATIC_CAST(propertyTableEntry*,
PropertyTableEntry *entry =
NS_STATIC_CAST(PropertyTableEntry*,
PL_DHashTableOperate(&mTable, flatKey.get(), PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_FREE(entry))
@ -339,9 +319,9 @@ AddElemToArray(PLDHashTable* table, PLDHashEntryHdr *hdr,
PRUint32 i, void *arg)
{
nsISupportsArray *propArray = (nsISupportsArray *) arg;
propertyTableEntry* entry =
NS_STATIC_CAST(propertyTableEntry*, hdr);
PropertyTableEntry* entry =
NS_STATIC_CAST(PropertyTableEntry*, hdr);
nsPropertyElement *element =
new nsPropertyElement(nsDependentCString(entry->mKey),
nsDependentString(entry->mValue));
@ -367,11 +347,11 @@ nsPersistentProperties::Enumerate(nsISimpleEnumerator** aResult)
// Step through hash entries populating a transient array
PRUint32 n =
PL_DHashTableEnumerate(&mTable, AddElemToArray, (void *)propArray);
if ( n < mTable.entryCount )
PL_DHashTableEnumerate(&mTable, AddElemToArray, (void *)propArray);
if (n < mTable.entryCount)
return NS_ERROR_OUT_OF_MEMORY;
return NS_NewArrayEnumerator(aResult, propArray);
return NS_NewArrayEnumerator(aResult, propArray);
}
@ -420,33 +400,33 @@ nsPersistentProperties::SkipLine(PRInt32 c)
}
////////////////////////////////////////////////////////////////////////////////
// XXX Some day we'll unify the nsIPersistentProperties interface with
// XXX Some day we'll unify the nsIPersistentProperties interface with
// nsIProperties, but until now...
NS_IMETHODIMP
NS_IMETHODIMP
nsPersistentProperties::Get(const char* prop, const nsIID & uuid, void* *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NS_IMETHODIMP
nsPersistentProperties::Set(const char* prop, nsISupports* value)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NS_IMETHODIMP
nsPersistentProperties::Undefine(const char* prop)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NS_IMETHODIMP
nsPersistentProperties::Has(const char* prop, PRBool *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NS_IMETHODIMP
nsPersistentProperties::GetKeys(PRUint32 *count, char ***keys)
{
return NS_ERROR_NOT_IMPLEMENTED;
@ -460,15 +440,15 @@ nsPersistentProperties::GetKeys(PRUint32 *count, char ***keys)
NS_METHOD
nsPropertyElement::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsPropertyElement* propElem = new nsPropertyElement();
if (propElem == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(propElem);
nsresult rv = propElem->QueryInterface(aIID, aResult);
NS_RELEASE(propElem);
return rv;
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsPropertyElement* propElem = new nsPropertyElement();
if (propElem == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(propElem);
nsresult rv = propElem->QueryInterface(aIID, aResult);
NS_RELEASE(propElem);
return rv;
}
NS_IMPL_ISUPPORTS1(nsPropertyElement, nsIPropertyElement)

View File

@ -43,7 +43,7 @@
#define PL_ARENA_CONST_ALIGN_MASK 3
#include "nsStaticNameTable.h"
struct nameTableEntry : public PLDHashEntryHdr
struct NameTableEntry : public PLDHashEntryHdr
{
// no ownership here!
const char *mKey;
@ -54,8 +54,8 @@ PR_STATIC_CALLBACK(PRBool)
matchNameKeysCaseInsensitive(PLDHashTable*, const PLDHashEntryHdr* aHdr,
const void* key)
{
const nameTableEntry* entry =
NS_STATIC_CAST(const nameTableEntry *, aHdr);
const NameTableEntry* entry =
NS_STATIC_CAST(const NameTableEntry *, aHdr);
const char *keyValue = NS_STATIC_CAST(const char*, key);
return (nsCRT::strcasecmp(entry->mKey, keyValue)==0);
@ -81,18 +81,10 @@ caseInsensitiveStringHashKey(PLDHashTable *table, const void *key)
return h;
}
PR_STATIC_CALLBACK(const void*)
getNameKey(PLDHashTable*, PLDHashEntryHdr* aHdr)
{
nameTableEntry* entry = NS_STATIC_CAST(nameTableEntry*, aHdr);
return entry->mKey;
}
static const struct PLDHashTableOps nametable_CaseInsensitiveHashTableOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
getNameKey,
PL_DHashGetKeyStub,
caseInsensitiveStringHashKey,
matchNameKeysCaseInsensitive,
PL_DHashMoveEntryStub,
@ -137,7 +129,7 @@ nsStaticCaseInsensitiveNameTable::Init(const char* const aNames[], PRInt32 Count
if (!PL_DHashTableInit(&mNameTable,
&nametable_CaseInsensitiveHashTableOps,
nsnull, sizeof(nameTableEntry), Count)) {
nsnull, sizeof(NameTableEntry), Count)) {
mNameTable.ops = nsnull;
return PR_FALSE;
}
@ -159,8 +151,8 @@ nsStaticCaseInsensitiveNameTable::Init(const char* const aNames[], PRInt32 Count
// use placement-new to initialize the string object
new (&mNameArray[index]) nsDependentCString(raw);
nameTableEntry *entry =
NS_STATIC_CAST(nameTableEntry*,
NameTableEntry *entry =
NS_STATIC_CAST(NameTableEntry*,
PL_DHashTableOperate(&mNameTable, raw, PL_DHASH_ADD));
if (!entry) continue;
@ -177,11 +169,11 @@ inline PRInt32
LookupFlatKeyword(const nsAFlatCString& aKeyword,
PLDHashTable& aTable)
{
nameTableEntry *entry =
NS_STATIC_CAST(nameTableEntry*,
NameTableEntry *entry =
NS_STATIC_CAST(NameTableEntry*,
PL_DHashTableOperate(&aTable, aKeyword.get(), PL_DHASH_LOOKUP));
if (!entry || PL_DHASH_ENTRY_IS_FREE(entry))
if (PL_DHASH_ENTRY_IS_FREE(entry))
return nsStaticCaseInsensitiveNameTable::NOT_FOUND;
return entry->mIndex;

View File

@ -165,7 +165,7 @@ public:
NS_CONST_CAST(PLDHashTable*,&mTable),
EntryType::KeyToPointer(aKey),
PL_DHASH_LOOKUP));
return PL_DHASH_ENTRY_IS_BUSY(entry) ? entry : nsnull;
return PL_DHASH_ENTRY_IS_BUSY(entry) ? entry : nsnull;
}
/**
@ -268,9 +268,9 @@ protected:
static void PR_CALLBACK s_ClearEntry(PLDHashTable *table,
PLDHashEntryHdr *entry);
static void PR_CALLBACK s_InitEntry(PLDHashTable *table,
PLDHashEntryHdr *entry,
const void *key);
static PRBool PR_CALLBACK s_InitEntry(PLDHashTable *table,
PLDHashEntryHdr *entry,
const void *key);
/**
* passed internally during enumeration. Allocated on the stack.
@ -401,12 +401,13 @@ nsTHashtable<EntryType>::s_ClearEntry(PLDHashTable *table,
}
template<class EntryType>
void
PRBool
nsTHashtable<EntryType>::s_InitEntry(PLDHashTable *table,
PLDHashEntryHdr *entry,
const void *key)
{
new(entry) EntryType(NS_REINTERPRET_CAST(KeyTypePointer,key));
return PR_TRUE;
}
template<class EntryType>

View File

@ -105,6 +105,18 @@ PL_DHashMatchEntryStub(PLDHashTable *table,
return stub->key == key;
}
PR_IMPLEMENT(PRBool)
PL_DHashMatchStringKey(PLDHashTable *table,
const PLDHashEntryHdr *entry,
const void *key)
{
const PLDHashEntryStub *stub = (const PLDHashEntryStub *)entry;
/* XXX tolerate null keys on account of sloppy Mozilla callers. */
return stub->key == key ||
(stub->key && key && strcmp(stub->key, key) == 0);
}
PR_IMPLEMENT(void)
PL_DHashMoveEntryStub(PLDHashTable *table,
const PLDHashEntryHdr *from,
@ -119,6 +131,15 @@ PL_DHashClearEntryStub(PLDHashTable *table, PLDHashEntryHdr *entry)
memset(entry, 0, table->entrySize);
}
PR_IMPLEMENT(void)
PL_DHashFreeStringKey(PLDHashTable *table, PLDHashEntryHdr *entry)
{
const PLDHashEntryStub *stub = (const PLDHashEntryStub *)entry;
free((void *) stub->key);
memset(entry, 0, table->entrySize);
}
PR_IMPLEMENT(void)
PL_DHashFinalizeStub(PLDHashTable *table)
{
@ -520,8 +541,12 @@ PL_DHashTableOperate(PLDHashTable *table, const void *key, PLDHashOperator op)
table->removedCount--;
keyHash |= COLLISION_FLAG;
}
if (table->ops->initEntry)
table->ops->initEntry(table, entry, key);
if (table->ops->initEntry &&
!table->ops->initEntry(table, entry, key)) {
/* We haven't claimed entry yet; fail with null return. */
memset(entry + 1, 0, table->entrySize - sizeof *entry);
return NULL;
}
entry->keyHash = keyHash;
table->entryCount++;
}

View File

@ -296,7 +296,7 @@ typedef void
* set yet, to avoid claiming the last free entry in a severely overloaded
* table.
*/
typedef void
typedef PRBool
(* PR_CALLBACK PLDHashInitEntry)(PLDHashTable *table,
PLDHashEntryHdr *entry,
const void *key);
@ -310,6 +310,7 @@ typedef void
* allocTable Allocate raw bytes with malloc, no ctors run.
* freeTable Free raw bytes with free, no dtors run.
* initEntry Call placement new using default key-based ctor.
* Return PR_TRUE on success, PR_FALSE on error.
* moveEntry Call placement new using copy ctor, run dtor on old
* entry storage.
* clearEntry Run dtor on entry.
@ -371,6 +372,11 @@ PL_DHashMatchEntryStub(PLDHashTable *table,
const PLDHashEntryHdr *entry,
const void *key);
PR_EXTERN(PRBool)
PL_DHashMatchStringKey(PLDHashTable *table,
const PLDHashEntryHdr *entry,
const void *key);
PR_EXTERN(void)
PL_DHashMoveEntryStub(PLDHashTable *table,
const PLDHashEntryHdr *from,
@ -379,6 +385,9 @@ PL_DHashMoveEntryStub(PLDHashTable *table,
PR_EXTERN(void)
PL_DHashClearEntryStub(PLDHashTable *table, PLDHashEntryHdr *entry);
PR_EXTERN(void)
PL_DHashFreeStringKey(PLDHashTable *table, PLDHashEntryHdr *entry);
PR_EXTERN(void)
PL_DHashFinalizeStub(PLDHashTable *table);
@ -474,8 +483,11 @@ typedef enum PLDHashOperator {
*
* entry = PL_DHashTableOperate(table, key, PL_DHASH_ADD);
*
* If entry is null upon return, the table is severely overloaded, and new
* memory can't be allocated for new entry storage via table->ops->allocTable.
* If entry is null upon return, then either the table is severely overloaded,
* and memory can't be allocated for entry storage via table->ops->allocTable;
* Or if table->ops->initEntry is non-null, the table->ops->initEntry op may
* have returned false.
*
* Otherwise, entry->keyHash has been set so that PL_DHASH_ENTRY_IS_BUSY(entry)
* is true, and it is up to the caller to initialize the key and value parts
* of the entry sub-type, if they have not been set already (i.e. if entry was

View File

@ -326,18 +326,6 @@ struct nsDocumentMapReadEntry : public nsDocumentMapEntry {
// mux schedule
};
PR_STATIC_CALLBACK(PRBool)
strmap_MatchEntry(PLDHashTable *aTable,
const PLDHashEntryHdr *aHdr,
const void *aKey)
{
const nsStringMapEntry* entry =
NS_STATIC_CAST(const nsStringMapEntry*, aHdr);
const char* string = NS_REINTERPRET_CAST(const char*, aKey);
return strcmp(entry->mString, string) == 0;
}
PR_STATIC_CALLBACK(void)
strmap_ClearEntry(PLDHashTable *aTable, PLDHashEntryHdr *aHdr)
{
@ -354,7 +342,7 @@ static const PLDHashTableOps strmap_DHashTableOps = {
PL_DHashFreeTable,
PL_DHashGetKeyStub,
PL_DHashStringKey,
strmap_MatchEntry,
PL_DHashMatchStringKey,
PL_DHashMoveEntryStub,
strmap_ClearEntry,
PL_DHashFinalizeStub,