xpcom/glue/nsArrayEnumerator.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 #include "mozilla/Attributes.h"
     8 #include "nsArrayEnumerator.h"
    10 #include "nsIArray.h"
    11 #include "nsISimpleEnumerator.h"
    13 #include "nsCOMArray.h"
    14 #include "nsCOMPtr.h"
    16 class nsSimpleArrayEnumerator MOZ_FINAL : public nsISimpleEnumerator
    17 {
    18 public:
    19     // nsISupports interface
    20     NS_DECL_ISUPPORTS
    22     // nsISimpleEnumerator interface
    23     NS_DECL_NSISIMPLEENUMERATOR
    25     // nsSimpleArrayEnumerator methods
    26     nsSimpleArrayEnumerator(nsIArray* aValueArray) :
    27         mValueArray(aValueArray), mIndex(0) {
    28     }
    30 private:
    31     ~nsSimpleArrayEnumerator() {}
    33 protected:
    34     nsCOMPtr<nsIArray> mValueArray;
    35     uint32_t mIndex;
    36 };
    38 NS_IMPL_ISUPPORTS(nsSimpleArrayEnumerator, nsISimpleEnumerator)
    40 NS_IMETHODIMP
    41 nsSimpleArrayEnumerator::HasMoreElements(bool* aResult)
    42 {
    43     NS_PRECONDITION(aResult != 0, "null ptr");
    44     if (! aResult)
    45         return NS_ERROR_NULL_POINTER;
    47     if (!mValueArray) {
    48         *aResult = false;
    49         return NS_OK;
    50     }
    52     uint32_t cnt;
    53     nsresult rv = mValueArray->GetLength(&cnt);
    54     if (NS_FAILED(rv)) return rv;
    55     *aResult = (mIndex < cnt);
    56     return NS_OK;
    57 }
    59 NS_IMETHODIMP
    60 nsSimpleArrayEnumerator::GetNext(nsISupports** aResult)
    61 {
    62     NS_PRECONDITION(aResult != 0, "null ptr");
    63     if (! aResult)
    64         return NS_ERROR_NULL_POINTER;
    66     if (!mValueArray) {
    67         *aResult = nullptr;
    68         return NS_OK;
    69     }
    71     uint32_t cnt;
    72     nsresult rv = mValueArray->GetLength(&cnt);
    73     if (NS_FAILED(rv)) return rv;
    74     if (mIndex >= cnt)
    75         return NS_ERROR_UNEXPECTED;
    77     return mValueArray->QueryElementAt(mIndex++, NS_GET_IID(nsISupports), (void**)aResult);
    78 }
    80 nsresult
    81 NS_NewArrayEnumerator(nsISimpleEnumerator* *result,
    82                       nsIArray* array)
    83 {
    84     nsSimpleArrayEnumerator* enumer = new nsSimpleArrayEnumerator(array);
    85     if (enumer == nullptr)
    86         return NS_ERROR_OUT_OF_MEMORY;
    88     NS_ADDREF(*result = enumer);
    89     return NS_OK;
    90 }
    92 ////////////////////////////////////////////////////////////////////////////////
    94 // enumerator implementation for nsCOMArray
    95 // creates a snapshot of the array in question
    96 // you MUST use NS_NewArrayEnumerator to create this, so that
    97 // allocation is done correctly
    98 class nsCOMArrayEnumerator MOZ_FINAL : public nsISimpleEnumerator
    99 {
   100 public:
   101     // nsISupports interface
   102     NS_DECL_ISUPPORTS
   104     // nsISimpleEnumerator interface
   105     NS_DECL_NSISIMPLEENUMERATOR
   107     // nsSimpleArrayEnumerator methods
   108     nsCOMArrayEnumerator() : mIndex(0) {
   109     }
   111     // specialized operator to make sure we make room for mValues
   112     void* operator new (size_t size, const nsCOMArray_base& aArray) CPP_THROW_NEW;
   113     void operator delete(void* ptr) {
   114         ::operator delete(ptr);
   115     }
   117 private:
   118     ~nsCOMArrayEnumerator(void);
   120 protected:
   121     uint32_t mIndex;            // current position
   122     uint32_t mArraySize;        // size of the array
   124     // this is actually bigger
   125     nsISupports* mValueArray[1];
   126 };
   128 NS_IMPL_ISUPPORTS(nsCOMArrayEnumerator, nsISimpleEnumerator)
   130 nsCOMArrayEnumerator::~nsCOMArrayEnumerator()
   131 {
   132     // only release the entries that we haven't visited yet
   133     for (; mIndex < mArraySize; ++mIndex) {
   134         NS_IF_RELEASE(mValueArray[mIndex]);
   135     }
   136 }
   138 NS_IMETHODIMP
   139 nsCOMArrayEnumerator::HasMoreElements(bool* aResult)
   140 {
   141     NS_PRECONDITION(aResult != 0, "null ptr");
   142     if (! aResult)
   143         return NS_ERROR_NULL_POINTER;
   145     *aResult = (mIndex < mArraySize);
   146     return NS_OK;
   147 }
   149 NS_IMETHODIMP
   150 nsCOMArrayEnumerator::GetNext(nsISupports** aResult)
   151 {
   152     NS_PRECONDITION(aResult != 0, "null ptr");
   153     if (! aResult)
   154         return NS_ERROR_NULL_POINTER;
   156     if (mIndex >= mArraySize)
   157         return NS_ERROR_UNEXPECTED;
   159     // pass the ownership of the reference to the caller. Since
   160     // we AddRef'ed during creation of |this|, there is no need
   161     // to AddRef here
   162     *aResult = mValueArray[mIndex++];
   164     // this really isn't necessary. just pretend this happens, since
   165     // we'll never visit this value again!
   166     // mValueArray[(mIndex-1)] = nullptr;
   168     return NS_OK;
   169 }
   171 void*
   172 nsCOMArrayEnumerator::operator new (size_t size, const nsCOMArray_base& aArray)
   173     CPP_THROW_NEW
   174 {
   175     // create enough space such that mValueArray points to a large
   176     // enough value. Note that the initial value of size gives us
   177     // space for mValueArray[0], so we must subtract
   178     size += (aArray.Count() - 1) * sizeof(aArray[0]);
   180     // do the actual allocation
   181     nsCOMArrayEnumerator * result =
   182         static_cast<nsCOMArrayEnumerator*>(::operator new(size));
   184     // now need to copy over the values, and addref each one
   185     // now this might seem like a lot of work, but we're actually just
   186     // doing all our AddRef's ahead of time since GetNext() doesn't
   187     // need to AddRef() on the way out
   188     uint32_t i;
   189     uint32_t max = result->mArraySize = aArray.Count();
   190     for (i = 0; i<max; i++) {
   191         result->mValueArray[i] = aArray[i];
   192         NS_IF_ADDREF(result->mValueArray[i]);
   193     }
   195     return result;
   196 }
   198 nsresult
   199 NS_NewArrayEnumerator(nsISimpleEnumerator* *aResult,
   200                       const nsCOMArray_base& aArray)
   201 {
   202     nsCOMArrayEnumerator *enumerator = new (aArray) nsCOMArrayEnumerator();
   203     if (!enumerator) return NS_ERROR_OUT_OF_MEMORY;
   205     NS_ADDREF(*aResult = enumerator);
   206     return NS_OK;
   207 }

mercurial