📄 wsdloper.cpp
字号:
m_ppchparameterOrder = new TCHAR*[16];
if (!m_ppchparameterOrder)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
memset(m_ppchparameterOrder, 0, sizeof(TCHAR*));
if (m_bstrparameterOrder && m_bstrparameterOrder.Len() > 0)
{
pchToken = _tcstok(m_bstrparameterOrder, _T(" "));
while (pchToken)
{
if (ulOrder >= ulCount)
{
// need to realloc that array
ulCount += 16;
#ifndef UNDER_CE
m_ppchparameterOrder = (TCHAR**)realloc(m_ppchparameterOrder, sizeof(TCHAR**)*ulCount);
if (!m_ppchparameterOrder)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
#else //change makes sure we dont leak if realloc fails
TCHAR **ppTemp = (TCHAR**)realloc(m_ppchparameterOrder, sizeof(TCHAR**)*ulCount);
if (!ppTemp)
{
delete [] m_ppchparameterOrder;
m_ppchparameterOrder = NULL;
hr = E_OUTOFMEMORY;
goto Cleanup;
}
m_ppchparameterOrder = ppTemp;
#endif
}
m_ppchparameterOrder[ulOrder] = pchToken;
pchToken = _tcstok(0, _T(" "));
ulOrder++;
m_cbparaOrder = ulOrder;
}
}
Cleanup:
return (hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CWSDLOperation::AddMapper(CSoapMapper *pSoapMapper, CWSDLMessagePart *pMessage, bool fInput, long lOrder)
//
// parameters:
//
// description:
// does several things
// a) add the mapper to the collection
// b) if in/out set the original mapper to in/out type and update the saveorder for output
// c) set's the parameter order of the mapper if parameterOrder is set in the wsdl
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWSDLOperation::AddMapper(CSoapMapper *pSoapMapper, CWSDLMessagePart *pMessage, bool fInput, long lOrder)
{
HRESULT hr=S_OK;
CAutoRefc<ISoapMapper> pMapper;
#ifndef UNDER_CE
TCHAR *pchFound;
#endif
long lparaOrder=0;
#ifndef UNDER_CE
long lCurOrder;
long ret;
#endif
DWORD dwCookie;
CEnumSoapMappers *pMappers;
ASSERT(pSoapMapper!=0);
ASSERT(m_pEnumSoapMappers!=0);
// we need to check the parameterOrder attribute to see if the part of that mapper is mentioned there...
if (m_cbparaOrder > 0)
{
for (lparaOrder = 0; lparaOrder < m_cbparaOrder; lparaOrder++)
{
if (pSoapMapper->getPartName() && _tcscmp(pSoapMapper->getPartName(), m_ppchparameterOrder[lparaOrder])==0)
{
break;
}
}
if (lparaOrder == m_cbparaOrder)
{
// not found, make return value
lparaOrder = -1;
if (!m_fDocumentMode)
{
// in RPC mode, save this guy first
lOrder = -1 ;
}
}
}
else
{
m_pEnumSoapMappers->parameterCount(&lparaOrder);
}
pSoapMapper->setparameterOrder(lparaOrder);
// the next thing we do is check if that mapper (in case of output message) is already in
// the list (input message) -> we then don't add it, but make it in/out
dwCookie = 0;
while (m_pEnumSoapMappers->getNext(&pMapper, &dwCookie)==S_OK)
{
if (wcscmp(((CSoapMapper*)(ISoapMapper*)pMapper)->getVarName(),((CSoapMapper*)pSoapMapper)->getVarName())==0)
{
// equal guys, change the old mapper to in/out, forget the new mapper
((CSoapMapper*)(ISoapMapper*)pMapper)->setInput(smInOut);
CHK(pMessage->AddOrdered(pMapper));
// need to shutdown the original
pSoapMapper->Shutdown();
pMapper.Clear();
goto Cleanup;
}
pMapper.Clear();
}
// first see if we are adding the same parameterOrder twice
if (m_cbparaOrder > 0)
{
if (m_pEnumSoapMappers->FindParameter(lparaOrder, 0)==S_OK)
{
// we already a parameter with this order, so there must be something wrong
hr = E_INVALIDARG;
globalAddError(WSDL_IDS_OPERPARAORDERINVALID, WSDL_IDS_OPERATION, hr, m_bstrMethodName);
goto Cleanup;
}
}
if (isDocumentMode() && pMessage->IsLiteral() && pSoapMapper->isBasedOnType())
{
// check if we have ONLY ONE part type= in this mode
pMappers = pMessage->getMappers();
dwCookie = 0;
while (pMappers->getNext(&pMapper, &dwCookie)==S_OK)
{
if (((CSoapMapper*)(ISoapMapper*)pMapper)->isBasedOnType())
{
hr = E_INVALIDARG;
globalAddError(WSDL_IDS_OPERMULTIPLEPARTSWITHTYPE, WSDL_IDS_OPERATION, hr, m_bstrMethodName);
goto Cleanup;
}
}
}
hr = m_pEnumSoapMappers->Add(pSoapMapper);
if (FAILED(hr))
goto Cleanup;
// so we have no parameterOrder attribute. NOW, if this is the FIRST OUTPUT MAPPER, and it's NOT AN IN/OUT
// we want to give him the result signature
if (m_cbparaOrder == 0 && !fInput && lOrder == 0)
{
pSoapMapper->setparameterOrder(-1);
}
hr = pMessage->AddOrdered(pSoapMapper);
if (FAILED(hr))
goto Cleanup;
Cleanup:
ASSERT(hr==S_OK);
return (hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CWSDLMessagePart::CWSDLMessagePart()
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
CWSDLMessagePart::CWSDLMessagePart()
{
memset(this, 0, sizeof(CWSDLMessagePart));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CWSDLMessagePart::~CWSDLMessagePart()
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
CWSDLMessagePart::~CWSDLMessagePart()
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CWSDLMessagePart::Init(IXMLDOMNode *pOperationNode, ISoapTypeMapperFactory *ptypeFactory,
// TCHAR *pchPortType, TCHAR *pchMessageType, TCHAR *pchOperationName, CWSDLOperation *pParent)
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWSDLMessagePart::Init(IXMLDOMNode *pOperationNode, ISoapTypeMapperFactory *ptypeFactory, TCHAR *pchPortType, TCHAR *pchMessageType, TCHAR *pchOperationName, CWSDLOperation *pParent)
{
HRESULT hr = E_FAIL;
CAutoBSTR bstrPartName;
CAutoRefc<IXMLDOMNode> pBody=0;
CAutoRefc<IXMLDOMNode> pPortInfo=0;
CAutoRefc<IXMLDOMNode> pPart=0;
CAutoRefc<IXMLDOMNodeList> pNodeList=0;
CAutoRefc<IXMLDOMNodeList> pSubList=0;
CAutoBSTR bstrNSUri;
CAutoBSTR bstrParameterWithPrefix;
CSoapMapper *pSoapMapper=0;
bool fInput=false;
long lOrder=0;
long lLength;
CAutoFormat autoFormat;
ASSERT(pOperationNode!=0);
ASSERT(pchPortType != 0);
// first get the subnode
m_pEnumMappersToSave = new CSoapObject<CEnumSoapMappers>(INITIAL_REFERENCE);
if (!m_pEnumMappersToSave)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
fInput = *pchMessageType==_T('i') ? true : false;
CHK(autoFormat.sprintf(_T("def:%s/soap:body"), pchMessageType));
m_fBody = true;
hr = pOperationNode->selectSingleNode(&autoFormat, &pBody);
if (hr != S_OK)
{
// now maybe this guys is a HEADER definition, so search for that guy
CHK(autoFormat.sprintf(_T("def:%s/soap:header"), pchMessageType));
hr = pOperationNode->selectSingleNode(&autoFormat, &pBody);
m_fBody=false;
}
if (hr != S_OK)
{
// globalAddError(WSDL_IDS_OPERNOBODYHEADER, WSDL_IDS_OPERATION, hr, pchOperationName);
// remove the error. the input/output COULD be mime: or any other binding. Check in the operation
// to remove this message part.
goto Cleanup;
}
{
CAutoBSTR bstrTemp;
hr = _WSDLUtilFindAttribute(pBody, _T("use"), &bstrTemp);
if (FAILED(hr))
{
globalAddError(WSDL_IDS_OPERNOUSEATTR, WSDL_IDS_OPERATION, hr, pchOperationName);
goto Cleanup;
}
m_fIsLiteral = (wcscmp(bstrTemp, _T("literal"))==0);
}
if (m_fIsLiteral == false)
{
if (pParent->isDocumentMode())
{
// now we have document/encoded. This is NOT supported, error OUT
hr = E_FAIL;
globalAddError(WSDL_IDS_UNSUPPORTEDMODE, WSDL_IDS_OPERATION, hr, pchOperationName);
goto Cleanup;
}
// if use = encoding, we need an encoding style
hr = _WSDLUtilFindAttribute(pBody, _T("encodingStyle"), &m_bstrEncodingStyle);
if (FAILED(hr))
{
// error. if the style is not literal, it's encoded, hence encodingstyle has to be there
globalAddError(WSDL_IDS_NOENCODINGSTYLE, WSDL_IDS_OPERATION, hr, pchOperationName);
goto Cleanup;
}
else
{
// now check the encodingstyle, only SOAP defined encoding is supported
if (_tcsncmp(m_bstrEncodingStyle, g_pwstrEncStyleNS,
wcslen(g_pwstrEncStyleNS))!=0)
{
hr = E_FAIL;
globalAddError(WSDL_IDS_WRONGENCODINGSTYLE, WSDL_IDS_OPERATION, hr, m_bstrEncodingStyle);
goto Cleanup;
}
}
hr = _WSDLUtilFindAttribute(pBody, _T("namespace"), &m_bstrNameSpace);
if (FAILED(hr) || m_bstrNameSpace.Len() == 0)
{
globalAddError(WSDL_IDS_NONONAMSPACE, WSDL_IDS_OPERATION, hr, pchOperationName);
goto Cleanup;
}
}
else
{
// search for the namespace anyway for literal mode, but ignore if not there
_WSDLUtilFindAttribute(pBody, _T("namespace"), &m_bstrNameSpace);
if (m_bstrNameSpace.Len() == 0)
{
m_bstrNameSpace.Clear();
}
}
// now we got everything we need OUT of the binding/opertaion node, now we need to find the correct porttype etc
CHK(autoFormat.sprintf(_T("//def:portType[@name=\"%s\"]/def:operation[@name=\"%s\"]/def:%s"), pchPortType, pchOperationName, pchMessageType));
hr = _XPATHUtilFindNodeFromRoot(pOperationNode, &autoFormat, &pPortInfo);
if (FAILED(hr))
{
globalAddError(WSDL_IDS_OPERNOTFOUNDINPORT, WSDL_IDS_OPERATION, hr, &autoFormat);
goto Cleanup;
}
{
CAutoBSTR bstrTemp;
hr = _WSDLUtilFindAttribute(pPortInfo, _T("message"), &bstrTemp);
if (FAILED(hr))
{
globalAddError(WSDL_IDS_OPERMSGPARTINPORTNF, WSDL_IDS_OPERATION, hr, pchOperationName);
goto Cleanup;
}
_WSDLUtilSplitQName(bstrTemp, 0, &bstrPartName);
}
// we will ignore the name in the port for all cases ...
// we will still have to verify if this is true for document and rpc mode
if (!fInput)
{
CHK(autoFormat.sprintf(_T("%s%s"), pchOperationName, _T("Response")));
CHK(m_bstrMessageName.Assign(&autoFormat));
}
else
{
CHK(m_bstrMessageName.Assign(pchOperationName));
}
// now we have the message definiton. We need to walk over the parts and get the data out of there
// first see if the message definition is there, this HAS to be there
CHK(autoFormat.sprintf(_T("//def:message[@name=\"%s\"]"), bstrPartName));
hr = _XPATHUtilFindNodeFromRoot(pOperationNode, &autoFormat, &pPart);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -