/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 2001 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Harshal Pradhan * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsString.h" #include "nsIProperty.h" #include "nsSOAPPropertyBag.h" #include "nsCOMArray.h" #include "nsInterfaceHashtable.h" #include "nsHashKeys.h" #include "jsapi.h" #include "nsIXPCScriptable.h" #include "nsIClassInfoImpl.h" class nsSOAPPropertyBagEnumerator; class nsSOAPPropertyBag:public nsIPropertyBag, public nsIXPCScriptable { public: nsSOAPPropertyBag(); virtual ~nsSOAPPropertyBag(); NS_DECL_ISUPPORTS NS_DECL_NSIPROPERTYBAG NS_DECL_NSIXPCSCRIPTABLE nsresult Init(); nsresult SetProperty(const nsAString& aName, nsIVariant *aValue); protected: nsInterfaceHashtable mProperties; friend class nsSOAPPropertyBagEnumerator; }; class nsSOAPProperty:public nsIProperty { public: nsSOAPProperty(const nsAString & aName, nsIVariant * aValue); virtual ~nsSOAPProperty(); NS_DECL_ISUPPORTS NS_DECL_NSIPROPERTY protected: nsString mName; nsCOMPtr mValue; }; class nsSOAPPropertyBagEnumerator:public nsISimpleEnumerator { public: NS_DECL_ISUPPORTS NS_DECL_NSISIMPLEENUMERATOR nsSOAPPropertyBagEnumerator(); virtual ~nsSOAPPropertyBagEnumerator(); nsresult Init(nsSOAPPropertyBag*); protected: nsCOMArray mProperties; PRUint32 mCurrent; }; NS_IMPL_ISUPPORTS2_CI(nsSOAPPropertyBag, nsIPropertyBag, nsIXPCScriptable) nsSOAPPropertyBag::nsSOAPPropertyBag() { } nsSOAPPropertyBag::~nsSOAPPropertyBag() { } nsresult nsSOAPPropertyBag::Init() { return mProperties.Init() ? NS_OK : NS_ERROR_FAILURE; } /* nsIVariant getProperty (in AString name); */ NS_IMETHODIMP nsSOAPPropertyBag::GetProperty(const nsAString & aName, nsIVariant ** _retval) { NS_ENSURE_ARG_POINTER(_retval); return mProperties.Get(aName, _retval) ? NS_OK : NS_ERROR_FAILURE; } nsresult nsSOAPPropertyBag::SetProperty(const nsAString & aName, nsIVariant * aValue) { NS_ENSURE_ARG_POINTER(aValue); return mProperties.Put(aName, aValue); } // The nsIXPCScriptable map declaration that will generate stubs for us... #define XPC_MAP_CLASSNAME nsSOAPPropertyBag #define XPC_MAP_QUOTED_CLASSNAME "SOAPPropertyBag" #define XPC_MAP_WANT_GETPROPERTY #define XPC_MAP_FLAGS 0 #include "xpc_map_end.h" /* This will #undef the above */ NS_IMETHODIMP nsSOAPPropertyBag::GetProperty(nsIXPConnectWrappedNative * wrapper, JSContext * cx, JSObject * obj, jsval id, jsval * vp, PRBool * _retval) { nsresult rv = NS_OK; if (JSVAL_IS_STRING(id)) { JSString *str = JSVAL_TO_STRING(id); const PRUnichar *name = reinterpret_cast (JS_GetStringChars(str)); nsCOMPtr value; mProperties.Get(nsDependentString(name), getter_AddRefs(value)); if (!value) return rv; rv = NS_SUCCESS_I_DID_SOMETHING; void *mark; jsval *argv = JS_PushArguments(cx, &mark, "%iv", value.get()); *vp = *argv; JS_PopArguments(cx, mark); } return rv; } PLDHashOperator PR_CALLBACK PropertyBagEnumFunc(const nsAString& aKey, nsIVariant *aData, void *aClosure) { nsCOMArray* properties = static_cast*>(aClosure); nsSOAPProperty* prop = new nsSOAPProperty(aKey, aData); NS_ENSURE_TRUE(prop, PL_DHASH_STOP); properties->AppendObject(prop); return PL_DHASH_NEXT; } nsSOAPPropertyBagEnumerator::nsSOAPPropertyBagEnumerator() : mCurrent(0) { } nsSOAPPropertyBagEnumerator::~nsSOAPPropertyBagEnumerator() { } NS_IMPL_ISUPPORTS1_CI(nsSOAPPropertyBagEnumerator, nsISimpleEnumerator) nsresult nsSOAPPropertyBagEnumerator::Init(nsSOAPPropertyBag* aPropertyBag) { PRUint32 count = aPropertyBag->mProperties.EnumerateRead(PropertyBagEnumFunc, &mProperties); // Check if all the properties got copied to the array. if (count != aPropertyBag->mProperties.Count()) { return NS_ERROR_FAILURE; } return NS_OK; } NS_IMETHODIMP nsSOAPPropertyBagEnumerator::GetNext(nsISupports ** aItem) { NS_ENSURE_ARG_POINTER(aItem); PRUint32 count = mProperties.Count(); if (mCurrent < count) { NS_ADDREF(*aItem = mProperties[mCurrent++]); return NS_OK; } return NS_ERROR_FAILURE; } NS_IMETHODIMP nsSOAPPropertyBagEnumerator::HasMoreElements(PRBool * aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = mCurrent < (PRUint32) mProperties.Count(); return NS_OK; } NS_IMPL_ISUPPORTS1_CI(nsSOAPProperty, nsIProperty) nsSOAPProperty::nsSOAPProperty(const nsAString& aName, nsIVariant *aValue) : mName(aName), mValue(aValue) { } nsSOAPProperty::~nsSOAPProperty() { } NS_IMETHODIMP nsSOAPProperty::GetName(nsAString& _retval) { _retval.Assign(mName); return NS_OK; } NS_IMETHODIMP nsSOAPProperty::GetValue(nsIVariant** _retval) { NS_ENSURE_ARG_POINTER(_retval); *_retval = mValue; NS_ADDREF(*_retval); return NS_OK; } /* readonly attribute nsISimpleEnumerator enumerator; */ NS_IMETHODIMP nsSOAPPropertyBag::GetEnumerator(nsISimpleEnumerator * *aEnumerator) { NS_ENSURE_ARG_POINTER(aEnumerator); nsRefPtr enumerator = new nsSOAPPropertyBagEnumerator(); NS_ENSURE_TRUE(enumerator, NS_ERROR_OUT_OF_MEMORY); nsresult rv = enumerator->Init(this); NS_ENSURE_SUCCESS(rv, rv); NS_ADDREF(*aEnumerator = enumerator); return NS_OK; } nsSOAPPropertyBagMutator::nsSOAPPropertyBagMutator() { } nsSOAPPropertyBagMutator::~nsSOAPPropertyBagMutator() { } NS_IMPL_ISUPPORTS1_CI(nsSOAPPropertyBagMutator, nsISOAPPropertyBagMutator) nsresult nsSOAPPropertyBagMutator::Init() { mSOAPBag = new nsSOAPPropertyBag(); NS_ENSURE_TRUE(mSOAPBag, NS_ERROR_OUT_OF_MEMORY); return mSOAPBag->Init(); } NS_IMETHODIMP nsSOAPPropertyBagMutator::GetPropertyBag(nsIPropertyBag ** aPropertyBag) { NS_ENSURE_ARG_POINTER(aPropertyBag); NS_ADDREF(*aPropertyBag = mSOAPBag); return NS_OK; } NS_IMETHODIMP nsSOAPPropertyBagMutator::AddProperty(const nsAString& aName, nsIVariant *aValue) { NS_ENSURE_ARG_POINTER(aValue); return mSOAPBag->SetProperty(aName, aValue); }