1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/ds/nsHashPropertyBag.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,257 @@ 1.4 +/* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* vim:set ts=4 sw=4 sts=4: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "nsHashPropertyBag.h" 1.11 +#include "nsArray.h" 1.12 +#include "nsArrayEnumerator.h" 1.13 +#include "nsIVariant.h" 1.14 +#include "nsIProperty.h" 1.15 +#include "nsVariant.h" 1.16 +#include "mozilla/Attributes.h" 1.17 + 1.18 +nsresult 1.19 +NS_NewHashPropertyBag(nsIWritablePropertyBag* *_retval) 1.20 +{ 1.21 + nsRefPtr<nsHashPropertyBag> hpb = new nsHashPropertyBag(); 1.22 + hpb.forget(_retval); 1.23 + return NS_OK; 1.24 +} 1.25 + 1.26 +/* 1.27 + * nsHashPropertyBag impl 1.28 + */ 1.29 + 1.30 +NS_IMPL_ADDREF(nsHashPropertyBag) 1.31 +NS_IMPL_RELEASE(nsHashPropertyBag) 1.32 +NS_INTERFACE_MAP_BEGIN(nsHashPropertyBag) 1.33 + NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag) 1.34 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIPropertyBag, nsIWritablePropertyBag) 1.35 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWritablePropertyBag) 1.36 + NS_INTERFACE_MAP_ENTRY(nsIPropertyBag2) 1.37 + NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag2) 1.38 +NS_INTERFACE_MAP_END 1.39 + 1.40 +NS_IMETHODIMP 1.41 +nsHashPropertyBag::HasKey(const nsAString& name, bool *aResult) 1.42 +{ 1.43 + *aResult = mPropertyHash.Get(name, nullptr); 1.44 + 1.45 + return NS_OK; 1.46 +} 1.47 + 1.48 +NS_IMETHODIMP 1.49 +nsHashPropertyBag::Get(const nsAString& name, nsIVariant* *_retval) 1.50 +{ 1.51 + if (!mPropertyHash.Get(name, _retval)) 1.52 + *_retval = nullptr; 1.53 + 1.54 + return NS_OK; 1.55 +} 1.56 + 1.57 +NS_IMETHODIMP 1.58 +nsHashPropertyBag::GetProperty(const nsAString& name, nsIVariant* *_retval) 1.59 +{ 1.60 + bool isFound = mPropertyHash.Get(name, _retval); 1.61 + if (!isFound) 1.62 + return NS_ERROR_FAILURE; 1.63 + 1.64 + return NS_OK; 1.65 +} 1.66 + 1.67 +NS_IMETHODIMP 1.68 +nsHashPropertyBag::SetProperty(const nsAString& name, nsIVariant *value) 1.69 +{ 1.70 + if (NS_WARN_IF(!value)) 1.71 + return NS_ERROR_INVALID_ARG; 1.72 + 1.73 + mPropertyHash.Put(name, value); 1.74 + 1.75 + return NS_OK; 1.76 +} 1.77 + 1.78 +NS_IMETHODIMP 1.79 +nsHashPropertyBag::DeleteProperty(const nsAString& name) 1.80 +{ 1.81 + // is it too much to ask for ns*Hashtable to return 1.82 + // a boolean indicating whether RemoveEntry succeeded 1.83 + // or not?!?! 1.84 + bool isFound = mPropertyHash.Get(name, nullptr); 1.85 + if (!isFound) 1.86 + return NS_ERROR_FAILURE; 1.87 + 1.88 + // then from the hash 1.89 + mPropertyHash.Remove(name); 1.90 + 1.91 + return NS_OK; 1.92 +} 1.93 + 1.94 + 1.95 +// 1.96 +// nsSimpleProperty class and impl; used for GetEnumerator 1.97 +// 1.98 + 1.99 +class nsSimpleProperty MOZ_FINAL : public nsIProperty { 1.100 +public: 1.101 + nsSimpleProperty(const nsAString& aName, nsIVariant* aValue) 1.102 + : mName(aName), mValue(aValue) 1.103 + { 1.104 + } 1.105 + 1.106 + NS_DECL_ISUPPORTS 1.107 + NS_DECL_NSIPROPERTY 1.108 +protected: 1.109 + nsString mName; 1.110 + nsCOMPtr<nsIVariant> mValue; 1.111 +}; 1.112 + 1.113 +NS_IMPL_ISUPPORTS(nsSimpleProperty, nsIProperty) 1.114 + 1.115 +NS_IMETHODIMP 1.116 +nsSimpleProperty::GetName(nsAString& aName) 1.117 +{ 1.118 + aName.Assign(mName); 1.119 + return NS_OK; 1.120 +} 1.121 + 1.122 +NS_IMETHODIMP 1.123 +nsSimpleProperty::GetValue(nsIVariant* *aValue) 1.124 +{ 1.125 + NS_IF_ADDREF(*aValue = mValue); 1.126 + return NS_OK; 1.127 +} 1.128 + 1.129 +// end nsSimpleProperty 1.130 + 1.131 +static PLDHashOperator 1.132 +PropertyHashToArrayFunc (const nsAString &aKey, 1.133 + nsIVariant* aData, 1.134 + void *userArg) 1.135 +{ 1.136 + nsIMutableArray *propertyArray = 1.137 + static_cast<nsIMutableArray *>(userArg); 1.138 + nsSimpleProperty *sprop = new nsSimpleProperty(aKey, aData); 1.139 + propertyArray->AppendElement(sprop, false); 1.140 + return PL_DHASH_NEXT; 1.141 +} 1.142 + 1.143 + 1.144 +NS_IMETHODIMP 1.145 +nsHashPropertyBag::GetEnumerator(nsISimpleEnumerator* *_retval) 1.146 +{ 1.147 + nsCOMPtr<nsIMutableArray> propertyArray = nsArray::Create(); 1.148 + if (!propertyArray) 1.149 + return NS_ERROR_OUT_OF_MEMORY; 1.150 + 1.151 + mPropertyHash.EnumerateRead(PropertyHashToArrayFunc, propertyArray.get()); 1.152 + 1.153 + return NS_NewArrayEnumerator(_retval, propertyArray); 1.154 +} 1.155 + 1.156 +#define IMPL_GETSETPROPERTY_AS(Name, Type) \ 1.157 +NS_IMETHODIMP \ 1.158 +nsHashPropertyBag::GetPropertyAs ## Name (const nsAString & prop, Type *_retval) \ 1.159 +{ \ 1.160 + nsIVariant* v = mPropertyHash.GetWeak(prop); \ 1.161 + if (!v) \ 1.162 + return NS_ERROR_NOT_AVAILABLE; \ 1.163 + return v->GetAs ## Name(_retval); \ 1.164 +} \ 1.165 +\ 1.166 +NS_IMETHODIMP \ 1.167 +nsHashPropertyBag::SetPropertyAs ## Name (const nsAString & prop, Type value) \ 1.168 +{ \ 1.169 + nsCOMPtr<nsIWritableVariant> var = new nsVariant(); \ 1.170 + var->SetAs ## Name(value); \ 1.171 + return SetProperty(prop, var); \ 1.172 +} 1.173 + 1.174 +IMPL_GETSETPROPERTY_AS(Int32, int32_t) 1.175 +IMPL_GETSETPROPERTY_AS(Uint32, uint32_t) 1.176 +IMPL_GETSETPROPERTY_AS(Int64, int64_t) 1.177 +IMPL_GETSETPROPERTY_AS(Uint64, uint64_t) 1.178 +IMPL_GETSETPROPERTY_AS(Double, double) 1.179 +IMPL_GETSETPROPERTY_AS(Bool, bool) 1.180 + 1.181 + 1.182 +NS_IMETHODIMP 1.183 +nsHashPropertyBag::GetPropertyAsAString(const nsAString & prop, nsAString & _retval) 1.184 +{ 1.185 + nsIVariant* v = mPropertyHash.GetWeak(prop); 1.186 + if (!v) 1.187 + return NS_ERROR_NOT_AVAILABLE; 1.188 + return v->GetAsAString(_retval); 1.189 +} 1.190 + 1.191 +NS_IMETHODIMP 1.192 +nsHashPropertyBag::GetPropertyAsACString(const nsAString & prop, nsACString & _retval) 1.193 +{ 1.194 + nsIVariant* v = mPropertyHash.GetWeak(prop); 1.195 + if (!v) 1.196 + return NS_ERROR_NOT_AVAILABLE; 1.197 + return v->GetAsACString(_retval); 1.198 +} 1.199 + 1.200 +NS_IMETHODIMP 1.201 +nsHashPropertyBag::GetPropertyAsAUTF8String(const nsAString & prop, nsACString & _retval) 1.202 +{ 1.203 + nsIVariant* v = mPropertyHash.GetWeak(prop); 1.204 + if (!v) 1.205 + return NS_ERROR_NOT_AVAILABLE; 1.206 + return v->GetAsAUTF8String(_retval); 1.207 +} 1.208 + 1.209 +NS_IMETHODIMP 1.210 +nsHashPropertyBag::GetPropertyAsInterface(const nsAString & prop, 1.211 + const nsIID & aIID, 1.212 + void** _retval) 1.213 +{ 1.214 + nsIVariant* v = mPropertyHash.GetWeak(prop); 1.215 + if (!v) 1.216 + return NS_ERROR_NOT_AVAILABLE; 1.217 + nsCOMPtr<nsISupports> val; 1.218 + nsresult rv = v->GetAsISupports(getter_AddRefs(val)); 1.219 + if (NS_FAILED(rv)) 1.220 + return rv; 1.221 + if (!val) { 1.222 + // We have a value, but it's null 1.223 + *_retval = nullptr; 1.224 + return NS_OK; 1.225 + } 1.226 + return val->QueryInterface(aIID, _retval); 1.227 +} 1.228 + 1.229 +NS_IMETHODIMP 1.230 +nsHashPropertyBag::SetPropertyAsAString(const nsAString & prop, const nsAString & value) 1.231 +{ 1.232 + nsCOMPtr<nsIWritableVariant> var = new nsVariant(); 1.233 + var->SetAsAString(value); 1.234 + return SetProperty(prop, var); 1.235 +} 1.236 + 1.237 +NS_IMETHODIMP 1.238 +nsHashPropertyBag::SetPropertyAsACString(const nsAString & prop, const nsACString & value) 1.239 +{ 1.240 + nsCOMPtr<nsIWritableVariant> var = new nsVariant(); 1.241 + var->SetAsACString(value); 1.242 + return SetProperty(prop, var); 1.243 +} 1.244 + 1.245 +NS_IMETHODIMP 1.246 +nsHashPropertyBag::SetPropertyAsAUTF8String(const nsAString & prop, const nsACString & value) 1.247 +{ 1.248 + nsCOMPtr<nsIWritableVariant> var = new nsVariant(); 1.249 + var->SetAsAUTF8String(value); 1.250 + return SetProperty(prop, var); 1.251 +} 1.252 + 1.253 +NS_IMETHODIMP 1.254 +nsHashPropertyBag::SetPropertyAsInterface(const nsAString & prop, nsISupports* value) 1.255 +{ 1.256 + nsCOMPtr<nsIWritableVariant> var = new nsVariant(); 1.257 + var->SetAsISupports(value); 1.258 + return SetProperty(prop, var); 1.259 +} 1.260 +