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.

     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

mercurial