/gecko_api/include/nsRefPtrHashtable.h

http://firefox-mac-pdf.googlecode.com/ · C Header · 197 lines · 85 code · 31 blank · 81 comment · 9 complexity · fccafcd76b4d7fbb1940ad20cf84e0e9 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. * Neil Rashbrook <neil@parkwaycc.co.uk>
  24. *
  25. * Alternatively, the contents of this file may be used under the terms of
  26. * either the GNU General Public License Version 2 or later (the "GPL"), or
  27. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28. * in which case the provisions of the GPL or the LGPL are applicable instead
  29. * of those above. If you wish to allow use of your version of this file only
  30. * under the terms of either the GPL or the LGPL, and not to allow others to
  31. * use your version of this file under the terms of the MPL, indicate your
  32. * decision by deleting the provisions above and replace them with the notice
  33. * and other provisions required by the GPL or the LGPL. If you do not delete
  34. * the provisions above, a recipient may use your version of this file under
  35. * the terms of any one of the MPL, the GPL or the LGPL.
  36. *
  37. * ***** END LICENSE BLOCK ***** */
  38. #ifndef nsRefPtrHashtable_h__
  39. #define nsRefPtrHashtable_h__
  40. #include "nsBaseHashtable.h"
  41. #include "nsHashKeys.h"
  42. #include "nsAutoPtr.h"
  43. /**
  44. * templated hashtable class maps keys to reference pointers.
  45. * See nsBaseHashtable for complete declaration.
  46. * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
  47. * for a complete specification.
  48. * @param RefPtr the reference-type being wrapped
  49. * @see nsDataHashtable, nsClassHashtable
  50. */
  51. template<class KeyClass, class RefPtr>
  52. class nsRefPtrHashtable :
  53. public nsBaseHashtable< KeyClass, nsRefPtr<RefPtr> , RefPtr* >
  54. {
  55. public:
  56. typedef typename KeyClass::KeyType KeyType;
  57. typedef RefPtr* UserDataType;
  58. /**
  59. * @copydoc nsBaseHashtable::Get
  60. * @param pData This is an XPCOM getter, so pData is already_addrefed.
  61. * If the key doesn't exist, pData will be set to nsnull.
  62. */
  63. PRBool Get(KeyType aKey, UserDataType* pData) const;
  64. /**
  65. * Gets a weak reference to the hashtable entry.
  66. * @param aFound If not nsnull, will be set to PR_TRUE if the entry is found,
  67. * to PR_FALSE otherwise.
  68. * @return The entry, or nsnull if not found. Do not release this pointer!
  69. */
  70. RefPtr* GetWeak(KeyType aKey, PRBool* aFound = nsnull) const;
  71. };
  72. /**
  73. * Thread-safe version of nsRefPtrHashtable
  74. * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
  75. * for a complete specification.
  76. * @param RefPtr the reference-type being wrapped
  77. */
  78. template<class KeyClass, class RefPtr>
  79. class nsRefPtrHashtableMT :
  80. public nsBaseHashtableMT< KeyClass, nsRefPtr<RefPtr> , RefPtr* >
  81. {
  82. public:
  83. typedef typename KeyClass::KeyType KeyType;
  84. typedef RefPtr* UserDataType;
  85. /**
  86. * @copydoc nsBaseHashtable::Get
  87. * @param pData This is an XPCOM getter, so pData is already_addrefed.
  88. * If the key doesn't exist, pData will be set to nsnull.
  89. */
  90. PRBool Get(KeyType aKey, UserDataType* pData) const;
  91. // GetWeak does not make sense on a multi-threaded hashtable, where another
  92. // thread may remove the entry (and hence release it) as soon as GetWeak
  93. // returns
  94. };
  95. //
  96. // nsRefPtrHashtable definitions
  97. //
  98. template<class KeyClass, class RefPtr>
  99. PRBool
  100. nsRefPtrHashtable<KeyClass,RefPtr>::Get
  101. (KeyType aKey, UserDataType* pRefPtr) const
  102. {
  103. typename nsBaseHashtable<KeyClass, nsRefPtr<RefPtr>, RefPtr*>::EntryType* ent =
  104. GetEntry(aKey);
  105. if (ent)
  106. {
  107. if (pRefPtr)
  108. {
  109. *pRefPtr = ent->mData;
  110. NS_IF_ADDREF(*pRefPtr);
  111. }
  112. return PR_TRUE;
  113. }
  114. // if the key doesn't exist, set *pRefPtr to null
  115. // so that it is a valid XPCOM getter
  116. if (pRefPtr)
  117. *pRefPtr = nsnull;
  118. return PR_FALSE;
  119. }
  120. template<class KeyClass, class RefPtr>
  121. RefPtr*
  122. nsRefPtrHashtable<KeyClass,RefPtr>::GetWeak
  123. (KeyType aKey, PRBool* aFound) const
  124. {
  125. typename nsBaseHashtable<KeyClass, nsRefPtr<RefPtr>, RefPtr*>::EntryType* ent =
  126. GetEntry(aKey);
  127. if (ent)
  128. {
  129. if (aFound)
  130. *aFound = PR_TRUE;
  131. return ent->mData;
  132. }
  133. // Key does not exist, return nsnull and set aFound to PR_FALSE
  134. if (aFound)
  135. *aFound = PR_FALSE;
  136. return nsnull;
  137. }
  138. //
  139. // nsRefPtrHashtableMT definitions
  140. //
  141. template<class KeyClass, class RefPtr>
  142. PRBool
  143. nsRefPtrHashtableMT<KeyClass,RefPtr>::Get
  144. (KeyType aKey, UserDataType* pRefPtr) const
  145. {
  146. PR_Lock(this->mLock);
  147. typename nsBaseHashtableMT<KeyClass, nsRefPtr<RefPtr>, RefPtr*>::EntryType* ent =
  148. GetEntry(aKey);
  149. if (ent)
  150. {
  151. if (pRefPtr)
  152. {
  153. *pRefPtr = ent->mData;
  154. NS_IF_ADDREF(*pRefPtr);
  155. }
  156. PR_Unlock(this->mLock);
  157. return PR_TRUE;
  158. }
  159. // if the key doesn't exist, set *pRefPtr to null
  160. // so that it is a valid XPCOM getter
  161. if (pRefPtr)
  162. *pRefPtr = nsnull;
  163. PR_Unlock(this->mLock);
  164. return PR_FALSE;
  165. }
  166. #endif // nsRefPtrHashtable_h__