xpcom/glue/nsHashKeys.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef nsTHashKeys_h__
     7 #define nsTHashKeys_h__
     9 #include "nsID.h"
    10 #include "nsISupports.h"
    11 #include "nsIHashable.h"
    12 #include "nsAutoPtr.h"
    13 #include "nsCOMPtr.h"
    14 #include "pldhash.h"
    15 #include <new>
    17 #include "nsStringGlue.h"
    18 #include "nsCRTGlue.h"
    19 #include "nsUnicharUtils.h"
    21 #include <stdlib.h>
    22 #include <string.h>
    24 #include "mozilla/HashFunctions.h"
    25 #include "mozilla/Move.h"
    27 namespace mozilla {
    29 // These are defined analogously to the HashString overloads in mfbt.
    31 inline uint32_t
    32 HashString(const nsAString& aStr)
    33 {
    34   return HashString(aStr.BeginReading(), aStr.Length());
    35 }
    37 inline uint32_t
    38 HashString(const nsACString& aStr)
    39 {
    40   return HashString(aStr.BeginReading(), aStr.Length());
    41 }
    43 } // namespace mozilla
    45 /** @file nsHashKeys.h
    46  * standard HashKey classes for nsBaseHashtable and relatives. Each of these
    47  * classes follows the nsTHashtable::EntryType specification
    48  *
    49  * Lightweight keytypes provided here:
    50  * nsStringHashKey
    51  * nsCStringHashKey
    52  * nsUint32HashKey
    53  * nsUint64HashKey
    54  * nsFloatHashKey
    55  * nsPtrHashkey
    56  * nsClearingPtrHashKey
    57  * nsVoidPtrHashKey
    58  * nsClearingVoidPtrHashKey
    59  * nsISupportsHashKey
    60  * nsIDHashKey
    61  * nsDepCharHashKey
    62  * nsCharPtrHashKey
    63  * nsUnicharPtrHashKey
    64  * nsHashableHashKey
    65  * nsGenericHashKey
    66  */
    68 /**
    69  * hashkey wrapper using nsAString KeyType
    70  *
    71  * @see nsTHashtable::EntryType for specification
    72  */
    73 class nsStringHashKey : public PLDHashEntryHdr
    74 {
    75 public:
    76   typedef const nsAString& KeyType;
    77   typedef const nsAString* KeyTypePointer;
    79   nsStringHashKey(KeyTypePointer aStr) : mStr(*aStr) { }
    80   nsStringHashKey(const nsStringHashKey& toCopy) : mStr(toCopy.mStr) { }
    81   ~nsStringHashKey() { }
    83   KeyType GetKey() const { return mStr; }
    84   bool KeyEquals(const KeyTypePointer aKey) const
    85   {
    86     return mStr.Equals(*aKey);
    87   }
    89   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
    90   static PLDHashNumber HashKey(const KeyTypePointer aKey)
    91   {
    92     return mozilla::HashString(*aKey);
    93   }
    94   enum { ALLOW_MEMMOVE = true };
    96 private:
    97   const nsString mStr;
    98 };
   100 #ifdef MOZILLA_INTERNAL_API
   102 /**
   103  * hashkey wrapper using nsAString KeyType
   104  *
   105  * This is internal-API only because nsCaseInsensitiveStringComparator is
   106  * internal-only.
   107  *
   108  * @see nsTHashtable::EntryType for specification
   109  */
   110 class nsStringCaseInsensitiveHashKey : public PLDHashEntryHdr
   111 {
   112 public:
   113   typedef const nsAString& KeyType;
   114   typedef const nsAString* KeyTypePointer;
   116   nsStringCaseInsensitiveHashKey(KeyTypePointer aStr) : mStr(*aStr) { } //take it easy just deal HashKey
   117   nsStringCaseInsensitiveHashKey(const nsStringCaseInsensitiveHashKey& toCopy) : mStr(toCopy.mStr) { }
   118   ~nsStringCaseInsensitiveHashKey() { }
   120   KeyType GetKey() const { return mStr; }
   121   bool KeyEquals(const KeyTypePointer aKey) const
   122   {
   123     return mStr.Equals(*aKey, nsCaseInsensitiveStringComparator());
   124   }
   126   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
   127   static PLDHashNumber HashKey(const KeyTypePointer aKey)
   128   {
   129       nsAutoString tmKey(*aKey);
   130       ToLowerCase(tmKey);
   131       return mozilla::HashString(tmKey);
   132   }
   133   enum { ALLOW_MEMMOVE = true };
   135 private:
   136   const nsString mStr;
   137 };
   139 #endif
   141 /**
   142  * hashkey wrapper using nsACString KeyType
   143  *
   144  * @see nsTHashtable::EntryType for specification
   145  */
   146 class nsCStringHashKey : public PLDHashEntryHdr
   147 {
   148 public:
   149   typedef const nsACString& KeyType;
   150   typedef const nsACString* KeyTypePointer;
   152   nsCStringHashKey(const nsACString* aStr) : mStr(*aStr) { }
   153   nsCStringHashKey(const nsCStringHashKey& toCopy) : mStr(toCopy.mStr) { }
   154   ~nsCStringHashKey() { }
   156   KeyType GetKey() const { return mStr; }
   158   bool KeyEquals(KeyTypePointer aKey) const { return mStr.Equals(*aKey); }
   160   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
   161   static PLDHashNumber HashKey(KeyTypePointer aKey)
   162   {
   163     return mozilla::HashString(*aKey);
   164   }
   165   enum { ALLOW_MEMMOVE = true };
   167 private:
   168   const nsCString mStr;
   169 };
   171 /**
   172  * hashkey wrapper using uint32_t KeyType
   173  *
   174  * @see nsTHashtable::EntryType for specification
   175  */
   176 class nsUint32HashKey : public PLDHashEntryHdr
   177 {
   178 public:
   179   typedef const uint32_t& KeyType;
   180   typedef const uint32_t* KeyTypePointer;
   182   nsUint32HashKey(KeyTypePointer aKey) : mValue(*aKey) { }
   183   nsUint32HashKey(const nsUint32HashKey& toCopy) : mValue(toCopy.mValue) { }
   184   ~nsUint32HashKey() { }
   186   KeyType GetKey() const { return mValue; }
   187   bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
   189   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
   190   static PLDHashNumber HashKey(KeyTypePointer aKey) { return *aKey; }
   191   enum { ALLOW_MEMMOVE = true };
   193 private:
   194   const uint32_t mValue;
   195 };
   197 /**
   198  * hashkey wrapper using uint64_t KeyType
   199  *
   200  * @see nsTHashtable::EntryType for specification
   201  */
   202 class nsUint64HashKey : public PLDHashEntryHdr
   203 {
   204 public:
   205   typedef const uint64_t& KeyType;
   206   typedef const uint64_t* KeyTypePointer;
   208   nsUint64HashKey(KeyTypePointer aKey) : mValue(*aKey) { }
   209   nsUint64HashKey(const nsUint64HashKey& toCopy) : mValue(toCopy.mValue) { }
   210   ~nsUint64HashKey() { }
   212   KeyType GetKey() const { return mValue; }
   213   bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
   215   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
   216   static PLDHashNumber HashKey(KeyTypePointer aKey) { return PLDHashNumber(*aKey); }
   217   enum { ALLOW_MEMMOVE = true };
   219 private:
   220   const uint64_t mValue;
   221 };
   223 /**
   224  * hashkey wrapper using float KeyType
   225  *
   226  * @see nsTHashtable::EntryType for specification
   227  */
   228 class nsFloatHashKey : public PLDHashEntryHdr
   229 {
   230 public:
   231   typedef const float& KeyType;
   232   typedef const float* KeyTypePointer;
   234   nsFloatHashKey(KeyTypePointer aKey) : mValue(*aKey) { }
   235   nsFloatHashKey(const nsFloatHashKey& toCopy) : mValue(toCopy.mValue) { }
   236   ~nsFloatHashKey() { }
   238   KeyType GetKey() const { return mValue; }
   239   bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
   241   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
   242   static PLDHashNumber HashKey(KeyTypePointer aKey) { return *reinterpret_cast<const uint32_t*>(aKey); }
   243   enum { ALLOW_MEMMOVE = true };
   245 private:
   246   const float mValue;
   247 };
   249 /**
   250  * hashkey wrapper using nsISupports* KeyType
   251  *
   252  * @see nsTHashtable::EntryType for specification
   253  */
   254 class nsISupportsHashKey : public PLDHashEntryHdr
   255 {
   256 public:
   257   typedef nsISupports* KeyType;
   258   typedef const nsISupports* KeyTypePointer;
   260   nsISupportsHashKey(const nsISupports* key) :
   261     mSupports(const_cast<nsISupports*>(key)) { }
   262   nsISupportsHashKey(const nsISupportsHashKey& toCopy) :
   263     mSupports(toCopy.mSupports) { }
   264   ~nsISupportsHashKey() { }
   266   KeyType GetKey() const { return mSupports; }
   268   bool KeyEquals(KeyTypePointer aKey) const { return aKey == mSupports; }
   270   static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
   271   static PLDHashNumber HashKey(KeyTypePointer aKey)
   272   {
   273     return NS_PTR_TO_INT32(aKey) >>2;
   274   }
   275   enum { ALLOW_MEMMOVE = true };
   277 private:
   278   nsCOMPtr<nsISupports> mSupports;
   279 };
   281 /**
   282  * hashkey wrapper using refcounted * KeyType
   283  *
   284  * @see nsTHashtable::EntryType for specification
   285  */
   286 template<class T>
   287 class nsRefPtrHashKey : public PLDHashEntryHdr
   288 {
   289 public:
   290   typedef T* KeyType;
   291   typedef const T* KeyTypePointer;
   293   nsRefPtrHashKey(const T* key) :
   294     mKey(const_cast<T*>(key)) { }
   295   nsRefPtrHashKey(const nsRefPtrHashKey& toCopy) :
   296     mKey(toCopy.mKey) { }
   297   ~nsRefPtrHashKey() { }
   299   KeyType GetKey() const { return mKey; }
   301   bool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
   303   static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
   304   static PLDHashNumber HashKey(KeyTypePointer aKey)
   305   {
   306     return NS_PTR_TO_INT32(aKey) >>2;
   307   }
   308   enum { ALLOW_MEMMOVE = true };
   310 private:
   311   nsRefPtr<T> mKey;
   312 };
   314 template <class T>
   315 inline void
   316 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
   317                             nsRefPtrHashKey<T>& aField,
   318                             const char* aName,
   319                             uint32_t aFlags = 0)
   320 {
   321   CycleCollectionNoteChild(aCallback, aField.GetKey(), aName, aFlags);
   322 }
   324 /**
   325  * hashkey wrapper using T* KeyType
   326  *
   327  * @see nsTHashtable::EntryType for specification
   328  */
   329 template<class T>
   330 class nsPtrHashKey : public PLDHashEntryHdr
   331 {
   332  public:
   333   typedef T *KeyType;
   334   typedef const T *KeyTypePointer;
   336   nsPtrHashKey(const T *key) : mKey(const_cast<T*>(key)) {}
   337   nsPtrHashKey(const nsPtrHashKey<T> &toCopy) : mKey(toCopy.mKey) {}
   338   ~nsPtrHashKey() {}
   340   KeyType GetKey() const { return mKey; }
   342   bool KeyEquals(KeyTypePointer key) const { return key == mKey; }
   344   static KeyTypePointer KeyToPointer(KeyType key) { return key; }
   345   static PLDHashNumber HashKey(KeyTypePointer key)
   346   {
   347     return NS_PTR_TO_INT32(key) >> 2;
   348   }
   349   enum { ALLOW_MEMMOVE = true };
   351  protected:
   352   T *mKey;
   353 };
   355 /**
   356  * hashkey wrapper using T* KeyType that sets key to nullptr upon
   357  * destruction. Relevant only in cases where a memory pointer-scanner
   358  * like valgrind might get confused about stale references.
   359  *
   360  * @see nsTHashtable::EntryType for specification
   361  */
   363 template<class T>
   364 class nsClearingPtrHashKey : public nsPtrHashKey<T>
   365 {
   366  public:
   367   nsClearingPtrHashKey(const T *key) : nsPtrHashKey<T>(key) {}
   368   nsClearingPtrHashKey(const nsClearingPtrHashKey<T> &toCopy) :
   369     nsPtrHashKey<T>(toCopy) {}
   370   ~nsClearingPtrHashKey() { nsPtrHashKey<T>::mKey = nullptr; }
   371 };
   373 typedef nsPtrHashKey<const void> nsVoidPtrHashKey; 
   374 typedef nsClearingPtrHashKey<const void> nsClearingVoidPtrHashKey;
   376 /**
   377  * hashkey wrapper using a function pointer KeyType
   378  *
   379  * @see nsTHashtable::EntryType for specification
   380  */
   381 template<class T>
   382 class nsFuncPtrHashKey : public PLDHashEntryHdr
   383 {
   384  public:
   385   typedef T &KeyType;
   386   typedef const T *KeyTypePointer;
   388   nsFuncPtrHashKey(const T *key) : mKey(*const_cast<T*>(key)) {}
   389   nsFuncPtrHashKey(const nsFuncPtrHashKey<T> &toCopy) : mKey(toCopy.mKey) {}
   390   ~nsFuncPtrHashKey() {}
   392   KeyType GetKey() const { return const_cast<T&>(mKey); }
   394   bool KeyEquals(KeyTypePointer key) const { return *key == mKey; }
   396   static KeyTypePointer KeyToPointer(KeyType key) { return &key; }
   397   static PLDHashNumber HashKey(KeyTypePointer key)
   398   {
   399     return NS_PTR_TO_INT32(*key) >> 2;
   400   }
   401   enum { ALLOW_MEMMOVE = true };
   403  protected:
   404   T mKey;
   405 };
   407 /**
   408  * hashkey wrapper using nsID KeyType
   409  *
   410  * @see nsTHashtable::EntryType for specification
   411  */
   412 class nsIDHashKey : public PLDHashEntryHdr
   413 {
   414 public:
   415   typedef const nsID& KeyType;
   416   typedef const nsID* KeyTypePointer;
   418   nsIDHashKey(const nsID* inID) : mID(*inID) { }
   419   nsIDHashKey(const nsIDHashKey& toCopy) : mID(toCopy.mID) { }
   420   ~nsIDHashKey() { }
   422   KeyType GetKey() const { return mID; }
   424   bool KeyEquals(KeyTypePointer aKey) const { return aKey->Equals(mID); }
   426   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
   427   static PLDHashNumber HashKey(KeyTypePointer aKey)
   428   {
   429     // Hash the nsID object's raw bytes.
   430     return mozilla::HashBytes(aKey, sizeof(KeyType));
   431   }
   433   enum { ALLOW_MEMMOVE = true };
   435 private:
   436   const nsID mID;
   437 };
   439 /**
   440  * hashkey wrapper for "dependent" const char*; this class does not "own"
   441  * its string pointer.
   442  *
   443  * This class must only be used if the strings have a lifetime longer than
   444  * the hashtable they occupy. This normally occurs only for static
   445  * strings or strings that have been arena-allocated.
   446  *
   447  * @see nsTHashtable::EntryType for specification
   448  */
   449 class nsDepCharHashKey : public PLDHashEntryHdr
   450 {
   451 public:
   452   typedef const char* KeyType;
   453   typedef const char* KeyTypePointer;
   455   nsDepCharHashKey(const char* aKey) { mKey = aKey; }
   456   nsDepCharHashKey(const nsDepCharHashKey& toCopy) { mKey = toCopy.mKey; }
   457   ~nsDepCharHashKey() { }
   459   const char* GetKey() const { return mKey; }
   460   bool KeyEquals(const char* aKey) const
   461   {
   462     return !strcmp(mKey, aKey);
   463   }
   465   static const char* KeyToPointer(const char* aKey) { return aKey; }
   466   static PLDHashNumber HashKey(const char* aKey) { return mozilla::HashString(aKey); }
   467   enum { ALLOW_MEMMOVE = true };
   469 private:
   470   const char* mKey;
   471 };
   473 /**
   474  * hashkey wrapper for const char*; at construction, this class duplicates
   475  * a string pointed to by the pointer so that it doesn't matter whether or not
   476  * the string lives longer than the hash table.
   477  */
   478 class nsCharPtrHashKey : public PLDHashEntryHdr
   479 {
   480 public:
   481   typedef const char* KeyType;
   482   typedef const char* KeyTypePointer;
   484   nsCharPtrHashKey(const char* aKey) : mKey(strdup(aKey)) { }
   485   nsCharPtrHashKey(const nsCharPtrHashKey& toCopy) : mKey(strdup(toCopy.mKey)) { }
   487   nsCharPtrHashKey(nsCharPtrHashKey&& other)
   488     : mKey(other.mKey)
   489   {
   490     other.mKey = nullptr;
   491   }
   493   ~nsCharPtrHashKey() { if (mKey) free(const_cast<char *>(mKey)); }
   495   const char* GetKey() const { return mKey; }
   496   bool KeyEquals(KeyTypePointer aKey) const
   497   {
   498     return !strcmp(mKey, aKey);
   499   }
   501   static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
   502   static PLDHashNumber HashKey(KeyTypePointer aKey) { return mozilla::HashString(aKey); }
   504   enum { ALLOW_MEMMOVE = true };
   506 private:
   507   const char* mKey;
   508 };
   510 /**
   511  * hashkey wrapper for const char16_t*; at construction, this class duplicates
   512  * a string pointed to by the pointer so that it doesn't matter whether or not
   513  * the string lives longer than the hash table.
   514  */
   515 class nsUnicharPtrHashKey : public PLDHashEntryHdr
   516 {
   517 public:
   518   typedef const char16_t* KeyType;
   519   typedef const char16_t* KeyTypePointer;
   521   nsUnicharPtrHashKey(const char16_t* aKey) : mKey(NS_strdup(aKey)) { }
   522   nsUnicharPtrHashKey(const nsUnicharPtrHashKey& toCopy) : mKey(NS_strdup(toCopy.mKey)) { }
   524   nsUnicharPtrHashKey(nsUnicharPtrHashKey&& other)
   525     : mKey(other.mKey)
   526   {
   527     other.mKey = nullptr;
   528   }
   530   ~nsUnicharPtrHashKey() { if (mKey) NS_Free(const_cast<char16_t *>(mKey)); }
   532   const char16_t* GetKey() const { return mKey; }
   533   bool KeyEquals(KeyTypePointer aKey) const
   534   {
   535     return !NS_strcmp(mKey, aKey);
   536   }
   538   static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
   539   static PLDHashNumber HashKey(KeyTypePointer aKey) { return mozilla::HashString(aKey); }
   541   enum { ALLOW_MEMMOVE = true };
   543 private:
   544   const char16_t* mKey;
   545 };
   547 /**
   548  * Hashtable key class to use with objects that support nsIHashable
   549  */
   550 class nsHashableHashKey : public PLDHashEntryHdr
   551 {
   552 public:
   553     typedef nsIHashable* KeyType;
   554     typedef const nsIHashable* KeyTypePointer;
   556     nsHashableHashKey(const nsIHashable* aKey) :
   557         mKey(const_cast<nsIHashable*>(aKey)) { }
   558     nsHashableHashKey(const nsHashableHashKey& toCopy) :
   559         mKey(toCopy.mKey) { }
   560     ~nsHashableHashKey() { }
   562     nsIHashable* GetKey() const { return mKey; }
   564     bool KeyEquals(const nsIHashable* aKey) const {
   565         bool eq;
   566         if (NS_SUCCEEDED(mKey->Equals(const_cast<nsIHashable*>(aKey), &eq))) {
   567             return eq;
   568         }
   569         return false;
   570     }
   572     static const nsIHashable* KeyToPointer(nsIHashable* aKey) { return aKey; }
   573     static PLDHashNumber HashKey(const nsIHashable* aKey) {
   574         uint32_t code = 8888; // magic number if GetHashCode fails :-(
   575 #ifdef DEBUG
   576         nsresult rv =
   577 #endif
   578         const_cast<nsIHashable*>(aKey)->GetHashCode(&code);
   579         NS_ASSERTION(NS_SUCCEEDED(rv), "GetHashCode should not throw!");
   580         return code;
   581     }
   583     enum { ALLOW_MEMMOVE = true };
   585 private:
   586     nsCOMPtr<nsIHashable> mKey;
   587 };
   589 /**
   590  * Hashtable key class to use with objects for which Hash() and operator==()
   591  * are defined.
   592  */
   593 template <typename T>
   594 class nsGenericHashKey : public PLDHashEntryHdr
   595 {
   596 public:
   597   typedef const T& KeyType;
   598   typedef const T* KeyTypePointer;
   600   nsGenericHashKey(KeyTypePointer aKey) : mKey(*aKey) { }
   601   nsGenericHashKey(const nsGenericHashKey<T>& aOther) : mKey(aOther.mKey) { }
   603   KeyType GetKey() const { return mKey; }
   604   bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mKey; }
   606   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
   607   static PLDHashNumber HashKey(KeyTypePointer aKey) { return aKey->Hash(); }
   608   enum { ALLOW_MEMMOVE = true };
   610 private:
   611   T mKey;
   612 };
   614 #endif // nsTHashKeys_h__

mercurial