michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: * This Original Code has been modified by IBM Corporation. michael@0: * Modifications made by IBM described herein are michael@0: * Copyright (c) International Business Machines michael@0: * Corporation, 2000 michael@0: * michael@0: * Modifications to Mozilla code or documentation michael@0: * identified per MPL Section 3.3 michael@0: * michael@0: * Date Modified by Description of modification michael@0: * 04/20/2000 IBM Corp. Added PR_CALLBACK for Optlink use in OS2 michael@0: */ michael@0: michael@0: /** michael@0: * nsHashtable is OBSOLETE. Use nsTHashtable or a derivative instead. michael@0: */ michael@0: michael@0: #ifndef nsHashtable_h__ michael@0: #define nsHashtable_h__ michael@0: michael@0: #include "pldhash.h" michael@0: #include "nscore.h" michael@0: #include "nsISupports.h" michael@0: #include "nsISupportsImpl.h" michael@0: #include "nsStringFwd.h" michael@0: michael@0: class nsIObjectInputStream; michael@0: class nsIObjectOutputStream; michael@0: michael@0: struct PRLock; michael@0: michael@0: class nsHashKey { michael@0: protected: michael@0: nsHashKey(void) { michael@0: #ifdef DEBUG michael@0: mKeyType = UnknownKey; michael@0: #endif michael@0: MOZ_COUNT_CTOR(nsHashKey); michael@0: } michael@0: michael@0: michael@0: public: michael@0: // Virtual destructor because all hash keys are |delete|d via a michael@0: // nsHashKey pointer. michael@0: michael@0: virtual ~nsHashKey(void); michael@0: virtual uint32_t HashCode(void) const = 0; michael@0: virtual bool Equals(const nsHashKey *aKey) const = 0; michael@0: virtual nsHashKey *Clone() const = 0; michael@0: virtual nsresult Write(nsIObjectOutputStream* aStream) const; michael@0: michael@0: #ifdef DEBUG michael@0: public: michael@0: // used for verification that we're casting to the correct key type michael@0: enum nsHashKeyType { michael@0: UnknownKey, michael@0: SupportsKey, michael@0: PRUint32Key, michael@0: VoidKey, michael@0: IDKey, michael@0: CStringKey, michael@0: StringKey michael@0: }; michael@0: nsHashKeyType GetKeyType() const { return mKeyType; } michael@0: protected: michael@0: nsHashKeyType mKeyType; michael@0: #endif michael@0: }; michael@0: michael@0: // Enumerator and Read/Write callback functions. michael@0: michael@0: // Return values for nsHashtableEnumFunc michael@0: enum { michael@0: kHashEnumerateStop = false, michael@0: kHashEnumerateNext = true michael@0: }; michael@0: michael@0: typedef bool michael@0: (* nsHashtableEnumFunc)(nsHashKey *aKey, void *aData, void* aClosure); michael@0: michael@0: typedef nsresult michael@0: (* nsHashtableReadEntryFunc)(nsIObjectInputStream *aStream, nsHashKey **aKey, michael@0: void **aData); michael@0: michael@0: // NB: may be called with null aKey or aData, to free just one of the two. michael@0: typedef void michael@0: (* nsHashtableFreeEntryFunc)(nsIObjectInputStream *aStream, nsHashKey *aKey, michael@0: void *aData); michael@0: michael@0: typedef nsresult michael@0: (* nsHashtableWriteDataFunc)(nsIObjectOutputStream *aStream, void *aData); michael@0: michael@0: class nsHashtable { michael@0: protected: michael@0: // members michael@0: PRLock* mLock; michael@0: PLDHashTable mHashtable; michael@0: bool mEnumerating; michael@0: michael@0: public: michael@0: nsHashtable(uint32_t aSize = 16, bool aThreadSafe = false); michael@0: virtual ~nsHashtable(); michael@0: michael@0: int32_t Count(void) { return mHashtable.entryCount; } michael@0: bool Exists(nsHashKey *aKey); michael@0: void *Put(nsHashKey *aKey, void *aData); michael@0: void *Get(nsHashKey *aKey); michael@0: void *Remove(nsHashKey *aKey); michael@0: nsHashtable *Clone(); michael@0: void Enumerate(nsHashtableEnumFunc aEnumFunc, void* aClosure = nullptr); michael@0: void Reset(); michael@0: void Reset(nsHashtableEnumFunc destroyFunc, void* aClosure = nullptr); michael@0: michael@0: nsHashtable(nsIObjectInputStream* aStream, michael@0: nsHashtableReadEntryFunc aReadEntryFunc, michael@0: nsHashtableFreeEntryFunc aFreeEntryFunc, michael@0: nsresult *aRetVal); michael@0: nsresult Write(nsIObjectOutputStream* aStream, michael@0: nsHashtableWriteDataFunc aWriteDataFunc) const; michael@0: }; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // nsObjectHashtable: an nsHashtable where the elements are C++ objects to be michael@0: // deleted michael@0: michael@0: typedef void* (* nsHashtableCloneElementFunc)(nsHashKey *aKey, void *aData, void* aClosure); michael@0: michael@0: class nsObjectHashtable : public nsHashtable { michael@0: public: michael@0: nsObjectHashtable(nsHashtableCloneElementFunc cloneElementFun, michael@0: void* cloneElementClosure, michael@0: nsHashtableEnumFunc destroyElementFun, michael@0: void* destroyElementClosure, michael@0: uint32_t aSize = 16, bool threadSafe = false); michael@0: ~nsObjectHashtable(); michael@0: michael@0: nsHashtable *Clone(); michael@0: void Reset(); michael@0: bool RemoveAndDelete(nsHashKey *aKey); michael@0: michael@0: protected: michael@0: static PLDHashOperator CopyElement(PLDHashTable* table, michael@0: PLDHashEntryHdr* hdr, michael@0: uint32_t i, void *arg); michael@0: michael@0: nsHashtableCloneElementFunc mCloneElementFun; michael@0: void* mCloneElementClosure; michael@0: nsHashtableEnumFunc mDestroyElementFun; michael@0: void* mDestroyElementClosure; michael@0: }; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: class nsPRUint32Key : public nsHashKey { michael@0: protected: michael@0: uint32_t mKey; michael@0: public: michael@0: nsPRUint32Key(uint32_t key) { michael@0: #ifdef DEBUG michael@0: mKeyType = PRUint32Key; michael@0: #endif michael@0: mKey = key; michael@0: } michael@0: michael@0: uint32_t HashCode(void) const { michael@0: return mKey; michael@0: } michael@0: michael@0: bool Equals(const nsHashKey *aKey) const { michael@0: return mKey == ((const nsPRUint32Key *) aKey)->mKey; michael@0: } michael@0: nsHashKey *Clone() const { michael@0: return new nsPRUint32Key(mKey); michael@0: } michael@0: uint32_t GetValue() { return mKey; } michael@0: }; michael@0: michael@0: // for null-terminated c-strings michael@0: class nsCStringKey : public nsHashKey { michael@0: public: michael@0: michael@0: // NB: when serializing, NEVER_OWN keys are deserialized as OWN. michael@0: enum Ownership { michael@0: NEVER_OWN, // very long lived, even clones don't need to copy it. michael@0: OWN_CLONE, // as long lived as this key. But clones make a copy. michael@0: OWN // to be free'd in key dtor. Clones make their own copy. michael@0: }; michael@0: michael@0: nsCStringKey(const nsCStringKey& aStrKey); michael@0: nsCStringKey(const char* str, int32_t strLen = -1, Ownership own = OWN_CLONE); michael@0: nsCStringKey(const nsAFlatCString& str); michael@0: nsCStringKey(const nsACString& str); michael@0: ~nsCStringKey(void); michael@0: michael@0: uint32_t HashCode(void) const; michael@0: bool Equals(const nsHashKey* aKey) const; michael@0: nsHashKey* Clone() const; michael@0: nsCStringKey(nsIObjectInputStream* aStream, nsresult *aResult); michael@0: nsresult Write(nsIObjectOutputStream* aStream) const; michael@0: michael@0: // For when the owner of the hashtable wants to peek at the actual michael@0: // string in the key. No copy is made, so be careful. michael@0: const char* GetString() const { return mStr; } michael@0: uint32_t GetStringLength() const { return mStrLen; } michael@0: michael@0: protected: michael@0: char* mStr; michael@0: uint32_t mStrLen; michael@0: Ownership mOwnership; michael@0: }; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: #endif // nsHashtable_h__