/*
 *   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.
 */

/*
 *
 * @author Susantha Kumara (skumara@virtusa.com)
 * @author Damitha Kumarage (damitha@opensource.lk, damitha@jkcsworld.com)
 * @author Roshan Weerasuriya (roshan@opensource.lk, roshanw@jkcsworld.com)
 * @author Samisa Abeysinghe (sabeysinghe@virtusa.com)
 *
 */

// !!! 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();
            }
            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();
    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 = m_pParser->anyNext();
        if (m_pNode == NULL)
        {
            logExitWithPointer(NULL)

            return (AnyType *)NULL;
        }
    }

    // Parser will throw an exception on a parser exception, that is ok...
    if (!m_pNode)
    {
        m_pNode = m_pParser->anyNext();

        if (m_pNode == NULL)
        {
            logExitWithPointer(NULL)

            return (AnyType *)NULL;
        }
    }

    int tagCount = 0;
    int lstSize = 0;
    bool bContinue = true;
    bool bElementFound = false;

    AxisString xmlStr = "";

    // There may have been namespace declarations that were previously processed....get it from
    // the node and reset the node variable.
    AxisString nsDecls = "";
    if (m_pNode)
    {
        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
