| /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
| /* ***** BEGIN LICENSE BLOCK ***** |
| * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| * |
| * The contents of this file are subject to the Mozilla Public License Version |
| * 1.1 (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * http://www.mozilla.org/MPL/ |
| * |
| * Software distributed under the License is distributed on an "AS IS" basis, |
| * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| * for the specific language governing rights and limitations under the |
| * License. |
| * |
| * The Original Code is mozilla.org code. |
| * |
| * 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. |
| * |
| * Contributor(s): |
| * |
| * Alternatively, the contents of this file may be used under the terms of |
| * either of 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 |
| * under the terms of either the GPL or the LGPL, and not to allow others to |
| * use your version of this file under the terms of the MPL, indicate your |
| * decision by deleting the provisions above and replace them with the notice |
| * and other provisions required by the GPL or the LGPL. If you do not delete |
| * the provisions above, a recipient may use your version of this file under |
| * the terms of any one of the MPL, the GPL or the LGPL. |
| * |
| * ***** END LICENSE BLOCK ***** |
| * 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 "prlock.h" |
| #include "nscore.h" |
| #include "nsString.h" |
| #include "nsISupportsBase.h" |
| #include "nsTraceRefcnt.h" |
| |
| class nsIObjectInputStream; |
| class nsIObjectOutputStream; |
| |
| class nsHashtable; |
| class nsStringKey; |
| |
| class NS_COM 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 PRUint32 HashCode(void) const = 0; |
| virtual PRBool 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 = PR_FALSE, |
| kHashEnumerateNext = PR_TRUE, |
| kHashEnumerateRemove = 2 |
| }; |
| |
| typedef PRIntn |
| (*PR_CALLBACK nsHashtableEnumFunc)(nsHashKey *aKey, void *aData, void* aClosure); |
| |
| typedef nsresult |
| (*PR_CALLBACK 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 |
| (*PR_CALLBACK nsHashtableFreeEntryFunc)(nsIObjectInputStream *aStream, |
| nsHashKey *aKey, |
| void *aData); |
| |
| typedef nsresult |
| (*PR_CALLBACK nsHashtableWriteDataFunc)(nsIObjectOutputStream *aStream, |
| void *aData); |
| |
| class NS_COM nsHashtable { |
| protected: |
| // members |
| PRLock* mLock; |
| PLDHashTable mHashtable; |
| PRBool mEnumerating; |
| |
| public: |
| nsHashtable(PRUint32 aSize = 16, PRBool threadSafe = PR_FALSE); |
| virtual ~nsHashtable(); |
| |
| PRInt32 Count(void) { return mHashtable.entryCount; } |
| PRBool 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 = NULL); |
| void Reset(); |
| void Reset(nsHashtableEnumFunc destroyFunc, void* aClosure = NULL); |
| |
| 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* (*PR_CALLBACK nsHashtableCloneElementFunc)(nsHashKey *aKey, void *aData, void* aClosure); |
| |
| class NS_COM nsObjectHashtable : public nsHashtable { |
| public: |
| nsObjectHashtable(nsHashtableCloneElementFunc cloneElementFun, |
| void* cloneElementClosure, |
| nsHashtableEnumFunc destroyElementFun, |
| void* destroyElementClosure, |
| PRUint32 aSize = 16, PRBool threadSafe = PR_FALSE); |
| ~nsObjectHashtable(); |
| |
| nsHashtable *Clone(); |
| void Reset(); |
| PRBool RemoveAndDelete(nsHashKey *aKey); |
| |
| protected: |
| static PLDHashOperator PR_CALLBACK CopyElement(PLDHashTable* table, |
| PLDHashEntryHdr* hdr, |
| PRUint32 i, void *arg); |
| |
| nsHashtableCloneElementFunc mCloneElementFun; |
| void* mCloneElementClosure; |
| nsHashtableEnumFunc mDestroyElementFun; |
| void* mDestroyElementClosure; |
| }; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // nsSupportsHashtable: an nsHashtable where the elements are nsISupports* |
| |
| class nsISupports; |
| |
| class NS_COM nsSupportsHashtable |
| : private nsHashtable |
| { |
| public: |
| typedef PRBool (* PR_CALLBACK EnumFunc) (nsHashKey *aKey, void *aData, void* aClosure); |
| |
| nsSupportsHashtable(PRUint32 aSize = 16, PRBool threadSafe = PR_FALSE) |
| : nsHashtable(aSize, threadSafe) {} |
| ~nsSupportsHashtable(); |
| |
| PRInt32 Count(void) { |
| return nsHashtable::Count(); |
| } |
| PRBool Exists(nsHashKey *aKey) { |
| return nsHashtable::Exists (aKey); |
| } |
| PRBool Put(nsHashKey *aKey, |
| nsISupports *aData, |
| nsISupports **value = nsnull); |
| nsISupports* Get(nsHashKey *aKey); |
| PRBool Remove(nsHashKey *aKey, nsISupports **value = nsnull); |
| nsHashtable *Clone(); |
| void Enumerate(EnumFunc aEnumFunc, void* aClosure = NULL) { |
| nsHashtable::Enumerate(aEnumFunc, aClosure); |
| } |
| void Reset(); |
| |
| private: |
| static PRBool PR_CALLBACK ReleaseElement(nsHashKey *, void *, void *); |
| static PLDHashOperator PR_CALLBACK EnumerateCopy(PLDHashTable*, |
| PLDHashEntryHdr* hdr, |
| PRUint32 i, void *arg); |
| }; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // nsISupportsKey: Where keys are nsISupports objects that get refcounted. |
| |
| #include "nsISupports.h" |
| |
| class NS_COM nsISupportsKey : public nsHashKey { |
| protected: |
| nsISupports* mKey; |
| |
| public: |
| nsISupportsKey(const nsISupportsKey& aKey) : mKey(aKey.mKey) { |
| #ifdef DEBUG |
| mKeyType = SupportsKey; |
| #endif |
| NS_IF_ADDREF(mKey); |
| } |
| |
| nsISupportsKey(nsISupports* key) { |
| #ifdef DEBUG |
| mKeyType = SupportsKey; |
| #endif |
| mKey = key; |
| NS_IF_ADDREF(mKey); |
| } |
| |
| ~nsISupportsKey(void) { |
| NS_IF_RELEASE(mKey); |
| } |
| |
| PRUint32 HashCode(void) const { |
| return NS_PTR_TO_INT32(mKey); |
| } |
| |
| PRBool Equals(const nsHashKey *aKey) const { |
| NS_ASSERTION(aKey->GetKeyType() == SupportsKey, "mismatched key types"); |
| return (mKey == ((nsISupportsKey *) aKey)->mKey); |
| } |
| |
| nsHashKey *Clone() const { |
| return new nsISupportsKey(mKey); |
| } |
| |
| nsISupportsKey(nsIObjectInputStream* aStream, nsresult *aResult); |
| nsresult Write(nsIObjectOutputStream* aStream) const; |
| }; |
| |
| |
| class nsPRUint32Key : public nsHashKey { |
| protected: |
| PRUint32 mKey; |
| public: |
| nsPRUint32Key(PRUint32 key) { |
| #ifdef DEBUG |
| mKeyType = PRUint32Key; |
| #endif |
| mKey = key; |
| } |
| |
| PRUint32 HashCode(void) const { |
| return mKey; |
| } |
| |
| PRBool Equals(const nsHashKey *aKey) const { |
| return mKey == ((const nsPRUint32Key *) aKey)->mKey; |
| } |
| nsHashKey *Clone() const { |
| return new nsPRUint32Key(mKey); |
| } |
| PRUint32 GetValue() { return mKey; } |
| }; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // nsVoidKey: Where keys are void* objects that don't get refcounted. |
| |
| class nsVoidKey : public nsHashKey { |
| protected: |
| void* mKey; |
| |
| public: |
| nsVoidKey(const nsVoidKey& aKey) : mKey(aKey.mKey) { |
| #ifdef DEBUG |
| mKeyType = aKey.mKeyType; |
| #endif |
| } |
| |
| nsVoidKey(void* key) { |
| #ifdef DEBUG |
| mKeyType = VoidKey; |
| #endif |
| mKey = key; |
| } |
| |
| PRUint32 HashCode(void) const { |
| return NS_PTR_TO_INT32(mKey); |
| } |
| |
| PRBool Equals(const nsHashKey *aKey) const { |
| NS_ASSERTION(aKey->GetKeyType() == VoidKey, "mismatched key types"); |
| return (mKey == ((const nsVoidKey *) aKey)->mKey); |
| } |
| |
| nsHashKey *Clone() const { |
| return new nsVoidKey(mKey); |
| } |
| |
| void* GetValue() { return mKey; } |
| }; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // nsIDKey: Where keys are nsIDs (e.g. nsIID, nsCID). |
| |
| #include "nsID.h" |
| |
| class NS_COM nsIDKey : public nsHashKey { |
| protected: |
| nsID mID; |
| |
| public: |
| nsIDKey(const nsIDKey& aKey) : mID(aKey.mID) { |
| #ifdef DEBUG |
| mKeyType = IDKey; |
| #endif |
| } |
| |
| nsIDKey(const nsID &aID) { |
| #ifdef DEBUG |
| mKeyType = IDKey; |
| #endif |
| mID = aID; |
| } |
| |
| PRUint32 HashCode(void) const { |
| return mID.m0; |
| } |
| |
| PRBool Equals(const nsHashKey *aKey) const { |
| NS_ASSERTION(aKey->GetKeyType() == IDKey, "mismatched key types"); |
| return (mID.Equals(((const nsIDKey *) aKey)->mID)); |
| } |
| |
| nsHashKey *Clone() const { |
| return new nsIDKey(mID); |
| } |
| |
| nsIDKey(nsIObjectInputStream* aStream, nsresult *aResult); |
| nsresult Write(nsIObjectOutputStream* aStream) const; |
| }; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| #include "nsString.h" |
| |
| // for null-terminated c-strings |
| class NS_COM 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, PRInt32 strLen = -1, Ownership own = OWN_CLONE); |
| nsCStringKey(const nsAFlatCString& str); |
| nsCStringKey(const nsACString& str); |
| ~nsCStringKey(void); |
| |
| PRUint32 HashCode(void) const; |
| PRBool 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; } |
| PRUint32 GetStringLength() const { return mStrLen; } |
| |
| protected: |
| char* mStr; |
| PRUint32 mStrLen; |
| Ownership mOwnership; |
| }; |
| |
| // for null-terminated unicode strings |
| class NS_COM nsStringKey : 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. |
| }; |
| |
| nsStringKey(const nsStringKey& aKey); |
| nsStringKey(const PRUnichar* str, PRInt32 strLen = -1, Ownership own = OWN_CLONE); |
| nsStringKey(const nsAFlatString& str); |
| nsStringKey(const nsAString& str); |
| ~nsStringKey(void); |
| |
| PRUint32 HashCode(void) const; |
| PRBool Equals(const nsHashKey* aKey) const; |
| nsHashKey* Clone() const; |
| nsStringKey(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 PRUnichar* GetString() const { return mStr; } |
| PRUint32 GetStringLength() const { return mStrLen; } |
| |
| protected: |
| PRUnichar* mStr; |
| PRUint32 mStrLen; |
| Ownership mOwnership; |
| }; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| #endif // nsHashtable_h__ |