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 nsClassHashtable_h__
39 : #define nsClassHashtable_h__
40 :
41 : #include "nsBaseHashtable.h"
42 : #include "nsHashKeys.h"
43 : #include "nsAutoPtr.h"
44 :
45 : /**
46 : * templated hashtable class maps keys to C++ object pointers.
47 : * See nsBaseHashtable for complete declaration.
48 : * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
49 : * for a complete specification.
50 : * @param Class the class-type being wrapped
51 : * @see nsInterfaceHashtable, nsClassHashtable
52 : */
53 : template<class KeyClass,class T>
54 : class nsClassHashtable :
55 : public nsBaseHashtable< KeyClass, nsAutoPtr<T>, T* >
56 42349 : {
57 : public:
58 : typedef typename KeyClass::KeyType KeyType;
59 : typedef T* UserDataType;
60 : typedef nsBaseHashtable< KeyClass, nsAutoPtr<T>, T* > base_type;
61 :
62 : /**
63 : * @copydoc nsBaseHashtable::Get
64 : * @param pData if the key doesn't exist, pData will be set to nsnull.
65 : */
66 : bool Get(KeyType aKey, UserDataType* pData) const;
67 :
68 : /**
69 : * @copydoc nsBaseHashtable::Get
70 : * @returns NULL if the key is not present.
71 : */
72 : UserDataType Get(KeyType aKey) const;
73 :
74 : /**
75 : * Remove the entry for the given key from the hashtable and return it in
76 : * aOut. If the key is not in the hashtable, aOut's pointer is set to NULL.
77 : *
78 : * Normally, an entry is deleted when it's removed from an nsClassHashtable,
79 : * but this function transfers ownership of the entry back to the caller
80 : * through aOut -- the entry will be deleted when aOut goes out of scope.
81 : *
82 : * @param aKey the key to get and remove from the hashtable
83 : */
84 : void RemoveAndForget(KeyType aKey, nsAutoPtr<T> &aOut);
85 : };
86 :
87 :
88 : /**
89 : * Thread-safe version of nsClassHashtable
90 : * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
91 : * for a complete specification.
92 : * @param Class the class-type being wrapped
93 : * @see nsInterfaceHashtable, nsClassHashtable
94 : */
95 : template<class KeyClass,class T>
96 : class nsClassHashtableMT :
97 : public nsBaseHashtableMT< KeyClass, nsAutoPtr<T>, T* >
98 2 : {
99 : public:
100 : typedef typename KeyClass::KeyType KeyType;
101 : typedef T* UserDataType;
102 : typedef nsBaseHashtableMT< KeyClass, nsAutoPtr<T>, T* > base_type;
103 :
104 : /**
105 : * @copydoc nsBaseHashtable::Get
106 : * @param pData if the key doesn't exist, pData will be set to nsnull.
107 : */
108 : bool Get(KeyType aKey, UserDataType* pData) const;
109 : };
110 :
111 :
112 : //
113 : // nsClassHashtable definitions
114 : //
115 :
116 : template<class KeyClass,class T>
117 : bool
118 517557 : nsClassHashtable<KeyClass,T>::Get(KeyType aKey, T** retVal) const
119 : {
120 517557 : typename base_type::EntryType* ent = this->GetEntry(aKey);
121 :
122 517557 : if (ent)
123 : {
124 432136 : if (retVal)
125 432136 : *retVal = ent->mData;
126 :
127 432136 : return true;
128 : }
129 :
130 85421 : if (retVal)
131 85347 : *retVal = nsnull;
132 :
133 85421 : return false;
134 : }
135 :
136 : template<class KeyClass,class T>
137 : T*
138 278971 : nsClassHashtable<KeyClass,T>::Get(KeyType aKey) const
139 : {
140 278971 : typename base_type::EntryType* ent = this->GetEntry(aKey);
141 :
142 278971 : if (!ent)
143 233115 : return NULL;
144 :
145 45856 : return ent->mData;
146 : }
147 :
148 : template<class KeyClass,class T>
149 : void
150 65736 : nsClassHashtable<KeyClass,T>::RemoveAndForget(KeyType aKey, nsAutoPtr<T> &aOut)
151 : {
152 65736 : aOut = nsnull;
153 131472 : nsAutoPtr<T> ptr;
154 :
155 65736 : typename base_type::EntryType *ent = this->GetEntry(aKey);
156 65736 : if (!ent)
157 : return;
158 :
159 : // Transfer ownership from ent->mData into aOut.
160 12661 : aOut = ent->mData;
161 :
162 12661 : this->Remove(aKey);
163 : }
164 :
165 :
166 : //
167 : // nsClassHashtableMT definitions
168 : //
169 :
170 : template<class KeyClass,class T>
171 : bool
172 17 : nsClassHashtableMT<KeyClass,T>::Get(KeyType aKey, T** retVal) const
173 : {
174 17 : PR_Lock(this->mLock);
175 :
176 17 : typename base_type::EntryType* ent = this->GetEntry(aKey);
177 :
178 17 : if (ent)
179 : {
180 16 : if (retVal)
181 16 : *retVal = ent->mData;
182 :
183 16 : PR_Unlock(this->mLock);
184 :
185 16 : return true;
186 : }
187 :
188 1 : if (retVal)
189 1 : *retVal = nsnull;
190 :
191 1 : PR_Unlock(this->mLock);
192 :
193 1 : return false;
194 : }
195 :
196 : #endif // nsClassHashtable_h__
|