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
4 : *
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/
9 : *
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.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
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.
21 : *
22 : * Contributor(s):
23 : *
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.
35 : *
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
41 : *
42 : * Modifications to Mozilla code or documentation
43 : * identified per MPL Section 3.3
44 : *
45 : * Date Modified by Description of modification
46 : * 04/20/2000 IBM Corp. Added PR_CALLBACK for Optlink use in OS2
47 : */
48 :
49 : /**
50 : * nsHashtable is OBSOLETE. Use nsTHashtable or a derivative instead.
51 : */
52 :
53 : #ifndef nsHashtable_h__
54 : #define nsHashtable_h__
55 :
56 : #include "pldhash.h"
57 : #include "prlock.h"
58 : #include "nscore.h"
59 : #include "nsString.h"
60 : #include "nsISupportsBase.h"
61 : #include "nsTraceRefcnt.h"
62 :
63 : class nsIObjectInputStream;
64 : class nsIObjectOutputStream;
65 :
66 : class nsHashtable;
67 : class nsStringKey;
68 :
69 : class nsHashKey {
70 : protected:
71 0 : nsHashKey(void) {
72 : #ifdef DEBUG
73 0 : mKeyType = UnknownKey;
74 : #endif
75 0 : MOZ_COUNT_CTOR(nsHashKey);
76 0 : }
77 :
78 :
79 : public:
80 : // Virtual destructor because all hash keys are |delete|d via a
81 : // nsHashKey pointer.
82 :
83 : virtual ~nsHashKey(void);
84 : virtual PRUint32 HashCode(void) const = 0;
85 : virtual bool Equals(const nsHashKey *aKey) const = 0;
86 : virtual nsHashKey *Clone() const = 0;
87 : virtual nsresult Write(nsIObjectOutputStream* aStream) const;
88 :
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
100 : };
101 0 : nsHashKeyType GetKeyType() const { return mKeyType; }
102 : protected:
103 : nsHashKeyType mKeyType;
104 : #endif
105 : };
106 :
107 : // Enumerator and Read/Write callback functions.
108 :
109 : // Return values for nsHashtableEnumFunc
110 : enum {
111 : kHashEnumerateStop = false,
112 : kHashEnumerateNext = true
113 : };
114 :
115 : typedef bool
116 : (* nsHashtableEnumFunc)(nsHashKey *aKey, void *aData, void* aClosure);
117 :
118 : typedef nsresult
119 : (* nsHashtableReadEntryFunc)(nsIObjectInputStream *aStream, nsHashKey **aKey,
120 : void **aData);
121 :
122 : // NB: may be called with null aKey or aData, to free just one of the two.
123 : typedef void
124 : (* nsHashtableFreeEntryFunc)(nsIObjectInputStream *aStream, nsHashKey *aKey,
125 : void *aData);
126 :
127 : typedef nsresult
128 : (* nsHashtableWriteDataFunc)(nsIObjectOutputStream *aStream, void *aData);
129 :
130 : class nsHashtable {
131 : protected:
132 : // members
133 : PRLock* mLock;
134 : PLDHashTable mHashtable;
135 : bool mEnumerating;
136 :
137 : public:
138 : nsHashtable(PRUint32 aSize = 16, bool threadSafe = false);
139 : virtual ~nsHashtable();
140 :
141 0 : PRInt32 Count(void) { return mHashtable.entryCount; }
142 : bool Exists(nsHashKey *aKey);
143 : void *Put(nsHashKey *aKey, void *aData);
144 : void *Get(nsHashKey *aKey);
145 : void *Remove(nsHashKey *aKey);
146 : nsHashtable *Clone();
147 : void Enumerate(nsHashtableEnumFunc aEnumFunc, void* aClosure = NULL);
148 : void Reset();
149 : void Reset(nsHashtableEnumFunc destroyFunc, void* aClosure = NULL);
150 :
151 : nsHashtable(nsIObjectInputStream* aStream,
152 : nsHashtableReadEntryFunc aReadEntryFunc,
153 : nsHashtableFreeEntryFunc aFreeEntryFunc,
154 : nsresult *aRetVal);
155 : nsresult Write(nsIObjectOutputStream* aStream,
156 : nsHashtableWriteDataFunc aWriteDataFunc) const;
157 : };
158 :
159 : ////////////////////////////////////////////////////////////////////////////////
160 : // nsObjectHashtable: an nsHashtable where the elements are C++ objects to be
161 : // deleted
162 :
163 : typedef void* (* nsHashtableCloneElementFunc)(nsHashKey *aKey, void *aData, void* aClosure);
164 :
165 : class nsObjectHashtable : public nsHashtable {
166 : public:
167 : nsObjectHashtable(nsHashtableCloneElementFunc cloneElementFun,
168 : void* cloneElementClosure,
169 : nsHashtableEnumFunc destroyElementFun,
170 : void* destroyElementClosure,
171 : PRUint32 aSize = 16, bool threadSafe = false);
172 : ~nsObjectHashtable();
173 :
174 : nsHashtable *Clone();
175 : void Reset();
176 : bool RemoveAndDelete(nsHashKey *aKey);
177 :
178 : protected:
179 : static PLDHashOperator CopyElement(PLDHashTable* table,
180 : PLDHashEntryHdr* hdr,
181 : PRUint32 i, void *arg);
182 :
183 : nsHashtableCloneElementFunc mCloneElementFun;
184 : void* mCloneElementClosure;
185 : nsHashtableEnumFunc mDestroyElementFun;
186 : void* mDestroyElementClosure;
187 : };
188 :
189 : ////////////////////////////////////////////////////////////////////////////////
190 : // nsSupportsHashtable: an nsHashtable where the elements are nsISupports*
191 :
192 : class nsISupports;
193 :
194 : class nsSupportsHashtable
195 : : private nsHashtable
196 : {
197 : public:
198 0 : nsSupportsHashtable(PRUint32 aSize = 16, bool threadSafe = false)
199 0 : : nsHashtable(aSize, threadSafe) {}
200 : ~nsSupportsHashtable();
201 :
202 0 : PRInt32 Count(void) {
203 0 : return nsHashtable::Count();
204 : }
205 : bool Exists(nsHashKey *aKey) {
206 : return nsHashtable::Exists (aKey);
207 : }
208 : bool Put(nsHashKey *aKey,
209 : nsISupports *aData,
210 : nsISupports **value = nsnull);
211 : nsISupports* Get(nsHashKey *aKey);
212 : bool Remove(nsHashKey *aKey, nsISupports **value = nsnull);
213 : nsHashtable *Clone();
214 0 : void Enumerate(nsHashtableEnumFunc aEnumFunc, void* aClosure = NULL) {
215 0 : nsHashtable::Enumerate(aEnumFunc, aClosure);
216 0 : }
217 : void Reset();
218 :
219 : private:
220 : static bool ReleaseElement(nsHashKey *, void *, void *);
221 : static PLDHashOperator EnumerateCopy(PLDHashTable*,
222 : PLDHashEntryHdr* hdr,
223 : PRUint32 i, void *arg);
224 : };
225 :
226 : ////////////////////////////////////////////////////////////////////////////////
227 : // nsISupportsKey: Where keys are nsISupports objects that get refcounted.
228 :
229 : #include "nsISupports.h"
230 :
231 : class nsISupportsKey : public nsHashKey {
232 : protected:
233 : nsISupports* mKey;
234 :
235 : public:
236 : nsISupportsKey(const nsISupportsKey& aKey) : mKey(aKey.mKey) {
237 : #ifdef DEBUG
238 : mKeyType = SupportsKey;
239 : #endif
240 : NS_IF_ADDREF(mKey);
241 : }
242 :
243 968 : nsISupportsKey(nsISupports* key) {
244 : #ifdef DEBUG
245 968 : mKeyType = SupportsKey;
246 : #endif
247 968 : mKey = key;
248 968 : NS_IF_ADDREF(mKey);
249 968 : }
250 :
251 1494 : ~nsISupportsKey(void) {
252 706 : NS_IF_RELEASE(mKey);
253 1576 : }
254 :
255 714 : PRUint32 HashCode(void) const {
256 714 : return NS_PTR_TO_INT32(mKey);
257 : }
258 :
259 336 : bool Equals(const nsHashKey *aKey) const {
260 336 : NS_ASSERTION(aKey->GetKeyType() == SupportsKey, "mismatched key types");
261 336 : return (mKey == ((nsISupportsKey *) aKey)->mKey);
262 : }
263 :
264 344 : nsHashKey *Clone() const {
265 344 : return new nsISupportsKey(mKey);
266 : }
267 :
268 : nsISupportsKey(nsIObjectInputStream* aStream, nsresult *aResult);
269 : nsresult Write(nsIObjectOutputStream* aStream) const;
270 :
271 0 : nsISupports* GetValue() { return mKey; }
272 : };
273 :
274 :
275 0 : class nsPRUint32Key : public nsHashKey {
276 : protected:
277 : PRUint32 mKey;
278 : public:
279 0 : nsPRUint32Key(PRUint32 key) {
280 : #ifdef DEBUG
281 0 : mKeyType = PRUint32Key;
282 : #endif
283 0 : mKey = key;
284 0 : }
285 :
286 0 : PRUint32 HashCode(void) const {
287 0 : return mKey;
288 : }
289 :
290 0 : bool Equals(const nsHashKey *aKey) const {
291 0 : return mKey == ((const nsPRUint32Key *) aKey)->mKey;
292 : }
293 0 : nsHashKey *Clone() const {
294 0 : return new nsPRUint32Key(mKey);
295 : }
296 0 : PRUint32 GetValue() { return mKey; }
297 : };
298 :
299 : ////////////////////////////////////////////////////////////////////////////////
300 : // nsVoidKey: Where keys are void* objects that don't get refcounted.
301 :
302 : class nsVoidKey : public nsHashKey {
303 : protected:
304 : void* mKey;
305 :
306 : public:
307 : nsVoidKey(const nsVoidKey& aKey) : mKey(aKey.mKey) {
308 : #ifdef DEBUG
309 : mKeyType = aKey.mKeyType;
310 : #endif
311 : }
312 :
313 : nsVoidKey(void* key) {
314 : #ifdef DEBUG
315 : mKeyType = VoidKey;
316 : #endif
317 : mKey = key;
318 : }
319 :
320 : PRUint32 HashCode(void) const {
321 : return NS_PTR_TO_INT32(mKey);
322 : }
323 :
324 : bool Equals(const nsHashKey *aKey) const {
325 : NS_ASSERTION(aKey->GetKeyType() == VoidKey, "mismatched key types");
326 : return (mKey == ((const nsVoidKey *) aKey)->mKey);
327 : }
328 :
329 : nsHashKey *Clone() const {
330 : return new nsVoidKey(mKey);
331 : }
332 :
333 : void* GetValue() { return mKey; }
334 : };
335 :
336 : #include "nsString.h"
337 :
338 : // for null-terminated c-strings
339 : class nsCStringKey : public nsHashKey {
340 : public:
341 :
342 : // NB: when serializing, NEVER_OWN keys are deserialized as OWN.
343 : enum Ownership {
344 : NEVER_OWN, // very long lived, even clones don't need to copy it.
345 : OWN_CLONE, // as long lived as this key. But clones make a copy.
346 : OWN // to be free'd in key dtor. Clones make their own copy.
347 : };
348 :
349 : nsCStringKey(const nsCStringKey& aStrKey);
350 : nsCStringKey(const char* str, PRInt32 strLen = -1, Ownership own = OWN_CLONE);
351 : nsCStringKey(const nsAFlatCString& str);
352 : nsCStringKey(const nsACString& str);
353 : ~nsCStringKey(void);
354 :
355 : PRUint32 HashCode(void) const;
356 : bool Equals(const nsHashKey* aKey) const;
357 : nsHashKey* Clone() const;
358 : nsCStringKey(nsIObjectInputStream* aStream, nsresult *aResult);
359 : nsresult Write(nsIObjectOutputStream* aStream) const;
360 :
361 : // For when the owner of the hashtable wants to peek at the actual
362 : // string in the key. No copy is made, so be careful.
363 : const char* GetString() const { return mStr; }
364 : PRUint32 GetStringLength() const { return mStrLen; }
365 :
366 : protected:
367 : char* mStr;
368 : PRUint32 mStrLen;
369 : Ownership mOwnership;
370 : };
371 :
372 : // for null-terminated unicode strings
373 : class nsStringKey : public nsHashKey {
374 : public:
375 :
376 : // NB: when serializing, NEVER_OWN keys are deserialized as OWN.
377 : enum Ownership {
378 : NEVER_OWN, // very long lived, even clones don't need to copy it.
379 : OWN_CLONE, // as long lived as this key. But clones make a copy.
380 : OWN // to be free'd in key dtor. Clones make their own copy.
381 : };
382 :
383 : nsStringKey(const nsStringKey& aKey);
384 : nsStringKey(const PRUnichar* str, PRInt32 strLen = -1, Ownership own = OWN_CLONE);
385 : nsStringKey(const nsAFlatString& str);
386 : nsStringKey(const nsAString& str);
387 : ~nsStringKey(void);
388 :
389 : PRUint32 HashCode(void) const;
390 : bool Equals(const nsHashKey* aKey) const;
391 : nsHashKey* Clone() const;
392 : nsStringKey(nsIObjectInputStream* aStream, nsresult *aResult);
393 : nsresult Write(nsIObjectOutputStream* aStream) const;
394 :
395 : // For when the owner of the hashtable wants to peek at the actual
396 : // string in the key. No copy is made, so be careful.
397 : const PRUnichar* GetString() const { return mStr; }
398 : PRUint32 GetStringLength() const { return mStrLen; }
399 :
400 : protected:
401 : PRUnichar* mStr;
402 : PRUint32 mStrLen;
403 : Ownership mOwnership;
404 : };
405 :
406 : ////////////////////////////////////////////////////////////////////////////////
407 :
408 : #endif // nsHashtable_h__
|