Back to index

lightning-sunbird  0.9+nobinonly
nsHashPropertyBag.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* vim:set ts=4 sw=4 sts=4: */
00003 /* ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is Oracle Corporation code.
00017  *
00018  * The Initial Developer of the Original Code is
00019  *  Oracle Corporation
00020  * Portions created by the Initial Developer are Copyright (C) 2004
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "nsHashPropertyBag.h"
00041 #include "nsArray.h"
00042 #include "nsArrayEnumerator.h"
00043 #include "nsComponentManagerUtils.h"
00044 #include "nsIVariant.h"
00045 #include "nsIProperty.h"
00046 #include "nsVariant.h"
00047 
00048 nsresult
00049 NS_NewHashPropertyBag(nsIWritablePropertyBag* *_retval)
00050 {
00051     nsHashPropertyBag *hpb = new nsHashPropertyBag();
00052     if (!hpb)
00053         return NS_ERROR_OUT_OF_MEMORY;
00054 
00055     NS_ADDREF(hpb);
00056 
00057     nsresult rv = hpb->Init();
00058     if (NS_FAILED(rv)) {
00059         NS_RELEASE(hpb);
00060         return rv;
00061     }
00062 
00063     *_retval = hpb;
00064     return NS_OK;
00065 }
00066 
00067 /*
00068  * nsHashPropertyBag impl
00069  */
00070 
00071 NS_IMPL_THREADSAFE_ADDREF(nsHashPropertyBag)
00072 NS_IMPL_THREADSAFE_RELEASE(nsHashPropertyBag)
00073 NS_INTERFACE_MAP_BEGIN(nsHashPropertyBag)
00074   NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag)
00075   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIPropertyBag, nsIWritablePropertyBag)
00076   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWritablePropertyBag)
00077   NS_INTERFACE_MAP_ENTRY(nsIPropertyBag2)
00078   NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag2)
00079 NS_INTERFACE_MAP_END
00080 
00081 nsresult
00082 nsHashPropertyBag::Init()
00083 {
00084     // we can only assume that Init will fail only due to OOM.
00085     if (!mPropertyHash.Init())
00086         return NS_ERROR_OUT_OF_MEMORY;
00087     return NS_OK;
00088 }
00089 
00090 NS_IMETHODIMP
00091 nsHashPropertyBag::GetProperty(const nsAString& name, nsIVariant* *_retval)
00092 {
00093     PRBool isFound = mPropertyHash.Get(name, _retval);
00094     if (!isFound)
00095         return NS_ERROR_FAILURE;
00096 
00097     return NS_OK;
00098 }
00099 
00100 NS_IMETHODIMP
00101 nsHashPropertyBag::SetProperty(const nsAString& name, nsIVariant *value)
00102 {
00103     NS_ENSURE_ARG_POINTER(value);
00104 
00105     PRBool success = mPropertyHash.Put(name, value);
00106     if (!success)
00107         return NS_ERROR_FAILURE;
00108 
00109     return NS_OK;
00110 }
00111 
00112 NS_IMETHODIMP
00113 nsHashPropertyBag::DeleteProperty(const nsAString& name)
00114 {
00115     // is it too much to ask for ns*Hashtable to return
00116     // a boolean indicating whether RemoveEntry succeeded
00117     // or not?!?!
00118     PRBool isFound = mPropertyHash.Get(name, nsnull);
00119     if (!isFound)
00120         return NS_ERROR_FAILURE;
00121 
00122     // then from the hash
00123     mPropertyHash.Remove(name);
00124 
00125     return NS_OK;
00126 }
00127 
00128 
00129 //
00130 // nsSimpleProperty class and impl; used for GetEnumerator
00131 //
00132 
00133 class nsSimpleProperty : public nsIProperty {
00134 public:
00135     nsSimpleProperty(const nsAString& aName, nsIVariant* aValue)
00136         : mName(aName), mValue(aValue)
00137     {
00138     }
00139 
00140     NS_DECL_ISUPPORTS
00141     NS_DECL_NSIPROPERTY
00142 protected:
00143     nsString mName;
00144     nsCOMPtr<nsIVariant> mValue;
00145 };
00146 
00147 NS_IMPL_ISUPPORTS1(nsSimpleProperty, nsIProperty)
00148 
00149 NS_IMETHODIMP
00150 nsSimpleProperty::GetName(nsAString& aName)
00151 {
00152     aName.Assign(mName);
00153     return NS_OK;
00154 }
00155 
00156 NS_IMETHODIMP
00157 nsSimpleProperty::GetValue(nsIVariant* *aValue)
00158 {
00159     NS_IF_ADDREF(*aValue = mValue);
00160     return NS_OK;
00161 }
00162 
00163 // end nsSimpleProperty
00164 
00165 PR_STATIC_CALLBACK(PLDHashOperator)
00166 PropertyHashToArrayFunc (const nsAString &aKey,
00167                          nsIVariant* aData,
00168                          void *userArg)
00169 {
00170     nsIMutableArray *propertyArray =
00171         NS_STATIC_CAST(nsIMutableArray *, userArg);
00172     nsSimpleProperty *sprop = new nsSimpleProperty(aKey, aData);
00173     propertyArray->AppendElement(sprop, PR_FALSE);
00174     return PL_DHASH_NEXT;
00175 }
00176 
00177 
00178 NS_IMETHODIMP
00179 nsHashPropertyBag::GetEnumerator(nsISimpleEnumerator* *_retval)
00180 {
00181     nsresult rv;
00182 
00183     nsCOMPtr<nsIMutableArray> propertyArray;
00184     rv = NS_NewArray (getter_AddRefs(propertyArray));
00185     if (NS_FAILED(rv))
00186         return rv;
00187 
00188     mPropertyHash.EnumerateRead(PropertyHashToArrayFunc, propertyArray.get());
00189 
00190     return NS_NewArrayEnumerator(_retval, propertyArray);
00191 }
00192 
00193 #define IMPL_GETSETPROPERTY_AS(Name, Type) \
00194 NS_IMETHODIMP \
00195 nsHashPropertyBag::GetPropertyAs ## Name (const nsAString & prop, Type *_retval) \
00196 { \
00197     nsIVariant* v = mPropertyHash.GetWeak(prop); \
00198     if (!v) \
00199         return NS_ERROR_NOT_AVAILABLE; \
00200     return v->GetAs ## Name(_retval); \
00201 } \
00202 \
00203 NS_IMETHODIMP \
00204 nsHashPropertyBag::SetPropertyAs ## Name (const nsAString & prop, Type value) \
00205 { \
00206     nsCOMPtr<nsIWritableVariant> var = new nsVariant(); \
00207     if (!var) \
00208         return NS_ERROR_OUT_OF_MEMORY; \
00209     var->SetAs ## Name(value); \
00210     return SetProperty(prop, var); \
00211 }
00212 
00213 IMPL_GETSETPROPERTY_AS(Int32, PRInt32)
00214 IMPL_GETSETPROPERTY_AS(Uint32, PRUint32)
00215 IMPL_GETSETPROPERTY_AS(Int64, PRInt64)
00216 IMPL_GETSETPROPERTY_AS(Uint64, PRUint64)
00217 IMPL_GETSETPROPERTY_AS(Double, double)
00218 IMPL_GETSETPROPERTY_AS(Bool, PRBool)
00219 
00220 
00221 NS_IMETHODIMP
00222 nsHashPropertyBag::GetPropertyAsAString(const nsAString & prop, nsAString & _retval)
00223 {
00224     nsIVariant* v = mPropertyHash.GetWeak(prop);
00225     if (!v)
00226         return NS_ERROR_NOT_AVAILABLE;
00227     return v->GetAsAString(_retval);
00228 }
00229 
00230 NS_IMETHODIMP
00231 nsHashPropertyBag::GetPropertyAsACString(const nsAString & prop, nsACString & _retval)
00232 {
00233     nsIVariant* v = mPropertyHash.GetWeak(prop);
00234     if (!v)
00235         return NS_ERROR_NOT_AVAILABLE;
00236     return v->GetAsACString(_retval);
00237 }
00238 
00239 NS_IMETHODIMP
00240 nsHashPropertyBag::GetPropertyAsAUTF8String(const nsAString & prop, nsACString & _retval)
00241 {
00242     nsIVariant* v = mPropertyHash.GetWeak(prop);
00243     if (!v)
00244         return NS_ERROR_NOT_AVAILABLE;
00245     return v->GetAsAUTF8String(_retval);
00246 }
00247 
00248 NS_IMETHODIMP
00249 nsHashPropertyBag::GetPropertyAsInterface(const nsAString & prop,
00250                                           const nsIID & aIID,
00251                                           void** _retval)
00252 {
00253     nsIVariant* v = mPropertyHash.GetWeak(prop);
00254     if (!v)
00255         return NS_ERROR_NOT_AVAILABLE;
00256     nsCOMPtr<nsISupports> val;
00257     nsresult rv = v->GetAsISupports(getter_AddRefs(val));
00258     if (NS_FAILED(rv))
00259         return rv;
00260     if (!val) {
00261         // We have a value, but it's null
00262         *_retval = nsnull;
00263         return NS_OK;
00264     }
00265     return val->QueryInterface(aIID, _retval);
00266 }
00267 
00268 NS_IMETHODIMP
00269 nsHashPropertyBag::SetPropertyAsAString(const nsAString & prop, const nsAString & value)
00270 {
00271     nsCOMPtr<nsIWritableVariant> var = new nsVariant();
00272     if (!var)
00273         return NS_ERROR_OUT_OF_MEMORY;
00274     var->SetAsAString(value);
00275     return SetProperty(prop, var);
00276 }
00277 
00278 NS_IMETHODIMP
00279 nsHashPropertyBag::SetPropertyAsACString(const nsAString & prop, const nsACString & value)
00280 {
00281     nsCOMPtr<nsIWritableVariant> var = new nsVariant();
00282     if (!var)
00283         return NS_ERROR_OUT_OF_MEMORY;
00284     var->SetAsACString(value);
00285     return SetProperty(prop, var);
00286 }
00287 
00288 NS_IMETHODIMP
00289 nsHashPropertyBag::SetPropertyAsAUTF8String(const nsAString & prop, const nsACString & value)
00290 {
00291     nsCOMPtr<nsIWritableVariant> var = new nsVariant();
00292     if (!var)
00293         return NS_ERROR_OUT_OF_MEMORY;
00294     var->SetAsAUTF8String(value);
00295     return SetProperty(prop, var);
00296 }
00297 
00298 NS_IMETHODIMP
00299 nsHashPropertyBag::SetPropertyAsInterface(const nsAString & prop, nsISupports* value)
00300 {
00301     nsCOMPtr<nsIWritableVariant> var = new nsVariant();
00302     if (!var)
00303         return NS_ERROR_OUT_OF_MEMORY;
00304     var->SetAsISupports(value);
00305     return SetProperty(prop, var);
00306 }
00307