LCOV - code coverage report
Current view: top level - xpcom/ds - nsArray.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 29 108 26.9 %
Date: 2017-07-14 16:53:18 Functions: 8 25 32.0 %
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 "nsArray.h"
       8             : #include "nsArrayEnumerator.h"
       9             : #include "nsIWeakReference.h"
      10             : #include "nsIWeakReferenceUtils.h"
      11             : #include "nsThreadUtils.h"
      12             : 
      13             : // used by IndexOf()
      14             : struct MOZ_STACK_CLASS findIndexOfClosure
      15             : {
      16             :   // This is only used for pointer comparison, so we can just use a void*.
      17             :   void* targetElement;
      18             :   uint32_t startIndex;
      19             :   uint32_t resultIndex;
      20             : };
      21             : 
      22             : static bool FindElementCallback(void* aElement, void* aClosure);
      23             : 
      24           0 : NS_INTERFACE_MAP_BEGIN(nsArray)
      25           0 :   NS_INTERFACE_MAP_ENTRY(nsIArray)
      26           0 :   NS_INTERFACE_MAP_ENTRY(nsIArrayExtensions)
      27           0 :   NS_INTERFACE_MAP_ENTRY(nsIMutableArray)
      28           0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMutableArray)
      29           0 : NS_INTERFACE_MAP_END
      30             : 
      31          58 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsArrayCC)
      32          56 :   NS_INTERFACE_MAP_ENTRY(nsIArray)
      33          48 :   NS_INTERFACE_MAP_ENTRY(nsIArrayExtensions)
      34          48 :   NS_INTERFACE_MAP_ENTRY(nsIMutableArray)
      35          40 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMutableArray)
      36          31 : NS_INTERFACE_MAP_END
      37             : 
      38           0 : nsArrayBase::~nsArrayBase()
      39             : {
      40           0 :   Clear();
      41           0 : }
      42             : 
      43             : 
      44           0 : NS_IMPL_ADDREF(nsArray)
      45           0 : NS_IMPL_RELEASE(nsArray)
      46             : 
      47             : NS_IMPL_CYCLE_COLLECTION_CLASS(nsArrayCC)
      48             : 
      49          35 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsArrayCC)
      50          27 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsArrayCC)
      51             : 
      52           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsArrayCC)
      53           0 :   tmp->Clear();
      54           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      55           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsArrayCC)
      56           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArray)
      57           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      58             : 
      59             : NS_IMETHODIMP
      60           5 : nsArrayBase::GetLength(uint32_t* aLength)
      61             : {
      62           5 :   *aLength = mArray.Count();
      63           5 :   return NS_OK;
      64             : }
      65             : 
      66             : NS_IMETHODIMP
      67          12 : nsArrayBase::QueryElementAt(uint32_t aIndex,
      68             :                             const nsIID& aIID,
      69             :                             void** aResult)
      70             : {
      71          12 :   nsISupports* obj = mArray.SafeObjectAt(aIndex);
      72          12 :   if (!obj) {
      73           8 :     return NS_ERROR_ILLEGAL_VALUE;
      74             :   }
      75             : 
      76             :   // no need to worry about a leak here, because SafeObjectAt()
      77             :   // doesn't addref its result
      78           4 :   return obj->QueryInterface(aIID, aResult);
      79             : }
      80             : 
      81             : NS_IMETHODIMP
      82           0 : nsArrayBase::IndexOf(uint32_t aStartIndex, nsISupports* aElement,
      83             :                      uint32_t* aResult)
      84             : {
      85             :   // optimize for the common case by forwarding to mArray
      86           0 :   if (aStartIndex == 0) {
      87           0 :     uint32_t idx = mArray.IndexOf(aElement);
      88           0 :     if (idx == UINT32_MAX) {
      89           0 :       return NS_ERROR_FAILURE;
      90             :     }
      91             : 
      92           0 :     *aResult = idx;
      93           0 :     return NS_OK;
      94             :   }
      95             : 
      96           0 :   findIndexOfClosure closure = { aElement, aStartIndex, 0 };
      97           0 :   bool notFound = mArray.EnumerateForwards(FindElementCallback, &closure);
      98           0 :   if (notFound) {
      99           0 :     return NS_ERROR_FAILURE;
     100             :   }
     101             : 
     102           0 :   *aResult = closure.resultIndex;
     103           0 :   return NS_OK;
     104             : }
     105             : 
     106             : NS_IMETHODIMP
     107           0 : nsArrayBase::Enumerate(nsISimpleEnumerator** aResult)
     108             : {
     109           0 :   return NS_NewArrayEnumerator(aResult, static_cast<nsIArray*>(this));
     110             : }
     111             : 
     112             : // nsIMutableArray implementation
     113             : 
     114             : NS_IMETHODIMP
     115           6 : nsArrayBase::AppendElement(nsISupports* aElement, bool aWeak)
     116             : {
     117             :   bool result;
     118           6 :   if (aWeak) {
     119           0 :     nsCOMPtr<nsIWeakReference> elementRef = do_GetWeakReference(aElement);
     120           0 :     NS_ASSERTION(elementRef,
     121             :                  "AppendElement: Trying to use weak references on an object that doesn't support it");
     122           0 :     if (!elementRef) {
     123           0 :       return NS_ERROR_FAILURE;
     124             :     }
     125           0 :     result = mArray.AppendObject(elementRef);
     126             :   }
     127             : 
     128             :   else {
     129             :     // add the object directly
     130           6 :     result = mArray.AppendObject(aElement);
     131             :   }
     132           6 :   return result ? NS_OK : NS_ERROR_FAILURE;
     133             : }
     134             : 
     135             : NS_IMETHODIMP
     136           0 : nsArrayBase::RemoveElementAt(uint32_t aIndex)
     137             : {
     138           0 :   bool result = mArray.RemoveObjectAt(aIndex);
     139           0 :   return result ? NS_OK : NS_ERROR_FAILURE;
     140             : }
     141             : 
     142             : NS_IMETHODIMP
     143           0 : nsArrayBase::InsertElementAt(nsISupports* aElement, uint32_t aIndex, bool aWeak)
     144             : {
     145           0 :   nsCOMPtr<nsISupports> elementRef;
     146           0 :   if (aWeak) {
     147           0 :     elementRef = do_GetWeakReference(aElement);
     148           0 :     NS_ASSERTION(elementRef,
     149             :                  "InsertElementAt: Trying to use weak references on an object that doesn't support it");
     150           0 :     if (!elementRef) {
     151           0 :       return NS_ERROR_FAILURE;
     152             :     }
     153             :   } else {
     154           0 :     elementRef = aElement;
     155             :   }
     156           0 :   bool result = mArray.InsertObjectAt(elementRef, aIndex);
     157           0 :   return result ? NS_OK : NS_ERROR_FAILURE;
     158             : }
     159             : 
     160             : NS_IMETHODIMP
     161           0 : nsArrayBase::ReplaceElementAt(nsISupports* aElement, uint32_t aIndex, bool aWeak)
     162             : {
     163           0 :   nsCOMPtr<nsISupports> elementRef;
     164           0 :   if (aWeak) {
     165           0 :     elementRef = do_GetWeakReference(aElement);
     166           0 :     NS_ASSERTION(elementRef,
     167             :                  "ReplaceElementAt: Trying to use weak references on an object that doesn't support it");
     168           0 :     if (!elementRef) {
     169           0 :       return NS_ERROR_FAILURE;
     170             :     }
     171             :   } else {
     172           0 :     elementRef = aElement;
     173             :   }
     174           0 :   mArray.ReplaceObjectAt(elementRef, aIndex);
     175           0 :   return NS_OK;
     176             : }
     177             : 
     178             : NS_IMETHODIMP
     179           0 : nsArrayBase::Clear()
     180             : {
     181           0 :   mArray.Clear();
     182           0 :   return NS_OK;
     183             : }
     184             : 
     185             : // nsIArrayExtensions implementation.
     186             : 
     187             : NS_IMETHODIMP
     188           0 : nsArrayBase::Count(uint32_t* aResult)
     189             : {
     190           0 :   return GetLength(aResult);
     191             : }
     192             : 
     193             : NS_IMETHODIMP
     194           0 : nsArrayBase::GetElementAt(uint32_t aIndex, nsISupports** aResult)
     195             : {
     196           0 :   nsCOMPtr<nsISupports> obj = mArray.SafeObjectAt(aIndex);
     197           0 :   obj.forget(aResult);
     198           0 :   return NS_OK;
     199             : }
     200             : 
     201             : //
     202             : // static helper routines
     203             : //
     204             : bool
     205           0 : FindElementCallback(void* aElement, void* aClosure)
     206             : {
     207           0 :   findIndexOfClosure* closure = static_cast<findIndexOfClosure*>(aClosure);
     208           0 :   nsISupports* element = static_cast<nsISupports*>(aElement);
     209             : 
     210             :   // don't start searching until we're past the startIndex
     211           0 :   if (closure->resultIndex >= closure->startIndex &&
     212           0 :       element == closure->targetElement) {
     213           0 :     return false;    // stop! We found it
     214             :   }
     215           0 :   closure->resultIndex++;
     216             : 
     217           0 :   return true;
     218             : }
     219             : 
     220             : nsresult
     221           2 : nsArrayBase::XPCOMConstructor(nsISupports* aOuter, const nsIID& aIID,
     222             :                               void** aResult)
     223             : {
     224           2 :   if (aOuter) {
     225           0 :     return NS_ERROR_NO_AGGREGATION;
     226             :   }
     227             : 
     228           4 :   nsCOMPtr<nsIMutableArray> inst = Create();
     229           2 :   return inst->QueryInterface(aIID, aResult);
     230             : }
     231             : 
     232             : already_AddRefed<nsIMutableArray>
     233           2 : nsArrayBase::Create()
     234             : {
     235           4 :   nsCOMPtr<nsIMutableArray> inst;
     236           2 :   if (NS_IsMainThread()) {
     237           2 :     inst = new nsArrayCC;
     238             :   } else {
     239           0 :     inst = new nsArray;
     240             :   }
     241           4 :   return inst.forget();
     242             : }

Generated by: LCOV version 1.13