LCOV - code coverage report
Current view: top level - xpcom/ds - nsHashPropertyBag.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 51 123 41.5 %
Date: 2017-07-14 16:53:18 Functions: 15 48 31.2 %
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 "nsHashPropertyBag.h"
       8             : #include "nsArray.h"
       9             : #include "nsArrayEnumerator.h"
      10             : #include "nsIVariant.h"
      11             : #include "nsIProperty.h"
      12             : #include "nsThreadUtils.h"
      13             : #include "nsVariant.h"
      14             : #include "mozilla/Attributes.h"
      15             : #include "mozilla/Move.h"
      16             : 
      17             : /*
      18             :  * nsHashPropertyBagBase implementation.
      19             :  */
      20             : 
      21             : NS_IMETHODIMP
      22           0 : nsHashPropertyBagBase::HasKey(const nsAString& aName, bool* aResult)
      23             : {
      24           0 :   *aResult = mPropertyHash.Get(aName, nullptr);
      25           0 :   return NS_OK;
      26             : }
      27             : 
      28             : NS_IMETHODIMP
      29           1 : nsHashPropertyBagBase::Get(const nsAString& aName, nsIVariant** aResult)
      30             : {
      31           1 :   if (!mPropertyHash.Get(aName, aResult)) {
      32           0 :     *aResult = nullptr;
      33             :   }
      34             : 
      35           1 :   return NS_OK;
      36             : }
      37             : 
      38             : NS_IMETHODIMP
      39          40 : nsHashPropertyBagBase::GetProperty(const nsAString& aName, nsIVariant** aResult)
      40             : {
      41          40 :   bool isFound = mPropertyHash.Get(aName, aResult);
      42          40 :   if (!isFound) {
      43           7 :     return NS_ERROR_FAILURE;
      44             :   }
      45             : 
      46          33 :   return NS_OK;
      47             : }
      48             : 
      49             : NS_IMETHODIMP
      50          43 : nsHashPropertyBagBase::SetProperty(const nsAString& aName, nsIVariant* aValue)
      51             : {
      52          43 :   if (NS_WARN_IF(!aValue)) {
      53           0 :     return NS_ERROR_INVALID_ARG;
      54             :   }
      55             : 
      56          43 :   mPropertyHash.Put(aName, aValue);
      57             : 
      58          43 :   return NS_OK;
      59             : }
      60             : 
      61             : NS_IMETHODIMP
      62           0 : nsHashPropertyBagBase::DeleteProperty(const nsAString& aName)
      63             : {
      64           0 :   return mPropertyHash.Remove(aName) ? NS_OK : NS_ERROR_FAILURE;
      65             : }
      66             : 
      67             : 
      68             : //
      69             : // nsSimpleProperty class and impl; used for GetEnumerator
      70             : //
      71             : 
      72             : class nsSimpleProperty final : public nsIProperty
      73             : {
      74           0 :   ~nsSimpleProperty() {}
      75             : 
      76             : public:
      77           0 :   nsSimpleProperty(const nsAString& aName, nsIVariant* aValue)
      78           0 :     : mName(aName)
      79           0 :     , mValue(aValue)
      80             :   {
      81           0 :   }
      82             : 
      83             :   NS_DECL_ISUPPORTS
      84             :   NS_DECL_NSIPROPERTY
      85             : protected:
      86             :   nsString mName;
      87             :   nsCOMPtr<nsIVariant> mValue;
      88             : };
      89             : 
      90           0 : NS_IMPL_ISUPPORTS(nsSimpleProperty, nsIProperty)
      91             : 
      92             : NS_IMETHODIMP
      93           0 : nsSimpleProperty::GetName(nsAString& aName)
      94             : {
      95           0 :   aName.Assign(mName);
      96           0 :   return NS_OK;
      97             : }
      98             : 
      99             : NS_IMETHODIMP
     100           0 : nsSimpleProperty::GetValue(nsIVariant** aValue)
     101             : {
     102           0 :   NS_IF_ADDREF(*aValue = mValue);
     103           0 :   return NS_OK;
     104             : }
     105             : 
     106             : // end nsSimpleProperty
     107             : 
     108             : NS_IMETHODIMP
     109           0 : nsHashPropertyBagBase::GetEnumerator(nsISimpleEnumerator** aResult)
     110             : {
     111           0 :   nsCOMPtr<nsIMutableArray> propertyArray = nsArray::Create();
     112           0 :   if (!propertyArray) {
     113           0 :     return NS_ERROR_OUT_OF_MEMORY;
     114             :   }
     115             : 
     116           0 :   for (auto iter = mPropertyHash.Iter(); !iter.Done(); iter.Next()) {
     117           0 :     const nsAString& key = iter.Key();
     118           0 :     nsIVariant* data = iter.UserData();
     119           0 :     nsSimpleProperty* sprop = new nsSimpleProperty(key, data);
     120           0 :     propertyArray->AppendElement(sprop, false);
     121             :   }
     122             : 
     123           0 :   return NS_NewArrayEnumerator(aResult, propertyArray);
     124             : }
     125             : 
     126             : #define IMPL_GETSETPROPERTY_AS(Name, Type) \
     127             : NS_IMETHODIMP \
     128             : nsHashPropertyBagBase::GetPropertyAs ## Name (const nsAString & prop, Type *_retval) \
     129             : { \
     130             :     nsIVariant* v = mPropertyHash.GetWeak(prop); \
     131             :     if (!v) \
     132             :         return NS_ERROR_NOT_AVAILABLE; \
     133             :     return v->GetAs ## Name(_retval); \
     134             : } \
     135             : \
     136             : NS_IMETHODIMP \
     137             : nsHashPropertyBagBase::SetPropertyAs ## Name (const nsAString & prop, Type value) \
     138             : { \
     139             :     nsCOMPtr<nsIWritableVariant> var = new nsVariant(); \
     140             :     var->SetAs ## Name(value); \
     141             :     return SetProperty(prop, var); \
     142             : }
     143             : 
     144          22 : IMPL_GETSETPROPERTY_AS(Int32, int32_t)
     145           2 : IMPL_GETSETPROPERTY_AS(Uint32, uint32_t)
     146           0 : IMPL_GETSETPROPERTY_AS(Int64, int64_t)
     147           2 : IMPL_GETSETPROPERTY_AS(Uint64, uint64_t)
     148           0 : IMPL_GETSETPROPERTY_AS(Double, double)
     149          34 : IMPL_GETSETPROPERTY_AS(Bool, bool)
     150             : 
     151             : 
     152             : NS_IMETHODIMP
     153           0 : nsHashPropertyBagBase::GetPropertyAsAString(const nsAString& aProp,
     154             :                                             nsAString& aResult)
     155             : {
     156           0 :   nsIVariant* v = mPropertyHash.GetWeak(aProp);
     157           0 :   if (!v) {
     158           0 :     return NS_ERROR_NOT_AVAILABLE;
     159             :   }
     160           0 :   return v->GetAsAString(aResult);
     161             : }
     162             : 
     163             : NS_IMETHODIMP
     164          25 : nsHashPropertyBagBase::GetPropertyAsACString(const nsAString& aProp,
     165             :                                              nsACString& aResult)
     166             : {
     167          25 :   nsIVariant* v = mPropertyHash.GetWeak(aProp);
     168          25 :   if (!v) {
     169          25 :     return NS_ERROR_NOT_AVAILABLE;
     170             :   }
     171           0 :   return v->GetAsACString(aResult);
     172             : }
     173             : 
     174             : NS_IMETHODIMP
     175           0 : nsHashPropertyBagBase::GetPropertyAsAUTF8String(const nsAString& aProp,
     176             :                                                 nsACString& aResult)
     177             : {
     178           0 :   nsIVariant* v = mPropertyHash.GetWeak(aProp);
     179           0 :   if (!v) {
     180           0 :     return NS_ERROR_NOT_AVAILABLE;
     181             :   }
     182           0 :   return v->GetAsAUTF8String(aResult);
     183             : }
     184             : 
     185             : NS_IMETHODIMP
     186          28 : nsHashPropertyBagBase::GetPropertyAsInterface(const nsAString& aProp,
     187             :                                               const nsIID& aIID,
     188             :                                               void** aResult)
     189             : {
     190          28 :   nsIVariant* v = mPropertyHash.GetWeak(aProp);
     191          28 :   if (!v) {
     192          25 :     return NS_ERROR_NOT_AVAILABLE;
     193             :   }
     194           6 :   nsCOMPtr<nsISupports> val;
     195           3 :   nsresult rv = v->GetAsISupports(getter_AddRefs(val));
     196           3 :   if (NS_FAILED(rv)) {
     197           0 :     return rv;
     198             :   }
     199           3 :   if (!val) {
     200             :     // We have a value, but it's null
     201           2 :     *aResult = nullptr;
     202           2 :     return NS_OK;
     203             :   }
     204           1 :   return val->QueryInterface(aIID, aResult);
     205             : }
     206             : 
     207             : NS_IMETHODIMP
     208           0 : nsHashPropertyBagBase::SetPropertyAsAString(const nsAString& aProp,
     209             :                                             const nsAString& aValue)
     210             : {
     211           0 :   nsCOMPtr<nsIWritableVariant> var = new nsVariant();
     212           0 :   var->SetAsAString(aValue);
     213           0 :   return SetProperty(aProp, var);
     214             : }
     215             : 
     216             : NS_IMETHODIMP
     217           5 : nsHashPropertyBagBase::SetPropertyAsACString(const nsAString& aProp,
     218             :                                              const nsACString& aValue)
     219             : {
     220          10 :   nsCOMPtr<nsIWritableVariant> var = new nsVariant();
     221           5 :   var->SetAsACString(aValue);
     222          10 :   return SetProperty(aProp, var);
     223             : }
     224             : 
     225             : NS_IMETHODIMP
     226           0 : nsHashPropertyBagBase::SetPropertyAsAUTF8String(const nsAString& aProp,
     227             :                                                 const nsACString& aValue)
     228             : {
     229           0 :   nsCOMPtr<nsIWritableVariant> var = new nsVariant();
     230           0 :   var->SetAsAUTF8String(aValue);
     231           0 :   return SetProperty(aProp, var);
     232             : }
     233             : 
     234             : NS_IMETHODIMP
     235           8 : nsHashPropertyBagBase::SetPropertyAsInterface(const nsAString& aProp,
     236             :                                               nsISupports* aValue)
     237             : {
     238          16 :   nsCOMPtr<nsIWritableVariant> var = new nsVariant();
     239           8 :   var->SetAsISupports(aValue);
     240          16 :   return SetProperty(aProp, var);
     241             : }
     242             : 
     243             : 
     244             : /*
     245             :  * nsHashPropertyBag implementation.
     246             :  */
     247             : 
     248        9286 : NS_IMPL_ADDREF(nsHashPropertyBag)
     249        9214 : NS_IMPL_RELEASE(nsHashPropertyBag)
     250             : 
     251        1699 : NS_INTERFACE_MAP_BEGIN(nsHashPropertyBag)
     252        1699 :   NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag)
     253        1699 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIPropertyBag, nsIWritablePropertyBag)
     254        1699 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWritablePropertyBag)
     255        1596 :   NS_INTERFACE_MAP_ENTRY(nsIPropertyBag2)
     256        1538 :   NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag2)
     257        1529 : NS_INTERFACE_MAP_END
     258             : 
     259             : /*
     260             :  * We need to ensure that the hashtable is destroyed on the main thread, as
     261             :  * the nsIVariant values are main-thread only objects.
     262             :  */
     263           0 : class ProxyHashtableDestructor final : public mozilla::Runnable
     264             : {
     265             : public:
     266             :   using HashtableType = nsInterfaceHashtable<nsStringHashKey, nsIVariant>;
     267           0 :   explicit ProxyHashtableDestructor(HashtableType&& aTable)
     268           0 :     : mozilla::Runnable("ProxyHashtableDestructor")
     269           0 :     , mPropertyHash(mozilla::Move(aTable))
     270           0 :   {}
     271             : 
     272             :   NS_IMETHODIMP
     273           0 :   Run()
     274             :   {
     275           0 :     MOZ_ASSERT(NS_IsMainThread());
     276           0 :     HashtableType table(mozilla::Move(mPropertyHash));
     277           0 :     return NS_OK;
     278             :   }
     279             : 
     280             : private:
     281             :   HashtableType mPropertyHash;
     282             : };
     283             : 
     284        2312 : nsHashPropertyBag::~nsHashPropertyBag()
     285             : {
     286        1156 :   if (!NS_IsMainThread()) {
     287             :     RefPtr<ProxyHashtableDestructor> runnable =
     288           0 :       new ProxyHashtableDestructor(mozilla::Move(mPropertyHash));
     289           0 :     MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
     290             :   }
     291        1156 : }
     292             : 
     293             : /*
     294             :  * nsHashPropertyBagCC implementation.
     295             :  */
     296             : 
     297           0 : NS_IMPL_CYCLE_COLLECTION(nsHashPropertyBagCC, mPropertyHash)
     298             : 
     299           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHashPropertyBagCC)
     300           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHashPropertyBagCC)
     301             : 
     302           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHashPropertyBagCC)
     303           0 :   NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag)
     304           0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIPropertyBag, nsIWritablePropertyBag)
     305           0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWritablePropertyBag)
     306           0 :   NS_INTERFACE_MAP_ENTRY(nsIPropertyBag2)
     307           0 :   NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag2)
     308           0 : NS_INTERFACE_MAP_END

Generated by: LCOV version 1.13