mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 971264 - Remove nsHashtable. r=bsmedberg
This commit is contained in:
parent
4669b66737
commit
27f0eee9f8
@ -13,7 +13,6 @@
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsArrayEnumerator.h"
|
||||
#include "nscore.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIObserverService.h"
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "nsIStreamConverterService.h"
|
||||
|
||||
#include "nsHashtable.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsTArrayForwardDeclare.h"
|
||||
|
@ -51,7 +51,6 @@ EXPORTS += [
|
||||
'nsCRT.h',
|
||||
'nsExpirationTracker.h',
|
||||
'nsHashPropertyBag.h',
|
||||
'nsHashtable.h',
|
||||
'nsMathUtils.h',
|
||||
'nsStaticAtom.h',
|
||||
'nsStaticNameTable.h',
|
||||
@ -74,7 +73,6 @@ UNIFIED_SOURCES += [
|
||||
'nsAtomTable.cpp',
|
||||
'nsCRT.cpp',
|
||||
'nsHashPropertyBag.cpp',
|
||||
'nsHashtable.cpp',
|
||||
'nsINIParserImpl.cpp',
|
||||
'nsObserverList.cpp',
|
||||
'nsObserverService.cpp',
|
||||
|
@ -1,608 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/.
|
||||
* This Original Code has been modified by IBM Corporation.
|
||||
* Modifications made by IBM described herein are
|
||||
* Copyright (c) International Business Machines
|
||||
* Corporation, 2000
|
||||
*
|
||||
* Modifications to Mozilla code or documentation
|
||||
* identified per MPL Section 3.3
|
||||
*
|
||||
* Date Modified by Description of modification
|
||||
* 04/20/2000 IBM Corp. Added PR_CALLBACK for Optlink use in OS2
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "prlog.h"
|
||||
#include "prlock.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsIObjectInputStream.h"
|
||||
#include "nsIObjectOutputStream.h"
|
||||
#include "nsCRTGlue.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
struct HTEntry : PLDHashEntryHdr
|
||||
{
|
||||
nsHashKey* key;
|
||||
void* value;
|
||||
};
|
||||
|
||||
//
|
||||
// Key operations
|
||||
//
|
||||
|
||||
static bool
|
||||
matchKeyEntry(PLDHashTable*, const PLDHashEntryHdr* entry,
|
||||
const void* key)
|
||||
{
|
||||
const HTEntry* hashEntry =
|
||||
static_cast<const HTEntry*>(entry);
|
||||
|
||||
if (hashEntry->key == key)
|
||||
return true;
|
||||
|
||||
const nsHashKey* otherKey = reinterpret_cast<const nsHashKey*>(key);
|
||||
return otherKey->Equals(hashEntry->key);
|
||||
}
|
||||
|
||||
static PLDHashNumber
|
||||
hashKey(PLDHashTable* table, const void* key)
|
||||
{
|
||||
const nsHashKey* hashKey = static_cast<const nsHashKey*>(key);
|
||||
|
||||
return hashKey->HashCode();
|
||||
}
|
||||
|
||||
static void
|
||||
clearHashEntry(PLDHashTable* table, PLDHashEntryHdr* entry)
|
||||
{
|
||||
HTEntry* hashEntry = static_cast<HTEntry*>(entry);
|
||||
|
||||
// leave it up to the nsHashKey destructor to free the "value"
|
||||
delete hashEntry->key;
|
||||
hashEntry->key = nullptr;
|
||||
hashEntry->value = nullptr; // probably not necessary, but for
|
||||
// sanity's sake
|
||||
}
|
||||
|
||||
|
||||
static const PLDHashTableOps hashtableOps = {
|
||||
PL_DHashAllocTable,
|
||||
PL_DHashFreeTable,
|
||||
hashKey,
|
||||
matchKeyEntry,
|
||||
PL_DHashMoveEntryStub,
|
||||
clearHashEntry,
|
||||
PL_DHashFinalizeStub,
|
||||
nullptr,
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Enumerator callback
|
||||
//
|
||||
|
||||
struct _HashEnumerateArgs {
|
||||
nsHashtableEnumFunc fn;
|
||||
void* arg;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
hashEnumerate(PLDHashTable* table, PLDHashEntryHdr* hdr, uint32_t i, void *arg)
|
||||
{
|
||||
_HashEnumerateArgs* thunk = (_HashEnumerateArgs*)arg;
|
||||
HTEntry* entry = static_cast<HTEntry*>(hdr);
|
||||
|
||||
if (thunk->fn(entry->key, entry->value, thunk->arg))
|
||||
return PL_DHASH_NEXT;
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
|
||||
//
|
||||
// HashKey
|
||||
//
|
||||
|
||||
nsHashKey::~nsHashKey(void)
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsHashKey);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHashKey::Write(nsIObjectOutputStream* aStream) const
|
||||
{
|
||||
NS_NOTREACHED("oops");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsHashtable::nsHashtable(uint32_t aInitSize, bool aThreadSafe)
|
||||
: mLock(nullptr), mEnumerating(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsHashtable);
|
||||
|
||||
bool result = PL_DHashTableInit(&mHashtable, &hashtableOps, nullptr,
|
||||
sizeof(HTEntry), aInitSize, fallible_t());
|
||||
NS_ASSERTION(result, "Hashtable failed to initialize");
|
||||
|
||||
// make sure we detect this later
|
||||
if (!result)
|
||||
mHashtable.ops = nullptr;
|
||||
|
||||
if (aThreadSafe) {
|
||||
mLock = PR_NewLock();
|
||||
if (mLock == nullptr) {
|
||||
// Cannot create a lock. If running on a multiprocessing system
|
||||
// we are sure to die.
|
||||
PR_ASSERT(mLock != nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsHashtable::~nsHashtable() {
|
||||
MOZ_COUNT_DTOR(nsHashtable);
|
||||
if (mHashtable.ops)
|
||||
PL_DHashTableFinish(&mHashtable);
|
||||
if (mLock) PR_DestroyLock(mLock);
|
||||
}
|
||||
|
||||
bool nsHashtable::Exists(nsHashKey *aKey)
|
||||
{
|
||||
if (mLock) PR_Lock(mLock);
|
||||
|
||||
if (!mHashtable.ops) {
|
||||
if (mLock) PR_Unlock(mLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
PLDHashEntryHdr *entry =
|
||||
PL_DHashTableOperate(&mHashtable, aKey, PL_DHASH_LOOKUP);
|
||||
|
||||
bool exists = PL_DHASH_ENTRY_IS_BUSY(entry);
|
||||
|
||||
if (mLock) PR_Unlock(mLock);
|
||||
|
||||
return exists;
|
||||
}
|
||||
|
||||
void *nsHashtable::Put(nsHashKey *aKey, void *aData)
|
||||
{
|
||||
void *res = nullptr;
|
||||
|
||||
if (!mHashtable.ops) return nullptr;
|
||||
|
||||
if (mLock) PR_Lock(mLock);
|
||||
|
||||
// shouldn't be adding an item during enumeration
|
||||
PR_ASSERT(!mEnumerating);
|
||||
|
||||
HTEntry* entry =
|
||||
static_cast<HTEntry*>
|
||||
(PL_DHashTableOperate(&mHashtable, aKey, PL_DHASH_ADD));
|
||||
|
||||
if (entry) { // don't return early, or you'll be locked!
|
||||
if (entry->key) {
|
||||
// existing entry, need to boot the old value
|
||||
res = entry->value;
|
||||
entry->value = aData;
|
||||
} else {
|
||||
// new entry (leave res == null)
|
||||
entry->key = aKey->Clone();
|
||||
entry->value = aData;
|
||||
}
|
||||
}
|
||||
|
||||
if (mLock) PR_Unlock(mLock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void *nsHashtable::Get(nsHashKey *aKey)
|
||||
{
|
||||
if (!mHashtable.ops) return nullptr;
|
||||
|
||||
if (mLock) PR_Lock(mLock);
|
||||
|
||||
HTEntry* entry =
|
||||
static_cast<HTEntry*>
|
||||
(PL_DHashTableOperate(&mHashtable, aKey, PL_DHASH_LOOKUP));
|
||||
void *ret = PL_DHASH_ENTRY_IS_BUSY(entry) ? entry->value : nullptr;
|
||||
|
||||
if (mLock) PR_Unlock(mLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *nsHashtable::Remove(nsHashKey *aKey)
|
||||
{
|
||||
if (!mHashtable.ops) return nullptr;
|
||||
|
||||
if (mLock) PR_Lock(mLock);
|
||||
|
||||
// shouldn't be adding an item during enumeration
|
||||
PR_ASSERT(!mEnumerating);
|
||||
|
||||
|
||||
// need to see if the entry is actually there, in order to get the
|
||||
// old value for the result
|
||||
HTEntry* entry =
|
||||
static_cast<HTEntry*>
|
||||
(PL_DHashTableOperate(&mHashtable, aKey, PL_DHASH_LOOKUP));
|
||||
void *res;
|
||||
|
||||
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
|
||||
// value wasn't in the table anyway
|
||||
res = nullptr;
|
||||
} else {
|
||||
res = entry->value;
|
||||
PL_DHashTableRawRemove(&mHashtable, entry);
|
||||
}
|
||||
|
||||
if (mLock) PR_Unlock(mLock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// XXX This method was called _hashEnumerateCopy, but it didn't copy the element!
|
||||
// I don't know how this was supposed to work since the elements are neither copied
|
||||
// nor refcounted.
|
||||
static PLDHashOperator
|
||||
hashEnumerateShare(PLDHashTable *table, PLDHashEntryHdr *hdr,
|
||||
uint32_t i, void *arg)
|
||||
{
|
||||
nsHashtable *newHashtable = (nsHashtable *)arg;
|
||||
HTEntry * entry = static_cast<HTEntry*>(hdr);
|
||||
|
||||
newHashtable->Put(entry->key, entry->value);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsHashtable * nsHashtable::Clone()
|
||||
{
|
||||
if (!mHashtable.ops) return nullptr;
|
||||
|
||||
bool threadSafe = (mLock != nullptr);
|
||||
nsHashtable *newHashTable = new nsHashtable(mHashtable.entryCount, threadSafe);
|
||||
|
||||
PL_DHashTableEnumerate(&mHashtable, hashEnumerateShare, newHashTable);
|
||||
return newHashTable;
|
||||
}
|
||||
|
||||
void nsHashtable::Enumerate(nsHashtableEnumFunc aEnumFunc, void* aClosure)
|
||||
{
|
||||
if (!mHashtable.ops) return;
|
||||
|
||||
bool wasEnumerating = mEnumerating;
|
||||
mEnumerating = true;
|
||||
_HashEnumerateArgs thunk;
|
||||
thunk.fn = aEnumFunc;
|
||||
thunk.arg = aClosure;
|
||||
PL_DHashTableEnumerate(&mHashtable, hashEnumerate, &thunk);
|
||||
mEnumerating = wasEnumerating;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
hashEnumerateRemove(PLDHashTable*, PLDHashEntryHdr* hdr, uint32_t i, void *arg)
|
||||
{
|
||||
HTEntry* entry = static_cast<HTEntry*>(hdr);
|
||||
_HashEnumerateArgs* thunk = (_HashEnumerateArgs*)arg;
|
||||
if (thunk) {
|
||||
return thunk->fn(entry->key, entry->value, thunk->arg)
|
||||
? PL_DHASH_REMOVE
|
||||
: PL_DHASH_STOP;
|
||||
}
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
void nsHashtable::Reset() {
|
||||
Reset(nullptr);
|
||||
}
|
||||
|
||||
void nsHashtable::Reset(nsHashtableEnumFunc destroyFunc, void* aClosure)
|
||||
{
|
||||
if (!mHashtable.ops) return;
|
||||
|
||||
_HashEnumerateArgs thunk, *thunkp;
|
||||
if (!destroyFunc) {
|
||||
thunkp = nullptr;
|
||||
} else {
|
||||
thunkp = &thunk;
|
||||
thunk.fn = destroyFunc;
|
||||
thunk.arg = aClosure;
|
||||
}
|
||||
PL_DHashTableEnumerate(&mHashtable, hashEnumerateRemove, thunkp);
|
||||
}
|
||||
|
||||
// nsISerializable helpers
|
||||
|
||||
nsHashtable::nsHashtable(nsIObjectInputStream* aStream,
|
||||
nsHashtableReadEntryFunc aReadEntryFunc,
|
||||
nsHashtableFreeEntryFunc aFreeEntryFunc,
|
||||
nsresult *aRetVal)
|
||||
: mLock(nullptr),
|
||||
mEnumerating(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsHashtable);
|
||||
|
||||
bool threadSafe;
|
||||
nsresult rv = aStream->ReadBoolean(&threadSafe);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (threadSafe) {
|
||||
mLock = PR_NewLock();
|
||||
if (!mLock)
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
uint32_t count;
|
||||
rv = aStream->Read32(&count);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
bool status =
|
||||
PL_DHashTableInit(&mHashtable, &hashtableOps,
|
||||
nullptr, sizeof(HTEntry), count,
|
||||
fallible_t());
|
||||
if (!status) {
|
||||
mHashtable.ops = nullptr;
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
} else {
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
nsHashKey* key;
|
||||
void *data;
|
||||
|
||||
rv = aReadEntryFunc(aStream, &key, &data);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
Put(key, data);
|
||||
|
||||
// XXXbe must we clone key? can't we hand off
|
||||
aFreeEntryFunc(aStream, key, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*aRetVal = rv;
|
||||
}
|
||||
|
||||
struct WriteEntryArgs {
|
||||
nsIObjectOutputStream* mStream;
|
||||
nsHashtableWriteDataFunc mWriteDataFunc;
|
||||
nsresult mRetVal;
|
||||
};
|
||||
|
||||
static bool
|
||||
WriteEntry(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
{
|
||||
WriteEntryArgs* args = (WriteEntryArgs*) aClosure;
|
||||
nsIObjectOutputStream* stream = args->mStream;
|
||||
|
||||
nsresult rv = aKey->Write(stream);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = args->mWriteDataFunc(stream, aData);
|
||||
|
||||
args->mRetVal = rv;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHashtable::Write(nsIObjectOutputStream* aStream,
|
||||
nsHashtableWriteDataFunc aWriteDataFunc) const
|
||||
{
|
||||
if (!mHashtable.ops)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
bool threadSafe = (mLock != nullptr);
|
||||
nsresult rv = aStream->WriteBoolean(threadSafe);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Write the entry count first, so we know how many key/value pairs to read.
|
||||
uint32_t count = mHashtable.entryCount;
|
||||
rv = aStream->Write32(count);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Write all key/value pairs in the table.
|
||||
WriteEntryArgs args = {aStream, aWriteDataFunc};
|
||||
const_cast<nsHashtable*>(this)->Enumerate(WriteEntry, (void*) &args);
|
||||
return args.mRetVal;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Copy Constructor
|
||||
// We need to free mStr if the object is passed with mOwnership as OWN. As the
|
||||
// destructor here is freeing mStr in that case, mStr is NOT getting leaked here.
|
||||
|
||||
nsCStringKey::nsCStringKey(const nsCStringKey& aKey)
|
||||
: mStr(aKey.mStr), mStrLen(aKey.mStrLen), mOwnership(aKey.mOwnership)
|
||||
{
|
||||
if (mOwnership != NEVER_OWN) {
|
||||
uint32_t len = mStrLen * sizeof(char);
|
||||
char* str = reinterpret_cast<char*>(nsMemory::Alloc(len + sizeof(char)));
|
||||
if (!str) {
|
||||
// Pray we don't dangle!
|
||||
mOwnership = NEVER_OWN;
|
||||
} else {
|
||||
// Use memcpy in case there are embedded NULs.
|
||||
memcpy(str, mStr, len);
|
||||
str[mStrLen] = '\0';
|
||||
mStr = str;
|
||||
mOwnership = OWN;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
mKeyType = CStringKey;
|
||||
#endif
|
||||
MOZ_COUNT_CTOR(nsCStringKey);
|
||||
}
|
||||
|
||||
nsCStringKey::nsCStringKey(const nsAFlatCString& str)
|
||||
: mStr(const_cast<char*>(str.get())),
|
||||
mStrLen(str.Length()),
|
||||
mOwnership(OWN_CLONE)
|
||||
{
|
||||
NS_ASSERTION(mStr, "null string key");
|
||||
#ifdef DEBUG
|
||||
mKeyType = CStringKey;
|
||||
#endif
|
||||
MOZ_COUNT_CTOR(nsCStringKey);
|
||||
}
|
||||
|
||||
nsCStringKey::nsCStringKey(const nsACString& str)
|
||||
: mStr(ToNewCString(str)),
|
||||
mStrLen(str.Length()),
|
||||
mOwnership(OWN)
|
||||
{
|
||||
NS_ASSERTION(mStr, "null string key");
|
||||
#ifdef DEBUG
|
||||
mKeyType = CStringKey;
|
||||
#endif
|
||||
MOZ_COUNT_CTOR(nsCStringKey);
|
||||
}
|
||||
|
||||
nsCStringKey::nsCStringKey(const char* str, int32_t strLen, Ownership own)
|
||||
: mStr((char*)str), mStrLen(strLen), mOwnership(own)
|
||||
{
|
||||
NS_ASSERTION(mStr, "null string key");
|
||||
if (mStrLen == uint32_t(-1))
|
||||
mStrLen = strlen(str);
|
||||
#ifdef DEBUG
|
||||
mKeyType = CStringKey;
|
||||
#endif
|
||||
MOZ_COUNT_CTOR(nsCStringKey);
|
||||
}
|
||||
|
||||
nsCStringKey::~nsCStringKey(void)
|
||||
{
|
||||
if (mOwnership == OWN)
|
||||
nsMemory::Free(mStr);
|
||||
MOZ_COUNT_DTOR(nsCStringKey);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nsCStringKey::HashCode(void) const
|
||||
{
|
||||
return HashString(mStr, mStrLen);
|
||||
}
|
||||
|
||||
bool
|
||||
nsCStringKey::Equals(const nsHashKey* aKey) const
|
||||
{
|
||||
NS_ASSERTION(aKey->GetKeyType() == CStringKey, "mismatched key types");
|
||||
nsCStringKey* other = (nsCStringKey*)aKey;
|
||||
NS_ASSERTION(mStrLen != uint32_t(-1), "never called HashCode");
|
||||
NS_ASSERTION(other->mStrLen != uint32_t(-1), "never called HashCode");
|
||||
if (mStrLen != other->mStrLen)
|
||||
return false;
|
||||
return memcmp(mStr, other->mStr, mStrLen * sizeof(char)) == 0;
|
||||
}
|
||||
|
||||
nsHashKey*
|
||||
nsCStringKey::Clone() const
|
||||
{
|
||||
if (mOwnership == NEVER_OWN)
|
||||
return new nsCStringKey(mStr, mStrLen, NEVER_OWN);
|
||||
|
||||
// Since this might hold binary data OR a string, we ensure that the
|
||||
// clone string is zero terminated, but don't assume that the source
|
||||
// string was so terminated.
|
||||
|
||||
uint32_t len = mStrLen * sizeof(char);
|
||||
char* str = (char*)nsMemory::Alloc(len + sizeof(char));
|
||||
if (str == nullptr)
|
||||
return nullptr;
|
||||
memcpy(str, mStr, len);
|
||||
str[len] = 0;
|
||||
return new nsCStringKey(str, mStrLen, OWN);
|
||||
}
|
||||
|
||||
nsCStringKey::nsCStringKey(nsIObjectInputStream* aStream, nsresult *aResult)
|
||||
: mStr(nullptr), mStrLen(0), mOwnership(OWN)
|
||||
{
|
||||
nsAutoCString str;
|
||||
nsresult rv = aStream->ReadCString(str);
|
||||
mStr = ToNewCString(str);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mStrLen = str.Length();
|
||||
*aResult = rv;
|
||||
MOZ_COUNT_CTOR(nsCStringKey);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCStringKey::Write(nsIObjectOutputStream* aStream) const
|
||||
{
|
||||
return aStream->WriteStringZ(mStr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsObjectHashtable: an nsHashtable where the elements are C++ objects to be
|
||||
// deleted
|
||||
|
||||
nsObjectHashtable::nsObjectHashtable(nsHashtableCloneElementFunc cloneElementFun,
|
||||
void* cloneElementClosure,
|
||||
nsHashtableEnumFunc destroyElementFun,
|
||||
void* destroyElementClosure,
|
||||
uint32_t aSize, bool threadSafe)
|
||||
: nsHashtable(aSize, threadSafe),
|
||||
mCloneElementFun(cloneElementFun),
|
||||
mCloneElementClosure(cloneElementClosure),
|
||||
mDestroyElementFun(destroyElementFun),
|
||||
mDestroyElementClosure(destroyElementClosure)
|
||||
{
|
||||
}
|
||||
|
||||
nsObjectHashtable::~nsObjectHashtable()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
||||
PLDHashOperator
|
||||
nsObjectHashtable::CopyElement(PLDHashTable* table,
|
||||
PLDHashEntryHdr* hdr,
|
||||
uint32_t i, void *arg)
|
||||
{
|
||||
nsObjectHashtable *newHashtable = (nsObjectHashtable *)arg;
|
||||
HTEntry *entry = static_cast<HTEntry*>(hdr);
|
||||
|
||||
void* newElement =
|
||||
newHashtable->mCloneElementFun(entry->key, entry->value,
|
||||
newHashtable->mCloneElementClosure);
|
||||
if (newElement == nullptr)
|
||||
return PL_DHASH_STOP;
|
||||
newHashtable->Put(entry->key, newElement);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsHashtable*
|
||||
nsObjectHashtable::Clone()
|
||||
{
|
||||
if (!mHashtable.ops) return nullptr;
|
||||
|
||||
bool threadSafe = false;
|
||||
if (mLock)
|
||||
threadSafe = true;
|
||||
nsObjectHashtable* newHashTable =
|
||||
new nsObjectHashtable(mCloneElementFun, mCloneElementClosure,
|
||||
mDestroyElementFun, mDestroyElementClosure,
|
||||
mHashtable.entryCount, threadSafe);
|
||||
|
||||
PL_DHashTableEnumerate(&mHashtable, CopyElement, newHashTable);
|
||||
return newHashTable;
|
||||
}
|
||||
|
||||
void
|
||||
nsObjectHashtable::Reset()
|
||||
{
|
||||
nsHashtable::Reset(mDestroyElementFun, mDestroyElementClosure);
|
||||
}
|
||||
|
||||
bool
|
||||
nsObjectHashtable::RemoveAndDelete(nsHashKey *aKey)
|
||||
{
|
||||
void *value = Remove(aKey);
|
||||
if (value && mDestroyElementFun)
|
||||
return !!(*mDestroyElementFun)(aKey, value, mDestroyElementClosure);
|
||||
return false;
|
||||
}
|
@ -1,217 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/.
|
||||
* This Original Code has been modified by IBM Corporation.
|
||||
* Modifications made by IBM described herein are
|
||||
* Copyright (c) International Business Machines
|
||||
* Corporation, 2000
|
||||
*
|
||||
* Modifications to Mozilla code or documentation
|
||||
* identified per MPL Section 3.3
|
||||
*
|
||||
* Date Modified by Description of modification
|
||||
* 04/20/2000 IBM Corp. Added PR_CALLBACK for Optlink use in OS2
|
||||
*/
|
||||
|
||||
/**
|
||||
* nsHashtable is OBSOLETE. Use nsTHashtable or a derivative instead.
|
||||
*/
|
||||
|
||||
#ifndef nsHashtable_h__
|
||||
#define nsHashtable_h__
|
||||
|
||||
#include "pldhash.h"
|
||||
#include "nscore.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsStringFwd.h"
|
||||
|
||||
class nsIObjectInputStream;
|
||||
class nsIObjectOutputStream;
|
||||
|
||||
struct PRLock;
|
||||
|
||||
class nsHashKey {
|
||||
protected:
|
||||
nsHashKey(void) {
|
||||
#ifdef DEBUG
|
||||
mKeyType = UnknownKey;
|
||||
#endif
|
||||
MOZ_COUNT_CTOR(nsHashKey);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
// Virtual destructor because all hash keys are |delete|d via a
|
||||
// nsHashKey pointer.
|
||||
|
||||
virtual ~nsHashKey(void);
|
||||
virtual uint32_t HashCode(void) const = 0;
|
||||
virtual bool Equals(const nsHashKey *aKey) const = 0;
|
||||
virtual nsHashKey *Clone() const = 0;
|
||||
virtual nsresult Write(nsIObjectOutputStream* aStream) const;
|
||||
|
||||
#ifdef DEBUG
|
||||
public:
|
||||
// used for verification that we're casting to the correct key type
|
||||
enum nsHashKeyType {
|
||||
UnknownKey,
|
||||
SupportsKey,
|
||||
PRUint32Key,
|
||||
VoidKey,
|
||||
IDKey,
|
||||
CStringKey,
|
||||
StringKey
|
||||
};
|
||||
nsHashKeyType GetKeyType() const { return mKeyType; }
|
||||
protected:
|
||||
nsHashKeyType mKeyType;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Enumerator and Read/Write callback functions.
|
||||
|
||||
// Return values for nsHashtableEnumFunc
|
||||
enum {
|
||||
kHashEnumerateStop = false,
|
||||
kHashEnumerateNext = true
|
||||
};
|
||||
|
||||
typedef bool
|
||||
(* nsHashtableEnumFunc)(nsHashKey *aKey, void *aData, void* aClosure);
|
||||
|
||||
typedef nsresult
|
||||
(* nsHashtableReadEntryFunc)(nsIObjectInputStream *aStream, nsHashKey **aKey,
|
||||
void **aData);
|
||||
|
||||
// NB: may be called with null aKey or aData, to free just one of the two.
|
||||
typedef void
|
||||
(* nsHashtableFreeEntryFunc)(nsIObjectInputStream *aStream, nsHashKey *aKey,
|
||||
void *aData);
|
||||
|
||||
typedef nsresult
|
||||
(* nsHashtableWriteDataFunc)(nsIObjectOutputStream *aStream, void *aData);
|
||||
|
||||
class nsHashtable {
|
||||
protected:
|
||||
// members
|
||||
PRLock* mLock;
|
||||
PLDHashTable mHashtable;
|
||||
bool mEnumerating;
|
||||
|
||||
public:
|
||||
nsHashtable(uint32_t aSize = 16, bool aThreadSafe = false);
|
||||
virtual ~nsHashtable();
|
||||
|
||||
int32_t Count(void) { return mHashtable.entryCount; }
|
||||
bool Exists(nsHashKey *aKey);
|
||||
void *Put(nsHashKey *aKey, void *aData);
|
||||
void *Get(nsHashKey *aKey);
|
||||
void *Remove(nsHashKey *aKey);
|
||||
nsHashtable *Clone();
|
||||
void Enumerate(nsHashtableEnumFunc aEnumFunc, void* aClosure = nullptr);
|
||||
void Reset();
|
||||
void Reset(nsHashtableEnumFunc destroyFunc, void* aClosure = nullptr);
|
||||
|
||||
nsHashtable(nsIObjectInputStream* aStream,
|
||||
nsHashtableReadEntryFunc aReadEntryFunc,
|
||||
nsHashtableFreeEntryFunc aFreeEntryFunc,
|
||||
nsresult *aRetVal);
|
||||
nsresult Write(nsIObjectOutputStream* aStream,
|
||||
nsHashtableWriteDataFunc aWriteDataFunc) const;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsObjectHashtable: an nsHashtable where the elements are C++ objects to be
|
||||
// deleted
|
||||
|
||||
typedef void* (* nsHashtableCloneElementFunc)(nsHashKey *aKey, void *aData, void* aClosure);
|
||||
|
||||
class nsObjectHashtable : public nsHashtable {
|
||||
public:
|
||||
nsObjectHashtable(nsHashtableCloneElementFunc cloneElementFun,
|
||||
void* cloneElementClosure,
|
||||
nsHashtableEnumFunc destroyElementFun,
|
||||
void* destroyElementClosure,
|
||||
uint32_t aSize = 16, bool threadSafe = false);
|
||||
~nsObjectHashtable();
|
||||
|
||||
nsHashtable *Clone();
|
||||
void Reset();
|
||||
bool RemoveAndDelete(nsHashKey *aKey);
|
||||
|
||||
protected:
|
||||
static PLDHashOperator CopyElement(PLDHashTable* table,
|
||||
PLDHashEntryHdr* hdr,
|
||||
uint32_t i, void *arg);
|
||||
|
||||
nsHashtableCloneElementFunc mCloneElementFun;
|
||||
void* mCloneElementClosure;
|
||||
nsHashtableEnumFunc mDestroyElementFun;
|
||||
void* mDestroyElementClosure;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsPRUint32Key : public nsHashKey {
|
||||
protected:
|
||||
uint32_t mKey;
|
||||
public:
|
||||
nsPRUint32Key(uint32_t key) {
|
||||
#ifdef DEBUG
|
||||
mKeyType = PRUint32Key;
|
||||
#endif
|
||||
mKey = key;
|
||||
}
|
||||
|
||||
uint32_t HashCode(void) const {
|
||||
return mKey;
|
||||
}
|
||||
|
||||
bool Equals(const nsHashKey *aKey) const {
|
||||
return mKey == ((const nsPRUint32Key *) aKey)->mKey;
|
||||
}
|
||||
nsHashKey *Clone() const {
|
||||
return new nsPRUint32Key(mKey);
|
||||
}
|
||||
uint32_t GetValue() { return mKey; }
|
||||
};
|
||||
|
||||
// for null-terminated c-strings
|
||||
class nsCStringKey : public nsHashKey {
|
||||
public:
|
||||
|
||||
// NB: when serializing, NEVER_OWN keys are deserialized as OWN.
|
||||
enum Ownership {
|
||||
NEVER_OWN, // very long lived, even clones don't need to copy it.
|
||||
OWN_CLONE, // as long lived as this key. But clones make a copy.
|
||||
OWN // to be free'd in key dtor. Clones make their own copy.
|
||||
};
|
||||
|
||||
nsCStringKey(const nsCStringKey& aStrKey);
|
||||
nsCStringKey(const char* str, int32_t strLen = -1, Ownership own = OWN_CLONE);
|
||||
nsCStringKey(const nsAFlatCString& str);
|
||||
nsCStringKey(const nsACString& str);
|
||||
~nsCStringKey(void);
|
||||
|
||||
uint32_t HashCode(void) const;
|
||||
bool Equals(const nsHashKey* aKey) const;
|
||||
nsHashKey* Clone() const;
|
||||
nsCStringKey(nsIObjectInputStream* aStream, nsresult *aResult);
|
||||
nsresult Write(nsIObjectOutputStream* aStream) const;
|
||||
|
||||
// For when the owner of the hashtable wants to peek at the actual
|
||||
// string in the key. No copy is made, so be careful.
|
||||
const char* GetString() const { return mStr; }
|
||||
uint32_t GetStringLength() const { return mStrLen; }
|
||||
|
||||
protected:
|
||||
char* mStr;
|
||||
uint32_t mStrLen;
|
||||
Ownership mOwnership;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // nsHashtable_h__
|
Loading…
Reference in New Issue
Block a user