xpcom/glue/nsCOMArray.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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.

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

mercurial