| /* -*- C++ -*- */ |
| |
| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 2002 The Apache Software Foundation. All rights |
| * reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. The end-user documentation included with the redistribution, |
| * if any, must include the following acknowledgment: |
| * "This product includes software developed by the |
| * Apache Software Foundation (http://www.apache.org/)." |
| * Alternately, this acknowledgment may appear in the software itself, |
| |
| |
| * if and wherever such third-party acknowledgments normally appear. |
| * |
| * 4. The names "SOAP" and "Apache Software Foundation" must |
| * not be used to endorse or promote products derived from this |
| * software without prior written permission. For written |
| * permission, please contact apache@apache.org. |
| * |
| * 5. Products derived from this software may not be called "Apache", |
| * nor may "Apache" appear in their name, without prior written |
| * permission of the Apache Software Foundation. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| * |
| * |
| * |
| * |
| * @author Roshan Weerasuriya (roshan@jkcs.slt.lk) |
| * @author Susantha Kumara (susantha@opensource.lk, skumara@virtusa.com) |
| * |
| */ |
| |
| // SoapSerializer.cpp: implementation of the SoapSerializer class. |
| // |
| ////////////////////////////////////////////////////////////////////// |
| |
| #ifdef WIN32 |
| #pragma warning (disable : 4786) |
| #endif |
| |
| #include <axis/soap/SoapEnvelope.h> |
| #include <axis/soap/SoapSerializer.h> |
| #include <axis/soap/HeaderBlock.h> |
| #include <axis/common/GDefine.h> |
| #include <axis/common/Packet.h> |
| #include <axis/common/ArrayBean.h> |
| #include <axis/common/BasicTypeSerializer.h> |
| #include <axis/soap/SoapKeywordMapping.h> |
| #include <stdio.h> |
| #include <stdarg.h> |
| |
| #include <axis/common/AxisTrace.h> |
| |
| ////////////////////////////////////////////////////////////////////// |
| // Construction/Destruction |
| ////////////////////////////////////////////////////////////////////// |
| // Following values should come from axis configuration files. |
| #define INITIAL_SERIALIZE_BUFFER_SIZE 4096 |
| #define NO_OF_SERIALIZE_BUFFERS 10 |
| |
| IWrapperSoapSerializerFunctions IWrapperSoapSerializer::ms_VFtable; |
| |
| SoapSerializer::SoapSerializer() |
| { |
| __vfptr = &ms_VFtable; |
| 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; |
| } |
| |
| int SoapSerializer::setSoapEnvelope(SoapEnvelope *pSoapEnvelope) |
| { |
| m_pSoapEnvelope = pSoapEnvelope; |
| |
| return AXIS_SUCCESS; |
| } |
| |
| int SoapSerializer::setSoapHeader(SoapHeader *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(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)) { |
| 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::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(const Ax_soapstream* pStream) |
| { |
| m_pOutputStream = pStream; |
| int iStatus= AXIS_SUCCESS; |
| |
| if(m_pSoapEnvelope) { |
| Serialize("<?xml version='1.0' encoding='utf-8' ?>", NULL); |
| iStatus= m_pSoapEnvelope->serialize(*this, (SOAP_VERSION)m_iSoapVersion); |
| SendSerializedBuffer(); |
| } |
| 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->transport.pSendFunct((char*)NULL, NULL, m_pOutputStream); |
| } |
| |
| /** |
| * 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); |
| 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(); |
| } |
| |
| 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; |
| if (NULL != m_pOutputStream->transport.pSendFunct) |
| { |
| nStatus = m_pOutputStream->transport.pSendFunct((char*) |
| m_pSZBuffers[m_nCurrentBufferIndex].buffer, (void*)(&(m_pSZBuffers[m_nCurrentBufferIndex].inuse)), m_pOutputStream); |
| 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; |
| } |
| } |
| else |
| { |
| return AXIS_FAIL; |
| } |
| 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; |
| } |
| } |
| AXISTRACE1("No buffers left for serialization"); |
| 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; |
| } |
| |
| /** |
| * 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; |
| } |
| |
| /** |
| * 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; |
| } |
| |
| /** |
| * 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 |
| */ |
| void axis_buffer_release(const char* buffer, const void* bufferid, const void* stream) |
| { |
| 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 */ |
| } |
| |
| |