PageRenderTime 224ms CodeModel.GetById 211ms RepoModel.GetById 0ms app.codeStats 0ms

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