LCOV - code coverage report
Current view: top level - toolkit/mozapps/extensions - AddonManagerStartup-inlines.h (source / functions) Hit Total Coverage
Test: output.info Lines: 62 64 96.9 %
Date: 2017-07-14 16:53:18 Functions: 24 24 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       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/. */
       5             : 
       6             : #ifndef AddonManagerStartup_inlines_h
       7             : #define AddonManagerStartup_inlines_h
       8             : 
       9             : #include "jsapi.h"
      10             : #include "nsJSUtils.h"
      11             : 
      12             : #include "mozilla/Maybe.h"
      13             : #include "mozilla/Move.h"
      14             : 
      15             : namespace mozilla {
      16             : 
      17             : class ArrayIterElem;
      18             : class PropertyIterElem;
      19             : 
      20             : 
      21             : /*****************************************************************************
      22             :  * Object iterator base classes
      23             :  *****************************************************************************/
      24             : 
      25             : template<class T, class PropertyType>
      26             : class MOZ_STACK_CLASS BaseIter {
      27             : public:
      28             :   typedef T SelfType;
      29             : 
      30           6 :   PropertyType begin() const
      31             :   {
      32          12 :     PropertyType elem(Self());
      33          12 :     return Move(elem);
      34             :   }
      35             : 
      36           6 :   PropertyType end() const
      37             :   {
      38          12 :     PropertyType elem(Self());
      39          12 :     return elem.End();
      40             :   }
      41             : 
      42          18 :   void* Context() const { return mContext; }
      43             : 
      44             : protected:
      45           8 :   BaseIter(JSContext* cx, JS::HandleObject object, void* context = nullptr)
      46             :     : mCx(cx)
      47             :     , mObject(object)
      48           8 :     , mContext(context)
      49           8 :   {}
      50             : 
      51          12 :   const SelfType& Self() const
      52             :   {
      53          12 :     return *static_cast<const SelfType*>(this);
      54             :   }
      55             :   SelfType& Self()
      56             :   {
      57             :     return *static_cast<SelfType*>(this);
      58             :   }
      59             : 
      60             :   JSContext* mCx;
      61             : 
      62             :   JS::HandleObject mObject;
      63             : 
      64             :   void* mContext;
      65             : };
      66             : 
      67             : template<class T, class IterType>
      68             : class MOZ_STACK_CLASS BaseIterElem {
      69             : public:
      70             :   typedef T SelfType;
      71             : 
      72          54 :   explicit BaseIterElem(const IterType& iter, uint32_t index = 0)
      73             :     : mIter(iter)
      74          54 :     , mIndex(index)
      75          54 :   {}
      76             : 
      77          54 :   uint32_t Length() const
      78             :   {
      79          54 :     return mIter.Length();
      80             :   }
      81             : 
      82          24 :   JS::Value Value()
      83             :   {
      84          48 :     JS::RootedValue value(mIter.mCx, JS::UndefinedValue());
      85             : 
      86          24 :     auto& self = Self();
      87          24 :     if (!self.GetValue(&value)) {
      88           0 :       JS_ClearPendingException(mIter.mCx);
      89             :     }
      90             : 
      91          48 :     return value;
      92             :   }
      93             : 
      94          24 :   SelfType& operator*() { return Self(); }
      95             : 
      96          24 :   SelfType& operator++()
      97             :   {
      98          24 :     MOZ_ASSERT(mIndex < Length());
      99          24 :     mIndex++;
     100          24 :     return Self();
     101             :   }
     102             : 
     103          30 :   bool operator!=(const SelfType& other) const
     104             :   {
     105          30 :     return &mIter != &other.mIter || mIndex != other.mIndex;
     106             :   }
     107             : 
     108             : 
     109           6 :   SelfType End() const
     110             :   {
     111          12 :     SelfType end(mIter);
     112           6 :     end.mIndex = Length();
     113          12 :     return Move(end);
     114             :   }
     115             : 
     116          18 :   void* Context() const { return mIter.Context(); }
     117             : 
     118             : protected:
     119             :   const SelfType& Self() const
     120             :   {
     121             :     return *static_cast<const SelfType*>(this);
     122             :   }
     123          72 :   SelfType& Self() {
     124          72 :     return *static_cast<SelfType*>(this);
     125             :   }
     126             : 
     127             :   const IterType& mIter;
     128             : 
     129             :   uint32_t mIndex;
     130             : };
     131             : 
     132             : 
     133             : /*****************************************************************************
     134             :  * Property iteration
     135             :  *****************************************************************************/
     136             : 
     137           8 : class MOZ_STACK_CLASS PropertyIter
     138             :   : public BaseIter<PropertyIter, PropertyIterElem>
     139             : {
     140             :   friend class PropertyIterElem;
     141             :   friend class BaseIterElem<PropertyIterElem, PropertyIter>;
     142             : 
     143             : public:
     144           8 :   PropertyIter(JSContext* cx, JS::HandleObject object, void* context = nullptr)
     145           8 :     : BaseIter(cx, object, context)
     146           8 :     , mIds(cx, JS::IdVector(cx))
     147             :   {
     148           8 :     if (!JS_Enumerate(cx, object, &mIds)) {
     149           0 :       JS_ClearPendingException(cx);
     150             :     }
     151           8 :   }
     152             : 
     153             :   PropertyIter(const PropertyIter& other)
     154             :     : PropertyIter(other.mCx, other.mObject, other.mContext)
     155             :   {}
     156             : 
     157             :   PropertyIter& operator=(const PropertyIter& other)
     158             :   {
     159             :     MOZ_ASSERT(other.mObject == mObject);
     160             :     mCx = other.mCx;
     161             :     mContext = other.mContext;
     162             : 
     163             :     mIds.clear();
     164             :     if (!JS_Enumerate(mCx, mObject, &mIds)) {
     165             :       JS_ClearPendingException(mCx);
     166             :     }
     167             :     return *this;
     168             :   }
     169             : 
     170          54 :   int32_t Length() const
     171             :   {
     172          54 :     return mIds.length();
     173             :   }
     174             : 
     175             : protected:
     176             :   JS::Rooted<JS::IdVector> mIds;
     177             : };
     178             : 
     179          54 : class MOZ_STACK_CLASS PropertyIterElem
     180             :   : public BaseIterElem<PropertyIterElem, PropertyIter>
     181             : {
     182             :   friend class BaseIterElem<PropertyIterElem, PropertyIter>;
     183             : 
     184             : public:
     185          18 :   using BaseIterElem::BaseIterElem;
     186             : 
     187          36 :   PropertyIterElem(const PropertyIterElem& other)
     188          36 :     : BaseIterElem(other.mIter, other.mIndex)
     189          36 :   {}
     190             : 
     191          42 :   jsid Id()
     192             :   {
     193          42 :     MOZ_ASSERT(mIndex < mIter.mIds.length());
     194             : 
     195          42 :     return mIter.mIds[mIndex];
     196             :   }
     197             : 
     198          18 :   const nsAString& Name()
     199             :   {
     200          18 :     if(mName.isNothing()) {
     201          18 :       mName.emplace();
     202          18 :       mName.ref().init(mIter.mCx, Id());
     203             :     }
     204          18 :     return mName.ref();
     205             :   }
     206             : 
     207          24 :   JSContext* Cx() { return mIter.mCx; }
     208             : 
     209             : protected:
     210          24 :   bool GetValue(JS::MutableHandleValue value)
     211             :   {
     212          24 :     MOZ_ASSERT(mIndex < Length());
     213          48 :     JS::Rooted<jsid> id(mIter.mCx, Id());
     214             : 
     215          48 :     return JS_GetPropertyById(mIter.mCx, mIter.mObject, id, value);
     216             :   }
     217             : 
     218             : private:
     219             :   Maybe<nsAutoJSString> mName;
     220             : };
     221             : 
     222             : 
     223             : /*****************************************************************************
     224             :  * Array iteration
     225             :  *****************************************************************************/
     226             : 
     227             : class MOZ_STACK_CLASS ArrayIter
     228             :   : public BaseIter<ArrayIter, ArrayIterElem>
     229             : {
     230             :   friend class ArrayIterElem;
     231             :   friend class BaseIterElem<ArrayIterElem, ArrayIter>;
     232             : 
     233             : public:
     234             :   ArrayIter(JSContext* cx, JS::HandleObject object)
     235             :     : BaseIter(cx, object)
     236             :     , mLength(0)
     237             :   {
     238             :     bool isArray;
     239             :     if (!JS_IsArrayObject(cx, object, &isArray) || !isArray) {
     240             :       JS_ClearPendingException(cx);
     241             :       return;
     242             :     }
     243             : 
     244             :     if (!JS_GetArrayLength(cx, object, &mLength)) {
     245             :       JS_ClearPendingException(cx);
     246             :     }
     247             :   }
     248             : 
     249             :   uint32_t Length() const
     250             :   {
     251             :     return mLength;
     252             :   }
     253             : 
     254             : private:
     255             :   uint32_t mLength;
     256             : };
     257             : 
     258             : class MOZ_STACK_CLASS ArrayIterElem
     259             :   : public BaseIterElem<ArrayIterElem, ArrayIter>
     260             : {
     261             :   friend class BaseIterElem<ArrayIterElem, ArrayIter>;
     262             : 
     263             : public:
     264             :   using BaseIterElem::BaseIterElem;
     265             : 
     266             :   ArrayIterElem(const ArrayIterElem& other)
     267             :     : BaseIterElem(other.mIter, other.mIndex)
     268             :   {}
     269             : 
     270             : protected:
     271             :   bool
     272             :   GetValue(JS::MutableHandleValue value)
     273             :   {
     274             :     MOZ_ASSERT(mIndex < Length());
     275             :     return JS_GetElement(mIter.mCx, mIter.mObject, mIndex, value);
     276             :   }
     277             : };
     278             : 
     279             : }
     280             : 
     281             : #endif // AddonManagerStartup_inlines_h

Generated by: LCOV version 1.13