blob: 77f801aed8b1363e9fa156a5a7bf170d34d27d3c [file] [log] [blame]
/*
* Copyright 2003-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @author Roshan Weerasuriya (roshan@opensource.lk, roshanw@jkcsworld.com)
* @author Susantha Kumara (susantha@opensource.lk, skumara@virtusa.com)
* @author Damitha Kumarage (damitha@opensource.lk, damitha@jkcsworld.com)
*
*/
#ifdef WIN32
#pragma warning (disable : 4786)
#endif
#include "SoapEnvelope.h"
#include "SoapSerializer.h"
#include "HeaderBlock.h"
#include <axis/server/GDefine.h>
#include <axis/server/Packet.h>
#include "../common/ArrayBean.h"
#include "../common/BasicTypeSerializer.h"
#include "../soap/SoapKeywordMapping.h"
#include "AxisSoapException.h"
#include <stdio.h>
#include <stdarg.h>
#include "../common/AxisTrace.h"
#include "../common/AxisConfig.h"
extern AxisTrace* g_pAT;
extern AxisConfig* g_pConfig;
/* Following values should come from axis configuration files. */
#define INITIAL_SERIALIZE_BUFFER_SIZE 1024
IWrapperSoapSerializerFunctions IWrapperSoapSerializer::ms_VFtable;
SoapSerializer::SoapSerializer()
{
m_pSoapEnvelope = NULL;
m_iSoapVersion = SOAP_VER_1_1;
m_pOutputStream = NULL;
m_nMaxBuffersToCreate = NO_OF_SERIALIZE_BUFFERS;
m_nInitialBufferSize = INITIAL_SERIALIZE_BUFFER_SIZE;
m_pSZBuffers = new SerializeBuffers[m_nMaxBuffersToCreate];
for (int x=0; x<m_nMaxBuffersToCreate; x++)
{
m_pSZBuffers[x].inuse = 0;
m_pSZBuffers[x].buffer = NULL;
}
}
SoapSerializer::~SoapSerializer()
{
if (m_pSoapEnvelope) delete m_pSoapEnvelope;
for (int x=0; x<m_nMaxBuffersToCreate; x++)
{
delete [] (char*)m_pSZBuffers[x].buffer;
}
delete [] (SerializeBuffers*)m_pSZBuffers;
}
int SoapSerializer::setSoapEnvelope(SoapEnvelope *pSoapEnvelope)
{
m_pSoapEnvelope = pSoapEnvelope;
return AXIS_SUCCESS;
}
int SoapSerializer::setSoapHeader(ISoapHeader *pSoapHeader)
{
int intStatus = AXIS_FAIL;
if(m_pSoapEnvelope)
{
if((m_pSoapEnvelope)&& (m_pSoapEnvelope->m_pSoapHeader))
{
/* no need to create a SOAP Header, it already exists */
intStatus= AXIS_OBJECT_ALREADY_EXISTS;
}
else
{
m_pSoapEnvelope->setSoapHeader((SoapHeader*)pSoapHeader);
intStatus= AXIS_SUCCESS;
}
}
return intStatus;
}
int SoapSerializer::setSoapBody(SoapBody *pSoapBody)
{
int intStatus= AXIS_FAIL;
if(m_pSoapEnvelope)
{
m_pSoapEnvelope->setSoapBody(pSoapBody);
intStatus= AXIS_SUCCESS;
}
return intStatus;
}
int SoapSerializer::setSoapMethod(SoapMethod *pSoapMethod)
{
int intStatus= AXIS_FAIL;
if(m_pSoapEnvelope && (m_pSoapEnvelope->m_pSoapBody))
{
if (!(m_pSoapEnvelope->m_pSoapBody->m_pSoapMethod)) {
m_pSoapEnvelope->m_pSoapBody->m_pSoapMethod= pSoapMethod;
}
intStatus= AXIS_SUCCESS;
}
return intStatus;
}
int SoapSerializer::addOutputBasicArrayParam(const Axis_Array* pArray,
XSDTYPE nType,
const AxisChar* pName)
{
IArrayBean* pAb = makeArrayBean(nType, (void*)(pArray->m_Array));
pAb->SetDimension(pArray->m_Size);
Param* pParam = new Param();
if (RPC_ENCODED == m_nStyle)
{
pAb->SetItemName("item");
pParam->setName(pName);
}
else
{
pAb->SetItemName(pName);
pParam->setName("array");
}
pParam->m_Value.pIArray = pAb;
pParam->m_Type = XSD_ARRAY;
if(m_pSoapEnvelope && (m_pSoapEnvelope->m_pSoapBody) &&
(m_pSoapEnvelope->m_pSoapBody->m_pSoapMethod))
{
m_pSoapEnvelope->m_pSoapBody->m_pSoapMethod->addOutputParam(pParam);
}
return AXIS_SUCCESS;
}
int SoapSerializer::addOutputCmplxArrayParam(const Axis_Array* pArray,
void* pSZFunct, void* pDelFunct,
void* pSizeFunct,
const AxisChar* pName,
const AxisChar* pNamespace)
{
IArrayBean* pAb = makeArrayBean((void*)(pArray->m_Array), pSZFunct,
pDelFunct, pSizeFunct);
pAb->SetDimension(pArray->m_Size);
Param* pParam = new Param();
if (RPC_ENCODED == m_nStyle)
{
pAb->SetItemName("item");
pAb->SetTypeName(pName);
pAb->SetUri(pNamespace);
pParam->setName(pName);
}
else
{
pAb->SetItemName(pName);
pParam->setName("array");
}
pParam->m_Value.pIArray = pAb;
pParam->m_Type = XSD_ARRAY;
if(m_pSoapEnvelope && (m_pSoapEnvelope->m_pSoapBody) && (m_pSoapEnvelope->
m_pSoapBody->m_pSoapMethod))
{
m_pSoapEnvelope->m_pSoapBody->m_pSoapMethod->addOutputParam(pParam);
}
pParam->setName(pName);
return AXIS_SUCCESS;
}
int SoapSerializer::addOutputCmplxParam(void* pObject, void* pSZFunct,
void* pDelFunct, const AxisChar* pName,
const AxisChar* pNamespace )
{
Param* pParam = new Param();
pParam->m_Value.pCplxObj = new ComplexObjectHandler;
pParam->m_Value.pCplxObj->pObject = pObject;
pParam->m_Value.pCplxObj->pSZFunct = (AXIS_SERIALIZE_FUNCT)pSZFunct;
pParam->m_Value.pCplxObj->pDelFunct = (AXIS_OBJECT_DELETE_FUNCT)pDelFunct;
if(m_pSoapEnvelope && (m_pSoapEnvelope->m_pSoapBody) && (m_pSoapEnvelope->
m_pSoapBody->m_pSoapMethod))
{
m_pSoapEnvelope->m_pSoapBody->m_pSoapMethod->addOutputParam(pParam);
}
pParam->setName(pName);
return AXIS_SUCCESS;
}
int SoapSerializer::addFaultDetail(void* pObject, void* pSZFunct,
void* pDelFunct, const AxisChar* pName,
const AxisChar* pNamespace )
{
Param* pParam = new Param();
pParam->m_Value.pCplxObj = new ComplexObjectHandler;
pParam->m_Value.pCplxObj->pObject = pObject;
pParam->m_Value.pCplxObj->pSZFunct = (AXIS_SERIALIZE_FUNCT)pSZFunct;
pParam->m_Value.pCplxObj->pDelFunct = (AXIS_OBJECT_DELETE_FUNCT)pDelFunct;
if(m_pSoapEnvelope && (m_pSoapEnvelope->m_pSoapBody) && (m_pSoapEnvelope->
m_pSoapBody->m_pSoapFault))
{
m_pSoapEnvelope->m_pSoapBody->m_pSoapFault->setFaultDetail(pParam);
}
pParam->setName(pName);
return AXIS_SUCCESS;
}
int SoapSerializer::setSoapFault(SoapFault *pSoapFault)
{
int intStatus= AXIS_FAIL;
if(m_pSoapEnvelope && (m_pSoapEnvelope->m_pSoapBody))
{
m_pSoapEnvelope->m_pSoapBody->m_pSoapFault= pSoapFault;
intStatus= AXIS_SUCCESS;
}
return intStatus;
}
int SoapSerializer::setOutputStream(SOAPTransport* pStream)
{
m_pOutputStream = pStream;
int iStatus= AXIS_SUCCESS;
try
{
m_pOutputStream->registerReleaseBufferCallback(releaseBufferCallBack);
if(m_pSoapEnvelope)
{
serialize("<?xml version='1.0' encoding='utf-8' ?>", NULL);
iStatus= m_pSoapEnvelope->serialize(*this,
(SOAP_VERSION)m_iSoapVersion);
sendSerializedBuffer();
}
}
catch(AxisSoapException& e)
{
throw;
}
catch(AxisException& e)
{
throw;
}
catch(...)
{
throw;
}
return iStatus;
}
/*
* Some client side transport layer may wait until the end of buffers is
* acknowladged. Use this function to do that.
*/
void SoapSerializer::markEndOfStream()
{
m_pOutputStream->flushOutput();
}
/*
* Initializing the members of the class. This is needed since
* the same object instance of this class, may be used to server
* several SOAP requests.
*/
int SoapSerializer::init()
{
m_nStatus = AXIS_SUCCESS;
if(m_pSoapEnvelope)
{
delete m_pSoapEnvelope;
m_pSoapEnvelope= NULL;
}
/* Adding SoapEnvelop and SoapBody to Serializer */
m_pSoapEnvelope = new SoapEnvelope();
m_pSoapEnvelope->setSoapBody(new SoapBody());
setNextSerilizeBuffer();
m_nCounter=0;
m_NsStack.clear();
return AXIS_SUCCESS;
}
int SoapSerializer::setSoapVersion(SOAP_VERSION nSoapVersion)
{
m_iSoapVersion = nSoapVersion;
/* here the default namespaces of the SoapEnvelop should be added and
* intialized as well.
*/
m_pSoapEnvelope->addStandardNamespaceDecl
(SoapKeywordMapping::map(nSoapVersion).pEnv);
m_pSoapEnvelope->addStandardNamespaceDecl
(SoapKeywordMapping::map(nSoapVersion).pXsd);
m_pSoapEnvelope->addStandardNamespaceDecl
(SoapKeywordMapping::map(nSoapVersion).pXsi);
/* Adding the standard SOAP namespace to the namespace stack */
m_NsStack[SoapKeywordMapping::map(nSoapVersion).pchNamespaceUri] =
SoapKeywordMapping::map(nSoapVersion).pchPrefix;
return AXIS_SUCCESS;
}
void SoapSerializer::removeNamespacePrefix(const AxisChar* pNamespace)
{
if (m_NsStack.find(pNamespace) != m_NsStack.end())
{
m_NsStack.erase(pNamespace);
}
}
const AxisChar* SoapSerializer::getNamespacePrefix(const AxisChar* pNamespace)
{
if (m_NsStack.find(pNamespace) == m_NsStack.end())
{
m_nCounter++;
AxisSprintf(m_Buf, 8, "ns%d", m_nCounter);
m_NsStack[pNamespace] = m_Buf;
}
return m_NsStack[pNamespace].c_str();
}
const AxisChar* SoapSerializer::getNamespacePrefix(const AxisChar* pNamespace,
bool& blnIsNewPrefix)
{
if (m_NsStack.find(pNamespace) == m_NsStack.end())
{
m_nCounter++;
AxisSprintf(m_Buf, 8, "ns%d", m_nCounter);
m_NsStack[pNamespace] = m_Buf;
blnIsNewPrefix = true;
}
return m_NsStack[pNamespace].c_str();
}
IWrapperSoapSerializer& SoapSerializer::operator <<(const AxisChar*
cSerialized)
{
if (AXIS_SUCCESS != m_nStatus)
{
/* some thing has gone wrong. So do nothing */
return *this;
}
int iTmpSerBufferSize = strlen(cSerialized);
if((m_nFilledSize + iTmpSerBufferSize)>= m_nCurrentBufferSize)
{
/*
* Send the current buffer to the transport and get
* another buffer to be filled
*/
if (AXIS_SUCCESS == sendSerializedBuffer())
{
if (AXIS_SUCCESS == setNextSerilizeBuffer())
{
strcat((char*)m_pSZBuffers[m_nCurrentBufferIndex].buffer,
cSerialized);
m_nFilledSize += iTmpSerBufferSize;
}
}
}
else
{
strcat((char*)m_pSZBuffers[m_nCurrentBufferIndex].buffer, cSerialized);
m_nFilledSize += iTmpSerBufferSize;
}
return *this;
}
int SoapSerializer::sendSerializedBuffer()
{
int nStatus;
try
{
nStatus = m_pOutputStream->sendBytes((char*)
m_pSZBuffers[m_nCurrentBufferIndex].buffer, (void*)(&(m_pSZBuffers
[m_nCurrentBufferIndex].inuse)));
if (TRANSPORT_FINISHED == nStatus)
/* transport layer has done with the buffer.So same buffer
* can be re-used
*/
{
m_pSZBuffers[m_nCurrentBufferIndex].buffer[0] = '\0'; /* put nul */
m_pSZBuffers[m_nCurrentBufferIndex].inuse = 0; /* not in use */
}
else if (TRANSPORT_FAILED == nStatus)
{
return AXIS_FAIL;
}
}
catch(AxisSoapException& e)
{
throw;
}
catch(AxisException& e)
{
throw;
}
catch(...)
{
throw;
}
return AXIS_SUCCESS;
}
/*
* This method sets the next buffer to be used for serialization.
*
*/
int SoapSerializer::setNextSerilizeBuffer()
{
for (int x=0;x<m_nMaxBuffersToCreate;x++)
{
if (m_pSZBuffers[x].buffer) /* a buffer has been created */
{
if (0 == m_pSZBuffers[x].inuse) /* buffer is not being used */
{
m_nCurrentBufferIndex = x;
m_pSZBuffers[m_nCurrentBufferIndex].inuse = 1;
m_pSZBuffers[m_nCurrentBufferIndex].buffer[0] = '\0';
m_nFilledSize = 0;
m_nCurrentBufferSize = m_nInitialBufferSize*
(1 << m_nCurrentBufferIndex);
return AXIS_SUCCESS;
}
}
else
/* a buffer is not yet created at this array index.
* So create one and use it
*/
{
m_nCurrentBufferIndex = x;
m_nCurrentBufferSize = m_nInitialBufferSize*
(1 << m_nCurrentBufferIndex);
m_pSZBuffers[m_nCurrentBufferIndex].buffer =
new char[m_nCurrentBufferSize];
m_pSZBuffers[m_nCurrentBufferIndex].inuse = 1;
m_pSZBuffers[m_nCurrentBufferIndex].buffer[0] = '\0';
m_nFilledSize = 0;
return AXIS_SUCCESS;
}
}
return AXIS_FAIL;
}
int SoapSerializer::createSoapMethod(const AxisChar* sLocalName,
const AxisChar* sURI)
{
SoapMethod* pMethod = new SoapMethod();
setSoapMethod(pMethod);
pMethod->setLocalName(sLocalName);
pMethod->setPrefix(getNamespacePrefix(sURI));
pMethod->setUri(sURI);
return AXIS_SUCCESS;
}
int SoapSerializer::createSoapFault(const AxisChar* sLocalName,
const AxisChar* sURI,
const AxisChar* sFaultCode,
const AxisChar* sFaultString)
{
SoapFault* pSoapFault = new SoapFault();
setSoapFault(pSoapFault);
pSoapFault->setLocalName(sLocalName);
pSoapFault->setPrefix(getNamespacePrefix(sURI));
pSoapFault->setUri(sURI);
pSoapFault->setFaultcode(sFaultCode);
pSoapFault->setFaultstring(sFaultString);
char* pcNodeName = g_pConfig->getAxisConfProperty(AXCONF_NODENAME);
char* pcPort = g_pConfig->getAxisConfProperty(AXCONF_LISTENPORT);
string strUrl = pcNodeName;
strUrl += ":";
strUrl += string(pcPort);
pSoapFault->setFaultactor(strUrl);
return AXIS_SUCCESS;
}
/*
* Used to create an ArrayBean when the return type of a method is an array
* of basic types
*/
IArrayBean* SoapSerializer::makeArrayBean(XSDTYPE nType, void* pArray)
{
ArrayBean* pAb = new ArrayBean();
pAb->m_type = nType;
pAb->m_value.sta = pArray;
return pAb;
}
/*
* Used to create an ArrayBean when the return type of a method is an array
* of complex types
*/
IArrayBean* SoapSerializer::makeArrayBean(void* pObject, void* pSZFunct,
void* pDelFunct, void* pSizeFunct)
{
ArrayBean* pAb = new ArrayBean();
pAb->m_type = USER_TYPE;
pAb->m_value.cta = new ComplexObjectHandler;
pAb->m_value.cta->pSZFunct = (AXIS_SERIALIZE_FUNCT)pSZFunct;
pAb->m_value.cta->pDelFunct = (AXIS_OBJECT_DELETE_FUNCT)pDelFunct;
pAb->m_value.cta->pSizeFunct = (AXIS_OBJECT_SIZE_FUNCT)pSizeFunct;
pAb->m_value.cta->pObject = pObject;
return pAb;
}
IHeaderBlock* SoapSerializer::createHeaderBlock()
{
HeaderBlock* pHeaderBlock= new HeaderBlock();
setHeaderBlock(pHeaderBlock);
return pHeaderBlock;
}
int SoapSerializer::setHeaderBlock(HeaderBlock *pHeaderBlock)
{
int intStatus= AXIS_FAIL;
if((m_pSoapEnvelope)&& (m_pSoapEnvelope->m_pSoapHeader))
{
/* no need to create a SOAP Header, it already exists */
}
else
{
SoapHeader* pSoapHeader= new SoapHeader();
setSoapHeader(pSoapHeader);
}
m_pSoapEnvelope->m_pSoapHeader->addHeaderBlock(pHeaderBlock);
intStatus= AXIS_SUCCESS;
return intStatus;
}
/*
* This method not only removes the existing SoapHeader, but also removes
* all the existing HeaderBlocks which are associated with this SoapHeader.
* Therefore the caller of this method has to be exactly sure whether he wants
* to do this.
*/
int SoapSerializer::removeSoapHeader()
{
delete m_pSoapEnvelope->m_pSoapHeader;
m_pSoapEnvelope->m_pSoapHeader= NULL;
return AXIS_SUCCESS;
}
/*
* Used to Serialize an array of complex types inside a complex type. Called
* from within the Serialize wrapper method of the complex type.
*/
int SoapSerializer::serializeCmplxArray(const Axis_Array* pArray,
void* pSZFunct, void* pDelFunct,
void* pSizeFunct,
const AxisChar* pName,
const AxisChar* pNamespace)
{
ArrayBean* pAb = (ArrayBean*)makeArrayBean((void*)(pArray->m_Array),
pSZFunct, pDelFunct, pSizeFunct);
pAb->SetDimension(pArray->m_Size);
Param* pParam = new Param();
if (RPC_ENCODED == m_nStyle)
{
pAb->SetItemName("item");
pAb->SetTypeName(pName);
pAb->SetUri(pNamespace);
pParam->setName(pName);
}
else
{
pAb->SetItemName(pName);
pParam->setName("array");
}
pParam->m_Value.pIArray = pAb;
pParam->m_Type = XSD_ARRAY;
pParam->serialize(*this);
/* Remove pointer to the array from the ArrayBean to avoid deleting the
* array when ArrayBean is deleted. Array will be deleted when the complex
* type that contains this array is deleted */
pAb->RemoveArrayPointer();
delete pParam;
return AXIS_SUCCESS;
}
/*
* Used to Serialize an array of basic types inside a complex type. Called from
* within the Serialize wrapper method of the complex type.
*/
int SoapSerializer::serializeBasicArray(const Axis_Array* pArray,
XSDTYPE nType, const AxisChar* pName)
{
ArrayBean* pAb = (ArrayBean*)makeArrayBean(nType,
(void*)(pArray->m_Array));
pAb->SetDimension(pArray->m_Size);
Param* pParam = new Param();
if (RPC_ENCODED == m_nStyle)
{
pAb->SetItemName("item");
pParam->setName(pName);
}
else
{
pAb->SetItemName(pName);
pParam->setName("array");
}
pParam->m_Value.pIArray = pAb;
pParam->m_Type = XSD_ARRAY;
pParam->serialize(*this);
/* Remove pointer to the array from the ArrayBean to avoid deleting the
* array when ArrayBean is deleted. Array will be deleted when the complex
* type that contains this array is deleted
*/
pAb->RemoveArrayPointer();
delete pParam;
return AXIS_SUCCESS;
}
#ifdef UNIT_TESTING_ON
int SoapSerializer::setOutputStreamForTesting(SOAPTransport* pStream)
{
m_pOutputStream = pStream;
return AXIS_SUCCESS;
}
#endif
/*
* Basic output parameter going to be serialized as an Element later
*/
int SoapSerializer::addOutputParam(const AxisChar* pchName, void* pValue,
XSDTYPE type)
{
Param* pParam = new Param();
if (!pParam) return AXIS_FAIL;
pParam->m_Type = type;
pParam->m_sName = pchName;
switch(type)
{
case XSD_INT:
case XSD_BOOLEAN:
pParam->m_Value.nValue = *((int*)(pValue));
break;
case XSD_UNSIGNEDINT:
pParam->m_Value.unValue = *((unsigned int*)(pValue));
break;
case XSD_SHORT:
pParam->m_Value.sValue = *((short*)(pValue));
break;
case XSD_UNSIGNEDSHORT:
pParam->m_Value.usValue = *((unsigned short*)(pValue));
break;
case XSD_BYTE:
pParam->m_Value.cValue = *((char*)(pValue));
break;
case XSD_UNSIGNEDBYTE:
pParam->m_Value.ucValue = *((unsigned char*)(pValue));
break;
case XSD_LONG:
case XSD_INTEGER:
case XSD_DURATION:
pParam->m_Value.lValue = *((long*)(pValue));
break;
case XSD_UNSIGNEDLONG:
pParam->m_Value.ulValue = *((unsigned long*)(pValue));
break;
case XSD_FLOAT:
pParam->m_Value.fValue = *((float*)(pValue));
break;
case XSD_DOUBLE:
case XSD_DECIMAL:
pParam->m_Value.dValue = *((double*)(pValue));
break;
case XSD_STRING:
pParam->m_Value.pStrValue = *((char**)(pValue));
break;
case XSD_HEXBINARY:
pParam->m_Value.hbValue = *((xsd__hexBinary*)(pValue));
break;
case XSD_BASE64BINARY:
pParam->m_Value.b64bValue = *((xsd__base64Binary*)(pValue));
break;
case XSD_DATETIME:
case XSD_DATE:
case XSD_TIME:
pParam->m_Value.tValue = *((struct tm*)(pValue));
break;
default:
delete pParam;
return AXIS_FAIL;
}
if(m_pSoapEnvelope && (m_pSoapEnvelope->m_pSoapBody) && (m_pSoapEnvelope->
m_pSoapBody->m_pSoapMethod))
{
m_pSoapEnvelope->m_pSoapBody->m_pSoapMethod->addOutputParam(pParam);
}
else
{
delete pParam;
return AXIS_FAIL;
}
return AXIS_SUCCESS;
}
int SoapSerializer::serializeAsElement(const AxisChar* pName, void* pValue,
XSDTYPE type)
{
const AxisChar* pSerialized = m_BTSZ.serializeAsElement(pName, pValue,
type);
if (pSerialized)
{
*this << pSerialized;
return AXIS_SUCCESS;
}
else
{
return AXIS_FAIL;
}
}
int SoapSerializer::serializeAsAttribute(const AxisChar* pName,
const AxisChar* pNamespace,
void* pValue, XSDTYPE type)
{
const AxisChar* pPrefix = NULL;
if (pNamespace)
{
pPrefix = getNamespacePrefix(pNamespace);
}
const AxisChar* pSerialized = m_BTSZ.serializeAsAttribute(pName, pPrefix,
pValue, type);
if (pSerialized)
{
*this << pSerialized;
return AXIS_SUCCESS;
}
else
{
return AXIS_FAIL;
}
}
void SoapSerializer::serialize(const char* pFirst, ...)
{
va_list vList;
const char* pArg;
if (pFirst) *this << pFirst;
va_start( vList, pFirst ); /* Initialize variable arguments. */
do
{
pArg = va_arg( vList, const char*);
if (pArg)
*this << pArg;
}
while (pArg != NULL);
va_end( vList); /* Reset variable arguments. */
}
/*
* Used probably by a handler to add a header block to the Serializer.
*/
int SoapSerializer::addHeaderBlock(IHeaderBlock* pBlk)
{
if (m_pSoapEnvelope)
{
if(!m_pSoapEnvelope->m_pSoapHeader) m_pSoapEnvelope->m_pSoapHeader =
new SoapHeader();
}
else /* error : by this time there should be an envelope */
{
return AXIS_FAIL;
}
m_pSoapEnvelope->m_pSoapHeader->addHeaderBlock((HeaderBlock*)pBlk);
return AXIS_SUCCESS;
}
int SoapSerializer::setBodyAsHexBinary(xsd__hexBinary body)
{
/* TODO */
return AXIS_SUCCESS;
}
int SoapSerializer::setBodyAsBase64Binary(xsd__base64Binary body)
{
/* TODO */
return AXIS_SUCCESS;
}
const AxisChar* SoapSerializer::getBodyAsString()
{
/* TODO */
return NULL;
}
/* following two functions are needed by serializer functions of complex types
* for RPC style web services
*/
void SoapSerializer::serializeStartElementOfType(const AxisChar* pName,
const AxisChar* pNamespace,
const AxisChar* pPrefix)
{
if (pPrefix)
{
serialize("<", pName, " xsi:type=\"", pPrefix, ":", pName, "\" xmlns:",
pPrefix, "=\"", pNamespace, "\">", NULL);
}
else
{
serialize("<", pName, ">", NULL);
}
}
void SoapSerializer::serializeEndElementOfType(const AxisChar* pName)
{
serialize("</", pName, ">", NULL);
}
/*
* Callback function that should be called by the transport module to release
* a buffer passed to it by a Serializer.
* @param
* buffer - Same buffer passed to transport by calling transport's
* AXIS_MODULE_CALLBACK_SEND_MESSAGE_BYTES
* callback
* buffer - Same bufferid passed to transport by calling transport's
* AXIS_MODULE_CALLBACK_SEND_MESSAGE_BYTES
* callback
* stream - Same stream object passed to transport by calling
* transport's AXIS_MODULE_CALLBACK_SEND_MESSAGE_BYTES
* callback
*/
#ifndef USER_SERIALIZER
void SoapSerializer::releaseBufferCallBack(const char* buffer, const void* bufferid)
{
int* pInt = (int*)bufferid;
*pInt = 0; /* set that the buffer is not in use */
char *pChar = const_cast<char*>(buffer);
pChar[0] = '\0'; /* set nul */
}
#endif
IHeaderBlock* SoapSerializer::createHeaderBlock(AxisChar *pachLocalName,
AxisChar *pachUri)
{
HeaderBlock* pHeaderBlock= new HeaderBlock(pachLocalName, pachUri);
setHeaderBlock(pHeaderBlock);
return pHeaderBlock;
}
SoapMethod* SoapSerializer::getSOAPMethod()
{
/*
*TODO
* return the SOAPMethod object if one is available. If not available create a SOAPMethod and set it and return it.
*/
return NULL;
}
int SoapSerializer::setSOAPMethodAttribute(Attribute *pAttribute)
{
m_pSoapEnvelope->m_pSoapBody->m_pSoapMethod->addAttribute(pAttribute);
return AXIS_SUCCESS;
}
int SoapSerializer::serializeAnyObject(AnyType* pAnyObject)
{
int i;
for (i=0; i<pAnyObject->_size; i++)
{
serialize(pAnyObject->_array[i], 0);
}
return AXIS_SUCCESS;
}
int SoapSerializer::addOutputAnyObject(AnyType* pAnyObject)
{
Param* pParam = new Param();
pParam->m_Type = XSD_ANY;
pParam->m_Value.pAnyObject = pAnyObject;
if(m_pSoapEnvelope && (m_pSoapEnvelope->m_pSoapBody) && (m_pSoapEnvelope->
m_pSoapBody->m_pSoapMethod))
{
m_pSoapEnvelope->m_pSoapBody->m_pSoapMethod->addOutputParam(pParam);
}
return AXIS_SUCCESS;
}
IHeaderBlock* SoapSerializer::getHeaderBlock()
{
if ((!m_pSoapEnvelope) || (!m_pSoapEnvelope->m_pSoapHeader)) return NULL;
return (HeaderBlock*)m_pSoapEnvelope->m_pSoapHeader->getHeaderBlock(false);
}
IHeaderBlock* SoapSerializer::getHeaderBlock(const AxisChar *pcName,
const AxisChar *pcNamespace)
{
if ((!m_pSoapEnvelope) || (!m_pSoapEnvelope->m_pSoapHeader)) return NULL;
/* there has been no <Header> element so there
can be no Header blocks */
return m_pSoapEnvelope->m_pSoapHeader->getHeaderBlock(pcName, pcNamespace, false);
}