On x86 compilers without fastcall, simulate it when invoking traces and un-simulate...
[wine-gecko.git] / xpcom / ds / nsHashtable.h
blob21ce90283b917737766457d1287bfe2974f7e6e1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK *****
37 * This Original Code has been modified by IBM Corporation.
38 * Modifications made by IBM described herein are
39 * Copyright (c) International Business Machines
40 * Corporation, 2000
42 * Modifications to Mozilla code or documentation
43 * identified per MPL Section 3.3
45 * Date Modified by Description of modification
46 * 04/20/2000 IBM Corp. Added PR_CALLBACK for Optlink use in OS2
49 /**
50 * nsHashtable is OBSOLETE. Use nsTHashtable or a derivative instead.
53 #ifndef nsHashtable_h__
54 #define nsHashtable_h__
56 #include "pldhash.h"
57 #include "prlock.h"
58 #include "nscore.h"
59 #include "nsString.h"
60 #include "nsISupportsBase.h"
61 #include "nsTraceRefcnt.h"
63 class nsIObjectInputStream;
64 class nsIObjectOutputStream;
66 class nsHashtable;
67 class nsStringKey;
69 class NS_COM nsHashKey {
70 protected:
71 nsHashKey(void) {
72 #ifdef DEBUG
73 mKeyType = UnknownKey;
74 #endif
75 MOZ_COUNT_CTOR(nsHashKey);
79 public:
80 // Virtual destructor because all hash keys are |delete|d via a
81 // nsHashKey pointer.
83 virtual ~nsHashKey(void);
84 virtual PRUint32 HashCode(void) const = 0;
85 virtual PRBool Equals(const nsHashKey *aKey) const = 0;
86 virtual nsHashKey *Clone() const = 0;
87 virtual nsresult Write(nsIObjectOutputStream* aStream) const;
89 #ifdef DEBUG
90 public:
91 // used for verification that we're casting to the correct key type
92 enum nsHashKeyType {
93 UnknownKey,
94 SupportsKey,
95 PRUint32Key,
96 VoidKey,
97 IDKey,
98 CStringKey,
99 StringKey
101 nsHashKeyType GetKeyType() const { return mKeyType; }
102 protected:
103 nsHashKeyType mKeyType;
104 #endif
107 // Enumerator and Read/Write callback functions.
109 // Return values for nsHashtableEnumFunc
110 enum {
111 kHashEnumerateStop = PR_FALSE,
112 kHashEnumerateNext = PR_TRUE,
113 kHashEnumerateRemove = 2
116 typedef PRIntn
117 (*PR_CALLBACK nsHashtableEnumFunc)(nsHashKey *aKey, void *aData, void* aClosure);
119 typedef nsresult
120 (*PR_CALLBACK nsHashtableReadEntryFunc)(nsIObjectInputStream *aStream,
121 nsHashKey **aKey,
122 void **aData);
124 // NB: may be called with null aKey or aData, to free just one of the two.
125 typedef void
126 (*PR_CALLBACK nsHashtableFreeEntryFunc)(nsIObjectInputStream *aStream,
127 nsHashKey *aKey,
128 void *aData);
130 typedef nsresult
131 (*PR_CALLBACK nsHashtableWriteDataFunc)(nsIObjectOutputStream *aStream,
132 void *aData);
134 class NS_COM nsHashtable {
135 protected:
136 // members
137 PRLock* mLock;
138 PLDHashTable mHashtable;
139 PRBool mEnumerating;
141 public:
142 nsHashtable(PRUint32 aSize = 16, PRBool threadSafe = PR_FALSE);
143 virtual ~nsHashtable();
145 PRInt32 Count(void) { return mHashtable.entryCount; }
146 PRBool Exists(nsHashKey *aKey);
147 void *Put(nsHashKey *aKey, void *aData);
148 void *Get(nsHashKey *aKey);
149 void *Remove(nsHashKey *aKey);
150 nsHashtable *Clone();
151 void Enumerate(nsHashtableEnumFunc aEnumFunc, void* aClosure = NULL);
152 void Reset();
153 void Reset(nsHashtableEnumFunc destroyFunc, void* aClosure = NULL);
155 nsHashtable(nsIObjectInputStream* aStream,
156 nsHashtableReadEntryFunc aReadEntryFunc,
157 nsHashtableFreeEntryFunc aFreeEntryFunc,
158 nsresult *aRetVal);
159 nsresult Write(nsIObjectOutputStream* aStream,
160 nsHashtableWriteDataFunc aWriteDataFunc) const;
163 ////////////////////////////////////////////////////////////////////////////////
164 // nsObjectHashtable: an nsHashtable where the elements are C++ objects to be
165 // deleted
167 typedef void* (*PR_CALLBACK nsHashtableCloneElementFunc)(nsHashKey *aKey, void *aData, void* aClosure);
169 class NS_COM nsObjectHashtable : public nsHashtable {
170 public:
171 nsObjectHashtable(nsHashtableCloneElementFunc cloneElementFun,
172 void* cloneElementClosure,
173 nsHashtableEnumFunc destroyElementFun,
174 void* destroyElementClosure,
175 PRUint32 aSize = 16, PRBool threadSafe = PR_FALSE);
176 ~nsObjectHashtable();
178 nsHashtable *Clone();
179 void Reset();
180 PRBool RemoveAndDelete(nsHashKey *aKey);
182 protected:
183 static PLDHashOperator PR_CALLBACK CopyElement(PLDHashTable* table,
184 PLDHashEntryHdr* hdr,
185 PRUint32 i, void *arg);
187 nsHashtableCloneElementFunc mCloneElementFun;
188 void* mCloneElementClosure;
189 nsHashtableEnumFunc mDestroyElementFun;
190 void* mDestroyElementClosure;
193 ////////////////////////////////////////////////////////////////////////////////
194 // nsSupportsHashtable: an nsHashtable where the elements are nsISupports*
196 class nsISupports;
198 class NS_COM nsSupportsHashtable
199 : private nsHashtable
201 public:
202 typedef PRBool (* PR_CALLBACK EnumFunc) (nsHashKey *aKey, void *aData, void* aClosure);
204 nsSupportsHashtable(PRUint32 aSize = 16, PRBool threadSafe = PR_FALSE)
205 : nsHashtable(aSize, threadSafe) {}
206 ~nsSupportsHashtable();
208 PRInt32 Count(void) {
209 return nsHashtable::Count();
211 PRBool Exists(nsHashKey *aKey) {
212 return nsHashtable::Exists (aKey);
214 PRBool Put(nsHashKey *aKey,
215 nsISupports *aData,
216 nsISupports **value = nsnull);
217 nsISupports* Get(nsHashKey *aKey);
218 PRBool Remove(nsHashKey *aKey, nsISupports **value = nsnull);
219 nsHashtable *Clone();
220 void Enumerate(EnumFunc aEnumFunc, void* aClosure = NULL) {
221 nsHashtable::Enumerate(aEnumFunc, aClosure);
223 void Reset();
225 private:
226 static PRBool PR_CALLBACK ReleaseElement(nsHashKey *, void *, void *);
227 static PLDHashOperator PR_CALLBACK EnumerateCopy(PLDHashTable*,
228 PLDHashEntryHdr* hdr,
229 PRUint32 i, void *arg);
232 ////////////////////////////////////////////////////////////////////////////////
233 // nsISupportsKey: Where keys are nsISupports objects that get refcounted.
235 #include "nsISupports.h"
237 class NS_COM nsISupportsKey : public nsHashKey {
238 protected:
239 nsISupports* mKey;
241 public:
242 nsISupportsKey(const nsISupportsKey& aKey) : mKey(aKey.mKey) {
243 #ifdef DEBUG
244 mKeyType = SupportsKey;
245 #endif
246 NS_IF_ADDREF(mKey);
249 nsISupportsKey(nsISupports* key) {
250 #ifdef DEBUG
251 mKeyType = SupportsKey;
252 #endif
253 mKey = key;
254 NS_IF_ADDREF(mKey);
257 ~nsISupportsKey(void) {
258 NS_IF_RELEASE(mKey);
261 PRUint32 HashCode(void) const {
262 return NS_PTR_TO_INT32(mKey);
265 PRBool Equals(const nsHashKey *aKey) const {
266 NS_ASSERTION(aKey->GetKeyType() == SupportsKey, "mismatched key types");
267 return (mKey == ((nsISupportsKey *) aKey)->mKey);
270 nsHashKey *Clone() const {
271 return new nsISupportsKey(mKey);
274 nsISupportsKey(nsIObjectInputStream* aStream, nsresult *aResult);
275 nsresult Write(nsIObjectOutputStream* aStream) const;
279 class nsPRUint32Key : public nsHashKey {
280 protected:
281 PRUint32 mKey;
282 public:
283 nsPRUint32Key(PRUint32 key) {
284 #ifdef DEBUG
285 mKeyType = PRUint32Key;
286 #endif
287 mKey = key;
290 PRUint32 HashCode(void) const {
291 return mKey;
294 PRBool Equals(const nsHashKey *aKey) const {
295 return mKey == ((const nsPRUint32Key *) aKey)->mKey;
297 nsHashKey *Clone() const {
298 return new nsPRUint32Key(mKey);
300 PRUint32 GetValue() { return mKey; }
303 ////////////////////////////////////////////////////////////////////////////////
304 // nsVoidKey: Where keys are void* objects that don't get refcounted.
306 class nsVoidKey : public nsHashKey {
307 protected:
308 void* mKey;
310 public:
311 nsVoidKey(const nsVoidKey& aKey) : mKey(aKey.mKey) {
312 #ifdef DEBUG
313 mKeyType = aKey.mKeyType;
314 #endif
317 nsVoidKey(void* key) {
318 #ifdef DEBUG
319 mKeyType = VoidKey;
320 #endif
321 mKey = key;
324 PRUint32 HashCode(void) const {
325 return NS_PTR_TO_INT32(mKey);
328 PRBool Equals(const nsHashKey *aKey) const {
329 NS_ASSERTION(aKey->GetKeyType() == VoidKey, "mismatched key types");
330 return (mKey == ((const nsVoidKey *) aKey)->mKey);
333 nsHashKey *Clone() const {
334 return new nsVoidKey(mKey);
337 void* GetValue() { return mKey; }
340 ////////////////////////////////////////////////////////////////////////////////
341 // nsIDKey: Where keys are nsIDs (e.g. nsIID, nsCID).
343 #include "nsID.h"
345 class NS_COM nsIDKey : public nsHashKey {
346 protected:
347 nsID mID;
349 public:
350 nsIDKey(const nsIDKey& aKey) : mID(aKey.mID) {
351 #ifdef DEBUG
352 mKeyType = IDKey;
353 #endif
356 nsIDKey(const nsID &aID) {
357 #ifdef DEBUG
358 mKeyType = IDKey;
359 #endif
360 mID = aID;
363 PRUint32 HashCode(void) const {
364 return mID.m0;
367 PRBool Equals(const nsHashKey *aKey) const {
368 NS_ASSERTION(aKey->GetKeyType() == IDKey, "mismatched key types");
369 return (mID.Equals(((const nsIDKey *) aKey)->mID));
372 nsHashKey *Clone() const {
373 return new nsIDKey(mID);
376 nsIDKey(nsIObjectInputStream* aStream, nsresult *aResult);
377 nsresult Write(nsIObjectOutputStream* aStream) const;
380 ////////////////////////////////////////////////////////////////////////////////
382 #include "nsString.h"
384 // for null-terminated c-strings
385 class NS_COM nsCStringKey : public nsHashKey {
386 public:
388 // NB: when serializing, NEVER_OWN keys are deserialized as OWN.
389 enum Ownership {
390 NEVER_OWN, // very long lived, even clones don't need to copy it.
391 OWN_CLONE, // as long lived as this key. But clones make a copy.
392 OWN // to be free'd in key dtor. Clones make their own copy.
395 nsCStringKey(const nsCStringKey& aStrKey);
396 nsCStringKey(const char* str, PRInt32 strLen = -1, Ownership own = OWN_CLONE);
397 nsCStringKey(const nsAFlatCString& str);
398 nsCStringKey(const nsACString& str);
399 ~nsCStringKey(void);
401 PRUint32 HashCode(void) const;
402 PRBool Equals(const nsHashKey* aKey) const;
403 nsHashKey* Clone() const;
404 nsCStringKey(nsIObjectInputStream* aStream, nsresult *aResult);
405 nsresult Write(nsIObjectOutputStream* aStream) const;
407 // For when the owner of the hashtable wants to peek at the actual
408 // string in the key. No copy is made, so be careful.
409 const char* GetString() const { return mStr; }
410 PRUint32 GetStringLength() const { return mStrLen; }
412 protected:
413 char* mStr;
414 PRUint32 mStrLen;
415 Ownership mOwnership;
418 // for null-terminated unicode strings
419 class NS_COM nsStringKey : public nsHashKey {
420 public:
422 // NB: when serializing, NEVER_OWN keys are deserialized as OWN.
423 enum Ownership {
424 NEVER_OWN, // very long lived, even clones don't need to copy it.
425 OWN_CLONE, // as long lived as this key. But clones make a copy.
426 OWN // to be free'd in key dtor. Clones make their own copy.
429 nsStringKey(const nsStringKey& aKey);
430 nsStringKey(const PRUnichar* str, PRInt32 strLen = -1, Ownership own = OWN_CLONE);
431 nsStringKey(const nsAFlatString& str);
432 nsStringKey(const nsAString& str);
433 ~nsStringKey(void);
435 PRUint32 HashCode(void) const;
436 PRBool Equals(const nsHashKey* aKey) const;
437 nsHashKey* Clone() const;
438 nsStringKey(nsIObjectInputStream* aStream, nsresult *aResult);
439 nsresult Write(nsIObjectOutputStream* aStream) const;
441 // For when the owner of the hashtable wants to peek at the actual
442 // string in the key. No copy is made, so be careful.
443 const PRUnichar* GetString() const { return mStr; }
444 PRUint32 GetStringLength() const { return mStrLen; }
446 protected:
447 PRUnichar* mStr;
448 PRUint32 mStrLen;
449 Ownership mOwnership;
452 ////////////////////////////////////////////////////////////////////////////////
454 #endif // nsHashtable_h__