r=shaver sr=darin git-svn-id: svn://10.0.0.236/trunk@170990 18797224-902f-48f8-a5cc-f745e15eee43
1352 lines
37 KiB
C++
1352 lines
37 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Netscape Communications Corporation.
|
|
* Portions created by the Initial Developer are Copyright (C) 2001
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Vidur Apparao (vidur@netscape.com) (Original author)
|
|
* John Bandhauer (jband@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 MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#include "wspprivate.h"
|
|
#include "nsAutoPtr.h"
|
|
#include "nsIWSDL.h"
|
|
#include "nsIWSDLSOAPBinding.h"
|
|
#include "nsISchema.h"
|
|
#include "nsISOAPParameter.h"
|
|
#include "nsISOAPHeaderBlock.h"
|
|
#include "nsISOAPEncoding.h"
|
|
#include "nsIComponentManager.h"
|
|
#include "nsIVariant.h"
|
|
#include "nsVoidArray.h"
|
|
|
|
#define NS_SOAP_1_1_ENCODING_NAMESPACE \
|
|
"http://schemas.xmlsoap.org/soap/encoding/"
|
|
#define NS_SOAP_1_2_ENCODING_NAMESPACE \
|
|
"http://www.w3.org/2001/09/soap-encoding"
|
|
|
|
WSPProxy::WSPProxy()
|
|
: mIID(nsnull)
|
|
{
|
|
}
|
|
|
|
WSPProxy::~WSPProxy()
|
|
{
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
WSPProxy::Init(nsIWSDLPort* aPort, nsIInterfaceInfo* aPrimaryInterface,
|
|
nsIInterfaceInfoManager* aInterfaceInfoManager,
|
|
const nsAString& aQualifier, PRBool aIsAsync)
|
|
{
|
|
NS_ENSURE_ARG(aPort);
|
|
NS_ENSURE_ARG(aPrimaryInterface);
|
|
|
|
mPort = aPort;
|
|
mPrimaryInterface = aPrimaryInterface;
|
|
mInterfaceInfoManager = aInterfaceInfoManager;
|
|
mPrimaryInterface->GetIIDShared(&mIID);
|
|
mQualifier.Assign(aQualifier);
|
|
mIsAsync = aIsAsync;
|
|
|
|
nsresult rv;
|
|
|
|
mInterfaces = do_CreateInstance(NS_SCRIPTABLE_INTERFACES_CONTRACTID, &rv);
|
|
if (!mInterfaces) {
|
|
return rv;
|
|
}
|
|
|
|
rv = mInterfaces->SetManager(mInterfaceInfoManager);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
if (mIsAsync) {
|
|
// Get the completion method info
|
|
const nsXPTMethodInfo* listenerGetter;
|
|
rv = mPrimaryInterface->GetMethodInfo(3, &listenerGetter);
|
|
if (NS_FAILED(rv)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
const nsXPTParamInfo& listenerParam = listenerGetter->GetParam(0);
|
|
const nsXPTType& type = listenerParam.GetType();
|
|
if (!type.IsInterfacePointer()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
rv = mPrimaryInterface->GetInfoForParam(3, &listenerParam,
|
|
getter_AddRefs(mListenerInterfaceInfo));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_METHOD
|
|
WSPProxy::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aInstancePtr);
|
|
NS_ENSURE_NO_AGGREGATION(outer);
|
|
|
|
WSPProxy* proxy = new WSPProxy();
|
|
if (!proxy) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
NS_ADDREF(proxy);
|
|
nsresult rv = proxy->QueryInterface(aIID, aInstancePtr);
|
|
NS_RELEASE(proxy);
|
|
return rv;
|
|
}
|
|
|
|
NS_IMPL_ADDREF(WSPProxy)
|
|
NS_IMPL_RELEASE(WSPProxy)
|
|
|
|
NS_IMETHODIMP
|
|
WSPProxy::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
{
|
|
if((mIID && aIID.Equals(*mIID)) || aIID.Equals(NS_GET_IID(nsISupports))) {
|
|
*aInstancePtr = NS_STATIC_CAST(nsXPTCStubBase*, this);
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
else if (aIID.Equals(NS_GET_IID(nsIWebServiceProxy))) {
|
|
*aInstancePtr = NS_STATIC_CAST(nsIWebServiceProxy*, this);
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
else if (aIID.Equals(NS_GET_IID(nsIClassInfo))) {
|
|
*aInstancePtr = NS_STATIC_CAST(nsIClassInfo*, this);
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_ERROR_NO_INTERFACE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////
|
|
//
|
|
// Implementation of nsXPTCStubBase methods
|
|
//
|
|
///////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Asynchronous processing :
|
|
* 1-> WSPProxy::CallMethod
|
|
* 2 -> WSPCallContext::CallAsync
|
|
* 3 -> nsSOAPCall::AsyncInvoke
|
|
* 4 -> nsXXXSOAPTransport::AsyncCall
|
|
* 5 -> nsIXMLHttpRequest::Send, nsXXXSOAPTransportCompletion::AddEventListener
|
|
* ---- asynchronous ----
|
|
* 6 -> nsXXXSOAPTransportCompletion::HandleEvent
|
|
* 7 -> WSPCallContext::HandleResponse,
|
|
* WSPCallContext::CallCompletionListener
|
|
* 8 -> nsSOAPBlock::SetSchemaType, nsSOAPBlock::GetValue
|
|
* 9 -> nsSOAPEncoding::Decode, nsDefaultSOAPDecode::Decode
|
|
* 10 -> WSPProxy::CallCompleted
|
|
*/
|
|
NS_IMETHODIMP
|
|
WSPProxy::CallMethod(PRUint16 methodIndex,
|
|
const nsXPTMethodInfo* info,
|
|
nsXPTCMiniVariant* params)
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsIWebServiceCallContext> cc;
|
|
nsCOMPtr<nsIWSDLBinding> binding;
|
|
|
|
if (methodIndex < 3) {
|
|
NS_ERROR("WSPProxy: bad method index");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// The first method in the interface for async callers is the
|
|
// one to set the async listener
|
|
if (mIsAsync && (methodIndex == 3)) {
|
|
nsISupports* listener = NS_STATIC_CAST(nsISupports*, params[0].val.p);
|
|
mAsyncListener = listener;
|
|
return NS_OK;
|
|
}
|
|
|
|
PRUint32 methodOffset;
|
|
if (mIsAsync) {
|
|
methodOffset = 4;
|
|
}
|
|
else {
|
|
methodOffset = 3;
|
|
}
|
|
|
|
nsCOMPtr<nsIWSDLOperation> operation;
|
|
rv = mPort->GetOperation(methodIndex - methodOffset,
|
|
getter_AddRefs(operation));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
nsCOMPtr<nsIWSDLMessage> input;
|
|
rv = operation->GetInput(getter_AddRefs(input));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
// Create the call instance
|
|
nsCOMPtr<nsISOAPCall> call = do_CreateInstance(NS_SOAPCALL_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
nsCOMPtr<nsISOAPEncoding> encoding =
|
|
do_CreateInstance(NS_SOAPENCODING_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
call->SetEncoding(encoding);
|
|
|
|
// Get the method name and target object uri
|
|
nsAutoString methodName, targetObjectURI;
|
|
rv = operation->GetBinding(getter_AddRefs(binding));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
nsCOMPtr<nsISOAPOperationBinding> operationBinding =
|
|
do_QueryInterface(binding, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
nsAutoString soapAction;
|
|
operationBinding->GetSoapAction(soapAction);
|
|
call->SetActionURI(soapAction);
|
|
|
|
PRUint16 style;
|
|
operationBinding->GetStyle(&style);
|
|
// If the style is RPC, find the method name and target object URI.
|
|
// If it is document-style, these are both left blank.
|
|
if (style == nsISOAPPortBinding::STYLE_RPC) {
|
|
operation->GetName(methodName);
|
|
rv = input->GetBinding(getter_AddRefs(binding));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
nsCOMPtr<nsISOAPMessageBinding> messageBinding =
|
|
do_QueryInterface(binding, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
messageBinding->GetNamespace(targetObjectURI);
|
|
}
|
|
|
|
// Set the transport URI
|
|
rv = mPort->GetBinding(getter_AddRefs(binding));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
nsCOMPtr<nsISOAPPortBinding> portBinding = do_QueryInterface(binding, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
nsAutoString address;
|
|
portBinding->GetAddress(address);
|
|
rv = call->SetTransportURI(address);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
PRUint16 version;
|
|
portBinding->GetSoapVersion(&version);
|
|
if (version == nsISOAPMessage::VERSION_UNKNOWN) {
|
|
version = nsISOAPMessage::VERSION_1_1;
|
|
}
|
|
|
|
// Set up the parameters to the call
|
|
PRUint32 i, partCount;
|
|
input->GetPartCount(&partCount);
|
|
|
|
PRUint32 maxParamIndex = info->GetParamCount()-1;
|
|
|
|
// Iterate through the parts to figure out how many are
|
|
// body vs. header blocks
|
|
nsCOMPtr<nsIWSDLPart> part;
|
|
PRUint32 headerCount = 0, bodyCount = 0;
|
|
|
|
for (i = 0; i < partCount; i++) {
|
|
rv = input->GetPart(i, getter_AddRefs(part));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
rv = part->GetBinding(getter_AddRefs(binding));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
nsCOMPtr<nsISOAPPartBinding> partBinding = do_QueryInterface(binding, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
PRUint16 location;
|
|
partBinding->GetLocation(&location);
|
|
if (location == nsISOAPPartBinding::LOCATION_HEADER) {
|
|
headerCount++;
|
|
}
|
|
else if (location == nsISOAPPartBinding::LOCATION_BODY) {
|
|
bodyCount++;
|
|
}
|
|
}
|
|
|
|
// Allocate parameter and header blocks
|
|
nsISOAPParameter** bodyBlocks = nsnull;
|
|
if (bodyCount) {
|
|
bodyBlocks = NS_STATIC_CAST(nsISOAPParameter**,
|
|
nsMemory::Alloc(bodyCount * sizeof(nsISOAPParameter*)));
|
|
if (!bodyBlocks) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
for (i = 0; i < bodyCount; i++) {
|
|
rv = CallCreateInstance(NS_SOAPPARAMETER_CONTRACTID, &bodyBlocks[i]);
|
|
if (NS_FAILED(rv)) {
|
|
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(i, bodyBlocks);
|
|
|
|
return rv;
|
|
}
|
|
}
|
|
}
|
|
|
|
nsISOAPHeaderBlock** headerBlocks = nsnull;
|
|
if (headerCount) {
|
|
headerBlocks = NS_STATIC_CAST(nsISOAPHeaderBlock**,
|
|
nsMemory::Alloc(headerCount * sizeof(nsISOAPHeaderBlock*)));
|
|
if (!headerBlocks) {
|
|
if (bodyBlocks) {
|
|
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(bodyCount, bodyBlocks);
|
|
}
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
for (i = 0; i < headerCount; i++) {
|
|
rv = CallCreateInstance(NS_SOAPHEADERBLOCK_CONTRACTID, &headerBlocks[i]);
|
|
if (NS_FAILED(rv)) {
|
|
if (bodyBlocks) {
|
|
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(bodyCount, bodyBlocks);
|
|
}
|
|
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(i, headerBlocks);
|
|
|
|
return rv;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now iterate through the parameters and set up the parameter blocks
|
|
PRUint32 bodyEntry = 0, headerEntry = 0, paramIndex = 0;
|
|
for (i = 0; i < partCount; paramIndex++, i++) {
|
|
input->GetPart(i, getter_AddRefs(part));
|
|
part->GetBinding(getter_AddRefs(binding));
|
|
nsCOMPtr<nsISOAPPartBinding> partBinding = do_QueryInterface(binding);
|
|
PRUint16 location;
|
|
partBinding->GetLocation(&location);
|
|
|
|
nsCOMPtr<nsISOAPBlock> block;
|
|
if (location == nsISOAPPartBinding::LOCATION_HEADER) {
|
|
block = do_QueryInterface(headerBlocks[headerEntry++]);
|
|
}
|
|
else if (location == nsISOAPPartBinding::LOCATION_BODY) {
|
|
block = do_QueryInterface(bodyBlocks[bodyEntry++]);
|
|
}
|
|
|
|
if (!block) {
|
|
rv = NS_ERROR_FAILURE;
|
|
goto call_method_end;
|
|
}
|
|
|
|
// Get the name, namespaceURI and type of the block based on
|
|
// information from the WSDL part. If the schema component
|
|
// associated with the part is an element, these values come
|
|
// from the schema description of the element. If it is a
|
|
// type, then the values are gathered from elsewhere.
|
|
nsCOMPtr<nsISchemaComponent> schemaComponent;
|
|
rv = part->GetSchemaComponent(getter_AddRefs(schemaComponent));
|
|
if (NS_FAILED(rv)) {
|
|
goto call_method_end;
|
|
}
|
|
|
|
nsCOMPtr<nsISchemaType> type;
|
|
nsAutoString blockName, blockNamespace;
|
|
nsCOMPtr<nsISchemaElement> element = do_QueryInterface(schemaComponent);
|
|
|
|
if (element) {
|
|
rv = element->GetType(getter_AddRefs(type));
|
|
if (NS_FAILED(rv)) {
|
|
goto call_method_end;
|
|
}
|
|
|
|
element->GetName(blockName);
|
|
element->GetTargetNamespace(blockNamespace);
|
|
}
|
|
else {
|
|
type = do_QueryInterface(schemaComponent);
|
|
|
|
nsAutoString paramName;
|
|
part->GetName(paramName);
|
|
|
|
blockName.Assign(paramName);
|
|
partBinding->GetNamespace(blockNamespace);
|
|
}
|
|
|
|
block->SetName(blockName);
|
|
block->SetNamespaceURI(blockNamespace);
|
|
block->SetSchemaType(type);
|
|
|
|
nsAutoString encodingStyle;
|
|
PRUint16 use;
|
|
|
|
partBinding->GetUse(&use);
|
|
// XXX Need a way to specify that a block should not be
|
|
// encoded.
|
|
if (use == nsISOAPPartBinding::USE_ENCODED) {
|
|
partBinding->GetEncodingStyle(encodingStyle);
|
|
if (!encodingStyle.IsEmpty()) {
|
|
nsCOMPtr<nsISOAPEncoding> partEncoding;
|
|
encoding->GetAssociatedEncoding(encodingStyle, PR_FALSE,
|
|
getter_AddRefs(partEncoding));
|
|
block->SetEncoding(partEncoding);
|
|
}
|
|
}
|
|
|
|
// Look ahead in the param info array to see if the current part has to be
|
|
// treated as an array. If so then get the array length from the current
|
|
// param and increment the param index.
|
|
|
|
PRUint32 arrayLength;
|
|
|
|
if (paramIndex < maxParamIndex &&
|
|
info->GetParam((PRUint8)(paramIndex + 1)).GetType().IsArray()) {
|
|
arrayLength = params[paramIndex++].val.u32;
|
|
}
|
|
else {
|
|
arrayLength = 0;
|
|
}
|
|
|
|
NS_ASSERTION(paramIndex <= maxParamIndex,
|
|
"WSDL/IInfo param count mismatch");
|
|
|
|
const nsXPTParamInfo& paramInfo = info->GetParam(paramIndex);
|
|
|
|
nsCOMPtr<nsIVariant> value;
|
|
rv = ParameterToVariant(mPrimaryInterface, methodIndex,
|
|
¶mInfo, params[paramIndex],
|
|
arrayLength, getter_AddRefs(value));
|
|
if (NS_FAILED(rv)) {
|
|
goto call_method_end;
|
|
}
|
|
|
|
block->SetValue(value);
|
|
}
|
|
|
|
// Encode the parameters to the call
|
|
rv = call->Encode(version,
|
|
methodName, targetObjectURI,
|
|
headerCount, headerBlocks,
|
|
bodyCount, bodyBlocks);
|
|
if (NS_FAILED(rv)) {
|
|
goto call_method_end;
|
|
}
|
|
|
|
WSPCallContext* ccInst;
|
|
ccInst = new WSPCallContext(this, call, methodName, operation);
|
|
if (!ccInst) {
|
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
goto call_method_end;
|
|
}
|
|
cc = ccInst;
|
|
|
|
if (mIsAsync) {
|
|
PRUint8 pcount;
|
|
pcount = info->GetParamCount();
|
|
// There has to be at least one parameter - the retval.
|
|
if (pcount == 0) {
|
|
rv = NS_ERROR_FAILURE;
|
|
goto call_method_end;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
// The last one should be the retval.
|
|
const nsXPTParamInfo& retParamInfo = info->GetParam(pcount - 1);
|
|
if (!retParamInfo.IsRetval()) {
|
|
rv = NS_ERROR_FAILURE;
|
|
goto call_method_end;
|
|
}
|
|
|
|
// It should be an interface pointer
|
|
const nsXPTType& retType = retParamInfo.GetType();
|
|
if (!retType.IsInterfacePointer()) {
|
|
rv = NS_ERROR_FAILURE;
|
|
goto call_method_end;
|
|
}
|
|
#endif
|
|
|
|
nsIWebServiceCallContext** retval =
|
|
NS_STATIC_CAST(nsIWebServiceCallContext**, params[pcount-1].val.p);
|
|
if (!retval) {
|
|
rv = NS_ERROR_FAILURE;
|
|
goto call_method_end;
|
|
}
|
|
*retval = cc;
|
|
NS_ADDREF(*retval);
|
|
|
|
rv = ccInst->CallAsync(methodIndex, mAsyncListener);
|
|
if (NS_FAILED(rv)) {
|
|
goto call_method_end;
|
|
}
|
|
|
|
mPendingCalls.AppendObject(ccInst);
|
|
}
|
|
else {
|
|
rv = ccInst->CallSync(methodIndex, params);
|
|
}
|
|
|
|
call_method_end:
|
|
if (bodyBlocks) {
|
|
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(bodyCount, bodyBlocks);
|
|
}
|
|
if (headerBlocks) {
|
|
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(headerCount, headerBlocks);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
WSPProxy::ParameterToVariant(nsIInterfaceInfo* aInterfaceInfo,
|
|
PRUint32 aMethodIndex,
|
|
const nsXPTParamInfo* aParamInfo,
|
|
nsXPTCMiniVariant aMiniVariant,
|
|
PRUint32 aArrayLength, nsIVariant** aVariant)
|
|
{
|
|
nsXPTType type;
|
|
nsresult rv = aInterfaceInfo->GetTypeForParam(aMethodIndex, aParamInfo,
|
|
0, &type);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
uint8 type_tag = type.TagPart();
|
|
nsCOMPtr<nsIInterfaceInfo> iinfo;
|
|
if (type.IsArray()) {
|
|
nsXPTType arrayType;
|
|
rv = aInterfaceInfo->GetTypeForParam(aMethodIndex, aParamInfo,
|
|
1, &arrayType);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
if (arrayType.IsInterfacePointer()) {
|
|
rv = aInterfaceInfo->GetInfoForParam(aMethodIndex, aParamInfo,
|
|
getter_AddRefs(iinfo));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
return ArrayXPTCMiniVariantToVariant(arrayType.TagPart(), aMiniVariant,
|
|
aArrayLength, iinfo, aVariant);
|
|
}
|
|
|
|
// else
|
|
|
|
if (type.IsInterfacePointer()) {
|
|
rv = aInterfaceInfo->GetInfoForParam(aMethodIndex, aParamInfo,
|
|
getter_AddRefs(iinfo));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
return XPTCMiniVariantToVariant(type_tag, aMiniVariant, iinfo, aVariant);
|
|
}
|
|
|
|
nsresult
|
|
WSPProxy::WrapInPropertyBag(nsISupports* aInstance,
|
|
nsIInterfaceInfo* aInterfaceInfo,
|
|
nsIPropertyBag** aPropertyBag)
|
|
{
|
|
*aPropertyBag = nsnull;
|
|
nsresult rv;
|
|
nsCOMPtr<nsIWebServiceComplexTypeWrapper> wrapper =
|
|
do_CreateInstance(NS_WEBSERVICECOMPLEXTYPEWRAPPER_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
rv = wrapper->Init(aInstance, aInterfaceInfo);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
return CallQueryInterface(wrapper, aPropertyBag);
|
|
}
|
|
|
|
nsresult
|
|
WSPProxy::XPTCMiniVariantToVariant(uint8 aTypeTag, nsXPTCMiniVariant aResult,
|
|
nsIInterfaceInfo* aInterfaceInfo,
|
|
nsIVariant** aVariant)
|
|
{
|
|
nsresult rv;
|
|
|
|
// If a variant is passed in, just return it as is.
|
|
if (aTypeTag == nsXPTType::T_INTERFACE) {
|
|
nsISupports* inst = (nsISupports*)aResult.val.p;
|
|
nsCOMPtr<nsIVariant> instVar = do_QueryInterface(inst);
|
|
if (instVar) {
|
|
*aVariant = instVar;
|
|
NS_ADDREF(*aVariant);
|
|
return NS_OK;
|
|
}
|
|
}
|
|
|
|
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_CHAR_STR:
|
|
var->SetAsString(NS_STATIC_CAST(char*, aResult.val.p));
|
|
break;
|
|
case nsXPTType::T_WCHAR_STR:
|
|
var->SetAsWString(NS_STATIC_CAST(PRUnichar*, aResult.val.p));
|
|
break;
|
|
case nsXPTType::T_DOMSTRING:
|
|
case nsXPTType::T_ASTRING:
|
|
var->SetAsAString(*((nsAString*)aResult.val.p));
|
|
break;
|
|
case nsXPTType::T_INTERFACE:
|
|
{
|
|
nsISupports* instance = (nsISupports*)aResult.val.p;
|
|
if (instance) {
|
|
nsCOMPtr<nsIPropertyBag> propBag;
|
|
rv = WrapInPropertyBag(instance, aInterfaceInfo,
|
|
getter_AddRefs(propBag));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
var->SetAsInterface(NS_GET_IID(nsIPropertyBag), propBag);
|
|
// AFAICT, there is no need to release the instance here
|
|
// because the caller who owns the object should be releasing it.
|
|
// 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
|
|
WSPProxy::ArrayXPTCMiniVariantToVariant(uint8 aTypeTag,
|
|
nsXPTCMiniVariant 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) {
|
|
PRUint32 i = 0;
|
|
void* array = aResult.val.p;
|
|
void* entries;
|
|
nsISupports** entriesSup = nsnull;
|
|
const nsIID* iid = nsnull;
|
|
|
|
switch (aTypeTag) {
|
|
case nsXPTType::T_I8:
|
|
case nsXPTType::T_I16:
|
|
case nsXPTType::T_I32:
|
|
case nsXPTType::T_I64:
|
|
case nsXPTType::T_U8:
|
|
case nsXPTType::T_U16:
|
|
case nsXPTType::T_U32:
|
|
case nsXPTType::T_U64:
|
|
case nsXPTType::T_FLOAT:
|
|
case nsXPTType::T_DOUBLE:
|
|
case nsXPTType::T_BOOL:
|
|
case nsXPTType::T_CHAR:
|
|
case nsXPTType::T_WCHAR:
|
|
case nsXPTType::T_CHAR_STR:
|
|
case nsXPTType::T_WCHAR_STR:
|
|
entries = array;
|
|
break;
|
|
case nsXPTType::T_INTERFACE:
|
|
{
|
|
aInterfaceInfo->GetIIDShared(&iid);
|
|
if (iid->Equals(NS_GET_IID(nsIVariant))) {
|
|
entries = array;
|
|
}
|
|
else {
|
|
entriesSup = (nsISupports**)nsMemory::Alloc(aLength *
|
|
sizeof(nsISupports*));
|
|
if (!entriesSup) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
const nsIID& propbagIID = NS_GET_IID(nsIPropertyBag);
|
|
iid = &propbagIID;
|
|
entries = (void*)entriesSup;
|
|
for(i = 0; i < aLength; i++) {
|
|
nsISupports* instance = *((nsISupports**)array + i);
|
|
nsISupports** outptr = entriesSup + i;
|
|
if (instance) {
|
|
nsCOMPtr<nsIPropertyBag> propBag;
|
|
rv = WrapInPropertyBag(instance, aInterfaceInfo,
|
|
getter_AddRefs(propBag));
|
|
if (NS_FAILED(rv)) {
|
|
break;
|
|
}
|
|
propBag->QueryInterface(NS_GET_IID(nsISupports),
|
|
(void**)outptr);
|
|
}
|
|
else {
|
|
*outptr = nsnull;
|
|
}
|
|
}
|
|
}
|
|
aTypeTag = nsXPTType::T_INTERFACE_IS;
|
|
break;
|
|
}
|
|
default:
|
|
NS_ERROR("Conversion of illegal array type");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
rv = retvar->SetAsArray(aTypeTag, iid, aLength, entries);
|
|
}
|
|
|
|
if (entriesSup) {
|
|
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(i, entriesSup);
|
|
}
|
|
}
|
|
else {
|
|
retvar->SetAsEmpty();
|
|
}
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
*aVariant = retvar;
|
|
NS_ADDREF(*aVariant);
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
|
|
nsresult
|
|
WSPProxy::VariantToInParameter(nsIInterfaceInfo* aInterfaceInfo,
|
|
PRUint32 aMethodIndex,
|
|
const nsXPTParamInfo* aParamInfo,
|
|
nsIVariant* aVariant,
|
|
nsXPTCVariant* aXPTCVariant)
|
|
{
|
|
nsXPTType type;
|
|
nsresult rv = aInterfaceInfo->GetTypeForParam(aMethodIndex, aParamInfo,
|
|
0, &type);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
|
|
uint8 type_tag = type.TagPart();
|
|
nsCOMPtr<nsIInterfaceInfo> iinfo;
|
|
if (type.IsArray()) {
|
|
nsXPTType arrayType;
|
|
rv = aInterfaceInfo->GetTypeForParam(aMethodIndex, aParamInfo,
|
|
1, &arrayType);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
if (arrayType.IsInterfacePointer()) {
|
|
rv = aInterfaceInfo->GetInfoForParam(aMethodIndex, aParamInfo,
|
|
getter_AddRefs(iinfo));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
aXPTCVariant[0].type = nsXPTType::T_U32;
|
|
aXPTCVariant[1].type = nsXPTType::T_ARRAY;
|
|
aXPTCVariant[1].SetValIsArray();
|
|
return VariantToArrayValue(arrayType.TagPart(), aXPTCVariant, aXPTCVariant+1,
|
|
iinfo, aVariant);
|
|
}
|
|
// Set the param's type on the XPTCVariant because xptcinvoke's
|
|
// invoke_copy_to_stack depends on it. This fixes bug 203434.
|
|
aXPTCVariant->type = type;
|
|
// else
|
|
if (type.IsInterfacePointer()) {
|
|
rv = aInterfaceInfo->GetInfoForParam(aMethodIndex, aParamInfo,
|
|
getter_AddRefs(iinfo));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
if (type_tag == nsXPTType::T_DOMSTRING) {
|
|
// T_DOMSTRING values are expected to be stored in an nsAString
|
|
// object pointed to by the nsXPTCVariant...
|
|
return VariantToValue(type_tag, aXPTCVariant->val.p, iinfo, aVariant);
|
|
}
|
|
// else
|
|
|
|
// ... but other types are expected to be stored directly in the
|
|
// variant itself.
|
|
return VariantToValue(type_tag, &aXPTCVariant->val, iinfo, aVariant);
|
|
}
|
|
|
|
nsresult
|
|
WSPProxy::VariantToOutParameter(nsIInterfaceInfo* aInterfaceInfo,
|
|
PRUint32 aMethodIndex,
|
|
const nsXPTParamInfo* aParamInfo,
|
|
nsIVariant* aVariant,
|
|
nsXPTCMiniVariant* aMiniVariant)
|
|
{
|
|
nsXPTType type;
|
|
nsresult rv = aInterfaceInfo->GetTypeForParam(aMethodIndex, aParamInfo,
|
|
0, &type);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
uint8 type_tag = type.TagPart();
|
|
nsCOMPtr<nsIInterfaceInfo> iinfo;
|
|
if (type.IsArray()) {
|
|
nsXPTType arrayType;
|
|
rv = aInterfaceInfo->GetTypeForParam(aMethodIndex, aParamInfo,
|
|
1, &arrayType);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
if (arrayType.IsInterfacePointer()) {
|
|
rv = aInterfaceInfo->GetInfoForParam(aMethodIndex, aParamInfo,
|
|
getter_AddRefs(iinfo));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
return VariantToArrayValue(arrayType.TagPart(),
|
|
aMiniVariant, aMiniVariant + 1,
|
|
iinfo, aVariant);
|
|
}
|
|
// else
|
|
if (type.IsInterfacePointer()) {
|
|
rv = aInterfaceInfo->GetInfoForParam(aMethodIndex, aParamInfo,
|
|
getter_AddRefs(iinfo));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
return VariantToValue(type_tag, aMiniVariant->val.p, iinfo, aVariant);
|
|
}
|
|
|
|
nsresult
|
|
WSPProxy::WrapInComplexType(nsIPropertyBag* aPropertyBag,
|
|
nsIInterfaceInfo* aInterfaceInfo,
|
|
nsISupports** aComplexType)
|
|
{
|
|
*aComplexType = nsnull;
|
|
nsRefPtr<WSPPropertyBagWrapper> wrapper = new WSPPropertyBagWrapper();
|
|
if (!wrapper) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
nsresult rv = wrapper->Init(aPropertyBag, aInterfaceInfo);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
wrapper->QueryInterface(NS_GET_IID(nsISupports), (void**)aComplexType);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
WSPProxy::VariantToValue(uint8 aTypeTag, void* aValue,
|
|
nsIInterfaceInfo* aInterfaceInfo,
|
|
nsIVariant* aProperty)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
|
|
switch(aTypeTag) {
|
|
case nsXPTType::T_I8:
|
|
rv = aProperty->GetAsInt8((PRUint8*)aValue);
|
|
break;
|
|
case nsXPTType::T_I16:
|
|
rv = aProperty->GetAsInt16((PRInt16*)aValue);
|
|
break;
|
|
case nsXPTType::T_I32:
|
|
rv = aProperty->GetAsInt32((PRInt32*)aValue);
|
|
break;
|
|
case nsXPTType::T_I64:
|
|
rv = aProperty->GetAsInt64((PRInt64*)aValue);
|
|
break;
|
|
case nsXPTType::T_U8:
|
|
rv = aProperty->GetAsUint8((PRUint8*)aValue);
|
|
break;
|
|
case nsXPTType::T_U16:
|
|
rv = aProperty->GetAsUint16((PRUint16*)aValue);
|
|
break;
|
|
case nsXPTType::T_U32:
|
|
rv = aProperty->GetAsUint32((PRUint32*)aValue);
|
|
break;
|
|
case nsXPTType::T_U64:
|
|
rv = aProperty->GetAsUint64((PRUint64*)aValue);
|
|
break;
|
|
case nsXPTType::T_FLOAT:
|
|
rv = aProperty->GetAsFloat((float*)aValue);
|
|
break;
|
|
case nsXPTType::T_DOUBLE:
|
|
rv = aProperty->GetAsDouble((double*)aValue);
|
|
break;
|
|
case nsXPTType::T_BOOL:
|
|
rv = aProperty->GetAsBool((PRBool*)aValue);
|
|
break;
|
|
case nsXPTType::T_CHAR:
|
|
rv = aProperty->GetAsChar((char*)aValue);
|
|
break;
|
|
case nsXPTType::T_WCHAR:
|
|
rv = aProperty->GetAsWChar((PRUnichar*)aValue);
|
|
break;
|
|
case nsXPTType::T_CHAR_STR:
|
|
rv = aProperty->GetAsString((char**)aValue);
|
|
break;
|
|
case nsXPTType::T_WCHAR_STR:
|
|
rv = aProperty->GetAsWString((PRUnichar**)aValue);
|
|
break;
|
|
case nsXPTType::T_DOMSTRING:
|
|
case nsXPTType::T_ASTRING:
|
|
rv = aProperty->GetAsAString(*(nsAString*)aValue);
|
|
break;
|
|
case nsXPTType::T_INTERFACE:
|
|
{
|
|
const nsIID* iid;
|
|
aInterfaceInfo->GetIIDShared(&iid);
|
|
PRUint16 dataType;
|
|
aProperty->GetDataType(&dataType);
|
|
if (dataType == nsIDataType::VTYPE_EMPTY) {
|
|
*(nsISupports**)aValue = nsnull;
|
|
}
|
|
else if (iid->Equals(NS_GET_IID(nsIVariant))) {
|
|
*(nsIVariant**)aValue = aProperty;
|
|
NS_ADDREF(*(nsIVariant**)aValue);
|
|
}
|
|
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;
|
|
}
|
|
nsCOMPtr<nsISupports> wrapper;
|
|
rv = WrapInComplexType(propBag, aInterfaceInfo,
|
|
getter_AddRefs(wrapper));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
rv = wrapper->QueryInterface(*iid, (void**)aValue);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
NS_ERROR("Bad attribute type for complex type interface");
|
|
rv = NS_ERROR_FAILURE;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
WSPProxy::VariantToArrayValue(uint8 aTypeTag,
|
|
nsXPTCMiniVariant* aResultSize,
|
|
nsXPTCMiniVariant* aResultArray,
|
|
nsIInterfaceInfo* aInterfaceInfo,
|
|
nsIVariant* aProperty)
|
|
{
|
|
void* array;
|
|
PRUint16 type;
|
|
PRUint32 count;
|
|
|
|
nsIID arrayIID;
|
|
nsresult rv = aProperty->GetAsArray(&type, &arrayIID, &count, &array);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
aResultSize->val.u32 = count;
|
|
|
|
switch (aTypeTag) {
|
|
case nsXPTType::T_I8:
|
|
case nsXPTType::T_U8:
|
|
case nsXPTType::T_I16:
|
|
case nsXPTType::T_U16:
|
|
case nsXPTType::T_I32:
|
|
case nsXPTType::T_U32:
|
|
case nsXPTType::T_I64:
|
|
case nsXPTType::T_U64:
|
|
case nsXPTType::T_FLOAT:
|
|
case nsXPTType::T_DOUBLE:
|
|
case nsXPTType::T_BOOL:
|
|
case nsXPTType::T_CHAR:
|
|
case nsXPTType::T_WCHAR:
|
|
case nsXPTType::T_CHAR_STR:
|
|
case nsXPTType::T_WCHAR_STR:
|
|
aResultArray->val.p = array;
|
|
break;
|
|
case nsXPTType::T_INTERFACE:
|
|
case nsXPTType::T_INTERFACE_IS:
|
|
{
|
|
if (arrayIID.Equals(NS_GET_IID(nsIVariant))) {
|
|
aResultArray->val.p = array;
|
|
}
|
|
else if (!arrayIID.Equals(NS_GET_IID(nsIPropertyBag))) {
|
|
NS_ERROR("Array of complex types should be represented by property "
|
|
"bags");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
else {
|
|
nsISupports** outptr =
|
|
(nsISupports**)nsMemory::Alloc(count * sizeof(nsISupports*));
|
|
if (!outptr) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
nsISupports** arraySup = (nsISupports**)array;
|
|
const nsIID* iid;
|
|
aInterfaceInfo->GetIIDShared(&iid);
|
|
PRUint32 i;
|
|
for (i = 0; i < count; i++) {
|
|
nsCOMPtr<nsIPropertyBag> propBag(do_QueryInterface(arraySup[i]));
|
|
if (!propBag) {
|
|
*(outptr + i) = nsnull;
|
|
}
|
|
else {
|
|
nsCOMPtr<nsISupports> wrapper;
|
|
rv = WrapInComplexType(propBag, aInterfaceInfo,
|
|
getter_AddRefs(wrapper));
|
|
if (NS_FAILED(rv)) {
|
|
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(i, outptr);
|
|
return rv;
|
|
}
|
|
rv = wrapper->QueryInterface(*iid, (void**)(outptr + i));
|
|
if (NS_FAILED(rv)) {
|
|
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(i, outptr);
|
|
return rv;
|
|
}
|
|
}
|
|
}
|
|
aResultArray->val.p = outptr;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
NS_ERROR("Conversion of illegal array type");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetInterfaceInfo(nsIInterfaceInfo** info)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(info);
|
|
|
|
*info = mPrimaryInterface;
|
|
NS_ADDREF(*info);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
///////////////////////////////////////////////////
|
|
//
|
|
// Implementation of nsIWebServiceProxy
|
|
//
|
|
///////////////////////////////////////////////////
|
|
|
|
/* readonly attribute nsIWSDLPort port; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetPort(nsIWSDLPort * *aPort)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aPort);
|
|
|
|
*aPort = mPort;
|
|
NS_IF_ADDREF(*aPort);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
/* readonly attribute boolean isAsync; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetIsAsync(PRBool *aIsAsync)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aIsAsync);
|
|
*aIsAsync = mIsAsync;
|
|
return NS_OK;
|
|
}
|
|
|
|
/* readonly attribute AString qualifier; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetQualifier(nsAString & aQualifier)
|
|
{
|
|
aQualifier.Assign(mQualifier);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
/* readonly attribute nsISimpleEnumerator pendingCalls; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetPendingCalls(nsISimpleEnumerator * *aPendingCalls)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
nsresult
|
|
WSPProxy::GetInterfaceName(PRBool listener, char** retval)
|
|
{
|
|
if (!mPrimaryInterface) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
const char* rawName;
|
|
nsresult rv = mPrimaryInterface->GetNameShared(&rawName);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
nsCAutoString name;
|
|
|
|
if (listener) {
|
|
if (mIsAsync) {
|
|
name.Assign(rawName, strlen(rawName) - (sizeof("Async")-1) );
|
|
}
|
|
else {
|
|
name.Assign(rawName);
|
|
}
|
|
name.Append("Listener");
|
|
}
|
|
else {
|
|
name.Assign(rawName);
|
|
}
|
|
|
|
*retval = (char*) nsMemory::Clone(name.get(), name.Length()+1);
|
|
return *retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
/* readonly attribute string primaryInterfaceName; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetPrimaryInterfaceName(char * *aPrimaryInterfaceName)
|
|
{
|
|
return GetInterfaceName(PR_FALSE, aPrimaryInterfaceName);
|
|
}
|
|
|
|
/* readonly attribute string primaryAsyncListenerInterfaceName; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetPrimaryAsyncListenerInterfaceName(char * *aPrimaryAsyncListenerInterfaceName)
|
|
{
|
|
return GetInterfaceName(PR_TRUE, aPrimaryAsyncListenerInterfaceName);
|
|
}
|
|
|
|
/* readonly attribute nsIScriptableInterfaces interfaces; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetInterfaces(nsIScriptableInterfaces * *aInterfaces)
|
|
{
|
|
*aInterfaces = mInterfaces;
|
|
NS_IF_ADDREF(*aInterfaces);
|
|
return NS_OK;
|
|
}
|
|
|
|
///////////////////////////////////////////////////
|
|
//
|
|
// Implementation of nsIClassInfo
|
|
//
|
|
///////////////////////////////////////////////////
|
|
|
|
/* void getInterfaces (out PRUint32 count, [array, size_is (count),
|
|
retval] out nsIIDPtr array); */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetInterfaces(PRUint32 *count, nsIID * **array)
|
|
{
|
|
if (!mIID) {
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
}
|
|
|
|
*count = 2;
|
|
nsIID** iids = NS_STATIC_CAST(nsIID**, nsMemory::Alloc(2 * sizeof(nsIID*)));
|
|
if (!iids) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
iids[0] = NS_STATIC_CAST(nsIID *, nsMemory::Clone(mIID, sizeof(nsIID)));
|
|
if (NS_UNLIKELY(!iids[0])) {
|
|
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(0, iids);
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
const nsIID& wsiid = NS_GET_IID(nsIWebServiceProxy);
|
|
iids[1] = NS_STATIC_CAST(nsIID *, nsMemory::Clone(&wsiid, sizeof(nsIID)));
|
|
if (NS_UNLIKELY(!iids[1])) {
|
|
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(1, iids);
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
*array = iids;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
/* nsISupports getHelperForLanguage (in PRUint32 language); */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
|
|
{
|
|
*_retval = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
/* readonly attribute string contractID; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetContractID(char * *aContractID)
|
|
{
|
|
*aContractID = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
/* readonly attribute string classDescription; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetClassDescription(char * *aClassDescription)
|
|
{
|
|
*aClassDescription = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
/* readonly attribute nsCIDPtr classID; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetClassID(nsCID * *aClassID)
|
|
{
|
|
*aClassID = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
/* readonly attribute PRUint32 implementationLanguage; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
|
|
{
|
|
*aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
|
|
return NS_OK;
|
|
}
|
|
|
|
/* readonly attribute PRUint32 flags; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetFlags(PRUint32 *aFlags)
|
|
{
|
|
*aFlags = nsIClassInfo::DOM_OBJECT;
|
|
return NS_OK;
|
|
}
|
|
|
|
/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
|
|
NS_IMETHODIMP
|
|
WSPProxy::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
|
{
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
void
|
|
WSPProxy::GetListenerInterfaceInfo(nsIInterfaceInfo** aInfo)
|
|
{
|
|
*aInfo = mListenerInterfaceInfo;
|
|
NS_IF_ADDREF(*aInfo);
|
|
}
|
|
|
|
void
|
|
WSPProxy::CallCompleted(WSPCallContext* aContext)
|
|
{
|
|
mPendingCalls.RemoveObject(aContext);
|
|
}
|