LCOV - code coverage report
Current view: top level - xpcom/ds - nsInterfaceHashtable.h (source / functions) Hit Total Coverage
Test: output.info Lines: 40 47 85.1 %
Date: 2017-07-14 16:53:18 Functions: 46 144 31.9 %
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             : #ifndef nsInterfaceHashtable_h__
       8             : #define nsInterfaceHashtable_h__
       9             : 
      10             : #include "nsBaseHashtable.h"
      11             : #include "nsHashKeys.h"
      12             : #include "nsCOMPtr.h"
      13             : 
      14             : /**
      15             :  * templated hashtable class maps keys to interface pointers.
      16             :  * See nsBaseHashtable for complete declaration.
      17             :  * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
      18             :  *   for a complete specification.
      19             :  * @param Interface the interface-type being wrapped
      20             :  * @see nsDataHashtable, nsClassHashtable
      21             :  */
      22             : template<class KeyClass, class Interface>
      23        1164 : class nsInterfaceHashtable
      24             :   : public nsBaseHashtable<KeyClass, nsCOMPtr<Interface>, Interface*>
      25             : {
      26             : public:
      27             :   typedef typename KeyClass::KeyType KeyType;
      28             :   typedef Interface* UserDataType;
      29             :   typedef nsBaseHashtable<KeyClass, nsCOMPtr<Interface>, Interface*> base_type;
      30             : 
      31        1427 :   nsInterfaceHashtable() {}
      32          17 :   explicit nsInterfaceHashtable(uint32_t aInitLength)
      33          17 :     : nsBaseHashtable<KeyClass, nsCOMPtr<Interface>, Interface*>(aInitLength)
      34             :   {
      35          17 :   }
      36             : 
      37             :   /**
      38             :    * @copydoc nsBaseHashtable::Get
      39             :    * @param aData This is an XPCOM getter, so aData is already_addrefed.
      40             :    *   If the key doesn't exist, aData will be set to nullptr.
      41             :    */
      42             :   bool Get(KeyType aKey, UserDataType* aData) const;
      43             : 
      44             :   /**
      45             :    * @copydoc nsBaseHashtable::Get
      46             :    */
      47             :   already_AddRefed<Interface> Get(KeyType aKey) const;
      48             : 
      49             :   /**
      50             :    * Gets a weak reference to the hashtable entry.
      51             :    * @param aFound If not nullptr, will be set to true if the entry is found,
      52             :    *               to false otherwise.
      53             :    * @return The entry, or nullptr if not found. Do not release this pointer!
      54             :    */
      55             :   Interface* GetWeak(KeyType aKey, bool* aFound = nullptr) const;
      56             : 
      57             :   /**
      58             :    * Remove the entry associated with aKey (if any), optionally _moving_ its
      59             :    * current value into *aData, thereby avoiding calls to AddRef and Release.
      60             :    * Return true if found.
      61             :    * @param aKey the key to remove from the hashtable
      62             :    * @param aData where to move the value (if non-null).  If an entry is not
      63             :    *              found it will be set to nullptr.
      64             :    * @return true if an entry for aKey was found (and removed)
      65             :    */
      66             :   inline bool Remove(KeyType aKey, Interface** aData = nullptr);
      67             : };
      68             : 
      69             : template<typename K, typename T>
      70             : inline void
      71           0 : ImplCycleCollectionUnlink(nsInterfaceHashtable<K, T>& aField)
      72             : {
      73           0 :   aField.Clear();
      74           0 : }
      75             : 
      76             : template<typename K, typename T>
      77             : inline void
      78           1 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
      79             :                             const nsInterfaceHashtable<K, T>& aField,
      80             :                             const char* aName,
      81             :                             uint32_t aFlags = 0)
      82             : {
      83           2 :   for (auto iter = aField.ConstIter(); !iter.Done(); iter.Next()) {
      84           1 :     CycleCollectionNoteChild(aCallback, iter.UserData(), aName, aFlags);
      85             :   }
      86           1 : }
      87             : 
      88             : //
      89             : // nsInterfaceHashtable definitions
      90             : //
      91             : 
      92             : template<class KeyClass, class Interface>
      93             : bool
      94         574 : nsInterfaceHashtable<KeyClass, Interface>::Get(KeyType aKey,
      95             :                                                UserDataType* aInterface) const
      96             : {
      97         574 :   typename base_type::EntryType* ent = this->GetEntry(aKey);
      98             : 
      99         574 :   if (ent) {
     100         341 :     if (aInterface) {
     101         341 :       *aInterface = ent->mData;
     102             : 
     103         341 :       NS_IF_ADDREF(*aInterface);
     104             :     }
     105             : 
     106         341 :     return true;
     107             :   }
     108             : 
     109             :   // if the key doesn't exist, set *aInterface to null
     110             :   // so that it is a valid XPCOM getter
     111         233 :   if (aInterface) {
     112         233 :     *aInterface = nullptr;
     113             :   }
     114             : 
     115         233 :   return false;
     116             : }
     117             : 
     118             : template<class KeyClass, class Interface>
     119             : already_AddRefed<Interface>
     120         982 : nsInterfaceHashtable<KeyClass, Interface>::Get(KeyType aKey) const
     121             : {
     122         982 :   typename base_type::EntryType* ent = this->GetEntry(aKey);
     123         982 :   if (!ent) {
     124          64 :     return nullptr;
     125             :   }
     126             : 
     127        1836 :   nsCOMPtr<Interface> copy = ent->mData;
     128         918 :   return copy.forget();
     129             : }
     130             : 
     131             : template<class KeyClass, class Interface>
     132             : Interface*
     133         657 : nsInterfaceHashtable<KeyClass, Interface>::GetWeak(KeyType aKey,
     134             :                                                    bool* aFound) const
     135             : {
     136         657 :   typename base_type::EntryType* ent = this->GetEntry(aKey);
     137             : 
     138         657 :   if (ent) {
     139         242 :     if (aFound) {
     140           0 :       *aFound = true;
     141             :     }
     142             : 
     143         242 :     return ent->mData;
     144             :   }
     145             : 
     146             :   // Key does not exist, return nullptr and set aFound to false
     147         415 :   if (aFound) {
     148           0 :     *aFound = false;
     149             :   }
     150         415 :   return nullptr;
     151             : }
     152             : 
     153             : template<class KeyClass, class Interface>
     154             : bool
     155          76 : nsInterfaceHashtable<KeyClass, Interface>::Remove(KeyType aKey,
     156             :                                                   Interface** aData)
     157             : {
     158          76 :   typename base_type::EntryType* ent = this->GetEntry(aKey);
     159             : 
     160          76 :   if (ent) {
     161          65 :     if (aData) {
     162           0 :       ent->mData.forget(aData);
     163             :     }
     164          65 :     this->RemoveEntry(ent);
     165          65 :     return true;
     166             :   }
     167             : 
     168          11 :   if (aData) {
     169           0 :     *aData = nullptr;
     170             :   }
     171          11 :   return false;
     172             : }
     173             : 
     174             : #endif // nsInterfaceHashtable_h__

Generated by: LCOV version 1.13