LCOV - code coverage report
Current view: top level - dom/bindings - IterableIterator.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 68 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 64 0.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             : /* vim:set ts=2 sw=2 sts=2 et cindent: */
       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             : /**
       8             :  * The IterableIterator class is used for WebIDL interfaces that have a
       9             :  * iterable<> member defined with two types (so a pair iterator). It handles
      10             :  * the ES6 Iterator-like functions that are generated for the iterable
      11             :  * interface.
      12             :  *
      13             :  * For iterable interfaces with a pair iterator, the implementation class will
      14             :  * need to implement these two functions:
      15             :  *
      16             :  * - size_t GetIterableLength()
      17             :  *   - Returns the number of elements available to iterate over
      18             :  * - [type] GetValueAtIndex(size_t index)
      19             :  *   - Returns the value at the requested index.
      20             :  * - [type] GetKeyAtIndex(size_t index)
      21             :  *   - Returns the key at the requested index
      22             :  *
      23             :  * Examples of iterable interface implementations can be found in the bindings
      24             :  * test directory.
      25             :  */
      26             : 
      27             : #ifndef mozilla_dom_IterableIterator_h
      28             : #define mozilla_dom_IterableIterator_h
      29             : 
      30             : #include "nsISupports.h"
      31             : #include "nsWrapperCache.h"
      32             : #include "nsPIDOMWindow.h"
      33             : #include "nsCOMPtr.h"
      34             : #include "mozilla/dom/ToJSValue.h"
      35             : #include "jswrapper.h"
      36             : #include "mozilla/dom/IterableIteratorBinding.h"
      37             : 
      38             : namespace mozilla {
      39             : namespace dom {
      40             : 
      41             : class IterableIteratorBase : public nsISupports
      42             : {
      43             : public:
      44             :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
      45           0 :   NS_DECL_CYCLE_COLLECTION_CLASS(IterableIteratorBase)
      46             :   typedef enum {
      47             :     Keys = 0,
      48             :     Values,
      49             :     Entries
      50             :   } IterableIteratorType;
      51             : 
      52           0 :   IterableIteratorBase() {}
      53             : 
      54             : protected:
      55           0 :   virtual ~IterableIteratorBase() {}
      56             :   virtual void UnlinkHelper() = 0;
      57             :   virtual void TraverseHelper(nsCycleCollectionTraversalCallback& cb) = 0;
      58             : };
      59             : 
      60             : template <typename T>
      61             : class IterableIterator final : public IterableIteratorBase
      62             : {
      63             : public:
      64             :   typedef bool (*WrapFunc)(JSContext* aCx,
      65             :                            IterableIterator<T>* aObject,
      66             :                            JS::Handle<JSObject*> aGivenProto,
      67             :                            JS::MutableHandle<JSObject*> aReflector);
      68             : 
      69           0 :   explicit IterableIterator(T* aIterableObj,
      70             :                             IterableIteratorType aIteratorType,
      71             :                             WrapFunc aWrapFunc)
      72             :     : mIterableObj(aIterableObj)
      73             :     , mIteratorType(aIteratorType)
      74             :     , mWrapFunc(aWrapFunc)
      75           0 :     , mIndex(0)
      76             :   {
      77           0 :     MOZ_ASSERT(mIterableObj);
      78           0 :     MOZ_ASSERT(mWrapFunc);
      79           0 :   }
      80             : 
      81             :   void
      82           0 :   Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
      83             :   {
      84           0 :     JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
      85           0 :     if (mIndex >= this->mIterableObj->GetIterableLength()) {
      86           0 :       DictReturn(aCx, aResult, true, value, aRv);
      87           0 :       return;
      88             :     }
      89           0 :     switch (mIteratorType) {
      90             :     case IterableIteratorType::Keys:
      91             :     {
      92           0 :       if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &value)) {
      93           0 :         aRv.Throw(NS_ERROR_FAILURE);
      94           0 :         return;
      95             :       }
      96           0 :       DictReturn(aCx, aResult, false, value, aRv);
      97           0 :       break;
      98             :     }
      99             :     case IterableIteratorType::Values:
     100             :     {
     101           0 :       if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
     102           0 :         aRv.Throw(NS_ERROR_FAILURE);
     103           0 :         return;
     104             :       }
     105           0 :       DictReturn(aCx, aResult, false, value, aRv);
     106           0 :       break;
     107             :     }
     108             :     case IterableIteratorType::Entries:
     109             :     {
     110           0 :       JS::Rooted<JS::Value> key(aCx);
     111           0 :       if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &key)) {
     112           0 :         aRv.Throw(NS_ERROR_FAILURE);
     113           0 :         return;
     114             :       }
     115           0 :       if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
     116           0 :         aRv.Throw(NS_ERROR_FAILURE);
     117           0 :         return;
     118             :       }
     119           0 :       KeyAndValueReturn(aCx, key, value, aResult, aRv);
     120           0 :       break;
     121             :     }
     122             :     default:
     123           0 :       MOZ_CRASH("Invalid iterator type!");
     124             :     }
     125           0 :     ++mIndex;
     126             :   }
     127             : 
     128             :   bool
     129           0 :   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
     130             :   {
     131           0 :     return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
     132             :   }
     133             : 
     134             : protected:
     135             :   static void
     136           0 :   DictReturn(JSContext* aCx, JS::MutableHandle<JSObject*> aResult,
     137             :              bool aDone, JS::Handle<JS::Value> aValue, ErrorResult& aRv)
     138             :   {
     139           0 :     RootedDictionary<IterableKeyOrValueResult> dict(aCx);
     140           0 :     dict.mDone = aDone;
     141           0 :     dict.mValue = aValue;
     142           0 :     JS::Rooted<JS::Value> dictValue(aCx);
     143           0 :     if (!ToJSValue(aCx, dict, &dictValue)) {
     144           0 :       aRv.Throw(NS_ERROR_FAILURE);
     145           0 :       return;
     146             :     }
     147           0 :     aResult.set(&dictValue.toObject());
     148             :   }
     149             : 
     150             :   static void
     151           0 :   KeyAndValueReturn(JSContext* aCx, JS::Handle<JS::Value> aKey,
     152             :                     JS::Handle<JS::Value> aValue,
     153             :                     JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
     154             :   {
     155           0 :     RootedDictionary<IterableKeyAndValueResult> dict(aCx);
     156           0 :     dict.mDone = false;
     157             :     // Dictionary values are a Sequence, which is a FallibleTArray, so we need
     158             :     // to check returns when appending.
     159           0 :     if (!dict.mValue.AppendElement(aKey, mozilla::fallible)) {
     160           0 :       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     161           0 :       return;
     162             :     }
     163           0 :     if (!dict.mValue.AppendElement(aValue, mozilla::fallible)) {
     164           0 :       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     165           0 :       return;
     166             :     }
     167           0 :     JS::Rooted<JS::Value> dictValue(aCx);
     168           0 :     if (!ToJSValue(aCx, dict, &dictValue)) {
     169           0 :       aRv.Throw(NS_ERROR_FAILURE);
     170           0 :       return;
     171             :     }
     172           0 :     aResult.set(&dictValue.toObject());
     173             :   }
     174             : 
     175             : protected:
     176           0 :   virtual ~IterableIterator() {}
     177             : 
     178             :   // Since we're templated on a binding, we need to possibly CC it, but can't do
     179             :   // that through macros. So it happens here.
     180           0 :   virtual void UnlinkHelper() final
     181             :   {
     182           0 :     mIterableObj = nullptr;
     183           0 :   }
     184             : 
     185           0 :   virtual void TraverseHelper(nsCycleCollectionTraversalCallback& cb) override
     186             :   {
     187           0 :     IterableIterator<T>* tmp = this;
     188           0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIterableObj);
     189           0 :   }
     190             : 
     191             :   // Binding Implementation object that we're iterating over.
     192             :   RefPtr<T> mIterableObj;
     193             :   // Tells whether this is a key, value, or entries iterator.
     194             :   IterableIteratorType mIteratorType;
     195             :   // Function pointer to binding-type-specific Wrap() call for this iterator.
     196             :   WrapFunc mWrapFunc;
     197             :   // Current index of iteration.
     198             :   uint32_t mIndex;
     199             : };
     200             : 
     201             : } // namespace dom
     202             : } // namespace mozilla
     203             : 
     204             : #endif // mozilla_dom_IterableIterator_h

Generated by: LCOV version 1.13