⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tmapr.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
Cleanup:
    ASSERT(SUCCEEDED(hr));
    
    return (hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////




/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  function: HRESULT CCDATAMapper::write(ISoapSerializer* pSoapSerializer, BSTR bstrEncoding, enEncodingStyle enStyle, long lFlags,  VARIANT * pvar)
//
//  parameters:
//
//  description:
//      mapping a string into a soap message
//
//  returns: 
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CCDATAMapper::write(ISoapSerializer* pSoapSerializer, BSTR bstrEncoding, enEncodingStyle enStyle, long lFlags,  VARIANT * pvar)
{
    HRESULT hr=S_OK;
    CVariant varChanged;

    CHK (ConvertData(*pvar, (VARIANT *)&varChanged, VT_BSTR));

    CHK (pSoapSerializer->writeXML((BSTR)g_pwstrOpenCDATA));
    CHK (pSoapSerializer->writeXML(V_BSTR(&varChanged)));    
    CHK (pSoapSerializer->writeXML((BSTR)g_pwstrCloseCDATA));
Cleanup:
    ASSERT(SUCCEEDED(hr));
    
    return (hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////





/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  function: WCHAR * CSafearrayMapper::skipNoise(WCHAR * pc)
//
//  parameters:
//
//  description:
//      simple function to skip over blank and tab character
//
//  returns: 
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
WCHAR * CSafearrayMapper::skipNoise(WCHAR * pc)
{
    while (pc  && *pc)
    {
        if ( (*pc == '\t') || (*pc == ' '))
            pc++;
        else
            break;
    }
    return (pc);
}



/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  function: HRESULT CSafearrayMapper::ParseArrayDimensions(WCHAR * pcDefDim, long * pDimCount, long ** ppDim)
//
//  parameters:
//
//  description:
//      function parses string of the form "#,#,#,#]"
//      values for # are returned in an array of long (ppDim), count of # in pDimCount
//      any error case returns non-S_OK HRESULT
//
//  returns: 
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////

HRESULT CSafearrayMapper::ParseArrayDimensions(WCHAR * pcDefDim, long * pDimCount, long ** ppDim)
{
    HRESULT hr=S_OK;
    CAutoP<long>  pDims(NULL);  // a temporary array to keep track of things
    long  lDim = 0; // use this to count
    
    ASSERT (pcDefDim);
    ASSERT (pDimCount);
    ASSERT (ppDim);

    CHK_BOOL(pcDefDim && *pcDefDim, E_INVALIDARG);
    
    while (1)
    {
        {
            CAutoP<long> pl(NULL);  // need this for temporary copy area

            // we are ready to read a new dimenion, create an array
            // with sufficient room for it
            pl = (long*) new BYTE[sizeof(long) * (lDim+1)];
            CHK_BOOL(pl, E_OUTOFMEMORY);

            // move the current contents into this one if necessary
            if (pDims)
                memcpy(pl, pDims, sizeof(long) * lDim);

            // and take ownership of the new one
            pDims.Clear();
            pDims = pl.PvReturn();
        }

        long ltemp;
        WCHAR *pcTemp;

        pcDefDim = skipNoise(pcDefDim);
        CHK_BOOL(pcDefDim && *pcDefDim, E_INVALIDARG);

        if ( (*pcDefDim == ',') || (*pcDefDim == ']') )
        {
            // this is the case where we have no number, this dimension is going to be unbounded
            ltemp = -1;
            pcTemp = pcDefDim;
        }
        else
        {
            // there better be a number around ... let's figure it out
            ltemp = wcstol(pcDefDim, &pcTemp, 10);
        }
        
        CHK_BOOL((ltemp != LONG_MAX) && (ltemp != LONG_MIN) && (pcTemp!=NULL) && (*pcTemp != 0), E_INVALIDARG);
        pcTemp = skipNoise(pcTemp);

        // throw the value into the array
        pDims[lDim] = ltemp;
        
        if (*pcTemp == ',')
        {
            // we are going to see another dimension ...
            lDim ++;

            pcDefDim = pcTemp+1;
            pcDefDim = skipNoise(pcDefDim);

            CHK_BOOL(pcDefDim && *pcDefDim, E_INVALIDARG);
            // at this point we are ready to keep reading
        }
        else
        {
            if (*pcTemp == ']')
            {
                // in this case we are done
                break;
            }   
            // no clue what got us here, we can handle this - kind of
            CHK (E_INVALIDARG);
        }
    }

    // take ownership of what we returned
    *ppDim = pDims.PvReturn();

    // and remember the number of dimensions
    *pDimCount = lDim +1;

Cleanup:
    ASSERT(hr == S_OK);
    return hr;
}



/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  function: HRESULT CSafearrayMapper::init(ISoapTypeMapperFactory *ptypeFactory, IXMLDOMNode * pSchema, enXSDType xsdType)
//
//  parameters:
//
//  description:
//      set the constrains for this guy
//  returns: 
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CSafearrayMapper::init(ISoapTypeMapperFactory *ptypeFactory, IXMLDOMNode * pSchema, enXSDType xsdType)
{
    HRESULT hr = S_OK;
    CAutoRefc<IXMLDOMNode> pArraySchema(NULL);
    XPathState  xp;

    // we should only initialize once
    ASSERT (m_ptypeFactory == NULL);
    
    // set the object into an empty state
    m_lDimensions = -1;
    m_pabound.Clear();
    m_bstrElementName.Clear();
    m_bstrTypeURI.Clear();
    m_bstrTypeName.Clear();

    m_LvtType  = -1;

    m_soaparraydef = FALSE;

    m_enRevision = enSchemaInvalid; 

    // check for needed parameter
    CHK_BOOL(ptypeFactory, E_INVALIDARG);
   
    // start initializing
    CHK(CTypeMapper::init(ptypeFactory, pSchema, xsdType));

    // hold on to the typefactory, we will need this later
    assign(&m_ptypeFactory, ptypeFactory);

    if (pSchema == NULL)
    {
        // in this case we are assuming we are getting called 
        // from inside the AnyType-Mapper and will do standard 
        // variant type discovery later
        m_enXSDType = enXSDanyType;
        return S_OK;
    }


    // from here on we need a schema
    CHK_BOOL(pSchema, E_INVALIDARG);

    CHK(_XSDFindRevision(pSchema, &m_enRevision));
    
    CHK (xp.init(pSchema));
    // set up our prefixes we can use in xpath
    CHK (xp.addNamespace(g_pwstrXpathEnc)); //give us enc: for encoding
    CHK (xp.addNamespace(g_pwstrXpathDef)); //give us def: wsdl
    
    // we need a schema namespace to look for - actually, we do not care if it is a 
    // 1999 or 2000
    {
        CAutoFormat autoFormat;
        CHK(autoFormat.sprintf(L"xmlns:schema='%s'", _XSDSchemaNS(m_enRevision)));        
        CHK (xp.addNamespace(&autoFormat));         //gives us schema: 
    }
    showNode(pSchema);

    // again 5 scenarios we want to check for:
    // (1) <element><complexType><sequence><element>
    // (2) <complexType><sequence><element>
    // (3) <element><complexType><element>
    // (4) <complexType><complexContent><restriction><attribute>
    // (5) <complexType><complexContent><restriction><sequence><attribute>

    // lets try to figure out if we are in 1,2,3 or 5
    pSchema->selectSingleNode(L".//schema:complexType/schema:sequence/schema:element", &pArraySchema);

    if (!pArraySchema)
        pSchema->selectSingleNode(L".//schema:sequence/schema:element", &pArraySchema);

    if (!pArraySchema)
        pSchema->selectSingleNode(L".//schema:complexType/schema:element", &pArraySchema);

    if (!pArraySchema)
        pSchema->selectSingleNode(L".//schema:complexContent/schema:restriction/schema:sequence/schema:attribute", &pArraySchema);

    if (pArraySchema)
    {
        CAutoBSTR bstrType;

        // we are on an element node now in pArraySchema...get the information we need ...
        CHK( _XPATHFindAttribute(pArraySchema, g_pwstrName, &m_bstrElementName));

        CHK ( _XPATHFindAttribute(pArraySchema, g_pwstrXSDtype, &bstrType) );
        CHK_BOOL(bstrType, E_FAIL);
        {
            WCHAR achPrefix[_MAX_ATTRIBUTE_LEN];
            CAutoBSTR bstrtemp;

            CHK(_WSDLUtilSplitQName(bstrType, achPrefix, &m_bstrTypeName));
            CHK (_XSDFindURIForPrefix(pArraySchema, achPrefix, &m_bstrTypeURI));      

            //this thing will allways have one dimension
            m_pabound = (SAFEARRAYBOUND*)new BYTE[sizeof(SAFEARRAYBOUND)];
            CHK_BOOL(m_pabound, E_OUTOFMEMORY);

            m_pabound[0].cElements = -1;
            m_pabound[0].lLbound = 0;
            m_lDimensions = 1;
            
            //find the maxOccurs values
            CHK ( _XPATHFindAttribute(pArraySchema, g_pwstrMaxOccurs, &bstrtemp) );
            if (bstrtemp)
            {
                long ltemp = -1;
                if ((wcsicmp(bstrtemp, g_pwstrUnbounded)!= 0)&&(wcsicmp(bstrtemp, g_pwstrStar)!= 0))
                {  //  maxOccurs != "unbounded" and  maxOccurs != "*"
                    WCHAR *ptemp = NULL;
                    
                    // figure out maxoccurs:
                    ltemp = wcstol(bstrtemp, &ptemp, 10);
                    CHK_BOOL((ltemp != LONG_MAX) && (ltemp != LONG_MIN) && (ptemp!=NULL) && (*ptemp == 0) && (ltemp>=0), E_INVALIDARG);
                }
                m_pabound[0].cElements = ltemp;
            }
            m_soaparraydef = FALSE;            
            TRACE ( ("cElemts: %d lLBound: %d type: %S %S\n", m_pabound[0].cElements, m_pabound[0].lLbound, m_bstrTypeName, m_bstrTypeURI) );
        }
    }
    else
    {
        CAutoBSTR bstrType;
        
        // we better be in scenario 4 ....
        pSchema->selectSingleNode(L".//schema:complexContent/schema:restriction/schema:attribute", &pArraySchema);

        CHK_BOOL(pArraySchema, E_FAIL);     // in case we could not recognize anything

        showNode(pArraySchema);
        
        // assume we do soapencoding here always
        CHK ( _XPATHFindAttribute(pArraySchema, _T("def:arrayType"), &bstrType) );
        CHK_BOOL(bstrType, E_FAIL);
        
        // check if it is an arraytype
        WCHAR * pDimension = wcsstr(bstrType, L"[");
        CHK_BOOL(pDimension, E_FAIL);

        *pDimension = 0;
        {
            WCHAR achPrefix[_MAX_ATTRIBUTE_LEN];
            CAutoBSTR bstrtempType;
            CAutoP<long> pDim(NULL);
            
            CHK(_WSDLUtilSplitQName(bstrType, achPrefix, &m_bstrTypeName));
            CHK (_XSDFindURIForPrefix(pArraySchema, achPrefix, &m_bstrTypeURI));      

            // now figure out the dimension thing
            pDimension++;   // points to the beginning of the dimension string
            CHK_BOOL(*pDimension, E_INVALIDARG);        // certainly do not expect the end of string here

            CHK(ParseArrayDimensions(pDimension, &m_lDimensions, &pDim));

            m_pabound = (SAFEARRAYBOUND*)new BYTE[m_lDimensions * sizeof(SAFEARRAYBOUND)];
            CHK_BOOL(m_pabound, E_OUTOFMEMORY);

            // now we have to verify the information and move it into the
            // member structures
            for (long lc = 0; lc < m_lDimensions; lc ++)
            {
//                if ( (pDim[lc] == -1) && (lc != 0) )
//                {
//                    CHK (DISP_E_BADINDEX);
//                }
                m_pabound[lc].cElements = pDim[lc];
                m_pabound[lc].lLbound = 0;
                TRACE ( ("dim: %d cElemts: %d lLBound: %d type: %S %S\n", lc,
                                            m_pabound[m_lDimensions-1].cElements, m_pabound[m_lDimensions-1].lLbound, m_bstrTypeName, m_bstrTypeURI) );
            }
            
        }
        m_soaparraydef = TRUE;
    }

Cleanup:
    ASSERT(SUCCEEDED(hr));

    return (hr);
}



/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  function: HRESULT CSafearrayMapper::read(IXMLDOMNode *_pNodeOfMapper, BSTR bstrEncoding, enEncodingStyle enStyle, long lFlags,  VARIANT * pvar)
//
//  parameters:
//
//  description:
//      reading a string out of a soap message
//
//  returns: 
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CSafearrayMapper::read(IXMLDOMNode *_pNodeOfMapper, BSTR bstrEncoding, enEncodingStyle enStyle, long lFlags,  VARIANT * pvar)
{
    HRESULT hr = E_FAIL;
    CAutoRefc<IXMLDOMNode> pTemp(NULL);
    CAutoRefc<IXMLDOMNode> pChild(NULL);
    CAutoRefc<ISoapTypeMapper> ptm(NULL);
    CAutoRefc<IXMLDOMNode> pNodeOfMapper(_pNodeOfMapper);
    
    SAFEARRAY * psa = NULL;
    VARTYPE vartype;
    DOMNodeType dnt;
    long lDimension;
    
    BOOL bDoSoapEncoding = FALSE;
    CAutoP<long> pIndicesHigh(NULL);
    CAutoP<SAFEARRAYBOUND> pabound(NULL);
    CAutoP<long> pIndices(NULL);
    
    XPathState  xp;

    // make sure we got a node
    CHK_BOOL(pNodeOfMapper, E_INVALIDARG);
    // and create an additional refcount, since we are handling it in a CAutoRefc
    pNodeOfMapper->AddRef();

    // follow the Href if necessary
    CHK (FollowHref(&pNodeOfMapper));

    showNode(pNodeOfMapper);

    CHK (xp.init(pNodeOfMapper));
    CHK (xp.addNamespace(g_pwstrXpathEnv));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -