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: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 nsCOMArray_h__
7 #define nsCOMArray_h__
9 #include "mozilla/Attributes.h"
10 #include "mozilla/MemoryReporting.h"
12 #include "nsCycleCollectionNoteChild.h"
13 #include "nsTArray.h"
14 #include "nsISupports.h"
16 // See below for the definition of nsCOMArray<T>
18 // a class that's nsISupports-specific, so that we can contain the
19 // work of this class in the XPCOM dll
20 class NS_COM_GLUE nsCOMArray_base
21 {
22 friend class nsArray;
23 protected:
24 nsCOMArray_base() {}
25 nsCOMArray_base(int32_t aCount) : mArray(aCount) {}
26 nsCOMArray_base(const nsCOMArray_base& other);
27 ~nsCOMArray_base();
29 int32_t IndexOf(nsISupports* aObject, uint32_t aStartIndex = 0) const;
30 bool Contains(nsISupports* aObject) const {
31 return IndexOf(aObject) != -1;
32 }
34 int32_t IndexOfObject(nsISupports* aObject) const;
35 bool ContainsObject(nsISupports* aObject) const {
36 return IndexOfObject(aObject) != -1;
37 }
39 typedef bool (* nsBaseArrayEnumFunc)
40 (void* aElement, void *aData);
42 // enumerate through the array with a callback.
43 bool EnumerateForwards(nsBaseArrayEnumFunc aFunc, void* aData) const;
45 bool EnumerateBackwards(nsBaseArrayEnumFunc aFunc, void* aData) const;
47 typedef int (* nsBaseArrayComparatorFunc)
48 (nsISupports* aElement1, nsISupports* aElement2, void* aData);
50 struct nsCOMArrayComparatorContext {
51 nsBaseArrayComparatorFunc mComparatorFunc;
52 void* mData;
53 };
55 static int nsCOMArrayComparator(const void* aElement1, const void* aElement2, void* aData);
56 void Sort(nsBaseArrayComparatorFunc aFunc, void* aData);
58 bool InsertObjectAt(nsISupports* aObject, int32_t aIndex);
59 void InsertElementAt(uint32_t aIndex, nsISupports* aElement);
60 bool InsertObjectsAt(const nsCOMArray_base& aObjects, int32_t aIndex);
61 void InsertElementsAt(uint32_t aIndex, const nsCOMArray_base& aElements);
62 void InsertElementsAt(uint32_t aIndex, nsISupports* const* aElements, uint32_t aCount);
63 bool ReplaceObjectAt(nsISupports* aObject, int32_t aIndex);
64 void ReplaceElementAt(uint32_t aIndex, nsISupports* aElement) {
65 nsISupports* oldElement = mArray[aIndex];
66 NS_IF_ADDREF(mArray[aIndex] = aElement);
67 NS_IF_RELEASE(oldElement);
68 }
69 bool AppendObject(nsISupports *aObject) {
70 return InsertObjectAt(aObject, Count());
71 }
72 void AppendElement(nsISupports* aElement) {
73 InsertElementAt(Length(), aElement);
74 }
75 bool AppendObjects(const nsCOMArray_base& aObjects) {
76 return InsertObjectsAt(aObjects, Count());
77 }
78 void AppendElements(const nsCOMArray_base& aElements) {
79 return InsertElementsAt(Length(), aElements);
80 }
81 void AppendElements(nsISupports* const* aElements, uint32_t aCount) {
82 return InsertElementsAt(Length(), aElements, aCount);
83 }
84 bool RemoveObject(nsISupports *aObject);
85 nsISupports** Elements() {
86 return mArray.Elements();
87 }
88 void SwapElements(nsCOMArray_base& aOther) {
89 mArray.SwapElements(aOther.mArray);
90 }
92 void Adopt(nsISupports** aElements, uint32_t aCount);
93 uint32_t Forget(nsISupports*** aElements);
94 public:
95 // elements in the array (including null elements!)
96 int32_t Count() const {
97 return mArray.Length();
98 }
99 // nsTArray-compatible version
100 uint32_t Length() const {
101 return mArray.Length();
102 }
103 bool IsEmpty() const {
104 return mArray.IsEmpty();
105 }
107 // If the array grows, the newly created entries will all be null;
108 // if the array shrinks, the excess entries will all be released.
109 bool SetCount(int32_t aNewCount);
110 // nsTArray-compatible version
111 void TruncateLength(uint32_t aNewLength) {
112 if (mArray.Length() > aNewLength)
113 RemoveElementsAt(aNewLength, mArray.Length() - aNewLength);
114 }
116 // remove all elements in the array, and call NS_RELEASE on each one
117 void Clear();
119 nsISupports* ObjectAt(int32_t aIndex) const {
120 return mArray[aIndex];
121 }
122 // nsTArray-compatible version
123 nsISupports* ElementAt(uint32_t aIndex) const {
124 return mArray[aIndex];
125 }
127 nsISupports* SafeObjectAt(int32_t aIndex) const {
128 return mArray.SafeElementAt(aIndex, nullptr);
129 }
130 // nsTArray-compatible version
131 nsISupports* SafeElementAt(uint32_t aIndex) const {
132 return mArray.SafeElementAt(aIndex, nullptr);
133 }
135 nsISupports* operator[](int32_t aIndex) const {
136 return mArray[aIndex];
137 }
139 // remove an element at a specific position, shrinking the array
140 // as necessary
141 bool RemoveObjectAt(int32_t aIndex);
142 // nsTArray-compatible version
143 void RemoveElementAt(uint32_t aIndex);
145 // remove a range of elements at a specific position, shrinking the array
146 // as necessary
147 bool RemoveObjectsAt(int32_t aIndex, int32_t aCount);
148 // nsTArray-compatible version
149 void RemoveElementsAt(uint32_t aIndex, uint32_t aCount);
151 void SwapElementsAt(uint32_t aIndex1, uint32_t aIndex2) {
152 nsISupports *tmp = mArray[aIndex1];
153 mArray[aIndex1] = mArray[aIndex2];
154 mArray[aIndex2] = tmp;
155 }
157 // Ensures there is enough space to store a total of aCapacity objects.
158 // This method never deletes any objects.
159 void SetCapacity(uint32_t aCapacity) {
160 mArray.SetCapacity(aCapacity);
161 }
162 uint32_t Capacity() {
163 return mArray.Capacity();
164 }
166 typedef size_t (* nsBaseArraySizeOfElementIncludingThisFunc)
167 (nsISupports* aElement, mozilla::MallocSizeOf aMallocSizeOf, void *aData);
169 // Measures the size of the array's element storage, and if
170 // |aSizeOfElement| is non-nullptr, measures the size of things pointed to
171 // by elements.
172 size_t SizeOfExcludingThis(
173 nsBaseArraySizeOfElementIncludingThisFunc aSizeOfElementIncludingThis,
174 mozilla::MallocSizeOf aMallocSizeOf, void* aData = nullptr) const;
176 private:
178 // the actual storage
179 nsTArray<nsISupports*> mArray;
181 // don't implement these, defaults will muck with refcounts!
182 nsCOMArray_base& operator=(const nsCOMArray_base& other) MOZ_DELETE;
183 };
185 inline void
186 ImplCycleCollectionUnlink(nsCOMArray_base& aField)
187 {
188 aField.Clear();
189 }
191 inline void
192 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
193 nsCOMArray_base& aField,
194 const char* aName,
195 uint32_t aFlags = 0)
196 {
197 aFlags |= CycleCollectionEdgeNameArrayFlag;
198 int32_t length = aField.Count();
199 for (int32_t i = 0; i < length; ++i) {
200 CycleCollectionNoteChild(aCallback, aField[i], aName, aFlags);
201 }
202 }
205 // a non-XPCOM, refcounting array of XPCOM objects
206 // used as a member variable or stack variable - this object is NOT
207 // refcounted, but the objects that it holds are
208 //
209 // most of the read-only accessors like ObjectAt()/etc do NOT refcount
210 // on the way out. This means that you can do one of two things:
211 //
212 // * does an addref, but holds onto a reference
213 // nsCOMPtr<T> foo = array[i];
214 //
215 // * avoids the refcount, but foo might go stale if array[i] is ever
216 // * modified/removed. Be careful not to NS_RELEASE(foo)!
217 // T* foo = array[i];
218 //
219 // This array will accept null as an argument for any object, and will
220 // store null in the array, just like nsVoidArray. But that also means
221 // that methods like ObjectAt() may return null when referring to an
222 // existing, but null entry in the array.
223 template <class T>
224 class nsCOMArray : public nsCOMArray_base
225 {
226 public:
227 nsCOMArray() {}
229 explicit
230 nsCOMArray(int32_t aCount) : nsCOMArray_base(aCount) {}
232 explicit
233 nsCOMArray(const nsCOMArray<T>& aOther) : nsCOMArray_base(aOther) { }
235 nsCOMArray(nsCOMArray<T>&& aOther) { SwapElements(aOther); }
237 ~nsCOMArray() {}
239 // We have a move assignment operator, but no copy assignment operator.
240 nsCOMArray<T>& operator=(nsCOMArray<T>&& aOther) {
241 SwapElements(aOther);
242 return *this;
243 }
245 // these do NOT refcount on the way out, for speed
246 T* ObjectAt(int32_t aIndex) const {
247 return static_cast<T*>(nsCOMArray_base::ObjectAt(aIndex));
248 }
249 // nsTArray-compatible version
250 T* ElementAt(uint32_t aIndex) const {
251 return static_cast<T*>(nsCOMArray_base::ElementAt(aIndex));
252 }
254 // these do NOT refcount on the way out, for speed
255 T* SafeObjectAt(int32_t aIndex) const {
256 return static_cast<T*>(nsCOMArray_base::SafeObjectAt(aIndex));
257 }
258 // nsTArray-compatible version
259 T* SafeElementAt(uint32_t aIndex) const {
260 return static_cast<T*>(nsCOMArray_base::SafeElementAt(aIndex));
261 }
263 // indexing operator for syntactic sugar
264 T* operator[](int32_t aIndex) const {
265 return ObjectAt(aIndex);
266 }
268 // index of the element in question.. does NOT refcount
269 // note: this does not check COM object identity. Use
270 // IndexOfObject() for that purpose
271 int32_t IndexOf(T* aObject, uint32_t aStartIndex = 0) const {
272 return nsCOMArray_base::IndexOf(aObject, aStartIndex);
273 }
274 bool Contains(nsISupports* aObject) const {
275 return nsCOMArray_base::Contains(aObject);
276 }
278 // index of the element in question.. be careful!
279 // this is much slower than IndexOf() because it uses
280 // QueryInterface to determine actual COM identity of the object
281 // if you need to do this frequently then consider enforcing
282 // COM object identity before adding/comparing elements
283 int32_t IndexOfObject(T* aObject) const {
284 return nsCOMArray_base::IndexOfObject(aObject);
285 }
286 bool ContainsObject(nsISupports* aObject) const {
287 return nsCOMArray_base::ContainsObject(aObject);
288 }
290 // inserts aObject at aIndex, shifting the objects at aIndex and
291 // later to make space
292 bool InsertObjectAt(T* aObject, int32_t aIndex) {
293 return nsCOMArray_base::InsertObjectAt(aObject, aIndex);
294 }
295 // nsTArray-compatible version
296 void InsertElementAt(uint32_t aIndex, T* aElement) {
297 nsCOMArray_base::InsertElementAt(aIndex, aElement);
298 }
300 // inserts the objects from aObject at aIndex, shifting the
301 // objects at aIndex and later to make space
302 bool InsertObjectsAt(const nsCOMArray<T>& aObjects, int32_t aIndex) {
303 return nsCOMArray_base::InsertObjectsAt(aObjects, aIndex);
304 }
305 // nsTArray-compatible version
306 void InsertElementsAt(uint32_t aIndex, const nsCOMArray<T>& aElements) {
307 nsCOMArray_base::InsertElementsAt(aIndex, aElements);
308 }
309 void InsertElementsAt(uint32_t aIndex, T* const* aElements, uint32_t aCount) {
310 nsCOMArray_base::InsertElementsAt(aIndex, reinterpret_cast<nsISupports* const*>(aElements), aCount);
311 }
313 // replaces an existing element. Warning: if the array grows,
314 // the newly created entries will all be null
315 bool ReplaceObjectAt(T* aObject, int32_t aIndex) {
316 return nsCOMArray_base::ReplaceObjectAt(aObject, aIndex);
317 }
318 // nsTArray-compatible version
319 void ReplaceElementAt(uint32_t aIndex, T* aElement) {
320 nsCOMArray_base::ReplaceElementAt(aIndex, aElement);
321 }
323 // Enumerator callback function. Return false to stop
324 // Here's a more readable form:
325 // bool enumerate(T* aElement, void* aData)
326 typedef bool (* nsCOMArrayEnumFunc)
327 (T* aElement, void *aData);
329 // enumerate through the array with a callback.
330 bool EnumerateForwards(nsCOMArrayEnumFunc aFunc, void* aData) {
331 return nsCOMArray_base::EnumerateForwards(nsBaseArrayEnumFunc(aFunc),
332 aData);
333 }
335 bool EnumerateBackwards(nsCOMArrayEnumFunc aFunc, void* aData) {
336 return nsCOMArray_base::EnumerateBackwards(nsBaseArrayEnumFunc(aFunc),
337 aData);
338 }
340 typedef int (* nsCOMArrayComparatorFunc)
341 (T* aElement1, T* aElement2, void* aData);
343 void Sort(nsCOMArrayComparatorFunc aFunc, void* aData) {
344 nsCOMArray_base::Sort(nsBaseArrayComparatorFunc(aFunc), aData);
345 }
347 // append an object, growing the array as necessary
348 bool AppendObject(T *aObject) {
349 return nsCOMArray_base::AppendObject(aObject);
350 }
351 // nsTArray-compatible version
352 void AppendElement(T* aElement) {
353 nsCOMArray_base::AppendElement(aElement);
354 }
356 // append objects, growing the array as necessary
357 bool AppendObjects(const nsCOMArray<T>& aObjects) {
358 return nsCOMArray_base::AppendObjects(aObjects);
359 }
360 // nsTArray-compatible version
361 void AppendElements(const nsCOMArray<T>& aElements) {
362 return nsCOMArray_base::AppendElements(aElements);
363 }
364 void AppendElements(T* const* aElements, uint32_t aCount) {
365 InsertElementsAt(Length(), aElements, aCount);
366 }
368 // remove the first instance of the given object and shrink the
369 // array as necessary
370 // Warning: if you pass null here, it will remove the first null element
371 bool RemoveObject(T *aObject) {
372 return nsCOMArray_base::RemoveObject(aObject);
373 }
374 // nsTArray-compatible version
375 bool RemoveElement(T* aElement) {
376 return nsCOMArray_base::RemoveObject(aElement);
377 }
379 T** Elements() {
380 return reinterpret_cast<T**>(nsCOMArray_base::Elements());
381 }
382 void SwapElements(nsCOMArray<T>& aOther) {
383 nsCOMArray_base::SwapElements(aOther);
384 }
386 // Each element in an nsCOMArray<T> is actually a T*, so this function is
387 // "IncludingThis" rather than "ExcludingThis" because it needs to measure
388 // the memory taken by the T itself as well as anything it points to.
389 typedef size_t (* nsCOMArraySizeOfElementIncludingThisFunc)
390 (T* aElement, mozilla::MallocSizeOf aMallocSizeOf, void *aData);
392 size_t SizeOfExcludingThis(
393 nsCOMArraySizeOfElementIncludingThisFunc aSizeOfElementIncludingThis,
394 mozilla::MallocSizeOf aMallocSizeOf, void *aData = nullptr) const {
395 return nsCOMArray_base::SizeOfExcludingThis(
396 nsBaseArraySizeOfElementIncludingThisFunc(aSizeOfElementIncludingThis),
397 aMallocSizeOf, aData);
398 }
400 /**
401 * Adopt parameters that resulted from an XPIDL outparam. The aElements
402 * parameter will be freed as a result of the call.
403 *
404 * Example usage:
405 * nsCOMArray<nsISomeInterface> array;
406 * nsISomeInterface** elements;
407 * uint32_t length;
408 * ptr->GetSomeArray(&elements, &length);
409 * array.Adopt(elements, length);
410 */
411 void Adopt(T** aElements, uint32_t aSize) {
412 nsCOMArray_base::Adopt(reinterpret_cast<nsISupports**>(aElements),
413 aSize);
414 }
416 /**
417 * Export the contents of this array to an XPIDL outparam. The array will be
418 * Clear()'d after this operation.
419 *
420 * Example usage:
421 * nsCOMArray<nsISomeInterface> array;
422 * *length = array.Forget(retval);
423 */
424 uint32_t Forget(T*** elements) {
425 return nsCOMArray_base::Forget(
426 reinterpret_cast<nsISupports***>(elements));
427 }
429 private:
431 // don't implement these!
432 nsCOMArray<T>& operator=(const nsCOMArray<T>& other) MOZ_DELETE;
433 };
435 template <typename T>
436 inline void
437 ImplCycleCollectionUnlink(nsCOMArray<T>& aField)
438 {
439 aField.Clear();
440 }
442 template <typename E>
443 inline void
444 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
445 nsCOMArray<E>& aField,
446 const char* aName,
447 uint32_t aFlags = 0)
448 {
449 aFlags |= CycleCollectionEdgeNameArrayFlag;
450 int32_t length = aField.Count();
451 for (int32_t i = 0; i < length; ++i) {
452 CycleCollectionNoteChild(aCallback, aField[i], aName, aFlags);
453 }
454 }
456 #endif