| |
| /* |
| * Copyright 2003-2004 The Apache Software Foundation. |
| // (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved |
| * |
| * 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. |
| */ |
| |
| |
| // !!! This include file must be first thing in file !!! |
| #include "../platforms/PlatformAutoSense.hpp" |
| |
| #include <list> |
| #include <iostream> |
| |
| #include <axis/Axis.hpp> |
| #include <axis/GDefine.hpp> |
| |
| #include "SoapDeSerializer.h" |
| #include "SoapEnvelope.h" |
| #include "SoapKeywordMapping.h" |
| #include "URIMapping.h" |
| #include "SoapHeader.h" |
| #include "SoapMethod.h" |
| #include "SoapBody.h" |
| #include "SoapFault.h" |
| #include "ComplexElement.h" |
| #include "CharacterElement.h" |
| #include "apr_base64.h" |
| #include "HexCoder.h" |
| #include "../engine/XMLParserFactory.h" |
| #include "../xml/XMLParser.h" |
| #include "../xml/QName.h" |
| #include "../xml/AxisParseException.h" |
| #include "AxisSoapException.h" |
| #include "../common/AxisGenException.h" |
| |
| #include "../common/AxisTrace.h" |
| |
| |
| |
| AxisChar * pBodyContent; |
| |
| AXIS_CPP_NAMESPACE_START |
| |
| SoapDeSerializer:: |
| SoapDeSerializer () |
| { |
| logEntryEngine("SoapDeSerializer::SoapDeSerializer") |
| |
| m_pParser = XMLParserFactory::getParserObject (); |
| m_pEnv = NULL; |
| m_pHeader = NULL; |
| m_pCurrNode = NULL; |
| m_pNode = NULL; |
| m_pInputStream = NULL; |
| m_nStatus = AXIS_SUCCESS; |
| m_nSoapVersion = VERSION_LAST; |
| |
| m_doNotSkip = false; |
| m_pStub = NULL; |
| |
| logExit() |
| } |
| |
| SoapDeSerializer:: |
| ~SoapDeSerializer () |
| { |
| logEntryEngine("SoapDeSerializer::~SoapDeSerializer") |
| |
| delete m_pEnv; |
| delete m_pHeader; |
| if (m_pParser) |
| XMLParserFactory::destroyParserObject (m_pParser); |
| delete pBodyContent; |
| |
| logExit() |
| } |
| |
| int SoapDeSerializer:: |
| setInputStream (SOAPTransport * pInputStream) |
| { |
| logEntryEngine("SoapDeSerializer::setInputStream") |
| |
| int iStatus = AXIS_FAIL; |
| |
| if (NULL != pInputStream) |
| { |
| m_pInputStream = pInputStream; |
| iStatus = m_pParser->setInputStream (pInputStream); |
| } |
| |
| logExitWithReturnCode(iStatus) |
| |
| return iStatus; |
| } |
| |
| /* |
| * Routine to help obtain parser information and throw it as an exception |
| */ |
| void SoapDeSerializer:: |
| throwParserException() |
| { |
| logEntryEngine("SoapDeSerializer::throwParserException") |
| |
| AxisParseException e; |
| |
| if (m_pParser->getStatus() != AXIS_SUCCESS) |
| e.setMessage(m_pParser->getErrorCode(), "AxisParseException:", m_pParser->getErrorString()); |
| else |
| e.setMessage(SERVER_PARSE_PARSER_FAILED, "AxisParseException:"); |
| |
| logThrowExceptionWithData("AxisParseException", e.what()) |
| |
| throw e; |
| } |
| |
| /* |
| * Routine that handles getting next node, in the future when we sync |
| * up rpc and doc processing and eliminate peek, we should be able to |
| * get rid of the first parameter! |
| */ |
| int SoapDeSerializer:: |
| getNextNode(bool ifNotSet, bool characterMode, bool throwExcOnError) |
| { |
| logSetFunctionNameEngine("SoapDeSerializer::getNextNode") |
| |
| int iStatus = AXIS_FAIL; |
| |
| // If node pointer is set and user requested that we |
| // only get next element if not set, return. |
| if (ifNotSet && m_pNode) |
| iStatus = AXIS_SUCCESS; |
| else |
| { |
| // Ensure m_pNode is NULL before calling parser in case of exceptions. |
| m_pNode = NULL; |
| |
| // Just a sanity check |
| if (m_pParser) |
| { |
| try |
| { |
| m_pNode = m_pParser->next(characterMode); |
| } |
| catch (AxisException &e) |
| { |
| m_nStatus = AXIS_FAIL; |
| if (throwExcOnError) |
| throw e; |
| } |
| |
| // If no node obtained, either there is no more data to read (at this time |
| // we treat this as an error but we do not throw an exception for this) or the |
| // parser had an exception, in which case we throw an exception if requested. |
| if (!m_pNode) |
| { |
| m_nStatus = AXIS_FAIL; |
| if (throwExcOnError && (AXIS_FAIL == m_pParser->getStatus())) |
| throwParserException(); |
| } |
| else |
| iStatus = AXIS_SUCCESS; |
| } |
| } |
| |
| if (AXIS_SUCCESS != iStatus) |
| { |
| logDebug("Status being returned is AXIS_FAIL") |
| } |
| |
| return iStatus; |
| } |
| |
| |
| /* |
| * Routine that ensures we are actually skipping the expected node...usually an end node. |
| */ |
| int SoapDeSerializer:: |
| skipNode(bool verifyIfEndNode, bool throwExcOnError) |
| { |
| logEntryEngine("SoapDeSerializer::skipNode") |
| |
| int rc = getNextNode(false, false, throwExcOnError); |
| |
| if (rc == AXIS_SUCCESS) |
| { |
| if (verifyIfEndNode) |
| { |
| // TODO add code to determine if in fact |
| // TODO the node we are about to skip is an end node. If not, we need |
| // TODO to throw an exception since there could be extra elements that |
| // TODO is due to server/client differences in wsdl being used, etc. |
| // TODO in addition, a check is another safeguard. |
| } |
| |
| m_pNode = NULL; |
| } |
| |
| logExitWithReturnCode(rc) |
| |
| return rc; |
| } |
| |
| SoapEnvelope *SoapDeSerializer:: |
| getEnvelope () |
| { |
| logEntryEngine("SoapDeSerializer::getEnvelope") |
| |
| if (AXIS_FAIL == getNextNode(true)) |
| { |
| logExitWithPointer(NULL) |
| |
| return NULL; |
| } |
| |
| // Better be a start-element. |
| if (START_ELEMENT != m_pNode->m_type) |
| { |
| m_nStatus = AXIS_FAIL; |
| |
| logThrowExceptionWithData("AxisSoapException - CLIENT_SOAP_SOAP_CONTENT_ERROR", "Start-element for SOAP Envelope not found.") |
| |
| throw AxisSoapException (CLIENT_SOAP_SOAP_CONTENT_ERROR, "Start-element for SOAP Envelope not found."); |
| } |
| |
| // We are expecting a SOAP envelope. |
| if (0 != strcmp(m_pNode->m_pchNameOrValue,SoapKeywordMapping::map(SOAP_VER_1_2).pchWords[SKW_ENVELOPE])) |
| { |
| m_nStatus = AXIS_FAIL; |
| |
| logThrowExceptionWithData("AxisSoapException - CLIENT_SOAP_SOAP_CONTENT_ERROR", "Element is not a SOAP Envelope.") |
| |
| throw AxisSoapException (CLIENT_SOAP_SOAP_CONTENT_ERROR, "Element is not a SOAP Envelope."); |
| } |
| |
| // No try/catch block needed here since we already have the node |
| SoapEnvelope *m_pEnvl = new SoapEnvelope (); |
| |
| // set all attributes of SoapEnvelope |
| std::list<Attribute*> attributeList0; |
| Attribute * pAttr = new Attribute ( attributeList0); |
| |
| pAttr->setValue (m_pNode->m_pchNamespace); |
| m_pEnvl->addNamespaceDecl (pAttr); |
| |
| if (0 == strcmp (m_pNode->m_pchNamespace, SoapKeywordMapping::map (SOAP_VER_1_1).pchNamespaceUri)) |
| m_nSoapVersion = SOAP_VER_1_1; |
| else if (0 == strcmp (m_pNode->m_pchNamespace, SoapKeywordMapping::map (SOAP_VER_1_2).pchNamespaceUri)) |
| m_nSoapVersion = SOAP_VER_1_2; |
| else |
| m_nSoapVersion = VERSION_LAST; |
| |
| // Set Attributes |
| for (int i = 0; m_pNode->m_pchAttributes[i]; i += 3) |
| { |
| std::list<Attribute*> attributeList1; |
| pAttr = new Attribute (attributeList1); |
| pAttr->setLocalName (m_pNode->m_pchAttributes[i]); |
| pAttr->setURI (m_pNode->m_pchAttributes[i + 1]); |
| pAttr->setValue (m_pNode->m_pchAttributes[i + 2]); |
| m_pEnvl->addAttribute (pAttr); |
| } |
| |
| // indicate node consumed and return envelope |
| m_pNode = NULL; |
| |
| logExitWithPointer(m_pEnvl) |
| |
| return m_pEnvl; |
| } |
| |
| /* |
| * Header block parsing should be done differently for different SOAP versions. |
| * Since the Header blocks may be requested in a different order than it is in |
| * the SOAP stream there must be a mechanism to manage the situation. Possibly |
| * to re-parse the stream part which has unused header blocks. |
| */ |
| IHeaderBlock *SoapDeSerializer:: |
| getHeaderBlock (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| logEntryEngine("SoapDeSerializer::getHeaderBlock") |
| |
| IHeaderBlock * returnValue = NULL; |
| |
| if (m_pHeader) |
| returnValue = m_pHeader->getHeaderBlock (pName, pNamespace, true); |
| |
| logExitWithPointer(returnValue) |
| |
| return returnValue; |
| } |
| |
| int SoapDeSerializer:: |
| getHeader () |
| { |
| logEntryEngine("SoapDeSerializer::getHeader") |
| |
| if (m_pHeader || AXIS_FAIL == getNextNode()) |
| { |
| logExitWithReturnCode(m_nStatus) |
| |
| return m_nStatus; |
| } |
| |
| if ((START_ELEMENT == m_pNode->m_type) |
| && (m_nSoapVersion != VERSION_LAST) |
| && (0 == strcmp (m_pNode->m_pchNameOrValue,SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_HEADER]))) |
| { |
| delete m_pHeader; |
| m_pHeader = new SoapHeader (); |
| |
| // Set any attributes/namspaces to the SoapHeader object |
| while (true) |
| { |
| if (AXIS_FAIL == getNextNode(false, true, false)) |
| break; |
| |
| if ((END_ELEMENT == m_pNode->m_type) && |
| (0 == strcmp (m_pNode->m_pchNameOrValue,SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_HEADER]))) |
| { |
| m_pNode = NULL; // indicate node consumed |
| break; |
| } |
| |
| // following is done to ignore anything (eg : the toplevel whitespaces) but a start element. |
| if (START_ELEMENT != m_pNode->m_type) |
| { |
| m_pNode = NULL; // indicate node consumed |
| continue; |
| } |
| |
| HeaderBlock *pHeaderBlock = new HeaderBlock (); |
| |
| if (m_pNode->m_pchNamespace) |
| pHeaderBlock->setURI (m_pNode->m_pchNamespace); |
| |
| pHeaderBlock->setLocalName (m_pNode->m_pchNameOrValue); |
| |
| if ((m_pNode->m_pchAttributes[0]) != NULL) |
| { |
| int iAttributeArrayIndex = 0; |
| |
| while (true) |
| { |
| std::list<Attribute*> attributeList2; |
| Attribute *pAttribute = new Attribute (attributeList2); |
| pAttribute->setLocalName (m_pNode->m_pchAttributes[iAttributeArrayIndex++]); |
| pAttribute->setURI (m_pNode->m_pchAttributes[iAttributeArrayIndex++]); |
| pAttribute->setValue (m_pNode->m_pchAttributes[iAttributeArrayIndex++]); |
| |
| pHeaderBlock->addAttribute (pAttribute); |
| |
| if (m_pNode->m_pchAttributes[iAttributeArrayIndex] == '\0') |
| break; |
| } |
| } |
| |
| BasicNode *pNodeList[10]; |
| pNodeList[0] = NULL; |
| int iListPos = 0; |
| int iLevel = 0; |
| |
| while (true) |
| { |
| if (AXIS_FAIL == getNextNode(false, true, false)) |
| break; |
| |
| if (END_ELEMENT == m_pNode->m_type) |
| { |
| if (iLevel == 0) |
| { |
| //do nothing |
| m_pHeader->addHeaderBlock (pHeaderBlock); |
| break; |
| } |
| else if (iLevel == 1) |
| { |
| if ((pNodeList[0]) != NULL) |
| { |
| pHeaderBlock->addChild (pNodeList[0]); |
| iListPos--; |
| iLevel--; |
| } |
| } |
| else |
| { |
| (pNodeList[iListPos - 2])->addChild (pNodeList[iListPos - 1]); |
| iListPos--; |
| iLevel--; |
| } |
| } |
| else if (START_ELEMENT == m_pNode->m_type) |
| { |
| //createBaisNode and setValue |
| BasicNode *pComplexElement = new ComplexElement (); |
| |
| if (m_pNode->m_pchNamespace) |
| pComplexElement->setURI (m_pNode->m_pchNamespace); |
| |
| pComplexElement->setLocalName (m_pNode->m_pchNameOrValue); |
| |
| //addtoList |
| pNodeList[iListPos] = pComplexElement; |
| iListPos++; |
| iLevel++; |
| } |
| else if (CHARACTER_ELEMENT == m_pNode->m_type) |
| { |
| //createBasicNode and setValue |
| BasicNode *pBasicNode = new CharacterElement (m_pNode->m_pchNameOrValue); |
| |
| //addToImmidiateParent |
| if (iLevel == 0) |
| pHeaderBlock->addChild (pBasicNode); |
| else |
| (pNodeList[iListPos - 1])->addChild (pBasicNode); |
| } |
| } // end while |
| } |
| } |
| |
| logExitWithReturnCode(m_nStatus) |
| |
| return m_nStatus; |
| } |
| |
| // This method adds to allow "all" & "choice" constructs to peek head next element. |
| const char*SoapDeSerializer:: |
| peekNextElementName () |
| { |
| logEntryEngine("SoapDeSerializer::peekNextElementName") |
| |
| const char*name = NULL; |
| |
| if (m_pParser) |
| name = m_pParser->peek (); |
| |
| logExitWithString(name) |
| |
| return name; |
| } |
| |
| int SoapDeSerializer:: |
| getBody () |
| { |
| logEntryEngine("SoapDeSerializer::getBody") |
| |
| int iStatus = AXIS_FAIL; |
| |
| if (AXIS_FAIL == getNextNode(true)) |
| iStatus = m_nStatus; |
| else |
| { |
| // previous header searching may have left a node unidentified |
| if ((START_ELEMENT == m_pNode->m_type) |
| && (m_nSoapVersion != VERSION_LAST) |
| && (0 == strcmp (m_pNode->m_pchNameOrValue,SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY]))) |
| { |
| // indicate node consumed |
| m_pNode = NULL; |
| |
| // peek for the method name |
| m_strMethodNameToInvoke = m_pParser->peek(); |
| |
| iStatus = AXIS_SUCCESS; |
| } |
| } |
| |
| logExitWithReturnCode(iStatus) |
| |
| return iStatus; |
| } |
| |
| int SoapDeSerializer:: |
| checkMessageBody (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| return validateMessageBody(pName, pNamespace, true); |
| } |
| |
| int SoapDeSerializer:: |
| validateMessageBody(const AxisChar * pName, const AxisChar * pNamespace, bool consumeIt) |
| { |
| logEntryEngine("SoapDeSerializer::validateMessageBody") |
| |
| int iStatus = AXIS_FAIL; |
| |
| // Will throw exception if failure in parser |
| if (AXIS_FAIL != getNextNode(true)) |
| { |
| if (START_ELEMENT != m_pNode->m_type) |
| { |
| logThrowExceptionWithData("AxisSoapException - CLIENT_SOAP_SOAP_CONTENT_ERROR", "Start-element was not found.") |
| |
| throw AxisSoapException (CLIENT_SOAP_SOAP_CONTENT_ERROR, "Start-element was not found."); |
| } |
| |
| // If a fault has occurred or the node name is unexpected, throw exception |
| // deserialize it as doc literal by setting style. |
| if (0 != strcmp (m_pNode->m_pchNameOrValue, pName)) |
| { |
| setStyle (DOC_LITERAL); |
| |
| logThrowException("AxisGenException - AXISC_NODE_VALUE_MISMATCH_EXCEPTION") |
| |
| throw AxisGenException (AXISC_NODE_VALUE_MISMATCH_EXCEPTION); |
| } |
| |
| // indicate node consumed |
| if (consumeIt) |
| m_pNode = NULL; |
| |
| iStatus = AXIS_SUCCESS; |
| } |
| |
| logExitWithReturnCode(iStatus) |
| |
| return iStatus; |
| } |
| |
| // Used for one-way message processing, to initiate a fault. |
| void SoapDeSerializer:: |
| initiateFault (const AxisChar * pNamespace) |
| { |
| logEntryEngine("SoapDeSerializer::initiateFault") |
| |
| // Will throw exception if failure in parser |
| if (AXIS_FAIL != getNextNode(true)) |
| { |
| if (START_ELEMENT != m_pNode->m_type) |
| { |
| logThrowExceptionWithData("AxisSoapException - CLIENT_SOAP_SOAP_CONTENT_ERROR", "Start-element was not found.") |
| |
| throw AxisSoapException (CLIENT_SOAP_SOAP_CONTENT_ERROR, "Start-element was not found."); |
| } |
| |
| setStyle (DOC_LITERAL); |
| |
| logThrowException("AxisGenException - AXISC_NODE_VALUE_MISMATCH_EXCEPTION") |
| |
| throw AxisGenException (AXISC_NODE_VALUE_MISMATCH_EXCEPTION); |
| } |
| |
| logExit() |
| } |
| |
| void *SoapDeSerializer:: |
| checkForFault (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| logEntryEngine("SoapDeSerializer::checkForFault") |
| |
| if (0 != strcmp ("Fault", pName)) |
| { |
| logThrowExceptionWithData("AxisGenException - AXISC_NODE_VALUE_MISMATCH_EXCEPTION", "Fault element name not valid.") |
| |
| throw AxisGenException (AXISC_NODE_VALUE_MISMATCH_EXCEPTION, |
| "Fault element name not valid."); |
| } |
| |
| if (0 != strcmp (m_pNode->m_pchNameOrValue, pName)) |
| { |
| m_nStatus = AXIS_SUCCESS; |
| m_pNode = NULL; |
| |
| logThrowException("AxisGenException - AXISC_NODE_VALUE_MISMATCH_EXCEPTION") |
| |
| throw AxisGenException (AXISC_NODE_VALUE_MISMATCH_EXCEPTION); |
| } |
| |
| char *pcDetail = NULL; |
| char *pcFaultCode = NULL; |
| char *pcFaultstring = NULL; |
| char *pcFaultactor = NULL; |
| |
| SoapFault *pFault = new SoapFault (); |
| pFault->setDeSerializer (this); |
| |
| // indicate node consumed |
| m_nStatus = AXIS_SUCCESS; |
| m_pNode = NULL; |
| |
| // We deserialize fault code in doc literal. |
| m_nStyle = getStyle (); |
| setStyle (DOC_LITERAL); |
| |
| // getElement or peek will throw exceptions, so need to clean up memory allocations |
| try |
| { |
| // Get fault code |
| pcFaultCode = getElementAsString ("faultcode", 0); |
| pFault->setFaultcode (pcFaultCode == NULL ? "" : pcFaultCode); |
| delete [] pcFaultCode; |
| |
| // Get fault string |
| pcFaultstring = getElementAsString ("faultstring", 0); |
| pFault->setFaultstring (pcFaultstring == NULL ? "" : pcFaultstring); |
| delete [] pcFaultstring; |
| |
| // faultactor is optional |
| const char* elementName = peekNextElementName(); |
| if (strcmp(elementName, "faultactor") == 0) |
| { |
| pcFaultactor = getElementAsString ("faultactor", 0); |
| pFault->setFaultactor (pcFaultactor == NULL ? "" : pcFaultactor); |
| delete [] pcFaultactor; |
| } |
| |
| // detail is optional. |
| // Changed the namespace from null to a single space (an impossible |
| // value) to help method know that it is parsing a fault message. |
| elementName = peekNextElementName(); |
| if (strcmp(elementName, "detail") == 0) |
| { |
| pcDetail = getElementAsString ("detail", " "); |
| |
| if (pcDetail) |
| { |
| pFault->setFaultDetail (pcDetail); |
| delete [] pcDetail; |
| } |
| else |
| { |
| const char *pcCmplxFaultName = ""; |
| |
| if ((AXIS_SUCCESS == getNextNode(true)) && m_pNode->m_pchNameOrValue) |
| pcCmplxFaultName = m_pNode->m_pchNameOrValue; |
| |
| pFault->setCmplxFaultObjectName (pcCmplxFaultName); |
| } |
| } |
| } |
| catch ( ... ) |
| { |
| setStyle (m_nStyle); |
| |
| delete [] pcFaultCode; |
| delete [] pcFaultstring; |
| delete [] pcFaultactor; |
| delete [] pcDetail; |
| delete pFault; |
| |
| logRethrowException() |
| |
| throw; |
| } |
| |
| setStyle (m_nStyle); |
| |
| logExitWithPointer(pFault) |
| |
| return pFault; |
| } |
| |
| int SoapDeSerializer:: |
| init () |
| { |
| logEntryEngine("SoapDeSerializer::init") |
| |
| m_pNode = NULL; |
| m_pCurrNode = NULL; |
| |
| delete m_pEnv; |
| m_pEnv = NULL; |
| |
| delete m_pHeader; |
| m_pHeader = NULL; |
| |
| m_nSoapVersion = VERSION_LAST; |
| m_nStatus = AXIS_SUCCESS; |
| |
| m_pStub = NULL; |
| |
| logExitWithReturnCode(m_nStatus) |
| |
| return m_nStatus; |
| } |
| |
| int SoapDeSerializer:: |
| getVersion () |
| { |
| logEntryEngine("SoapDeSerializer::getVersion") |
| |
| if (VERSION_LAST == m_nSoapVersion) |
| { |
| delete m_pEnv; |
| m_pEnv = NULL; |
| m_pEnv = getEnvelope (); |
| } |
| |
| logExitWithInteger(m_nSoapVersion) |
| |
| return m_nSoapVersion; |
| } |
| |
| /* |
| * Get Size of the single dimension array from arrayType attribute |
| * Ex : enc:arrayType="xs:string[6]" |
| * RPC/Encoded only processing. |
| */ |
| int SoapDeSerializer:: |
| getArraySize () |
| { |
| logEntryEngine("SoapDeSerializer::getArraySize") |
| |
| int nSize = 0; |
| |
| // If not RPC or failure in getNextNode, return zero. |
| if (RPC_ENCODED != m_nStyle || (AXIS_FAIL == getNextNode())) |
| { |
| logExitWithInteger(nSize) |
| |
| return nSize; |
| } |
| |
| // first check whether this is a start element node |
| if (START_ELEMENT == m_pNode->m_type) |
| { |
| // If start-end element, then empty array |
| if (START_END_ELEMENT == m_pNode->m_type2) |
| { |
| skipNode(); |
| |
| logExitWithInteger(nSize) |
| |
| return nSize; |
| } |
| } |
| else if (END_ELEMENT == m_pNode->m_type) |
| { |
| logExitWithInteger(nSize) |
| |
| return nSize; |
| } |
| |
| for (int i = 0; m_pNode->m_pchAttributes[i]; i += 3) |
| { |
| if (URI_ENC == URIMapping::getURI (m_pNode->m_pchAttributes[i + 1]) |
| && (0 == strcmp (m_pNode->m_pchAttributes[i], |
| SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_ARRAYTYPE]))) |
| { |
| QName qn; |
| |
| qn.splitQNameString (m_pNode->m_pchAttributes[i + 2], '['); |
| nSize = strtol (qn.localname, &m_pEndptr, 10); |
| qn.mergeQNameString ('['); |
| |
| if (nSize == 0) |
| skipNode(); |
| |
| logExitWithInteger(nSize) |
| |
| return nSize; |
| } |
| } |
| |
| logExitWithInteger(nSize) |
| |
| return nSize; |
| } |
| |
| |
| /* |
| * In rpc/encoded style the stream is as follows, |
| * <abc:ArrayOfPoints xmlns:abc="http://www.opensource.lk/Points" |
| * xmlns:enc="http://www.w3.org/2001/06/soap-encoding" |
| * enc:arrayType="xsd:Point[2]"> |
| * <abc:Point><x>5</x><y>6</y></abc:Point> |
| * <abc:Point><x>7</x><y>8</y></abc:Point> |
| * </abc:ArrayOfPoints> |
| * But in doc/literal style it is, |
| * <points><x>5</x><y>6</y></points> |
| * <points><x>7</x><y>8</y></points> |
| * |
| */ |
| |
| Axis_Array *SoapDeSerializer:: |
| getCmplxArray (Axis_Array* pArray, |
| void *pDZFunct, void *pCreFunct, void *pDelFunct, |
| const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| logEntryEngine("SoapDeSerializer::getCmplxArray") |
| |
| // if anything has gone wrong earlier just do nothing |
| if (AXIS_SUCCESS == m_nStatus) |
| { |
| // Loop through the array adding elements. |
| int arraySize = getArraySize (); |
| int count = 0; |
| const char* elementName; |
| |
| while(RPC_ENCODED != m_nStyle || count < arraySize) |
| { |
| // For RPC-encoded arrays, the element name in array cannot be derived - |
| // within an array value element names are not significant - so |
| // we read until end-of-element is encountered (i.e. null string |
| // is returned from peek()). |
| elementName = m_pParser->peek(); |
| if ((RPC_ENCODED == m_nStyle && 0x00 != *elementName) || strcmp(elementName, pName) == 0) |
| pArray->addElement(getCmplxObject(pDZFunct, pCreFunct, pDelFunct, pName, pNamespace)); |
| else |
| break; |
| |
| ++count; |
| } |
| |
| if (AXIS_FAIL == m_nStatus) // TODO - not sure this line is needed |
| m_pNode = NULL; // TODO - not sure this line is needed |
| else if (arraySize > 0) |
| skipNode(); |
| } |
| |
| logExitWithPointer(pArray) |
| |
| return pArray; |
| } |
| |
| /* |
| * In rpc/encoded style the stream is as follows, |
| * <abc:ArrayOfPhoneNumbers xmlns:abc="http://example.org/2001/06/numbers" |
| * xmlns:enc="http://www.w3.org/2001/06/soap-encoding" |
| * enc:arrayType="xsd:string[2]"> |
| * <item>+94-112-500500</item> |
| * <item>+94-112-500500</item> |
| * </abc:ArrayOfPhoneNumbers> |
| * But in doc/literal style it is, |
| * <phonenumbers>+94-112-500500</phonenumbers> |
| * <phonenumbers>+94-112-500500</phonenumbers> |
| * |
| * |
| */ |
| |
| Axis_Array*SoapDeSerializer:: |
| getBasicArray (XSDTYPE nType, const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| logEntryEngine("SoapDeSerializer::getBasicArray") |
| |
| int size = 0; |
| Axis_Array* Array = new Axis_Array(); |
| Array->m_Type = nType; |
| |
| // if anything has gone wrong earlier just do nothing |
| if (AXIS_SUCCESS == m_nStatus) |
| { |
| // Loop through the array adding elements. |
| IAnySimpleType* pSimpleType = NULL; |
| void * pValue = NULL; |
| |
| try |
| { |
| size = getArraySize (); |
| const char* elementName; |
| int count = 0; |
| |
| while(RPC_ENCODED != m_nStyle || count < size) |
| { |
| // For RPC-encoded arrays, the element name in array cannot be derived - |
| // within an array value element names are not significant - |
| // so we read until end-of-element is encountered (i.e. null string |
| // is returned from peek()). |
| elementName = m_pParser->peek(); |
| if ((RPC_ENCODED == m_nStyle && 0x00 != *elementName) || strcmp(elementName, pName) == 0) |
| { |
| // TODO instead of deleting the pointer use it by by-passing addElement(). |
| if (XSD_ANYTYPE != nType) |
| { |
| if (0 == count) |
| pSimpleType = AxisUtils::createSimpleTypeObject(nType); |
| getElement(pName, pNamespace, pSimpleType, (bool)(RPC_ENCODED == m_nStyle)); |
| pValue = pSimpleType->getValue(); |
| Array->addElement(pValue); |
| Axis::AxisDelete(pValue, pSimpleType->getType()); |
| } |
| else |
| { |
| pValue = getElementAsAnyType(pName, pNamespace); |
| Array->addElement(pValue); |
| Axis::AxisDelete(pValue, XSD_ANYTYPE); |
| } |
| |
| pValue = NULL; |
| } |
| else |
| break; |
| |
| ++count; |
| } |
| } |
| catch ( ... ) |
| { |
| if (pSimpleType) |
| { |
| if (pValue) |
| Axis::AxisDelete(pValue, pSimpleType->getType()); |
| delete pSimpleType; |
| } |
| |
| delete Array; |
| |
| logRethrowException() |
| |
| throw; |
| } |
| |
| delete pSimpleType; |
| |
| if (AXIS_FAIL == m_nStatus) // TODO - not sure this line is needed |
| m_pNode = NULL; // TODO - not sure this line is needed |
| else if (size > 0) |
| skipNode(); |
| } |
| |
| logExitWithPointer(Array) |
| |
| return Array; |
| } |
| |
| /* |
| * In doc/lit style pName is the name of the type instance "result" |
| * <result> |
| * <name>Widgets Inc.</name> |
| * <symbol>WID</symbol> |
| * <public>true</public> |
| * </result> |
| * But in rpc/encoded style pName is the name of the type "QuoteInfoType" |
| * <tns:QuoteInfoType xmlns:tns="http://www.getquote.org/test"> |
| * <name xsi:type="xsd:string">Widgets Inc.</name> |
| * <symbol xsi:type="xsd:string">WID</symbol> |
| * <public xsi:type="xsd:boolean">true</public> |
| * </tns:QuoteInfoType> |
| * |
| */ |
| void *SoapDeSerializer:: |
| getCmplxObject (void *pDZFunct, void *pCreFunct, void *pDelFunct, |
| const AxisChar * pName, const AxisChar * pNamespace, bool isFault) |
| { |
| logEntryEngine("SoapDeSerializer::getCmplxObject") |
| |
| if (!isFault) |
| { |
| if (AXIS_SUCCESS == m_nStatus && (RPC_ENCODED != m_nStyle) && (m_pNode == NULL)) |
| { |
| const char*name = peekNextElementName(); |
| if (0 != strcmp (pName, name)) |
| { |
| logExitWithPointer(NULL) |
| |
| return NULL; |
| } |
| } |
| |
| if (AXIS_SUCCESS != m_nStatus || (AXIS_FAIL == getNextNode(RPC_ENCODED != m_nStyle))) |
| { |
| logExitWithPointer(NULL) |
| |
| return NULL; |
| } |
| } |
| |
| if (RPC_ENCODED != m_nStyle) // TODO - why do we selectively do this check and not for all? |
| if (0 != strcmp (pName, m_pNode->m_pchNameOrValue)) |
| { |
| /* |
| * TODO: Need to verify what WS-I 1.0 says |
| * about the mandatory of all the elements in the response in case of |
| * null value or none filled value. Some Web services servers work |
| * like this. This apply for all the rest of the deserializer. |
| */ |
| logExitWithPointer(NULL) |
| |
| return NULL; |
| } |
| |
| // TODO - even if node is nil, there may be attributes associated with the element that |
| // TODO - need to be deserialized - thus in the generated code we need to get the nil |
| // TODO - attribute if element is nillable and check if it is true or false, in which case |
| // TODO - we would short-circuit the deserialization after any other attributes have been |
| // TODO - obtained. Thus changes will need to be made here and in the code generator. |
| // if node contain attributes let them be used by the complex type's deserializer |
| if (isNilValue()) |
| { |
| skipNode(); |
| |
| logExitWithPointer(NULL) |
| |
| return NULL; |
| } |
| |
| // Make attributes available to code that deserializes the attributes |
| m_pCurrNode = NULL; |
| if (0 != m_pNode->m_pchAttributes[0]) |
| m_pCurrNode = m_pNode; |
| |
| // indicate node consumed |
| m_pNode = NULL; |
| |
| if (!isFault && AXIS_FAIL == m_nStatus) |
| { |
| logExitWithPointer(NULL) |
| |
| return NULL; |
| } |
| |
| // Call the Axis-generated routine that will deserialize complex object, |
| // including any attributes. |
| |
| logDebugArg1("Calling object create function for %s", pName) |
| |
| void *pObject = ((AXIS_OBJECT_CREATE_FUNCT) pCreFunct) (0); |
| |
| logDebugArg2("Returned from object create function for %s, returned object %p", pName, pObject) |
| |
| if (pObject && pDZFunct) |
| { |
| try |
| { |
| m_doNotSkip = false; |
| |
| logDebugArg1("Calling object deserializer function for %s", pName) |
| |
| m_nStatus = ((AXIS_DESERIALIZE_FUNCT) pDZFunct) (pObject, this); |
| |
| logDebugArg2("Returned from object deserializer function for %s, status=%d", pName, m_nStatus) |
| |
| |
| if (AXIS_SUCCESS == m_nStatus) |
| { |
| if (!m_doNotSkip) |
| skipNode(); |
| m_doNotSkip = false; |
| } |
| else |
| { |
| logDebugArg2("Calling object delete function for %s for object %p", pName, pObject) |
| |
| ((AXIS_OBJECT_DELETE_FUNCT) pDelFunct) (pObject, 0); |
| |
| logDebugArg1("Returned from object delete function for %s", pName) |
| |
| pObject = NULL; |
| } |
| } |
| catch ( ... ) |
| { |
| logDebugArg2("Calling object delete function for %s for object %p", pName, pObject) |
| |
| ((AXIS_OBJECT_DELETE_FUNCT) pDelFunct) (pObject, 0); |
| |
| logDebugArg1("Returned from object delete function for %s", pName) |
| |
| logRethrowException() |
| |
| throw; |
| } |
| } |
| |
| logExitWithPointer(pObject) |
| |
| return pObject; |
| } |
| |
| void * SoapDeSerializer:: |
| getAttribute(const AxisChar* pName, const AxisChar * pNamespace, IAnySimpleType * pSimpleType) |
| { |
| logEntryEngine("SoapDeSerializer::getAttribute") |
| |
| void *returnValue = NULL; |
| |
| if (m_pCurrNode) |
| { |
| for (int i=0; m_pCurrNode->m_pchAttributes[i]; i += 3) |
| { |
| if (0 == strcmp(m_pCurrNode->m_pchAttributes[i], pName)) |
| { |
| pSimpleType->deserialize(m_pCurrNode->m_pchAttributes[i+2]); |
| returnValue = pSimpleType->getValue(); |
| break; |
| } |
| } |
| } |
| |
| logExitWithPointer(returnValue) |
| |
| return returnValue; |
| } |
| |
| xsd__int *SoapDeSerializer:: |
| getAttributeAsInt (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Int simpleType; |
| return (xsd__int *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__boolean *SoapDeSerializer:: |
| getAttributeAsBoolean (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Boolean simpleType; |
| return (xsd__boolean *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__unsignedInt *SoapDeSerializer:: |
| getAttributeAsUnsignedInt (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| UnsignedInt simpleType; |
| return (xsd__unsignedInt *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__short *SoapDeSerializer:: |
| getAttributeAsShort (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Short simpleType; |
| return (xsd__short *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__unsignedShort *SoapDeSerializer:: |
| getAttributeAsUnsignedShort (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| UnsignedShort simpleType; |
| return (xsd__unsignedShort *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__byte *SoapDeSerializer:: |
| getAttributeAsByte (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Byte simpleType; |
| return (xsd__byte *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__unsignedByte *SoapDeSerializer:: |
| getAttributeAsUnsignedByte (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| UnsignedByte simpleType; |
| return (xsd__unsignedByte *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__long *SoapDeSerializer:: |
| getAttributeAsLong (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Long simpleType; |
| return (xsd__long *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__integer *SoapDeSerializer:: |
| getAttributeAsInteger (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Integer simpleType; |
| return (xsd__integer *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__nonNegativeInteger *SoapDeSerializer:: |
| getAttributeAsNonNegativeInteger (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NonNegativeInteger simpleType; |
| return (xsd__nonNegativeInteger *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__positiveInteger *SoapDeSerializer:: |
| getAttributeAsPositiveInteger (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| PositiveInteger simpleType; |
| return (xsd__positiveInteger *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__nonPositiveInteger *SoapDeSerializer:: |
| getAttributeAsNonPositiveInteger (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NonPositiveInteger simpleType; |
| return (xsd__nonPositiveInteger *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__negativeInteger *SoapDeSerializer:: |
| getAttributeAsNegativeInteger (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NegativeInteger simpleType; |
| return (xsd__negativeInteger *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__unsignedLong *SoapDeSerializer:: |
| getAttributeAsUnsignedLong (const AxisChar *pName, const AxisChar * pNamespace) |
| { |
| UnsignedLong simpleType; |
| return (xsd__unsignedLong *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__float *SoapDeSerializer:: |
| getAttributeAsFloat (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Float simpleType; |
| return (xsd__float *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__double *SoapDeSerializer:: |
| getAttributeAsDouble (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Double simpleType; |
| return (xsd__double *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__decimal *SoapDeSerializer:: |
| getAttributeAsDecimal (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Decimal simpleType; |
| return (xsd__decimal *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__NOTATION SoapDeSerializer:: |
| getAttributeAsNOTATION (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NOTATION simpleType; |
| return (xsd__NOTATION)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__string SoapDeSerializer:: |
| getAttributeAsString (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| String simpleType; |
| return (xsd__string)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__normalizedString SoapDeSerializer:: |
| getAttributeAsNormalizedString (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NormalizedString simpleType; |
| return (xsd__normalizedString)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__token SoapDeSerializer:: |
| getAttributeAsToken (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Token simpleType; |
| return (xsd__token)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__language SoapDeSerializer:: |
| getAttributeAsLanguage (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Language simpleType; |
| return (xsd__language)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__NMTOKEN SoapDeSerializer:: |
| getAttributeAsNMTOKEN (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NMTOKEN simpleType; |
| return (xsd__NMTOKEN)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__NMTOKENS SoapDeSerializer:: |
| getAttributeAsNMTOKENS (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NMTOKENS simpleType; |
| return (xsd__NMTOKENS)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__Name SoapDeSerializer:: |
| getAttributeAsName (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Name simpleType; |
| return (xsd__Name)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__NCName SoapDeSerializer:: |
| getAttributeAsNCName (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NCName simpleType; |
| return (xsd__NCName)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__ID SoapDeSerializer:: |
| getAttributeAsID (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| ID simpleType; |
| return (xsd__ID)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__IDREF SoapDeSerializer:: |
| getAttributeAsIDREF (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| IDREF simpleType; |
| return (xsd__IDREF)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__IDREFS SoapDeSerializer:: |
| getAttributeAsIDREFS (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| IDREFS simpleType; |
| return (xsd__IDREFS)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__ENTITY SoapDeSerializer:: |
| getAttributeAsENTITY (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| ENTITY simpleType; |
| return (xsd__ENTITY)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__ENTITIES SoapDeSerializer:: |
| getAttributeAsENTITIES (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| ENTITIES simpleType; |
| return (xsd__ENTITIES)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__anyURI SoapDeSerializer:: |
| getAttributeAsAnyURI (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| AnyURI simpleType; |
| return (xsd__anyURI)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__QName SoapDeSerializer:: |
| getAttributeAsQName (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| XSD_QName simpleType; |
| return (xsd__QName)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__hexBinary *SoapDeSerializer:: |
| getAttributeAsHexBinary (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| HexBinary simpleType; |
| return (xsd__hexBinary *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__base64Binary *SoapDeSerializer:: |
| getAttributeAsBase64Binary (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Base64Binary simpleType; |
| return (xsd__base64Binary *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__dateTime *SoapDeSerializer:: |
| getAttributeAsDateTime (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| DateTime simpleType; |
| return (xsd__dateTime *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__date *SoapDeSerializer:: |
| getAttributeAsDate (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Date simpleType; |
| return (xsd__date *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__time *SoapDeSerializer:: |
| getAttributeAsTime (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Time simpleType; |
| return (xsd__time *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__gDay*SoapDeSerializer:: |
| getAttributeAsGDay (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| GDay simpleType; |
| return (xsd__gDay *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__gMonth*SoapDeSerializer:: |
| getAttributeAsGMonth (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| GMonth simpleType; |
| return (xsd__gMonth *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__gMonthDay*SoapDeSerializer:: |
| getAttributeAsGMonthDay (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| GMonthDay simpleType; |
| return (xsd__gMonthDay *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__gYear*SoapDeSerializer:: |
| getAttributeAsGYear (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| GYear simpleType; |
| return (xsd__gYear *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__gYearMonth*SoapDeSerializer:: |
| getAttributeAsGYearMonth (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| GYearMonth simpleType; |
| return (xsd__gYearMonth *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| xsd__duration *SoapDeSerializer:: |
| getAttributeAsDuration (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Duration simpleType; |
| return (xsd__duration *)getAttribute(pName, pNamespace, &simpleType); |
| } |
| |
| bool SoapDeSerializer:: |
| isNilValue() |
| { |
| logEntryEngine("SoapDeSerializer::isNilValue") |
| |
| bool isNillResult = false; |
| |
| // Go through the attributes looking for nil. We consider |
| // "true" or "1" to be equivalent. |
| for (int i = 0; m_pNode->m_pchAttributes[i]; i += 3) |
| { |
| string sLocalName = m_pNode->m_pchAttributes[i]; |
| string sValue = m_pNode->m_pchAttributes[i + 2]; |
| |
| if (strcmp("nil", sLocalName.c_str()) == 0 && |
| (strcmp("true", sValue.c_str()) == 0 || strcmp( "1", sValue.c_str()) == 0)) |
| { |
| isNillResult = true; |
| break; |
| } |
| } |
| |
| logExitWithBoolean(isNillResult) |
| |
| return isNillResult; |
| } |
| |
| void SoapDeSerializer:: |
| processFaultDetail(IAnySimpleType * pSimpleType, const AxisChar* elementValue) |
| { |
| logEntryEngine("SoapDeSerializer::processFaultDetail") |
| |
| bool isWhiteSpace = true; |
| |
| int len = elementValue ? strlen(elementValue) : 0; |
| |
| // See if detail element character data is whitespace |
| for (int i=0; i<len; ++i) |
| if (!(*elementValue == '\r' || *elementValue == '\n' |
| || *elementValue == '\t' || *elementValue == ' ')) |
| { |
| isWhiteSpace = false; |
| break; |
| } |
| |
| // If it is whitespace, peek to see if next element is the start of |
| // a new element, in which case the fault detail is complex. Peek() |
| // return null string if end-element tag is encountered. |
| char *workingString = (char *)elementValue; |
| if (isWhiteSpace) |
| { |
| // Since we will be doing a peek, elementValue will no longer |
| // be valid, so if we will deserialize null string if we need to. |
| workingString = ""; |
| |
| // if end tag not found, must be complex detail - fault handling code |
| // will know what to do when we return with no deserialization |
| const char* nextName = m_pParser->peek(); |
| if (nextName[0] != 0x00) |
| { |
| m_pNode = NULL; // node consumed |
| |
| logExit() |
| |
| return; |
| } |
| } |
| |
| // If here, detail is simple character data, deserialize simple string |
| pSimpleType->deserialize(workingString); |
| skipNode(); |
| |
| logExit() |
| |
| return; |
| } |
| |
| void SoapDeSerializer:: |
| getElement (const AxisChar * pName, const AxisChar * pNamespace, |
| IAnySimpleType * pSimpleType, |
| bool isArrayElement) |
| { |
| logEntryEngine("SoapDeSerializer::getElement") |
| |
| if (AXIS_SUCCESS != m_nStatus) |
| { |
| logExit() |
| |
| return; |
| } |
| |
| if ((RPC_ENCODED != m_nStyle) && (m_pNode == NULL)) |
| { |
| const char*name = peekNextElementName(); |
| if (0 != strcmp (pName, name)) |
| { |
| logExit() |
| |
| return; |
| } |
| } |
| |
| if (AXIS_FAIL == getNextNode(RPC_ENCODED != m_nStyle)) |
| { |
| logExit() |
| |
| return; |
| } |
| |
| bool bNillFound = false; |
| if (0 == strcmp (pName, m_pNode->m_pchNameOrValue)) |
| bNillFound = isNilValue(); |
| |
| if (RPC_ENCODED == m_nStyle) |
| { |
| // it is an error if type is different if the type exists |
| bool foundType; |
| if (!bNillFound && !isArrayElement |
| && (pSimpleType->getType() != getXSDType(m_pNode, foundType)) && foundType) |
| m_nStatus = AXIS_FAIL; |
| } |
| else if (0 != strcmp (pName, m_pNode->m_pchNameOrValue)) |
| { |
| logExit() |
| |
| return; |
| } |
| |
| if (AXIS_FAIL == m_nStatus) |
| { |
| logExit() |
| |
| return; |
| } |
| |
| // get next element, character mode |
| if (AXIS_FAIL == getNextNode(false, true)) |
| { |
| logExit() |
| |
| return; |
| } |
| |
| if (CHARACTER_ELEMENT == m_pNode->m_type) |
| { |
| const AxisChar* elementValue = m_pNode->m_pchNameOrValue; |
| |
| // Code for fault finding. As added protection against false findings, |
| // the namespace has been set to an invalid value of a single space character. |
| if (pNamespace != NULL && *pNamespace == ' ') |
| processFaultDetail(pSimpleType, elementValue); |
| else |
| { |
| pSimpleType->deserialize(elementValue); |
| skipNode(); |
| } |
| } |
| else if (END_ELEMENT == m_pNode->m_type) |
| { |
| // xsi:nil="true" OR empty tag case <tag/> |
| pSimpleType->deserialize(bNillFound ? NULL : ""); |
| m_pNode = NULL; |
| } |
| |
| logExit() |
| |
| return; |
| } |
| |
| /* |
| * Deserializing Elements as values directly. |
| */ |
| xsd__boolean *SoapDeSerializer:: |
| getElementAsBoolean (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Boolean simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getBoolean(); |
| } |
| |
| xsd__int *SoapDeSerializer:: |
| getElementAsInt (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Int simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getInt(); |
| } |
| |
| |
| xsd__unsignedInt *SoapDeSerializer:: |
| getElementAsUnsignedInt (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| UnsignedInt simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getUnsignedInt(); |
| } |
| |
| xsd__short *SoapDeSerializer:: |
| getElementAsShort (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Short simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getShort(); |
| } |
| |
| xsd__unsignedShort *SoapDeSerializer:: |
| getElementAsUnsignedShort (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| UnsignedShort simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getUnsignedShort(); |
| } |
| |
| xsd__byte *SoapDeSerializer:: |
| getElementAsByte (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Byte simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getByte(); |
| } |
| |
| xsd__unsignedByte *SoapDeSerializer:: |
| getElementAsUnsignedByte (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| UnsignedByte simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getUnsignedByte(); |
| } |
| |
| xsd__long *SoapDeSerializer:: |
| getElementAsLong (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Long simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getLong(); |
| } |
| |
| xsd__integer *SoapDeSerializer:: |
| getElementAsInteger (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Integer simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getInteger(); |
| } |
| |
| xsd__unsignedLong *SoapDeSerializer:: |
| getElementAsUnsignedLong (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| UnsignedLong simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getUnsignedLong(); |
| } |
| |
| xsd__float *SoapDeSerializer:: |
| getElementAsFloat (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Float simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getFloat(); |
| } |
| |
| xsd__double *SoapDeSerializer:: |
| getElementAsDouble (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Double simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getDouble(); |
| } |
| |
| xsd__decimal *SoapDeSerializer:: |
| getElementAsDecimal (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Decimal simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getDecimal(); |
| } |
| |
| xsd__string SoapDeSerializer:: |
| getElementAsString (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| String simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getString(); |
| } |
| |
| xsd__anyURI SoapDeSerializer:: |
| getElementAsAnyURI (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| AnyURI simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getAnyURI(); |
| } |
| |
| xsd__QName SoapDeSerializer:: |
| getElementAsQName (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| XSD_QName simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getQName(); |
| } |
| |
| xsd__hexBinary *SoapDeSerializer:: |
| getElementAsHexBinary (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| HexBinary simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getHexBinary(); |
| } |
| |
| xsd__base64Binary *SoapDeSerializer:: |
| getElementAsBase64Binary (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Base64Binary simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getBase64Binary(); |
| } |
| |
| xsd__dateTime *SoapDeSerializer:: |
| getElementAsDateTime (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| DateTime simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getDateTime(); |
| } |
| |
| xsd__date *SoapDeSerializer:: |
| getElementAsDate (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Date simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getDate(); |
| } |
| |
| xsd__time *SoapDeSerializer:: |
| getElementAsTime (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Time simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getTime(); |
| } |
| |
| xsd__duration *SoapDeSerializer:: |
| getElementAsDuration (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Duration simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getDuration(); |
| } |
| |
| xsd__gYearMonth *SoapDeSerializer:: |
| getElementAsGYearMonth (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| GYearMonth simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getGYearMonth(); |
| } |
| |
| xsd__gYear *SoapDeSerializer:: |
| getElementAsGYear (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| GYear simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getGYear(); |
| } |
| |
| xsd__gMonthDay *SoapDeSerializer:: |
| getElementAsGMonthDay (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| GMonthDay simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getGMonthDay(); |
| } |
| |
| xsd__gDay *SoapDeSerializer:: |
| getElementAsGDay (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| GDay simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getGDay(); |
| } |
| |
| xsd__gMonth *SoapDeSerializer:: |
| getElementAsGMonth (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| GMonth simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getGMonth(); |
| } |
| |
| xsd__nonPositiveInteger *SoapDeSerializer:: |
| getElementAsNonPositiveInteger (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NonPositiveInteger simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getNonPositiveInteger(); |
| } |
| |
| xsd__negativeInteger *SoapDeSerializer:: |
| getElementAsNegativeInteger (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NegativeInteger simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getNegativeInteger(); |
| } |
| |
| xsd__nonNegativeInteger *SoapDeSerializer:: |
| getElementAsNonNegativeInteger (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NonNegativeInteger simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getNonNegativeInteger(); |
| } |
| |
| xsd__positiveInteger *SoapDeSerializer:: |
| getElementAsPositiveInteger (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| PositiveInteger simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getPositiveInteger(); |
| } |
| |
| xsd__normalizedString SoapDeSerializer:: |
| getElementAsNormalizedString (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NormalizedString simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getNormalizedString(); |
| } |
| |
| xsd__token SoapDeSerializer:: |
| getElementAsToken (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Token simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getToken(); |
| } |
| |
| xsd__language SoapDeSerializer:: |
| getElementAsLanguage (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Language simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getLanguage(); |
| } |
| |
| xsd__Name SoapDeSerializer:: |
| getElementAsName (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| Name simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getName(); |
| } |
| |
| xsd__NCName SoapDeSerializer:: |
| getElementAsNCName (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NCName simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getNCName(); |
| } |
| |
| xsd__ID SoapDeSerializer:: |
| getElementAsID (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| ID simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getID(); |
| } |
| |
| xsd__IDREF SoapDeSerializer:: |
| getElementAsIDREF (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| IDREF simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getIDREF(); |
| } |
| |
| xsd__IDREFS SoapDeSerializer:: |
| getElementAsIDREFS (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| IDREFS simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getIDREFS(); |
| } |
| |
| xsd__ENTITY SoapDeSerializer:: |
| getElementAsENTITY (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| ENTITY simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getENTITY(); |
| } |
| |
| xsd__ENTITIES SoapDeSerializer:: |
| getElementAsENTITIES (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| ENTITIES simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getENTITIES(); |
| } |
| |
| xsd__NMTOKEN SoapDeSerializer:: |
| getElementAsNMTOKEN (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NMTOKEN simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getNMTOKEN(); |
| } |
| |
| xsd__NMTOKENS SoapDeSerializer:: |
| getElementAsNMTOKENS (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NMTOKENS simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getNMTOKENS(); |
| } |
| |
| xsd__NOTATION SoapDeSerializer:: |
| getElementAsNOTATION (const AxisChar * pName, const AxisChar * pNamespace) |
| { |
| NOTATION simpleType; |
| getElement(pName, pNamespace, &simpleType); |
| return simpleType.getNOTATION(); |
| } |
| |
| xsd__anyType SoapDeSerializer:: |
| getElementAsAnyType(const AxisChar* pName, const AxisChar* pNamespace) |
| { |
| xsd__anyType ret = NULL; |
| |
| if (AXIS_SUCCESS != m_nStatus) |
| return ret; |
| |
| AnyType *any = getAnyObject(pName, pNamespace); |
| if (NULL != any) |
| { |
| if (any->_size != 0) |
| { |
| ret = any->_array[0]; |
| any->_array[0] = NULL; |
| delete [] any->_array; |
| } |
| delete any; |
| } |
| |
| return ret; |
| } |
| |
| xsd__string SoapDeSerializer:: |
| getFaultAsXMLString() |
| { |
| if (AXIS_SUCCESS != m_nStatus || RPC_ENCODED == m_nStyle) |
| return NULL; |
| |
| AnyType *any = getAnyObject(); |
| if (any == NULL) |
| return (xsd__string)NULL; |
| |
| int len = 1, i; // Add 1 for the null terminator |
| for (i=0; i<any->_size; i++) |
| if (any->_array[i]) |
| len += strlen(any->_array[i]); |
| |
| xsd__string ret = new char[len]; |
| memset(ret,0,len); |
| for (i=0; i<any->_size; i++) |
| if (any->_array[i]) |
| { |
| strcat(ret,any->_array[i]); |
| delete [] any->_array[i]; |
| } |
| delete [] any->_array; |
| delete any; |
| return ret; |
| } |
| |
| /* |
| * This method checks the attribute list of pElement node for the xsi:type |
| * attribute. If it is found then finds what the type is. Otherwise returns |
| * XSD_UNKNOWN. |
| */ |
| XSDTYPE SoapDeSerializer:: |
| getXSDType (const AnyElement * pElement, bool & foundType) |
| { |
| foundType = false; |
| |
| XSDTYPE type = XSD_UNKNOWN; |
| |
| /* first check whether this is a start element node */ |
| if (START_ELEMENT == pElement->m_type) |
| { |
| for (int i = 0; pElement->m_pchAttributes[i]; i += 3) |
| { |
| if (URI_XSI == URIMapping::getURI (pElement->m_pchAttributes[i + 1])) |
| { |
| ::QName qn; |
| |
| qn.splitQNameString (pElement->m_pchAttributes[i + 2], ':'); |
| const char * pNS = m_pParser->getNS4Prefix (qn.uri); |
| if (pNS) |
| { |
| if (URI_XSD == URIMapping::getURI (pNS) || URI_ENC == URIMapping::getURI (pNS)) |
| type = TypeMapping::map (qn.localname); |
| } |
| qn.mergeQNameString (':'); |
| foundType = true; |
| break; |
| } |
| } |
| } |
| |
| return type; |
| } |
| |
| /* |
| * Used by the Axis Engine to get any left header blocks in the deserializer |
| * even after the completion of message path. Then those headers will be added |
| * to the serializer because they are probably headers targetted to nex soap |
| * processors. |
| */ |
| HeaderBlock * SoapDeSerializer:: |
| getHeaderBlock () |
| { |
| logEntryEngine("SoapDeSerializer::getHeaderBlock") |
| |
| HeaderBlock *returnValue = NULL; |
| |
| if (m_pHeader) |
| returnValue = (HeaderBlock *) m_pHeader->getHeaderBlock (true); |
| |
| logExitWithPointer(returnValue) |
| |
| return returnValue; |
| } |
| |
| /* |
| * Used probably by a handler to add a header block to the Deserializer. |
| * Probably to be used by a subsequent handler in the request message path |
| */ |
| int AXISCALL SoapDeSerializer:: |
| addHeaderBlock (IHeaderBlock * pBlk) |
| { |
| logEntryEngine("SoapDeSerializer::addHeaderBlock") |
| |
| if (!m_pHeader) |
| m_pHeader = new SoapHeader (); |
| m_pHeader->addHeaderBlock ((HeaderBlock *) pBlk); |
| |
| logExitWithReturnCode(AXIS_SUCCESS) |
| |
| return AXIS_SUCCESS; |
| } |
| |
| xsd__hexBinary SoapDeSerializer:: |
| getBodyAsHexBinary () |
| { |
| /* TODO */ |
| getNextNode(); |
| |
| // skip the BODY element declaration |
| if ((START_ELEMENT == m_pNode->m_type) |
| && (0 == strcmp (m_pNode->m_pchNameOrValue, |
| SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY]))) |
| getNextNode(); |
| |
| string bodyContent = ""; |
| |
| if (m_pNode) |
| { |
| while (!((END_ELEMENT == m_pNode->m_type) && |
| (0 == strcmp (m_pNode->m_pchNameOrValue, |
| SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY])))) |
| bodyContent += AnyElemntUtils::toString(m_pNode); |
| } |
| |
| xsd__hexBinary value; |
| xsd__int size = bodyContent.length() / 2; |
| xsd__unsignedByte * pTemp = new xsd__unsignedByte[size + 1]; |
| Hex_Decode (pTemp, bodyContent.c_str()); |
| pTemp[size] = 0; // Null terminate so it could be used as a string |
| value.set(pTemp, size); |
| delete [] pTemp; |
| |
| return value; |
| } |
| |
| xsd__base64Binary SoapDeSerializer:: |
| getBodyAsBase64Binary () |
| { |
| /* TODO */ |
| getNextNode(); |
| |
| // skip the BODY element declaration |
| if ((START_ELEMENT == m_pNode->m_type) |
| && (0 == strcmp (m_pNode->m_pchNameOrValue, |
| SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY]))) |
| getNextNode(); |
| |
| string bodyContent = ""; |
| |
| if (m_pNode) |
| { |
| while (!((END_ELEMENT == m_pNode->m_type) && |
| (0 == strcmp (m_pNode->m_pchNameOrValue, |
| SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY])))) |
| bodyContent += AnyElemntUtils::toString(m_pNode); |
| } |
| |
| xsd__base64Binary value; |
| xsd__int size = apr_base64_decode_len (bodyContent.c_str()); |
| xsd__unsignedByte * pTemp = new xsd__unsignedByte[size + 1]; |
| size = apr_base64_decode_binary (pTemp, bodyContent.c_str()); |
| pTemp[size] = 0; // Null terminate so it could used as a string |
| value.set(pTemp, size); |
| delete [] pTemp; |
| return value; |
| } |
| |
| AxisChar *SoapDeSerializer:: |
| getBodyAsChar () |
| { |
| if (AXIS_FAIL == getNextNode()) |
| return NULL; |
| |
| // skip the BODY element declaration |
| if ((START_ELEMENT == m_pNode->m_type) |
| && (0 == strcmp (m_pNode->m_pchNameOrValue, |
| SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY]))) |
| { |
| if (AXIS_FAIL == getNextNode()) |
| return NULL; |
| } |
| |
| pBodyContent = new AxisChar[1000]; |
| pBodyContent[0] = '\0'; |
| |
| while (!((END_ELEMENT == m_pNode->m_type) && |
| (0 == strcmp (m_pNode->m_pchNameOrValue, |
| SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY])))) |
| strcat (pBodyContent, (AnyElemntUtils::toString (m_pNode)).c_str ()); |
| |
| return pBodyContent; |
| } |
| |
| int SoapDeSerializer:: |
| setNewSoapBody (AxisChar * pNewSoapBody) |
| { |
| DeSerializerMemBufInputStream stream (pNewSoapBody); |
| return m_pParser->setInputStream (&stream); |
| } |
| |
| bool SoapDeSerializer:: |
| isAnyMustUnderstandHeadersLeft () |
| { |
| /* TODO */ |
| return false; |
| } |
| |
| int SoapDeSerializer:: |
| flushInputStream () |
| { |
| logEntryEngine("SoapDeSerializer::flushInputStream") |
| |
| int iStatus = AXIS_FAIL; |
| |
| if (m_pInputStream) |
| { |
| int nChars = 100; |
| char pBuffer[100]; |
| |
| while (TRANSPORT_IN_PROGRESS == m_pInputStream->getBytes (pBuffer, &nChars)); |
| iStatus = AXIS_SUCCESS; |
| } |
| |
| logExitWithReturnCode(iStatus) |
| |
| return iStatus; |
| } |
| |
| AnyType * SoapDeSerializer:: |
| getAnyObject () |
| { |
| return getAnyObject(NULL, NULL); |
| } |
| |
| |
| AnyType * SoapDeSerializer:: |
| getAnyObject (const AxisChar* pName, const AxisChar* pNamespace) |
| { |
| logEntryEngine("SoapDeSerializer::getAnyObject") |
| |
| // If pname is passed, then we need to move the parser pointer for RPC. |
| if ((pName != NULL && RPC_ENCODED == m_nStyle) || (m_pNode == NULL)) |
| { |
| getNextNode(false, false); |
| if (m_pNode == NULL) |
| { |
| logExitWithPointer(NULL) |
| |
| return (AnyType *)NULL; |
| } |
| } |
| |
| int tagCount = 0; |
| int lstSize = 0; |
| bool bContinue = true; |
| bool bElementFound = false; |
| AxisString xmlStr = ""; |
| AxisString nsDecls = ""; |
| |
| if (m_pNode) |
| { |
| // If this is an end-element node, simply return, there is no element to parse. Note |
| // we do not consume the node. |
| if (END_ELEMENT == m_pNode->m_type) |
| { |
| logExitWithPointer(NULL) |
| |
| return (AnyType *)NULL; |
| } |
| |
| // There may have been namespace declarations that were previously processed....get it from |
| // the node and reset the node variable. |
| nsDecls = ((AnyElement*)m_pNode)->m_strXMLNSDeclsForAnyObject.c_str(); |
| ((AnyElement*)m_pNode)->m_strXMLNSDeclsForAnyObject.clear(); |
| } |
| |
| stack <AxisString> nsPrefixStack; |
| |
| AxisString inValue = ""; |
| AxisString outValue = ""; |
| |
| // Loop and get an XML element node and its sub-elements. |
| // Note the a schema element will not be counted as an element but will be included as part |
| // of the data returned. |
| while (m_pNode && ((END_ELEMENT != m_pNode->m_type) || (tagCount > 0) || bContinue)) |
| { |
| // Root element needs to be what is expected for doc/literal. |
| if (pName != NULL |
| && RPC_ENCODED != m_nStyle |
| && START_ELEMENT == m_pNode->m_type) |
| { |
| if (0 != strcmp (pName, m_pNode->m_pchNameOrValue)) |
| { |
| // Need to save namespace string just in case it is needed later. |
| ((AnyElement*)m_pNode)->m_strXMLNSDeclsForAnyObject = nsDecls.c_str(); |
| |
| logExitWithPointer(NULL) |
| |
| return (AnyType *)NULL; |
| } |
| |
| // We do not need to do the check anymore |
| pName = NULL; |
| } |
| |
| // Continue if processing start prefix as we haven't yet found the true start of the tag |
| bContinue = false; |
| if (START_PREFIX == m_pNode->m_type) |
| bContinue = true; |
| |
| // if empty element we need to do a parser get to consume the end-element node. |
| // Note that start/end elements are not included in tagCount processing since the node |
| // is processed completely on first pass since it contains no sub-elements. |
| if (START_END_ELEMENT == m_pNode->m_type2) |
| { |
| if (END_ELEMENT == m_pNode->m_type) |
| { |
| m_pNode = m_pParser->anyNext (); |
| continue; |
| } |
| } |
| else |
| { |
| // Increment counter if entering new tag, Decrement counter if exiting tag |
| if (START_ELEMENT == m_pNode->m_type) |
| tagCount++; |
| else if (END_ELEMENT == m_pNode->m_type) |
| tagCount--; |
| } |
| |
| if (START_PREFIX == m_pNode->m_type) |
| { |
| nsDecls += " xmlns"; |
| if (m_pNode->m_pchNameOrValue && (*(m_pNode->m_pchNameOrValue) != 0x00)) |
| { |
| nsDecls += ":"; |
| nsDecls += m_pNode->m_pchNameOrValue; |
| } |
| nsDecls += "="; |
| nsDecls += PLATFORM_DOUBLE_QUOTE_S; |
| nsDecls += m_pNode->m_pchNamespace; |
| nsDecls += PLATFORM_DOUBLE_QUOTE_S; |
| } |
| else if (CHARACTER_ELEMENT != m_pNode->m_type) |
| { |
| bElementFound = true; |
| serializeTag (xmlStr, m_pNode, nsDecls, nsPrefixStack); |
| nsDecls = ""; |
| } |
| else |
| { |
| inValue = m_pNode->m_pchNameOrValue; |
| IAnySimpleType::replaceReservedCharacters(inValue, outValue); |
| xmlStr += outValue; |
| } |
| |
| // If element obtained...break out. Otherwise, get next node. |
| if (bElementFound && !bContinue && tagCount == 0 && (!xmlStr.empty ())) |
| { |
| // If the anyType element is empty element, we need to consume END_ELEMENT. |
| if (START_END_ELEMENT == m_pNode->m_type2 && START_ELEMENT == m_pNode->m_type) |
| m_pNode = m_pParser->anyNext (); |
| |
| m_pNode = NULL; |
| } |
| else |
| m_pNode = m_pParser->anyNext (); |
| } |
| |
| // Generate the axis type where we store anyType XML objects. |
| AnyType *pAny = new AnyType (); |
| pAny->_array = 0; |
| pAny->_size = 0; |
| |
| if (!xmlStr.empty ()) |
| { |
| pAny->_array = new char *[1]; |
| |
| const char *s = xmlStr.c_str (); |
| logDebugArg1("\nAnyType array element\n%s\n", s) |
| |
| pAny->_array[0] = new char[xmlStr.size() + 1]; |
| strcpy (pAny->_array[0], s); |
| |
| pAny->_size = 1; |
| } |
| |
| logExitWithPointer(pAny) |
| |
| return pAny; |
| } |
| |
| void SoapDeSerializer:: |
| serializeTag (AxisString & xmlStr, |
| const AnyElement * node, |
| AxisString & nsDecls, |
| std::stack<AxisString> & nsPrefixStack) |
| { |
| const XML_Ch *pchPrefix = 0; |
| |
| AxisString nsPrefix = ""; |
| |
| if (START_ELEMENT == node->m_type) |
| { |
| xmlStr += "<"; |
| |
| if (node->m_pchNamespace && (*(node->m_pchNamespace) != 0x00)) |
| { |
| pchPrefix = m_pParser->getPrefix4NS (node->m_pchNamespace); |
| |
| if (pchPrefix && *pchPrefix != 0x00) |
| { |
| nsPrefix = pchPrefix; |
| |
| xmlStr += pchPrefix; |
| xmlStr += ":"; |
| } |
| } |
| |
| // We do not need to save namespace prefix if start/end element. |
| if (START_END_ELEMENT != node->m_type2) |
| nsPrefixStack.push(nsPrefix); |
| |
| xmlStr += node->m_pchNameOrValue; |
| |
| if (!nsDecls.empty ()) |
| xmlStr += nsDecls.c_str (); |
| |
| if (node->m_pchAttributes) |
| { |
| int j; |
| |
| /* structure of the m_pchAttributes[] array is, |
| * sequence of (local_name, namespace_uri, value) |
| */ |
| |
| for (j = 0; j < 300; j += 3) /* MAX_NO_OF_ATTRIBUTES = 100 */ |
| { |
| if (node->m_pchAttributes[j]) |
| { |
| if (node->m_pchAttributes[j + 1]) |
| pchPrefix = m_pParser->getPrefix4NS (node->m_pchAttributes[j + 1]); |
| else |
| pchPrefix = NULL; |
| |
| xmlStr += " "; |
| |
| if (pchPrefix && (*pchPrefix != 0x00)) |
| { |
| xmlStr += pchPrefix; |
| xmlStr += ":"; |
| } |
| |
| xmlStr += node->m_pchAttributes[j]; |
| xmlStr += "="; |
| xmlStr += PLATFORM_DOUBLE_QUOTE_S; |
| xmlStr += node->m_pchAttributes[j + 2]; |
| xmlStr += PLATFORM_DOUBLE_QUOTE_S; |
| } |
| else |
| break; |
| } |
| } |
| |
| if (START_END_ELEMENT == node->m_type2) |
| xmlStr += " />"; |
| else |
| xmlStr += ">"; |
| } |
| else if (END_ELEMENT == node->m_type) |
| { |
| AxisString prefixTag = ""; |
| |
| if (!nsPrefixStack.empty()) |
| { |
| nsPrefix = nsPrefixStack.top(); |
| nsPrefixStack.pop(); |
| |
| if (!nsPrefix.empty()) |
| { |
| prefixTag += nsPrefix; |
| prefixTag += ":"; |
| } |
| } |
| |
| xmlStr += "</"; |
| xmlStr += prefixTag; |
| xmlStr += node->m_pchNameOrValue; |
| if (START_END_ELEMENT == node->m_type2) |
| xmlStr += " />"; |
| else |
| xmlStr += ">"; |
| } |
| } |
| |
| void SoapDeSerializer:: |
| getChardataAs (void **pValue, XSDTYPE type) |
| { |
| logEntryEngine("SoapDeSerializer::getChardataAs") |
| |
| if (pValue && AXIS_FAIL != getNextNode(true, true)) |
| { |
| *pValue = NULL; |
| if (CHARACTER_ELEMENT == m_pNode->m_type) |
| { |
| IAnySimpleType* pSimpleType = AxisUtils::createSimpleTypeObject(type); |
| pSimpleType->deserialize(m_pNode->m_pchNameOrValue); |
| *pValue = pSimpleType->getValue(); |
| delete pSimpleType; |
| } |
| else if (END_ELEMENT == m_pNode->m_type) |
| { |
| m_doNotSkip = true; |
| m_pNode = NULL; |
| } |
| } |
| |
| logExit() |
| } |
| |
| /* This function is never called. */ |
| AXIS_TRANSPORT_STATUS SoapDeSerializer:: |
| DeSerializerMemBufInputStream:: |
| sendBytes (const char *pcSendBuffer, const void *pBufferid) |
| { |
| return TRANSPORT_FINISHED; |
| } |
| |
| AXIS_TRANSPORT_STATUS SoapDeSerializer:: |
| DeSerializerMemBufInputStream:: |
| getBytes (char *pcBuffer, int *piRetSize) |
| { |
| logEntryEngine("SoapDeSerializer::DeSerializerMemBufInputStream::getBytes") |
| |
| if (!m_pcDeSeriaMemBuffer) |
| { |
| logExitWithMessage("Returned return code of TRANSPORT_FAILED") |
| |
| return TRANSPORT_FAILED; |
| } |
| |
| int nBufLen = strlen (m_pcDeSeriaMemBuffer); |
| if (0 == nBufLen) |
| { |
| logExitWithMessage("Returned return code of TRANSPORT_FINISHED") |
| |
| return TRANSPORT_FINISHED; |
| } |
| |
| nBufLen = ((*piRetSize - 1) < nBufLen) ? (*piRetSize - 1) : nBufLen; |
| strncpy (pcBuffer, m_pcDeSeriaMemBuffer, nBufLen); |
| pcBuffer[nBufLen] = 0; |
| m_pcDeSeriaMemBuffer += nBufLen; |
| |
| logExitWithMessage("Returned return code of TRANSPORT_IN_PROGRESS") |
| |
| return TRANSPORT_IN_PROGRESS; |
| } |
| |
| ISoapAttachment* SoapDeSerializer:: |
| getAttachment(const char* pcAttachmentid) |
| { |
| return m_pInputStream->getAttachment(pcAttachmentid); |
| } |
| |
| ISoapAttachment** SoapDeSerializer:: |
| getAllAttachments(int *pAttchArraySize) |
| { |
| return m_pInputStream->getAllAttachments(pAttchArraySize); |
| } |
| |
| const char* SoapDeSerializer:: |
| getMethodNameToInvoke() |
| { |
| return m_strMethodNameToInvoke.c_str(); |
| } |
| |
| void SoapDeSerializer:: |
| setMethodNameToInvoke(const char* methodName) |
| { |
| logEntryEngine("SoapDeSerializer::setMethodNameToInvoke") |
| |
| m_strMethodNameToInvoke = methodName; |
| |
| logExit() |
| } |
| |
| AXIS_CPP_NAMESPACE_END |