Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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 nsBaseHashtable_h__
7 #define nsBaseHashtable_h__
9 #include "mozilla/MemoryReporting.h"
10 #include "mozilla/Move.h"
11 #include "nsTHashtable.h"
12 #include "prlock.h"
13 #include "nsDebug.h"
15 template<class KeyClass,class DataType,class UserDataType>
16 class nsBaseHashtable; // forward declaration
18 /**
19 * the private nsTHashtable::EntryType class used by nsBaseHashtable
20 * @see nsTHashtable for the specification of this class
21 * @see nsBaseHashtable for template parameters
22 */
23 template<class KeyClass,class DataType>
24 class nsBaseHashtableET : public KeyClass
25 {
26 public:
27 DataType mData;
28 friend class nsTHashtable< nsBaseHashtableET<KeyClass,DataType> >;
30 private:
31 typedef typename KeyClass::KeyType KeyType;
32 typedef typename KeyClass::KeyTypePointer KeyTypePointer;
34 nsBaseHashtableET(KeyTypePointer aKey);
35 nsBaseHashtableET(nsBaseHashtableET<KeyClass,DataType>&& toMove);
36 ~nsBaseHashtableET();
37 };
39 /**
40 * templated hashtable for simple data types
41 * This class manages simple data types that do not need construction or
42 * destruction.
43 *
44 * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
45 * for a complete specification.
46 * @param DataType the datatype stored in the hashtable,
47 * for example, uint32_t or nsCOMPtr. If UserDataType is not the same,
48 * DataType must implicitly cast to UserDataType
49 * @param UserDataType the user sees, for example uint32_t or nsISupports*
50 */
51 template<class KeyClass,class DataType,class UserDataType>
52 class nsBaseHashtable :
53 protected nsTHashtable< nsBaseHashtableET<KeyClass,DataType> >
54 {
55 typedef mozilla::fallible_t fallible_t;
57 public:
58 typedef typename KeyClass::KeyType KeyType;
59 typedef nsBaseHashtableET<KeyClass,DataType> EntryType;
61 using nsTHashtable<EntryType>::Contains;
63 nsBaseHashtable()
64 {
65 }
66 explicit nsBaseHashtable(uint32_t aInitSize)
67 : nsTHashtable<EntryType>(aInitSize)
68 {
69 }
71 /**
72 * Return the number of entries in the table.
73 * @return number of entries
74 */
75 uint32_t Count() const
76 { return nsTHashtable<EntryType>::Count(); }
78 /**
79 * retrieve the value for a key.
80 * @param aKey the key to retreive
81 * @param pData data associated with this key will be placed at this
82 * pointer. If you only need to check if the key exists, pData
83 * may be null.
84 * @return true if the key exists. If key does not exist, pData is not
85 * modified.
86 */
87 bool Get(KeyType aKey, UserDataType* pData) const
88 {
89 EntryType* ent = this->GetEntry(aKey);
91 if (!ent)
92 return false;
94 if (pData)
95 *pData = ent->mData;
97 return true;
98 }
100 /**
101 * For pointer types, get the value, returning nullptr if the entry is not
102 * present in the table.
103 *
104 * @param aKey the key to retrieve
105 * @return The found value, or nullptr if no entry was found with the given key.
106 * @note If nullptr values are stored in the table, it is not possible to
107 * distinguish between a nullptr value and a missing entry.
108 */
109 UserDataType Get(KeyType aKey) const
110 {
111 EntryType* ent = this->GetEntry(aKey);
112 if (!ent)
113 return 0;
115 return ent->mData;
116 }
118 /**
119 * put a new value for the associated key
120 * @param aKey the key to put
121 * @param aData the new data
122 * @return always true, unless memory allocation failed
123 */
124 void Put(KeyType aKey, const UserDataType& aData)
125 {
126 if (!Put(aKey, aData, fallible_t()))
127 NS_ABORT_OOM(this->mTable.entrySize * this->mTable.entryCount);
128 }
130 bool Put(KeyType aKey, const UserDataType& aData, const fallible_t&) NS_WARN_UNUSED_RESULT
131 {
132 EntryType* ent = this->PutEntry(aKey);
134 if (!ent)
135 return false;
137 ent->mData = aData;
139 return true;
140 }
142 /**
143 * remove the data for the associated key
144 * @param aKey the key to remove from the hashtable
145 */
146 void Remove(KeyType aKey) { this->RemoveEntry(aKey); }
148 /**
149 * function type provided by the application for enumeration.
150 * @param aKey the key being enumerated
151 * @param aData data being enumerated
152 * @parm userArg passed unchanged from Enumerate
153 * @return either
154 * @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink or
155 * @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink
156 */
157 typedef PLDHashOperator
158 (* EnumReadFunction)(KeyType aKey,
159 UserDataType aData,
160 void* userArg);
162 /**
163 * enumerate entries in the hashtable, without allowing changes
164 * @param enumFunc enumeration callback
165 * @param userArg passed unchanged to the EnumReadFunction
166 */
167 uint32_t EnumerateRead(EnumReadFunction enumFunc, void* userArg) const
168 {
169 NS_ASSERTION(this->mTable.entrySize,
170 "nsBaseHashtable was not initialized properly.");
172 s_EnumReadArgs enumData = { enumFunc, userArg };
173 return PL_DHashTableEnumerate(const_cast<PLDHashTable*>(&this->mTable),
174 s_EnumReadStub,
175 &enumData);
176 }
178 /**
179 * function type provided by the application for enumeration.
180 * @param aKey the key being enumerated
181 * @param aData Reference to data being enumerated, may be altered. e.g. for
182 * nsInterfaceHashtable this is an nsCOMPtr reference...
183 * @parm userArg passed unchanged from Enumerate
184 * @return bitflag combination of
185 * @link PLDHashOperator::PL_DHASH_REMOVE @endlink,
186 * @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink, or
187 * @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink
188 */
189 typedef PLDHashOperator
190 (* EnumFunction)(KeyType aKey,
191 DataType& aData,
192 void* userArg);
194 /**
195 * enumerate entries in the hashtable, allowing changes. This
196 * functions write-locks the hashtable.
197 * @param enumFunc enumeration callback
198 * @param userArg passed unchanged to the EnumFunction
199 */
200 uint32_t Enumerate(EnumFunction enumFunc, void* userArg)
201 {
202 NS_ASSERTION(this->mTable.entrySize,
203 "nsBaseHashtable was not initialized properly.");
205 s_EnumArgs enumData = { enumFunc, userArg };
206 return PL_DHashTableEnumerate(&this->mTable,
207 s_EnumStub,
208 &enumData);
209 }
211 /**
212 * reset the hashtable, removing all entries
213 */
214 void Clear() { nsTHashtable<EntryType>::Clear(); }
216 /**
217 * client must provide a SizeOfEntryExcludingThisFun function for
218 * SizeOfExcludingThis.
219 * @param aKey the key being enumerated
220 * @param aData Reference to data being enumerated.
221 * @param mallocSizeOf the function used to measure heap-allocated blocks
222 * @param userArg passed unchanged from SizeOf{In,Ex}cludingThis
223 * @return summed size of the things pointed to by the entries
224 */
225 typedef size_t
226 (* SizeOfEntryExcludingThisFun)(KeyType aKey,
227 const DataType &aData,
228 mozilla::MallocSizeOf mallocSizeOf,
229 void* userArg);
231 /**
232 * Measure the size of the table's entry storage and the table itself.
233 * If |sizeOfEntryExcludingThis| is non-nullptr, measure the size of things
234 * pointed to by entries.
235 *
236 * @param sizeOfEntryExcludingThis
237 * the <code>SizeOfEntryExcludingThisFun</code> function to call
238 * @param mallocSizeOf the function used to meeasure heap-allocated blocks
239 * @param userArg a point to pass to the
240 * <code>SizeOfEntryExcludingThisFun</code> function
241 * @return the summed size of the entries, the table, and the table's storage
242 */
243 size_t SizeOfIncludingThis(SizeOfEntryExcludingThisFun sizeOfEntryExcludingThis,
244 mozilla::MallocSizeOf mallocSizeOf, void *userArg = nullptr)
245 {
246 return mallocSizeOf(this) + this->SizeOfExcludingThis(sizeOfEntryExcludingThis,
247 mallocSizeOf, userArg);
248 }
250 /**
251 * Measure the size of the table's entry storage, and if
252 * |sizeOfEntryExcludingThis| is non-nullptr, measure the size of things pointed
253 * to by entries.
254 *
255 * @param sizeOfEntryExcludingThis the
256 * <code>SizeOfEntryExcludingThisFun</code> function to call
257 * @param mallocSizeOf the function used to measure heap-allocated blocks
258 * @param userArg a pointer to pass to the
259 * <code>SizeOfEntryExcludingThisFun</code> function
260 * @return the summed size of all the entries
261 */
262 size_t SizeOfExcludingThis(SizeOfEntryExcludingThisFun sizeOfEntryExcludingThis,
263 mozilla::MallocSizeOf mallocSizeOf, void *userArg = nullptr) const
264 {
265 if (sizeOfEntryExcludingThis) {
266 s_SizeOfArgs args = { sizeOfEntryExcludingThis, userArg };
267 return PL_DHashTableSizeOfExcludingThis(&this->mTable, s_SizeOfStub,
268 mallocSizeOf, &args);
269 }
270 return PL_DHashTableSizeOfExcludingThis(&this->mTable, nullptr,
271 mallocSizeOf);
272 }
274 #ifdef DEBUG
275 using nsTHashtable<EntryType>::MarkImmutable;
276 #endif
278 protected:
279 /**
280 * used internally during EnumerateRead. Allocated on the stack.
281 * @param func the enumerator passed to EnumerateRead
282 * @param userArg the userArg passed to EnumerateRead
283 */
284 struct s_EnumReadArgs
285 {
286 EnumReadFunction func;
287 void* userArg;
288 };
290 static PLDHashOperator s_EnumReadStub(PLDHashTable *table,
291 PLDHashEntryHdr *hdr,
292 uint32_t number,
293 void *arg);
295 struct s_EnumArgs
296 {
297 EnumFunction func;
298 void* userArg;
299 };
301 static PLDHashOperator s_EnumStub(PLDHashTable *table,
302 PLDHashEntryHdr *hdr,
303 uint32_t number,
304 void *arg);
306 struct s_SizeOfArgs
307 {
308 SizeOfEntryExcludingThisFun func;
309 void* userArg;
310 };
312 static size_t s_SizeOfStub(PLDHashEntryHdr *entry,
313 mozilla::MallocSizeOf mallocSizeOf,
314 void *arg);
315 };
317 class nsCycleCollectionTraversalCallback;
319 struct MOZ_STACK_CLASS nsBaseHashtableCCTraversalData
320 {
321 nsBaseHashtableCCTraversalData(nsCycleCollectionTraversalCallback& aCallback,
322 const char* aName,
323 uint32_t aFlags)
324 : mCallback(aCallback),
325 mName(aName),
326 mFlags(aFlags)
327 {
328 }
330 nsCycleCollectionTraversalCallback& mCallback;
331 const char* mName;
332 uint32_t mFlags;
334 };
336 template <typename K, typename T>
337 PLDHashOperator
338 ImplCycleCollectionTraverse_EnumFunc(K aKey,
339 T aData,
340 void* aUserData)
341 {
342 nsBaseHashtableCCTraversalData* userData =
343 static_cast<nsBaseHashtableCCTraversalData*>(aUserData);
345 CycleCollectionNoteChild(userData->mCallback,
346 aData,
347 userData->mName,
348 userData->mFlags);
349 return PL_DHASH_NEXT;
350 }
352 //
353 // nsBaseHashtableET definitions
354 //
356 template<class KeyClass,class DataType>
357 nsBaseHashtableET<KeyClass,DataType>::nsBaseHashtableET(KeyTypePointer aKey) :
358 KeyClass(aKey)
359 { }
361 template<class KeyClass,class DataType>
362 nsBaseHashtableET<KeyClass,DataType>::nsBaseHashtableET
363 (nsBaseHashtableET<KeyClass,DataType>&& toMove) :
364 KeyClass(mozilla::Move(toMove)),
365 mData(mozilla::Move(toMove.mData))
366 { }
368 template<class KeyClass,class DataType>
369 nsBaseHashtableET<KeyClass,DataType>::~nsBaseHashtableET()
370 { }
373 //
374 // nsBaseHashtable definitions
375 //
377 template<class KeyClass,class DataType,class UserDataType>
378 PLDHashOperator
379 nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumReadStub
380 (PLDHashTable *table, PLDHashEntryHdr *hdr, uint32_t number, void* arg)
381 {
382 EntryType* ent = static_cast<EntryType*>(hdr);
383 s_EnumReadArgs* eargs = (s_EnumReadArgs*) arg;
385 PLDHashOperator res = (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg);
387 NS_ASSERTION( !(res & PL_DHASH_REMOVE ),
388 "PL_DHASH_REMOVE return during const enumeration; ignoring.");
390 if (res & PL_DHASH_STOP)
391 return PL_DHASH_STOP;
393 return PL_DHASH_NEXT;
394 }
396 template<class KeyClass,class DataType,class UserDataType>
397 PLDHashOperator
398 nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumStub
399 (PLDHashTable *table, PLDHashEntryHdr *hdr, uint32_t number, void* arg)
400 {
401 EntryType* ent = static_cast<EntryType*>(hdr);
402 s_EnumArgs* eargs = (s_EnumArgs*) arg;
404 return (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg);
405 }
407 template<class KeyClass,class DataType,class UserDataType>
408 size_t
409 nsBaseHashtable<KeyClass,DataType,UserDataType>::s_SizeOfStub
410 (PLDHashEntryHdr *hdr, mozilla::MallocSizeOf mallocSizeOf, void *arg)
411 {
412 EntryType* ent = static_cast<EntryType*>(hdr);
413 s_SizeOfArgs* eargs = static_cast<s_SizeOfArgs*>(arg);
415 return (eargs->func)(ent->GetKey(), ent->mData, mallocSizeOf, eargs->userArg);
416 }
418 #endif // nsBaseHashtable_h__