LCOV - code coverage report
Current view: top level - xpcom/ds - nsArrayEnumerator.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 30 69 43.5 %
Date: 2017-07-14 16:53:18 Functions: 10 18 55.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/Attributes.h"
       8             : 
       9             : #include "nsArrayEnumerator.h"
      10             : 
      11             : #include "nsIArray.h"
      12             : #include "nsISimpleEnumerator.h"
      13             : 
      14             : #include "nsCOMArray.h"
      15             : #include "nsCOMPtr.h"
      16             : #include "mozilla/RefPtr.h"
      17             : 
      18             : class nsSimpleArrayEnumerator final : public nsISimpleEnumerator
      19             : {
      20             : public:
      21             :   // nsISupports interface
      22             :   NS_DECL_ISUPPORTS
      23             : 
      24             :   // nsISimpleEnumerator interface
      25             :   NS_DECL_NSISIMPLEENUMERATOR
      26             : 
      27             :   // nsSimpleArrayEnumerator methods
      28           0 :   explicit nsSimpleArrayEnumerator(nsIArray* aValueArray)
      29           0 :     : mValueArray(aValueArray)
      30           0 :     , mIndex(0)
      31             :   {
      32           0 :   }
      33             : 
      34             : private:
      35           0 :   ~nsSimpleArrayEnumerator() = default;
      36             : 
      37             : protected:
      38             :   nsCOMPtr<nsIArray> mValueArray;
      39             :   uint32_t mIndex;
      40             : };
      41             : 
      42           0 : NS_IMPL_ISUPPORTS(nsSimpleArrayEnumerator, nsISimpleEnumerator)
      43             : 
      44             : NS_IMETHODIMP
      45           0 : nsSimpleArrayEnumerator::HasMoreElements(bool* aResult)
      46             : {
      47           0 :   NS_PRECONDITION(aResult != 0, "null ptr");
      48           0 :   if (!aResult) {
      49           0 :     return NS_ERROR_NULL_POINTER;
      50             :   }
      51             : 
      52           0 :   if (!mValueArray) {
      53           0 :     *aResult = false;
      54           0 :     return NS_OK;
      55             :   }
      56             : 
      57             :   uint32_t cnt;
      58           0 :   nsresult rv = mValueArray->GetLength(&cnt);
      59           0 :   if (NS_FAILED(rv)) {
      60           0 :     return rv;
      61             :   }
      62           0 :   *aResult = (mIndex < cnt);
      63           0 :   return NS_OK;
      64             : }
      65             : 
      66             : NS_IMETHODIMP
      67           0 : nsSimpleArrayEnumerator::GetNext(nsISupports** aResult)
      68             : {
      69           0 :   NS_PRECONDITION(aResult != 0, "null ptr");
      70           0 :   if (!aResult) {
      71           0 :     return NS_ERROR_NULL_POINTER;
      72             :   }
      73             : 
      74           0 :   if (!mValueArray) {
      75           0 :     *aResult = nullptr;
      76           0 :     return NS_OK;
      77             :   }
      78             : 
      79             :   uint32_t cnt;
      80           0 :   nsresult rv = mValueArray->GetLength(&cnt);
      81           0 :   if (NS_FAILED(rv)) {
      82           0 :     return rv;
      83             :   }
      84           0 :   if (mIndex >= cnt) {
      85           0 :     return NS_ERROR_UNEXPECTED;
      86             :   }
      87             : 
      88           0 :   return mValueArray->QueryElementAt(mIndex++, NS_GET_IID(nsISupports),
      89           0 :                                      (void**)aResult);
      90             : }
      91             : 
      92             : nsresult
      93           0 : NS_NewArrayEnumerator(nsISimpleEnumerator** aResult, nsIArray* aArray)
      94             : {
      95           0 :   RefPtr<nsSimpleArrayEnumerator> enumer = new nsSimpleArrayEnumerator(aArray);
      96           0 :   enumer.forget(aResult);
      97           0 :   return NS_OK;
      98             : }
      99             : 
     100             : ////////////////////////////////////////////////////////////////////////////////
     101             : 
     102             : // enumerator implementation for nsCOMArray
     103             : // creates a snapshot of the array in question
     104             : // you MUST use NS_NewArrayEnumerator to create this, so that
     105             : // allocation is done correctly
     106             : class nsCOMArrayEnumerator final : public nsISimpleEnumerator
     107             : {
     108             : public:
     109             :   // nsISupports interface
     110             :   NS_DECL_ISUPPORTS
     111             : 
     112             :   // nsISimpleEnumerator interface
     113             :   NS_DECL_NSISIMPLEENUMERATOR
     114             : 
     115             :   // nsSimpleArrayEnumerator methods
     116          23 :   nsCOMArrayEnumerator() : mIndex(0) {}
     117             : 
     118             :   // specialized operator to make sure we make room for mValues
     119             :   void* operator new(size_t aSize, const nsCOMArray_base& aArray) CPP_THROW_NEW;
     120          42 :   void operator delete(void* aPtr) { ::operator delete(aPtr); }
     121             : 
     122             : private:
     123             :   ~nsCOMArrayEnumerator(void);
     124             : 
     125             : protected:
     126             :   uint32_t mIndex;            // current position
     127             :   uint32_t mArraySize;        // size of the array
     128             : 
     129             :   // this is actually bigger
     130             :   nsISupports* mValueArray[1];
     131             : };
     132             : 
     133         387 : NS_IMPL_ISUPPORTS(nsCOMArrayEnumerator, nsISimpleEnumerator)
     134             : 
     135          42 : nsCOMArrayEnumerator::~nsCOMArrayEnumerator()
     136             : {
     137             :   // only release the entries that we haven't visited yet
     138          33 :   for (; mIndex < mArraySize; ++mIndex) {
     139           6 :     NS_IF_RELEASE(mValueArray[mIndex]);
     140             :   }
     141          21 : }
     142             : 
     143             : NS_IMETHODIMP
     144          61 : nsCOMArrayEnumerator::HasMoreElements(bool* aResult)
     145             : {
     146          61 :   NS_PRECONDITION(aResult != 0, "null ptr");
     147          61 :   if (!aResult) {
     148           0 :     return NS_ERROR_NULL_POINTER;
     149             :   }
     150             : 
     151          61 :   *aResult = (mIndex < mArraySize);
     152          61 :   return NS_OK;
     153             : }
     154             : 
     155             : NS_IMETHODIMP
     156          41 : nsCOMArrayEnumerator::GetNext(nsISupports** aResult)
     157             : {
     158          41 :   NS_PRECONDITION(aResult != 0, "null ptr");
     159          41 :   if (!aResult) {
     160           0 :     return NS_ERROR_NULL_POINTER;
     161             :   }
     162             : 
     163          41 :   if (mIndex >= mArraySize) {
     164           0 :     return NS_ERROR_UNEXPECTED;
     165             :   }
     166             : 
     167             :   // pass the ownership of the reference to the caller. Since
     168             :   // we AddRef'ed during creation of |this|, there is no need
     169             :   // to AddRef here
     170          41 :   *aResult = mValueArray[mIndex++];
     171             : 
     172             :   // this really isn't necessary. just pretend this happens, since
     173             :   // we'll never visit this value again!
     174             :   // mValueArray[(mIndex-1)] = nullptr;
     175             : 
     176          41 :   return NS_OK;
     177             : }
     178             : 
     179             : void*
     180          23 : nsCOMArrayEnumerator::operator new(size_t aSize,
     181             :                                    const nsCOMArray_base& aArray) CPP_THROW_NEW
     182             : {
     183             :   // create enough space such that mValueArray points to a large
     184             :   // enough value. Note that the initial value of aSize gives us
     185             :   // space for mValueArray[0], so we must subtract
     186          23 :   aSize += (aArray.Count() - 1) * sizeof(aArray[0]);
     187             : 
     188             :   // do the actual allocation
     189             :   nsCOMArrayEnumerator* result =
     190          23 :     static_cast<nsCOMArrayEnumerator*>(::operator new(aSize));
     191             : 
     192             :   // now need to copy over the values, and addref each one
     193             :   // now this might seem like a lot of work, but we're actually just
     194             :   // doing all our AddRef's ahead of time since GetNext() doesn't
     195             :   // need to AddRef() on the way out
     196             :   uint32_t i;
     197          23 :   uint32_t max = result->mArraySize = aArray.Count();
     198          70 :   for (i = 0; i < max; ++i) {
     199          47 :     result->mValueArray[i] = aArray[i];
     200          47 :     NS_IF_ADDREF(result->mValueArray[i]);
     201             :   }
     202             : 
     203          23 :   return result;
     204             : }
     205             : 
     206             : nsresult
     207          23 : NS_NewArrayEnumerator(nsISimpleEnumerator** aResult,
     208             :                       const nsCOMArray_base& aArray)
     209             : {
     210          46 :   RefPtr<nsCOMArrayEnumerator> enumerator = new (aArray) nsCOMArrayEnumerator();
     211          23 :   enumerator.forget(aResult);
     212          46 :   return NS_OK;
     213             : }

Generated by: LCOV version 1.13