1 : /* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim:set ts=4 sw=4 sts=4: */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Oracle Corporation code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Oracle Corporation
20 : * Portions created by the Initial Developer are Copyright (C) 2004
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "nsHashPropertyBag.h"
41 : #include "nsArray.h"
42 : #include "nsArrayEnumerator.h"
43 : #include "nsComponentManagerUtils.h"
44 : #include "nsIVariant.h"
45 : #include "nsIProperty.h"
46 : #include "nsVariant.h"
47 :
48 : nsresult
49 0 : NS_NewHashPropertyBag(nsIWritablePropertyBag* *_retval)
50 : {
51 0 : nsHashPropertyBag *hpb = new nsHashPropertyBag();
52 0 : if (!hpb)
53 0 : return NS_ERROR_OUT_OF_MEMORY;
54 :
55 0 : NS_ADDREF(hpb);
56 :
57 0 : nsresult rv = hpb->Init();
58 0 : if (NS_FAILED(rv)) {
59 0 : NS_RELEASE(hpb);
60 0 : return rv;
61 : }
62 :
63 0 : *_retval = hpb;
64 0 : return NS_OK;
65 : }
66 :
67 : /*
68 : * nsHashPropertyBag impl
69 : */
70 :
71 246184 : NS_IMPL_THREADSAFE_ADDREF(nsHashPropertyBag)
72 245908 : NS_IMPL_THREADSAFE_RELEASE(nsHashPropertyBag)
73 140631 : NS_INTERFACE_MAP_BEGIN(nsHashPropertyBag)
74 140631 : NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag)
75 140406 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIPropertyBag, nsIWritablePropertyBag)
76 140326 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWritablePropertyBag)
77 105057 : NS_INTERFACE_MAP_ENTRY(nsIPropertyBag2)
78 103413 : NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag2)
79 101358 : NS_INTERFACE_MAP_END
80 :
81 : nsresult
82 58262 : nsHashPropertyBag::Init()
83 : {
84 : // we can only assume that Init will fail only due to OOM.
85 58262 : if (!mPropertyHash.Init())
86 0 : return NS_ERROR_OUT_OF_MEMORY;
87 58262 : return NS_OK;
88 : }
89 :
90 : NS_IMETHODIMP
91 33 : nsHashPropertyBag::HasKey(const nsAString& name, bool *aResult)
92 : {
93 33 : *aResult = mPropertyHash.Get(name, nsnull);
94 :
95 33 : return NS_OK;
96 : }
97 :
98 : NS_IMETHODIMP
99 106 : nsHashPropertyBag::Get(const nsAString& name, nsIVariant* *_retval)
100 : {
101 106 : if (!mPropertyHash.Get(name, _retval))
102 75 : *_retval = nsnull;
103 :
104 106 : return NS_OK;
105 : }
106 :
107 : NS_IMETHODIMP
108 21379 : nsHashPropertyBag::GetProperty(const nsAString& name, nsIVariant* *_retval)
109 : {
110 21379 : bool isFound = mPropertyHash.Get(name, _retval);
111 21379 : if (!isFound)
112 17550 : return NS_ERROR_FAILURE;
113 :
114 3829 : return NS_OK;
115 : }
116 :
117 : NS_IMETHODIMP
118 13679 : nsHashPropertyBag::SetProperty(const nsAString& name, nsIVariant *value)
119 : {
120 13679 : NS_ENSURE_ARG_POINTER(value);
121 :
122 13679 : bool success = mPropertyHash.Put(name, value);
123 13679 : if (!success)
124 0 : return NS_ERROR_FAILURE;
125 :
126 13679 : return NS_OK;
127 : }
128 :
129 : NS_IMETHODIMP
130 0 : nsHashPropertyBag::DeleteProperty(const nsAString& name)
131 : {
132 : // is it too much to ask for ns*Hashtable to return
133 : // a boolean indicating whether RemoveEntry succeeded
134 : // or not?!?!
135 0 : bool isFound = mPropertyHash.Get(name, nsnull);
136 0 : if (!isFound)
137 0 : return NS_ERROR_FAILURE;
138 :
139 : // then from the hash
140 0 : mPropertyHash.Remove(name);
141 :
142 0 : return NS_OK;
143 : }
144 :
145 :
146 : //
147 : // nsSimpleProperty class and impl; used for GetEnumerator
148 : //
149 :
150 88 : class nsSimpleProperty : public nsIProperty {
151 : public:
152 88 : nsSimpleProperty(const nsAString& aName, nsIVariant* aValue)
153 88 : : mName(aName), mValue(aValue)
154 : {
155 88 : }
156 :
157 : NS_DECL_ISUPPORTS
158 : NS_DECL_NSIPROPERTY
159 : protected:
160 : nsString mName;
161 : nsCOMPtr<nsIVariant> mValue;
162 : };
163 :
164 2556 : NS_IMPL_ISUPPORTS1(nsSimpleProperty, nsIProperty)
165 :
166 : NS_IMETHODIMP
167 110 : nsSimpleProperty::GetName(nsAString& aName)
168 : {
169 110 : aName.Assign(mName);
170 110 : return NS_OK;
171 : }
172 :
173 : NS_IMETHODIMP
174 84 : nsSimpleProperty::GetValue(nsIVariant* *aValue)
175 : {
176 84 : NS_IF_ADDREF(*aValue = mValue);
177 84 : return NS_OK;
178 : }
179 :
180 : // end nsSimpleProperty
181 :
182 : static PLDHashOperator
183 88 : PropertyHashToArrayFunc (const nsAString &aKey,
184 : nsIVariant* aData,
185 : void *userArg)
186 : {
187 : nsIMutableArray *propertyArray =
188 88 : static_cast<nsIMutableArray *>(userArg);
189 88 : nsSimpleProperty *sprop = new nsSimpleProperty(aKey, aData);
190 88 : propertyArray->AppendElement(sprop, false);
191 88 : return PL_DHASH_NEXT;
192 : }
193 :
194 :
195 : NS_IMETHODIMP
196 44 : nsHashPropertyBag::GetEnumerator(nsISimpleEnumerator* *_retval)
197 : {
198 88 : nsCOMPtr<nsIMutableArray> propertyArray = new nsArray();
199 44 : if (!propertyArray)
200 0 : return NS_ERROR_OUT_OF_MEMORY;
201 :
202 44 : mPropertyHash.EnumerateRead(PropertyHashToArrayFunc, propertyArray.get());
203 :
204 44 : return NS_NewArrayEnumerator(_retval, propertyArray);
205 : }
206 :
207 : #define IMPL_GETSETPROPERTY_AS(Name, Type) \
208 : NS_IMETHODIMP \
209 : nsHashPropertyBag::GetPropertyAs ## Name (const nsAString & prop, Type *_retval) \
210 : { \
211 : nsIVariant* v = mPropertyHash.GetWeak(prop); \
212 : if (!v) \
213 : return NS_ERROR_NOT_AVAILABLE; \
214 : return v->GetAs ## Name(_retval); \
215 : } \
216 : \
217 : NS_IMETHODIMP \
218 : nsHashPropertyBag::SetPropertyAs ## Name (const nsAString & prop, Type value) \
219 : { \
220 : nsCOMPtr<nsIWritableVariant> var = new nsVariant(); \
221 : if (!var) \
222 : return NS_ERROR_OUT_OF_MEMORY; \
223 : var->SetAs ## Name(value); \
224 : return SetProperty(prop, var); \
225 : }
226 :
227 1840 : IMPL_GETSETPROPERTY_AS(Int32, PRInt32)
228 0 : IMPL_GETSETPROPERTY_AS(Uint32, PRUint32)
229 17106 : IMPL_GETSETPROPERTY_AS(Int64, PRInt64)
230 461 : IMPL_GETSETPROPERTY_AS(Uint64, PRUint64)
231 0 : IMPL_GETSETPROPERTY_AS(Double, double)
232 5066 : IMPL_GETSETPROPERTY_AS(Bool, bool)
233 :
234 :
235 : NS_IMETHODIMP
236 293 : nsHashPropertyBag::GetPropertyAsAString(const nsAString & prop, nsAString & _retval)
237 : {
238 293 : nsIVariant* v = mPropertyHash.GetWeak(prop);
239 293 : if (!v)
240 0 : return NS_ERROR_NOT_AVAILABLE;
241 293 : return v->GetAsAString(_retval);
242 : }
243 :
244 : NS_IMETHODIMP
245 0 : nsHashPropertyBag::GetPropertyAsACString(const nsAString & prop, nsACString & _retval)
246 : {
247 0 : nsIVariant* v = mPropertyHash.GetWeak(prop);
248 0 : if (!v)
249 0 : return NS_ERROR_NOT_AVAILABLE;
250 0 : return v->GetAsACString(_retval);
251 : }
252 :
253 : NS_IMETHODIMP
254 0 : nsHashPropertyBag::GetPropertyAsAUTF8String(const nsAString & prop, nsACString & _retval)
255 : {
256 0 : nsIVariant* v = mPropertyHash.GetWeak(prop);
257 0 : if (!v)
258 0 : return NS_ERROR_NOT_AVAILABLE;
259 0 : return v->GetAsAUTF8String(_retval);
260 : }
261 :
262 : NS_IMETHODIMP
263 801 : nsHashPropertyBag::GetPropertyAsInterface(const nsAString & prop,
264 : const nsIID & aIID,
265 : void** _retval)
266 : {
267 801 : nsIVariant* v = mPropertyHash.GetWeak(prop);
268 801 : if (!v)
269 646 : return NS_ERROR_NOT_AVAILABLE;
270 310 : nsCOMPtr<nsISupports> val;
271 155 : nsresult rv = v->GetAsISupports(getter_AddRefs(val));
272 155 : if (NS_FAILED(rv))
273 0 : return rv;
274 155 : if (!val) {
275 : // We have a value, but it's null
276 0 : *_retval = nsnull;
277 0 : return NS_OK;
278 : }
279 155 : return val->QueryInterface(aIID, _retval);
280 : }
281 :
282 : NS_IMETHODIMP
283 1665 : nsHashPropertyBag::SetPropertyAsAString(const nsAString & prop, const nsAString & value)
284 : {
285 3330 : nsCOMPtr<nsIWritableVariant> var = new nsVariant();
286 1665 : if (!var)
287 0 : return NS_ERROR_OUT_OF_MEMORY;
288 1665 : var->SetAsAString(value);
289 1665 : return SetProperty(prop, var);
290 : }
291 :
292 : NS_IMETHODIMP
293 1150 : nsHashPropertyBag::SetPropertyAsACString(const nsAString & prop, const nsACString & value)
294 : {
295 2300 : nsCOMPtr<nsIWritableVariant> var = new nsVariant();
296 1150 : if (!var)
297 0 : return NS_ERROR_OUT_OF_MEMORY;
298 1150 : var->SetAsACString(value);
299 1150 : return SetProperty(prop, var);
300 : }
301 :
302 : NS_IMETHODIMP
303 2 : nsHashPropertyBag::SetPropertyAsAUTF8String(const nsAString & prop, const nsACString & value)
304 : {
305 4 : nsCOMPtr<nsIWritableVariant> var = new nsVariant();
306 2 : if (!var)
307 0 : return NS_ERROR_OUT_OF_MEMORY;
308 2 : var->SetAsAUTF8String(value);
309 2 : return SetProperty(prop, var);
310 : }
311 :
312 : NS_IMETHODIMP
313 932 : nsHashPropertyBag::SetPropertyAsInterface(const nsAString & prop, nsISupports* value)
314 : {
315 1864 : nsCOMPtr<nsIWritableVariant> var = new nsVariant();
316 932 : if (!var)
317 0 : return NS_ERROR_OUT_OF_MEMORY;
318 932 : var->SetAsISupports(value);
319 932 : return SetProperty(prop, var);
320 : }
321 :
|