1 /* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:set ts=4 sw=4 sts=4: */
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/. */
7 #include "nsHashPropertyBag.h"
9 #include "nsArrayEnumerator.h"
10 #include "nsComponentManagerUtils.h"
11 #include "nsIVariant.h"
12 #include "nsIProperty.h"
13 #include "nsVariant.h"
14 #include "mozilla/Attributes.h"
17 NS_NewHashPropertyBag(nsIWritablePropertyBag
* *_retval
)
19 nsHashPropertyBag
*hpb
= new nsHashPropertyBag();
21 return NS_ERROR_OUT_OF_MEMORY
;
25 nsresult rv
= hpb
->Init();
36 * nsHashPropertyBag impl
39 NS_IMPL_THREADSAFE_ADDREF(nsHashPropertyBag
)
40 NS_IMPL_THREADSAFE_RELEASE(nsHashPropertyBag
)
41 NS_INTERFACE_MAP_BEGIN(nsHashPropertyBag
)
42 NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag
)
43 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIPropertyBag
, nsIWritablePropertyBag
)
44 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIWritablePropertyBag
)
45 NS_INTERFACE_MAP_ENTRY(nsIPropertyBag2
)
46 NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag2
)
50 nsHashPropertyBag::Init()
57 nsHashPropertyBag::HasKey(const nsAString
& name
, bool *aResult
)
59 *aResult
= mPropertyHash
.Get(name
, nullptr);
65 nsHashPropertyBag::Get(const nsAString
& name
, nsIVariant
* *_retval
)
67 if (!mPropertyHash
.Get(name
, _retval
))
74 nsHashPropertyBag::GetProperty(const nsAString
& name
, nsIVariant
* *_retval
)
76 bool isFound
= mPropertyHash
.Get(name
, _retval
);
78 return NS_ERROR_FAILURE
;
84 nsHashPropertyBag::SetProperty(const nsAString
& name
, nsIVariant
*value
)
86 NS_ENSURE_ARG_POINTER(value
);
88 mPropertyHash
.Put(name
, value
);
94 nsHashPropertyBag::DeleteProperty(const nsAString
& name
)
96 // is it too much to ask for ns*Hashtable to return
97 // a boolean indicating whether RemoveEntry succeeded
99 bool isFound
= mPropertyHash
.Get(name
, nullptr);
101 return NS_ERROR_FAILURE
;
103 // then from the hash
104 mPropertyHash
.Remove(name
);
111 // nsSimpleProperty class and impl; used for GetEnumerator
114 class nsSimpleProperty MOZ_FINAL
: public nsIProperty
{
116 nsSimpleProperty(const nsAString
& aName
, nsIVariant
* aValue
)
117 : mName(aName
), mValue(aValue
)
125 nsCOMPtr
<nsIVariant
> mValue
;
128 NS_IMPL_ISUPPORTS1(nsSimpleProperty
, nsIProperty
)
131 nsSimpleProperty::GetName(nsAString
& aName
)
138 nsSimpleProperty::GetValue(nsIVariant
* *aValue
)
140 NS_IF_ADDREF(*aValue
= mValue
);
144 // end nsSimpleProperty
146 static PLDHashOperator
147 PropertyHashToArrayFunc (const nsAString
&aKey
,
151 nsIMutableArray
*propertyArray
=
152 static_cast<nsIMutableArray
*>(userArg
);
153 nsSimpleProperty
*sprop
= new nsSimpleProperty(aKey
, aData
);
154 propertyArray
->AppendElement(sprop
, false);
155 return PL_DHASH_NEXT
;
160 nsHashPropertyBag::GetEnumerator(nsISimpleEnumerator
* *_retval
)
162 nsCOMPtr
<nsIMutableArray
> propertyArray
= nsArray::Create();
164 return NS_ERROR_OUT_OF_MEMORY
;
166 mPropertyHash
.EnumerateRead(PropertyHashToArrayFunc
, propertyArray
.get());
168 return NS_NewArrayEnumerator(_retval
, propertyArray
);
171 #define IMPL_GETSETPROPERTY_AS(Name, Type) \
173 nsHashPropertyBag::GetPropertyAs ## Name (const nsAString & prop, Type *_retval) \
175 nsIVariant* v = mPropertyHash.GetWeak(prop); \
177 return NS_ERROR_NOT_AVAILABLE; \
178 return v->GetAs ## Name(_retval); \
182 nsHashPropertyBag::SetPropertyAs ## Name (const nsAString & prop, Type value) \
184 nsCOMPtr<nsIWritableVariant> var = new nsVariant(); \
186 return NS_ERROR_OUT_OF_MEMORY; \
187 var->SetAs ## Name(value); \
188 return SetProperty(prop, var); \
191 IMPL_GETSETPROPERTY_AS(Int32
, int32_t)
192 IMPL_GETSETPROPERTY_AS(Uint32
, uint32_t)
193 IMPL_GETSETPROPERTY_AS(Int64
, int64_t)
194 IMPL_GETSETPROPERTY_AS(Uint64
, uint64_t)
195 IMPL_GETSETPROPERTY_AS(Double
, double)
196 IMPL_GETSETPROPERTY_AS(Bool
, bool)
200 nsHashPropertyBag::GetPropertyAsAString(const nsAString
& prop
, nsAString
& _retval
)
202 nsIVariant
* v
= mPropertyHash
.GetWeak(prop
);
204 return NS_ERROR_NOT_AVAILABLE
;
205 return v
->GetAsAString(_retval
);
209 nsHashPropertyBag::GetPropertyAsACString(const nsAString
& prop
, nsACString
& _retval
)
211 nsIVariant
* v
= mPropertyHash
.GetWeak(prop
);
213 return NS_ERROR_NOT_AVAILABLE
;
214 return v
->GetAsACString(_retval
);
218 nsHashPropertyBag::GetPropertyAsAUTF8String(const nsAString
& prop
, nsACString
& _retval
)
220 nsIVariant
* v
= mPropertyHash
.GetWeak(prop
);
222 return NS_ERROR_NOT_AVAILABLE
;
223 return v
->GetAsAUTF8String(_retval
);
227 nsHashPropertyBag::GetPropertyAsInterface(const nsAString
& prop
,
231 nsIVariant
* v
= mPropertyHash
.GetWeak(prop
);
233 return NS_ERROR_NOT_AVAILABLE
;
234 nsCOMPtr
<nsISupports
> val
;
235 nsresult rv
= v
->GetAsISupports(getter_AddRefs(val
));
239 // We have a value, but it's null
243 return val
->QueryInterface(aIID
, _retval
);
247 nsHashPropertyBag::SetPropertyAsAString(const nsAString
& prop
, const nsAString
& value
)
249 nsCOMPtr
<nsIWritableVariant
> var
= new nsVariant();
251 return NS_ERROR_OUT_OF_MEMORY
;
252 var
->SetAsAString(value
);
253 return SetProperty(prop
, var
);
257 nsHashPropertyBag::SetPropertyAsACString(const nsAString
& prop
, const nsACString
& value
)
259 nsCOMPtr
<nsIWritableVariant
> var
= new nsVariant();
261 return NS_ERROR_OUT_OF_MEMORY
;
262 var
->SetAsACString(value
);
263 return SetProperty(prop
, var
);
267 nsHashPropertyBag::SetPropertyAsAUTF8String(const nsAString
& prop
, const nsACString
& value
)
269 nsCOMPtr
<nsIWritableVariant
> var
= new nsVariant();
271 return NS_ERROR_OUT_OF_MEMORY
;
272 var
->SetAsAUTF8String(value
);
273 return SetProperty(prop
, var
);
277 nsHashPropertyBag::SetPropertyAsInterface(const nsAString
& prop
, nsISupports
* value
)
279 nsCOMPtr
<nsIWritableVariant
> var
= new nsVariant();
281 return NS_ERROR_OUT_OF_MEMORY
;
282 var
->SetAsISupports(value
);
283 return SetProperty(prop
, var
);