PageRenderTime 629ms CodeModel.GetById 81ms app.highlight 397ms RepoModel.GetById 78ms app.codeStats 1ms

/gecko_api/include/nsHashKeys.h

http://firefox-mac-pdf.googlecode.com/
C++ Header | 427 lines | 242 code | 72 blank | 113 comment | 7 complexity | 1903992b2c7644a55689bfb1e7e332d0 MD5 | raw file
  1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  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 C++ hashtable templates.
 16 *
 17 * The Initial Developer of the Original Code is
 18 * Benjamin Smedberg.
 19 * Portions created by the Initial Developer are Copyright (C) 2002
 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 the GNU General Public License Version 2 or later (the "GPL"), or
 26 * 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
 38#ifndef nsTHashKeys_h__
 39#define nsTHashKeys_h__
 40
 41#include "nsID.h"
 42#include "nsISupports.h"
 43#include "nsIHashable.h"
 44#include "nsCOMPtr.h"
 45#include "pldhash.h"
 46#include NEW_H
 47
 48#include "nsStringGlue.h"
 49#include "nsCRTGlue.h"
 50
 51#include <stdlib.h>
 52#include <string.h>
 53
 54/** @file nsHashKeys.h
 55 * standard HashKey classes for nsBaseHashtable and relatives. Each of these
 56 * classes follows the nsTHashtable::EntryType specification
 57 *
 58 * Lightweight keytypes provided here:
 59 * nsStringHashKey
 60 * nsCStringHashKey
 61 * nsUint32HashKey
 62 * nsVoidPtrHashKey
 63 * nsClearingVoidPtrHashKey
 64 * nsISupportsHashKey
 65 * nsIDHashKey
 66 * nsDepCharHashKey
 67 * nsCharPtrHashKey
 68 * nsUnicharPtrHashKey
 69 * nsHashableHashKey
 70 */
 71
 72NS_COM_GLUE PRUint32 HashString(const nsAString& aStr);
 73NS_COM_GLUE PRUint32 HashString(const nsACString& aStr);
 74NS_COM_GLUE PRUint32 HashString(const char* aKey);
 75NS_COM_GLUE PRUint32 HashString(const PRUnichar* aKey);
 76
 77/**
 78 * hashkey wrapper using nsAString KeyType
 79 *
 80 * @see nsTHashtable::EntryType for specification
 81 */
 82class nsStringHashKey : public PLDHashEntryHdr
 83{
 84public:
 85  typedef const nsAString& KeyType;
 86  typedef const nsAString* KeyTypePointer;
 87
 88  nsStringHashKey(KeyTypePointer aStr) : mStr(*aStr) { }
 89  nsStringHashKey(const nsStringHashKey& toCopy) : mStr(toCopy.mStr) { }
 90  ~nsStringHashKey() { }
 91
 92  KeyType GetKey() const { return mStr; }
 93  PRBool KeyEquals(const KeyTypePointer aKey) const
 94  {
 95    return mStr.Equals(*aKey);
 96  }
 97
 98  static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
 99  static PLDHashNumber HashKey(const KeyTypePointer aKey)
100  {
101    return HashString(*aKey);
102  }
103  enum { ALLOW_MEMMOVE = PR_TRUE };
104
105private:
106  const nsString mStr;
107};
108
109/**
110 * hashkey wrapper using nsACString KeyType
111 *
112 * @see nsTHashtable::EntryType for specification
113 */
114class nsCStringHashKey : public PLDHashEntryHdr
115{
116public:
117  typedef const nsACString& KeyType;
118  typedef const nsACString* KeyTypePointer;
119  
120  nsCStringHashKey(const nsACString* aStr) : mStr(*aStr) { }
121  nsCStringHashKey(const nsCStringHashKey& toCopy) : mStr(toCopy.mStr) { }
122  ~nsCStringHashKey() { }
123
124  KeyType GetKey() const { return mStr; }
125
126  PRBool KeyEquals(KeyTypePointer aKey) const { return mStr.Equals(*aKey); }
127
128  static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
129  static PLDHashNumber HashKey(KeyTypePointer aKey)
130  {
131    return HashString(*aKey);
132  }
133  enum { ALLOW_MEMMOVE = PR_TRUE };
134
135private:
136  const nsCString mStr;
137};
138
139/**
140 * hashkey wrapper using PRUint32 KeyType
141 *
142 * @see nsTHashtable::EntryType for specification
143 */
144class nsUint32HashKey : public PLDHashEntryHdr
145{
146public:
147  typedef const PRUint32& KeyType;
148  typedef const PRUint32* KeyTypePointer;
149  
150  nsUint32HashKey(KeyTypePointer aKey) : mValue(*aKey) { }
151  nsUint32HashKey(const nsUint32HashKey& toCopy) : mValue(toCopy.mValue) { }
152  ~nsUint32HashKey() { }
153
154  KeyType GetKey() const { return mValue; }
155  PRBool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
156
157  static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
158  static PLDHashNumber HashKey(KeyTypePointer aKey) { return *aKey; }
159  enum { ALLOW_MEMMOVE = PR_TRUE };
160
161private:
162  const PRUint32 mValue;
163};
164
165/**
166 * hashkey wrapper using nsISupports* KeyType
167 *
168 * @see nsTHashtable::EntryType for specification
169 */
170class nsISupportsHashKey : public PLDHashEntryHdr
171{
172public:
173  typedef nsISupports* KeyType;
174  typedef const nsISupports* KeyTypePointer;
175
176  nsISupportsHashKey(const nsISupports* key) :
177    mSupports(const_cast<nsISupports*>(key)) { }
178  nsISupportsHashKey(const nsISupportsHashKey& toCopy) :
179    mSupports(toCopy.mSupports) { }
180  ~nsISupportsHashKey() { }
181
182  KeyType GetKey() const { return mSupports; }
183  
184  PRBool KeyEquals(KeyTypePointer aKey) const { return aKey == mSupports; }
185
186  static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
187  static PLDHashNumber HashKey(KeyTypePointer aKey)
188  {
189    return NS_PTR_TO_INT32(aKey) >>2;
190  }
191  enum { ALLOW_MEMMOVE = PR_TRUE };
192
193private:
194  nsCOMPtr<nsISupports> mSupports;
195};
196
197/**
198 * hashkey wrapper using void* KeyType
199 *
200 * @see nsTHashtable::EntryType for specification
201 */
202class nsVoidPtrHashKey : public PLDHashEntryHdr
203{
204public:
205  typedef const void* KeyType;
206  typedef const void* KeyTypePointer;
207
208  nsVoidPtrHashKey(const void* key) :
209    mKey(key) { }
210  nsVoidPtrHashKey(const nsVoidPtrHashKey& toCopy) :
211    mKey(toCopy.mKey) { }
212  ~nsVoidPtrHashKey() { }
213
214  KeyType GetKey() const { return mKey; }
215  
216  PRBool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
217
218  static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
219  static PLDHashNumber HashKey(KeyTypePointer aKey)
220  {
221    return NS_PTR_TO_INT32(aKey) >>2;
222  }
223  enum { ALLOW_MEMMOVE = PR_TRUE };
224
225private:
226  const void* mKey;
227};
228
229/**
230 * hashkey wrapper using void* KeyType, that sets key to NULL upon
231 * destruction. Relevant only in cases where a memory pointer-scanner
232 * like valgrind might get confused about stale references.
233 *
234 * @see nsTHashtable::EntryType for specification
235 */
236
237class nsClearingVoidPtrHashKey : public PLDHashEntryHdr
238{
239public:
240  typedef const void* KeyType;
241  typedef const void* KeyTypePointer;
242
243  nsClearingVoidPtrHashKey(const void* key) :
244    mKey(key) { }
245  nsClearingVoidPtrHashKey(const nsClearingVoidPtrHashKey& toCopy) :
246    mKey(toCopy.mKey) { }
247  ~nsClearingVoidPtrHashKey() { mKey = NULL; }
248
249  KeyType GetKey() const { return mKey; }
250  
251  PRBool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
252
253  static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
254  static PLDHashNumber HashKey(KeyTypePointer aKey)
255  {
256    return NS_PTR_TO_INT32(aKey) >>2;
257  }
258  enum { ALLOW_MEMMOVE = PR_TRUE };
259
260private:
261  const void* mKey;
262};
263
264/**
265 * hashkey wrapper using nsID KeyType
266 *
267 * @see nsTHashtable::EntryType for specification
268 */
269class nsIDHashKey : public PLDHashEntryHdr
270{
271public:
272  typedef const nsID& KeyType;
273  typedef const nsID* KeyTypePointer;
274  
275  nsIDHashKey(const nsID* inID) : mID(*inID) { }
276  nsIDHashKey(const nsIDHashKey& toCopy) : mID(toCopy.mID) { }
277  ~nsIDHashKey() { }
278
279  KeyType GetKey() const { return mID; }
280
281  PRBool KeyEquals(KeyTypePointer aKey) const { return aKey->Equals(mID); }
282
283  static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
284  static PLDHashNumber HashKey(KeyTypePointer aKey);
285  enum { ALLOW_MEMMOVE = PR_TRUE };
286
287private:
288  const nsID mID;
289};
290
291/**
292 * hashkey wrapper for "dependent" const char*; this class does not "own"
293 * its string pointer.
294 *
295 * This class must only be used if the strings have a lifetime longer than
296 * the hashtable they occupy. This normally occurs only for static
297 * strings or strings that have been arena-allocated.
298 *
299 * @see nsTHashtable::EntryType for specification
300 */
301class nsDepCharHashKey : public PLDHashEntryHdr
302{
303public:
304  typedef const char* KeyType;
305  typedef const char* KeyTypePointer;
306
307  nsDepCharHashKey(const char* aKey) { mKey = aKey; }
308  nsDepCharHashKey(const nsDepCharHashKey& toCopy) { mKey = toCopy.mKey; }
309  ~nsDepCharHashKey() { }
310
311  const char* GetKey() const { return mKey; }
312  PRBool KeyEquals(const char* aKey) const
313  {
314    return !strcmp(mKey, aKey);
315  }
316
317  static const char* KeyToPointer(const char* aKey) { return aKey; }
318  static PLDHashNumber HashKey(const char* aKey) { return HashString(aKey); }
319  enum { ALLOW_MEMMOVE = PR_TRUE };
320
321private:
322  const char* mKey;
323};
324
325/**
326 * hashkey wrapper for const char*; at construction, this class duplicates
327 * a string pointed to by the pointer so that it doesn't matter whether or not
328 * the string lives longer than the hash table.
329 */
330class nsCharPtrHashKey : public PLDHashEntryHdr
331{
332public:
333  typedef const char* KeyType;
334  typedef const char* KeyTypePointer;
335
336  nsCharPtrHashKey(const char* aKey) : mKey(strdup(aKey)) { }
337  nsCharPtrHashKey(const nsCharPtrHashKey& toCopy) : mKey(strdup(toCopy.mKey)) { }
338  ~nsCharPtrHashKey() { if (mKey) free(const_cast<char *>(mKey)); }
339
340  const char* GetKey() const { return mKey; }
341  PRBool KeyEquals(KeyTypePointer aKey) const
342  {
343    return !strcmp(mKey, aKey);
344  }
345
346  static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
347  static PLDHashNumber HashKey(KeyTypePointer aKey) { return HashString(aKey); }
348
349  enum { ALLOW_MEMMOVE = PR_TRUE };
350
351private:
352  const char* mKey;
353};
354
355/**
356 * hashkey wrapper for const PRUnichar*; at construction, this class duplicates
357 * a string pointed to by the pointer so that it doesn't matter whether or not
358 * the string lives longer than the hash table.
359 */
360class nsUnicharPtrHashKey : public PLDHashEntryHdr
361{
362public:
363  typedef const PRUnichar* KeyType;
364  typedef const PRUnichar* KeyTypePointer;
365
366  nsUnicharPtrHashKey(const PRUnichar* aKey) : mKey(NS_strdup(aKey)) { }
367  nsUnicharPtrHashKey(const nsUnicharPtrHashKey& toCopy) : mKey(NS_strdup(toCopy.mKey)) { }
368  ~nsUnicharPtrHashKey() { if (mKey) NS_Free(const_cast<PRUnichar *>(mKey)); }
369
370  const PRUnichar* GetKey() const { return mKey; }
371  PRBool KeyEquals(KeyTypePointer aKey) const
372  {
373    return !NS_strcmp(mKey, aKey);
374  }
375
376  static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
377  static PLDHashNumber HashKey(KeyTypePointer aKey) { return HashString(aKey); }
378
379  enum { ALLOW_MEMMOVE = PR_TRUE };
380
381private:
382  const PRUnichar* mKey;
383};
384
385/**
386 * Hashtable key class to use with objects that support nsIHashable
387 */
388class nsHashableHashKey : public PLDHashEntryHdr
389{
390public:
391    typedef nsIHashable* KeyType;
392    typedef const nsIHashable* KeyTypePointer;
393
394    nsHashableHashKey(const nsIHashable* aKey) :
395        mKey(const_cast<nsIHashable*>(aKey)) { }
396    nsHashableHashKey(const nsHashableHashKey& toCopy) :
397        mKey(toCopy.mKey) { }
398    ~nsHashableHashKey() { }
399
400    nsIHashable* GetKey() const { return mKey; }
401
402    PRBool KeyEquals(const nsIHashable* aKey) const {
403        PRBool eq;
404        if (NS_SUCCEEDED(mKey->Equals(const_cast<nsIHashable*>(aKey), &eq))) {
405            return eq;
406        }
407        return PR_FALSE;
408    }
409
410    static const nsIHashable* KeyToPointer(nsIHashable* aKey) { return aKey; }
411    static PLDHashNumber HashKey(const nsIHashable* aKey) {
412        PRUint32 code = 8888; // magic number if GetHashCode fails :-(
413#ifdef NS_DEBUG
414        nsresult rv =
415#endif
416        const_cast<nsIHashable*>(aKey)->GetHashCode(&code);
417        NS_ASSERTION(NS_SUCCEEDED(rv), "GetHashCode should not throw!");
418        return code;
419    }
420    
421    enum { ALLOW_MEMMOVE = PR_TRUE };
422
423private:
424    nsCOMPtr<nsIHashable> mKey;
425};
426
427#endif // nsTHashKeys_h__