LCOV - code coverage report
Current view: top level - xpcom/ds - nsCOMArray.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 63 151 41.7 %
Date: 2017-07-14 16:53:18 Functions: 15 28 53.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 "nsCOMArray.h"
       8             : 
       9             : #include "mozilla/MemoryReporting.h"
      10             : #include "mozilla/OperatorNewExtensions.h"
      11             : 
      12             : #include "nsCOMPtr.h"
      13             : 
      14             : // This specialization is private to nsCOMArray.
      15             : // It exists solely to automatically zero-out newly created array elements.
      16             : template<>
      17             : class nsTArrayElementTraits<nsISupports*>
      18             : {
      19             :   typedef nsISupports* E;
      20             : public:
      21             :   // Zero out the value
      22           0 :   static inline void Construct(E* aE)
      23             :   {
      24           0 :     new (mozilla::KnownNotNull, static_cast<void*>(aE)) E();
      25           0 :   }
      26             :   // Invoke the copy-constructor in place.
      27             :   template<class A>
      28        3899 :   static inline void Construct(E* aE, const A& aArg)
      29             :   {
      30        3899 :     new (mozilla::KnownNotNull, static_cast<void*>(aE)) E(aArg);
      31        3899 :   }
      32             :   // Invoke the destructor in place.
      33         401 :   static inline void Destruct(E* aE)
      34             :   {
      35             :     aE->~E();
      36         401 :   }
      37             : };
      38             : 
      39             : static void ReleaseObjects(nsTArray<nsISupports*>& aArray);
      40             : 
      41             : // implementations of non-trivial methods in nsCOMArray_base
      42             : 
      43         758 : nsCOMArray_base::nsCOMArray_base(const nsCOMArray_base& aOther)
      44             : {
      45             :   // make sure we do only one allocation
      46         758 :   mArray.SetCapacity(aOther.Count());
      47         758 :   AppendObjects(aOther);
      48         758 : }
      49             : 
      50        1802 : nsCOMArray_base::~nsCOMArray_base()
      51             : {
      52         901 :   Clear();
      53         901 : }
      54             : 
      55             : int32_t
      56           1 : nsCOMArray_base::IndexOf(nsISupports* aObject, uint32_t aStartIndex) const
      57             : {
      58           1 :   return mArray.IndexOf(aObject, aStartIndex);
      59             : }
      60             : 
      61             : int32_t
      62           1 : nsCOMArray_base::IndexOfObject(nsISupports* aObject) const
      63             : {
      64           2 :   nsCOMPtr<nsISupports> supports = do_QueryInterface(aObject);
      65           1 :   if (NS_WARN_IF(!supports)) {
      66           0 :     return -1;
      67             :   }
      68             : 
      69             :   uint32_t i, count;
      70           1 :   int32_t retval = -1;
      71           1 :   count = mArray.Length();
      72           1 :   for (i = 0; i < count; ++i) {
      73           0 :     nsCOMPtr<nsISupports> arrayItem = do_QueryInterface(mArray[i]);
      74           0 :     if (arrayItem == supports) {
      75           0 :       retval = i;
      76           0 :       break;
      77             :     }
      78             :   }
      79           1 :   return retval;
      80             : }
      81             : 
      82             : bool
      83           0 : nsCOMArray_base::EnumerateForwards(nsBaseArrayEnumFunc aFunc, void* aData) const
      84             : {
      85           0 :   for (uint32_t index = 0; index < mArray.Length(); ++index) {
      86           0 :     if (!(*aFunc)(mArray[index], aData)) {
      87           0 :       return false;
      88             :     }
      89             :   }
      90             : 
      91           0 :   return true;
      92             : }
      93             : 
      94             : bool
      95           0 : nsCOMArray_base::EnumerateBackwards(nsBaseArrayEnumFunc aFunc, void* aData) const
      96             : {
      97           0 :   for (uint32_t index = mArray.Length(); index--; ) {
      98           0 :     if (!(*aFunc)(mArray[index], aData)) {
      99           0 :       return false;
     100             :     }
     101             :   }
     102             : 
     103           0 :   return true;
     104             : }
     105             : 
     106             : int
     107          54 : nsCOMArray_base::nsCOMArrayComparator(const void* aElement1,
     108             :                                       const void* aElement2,
     109             :                                       void* aData)
     110             : {
     111             :   nsCOMArrayComparatorContext* ctx =
     112          54 :     static_cast<nsCOMArrayComparatorContext*>(aData);
     113          54 :   return (*ctx->mComparatorFunc)(*static_cast<nsISupports* const*>(aElement1),
     114             :                                  *static_cast<nsISupports* const*>(aElement2),
     115          54 :                                  ctx->mData);
     116             : }
     117             : 
     118             : void
     119           6 : nsCOMArray_base::Sort(nsBaseArrayComparatorFunc aFunc, void* aData)
     120             : {
     121           6 :   if (mArray.Length() > 1) {
     122           6 :     nsCOMArrayComparatorContext ctx = {aFunc, aData};
     123           6 :     NS_QuickSort(mArray.Elements(), mArray.Length(), sizeof(nsISupports*),
     124           6 :                  nsCOMArrayComparator, &ctx);
     125             :   }
     126           6 : }
     127             : 
     128             : bool
     129        3851 : nsCOMArray_base::InsertObjectAt(nsISupports* aObject, int32_t aIndex)
     130             : {
     131        3851 :   if ((uint32_t)aIndex > mArray.Length()) {
     132           0 :     return false;
     133             :   }
     134             : 
     135        3851 :   if (!mArray.InsertElementAt(aIndex, aObject)) {
     136           0 :     return false;
     137             :   }
     138             : 
     139        3851 :   NS_IF_ADDREF(aObject);
     140        3851 :   return true;
     141             : }
     142             : 
     143             : void
     144           3 : nsCOMArray_base::InsertElementAt(uint32_t aIndex, nsISupports* aElement)
     145             : {
     146           3 :   mArray.InsertElementAt(aIndex, aElement);
     147           3 :   NS_IF_ADDREF(aElement);
     148           3 : }
     149             : 
     150             : void
     151          45 : nsCOMArray_base::InsertElementAt(uint32_t aIndex, already_AddRefed<nsISupports> aElement)
     152             : {
     153          45 :   mArray.InsertElementAt(aIndex, aElement.take());
     154          45 : }
     155             : 
     156             : bool
     157         758 : nsCOMArray_base::InsertObjectsAt(const nsCOMArray_base& aObjects, int32_t aIndex)
     158             : {
     159         758 :   if ((uint32_t)aIndex > mArray.Length()) {
     160           0 :     return false;
     161             :   }
     162             : 
     163         758 :   if (!mArray.InsertElementsAt(aIndex, aObjects.mArray)) {
     164           0 :     return false;
     165             :   }
     166             : 
     167             :   // need to addref all these
     168         758 :   uint32_t count = aObjects.Length();
     169         758 :   for (uint32_t i = 0; i < count; ++i) {
     170           0 :     NS_IF_ADDREF(aObjects[i]);
     171             :   }
     172             : 
     173         758 :   return true;
     174             : }
     175             : 
     176             : void
     177           0 : nsCOMArray_base::InsertElementsAt(uint32_t aIndex,
     178             :                                   const nsCOMArray_base& aElements)
     179             : {
     180           0 :   mArray.InsertElementsAt(aIndex, aElements.mArray);
     181             : 
     182             :   // need to addref all these
     183           0 :   uint32_t count = aElements.Length();
     184           0 :   for (uint32_t i = 0; i < count; ++i) {
     185           0 :     NS_IF_ADDREF(aElements[i]);
     186             :   }
     187           0 : }
     188             : 
     189             : void
     190           0 : nsCOMArray_base::InsertElementsAt(uint32_t aIndex,
     191             :                                   nsISupports* const* aElements,
     192             :                                   uint32_t aCount)
     193             : {
     194           0 :   mArray.InsertElementsAt(aIndex, aElements, aCount);
     195             : 
     196             :   // need to addref all these
     197           0 :   for (uint32_t i = 0; i < aCount; ++i) {
     198           0 :     NS_IF_ADDREF(aElements[i]);
     199             :   }
     200           0 : }
     201             : 
     202             : void
     203           0 : nsCOMArray_base::ReplaceObjectAt(nsISupports* aObject, int32_t aIndex)
     204             : {
     205           0 :   mArray.EnsureLengthAtLeast(aIndex + 1);
     206           0 :   nsISupports* oldObject = mArray[aIndex];
     207             :   // Make sure to addref first, in case aObject == oldObject
     208           0 :   NS_IF_ADDREF(mArray[aIndex] = aObject);
     209           0 :   NS_IF_RELEASE(oldObject);
     210           0 : }
     211             : 
     212             : bool
     213          22 : nsCOMArray_base::RemoveObject(nsISupports* aObject)
     214             : {
     215          22 :   bool result = mArray.RemoveElement(aObject);
     216          22 :   if (result) {
     217           7 :     NS_IF_RELEASE(aObject);
     218             :   }
     219          22 :   return result;
     220             : }
     221             : 
     222             : bool
     223           0 : nsCOMArray_base::RemoveObjectAt(int32_t aIndex)
     224             : {
     225           0 :   if (uint32_t(aIndex) < mArray.Length()) {
     226           0 :     nsISupports* element = mArray[aIndex];
     227             : 
     228           0 :     mArray.RemoveElementAt(aIndex);
     229           0 :     NS_IF_RELEASE(element);
     230           0 :     return true;
     231             :   }
     232             : 
     233           0 :   return false;
     234             : }
     235             : 
     236             : void
     237           0 : nsCOMArray_base::RemoveElementAt(uint32_t aIndex)
     238             : {
     239           0 :   nsISupports* element = mArray[aIndex];
     240           0 :   mArray.RemoveElementAt(aIndex);
     241           0 :   NS_IF_RELEASE(element);
     242           0 : }
     243             : 
     244             : bool
     245           0 : nsCOMArray_base::RemoveObjectsAt(int32_t aIndex, int32_t aCount)
     246             : {
     247           0 :   if (uint32_t(aIndex) + uint32_t(aCount) <= mArray.Length()) {
     248           0 :     nsTArray<nsISupports*> elementsToDestroy(aCount);
     249           0 :     elementsToDestroy.AppendElements(mArray.Elements() + aIndex, aCount);
     250           0 :     mArray.RemoveElementsAt(aIndex, aCount);
     251           0 :     ReleaseObjects(elementsToDestroy);
     252           0 :     return true;
     253             :   }
     254             : 
     255           0 :   return false;
     256             : }
     257             : 
     258             : void
     259           0 : nsCOMArray_base::RemoveElementsAt(uint32_t aIndex, uint32_t aCount)
     260             : {
     261           0 :   nsTArray<nsISupports*> elementsToDestroy(aCount);
     262           0 :   elementsToDestroy.AppendElements(mArray.Elements() + aIndex, aCount);
     263           0 :   mArray.RemoveElementsAt(aIndex, aCount);
     264           0 :   ReleaseObjects(elementsToDestroy);
     265           0 : }
     266             : 
     267             : // useful for destructors
     268             : void
     269        1002 : ReleaseObjects(nsTArray<nsISupports*>& aArray)
     270             : {
     271        1396 :   for (uint32_t i = 0; i < aArray.Length(); ++i) {
     272         394 :     NS_IF_RELEASE(aArray[i]);
     273             :   }
     274        1002 : }
     275             : 
     276             : void
     277        1002 : nsCOMArray_base::Clear()
     278             : {
     279        2004 :   nsTArray<nsISupports*> objects;
     280        1002 :   objects.SwapElements(mArray);
     281        1002 :   ReleaseObjects(objects);
     282        1002 : }
     283             : 
     284             : bool
     285           0 : nsCOMArray_base::SetCount(int32_t aNewCount)
     286             : {
     287           0 :   NS_ASSERTION(aNewCount >= 0, "SetCount(negative index)");
     288           0 :   if (aNewCount < 0) {
     289           0 :     return false;
     290             :   }
     291             : 
     292           0 :   int32_t count = mArray.Length();
     293           0 :   if (count > aNewCount) {
     294           0 :     RemoveObjectsAt(aNewCount, mArray.Length() - aNewCount);
     295             :   }
     296           0 :   mArray.SetLength(aNewCount);
     297           0 :   return true;
     298             : }
     299             : 
     300             : void
     301           0 : nsCOMArray_base::Adopt(nsISupports** aElements, uint32_t aSize)
     302             : {
     303           0 :   Clear();
     304           0 :   mArray.AppendElements(aElements, aSize);
     305             : 
     306             :   // Free the allocated array as well.
     307           0 :   NS_Free(aElements);
     308           0 : }
     309             : 
     310             : uint32_t
     311           0 : nsCOMArray_base::Forget(nsISupports*** aElements)
     312             : {
     313           0 :   uint32_t length = Length();
     314           0 :   size_t array_size = sizeof(nsISupports*) * length;
     315           0 :   nsISupports** array = static_cast<nsISupports**>(NS_Alloc(array_size));
     316           0 :   memmove(array, Elements(), array_size);
     317           0 :   *aElements = array;
     318             :   // Don't Release the contained pointers; the caller of the method will
     319             :   // do this eventually.
     320           0 :   mArray.Clear();
     321             : 
     322           0 :   return length;
     323             : }

Generated by: LCOV version 1.13