First implementation of wrapper classes and tests. This is not yet part of the build.

This commit is contained in:
vidur%netscape.com 2001-10-16 00:18:53 +00:00
Родитель c74ec6b6a3
Коммит 27134b139c
22 изменённых файлов: 4005 добавлений и 20 удалений

Просмотреть файл

@ -0,0 +1,54 @@
#
# 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 Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
ifdef ENABLE_TESTS
DIRS += tests
endif
MODULE = xmlextras
LIBRARY_NAME = xmlextrasproxy_s
REQUIRES = xpcom \
string \
xpconnect \
caps \
js \
necko \
$(NULL)
CPPSRCS= \
wspproxy.cpp \
wspfactory.cpp \
wspcomplextypewrapper.cpp \
wsppropertybagwrapper.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a
# static lib.
FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -40,7 +40,134 @@
#include "wspprivate.h"
WSPComplexTypeWrapper::WSPComplexTypeWrapper()
// xtpcall includes
#include "xptcall.h"
#include "xptinfo.h"
// xpcom includes
#include "nsIServiceManager.h"
class WSPComplexTypeProperty : public nsIProperty {
public:
WSPComplexTypeProperty(const nsAReadableString& aName,
nsIVariant* aValue);
virtual ~WSPComplexTypeProperty() {}
NS_DECL_ISUPPORTS
NS_DECL_NSIPROPERTY
protected:
nsString mName;
nsCOMPtr<nsIVariant> mValue;
};
WSPComplexTypeProperty::WSPComplexTypeProperty(const nsAReadableString& aName,
nsIVariant* aValue)
: mName(aName), mValue(aValue)
{
NS_INIT_ISUPPORTS();
}
NS_IMPL_ISUPPORTS1(WSPComplexTypeProperty, nsIProperty)
/* readonly attribute AString name; */
NS_IMETHODIMP
WSPComplexTypeProperty::GetName(nsAWritableString & aName)
{
aName.Assign(mName);
return NS_OK;
}
/* readonly attribute nsIVariant value; */
NS_IMETHODIMP
WSPComplexTypeProperty::GetValue(nsIVariant * *aValue)
{
NS_ADDREF(*aValue = mValue);
return NS_OK;
}
class WSPComplexTypeEnumerator : public nsISimpleEnumerator {
public:
WSPComplexTypeEnumerator(WSPComplexTypeWrapper* aWrapper,
nsIInterfaceInfo* aInterfaceInfo);
virtual ~WSPComplexTypeEnumerator() {}
NS_DECL_ISUPPORTS
NS_DECL_NSISIMPLEENUMERATOR
protected:
nsCOMPtr<WSPComplexTypeWrapper> mWrapper;
nsCOMPtr<nsIInterfaceInfo> mInterfaceInfo;
PRUint16 mIndex;
PRUint16 mCount;
};
WSPComplexTypeEnumerator::WSPComplexTypeEnumerator(WSPComplexTypeWrapper* aWrapper, nsIInterfaceInfo* aInterfaceInfo)
: mWrapper(aWrapper), mInterfaceInfo(aInterfaceInfo), mIndex(3)
{
NS_INIT_ISUPPORTS();
if (mInterfaceInfo) {
mInterfaceInfo->GetMethodCount(&mCount);
}
}
NS_IMPL_ISUPPORTS1(WSPComplexTypeEnumerator, nsISimpleEnumerator)
/* boolean hasMoreElements (); */
NS_IMETHODIMP
WSPComplexTypeEnumerator::HasMoreElements(PRBool *_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = mIndex < mCount;
return NS_OK;
}
/* nsISupports getNext (); */
NS_IMETHODIMP
WSPComplexTypeEnumerator::GetNext(nsISupports **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
if (mIndex >= mCount) {
NS_ERROR("Bad nsISimpleEnumerator caller!");
return NS_ERROR_FAILURE;
}
const nsXPTMethodInfo* methodInfo;
nsresult rv = mInterfaceInfo->GetMethodInfo(mIndex, &methodInfo);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIVariant> var;
rv = mWrapper->GetPropertyValue(mIndex++, methodInfo, getter_AddRefs(var));
if (NS_FAILED(rv)) {
return rv;
}
nsAutoString propName;
rv = WSPFactory::MethodToPropertyName(nsDependentCString(methodInfo->GetName()), propName);
if (NS_FAILED(rv)) {
return rv;
}
WSPComplexTypeProperty* prop = new WSPComplexTypeProperty(propName, var);
if (!prop) {
return NS_ERROR_OUT_OF_MEMORY;
}
*_retval = prop;
NS_ADDREF(*_retval);
return NS_OK;
}
WSPComplexTypeWrapper::WSPComplexTypeWrapper(nsISupports* aComplexTypeInstance,
nsIInterfaceInfo* aInterfaceInfo)
: mComplexTypeInstance(aComplexTypeInstance),
mInterfaceInfo(aInterfaceInfo)
{
NS_INIT_ISUPPORTS();
}
@ -49,16 +176,205 @@ WSPComplexTypeWrapper::~WSPComplexTypeWrapper()
{
}
NS_INTERFACE_MAP_BEGIN(WSPComplexTypeWrapper)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIPropertyBag)
NS_INTERFACE_MAP_END
nsresult
WSPComplexTypeWrapper::Create(nsISupports* aComplexTypeInstance,
nsIInterfaceInfo* aInterfaceInfo,
WSPComplexTypeWrapper** aWrapper)
{
NS_ENSURE_ARG(aComplexTypeInstance);
NS_ENSURE_ARG(aInterfaceInfo);
NS_ENSURE_ARG_POINTER(aWrapper);
WSPComplexTypeWrapper* wrapper = new WSPComplexTypeWrapper(aComplexTypeInstance, aInterfaceInfo);
if (!wrapper) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aWrapper = wrapper;
NS_ADDREF(*aWrapper);
return NS_OK;
}
NS_IMPL_ISUPPORTS1(WSPComplexTypeWrapper, nsIPropertyBag)
/* readonly attribute nsISimpleEnumerator enumerator; */
NS_IMETHODIMP
WSPComplexTypeWrapper::GetEnumerator(nsISimpleEnumerator * *aEnumerator)
{
return NS_ERROR_NOT_IMPLEMENTED;
WSPComplexTypeEnumerator* enumerator = new WSPComplexTypeEnumerator(this, mInterfaceInfo);
if (!enumerator) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aEnumerator = enumerator;
NS_ADDREF(*aEnumerator);
return NS_OK;
}
nsresult
WSPComplexTypeWrapper::ResultAsVariant(uint8 aTypeTag,
nsXPTCVariant aResult,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant** aVariant)
{
nsresult rv;
nsCOMPtr<nsIWritableVariant> var = do_CreateInstance(NS_VARIANT_CONTRACTID,
&rv);
if (NS_FAILED(rv)) {
return rv;
}
switch (aTypeTag) {
case nsXPTType::T_I8:
var->SetAsInt8(aResult.val.i8);
break;
case nsXPTType::T_I16:
var->SetAsInt16(aResult.val.i16);
break;
case nsXPTType::T_I32:
var->SetAsInt32(aResult.val.i32);
break;
case nsXPTType::T_I64:
var->SetAsInt64(aResult.val.i64);
break;
case nsXPTType::T_U8:
var->SetAsUint8(aResult.val.u8);
break;
case nsXPTType::T_U16:
var->SetAsUint16(aResult.val.u16);
break;
case nsXPTType::T_U32:
var->SetAsUint32(aResult.val.u32);
break;
case nsXPTType::T_U64:
var->SetAsUint64(aResult.val.u64);
break;
case nsXPTType::T_FLOAT:
var->SetAsFloat(aResult.val.f);
break;
case nsXPTType::T_DOUBLE:
var->SetAsDouble(aResult.val.d);
break;
case nsXPTType::T_BOOL:
var->SetAsBool(aResult.val.b);
break;
case nsXPTType::T_CHAR:
var->SetAsChar(aResult.val.c);
break;
case nsXPTType::T_WCHAR:
var->SetAsWChar(aResult.val.wc);
break;
case nsXPTType::T_DOMSTRING:
var->SetAsAString(*((nsAString*)aResult.val.p));
break;
case nsXPTType::T_INTERFACE:
{
nsISupports* instance = (nsISupports*)aResult.val.p;
if (instance) {
// Rewrap an interface instance in a property bag
nsCOMPtr<WSPComplexTypeWrapper> wrapper;
rv = Create(instance, aInterfaceInfo,
getter_AddRefs(wrapper));
if (NS_FAILED(rv)) {
return rv;
}
var->SetAsInterface(NS_GET_IID(nsIPropertyBag), wrapper);
NS_RELEASE(instance);
}
else {
var->SetAsEmpty();
}
break;
}
default:
NS_ERROR("Bad attribute type for complex type interface");
rv = NS_ERROR_FAILURE;
}
*aVariant = var;
NS_ADDREF(*aVariant);
return rv;
}
nsresult
WSPComplexTypeWrapper::ArrayResultAsVariant(uint8 aTypeTag,
nsXPTCVariant aResult,
PRUint32 aLength,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant** aVariant)
{
nsresult rv;
nsCOMPtr<nsIWritableVariant> retvar = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return rv;
}
if (aLength) {
nsIVariant** entries = (nsIVariant**)nsMemory::Alloc(aLength * sizeof(nsIVariant*));
if (!entries) {
return NS_ERROR_OUT_OF_MEMORY;
}
PRUint32 i = 0;
nsXPTCVariant var;
void* array = aResult.val.p;
nsCOMPtr<nsIVariant> element;
#define POPULATE(_t,_v) \
PR_BEGIN_MACRO \
for(i = 0; i < aLength; i++) \
{ \
var.type = aTypeTag; \
var.val._v = *((_t*)array + i); \
rv = ResultAsVariant(aTypeTag, var, aInterfaceInfo, \
entries+i); \
if (NS_FAILED(rv)) { \
break; \
} \
} \
PR_END_MACRO
switch (aTypeTag) {
case nsXPTType::T_I8: POPULATE(PRInt8, i8); break;
case nsXPTType::T_I16: POPULATE(PRInt16, i16); break;
case nsXPTType::T_I32: POPULATE(PRInt32, i32); break;
case nsXPTType::T_I64: POPULATE(PRInt64, i64); break;
case nsXPTType::T_U8: POPULATE(PRUint8, u8); break;
case nsXPTType::T_U16: POPULATE(PRUint16, u16); break;
case nsXPTType::T_U32: POPULATE(PRUint32, u32); break;
case nsXPTType::T_U64: POPULATE(PRUint64, u64); break;
case nsXPTType::T_FLOAT: POPULATE(float, f); break;
case nsXPTType::T_DOUBLE: POPULATE(double, d); break;
case nsXPTType::T_BOOL: POPULATE(PRBool, b); break;
case nsXPTType::T_CHAR: POPULATE(char, c); break;
case nsXPTType::T_WCHAR: POPULATE(PRUnichar, wc); break;
case nsXPTType::T_INTERFACE: POPULATE(nsISupports*, p); break;
}
#undef POPULATE
if (NS_SUCCEEDED(rv)) {
rv = retvar->SetAsArray(nsIDataType::TYPE_INTERFACE, aLength, entries);
}
// Even if we failed while converting, we want to release
// the entries that were already created.
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(i, entries);
}
else {
retvar->SetAsEmpty();
}
if (NS_SUCCEEDED(rv)) {
*aVariant = retvar;
NS_ADDREF(*aVariant);
}
return rv;
}
/* nsIVariant getProperty (in AString name); */
@ -66,5 +382,138 @@ NS_IMETHODIMP
WSPComplexTypeWrapper::GetProperty(const nsAString & name,
nsIVariant **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
NS_ENSURE_ARG_POINTER(_retval);
nsCAutoString methodName;
WSPFactory::PropertyToMethodName(name, methodName);
const nsXPTMethodInfo* methodInfo;
PRUint16 methodIndex;
nsresult rv = mInterfaceInfo->GetMethodInfoForName(methodName.get(),
&methodIndex,
&methodInfo);
if (NS_FAILED(rv)) {
return rv;
}
return GetPropertyValue(methodIndex, methodInfo, _retval);
}
nsresult
WSPComplexTypeWrapper::GetPropertyValue(PRUint32 aMethodIndex,
const nsXPTMethodInfo* aMethodInfo,
nsIVariant** _retval)
{
nsresult rv;
nsAutoString outstr;
PRUint32 numParams;
nsXPTCVariant var[2];
uint8 type_tag;
nsXPTType arrayType;
nsCOMPtr<nsIInterfaceInfo> iinfo;
var[0].ClearFlags();
var[1].ClearFlags();
// There are two possibilities here: a getter or a
// method that returns array and array size out parameters.
if (aMethodInfo->IsGetter()) {
// If it's a getter make sure that it takes just a single (out) param
if (aMethodInfo->GetParamCount() != 1) {
return NS_ERROR_FAILURE;
}
const nsXPTParamInfo& paramInfo = aMethodInfo->GetParam(0);
const nsXPTType& type = paramInfo.GetType();
type_tag = type.TagPart();
numParams = 1;
var[0].type = type_tag;
if (paramInfo.IsOut()) {
var[0].SetPtrIsData();
var[0].ptr = &var[0].val;
}
else if (paramInfo.IsDipper() && type.IsPointer() &&
(type_tag == nsXPTType::T_DOMSTRING)) {
var[0].val.p = &outstr;
}
else {
NS_ERROR("Unexpected parameter type for getter");
return NS_ERROR_FAILURE;
}
if (type_tag == nsXPTType::T_INTERFACE) {
rv = mInterfaceInfo->GetInfoForParam(aMethodIndex, &paramInfo,
getter_AddRefs(iinfo));
if (NS_FAILED(rv)) {
return rv;
}
}
}
// If it isn't a getter, then it has to be an array
// getter method
else {
// It must take two parameters for this to work
if (aMethodInfo->GetParamCount() != 2) {
return NS_ERROR_FAILURE;
}
numParams = 2;
// The first parameter must be "out PRUint32"
const nsXPTParamInfo& paramInfo1 = aMethodInfo->GetParam(0);
const nsXPTType& type1 = paramInfo1.GetType();
if (!paramInfo1.IsOut() || (type1.TagPart() != nsXPTType::T_U32)) {
NS_ERROR("Unexpected parameter type for getter");
return NS_ERROR_FAILURE;
}
var[0].type = nsXPTType::T_U32;
var[0].SetPtrIsData();
var[0].ptr = &var[0].val;
// The second parameter must be "[array] out"
const nsXPTParamInfo& paramInfo2 = aMethodInfo->GetParam(1);
const nsXPTType& type2 = paramInfo2.GetType();
type_tag = type2.TagPart();
if (!paramInfo2.IsOut() || !type2.IsArray()) {
NS_ERROR("Unexpected parameter type for getter");
return NS_ERROR_FAILURE;
}
var[1].type = type_tag;
var[1].SetPtrIsData();
var[1].ptr = &var[1].val;
rv = mInterfaceInfo->GetTypeForParam(aMethodIndex, &paramInfo2,
1, &arrayType);
if (NS_FAILED(rv)) {
return rv;
}
if (arrayType.IsInterfacePointer()) {
rv = mInterfaceInfo->GetInfoForParam(aMethodIndex, &paramInfo2,
getter_AddRefs(iinfo));
if (NS_FAILED(rv)) {
return rv;
}
}
}
rv = XPTC_InvokeByIndex(mComplexTypeInstance, aMethodIndex,
numParams, var);
if (NS_FAILED(rv)) {
return rv;
}
if (type_tag == nsXPTType::T_ARRAY) {
rv = ArrayResultAsVariant(arrayType.TagPart(), var[1],
var[0].val.u32, iinfo, _retval);
}
else {
rv = ResultAsVariant(type_tag, var[0], iinfo, _retval);
}
return rv;
}

Просмотреть файл

@ -0,0 +1,146 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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):
* John Bandhauer (jband@netscape.com)
* Vidur Apparao (vidur@netscape.com)
*
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "wspprivate.h"
// NSPR includes
#include "prprf.h"
WSPFactory::WSPFactory()
{
NS_INIT_ISUPPORTS();
}
WSPFactory::~WSPFactory()
{
}
NS_IMPL_ISUPPORTS1(WSPFactory, nsIWebServiceProxyFactory)
/* nsIWebServiceProxy createProxy (in AString wsdlURL, in AString portname, in AString qualifier, in boolean isAsync); */
NS_IMETHODIMP
WSPFactory::CreateProxy(const nsAString & wsdlURL,
const nsAString & portname,
const nsAString & qualifier,
PRBool isAsync,
nsIWebServiceProxy **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void createProxyAsync (in AString wsdlURL, in AString portname, in AString qualifier, in boolean isAsync, in nsIWebServiceProxyListener listener); */
NS_IMETHODIMP
WSPFactory::CreateProxyAsync(const nsAString & wsdlURL,
const nsAString & portname,
const nsAString & qualifier,
PRBool isAsync,
nsIWebServiceProxyListener *listener)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
#define P2M_ESCAPE_CHARACTER '_'
nsresult
WSPFactory::MethodToPropertyName(const nsAReadableCString& aMethodName,
nsAWritableString& aPropertyName)
{
nsReadingIterator<char> current, end;
aPropertyName.Truncate();
aMethodName.BeginReading(current);
aMethodName.EndReading(end);
while (current != end) {
char ch = *current++;
PRUnichar uch;
if (ch == P2M_ESCAPE_CHARACTER) {
// Grab the next 4 characters that make up the
// escape sequence
char buf[5];
for (PRUint16 i = 0; (i < 4) && (current != end); i++) {
buf[i] = *current++;
}
// If we didn't get through the entire escape sequence, then
// it's an error.
if (i < 4) {
return NS_ERROR_FAILURE;
}
buf[4] = 0;
PR_sscanf(buf, "%hx", &uch);
}
else {
uch = PRUnichar(ch);
}
aPropertyName.Append(uch);
}
return NS_OK;
}
void
WSPFactory::PropertyToMethodName(const nsAReadableString& aPropertyName,
nsAWritableCString& aMethodName)
{
nsReadingIterator<PRUnichar> current, end;
aMethodName.Truncate();
aPropertyName.BeginReading(current);
aPropertyName.EndReading(end);
while (current != end) {
PRUnichar uch = *current++;
if (((PRUnichar('a') <= uch) && (uch <= PRUnichar('z'))) ||
((PRUnichar('A') <= uch) && (uch <= PRUnichar('Z'))) ||
((PRUnichar('0') <= uch) && (uch <= PRUnichar('9')))) {
// Casting is safe since we know that it's an ASCII character
aMethodName.Append(char(uch));
}
else {
// Escape the character and append to the string
char buf[6];
buf[0] = P2M_ESCAPE_CHARACTER;
PR_snprintf(buf+1, 5, "%hx", uch);
aMethodName.Append(buf, 5);
}
}
}

Просмотреть файл

@ -65,6 +65,11 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBSERVICEPROXYFACTORY
static nsresult MethodToPropertyName(const nsAReadableCString& aMethodName,
nsAWritableString& aPropertyName);
static void PropertyToMethodName(const nsAReadableString& aPropertyName,
nsAWritableCString& aMethodName);
};
class WSPProxy : public nsXPTCStubBase,
@ -124,7 +129,8 @@ protected:
class WSPComplexTypeWrapper : public nsIPropertyBag
{
public:
WSPComplexTypeWrapper();
WSPComplexTypeWrapper(nsISupports* aComplexTypeInstance,
nsIInterfaceInfo* aInterfaceInfo);
virtual ~WSPComplexTypeWrapper();
NS_DECL_ISUPPORTS
@ -134,6 +140,20 @@ public:
nsIInterfaceInfo* aInterfaceInfo,
WSPComplexTypeWrapper** aWrapper);
nsresult GetPropertyValue(PRUint32 aMethodIndex,
const nsXPTMethodInfo* aMethodInfo,
nsIVariant** _retval);
protected:
nsresult ResultAsVariant(uint8 aTypeTag,
nsXPTCVariant aResult,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant** aVariant);
nsresult ArrayResultAsVariant(uint8 aTypeTag,
nsXPTCVariant aResult,
PRUint32 aLength,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant** aVariant);
protected:
nsCOMPtr<nsISupports> mComplexTypeInstance;
nsCOMPtr<nsIInterfaceInfo> mInterfaceInfo;
@ -142,7 +162,8 @@ protected:
class WSPPropertyBagWrapper : public nsXPTCStubBase
{
public:
WSPPropertyBagWrapper();
WSPPropertyBagWrapper(nsIPropertyBag* aPropertyBag,
nsIInterfaceInfo* aInterfaceInfo);
virtual ~WSPPropertyBagWrapper();
NS_DECL_ISUPPORTS
@ -156,10 +177,20 @@ public:
static nsresult Create(nsIPropertyBag* aPropertyBag,
nsIInterfaceInfo* aInterfaceInfo,
WSPPropertyBagWrapper** aWrapper);
protected:
nsresult VariantToResult(uint8 aTypeTag,
void* aResult,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant* aProperty);
nsresult VariantToArrayResult(uint8 aTypeTag,
nsXPTCMiniVariant* aResult,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant* aProperty);
protected:
nsCOMPtr<nsIPropertyBag> mPropertyBag;
nsCOMPtr<nsIInterfaceInfo> mInterfaceInfo;
const nsIID* mIID;
};
#endif // __wspprivate_h__

Просмотреть файл

@ -0,0 +1,379 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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):
* John Bandhauer (jband@netscape.com)
* Vidur Apparao (vidur@netscape.com)
*
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "wspprivate.h"
WSPPropertyBagWrapper::WSPPropertyBagWrapper(nsIPropertyBag* aPropertyBag,
nsIInterfaceInfo* aInterfaceInfo)
: mPropertyBag(aPropertyBag), mInterfaceInfo(aInterfaceInfo)
{
NS_INIT_ISUPPORTS();
mInterfaceInfo->GetIIDShared(&mIID);
}
WSPPropertyBagWrapper::~WSPPropertyBagWrapper()
{
}
nsresult
WSPPropertyBagWrapper::Create(nsIPropertyBag* aPropertyBag,
nsIInterfaceInfo* aInterfaceInfo,
WSPPropertyBagWrapper** aWrapper)
{
NS_ENSURE_ARG(aPropertyBag);
NS_ENSURE_ARG(aInterfaceInfo);
NS_ENSURE_ARG_POINTER(aWrapper);
WSPPropertyBagWrapper* wrapper = new WSPPropertyBagWrapper(aPropertyBag,
aInterfaceInfo);
if (!wrapper) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aWrapper = wrapper;
NS_ADDREF(*aWrapper);
return NS_OK;
}
NS_IMPL_ADDREF(WSPPropertyBagWrapper)
NS_IMPL_RELEASE(WSPPropertyBagWrapper)
NS_IMETHODIMP
WSPPropertyBagWrapper::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if(aIID.Equals(*mIID) || aIID.Equals(NS_GET_IID(nsISupports))) {
*aInstancePtr = NS_STATIC_CAST(nsISupports*, this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_ERROR_NO_INTERFACE;
}
nsresult
WSPPropertyBagWrapper::VariantToResult(uint8 aTypeTag,
void* aResult,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant* aProperty)
{
nsresult rv;
switch(aTypeTag) {
case nsXPTType::T_I8:
rv = aProperty->GetAsInt8((PRUint8*)aResult);
break;
case nsXPTType::T_I16:
rv = aProperty->GetAsInt16((PRInt16*)aResult);
break;
case nsXPTType::T_I32:
rv = aProperty->GetAsInt32((PRInt32*)aResult);
break;
case nsXPTType::T_I64:
rv = aProperty->GetAsInt64((PRInt64*)aResult);
break;
case nsXPTType::T_U8:
rv = aProperty->GetAsUint8((PRUint8*)aResult);
break;
case nsXPTType::T_U16:
rv = aProperty->GetAsUint16((PRUint16*)aResult);
break;
case nsXPTType::T_U32:
rv = aProperty->GetAsUint32((PRUint32*)aResult);
break;
case nsXPTType::T_U64:
rv = aProperty->GetAsUint64((PRUint64*)aResult);
break;
case nsXPTType::T_FLOAT:
rv = aProperty->GetAsFloat((float*)aResult);
break;
case nsXPTType::T_DOUBLE:
rv = aProperty->GetAsDouble((double*)aResult);
break;
case nsXPTType::T_BOOL:
rv = aProperty->GetAsBool((PRBool*)aResult);
break;
case nsXPTType::T_CHAR:
rv = aProperty->GetAsChar((char*)aResult);
break;
case nsXPTType::T_WCHAR:
rv = aProperty->GetAsWChar((PRUnichar*)aResult);
break;
case nsXPTType::T_DOMSTRING:
rv = aProperty->GetAsAString(*(nsAString*)aResult);
break;
case nsXPTType::T_INTERFACE:
{
PRUint16 dataType;
aProperty->GetDataType(&dataType);
if (dataType == nsIDataType::TYPE_EMPTY) {
*(nsISupports**)aResult = nsnull;
}
else {
nsCOMPtr<nsISupports> sup;
rv = aProperty->GetAsISupports(getter_AddRefs(sup));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIPropertyBag> propBag = do_QueryInterface(sup, &rv);
if (NS_FAILED(rv)) {
return rv;
}
WSPPropertyBagWrapper* wrapper;
rv = Create(propBag, aInterfaceInfo, &wrapper);
if (NS_FAILED(rv)) {
return rv;
}
const nsIID* iid;
aInterfaceInfo->GetIIDShared(&iid);
rv = wrapper->QueryInterface(*iid, (void**)aResult);
NS_RELEASE(wrapper);
}
break;
}
default:
NS_ERROR("Bad attribute type for complex type interface");
rv = NS_ERROR_FAILURE;
}
return rv;
}
nsresult
WSPPropertyBagWrapper::VariantToArrayResult(uint8 aTypeTag,
nsXPTCMiniVariant* aResult,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant* aProperty)
{
void* array;
PRUint16 type;
PRUint32 count;
nsresult rv = aProperty->GetAsArray(&type, &count, &array);
if (NS_FAILED(rv)) {
return rv;
}
// We assume it's an array of variants.
// XXX need a way to confirm that
if (type != nsIDataType::TYPE_INTERFACE) {
return NS_ERROR_FAILURE;
}
nsIVariant** variants = (nsIVariant**)array;
PRUint32 size;
// Allocate the array
switch (aTypeTag) {
case nsXPTType::T_I8:
case nsXPTType::T_U8:
size = sizeof(PRUint8);
break;
case nsXPTType::T_I16:
case nsXPTType::T_U16:
size = sizeof(PRUint16);
break;
case nsXPTType::T_I32:
case nsXPTType::T_U32:
size = sizeof(PRUint32);
break;
case nsXPTType::T_I64:
case nsXPTType::T_U64:
size = sizeof(PRUint64);
break;
case nsXPTType::T_FLOAT:
size = sizeof(float);
break;
case nsXPTType::T_DOUBLE:
size = sizeof(double);
break;
case nsXPTType::T_BOOL:
size = sizeof(PRBool);
break;
case nsXPTType::T_CHAR:
size = sizeof(char);
break;
case nsXPTType::T_WCHAR:
size = sizeof(PRUnichar);
break;
case nsXPTType::T_INTERFACE:
size = sizeof(nsISupports*);
break;
default:
NS_ERROR("Unexpected array type");
return NS_ERROR_FAILURE;
}
void* outptr = nsMemory::Alloc(count * size);
if (!outptr) {
return NS_ERROR_OUT_OF_MEMORY;
}
PRUint32 i;
for (i = 0; i < count; i++) {
rv = VariantToResult(aTypeTag, (void*)((char*)outptr + (i*size)),
aInterfaceInfo, variants[i]);
if (NS_FAILED(rv)) {
break;
}
}
// Free the variant array passed back to us
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, variants);
// If conversion failed, free the allocated structures
if (NS_FAILED(rv)) {
if (aTypeTag == nsXPTType::T_INTERFACE) {
nsMemory::Free(outptr);
}
else {
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(i, (nsISupports**)outptr);
}
return rv;
}
*((PRUint32*)aResult[0].val.p) = count;
*((void**)aResult[1].val.p) = outptr;
return NS_OK;
}
NS_IMETHODIMP
WSPPropertyBagWrapper::CallMethod(PRUint16 methodIndex,
const nsXPTMethodInfo* info,
nsXPTCMiniVariant* params)
{
nsresult rv = NS_OK;
nsAutoString propName;
nsCOMPtr<nsIVariant> val;
if (methodIndex < 3) {
NS_ERROR("WSPPropertyBagWrapper: bad method index");
return NS_ERROR_FAILURE;
}
else {
rv = WSPFactory::MethodToPropertyName(nsDependentCString(info->GetName()),
propName);
if (NS_FAILED(rv)) {
return rv;
}
rv = mPropertyBag->GetProperty(propName, getter_AddRefs(val));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIInterfaceInfo> iinfo;
if (info->IsGetter()) {
const nsXPTParamInfo& paramInfo = info->GetParam(0);
const nsXPTType& type = paramInfo.GetType();
uint8 type_tag = type.TagPart();
if (type_tag == nsXPTType::T_INTERFACE) {
rv = mInterfaceInfo->GetInfoForParam(methodIndex, &paramInfo,
getter_AddRefs(iinfo));
if (NS_FAILED(rv)) {
return rv;
}
}
rv = VariantToResult(type_tag, params[0].val.p, iinfo, val);
}
else if (info->GetParamCount() == 2) {
// If it's not an explicit getter, it has to be an array
// getter method.
// The first parameter should be the array length out param
const nsXPTParamInfo& paramInfo1 = info->GetParam(0);
const nsXPTType& type1 = paramInfo1.GetType();
if (!paramInfo1.IsOut() || (type1.TagPart() != nsXPTType::T_U32)) {
NS_ERROR("Unexpected parameter type for getter");
return NS_ERROR_FAILURE;
}
// The second parameter should be the array out pointer
// itself.
const nsXPTParamInfo& paramInfo2 = info->GetParam(1);
const nsXPTType& type2 = paramInfo2.GetType();
if (!paramInfo2.IsOut() || !type2.IsArray()) {
NS_ERROR("Unexpected parameter type for getter");
return NS_ERROR_FAILURE;
}
nsXPTType arrayType;
rv = mInterfaceInfo->GetTypeForParam(methodIndex, &paramInfo2,
1, &arrayType);
if (NS_FAILED(rv)) {
return rv;
}
if (arrayType.IsInterfacePointer()) {
rv = mInterfaceInfo->GetInfoForParam(methodIndex, &paramInfo2,
getter_AddRefs(iinfo));
if (NS_FAILED(rv)) {
return rv;
}
}
rv = VariantToArrayResult(arrayType.TagPart(), params, iinfo, val);
}
else {
NS_ERROR("Unexpected method signature for property bag wrapper");
return NS_ERROR_FAILURE;
}
}
return rv;
}
NS_IMETHODIMP
WSPPropertyBagWrapper::GetInterfaceInfo(nsIInterfaceInfo** info)
{
NS_ENSURE_ARG_POINTER(info);
*info = mInterfaceInfo;
NS_ADDREF(*info);
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,58 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
REQUIRES = xpcom \
string \
xmlextras \
xpconnect \
caps \
js \
necko \
$(NULL)
XPIDLSRCS = .\nsIWSPProxyTest.idl \
$(NULL)
CPPSRCS = \
wspproxytest.cpp \
$(NULL)
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
include $(topsrcdir)/config/config.mk
LIBS = \
$(DIST)/lib/libxmlextrasproxy_s.$(LIB_SUFFIX) \
$(MOZ_JS_LIBS) \
$(XPCOM_LIBS) \
$(NSPR_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk
DEFINES += -DUSE_NSREG

Просмотреть файл

@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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):
* John Bandhauer (jband@netscape.com)
* Vidur Apparao (vidur@netscape.com)
*
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIWebServiceProxy.idl"
[scriptable, uuid(fd25b392-f435-4aea-bbbc-0886f8239dce)]
interface nsIWSPProxyTest : nsISupports {
void testComplexTypeWrapper();
void testPropertyBagWrapper();
};
[uuid(6de70ec8-46fb-49d5-8dac-9d2eae42ea5a)]
interface nsIWSPTestComplexType : nsISupports {
readonly attribute PRUint8 i8;
readonly attribute PRInt16 i16;
readonly attribute PRInt32 i32;
readonly attribute PRInt64 i64;
readonly attribute PRUint8 u8;
readonly attribute PRUint16 u16;
readonly attribute PRUint32 u32;
readonly attribute PRUint64 u64;
readonly attribute PRBool b;
readonly attribute float f;
readonly attribute double d;
readonly attribute char c;
readonly attribute wchar wc;
readonly attribute AString s;
readonly attribute nsIWSPTestComplexType p;
readonly attribute nsIWSPTestComplexType p2;
void array1(out PRUint32 length, [array, retval, size_is(length)] out PRUint32 array1);
void array2(out PRUint32 length, [array, retval, size_is(length)] out double array2);
void array3(out PRUint32 length, [array, retval, size_is(length)] out nsIWSPTestComplexType array3);
};
%{ C++
#define NS_WSPPROXYTEST_CONTRACTID "@mozilla.org/xmlextras/proxy/webserviceproxytest;1"
#define NS_WSPPROXYTEST_CID \
{ /* cdb03ec6-4a5e-4461-996e-16f517e53b87 */ \
0xcdb03ec6, 0x4a5e, 0x4461, \
{0x99, 0x6e, 0x16, 0xf5, 0x17, 0xe5, 0x3b, 0x87} }
%}

Просмотреть файл

@ -0,0 +1,686 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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):
* John Bandhauer (jband@netscape.com)
* Vidur Apparao (vidur@netscape.com)
*
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "wspproxytest.h"
#include "nsAString.h"
#include "nsIInterfaceInfoManager.h"
#include "nsIServiceManager.h"
const PRUint8 sInt8Val = 2;
const PRInt16 sInt16Val = 0x1234;
const PRInt32 sInt32Val = 0x12345678;
#ifdef HAVE_LONG_LONG
const PRInt64 sInt64Val = 0x1234567887654321;
#else
const PRInt64 sInt64Val = {0x12345678, 0x87654321};
#endif
const PRUint8 sUint8Val = 2;
const PRUint16 sUint16Val = 0x1234;
const PRUint32 sUint32Val = 0x12345678;
#ifdef HAVE_LONG_LONG
const PRUint64 sUint64Val = 0x1234567887654321;
#else
const PRUint64 sUint64Val = {0x12345678, 0x87654321};
#endif
const PRBool sBoolVal = PR_TRUE;
const float sFloatVal = 0.0;
const double sDoubleVal = 0.03;
const char sCharVal = 'a';
const PRUnichar sWcharVal = PRUnichar('a');
#define STRING_VAL "Hello world"
const PRUint32 sArray1Length = 3;
const PRUint32 sArray1[] = { 4, 23, 37 };
const PRUint32 sArray2Length = 4;
const double sArray2[] = { 4.234, 23.97, 3434.2945, 0.03 };
WSPProxyTest::WSPProxyTest()
{
NS_INIT_ISUPPORTS();
}
WSPProxyTest::~WSPProxyTest()
{
}
NS_IMPL_ISUPPORTS1(WSPProxyTest, nsIWSPProxyTest)
nsresult
WSPProxyTest::CreateComplexTypeWrapper(WSPComplexTypeWrapper** aWrapper,
nsIInterfaceInfo** aInfo)
{
static nsIID sComplexTypeIID = NS_GET_IID(nsIWSPTestComplexType);
nsCOMPtr<WSPTestComplexType> ct = new WSPTestComplexType();
if (!ct) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult rv;
nsCOMPtr<nsIInterfaceInfoManager> manager = do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIInterfaceInfo> iinfo;
rv = manager->GetInfoForIID(&sComplexTypeIID, getter_AddRefs(iinfo));
if (NS_FAILED(rv)) {
return rv;
}
*aInfo = iinfo;
NS_ADDREF(*aInfo);
return WSPComplexTypeWrapper::Create(ct, iinfo, aWrapper);
}
NS_IMETHODIMP
WSPProxyTest::TestComplexTypeWrapper()
{
nsCOMPtr<nsIInterfaceInfo> info;
nsCOMPtr<WSPComplexTypeWrapper> wrapper;
nsresult rv = CreateComplexTypeWrapper(getter_AddRefs(wrapper),
getter_AddRefs(info));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIPropertyBag> propBag = do_QueryInterface(wrapper);
if (!propBag) {
return NS_ERROR_FAILURE;
}
rv = TestComplexTypeWrapperInstance(propBag);
if (NS_FAILED(rv)) {
return rv;
}
return NS_OK;
}
nsresult
WSPProxyTest::TestComplexTypeWrapperInstance(nsIPropertyBag* propBag)
{
nsCOMPtr<nsISimpleEnumerator> enumerator;
nsresult rv = propBag->GetEnumerator(getter_AddRefs(enumerator));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsISupports> sup;
nsCOMPtr<nsIProperty> prop;
nsCOMPtr<nsIVariant> val;
nsAutoString propName;
#define GET_AND_TEST_NAME(_name) \
rv = enumerator->GetNext(getter_AddRefs(sup)); \
if (NS_FAILED(rv)) { \
printf("WSPProxyTest: Failed getting property " #_name "\n"); \
return rv; \
} \
\
prop = do_QueryInterface(sup, &rv); \
if (NS_FAILED(rv)) { \
return rv; \
} \
\
prop->GetName(propName); \
if (!propName.Equals(NS_LITERAL_STRING(#_name))) { \
printf("WSPProxyTest: Name doesn't match for property " #_name "\n");\
return NS_ERROR_FAILURE; \
} \
prop->GetValue(getter_AddRefs(val)); \
if (!val) { \
return NS_ERROR_FAILURE; \
}
#define GET_AND_TEST(_t, _n, _name, _val) \
GET_AND_TEST_NAME(_name) \
_t _name; \
rv = val->GetAs##_n(&_name); \
if (NS_FAILED(rv)) { \
printf("WSPProxyTest: Failed getting value for property " #_name "\n");\
return rv; \
} \
if (_name != _val) { \
printf("WSPProxyTest: Value doesn't match for property " #_name "\n");\
return NS_ERROR_FAILURE; \
}
GET_AND_TEST(PRUint8, Int8, i8, sInt8Val)
GET_AND_TEST(PRInt16, Int16, i16, sInt16Val)
GET_AND_TEST(PRInt32, Int32, i32, sInt32Val)
GET_AND_TEST(PRInt64, Int64, i64, sInt64Val)
GET_AND_TEST(PRUint8, Uint8, u8, sUint8Val)
GET_AND_TEST(PRUint16, Uint16, u16, sUint16Val)
GET_AND_TEST(PRUint32, Uint32, u32, sUint32Val)
GET_AND_TEST(PRUint64, Uint64, u64, sUint64Val)
GET_AND_TEST(PRBool, Bool, b, sBoolVal)
GET_AND_TEST(float, Float, f, sFloatVal)
GET_AND_TEST(double, Double, d, sDoubleVal)
GET_AND_TEST(char, Char, c, sCharVal)
GET_AND_TEST(PRUnichar, WChar, wc, sWcharVal)
GET_AND_TEST_NAME(s);
nsAutoString str;
rv = val->GetAsAString(str);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for property s\n");
return rv;
}
if (!str.Equals(NS_LITERAL_STRING(STRING_VAL))) {
printf("WSPProxyTest: Value doesn't match for property s\n");
return NS_ERROR_FAILURE;
}
GET_AND_TEST_NAME(p)
nsCOMPtr<nsISupports> supVal;
rv = val->GetAsISupports(getter_AddRefs(supVal));
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for property p\n");
return rv;
}
nsCOMPtr<nsIPropertyBag> propBagVal = do_QueryInterface(supVal, &rv);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Value doesn't match for property p\n");
return rv;
}
GET_AND_TEST_NAME(p2)
PRUint16 dataType;
val->GetDataType(&dataType);
if (dataType != nsIDataType::TYPE_EMPTY) {
printf("WSPProxyTest: Value doesn't match for property p\n");
return NS_ERROR_FAILURE;
}
PRUint16 type;
PRUint32 index, count;
nsIVariant** arrayVal;
GET_AND_TEST_NAME(array1)
rv = val->GetAsArray(&type, &count, (void**)&arrayVal);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for property array1\n");
return rv;
}
for (index = 0; index < count; index++) {
nsIVariant* arrayVar = arrayVal[index];
PRUint32 arrayInt;
rv = arrayVar->GetAsUint32(&arrayInt);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for element of property array1\n");
return rv;
}
if (arrayInt != sArray1[index]) {
printf("WSPProxyTest: Value doesn't match for element of property array1\n");
return rv;
}
}
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, arrayVal);
GET_AND_TEST_NAME(array2)
rv = val->GetAsArray(&type, &count, (void**)&arrayVal);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for property array2\n");
return rv;
}
for (index = 0; index < count; index++) {
nsIVariant* arrayVar = arrayVal[index];
double arrayDouble;
rv = arrayVar->GetAsDouble(&arrayDouble);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for element of property array1\n");
return rv;
}
if (arrayDouble != sArray2[index]) {
printf("WSPProxyTest: Value doesn't match for element of property array1\n");
return rv;
}
}
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, arrayVal);
GET_AND_TEST_NAME(array3)
rv = val->GetAsArray(&type, &count, (void**)&arrayVal);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for property array2\n");
return rv;
}
nsIVariant* array3Var = arrayVal[0];
rv = array3Var->GetAsISupports(getter_AddRefs(supVal));
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for element of property array3\n");
return rv;
}
propBagVal = do_QueryInterface(supVal, &rv);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Value doesn't match for element of property array3\n");
return rv;
}
array3Var = arrayVal[1];
array3Var->GetDataType(&dataType);
if (dataType != nsIDataType::TYPE_EMPTY) {
printf("WSPProxyTest: Value doesn't match for element of property array3\n");
return NS_ERROR_FAILURE;
}
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, arrayVal);
#undef GET_AND_TEST
#undef GET_AND_TEST_NAME
return NS_OK;
}
NS_IMETHODIMP
WSPProxyTest::TestPropertyBagWrapper()
{
nsCOMPtr<nsIInterfaceInfo> info;
nsCOMPtr<WSPComplexTypeWrapper> ctwrapper;
nsresult rv = CreateComplexTypeWrapper(getter_AddRefs(ctwrapper),
getter_AddRefs(info));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIPropertyBag> propBag = do_QueryInterface(ctwrapper);
if (!propBag) {
return NS_ERROR_FAILURE;
}
WSPPropertyBagWrapper* wrapper;
rv = WSPPropertyBagWrapper::Create(propBag, info, &wrapper);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIWSPTestComplexType> ct = do_QueryInterface(wrapper, &rv);
NS_RELEASE(wrapper);
if (NS_FAILED(rv)) {
return rv;
}
#define GET_AND_TEST(_t, _name, _val) \
_t _name; \
rv = ct->Get##_name(&_name); \
if (NS_FAILED(rv)) { \
printf("WSPProxyTest: Failed to get value for attribute" #_name "\n"); \
return rv; \
} \
if (_name != _val) { \
printf("WSPProxyTest: Value doesn't match for attribute " #_name "\n"); \
return NS_ERROR_FAILURE; \
}
GET_AND_TEST(PRUint8, I8, sInt8Val)
GET_AND_TEST(PRInt16, I16, sInt16Val)
GET_AND_TEST(PRInt32, I32, sInt32Val)
GET_AND_TEST(PRInt64, I64, sInt64Val)
GET_AND_TEST(PRUint8, U8, sUint8Val)
GET_AND_TEST(PRUint16, U16, sUint16Val)
GET_AND_TEST(PRUint32, U32, sUint32Val)
GET_AND_TEST(PRUint64, U64, sUint64Val)
GET_AND_TEST(float, F, sFloatVal)
GET_AND_TEST(double, D, sDoubleVal)
GET_AND_TEST(PRBool, B, sBoolVal)
GET_AND_TEST(char, C, sCharVal)
GET_AND_TEST(PRUnichar, Wc, sWcharVal)
nsAutoString str;
rv = ct->GetS(str);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed to get value for attribute s\n");
return rv;
}
if (!str.Equals(NS_LITERAL_STRING(STRING_VAL))) {
printf("WSPProxyTest: Value doesn't match for attribute s\n");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIWSPTestComplexType> p;
rv = ct->GetP(getter_AddRefs(p));
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed to get value for attribute p\n");
return rv;
}
rv = ct->GetP2(getter_AddRefs(p));
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed to get value for attribute p2\n");
return rv;
}
if (p) {
printf("WSPProxyTest: Value doesn't match for attribute p2\n");
return NS_ERROR_FAILURE;
}
PRUint32 index, count;
PRUint32* array1;
rv = ct->Array1(&count, &array1);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed to get value for attribute array1\n");
return rv;
}
for (index = 0; index < count; index++) {
if (array1[index] != sArray1[index]) {
printf("WSPProxyTest: Value doesn't match for element of attribute array1\n");
return NS_ERROR_FAILURE;
}
}
nsMemory::Free(array1);
double* array2;
rv = ct->Array2(&count, &array2);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed to get value for attribute array2\n");
return rv;
}
for (index = 0; index < count; index++) {
if (array2[index] != sArray2[index]) {
printf("WSPProxyTest: Value doesn't match for element of attribute array2\n");
return NS_ERROR_FAILURE;
}
}
nsMemory::Free(array2);
nsIWSPTestComplexType** array3;
rv = ct->Array3(&count, &array3);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed to get value for attribute array3\n");
return rv;
}
if (!array3[0] || array3[1]) {
printf("WSPProxyTest: Value doesn't match for element of attribute array3\n");
return NS_ERROR_FAILURE;
}
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, array3);
#undef GET_AND_TEST
return NS_OK;
}
WSPTestComplexType::WSPTestComplexType()
{
NS_INIT_ISUPPORTS();
}
WSPTestComplexType::~WSPTestComplexType()
{
}
NS_IMPL_ISUPPORTS1(WSPTestComplexType, nsIWSPTestComplexType)
/* readonly attribute PRUint8 i8; */
NS_IMETHODIMP
WSPTestComplexType::GetI8(PRUint8 *aI8)
{
*aI8 = sInt8Val;
return NS_OK;
}
/* readonly attribute PRInt16 i16; */
NS_IMETHODIMP
WSPTestComplexType::GetI16(PRInt16 *aI16)
{
*aI16 = sInt16Val;
return NS_OK;
}
/* readonly attribute PRInt32 i32; */
NS_IMETHODIMP
WSPTestComplexType::GetI32(PRInt32 *aI32)
{
*aI32 = sInt32Val;
return NS_OK;
}
/* readonly attribute PRInt64 i64; */
NS_IMETHODIMP
WSPTestComplexType::GetI64(PRInt64 *aI64)
{
*aI64 = sInt64Val;
return NS_OK;
}
/* readonly attribute PRUint8 u8; */
NS_IMETHODIMP
WSPTestComplexType::GetU8(PRUint8 *aU8)
{
*aU8 = sUint8Val;
return NS_OK;
}
/* readonly attribute PRUint16 u16; */
NS_IMETHODIMP
WSPTestComplexType::GetU16(PRUint16 *aU16)
{
*aU16 = sUint16Val;
return NS_OK;
}
/* readonly attribute PRUint32 u32; */
NS_IMETHODIMP
WSPTestComplexType::GetU32(PRUint32 *aU32)
{
*aU32 = sUint32Val;
return NS_OK;
}
/* readonly attribute PRUint64 u64; */
NS_IMETHODIMP
WSPTestComplexType::GetU64(PRUint64 *aU64)
{
*aU64 = sUint64Val;
return NS_OK;
}
/* readonly attribute PRBool b; */
NS_IMETHODIMP
WSPTestComplexType::GetB(PRBool *aB)
{
*aB = sBoolVal;
return NS_OK;
}
/* readonly attribute float f; */
NS_IMETHODIMP
WSPTestComplexType::GetF(float *aF)
{
*aF = sFloatVal;
return NS_OK;
}
/* readonly attribute double d; */
NS_IMETHODIMP
WSPTestComplexType::GetD(double *aD)
{
*aD = sDoubleVal;
return NS_OK;
}
/* readonly attribute char c */
NS_IMETHODIMP
WSPTestComplexType::GetC(char *aC)
{
*aC = sCharVal;
return NS_OK;
}
/* readonly attribute wchar wc */
NS_IMETHODIMP
WSPTestComplexType::GetWc(PRUnichar *aWC)
{
*aWC = sWcharVal;
return NS_OK;
}
/* readonly attribute nsIWSPTestComplexType p; */
NS_IMETHODIMP
WSPTestComplexType::GetP(nsIWSPTestComplexType * *aP)
{
WSPTestComplexType* inst = new WSPTestComplexType();
if (!inst) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aP = inst;
NS_ADDREF(*aP);
return NS_OK;
}
/* readonly attribute nsIWSPTestComplexType p2; */
NS_IMETHODIMP
WSPTestComplexType::GetP2(nsIWSPTestComplexType * *aP2)
{
*aP2 = nsnull;
return NS_OK;
}
/* readonly attribute AString s; */
NS_IMETHODIMP
WSPTestComplexType::GetS(nsAString & aS)
{
aS.Assign(NS_LITERAL_STRING(STRING_VAL));
return NS_OK;
}
/* void array1 (out PRUint32 length, [array, size_is (length), retval] out PRUint32 array1); */
NS_IMETHODIMP
WSPTestComplexType::Array1(PRUint32 *length, PRUint32 **array1)
{
PRUint32* ptr = (PRUint32*)nsMemory::Alloc(sArray1Length * sizeof(PRUint32));
if (!ptr) {
return NS_ERROR_OUT_OF_MEMORY;
}
PRUint32 index;
for (index = 0; index < sArray1Length; index++) {
ptr[index] = sArray1[index];
}
*length = sArray1Length;
*array1 = ptr;
return NS_OK;
}
/* void array2 (out PRUint32 length, [array, size_is (length), retval] out double array2); */
NS_IMETHODIMP
WSPTestComplexType::Array2(PRUint32 *length, double **array2)
{
double* ptr = (double*)nsMemory::Alloc(sArray2Length * sizeof(double));
if (!ptr) {
return NS_ERROR_OUT_OF_MEMORY;
}
PRUint32 index;
for (index = 0; index < sArray2Length; index++) {
ptr[index] = sArray2[index];
}
*length = sArray2Length;
*array2 = ptr;
return NS_OK;
}
/* void array3 (out PRUint32 length, [array, size_is (length), retval] out nsIWSPTestComplexType array3); */
NS_IMETHODIMP
WSPTestComplexType::Array3(PRUint32 *length, nsIWSPTestComplexType ***array3)
{
nsIWSPTestComplexType** ptr = (nsIWSPTestComplexType**)nsMemory::Alloc(2 *
sizeof(nsISupports*));
if (!ptr) {
return NS_ERROR_OUT_OF_MEMORY;
}
WSPTestComplexType* inst = new WSPTestComplexType();
if (!inst) {
return NS_ERROR_OUT_OF_MEMORY;
}
ptr[0] = inst;
NS_ADDREF(ptr[0]);
ptr[1] = nsnull;
*length = 2;
*array3 = ptr;
return NS_OK;
}
int main (int argc, char* argv[])
{
nsIServiceManager *servMgr;
nsresult rv = NS_InitXPCOM(&servMgr, nsnull);
if (NS_FAILED(rv)) {
printf("failed to initialize XPCOM");
return rv;
}
nsCOMPtr<WSPProxyTest> test = new WSPProxyTest();
if (!test) {
printf("Error creating proxy test instance\n");
return NS_ERROR_OUT_OF_MEMORY;
}
printf("--- Testing complex type wrapper --- \n");
rv = test->TestComplexTypeWrapper();
if (NS_FAILED(rv)) {
printf("--- Test FAILED --- \n");
}
else {
printf("--- Test SUCCEEDED --- \n");
}
printf("--- Testing property bag wrapper --- \n");
rv = test->TestPropertyBagWrapper();
if (NS_FAILED(rv)) {
printf("--- Test FAILED --- \n");
}
else {
printf("--- Test SUCCEEDED --- \n");
}
if (servMgr)
rv = NS_ShutdownXPCOM(servMgr);
return rv;
}

Просмотреть файл

@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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):
* John Bandhauer (jband@netscape.com)
* Vidur Apparao (vidur@netscape.com)
*
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __wspproxytest_h__
#define __wspproxytest_h__
#include "nsIWSPProxyTest.h"
#include "nsIPropertyBag.h"
#include "wspprivate.h"
class WSPProxyTest : public nsIWSPProxyTest {
public:
WSPProxyTest();
virtual ~WSPProxyTest();
NS_DECL_ISUPPORTS
NS_DECL_NSIWSPPROXYTEST
protected:
nsresult CreateComplexTypeWrapper(WSPComplexTypeWrapper** aWrapper,
nsIInterfaceInfo** aInfo);
nsresult TestComplexTypeWrapperInstance(nsIPropertyBag* propBag);
};
class WSPTestComplexType : public nsIWSPTestComplexType {
public:
WSPTestComplexType();
virtual ~WSPTestComplexType();
NS_DECL_ISUPPORTS
NS_DECL_NSIWSPTESTCOMPLEXTYPE
};
#endif // __wspproxytest_h__

Просмотреть файл

@ -290,3 +290,6 @@ interface nsIWebServiceCallContext : nsISupports {
void abort(in nsIException error);
};
%{ C++
#define NS_WEBSERVICEPROXYFACTORY_CONTRACTID "@mozilla.org/xmlextras/proxy/webserviceproxyfactory;1"
%}

Просмотреть файл

@ -290,3 +290,6 @@ interface nsIWebServiceCallContext : nsISupports {
void abort(in nsIException error);
};
%{ C++
#define NS_WEBSERVICEPROXYFACTORY_CONTRACTID "@mozilla.org/xmlextras/proxy/webserviceproxyfactory;1"
%}

Просмотреть файл

@ -0,0 +1,54 @@
#
# 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 Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
ifdef ENABLE_TESTS
DIRS += tests
endif
MODULE = xmlextras
LIBRARY_NAME = xmlextrasproxy_s
REQUIRES = xpcom \
string \
xpconnect \
caps \
js \
necko \
$(NULL)
CPPSRCS= \
wspproxy.cpp \
wspfactory.cpp \
wspcomplextypewrapper.cpp \
wsppropertybagwrapper.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a
# static lib.
FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -21,6 +21,10 @@
DEPTH=..\..\..\..
!if !defined(DISABLE_TESTS)
DIRS=tests
!endif
LIBRARY_NAME=xmlextrasproxy_s
MODULE=xmlextras
@ -35,11 +39,17 @@ REQUIRES = xpcom \
$(NULL)
CPPSRCS= \
wspProxy.cpp \
wspproxy.cpp \
wspfactory.cpp \
wspcomplextypewrapper.cpp \
wsppropertybagwrapper.cpp \
$(NULL)
CPP_OBJS= \
.\$(OBJDIR)\wspProxy.obj \
.\$(OBJDIR)\wspproxy.obj \
.\$(OBJDIR)\wspfactory.obj \
.\$(OBJDIR)\wspcomplextypewrapper.obj \
.\$(OBJDIR)\wsppropertybagwrapper.obj \
$(NULL)
EXPORTS = \

Просмотреть файл

@ -0,0 +1,58 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
REQUIRES = xpcom \
string \
xmlextras \
xpconnect \
caps \
js \
necko \
$(NULL)
XPIDLSRCS = .\nsIWSPProxyTest.idl \
$(NULL)
CPPSRCS = \
wspproxytest.cpp \
$(NULL)
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
include $(topsrcdir)/config/config.mk
LIBS = \
$(DIST)/lib/libxmlextrasproxy_s.$(LIB_SUFFIX) \
$(MOZ_JS_LIBS) \
$(XPCOM_LIBS) \
$(NSPR_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk
DEFINES += -DUSE_NSREG

Просмотреть файл

@ -0,0 +1,63 @@
#!nmake
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..\..\..
XPIDL_MODULE=wsproxytest
XPIDLSRCS = .\nsIWSPProxyTest.idl \
$(NULL)
REQUIRES = xpcom \
string \
xmlextras \
xpconnect \
caps \
js \
necko \
$(NULL)
include <$(DEPTH)/config/config.mak>
MAKE_OBJ_TYPE = EXE
PROG1 = .\$(OBJDIR)\wspproxytest.exe
PROGRAMS = $(PROG1) \
$(NULL)
LCFLAGS = -DUSE_NSREG -GX
LLIBS = \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\xmlextrasproxy_s.lib \
$(LIBNSPR)
LINCS=-I..\
include <$(DEPTH)\config\rules.mak>
install:: $(PROGRAMS)
-for %p in ($(PROGRAMS)) do $(MAKE_INSTALL) %p $(DIST)\bin
clobber::
-for %p in ($(PROGRAMS)) do $(RM) %p $(DIST)\bin\%p
$(PROG1): $(OBJDIR) wspproxytest.cpp

Просмотреть файл

@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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):
* John Bandhauer (jband@netscape.com)
* Vidur Apparao (vidur@netscape.com)
*
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIWebServiceProxy.idl"
[scriptable, uuid(fd25b392-f435-4aea-bbbc-0886f8239dce)]
interface nsIWSPProxyTest : nsISupports {
void testComplexTypeWrapper();
void testPropertyBagWrapper();
};
[uuid(6de70ec8-46fb-49d5-8dac-9d2eae42ea5a)]
interface nsIWSPTestComplexType : nsISupports {
readonly attribute PRUint8 i8;
readonly attribute PRInt16 i16;
readonly attribute PRInt32 i32;
readonly attribute PRInt64 i64;
readonly attribute PRUint8 u8;
readonly attribute PRUint16 u16;
readonly attribute PRUint32 u32;
readonly attribute PRUint64 u64;
readonly attribute PRBool b;
readonly attribute float f;
readonly attribute double d;
readonly attribute char c;
readonly attribute wchar wc;
readonly attribute AString s;
readonly attribute nsIWSPTestComplexType p;
readonly attribute nsIWSPTestComplexType p2;
void array1(out PRUint32 length, [array, retval, size_is(length)] out PRUint32 array1);
void array2(out PRUint32 length, [array, retval, size_is(length)] out double array2);
void array3(out PRUint32 length, [array, retval, size_is(length)] out nsIWSPTestComplexType array3);
};
%{ C++
#define NS_WSPPROXYTEST_CONTRACTID "@mozilla.org/xmlextras/proxy/webserviceproxytest;1"
#define NS_WSPPROXYTEST_CID \
{ /* cdb03ec6-4a5e-4461-996e-16f517e53b87 */ \
0xcdb03ec6, 0x4a5e, 0x4461, \
{0x99, 0x6e, 0x16, 0xf5, 0x17, 0xe5, 0x3b, 0x87} }
%}

Просмотреть файл

@ -0,0 +1,686 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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):
* John Bandhauer (jband@netscape.com)
* Vidur Apparao (vidur@netscape.com)
*
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "wspproxytest.h"
#include "nsAString.h"
#include "nsIInterfaceInfoManager.h"
#include "nsIServiceManager.h"
const PRUint8 sInt8Val = 2;
const PRInt16 sInt16Val = 0x1234;
const PRInt32 sInt32Val = 0x12345678;
#ifdef HAVE_LONG_LONG
const PRInt64 sInt64Val = 0x1234567887654321;
#else
const PRInt64 sInt64Val = {0x12345678, 0x87654321};
#endif
const PRUint8 sUint8Val = 2;
const PRUint16 sUint16Val = 0x1234;
const PRUint32 sUint32Val = 0x12345678;
#ifdef HAVE_LONG_LONG
const PRUint64 sUint64Val = 0x1234567887654321;
#else
const PRUint64 sUint64Val = {0x12345678, 0x87654321};
#endif
const PRBool sBoolVal = PR_TRUE;
const float sFloatVal = 0.0;
const double sDoubleVal = 0.03;
const char sCharVal = 'a';
const PRUnichar sWcharVal = PRUnichar('a');
#define STRING_VAL "Hello world"
const PRUint32 sArray1Length = 3;
const PRUint32 sArray1[] = { 4, 23, 37 };
const PRUint32 sArray2Length = 4;
const double sArray2[] = { 4.234, 23.97, 3434.2945, 0.03 };
WSPProxyTest::WSPProxyTest()
{
NS_INIT_ISUPPORTS();
}
WSPProxyTest::~WSPProxyTest()
{
}
NS_IMPL_ISUPPORTS1(WSPProxyTest, nsIWSPProxyTest)
nsresult
WSPProxyTest::CreateComplexTypeWrapper(WSPComplexTypeWrapper** aWrapper,
nsIInterfaceInfo** aInfo)
{
static nsIID sComplexTypeIID = NS_GET_IID(nsIWSPTestComplexType);
nsCOMPtr<WSPTestComplexType> ct = new WSPTestComplexType();
if (!ct) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult rv;
nsCOMPtr<nsIInterfaceInfoManager> manager = do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIInterfaceInfo> iinfo;
rv = manager->GetInfoForIID(&sComplexTypeIID, getter_AddRefs(iinfo));
if (NS_FAILED(rv)) {
return rv;
}
*aInfo = iinfo;
NS_ADDREF(*aInfo);
return WSPComplexTypeWrapper::Create(ct, iinfo, aWrapper);
}
NS_IMETHODIMP
WSPProxyTest::TestComplexTypeWrapper()
{
nsCOMPtr<nsIInterfaceInfo> info;
nsCOMPtr<WSPComplexTypeWrapper> wrapper;
nsresult rv = CreateComplexTypeWrapper(getter_AddRefs(wrapper),
getter_AddRefs(info));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIPropertyBag> propBag = do_QueryInterface(wrapper);
if (!propBag) {
return NS_ERROR_FAILURE;
}
rv = TestComplexTypeWrapperInstance(propBag);
if (NS_FAILED(rv)) {
return rv;
}
return NS_OK;
}
nsresult
WSPProxyTest::TestComplexTypeWrapperInstance(nsIPropertyBag* propBag)
{
nsCOMPtr<nsISimpleEnumerator> enumerator;
nsresult rv = propBag->GetEnumerator(getter_AddRefs(enumerator));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsISupports> sup;
nsCOMPtr<nsIProperty> prop;
nsCOMPtr<nsIVariant> val;
nsAutoString propName;
#define GET_AND_TEST_NAME(_name) \
rv = enumerator->GetNext(getter_AddRefs(sup)); \
if (NS_FAILED(rv)) { \
printf("WSPProxyTest: Failed getting property " #_name "\n"); \
return rv; \
} \
\
prop = do_QueryInterface(sup, &rv); \
if (NS_FAILED(rv)) { \
return rv; \
} \
\
prop->GetName(propName); \
if (!propName.Equals(NS_LITERAL_STRING(#_name))) { \
printf("WSPProxyTest: Name doesn't match for property " #_name "\n");\
return NS_ERROR_FAILURE; \
} \
prop->GetValue(getter_AddRefs(val)); \
if (!val) { \
return NS_ERROR_FAILURE; \
}
#define GET_AND_TEST(_t, _n, _name, _val) \
GET_AND_TEST_NAME(_name) \
_t _name; \
rv = val->GetAs##_n(&_name); \
if (NS_FAILED(rv)) { \
printf("WSPProxyTest: Failed getting value for property " #_name "\n");\
return rv; \
} \
if (_name != _val) { \
printf("WSPProxyTest: Value doesn't match for property " #_name "\n");\
return NS_ERROR_FAILURE; \
}
GET_AND_TEST(PRUint8, Int8, i8, sInt8Val)
GET_AND_TEST(PRInt16, Int16, i16, sInt16Val)
GET_AND_TEST(PRInt32, Int32, i32, sInt32Val)
GET_AND_TEST(PRInt64, Int64, i64, sInt64Val)
GET_AND_TEST(PRUint8, Uint8, u8, sUint8Val)
GET_AND_TEST(PRUint16, Uint16, u16, sUint16Val)
GET_AND_TEST(PRUint32, Uint32, u32, sUint32Val)
GET_AND_TEST(PRUint64, Uint64, u64, sUint64Val)
GET_AND_TEST(PRBool, Bool, b, sBoolVal)
GET_AND_TEST(float, Float, f, sFloatVal)
GET_AND_TEST(double, Double, d, sDoubleVal)
GET_AND_TEST(char, Char, c, sCharVal)
GET_AND_TEST(PRUnichar, WChar, wc, sWcharVal)
GET_AND_TEST_NAME(s);
nsAutoString str;
rv = val->GetAsAString(str);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for property s\n");
return rv;
}
if (!str.Equals(NS_LITERAL_STRING(STRING_VAL))) {
printf("WSPProxyTest: Value doesn't match for property s\n");
return NS_ERROR_FAILURE;
}
GET_AND_TEST_NAME(p)
nsCOMPtr<nsISupports> supVal;
rv = val->GetAsISupports(getter_AddRefs(supVal));
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for property p\n");
return rv;
}
nsCOMPtr<nsIPropertyBag> propBagVal = do_QueryInterface(supVal, &rv);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Value doesn't match for property p\n");
return rv;
}
GET_AND_TEST_NAME(p2)
PRUint16 dataType;
val->GetDataType(&dataType);
if (dataType != nsIDataType::TYPE_EMPTY) {
printf("WSPProxyTest: Value doesn't match for property p\n");
return NS_ERROR_FAILURE;
}
PRUint16 type;
PRUint32 index, count;
nsIVariant** arrayVal;
GET_AND_TEST_NAME(array1)
rv = val->GetAsArray(&type, &count, (void**)&arrayVal);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for property array1\n");
return rv;
}
for (index = 0; index < count; index++) {
nsIVariant* arrayVar = arrayVal[index];
PRUint32 arrayInt;
rv = arrayVar->GetAsUint32(&arrayInt);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for element of property array1\n");
return rv;
}
if (arrayInt != sArray1[index]) {
printf("WSPProxyTest: Value doesn't match for element of property array1\n");
return rv;
}
}
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, arrayVal);
GET_AND_TEST_NAME(array2)
rv = val->GetAsArray(&type, &count, (void**)&arrayVal);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for property array2\n");
return rv;
}
for (index = 0; index < count; index++) {
nsIVariant* arrayVar = arrayVal[index];
double arrayDouble;
rv = arrayVar->GetAsDouble(&arrayDouble);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for element of property array1\n");
return rv;
}
if (arrayDouble != sArray2[index]) {
printf("WSPProxyTest: Value doesn't match for element of property array1\n");
return rv;
}
}
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, arrayVal);
GET_AND_TEST_NAME(array3)
rv = val->GetAsArray(&type, &count, (void**)&arrayVal);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for property array2\n");
return rv;
}
nsIVariant* array3Var = arrayVal[0];
rv = array3Var->GetAsISupports(getter_AddRefs(supVal));
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed getting value for element of property array3\n");
return rv;
}
propBagVal = do_QueryInterface(supVal, &rv);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Value doesn't match for element of property array3\n");
return rv;
}
array3Var = arrayVal[1];
array3Var->GetDataType(&dataType);
if (dataType != nsIDataType::TYPE_EMPTY) {
printf("WSPProxyTest: Value doesn't match for element of property array3\n");
return NS_ERROR_FAILURE;
}
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, arrayVal);
#undef GET_AND_TEST
#undef GET_AND_TEST_NAME
return NS_OK;
}
NS_IMETHODIMP
WSPProxyTest::TestPropertyBagWrapper()
{
nsCOMPtr<nsIInterfaceInfo> info;
nsCOMPtr<WSPComplexTypeWrapper> ctwrapper;
nsresult rv = CreateComplexTypeWrapper(getter_AddRefs(ctwrapper),
getter_AddRefs(info));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIPropertyBag> propBag = do_QueryInterface(ctwrapper);
if (!propBag) {
return NS_ERROR_FAILURE;
}
WSPPropertyBagWrapper* wrapper;
rv = WSPPropertyBagWrapper::Create(propBag, info, &wrapper);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIWSPTestComplexType> ct = do_QueryInterface(wrapper, &rv);
NS_RELEASE(wrapper);
if (NS_FAILED(rv)) {
return rv;
}
#define GET_AND_TEST(_t, _name, _val) \
_t _name; \
rv = ct->Get##_name(&_name); \
if (NS_FAILED(rv)) { \
printf("WSPProxyTest: Failed to get value for attribute" #_name "\n"); \
return rv; \
} \
if (_name != _val) { \
printf("WSPProxyTest: Value doesn't match for attribute " #_name "\n"); \
return NS_ERROR_FAILURE; \
}
GET_AND_TEST(PRUint8, I8, sInt8Val)
GET_AND_TEST(PRInt16, I16, sInt16Val)
GET_AND_TEST(PRInt32, I32, sInt32Val)
GET_AND_TEST(PRInt64, I64, sInt64Val)
GET_AND_TEST(PRUint8, U8, sUint8Val)
GET_AND_TEST(PRUint16, U16, sUint16Val)
GET_AND_TEST(PRUint32, U32, sUint32Val)
GET_AND_TEST(PRUint64, U64, sUint64Val)
GET_AND_TEST(float, F, sFloatVal)
GET_AND_TEST(double, D, sDoubleVal)
GET_AND_TEST(PRBool, B, sBoolVal)
GET_AND_TEST(char, C, sCharVal)
GET_AND_TEST(PRUnichar, Wc, sWcharVal)
nsAutoString str;
rv = ct->GetS(str);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed to get value for attribute s\n");
return rv;
}
if (!str.Equals(NS_LITERAL_STRING(STRING_VAL))) {
printf("WSPProxyTest: Value doesn't match for attribute s\n");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIWSPTestComplexType> p;
rv = ct->GetP(getter_AddRefs(p));
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed to get value for attribute p\n");
return rv;
}
rv = ct->GetP2(getter_AddRefs(p));
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed to get value for attribute p2\n");
return rv;
}
if (p) {
printf("WSPProxyTest: Value doesn't match for attribute p2\n");
return NS_ERROR_FAILURE;
}
PRUint32 index, count;
PRUint32* array1;
rv = ct->Array1(&count, &array1);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed to get value for attribute array1\n");
return rv;
}
for (index = 0; index < count; index++) {
if (array1[index] != sArray1[index]) {
printf("WSPProxyTest: Value doesn't match for element of attribute array1\n");
return NS_ERROR_FAILURE;
}
}
nsMemory::Free(array1);
double* array2;
rv = ct->Array2(&count, &array2);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed to get value for attribute array2\n");
return rv;
}
for (index = 0; index < count; index++) {
if (array2[index] != sArray2[index]) {
printf("WSPProxyTest: Value doesn't match for element of attribute array2\n");
return NS_ERROR_FAILURE;
}
}
nsMemory::Free(array2);
nsIWSPTestComplexType** array3;
rv = ct->Array3(&count, &array3);
if (NS_FAILED(rv)) {
printf("WSPProxyTest: Failed to get value for attribute array3\n");
return rv;
}
if (!array3[0] || array3[1]) {
printf("WSPProxyTest: Value doesn't match for element of attribute array3\n");
return NS_ERROR_FAILURE;
}
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, array3);
#undef GET_AND_TEST
return NS_OK;
}
WSPTestComplexType::WSPTestComplexType()
{
NS_INIT_ISUPPORTS();
}
WSPTestComplexType::~WSPTestComplexType()
{
}
NS_IMPL_ISUPPORTS1(WSPTestComplexType, nsIWSPTestComplexType)
/* readonly attribute PRUint8 i8; */
NS_IMETHODIMP
WSPTestComplexType::GetI8(PRUint8 *aI8)
{
*aI8 = sInt8Val;
return NS_OK;
}
/* readonly attribute PRInt16 i16; */
NS_IMETHODIMP
WSPTestComplexType::GetI16(PRInt16 *aI16)
{
*aI16 = sInt16Val;
return NS_OK;
}
/* readonly attribute PRInt32 i32; */
NS_IMETHODIMP
WSPTestComplexType::GetI32(PRInt32 *aI32)
{
*aI32 = sInt32Val;
return NS_OK;
}
/* readonly attribute PRInt64 i64; */
NS_IMETHODIMP
WSPTestComplexType::GetI64(PRInt64 *aI64)
{
*aI64 = sInt64Val;
return NS_OK;
}
/* readonly attribute PRUint8 u8; */
NS_IMETHODIMP
WSPTestComplexType::GetU8(PRUint8 *aU8)
{
*aU8 = sUint8Val;
return NS_OK;
}
/* readonly attribute PRUint16 u16; */
NS_IMETHODIMP
WSPTestComplexType::GetU16(PRUint16 *aU16)
{
*aU16 = sUint16Val;
return NS_OK;
}
/* readonly attribute PRUint32 u32; */
NS_IMETHODIMP
WSPTestComplexType::GetU32(PRUint32 *aU32)
{
*aU32 = sUint32Val;
return NS_OK;
}
/* readonly attribute PRUint64 u64; */
NS_IMETHODIMP
WSPTestComplexType::GetU64(PRUint64 *aU64)
{
*aU64 = sUint64Val;
return NS_OK;
}
/* readonly attribute PRBool b; */
NS_IMETHODIMP
WSPTestComplexType::GetB(PRBool *aB)
{
*aB = sBoolVal;
return NS_OK;
}
/* readonly attribute float f; */
NS_IMETHODIMP
WSPTestComplexType::GetF(float *aF)
{
*aF = sFloatVal;
return NS_OK;
}
/* readonly attribute double d; */
NS_IMETHODIMP
WSPTestComplexType::GetD(double *aD)
{
*aD = sDoubleVal;
return NS_OK;
}
/* readonly attribute char c */
NS_IMETHODIMP
WSPTestComplexType::GetC(char *aC)
{
*aC = sCharVal;
return NS_OK;
}
/* readonly attribute wchar wc */
NS_IMETHODIMP
WSPTestComplexType::GetWc(PRUnichar *aWC)
{
*aWC = sWcharVal;
return NS_OK;
}
/* readonly attribute nsIWSPTestComplexType p; */
NS_IMETHODIMP
WSPTestComplexType::GetP(nsIWSPTestComplexType * *aP)
{
WSPTestComplexType* inst = new WSPTestComplexType();
if (!inst) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aP = inst;
NS_ADDREF(*aP);
return NS_OK;
}
/* readonly attribute nsIWSPTestComplexType p2; */
NS_IMETHODIMP
WSPTestComplexType::GetP2(nsIWSPTestComplexType * *aP2)
{
*aP2 = nsnull;
return NS_OK;
}
/* readonly attribute AString s; */
NS_IMETHODIMP
WSPTestComplexType::GetS(nsAString & aS)
{
aS.Assign(NS_LITERAL_STRING(STRING_VAL));
return NS_OK;
}
/* void array1 (out PRUint32 length, [array, size_is (length), retval] out PRUint32 array1); */
NS_IMETHODIMP
WSPTestComplexType::Array1(PRUint32 *length, PRUint32 **array1)
{
PRUint32* ptr = (PRUint32*)nsMemory::Alloc(sArray1Length * sizeof(PRUint32));
if (!ptr) {
return NS_ERROR_OUT_OF_MEMORY;
}
PRUint32 index;
for (index = 0; index < sArray1Length; index++) {
ptr[index] = sArray1[index];
}
*length = sArray1Length;
*array1 = ptr;
return NS_OK;
}
/* void array2 (out PRUint32 length, [array, size_is (length), retval] out double array2); */
NS_IMETHODIMP
WSPTestComplexType::Array2(PRUint32 *length, double **array2)
{
double* ptr = (double*)nsMemory::Alloc(sArray2Length * sizeof(double));
if (!ptr) {
return NS_ERROR_OUT_OF_MEMORY;
}
PRUint32 index;
for (index = 0; index < sArray2Length; index++) {
ptr[index] = sArray2[index];
}
*length = sArray2Length;
*array2 = ptr;
return NS_OK;
}
/* void array3 (out PRUint32 length, [array, size_is (length), retval] out nsIWSPTestComplexType array3); */
NS_IMETHODIMP
WSPTestComplexType::Array3(PRUint32 *length, nsIWSPTestComplexType ***array3)
{
nsIWSPTestComplexType** ptr = (nsIWSPTestComplexType**)nsMemory::Alloc(2 *
sizeof(nsISupports*));
if (!ptr) {
return NS_ERROR_OUT_OF_MEMORY;
}
WSPTestComplexType* inst = new WSPTestComplexType();
if (!inst) {
return NS_ERROR_OUT_OF_MEMORY;
}
ptr[0] = inst;
NS_ADDREF(ptr[0]);
ptr[1] = nsnull;
*length = 2;
*array3 = ptr;
return NS_OK;
}
int main (int argc, char* argv[])
{
nsIServiceManager *servMgr;
nsresult rv = NS_InitXPCOM(&servMgr, nsnull);
if (NS_FAILED(rv)) {
printf("failed to initialize XPCOM");
return rv;
}
nsCOMPtr<WSPProxyTest> test = new WSPProxyTest();
if (!test) {
printf("Error creating proxy test instance\n");
return NS_ERROR_OUT_OF_MEMORY;
}
printf("--- Testing complex type wrapper --- \n");
rv = test->TestComplexTypeWrapper();
if (NS_FAILED(rv)) {
printf("--- Test FAILED --- \n");
}
else {
printf("--- Test SUCCEEDED --- \n");
}
printf("--- Testing property bag wrapper --- \n");
rv = test->TestPropertyBagWrapper();
if (NS_FAILED(rv)) {
printf("--- Test FAILED --- \n");
}
else {
printf("--- Test SUCCEEDED --- \n");
}
if (servMgr)
rv = NS_ShutdownXPCOM(servMgr);
return rv;
}

Просмотреть файл

@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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):
* John Bandhauer (jband@netscape.com)
* Vidur Apparao (vidur@netscape.com)
*
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __wspproxytest_h__
#define __wspproxytest_h__
#include "nsIWSPProxyTest.h"
#include "nsIPropertyBag.h"
#include "wspprivate.h"
class WSPProxyTest : public nsIWSPProxyTest {
public:
WSPProxyTest();
virtual ~WSPProxyTest();
NS_DECL_ISUPPORTS
NS_DECL_NSIWSPPROXYTEST
protected:
nsresult CreateComplexTypeWrapper(WSPComplexTypeWrapper** aWrapper,
nsIInterfaceInfo** aInfo);
nsresult TestComplexTypeWrapperInstance(nsIPropertyBag* propBag);
};
class WSPTestComplexType : public nsIWSPTestComplexType {
public:
WSPTestComplexType();
virtual ~WSPTestComplexType();
NS_DECL_ISUPPORTS
NS_DECL_NSIWSPTESTCOMPLEXTYPE
};
#endif // __wspproxytest_h__

Просмотреть файл

@ -40,7 +40,134 @@
#include "wspprivate.h"
WSPComplexTypeWrapper::WSPComplexTypeWrapper()
// xtpcall includes
#include "xptcall.h"
#include "xptinfo.h"
// xpcom includes
#include "nsIServiceManager.h"
class WSPComplexTypeProperty : public nsIProperty {
public:
WSPComplexTypeProperty(const nsAReadableString& aName,
nsIVariant* aValue);
virtual ~WSPComplexTypeProperty() {}
NS_DECL_ISUPPORTS
NS_DECL_NSIPROPERTY
protected:
nsString mName;
nsCOMPtr<nsIVariant> mValue;
};
WSPComplexTypeProperty::WSPComplexTypeProperty(const nsAReadableString& aName,
nsIVariant* aValue)
: mName(aName), mValue(aValue)
{
NS_INIT_ISUPPORTS();
}
NS_IMPL_ISUPPORTS1(WSPComplexTypeProperty, nsIProperty)
/* readonly attribute AString name; */
NS_IMETHODIMP
WSPComplexTypeProperty::GetName(nsAWritableString & aName)
{
aName.Assign(mName);
return NS_OK;
}
/* readonly attribute nsIVariant value; */
NS_IMETHODIMP
WSPComplexTypeProperty::GetValue(nsIVariant * *aValue)
{
NS_ADDREF(*aValue = mValue);
return NS_OK;
}
class WSPComplexTypeEnumerator : public nsISimpleEnumerator {
public:
WSPComplexTypeEnumerator(WSPComplexTypeWrapper* aWrapper,
nsIInterfaceInfo* aInterfaceInfo);
virtual ~WSPComplexTypeEnumerator() {}
NS_DECL_ISUPPORTS
NS_DECL_NSISIMPLEENUMERATOR
protected:
nsCOMPtr<WSPComplexTypeWrapper> mWrapper;
nsCOMPtr<nsIInterfaceInfo> mInterfaceInfo;
PRUint16 mIndex;
PRUint16 mCount;
};
WSPComplexTypeEnumerator::WSPComplexTypeEnumerator(WSPComplexTypeWrapper* aWrapper, nsIInterfaceInfo* aInterfaceInfo)
: mWrapper(aWrapper), mInterfaceInfo(aInterfaceInfo), mIndex(3)
{
NS_INIT_ISUPPORTS();
if (mInterfaceInfo) {
mInterfaceInfo->GetMethodCount(&mCount);
}
}
NS_IMPL_ISUPPORTS1(WSPComplexTypeEnumerator, nsISimpleEnumerator)
/* boolean hasMoreElements (); */
NS_IMETHODIMP
WSPComplexTypeEnumerator::HasMoreElements(PRBool *_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = mIndex < mCount;
return NS_OK;
}
/* nsISupports getNext (); */
NS_IMETHODIMP
WSPComplexTypeEnumerator::GetNext(nsISupports **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
if (mIndex >= mCount) {
NS_ERROR("Bad nsISimpleEnumerator caller!");
return NS_ERROR_FAILURE;
}
const nsXPTMethodInfo* methodInfo;
nsresult rv = mInterfaceInfo->GetMethodInfo(mIndex, &methodInfo);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIVariant> var;
rv = mWrapper->GetPropertyValue(mIndex++, methodInfo, getter_AddRefs(var));
if (NS_FAILED(rv)) {
return rv;
}
nsAutoString propName;
rv = WSPFactory::MethodToPropertyName(nsDependentCString(methodInfo->GetName()), propName);
if (NS_FAILED(rv)) {
return rv;
}
WSPComplexTypeProperty* prop = new WSPComplexTypeProperty(propName, var);
if (!prop) {
return NS_ERROR_OUT_OF_MEMORY;
}
*_retval = prop;
NS_ADDREF(*_retval);
return NS_OK;
}
WSPComplexTypeWrapper::WSPComplexTypeWrapper(nsISupports* aComplexTypeInstance,
nsIInterfaceInfo* aInterfaceInfo)
: mComplexTypeInstance(aComplexTypeInstance),
mInterfaceInfo(aInterfaceInfo)
{
NS_INIT_ISUPPORTS();
}
@ -49,16 +176,205 @@ WSPComplexTypeWrapper::~WSPComplexTypeWrapper()
{
}
NS_INTERFACE_MAP_BEGIN(WSPComplexTypeWrapper)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIPropertyBag)
NS_INTERFACE_MAP_END
nsresult
WSPComplexTypeWrapper::Create(nsISupports* aComplexTypeInstance,
nsIInterfaceInfo* aInterfaceInfo,
WSPComplexTypeWrapper** aWrapper)
{
NS_ENSURE_ARG(aComplexTypeInstance);
NS_ENSURE_ARG(aInterfaceInfo);
NS_ENSURE_ARG_POINTER(aWrapper);
WSPComplexTypeWrapper* wrapper = new WSPComplexTypeWrapper(aComplexTypeInstance, aInterfaceInfo);
if (!wrapper) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aWrapper = wrapper;
NS_ADDREF(*aWrapper);
return NS_OK;
}
NS_IMPL_ISUPPORTS1(WSPComplexTypeWrapper, nsIPropertyBag)
/* readonly attribute nsISimpleEnumerator enumerator; */
NS_IMETHODIMP
WSPComplexTypeWrapper::GetEnumerator(nsISimpleEnumerator * *aEnumerator)
{
return NS_ERROR_NOT_IMPLEMENTED;
WSPComplexTypeEnumerator* enumerator = new WSPComplexTypeEnumerator(this, mInterfaceInfo);
if (!enumerator) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aEnumerator = enumerator;
NS_ADDREF(*aEnumerator);
return NS_OK;
}
nsresult
WSPComplexTypeWrapper::ResultAsVariant(uint8 aTypeTag,
nsXPTCVariant aResult,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant** aVariant)
{
nsresult rv;
nsCOMPtr<nsIWritableVariant> var = do_CreateInstance(NS_VARIANT_CONTRACTID,
&rv);
if (NS_FAILED(rv)) {
return rv;
}
switch (aTypeTag) {
case nsXPTType::T_I8:
var->SetAsInt8(aResult.val.i8);
break;
case nsXPTType::T_I16:
var->SetAsInt16(aResult.val.i16);
break;
case nsXPTType::T_I32:
var->SetAsInt32(aResult.val.i32);
break;
case nsXPTType::T_I64:
var->SetAsInt64(aResult.val.i64);
break;
case nsXPTType::T_U8:
var->SetAsUint8(aResult.val.u8);
break;
case nsXPTType::T_U16:
var->SetAsUint16(aResult.val.u16);
break;
case nsXPTType::T_U32:
var->SetAsUint32(aResult.val.u32);
break;
case nsXPTType::T_U64:
var->SetAsUint64(aResult.val.u64);
break;
case nsXPTType::T_FLOAT:
var->SetAsFloat(aResult.val.f);
break;
case nsXPTType::T_DOUBLE:
var->SetAsDouble(aResult.val.d);
break;
case nsXPTType::T_BOOL:
var->SetAsBool(aResult.val.b);
break;
case nsXPTType::T_CHAR:
var->SetAsChar(aResult.val.c);
break;
case nsXPTType::T_WCHAR:
var->SetAsWChar(aResult.val.wc);
break;
case nsXPTType::T_DOMSTRING:
var->SetAsAString(*((nsAString*)aResult.val.p));
break;
case nsXPTType::T_INTERFACE:
{
nsISupports* instance = (nsISupports*)aResult.val.p;
if (instance) {
// Rewrap an interface instance in a property bag
nsCOMPtr<WSPComplexTypeWrapper> wrapper;
rv = Create(instance, aInterfaceInfo,
getter_AddRefs(wrapper));
if (NS_FAILED(rv)) {
return rv;
}
var->SetAsInterface(NS_GET_IID(nsIPropertyBag), wrapper);
NS_RELEASE(instance);
}
else {
var->SetAsEmpty();
}
break;
}
default:
NS_ERROR("Bad attribute type for complex type interface");
rv = NS_ERROR_FAILURE;
}
*aVariant = var;
NS_ADDREF(*aVariant);
return rv;
}
nsresult
WSPComplexTypeWrapper::ArrayResultAsVariant(uint8 aTypeTag,
nsXPTCVariant aResult,
PRUint32 aLength,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant** aVariant)
{
nsresult rv;
nsCOMPtr<nsIWritableVariant> retvar = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return rv;
}
if (aLength) {
nsIVariant** entries = (nsIVariant**)nsMemory::Alloc(aLength * sizeof(nsIVariant*));
if (!entries) {
return NS_ERROR_OUT_OF_MEMORY;
}
PRUint32 i = 0;
nsXPTCVariant var;
void* array = aResult.val.p;
nsCOMPtr<nsIVariant> element;
#define POPULATE(_t,_v) \
PR_BEGIN_MACRO \
for(i = 0; i < aLength; i++) \
{ \
var.type = aTypeTag; \
var.val._v = *((_t*)array + i); \
rv = ResultAsVariant(aTypeTag, var, aInterfaceInfo, \
entries+i); \
if (NS_FAILED(rv)) { \
break; \
} \
} \
PR_END_MACRO
switch (aTypeTag) {
case nsXPTType::T_I8: POPULATE(PRInt8, i8); break;
case nsXPTType::T_I16: POPULATE(PRInt16, i16); break;
case nsXPTType::T_I32: POPULATE(PRInt32, i32); break;
case nsXPTType::T_I64: POPULATE(PRInt64, i64); break;
case nsXPTType::T_U8: POPULATE(PRUint8, u8); break;
case nsXPTType::T_U16: POPULATE(PRUint16, u16); break;
case nsXPTType::T_U32: POPULATE(PRUint32, u32); break;
case nsXPTType::T_U64: POPULATE(PRUint64, u64); break;
case nsXPTType::T_FLOAT: POPULATE(float, f); break;
case nsXPTType::T_DOUBLE: POPULATE(double, d); break;
case nsXPTType::T_BOOL: POPULATE(PRBool, b); break;
case nsXPTType::T_CHAR: POPULATE(char, c); break;
case nsXPTType::T_WCHAR: POPULATE(PRUnichar, wc); break;
case nsXPTType::T_INTERFACE: POPULATE(nsISupports*, p); break;
}
#undef POPULATE
if (NS_SUCCEEDED(rv)) {
rv = retvar->SetAsArray(nsIDataType::TYPE_INTERFACE, aLength, entries);
}
// Even if we failed while converting, we want to release
// the entries that were already created.
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(i, entries);
}
else {
retvar->SetAsEmpty();
}
if (NS_SUCCEEDED(rv)) {
*aVariant = retvar;
NS_ADDREF(*aVariant);
}
return rv;
}
/* nsIVariant getProperty (in AString name); */
@ -66,5 +382,138 @@ NS_IMETHODIMP
WSPComplexTypeWrapper::GetProperty(const nsAString & name,
nsIVariant **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
NS_ENSURE_ARG_POINTER(_retval);
nsCAutoString methodName;
WSPFactory::PropertyToMethodName(name, methodName);
const nsXPTMethodInfo* methodInfo;
PRUint16 methodIndex;
nsresult rv = mInterfaceInfo->GetMethodInfoForName(methodName.get(),
&methodIndex,
&methodInfo);
if (NS_FAILED(rv)) {
return rv;
}
return GetPropertyValue(methodIndex, methodInfo, _retval);
}
nsresult
WSPComplexTypeWrapper::GetPropertyValue(PRUint32 aMethodIndex,
const nsXPTMethodInfo* aMethodInfo,
nsIVariant** _retval)
{
nsresult rv;
nsAutoString outstr;
PRUint32 numParams;
nsXPTCVariant var[2];
uint8 type_tag;
nsXPTType arrayType;
nsCOMPtr<nsIInterfaceInfo> iinfo;
var[0].ClearFlags();
var[1].ClearFlags();
// There are two possibilities here: a getter or a
// method that returns array and array size out parameters.
if (aMethodInfo->IsGetter()) {
// If it's a getter make sure that it takes just a single (out) param
if (aMethodInfo->GetParamCount() != 1) {
return NS_ERROR_FAILURE;
}
const nsXPTParamInfo& paramInfo = aMethodInfo->GetParam(0);
const nsXPTType& type = paramInfo.GetType();
type_tag = type.TagPart();
numParams = 1;
var[0].type = type_tag;
if (paramInfo.IsOut()) {
var[0].SetPtrIsData();
var[0].ptr = &var[0].val;
}
else if (paramInfo.IsDipper() && type.IsPointer() &&
(type_tag == nsXPTType::T_DOMSTRING)) {
var[0].val.p = &outstr;
}
else {
NS_ERROR("Unexpected parameter type for getter");
return NS_ERROR_FAILURE;
}
if (type_tag == nsXPTType::T_INTERFACE) {
rv = mInterfaceInfo->GetInfoForParam(aMethodIndex, &paramInfo,
getter_AddRefs(iinfo));
if (NS_FAILED(rv)) {
return rv;
}
}
}
// If it isn't a getter, then it has to be an array
// getter method
else {
// It must take two parameters for this to work
if (aMethodInfo->GetParamCount() != 2) {
return NS_ERROR_FAILURE;
}
numParams = 2;
// The first parameter must be "out PRUint32"
const nsXPTParamInfo& paramInfo1 = aMethodInfo->GetParam(0);
const nsXPTType& type1 = paramInfo1.GetType();
if (!paramInfo1.IsOut() || (type1.TagPart() != nsXPTType::T_U32)) {
NS_ERROR("Unexpected parameter type for getter");
return NS_ERROR_FAILURE;
}
var[0].type = nsXPTType::T_U32;
var[0].SetPtrIsData();
var[0].ptr = &var[0].val;
// The second parameter must be "[array] out"
const nsXPTParamInfo& paramInfo2 = aMethodInfo->GetParam(1);
const nsXPTType& type2 = paramInfo2.GetType();
type_tag = type2.TagPart();
if (!paramInfo2.IsOut() || !type2.IsArray()) {
NS_ERROR("Unexpected parameter type for getter");
return NS_ERROR_FAILURE;
}
var[1].type = type_tag;
var[1].SetPtrIsData();
var[1].ptr = &var[1].val;
rv = mInterfaceInfo->GetTypeForParam(aMethodIndex, &paramInfo2,
1, &arrayType);
if (NS_FAILED(rv)) {
return rv;
}
if (arrayType.IsInterfacePointer()) {
rv = mInterfaceInfo->GetInfoForParam(aMethodIndex, &paramInfo2,
getter_AddRefs(iinfo));
if (NS_FAILED(rv)) {
return rv;
}
}
}
rv = XPTC_InvokeByIndex(mComplexTypeInstance, aMethodIndex,
numParams, var);
if (NS_FAILED(rv)) {
return rv;
}
if (type_tag == nsXPTType::T_ARRAY) {
rv = ArrayResultAsVariant(arrayType.TagPart(), var[1],
var[0].val.u32, iinfo, _retval);
}
else {
rv = ResultAsVariant(type_tag, var[0], iinfo, _retval);
}
return rv;
}

Просмотреть файл

@ -0,0 +1,146 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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):
* John Bandhauer (jband@netscape.com)
* Vidur Apparao (vidur@netscape.com)
*
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "wspprivate.h"
// NSPR includes
#include "prprf.h"
WSPFactory::WSPFactory()
{
NS_INIT_ISUPPORTS();
}
WSPFactory::~WSPFactory()
{
}
NS_IMPL_ISUPPORTS1(WSPFactory, nsIWebServiceProxyFactory)
/* nsIWebServiceProxy createProxy (in AString wsdlURL, in AString portname, in AString qualifier, in boolean isAsync); */
NS_IMETHODIMP
WSPFactory::CreateProxy(const nsAString & wsdlURL,
const nsAString & portname,
const nsAString & qualifier,
PRBool isAsync,
nsIWebServiceProxy **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void createProxyAsync (in AString wsdlURL, in AString portname, in AString qualifier, in boolean isAsync, in nsIWebServiceProxyListener listener); */
NS_IMETHODIMP
WSPFactory::CreateProxyAsync(const nsAString & wsdlURL,
const nsAString & portname,
const nsAString & qualifier,
PRBool isAsync,
nsIWebServiceProxyListener *listener)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
#define P2M_ESCAPE_CHARACTER '_'
nsresult
WSPFactory::MethodToPropertyName(const nsAReadableCString& aMethodName,
nsAWritableString& aPropertyName)
{
nsReadingIterator<char> current, end;
aPropertyName.Truncate();
aMethodName.BeginReading(current);
aMethodName.EndReading(end);
while (current != end) {
char ch = *current++;
PRUnichar uch;
if (ch == P2M_ESCAPE_CHARACTER) {
// Grab the next 4 characters that make up the
// escape sequence
char buf[5];
for (PRUint16 i = 0; (i < 4) && (current != end); i++) {
buf[i] = *current++;
}
// If we didn't get through the entire escape sequence, then
// it's an error.
if (i < 4) {
return NS_ERROR_FAILURE;
}
buf[4] = 0;
PR_sscanf(buf, "%hx", &uch);
}
else {
uch = PRUnichar(ch);
}
aPropertyName.Append(uch);
}
return NS_OK;
}
void
WSPFactory::PropertyToMethodName(const nsAReadableString& aPropertyName,
nsAWritableCString& aMethodName)
{
nsReadingIterator<PRUnichar> current, end;
aMethodName.Truncate();
aPropertyName.BeginReading(current);
aPropertyName.EndReading(end);
while (current != end) {
PRUnichar uch = *current++;
if (((PRUnichar('a') <= uch) && (uch <= PRUnichar('z'))) ||
((PRUnichar('A') <= uch) && (uch <= PRUnichar('Z'))) ||
((PRUnichar('0') <= uch) && (uch <= PRUnichar('9')))) {
// Casting is safe since we know that it's an ASCII character
aMethodName.Append(char(uch));
}
else {
// Escape the character and append to the string
char buf[6];
buf[0] = P2M_ESCAPE_CHARACTER;
PR_snprintf(buf+1, 5, "%hx", uch);
aMethodName.Append(buf, 5);
}
}
}

Просмотреть файл

@ -65,6 +65,11 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBSERVICEPROXYFACTORY
static nsresult MethodToPropertyName(const nsAReadableCString& aMethodName,
nsAWritableString& aPropertyName);
static void PropertyToMethodName(const nsAReadableString& aPropertyName,
nsAWritableCString& aMethodName);
};
class WSPProxy : public nsXPTCStubBase,
@ -124,7 +129,8 @@ protected:
class WSPComplexTypeWrapper : public nsIPropertyBag
{
public:
WSPComplexTypeWrapper();
WSPComplexTypeWrapper(nsISupports* aComplexTypeInstance,
nsIInterfaceInfo* aInterfaceInfo);
virtual ~WSPComplexTypeWrapper();
NS_DECL_ISUPPORTS
@ -134,6 +140,20 @@ public:
nsIInterfaceInfo* aInterfaceInfo,
WSPComplexTypeWrapper** aWrapper);
nsresult GetPropertyValue(PRUint32 aMethodIndex,
const nsXPTMethodInfo* aMethodInfo,
nsIVariant** _retval);
protected:
nsresult ResultAsVariant(uint8 aTypeTag,
nsXPTCVariant aResult,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant** aVariant);
nsresult ArrayResultAsVariant(uint8 aTypeTag,
nsXPTCVariant aResult,
PRUint32 aLength,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant** aVariant);
protected:
nsCOMPtr<nsISupports> mComplexTypeInstance;
nsCOMPtr<nsIInterfaceInfo> mInterfaceInfo;
@ -142,7 +162,8 @@ protected:
class WSPPropertyBagWrapper : public nsXPTCStubBase
{
public:
WSPPropertyBagWrapper();
WSPPropertyBagWrapper(nsIPropertyBag* aPropertyBag,
nsIInterfaceInfo* aInterfaceInfo);
virtual ~WSPPropertyBagWrapper();
NS_DECL_ISUPPORTS
@ -156,10 +177,20 @@ public:
static nsresult Create(nsIPropertyBag* aPropertyBag,
nsIInterfaceInfo* aInterfaceInfo,
WSPPropertyBagWrapper** aWrapper);
protected:
nsresult VariantToResult(uint8 aTypeTag,
void* aResult,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant* aProperty);
nsresult VariantToArrayResult(uint8 aTypeTag,
nsXPTCMiniVariant* aResult,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant* aProperty);
protected:
nsCOMPtr<nsIPropertyBag> mPropertyBag;
nsCOMPtr<nsIInterfaceInfo> mInterfaceInfo;
const nsIID* mIID;
};
#endif // __wspprivate_h__

Просмотреть файл

@ -0,0 +1,379 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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):
* John Bandhauer (jband@netscape.com)
* Vidur Apparao (vidur@netscape.com)
*
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "wspprivate.h"
WSPPropertyBagWrapper::WSPPropertyBagWrapper(nsIPropertyBag* aPropertyBag,
nsIInterfaceInfo* aInterfaceInfo)
: mPropertyBag(aPropertyBag), mInterfaceInfo(aInterfaceInfo)
{
NS_INIT_ISUPPORTS();
mInterfaceInfo->GetIIDShared(&mIID);
}
WSPPropertyBagWrapper::~WSPPropertyBagWrapper()
{
}
nsresult
WSPPropertyBagWrapper::Create(nsIPropertyBag* aPropertyBag,
nsIInterfaceInfo* aInterfaceInfo,
WSPPropertyBagWrapper** aWrapper)
{
NS_ENSURE_ARG(aPropertyBag);
NS_ENSURE_ARG(aInterfaceInfo);
NS_ENSURE_ARG_POINTER(aWrapper);
WSPPropertyBagWrapper* wrapper = new WSPPropertyBagWrapper(aPropertyBag,
aInterfaceInfo);
if (!wrapper) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aWrapper = wrapper;
NS_ADDREF(*aWrapper);
return NS_OK;
}
NS_IMPL_ADDREF(WSPPropertyBagWrapper)
NS_IMPL_RELEASE(WSPPropertyBagWrapper)
NS_IMETHODIMP
WSPPropertyBagWrapper::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if(aIID.Equals(*mIID) || aIID.Equals(NS_GET_IID(nsISupports))) {
*aInstancePtr = NS_STATIC_CAST(nsISupports*, this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_ERROR_NO_INTERFACE;
}
nsresult
WSPPropertyBagWrapper::VariantToResult(uint8 aTypeTag,
void* aResult,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant* aProperty)
{
nsresult rv;
switch(aTypeTag) {
case nsXPTType::T_I8:
rv = aProperty->GetAsInt8((PRUint8*)aResult);
break;
case nsXPTType::T_I16:
rv = aProperty->GetAsInt16((PRInt16*)aResult);
break;
case nsXPTType::T_I32:
rv = aProperty->GetAsInt32((PRInt32*)aResult);
break;
case nsXPTType::T_I64:
rv = aProperty->GetAsInt64((PRInt64*)aResult);
break;
case nsXPTType::T_U8:
rv = aProperty->GetAsUint8((PRUint8*)aResult);
break;
case nsXPTType::T_U16:
rv = aProperty->GetAsUint16((PRUint16*)aResult);
break;
case nsXPTType::T_U32:
rv = aProperty->GetAsUint32((PRUint32*)aResult);
break;
case nsXPTType::T_U64:
rv = aProperty->GetAsUint64((PRUint64*)aResult);
break;
case nsXPTType::T_FLOAT:
rv = aProperty->GetAsFloat((float*)aResult);
break;
case nsXPTType::T_DOUBLE:
rv = aProperty->GetAsDouble((double*)aResult);
break;
case nsXPTType::T_BOOL:
rv = aProperty->GetAsBool((PRBool*)aResult);
break;
case nsXPTType::T_CHAR:
rv = aProperty->GetAsChar((char*)aResult);
break;
case nsXPTType::T_WCHAR:
rv = aProperty->GetAsWChar((PRUnichar*)aResult);
break;
case nsXPTType::T_DOMSTRING:
rv = aProperty->GetAsAString(*(nsAString*)aResult);
break;
case nsXPTType::T_INTERFACE:
{
PRUint16 dataType;
aProperty->GetDataType(&dataType);
if (dataType == nsIDataType::TYPE_EMPTY) {
*(nsISupports**)aResult = nsnull;
}
else {
nsCOMPtr<nsISupports> sup;
rv = aProperty->GetAsISupports(getter_AddRefs(sup));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIPropertyBag> propBag = do_QueryInterface(sup, &rv);
if (NS_FAILED(rv)) {
return rv;
}
WSPPropertyBagWrapper* wrapper;
rv = Create(propBag, aInterfaceInfo, &wrapper);
if (NS_FAILED(rv)) {
return rv;
}
const nsIID* iid;
aInterfaceInfo->GetIIDShared(&iid);
rv = wrapper->QueryInterface(*iid, (void**)aResult);
NS_RELEASE(wrapper);
}
break;
}
default:
NS_ERROR("Bad attribute type for complex type interface");
rv = NS_ERROR_FAILURE;
}
return rv;
}
nsresult
WSPPropertyBagWrapper::VariantToArrayResult(uint8 aTypeTag,
nsXPTCMiniVariant* aResult,
nsIInterfaceInfo* aInterfaceInfo,
nsIVariant* aProperty)
{
void* array;
PRUint16 type;
PRUint32 count;
nsresult rv = aProperty->GetAsArray(&type, &count, &array);
if (NS_FAILED(rv)) {
return rv;
}
// We assume it's an array of variants.
// XXX need a way to confirm that
if (type != nsIDataType::TYPE_INTERFACE) {
return NS_ERROR_FAILURE;
}
nsIVariant** variants = (nsIVariant**)array;
PRUint32 size;
// Allocate the array
switch (aTypeTag) {
case nsXPTType::T_I8:
case nsXPTType::T_U8:
size = sizeof(PRUint8);
break;
case nsXPTType::T_I16:
case nsXPTType::T_U16:
size = sizeof(PRUint16);
break;
case nsXPTType::T_I32:
case nsXPTType::T_U32:
size = sizeof(PRUint32);
break;
case nsXPTType::T_I64:
case nsXPTType::T_U64:
size = sizeof(PRUint64);
break;
case nsXPTType::T_FLOAT:
size = sizeof(float);
break;
case nsXPTType::T_DOUBLE:
size = sizeof(double);
break;
case nsXPTType::T_BOOL:
size = sizeof(PRBool);
break;
case nsXPTType::T_CHAR:
size = sizeof(char);
break;
case nsXPTType::T_WCHAR:
size = sizeof(PRUnichar);
break;
case nsXPTType::T_INTERFACE:
size = sizeof(nsISupports*);
break;
default:
NS_ERROR("Unexpected array type");
return NS_ERROR_FAILURE;
}
void* outptr = nsMemory::Alloc(count * size);
if (!outptr) {
return NS_ERROR_OUT_OF_MEMORY;
}
PRUint32 i;
for (i = 0; i < count; i++) {
rv = VariantToResult(aTypeTag, (void*)((char*)outptr + (i*size)),
aInterfaceInfo, variants[i]);
if (NS_FAILED(rv)) {
break;
}
}
// Free the variant array passed back to us
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, variants);
// If conversion failed, free the allocated structures
if (NS_FAILED(rv)) {
if (aTypeTag == nsXPTType::T_INTERFACE) {
nsMemory::Free(outptr);
}
else {
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(i, (nsISupports**)outptr);
}
return rv;
}
*((PRUint32*)aResult[0].val.p) = count;
*((void**)aResult[1].val.p) = outptr;
return NS_OK;
}
NS_IMETHODIMP
WSPPropertyBagWrapper::CallMethod(PRUint16 methodIndex,
const nsXPTMethodInfo* info,
nsXPTCMiniVariant* params)
{
nsresult rv = NS_OK;
nsAutoString propName;
nsCOMPtr<nsIVariant> val;
if (methodIndex < 3) {
NS_ERROR("WSPPropertyBagWrapper: bad method index");
return NS_ERROR_FAILURE;
}
else {
rv = WSPFactory::MethodToPropertyName(nsDependentCString(info->GetName()),
propName);
if (NS_FAILED(rv)) {
return rv;
}
rv = mPropertyBag->GetProperty(propName, getter_AddRefs(val));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIInterfaceInfo> iinfo;
if (info->IsGetter()) {
const nsXPTParamInfo& paramInfo = info->GetParam(0);
const nsXPTType& type = paramInfo.GetType();
uint8 type_tag = type.TagPart();
if (type_tag == nsXPTType::T_INTERFACE) {
rv = mInterfaceInfo->GetInfoForParam(methodIndex, &paramInfo,
getter_AddRefs(iinfo));
if (NS_FAILED(rv)) {
return rv;
}
}
rv = VariantToResult(type_tag, params[0].val.p, iinfo, val);
}
else if (info->GetParamCount() == 2) {
// If it's not an explicit getter, it has to be an array
// getter method.
// The first parameter should be the array length out param
const nsXPTParamInfo& paramInfo1 = info->GetParam(0);
const nsXPTType& type1 = paramInfo1.GetType();
if (!paramInfo1.IsOut() || (type1.TagPart() != nsXPTType::T_U32)) {
NS_ERROR("Unexpected parameter type for getter");
return NS_ERROR_FAILURE;
}
// The second parameter should be the array out pointer
// itself.
const nsXPTParamInfo& paramInfo2 = info->GetParam(1);
const nsXPTType& type2 = paramInfo2.GetType();
if (!paramInfo2.IsOut() || !type2.IsArray()) {
NS_ERROR("Unexpected parameter type for getter");
return NS_ERROR_FAILURE;
}
nsXPTType arrayType;
rv = mInterfaceInfo->GetTypeForParam(methodIndex, &paramInfo2,
1, &arrayType);
if (NS_FAILED(rv)) {
return rv;
}
if (arrayType.IsInterfacePointer()) {
rv = mInterfaceInfo->GetInfoForParam(methodIndex, &paramInfo2,
getter_AddRefs(iinfo));
if (NS_FAILED(rv)) {
return rv;
}
}
rv = VariantToArrayResult(arrayType.TagPart(), params, iinfo, val);
}
else {
NS_ERROR("Unexpected method signature for property bag wrapper");
return NS_ERROR_FAILURE;
}
}
return rv;
}
NS_IMETHODIMP
WSPPropertyBagWrapper::GetInterfaceInfo(nsIInterfaceInfo** info)
{
NS_ENSURE_ARG_POINTER(info);
*info = mInterfaceInfo;
NS_ADDREF(*info);
return NS_OK;
}