1 // This is a part of the Active Template Library.
2 // Copyright (C) Microsoft Corporation
3 // All rights reserved.
5 // This source code is only intended as a supplement to the
6 // Active Template Library Reference and related
7 // electronic documentation provided with the library.
8 // See these sources for detailed information regarding the
9 // Active Template Library product.
16 #if (defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_))
17 #error require winsock2.h -- include <winsock2.h> before you include <windows.h>
20 #if ((_WIN32_WINNT < 0x0400) && (_WIN32_WINDOWS <= 0x0400))
21 #error require _WIN32_WINNT >= 0x0400 or _WIN32_WINDOWS > 0x0400
25 #ifdef _ATLSOAP_TRACE_XML
26 #define ATLSOAP_TRACE(__data, __len) AtlSoapTraceXML(__data, __len)
28 #define ATLSOAP_TRACE(__data, __len) __noop
30 #endif // ATLSOAP_TRACE
32 // override this macro to ATL_BASE64_FLAG_NOCRLF if you do
33 // not want Base64-encoded binary data to contain CRLFs
34 #ifndef ATLSOAP_BASE64_FLAGS
35 #define ATLSOAP_BASE64_FLAGS ATL_BASE64_FLAG_NONE
36 #endif // ATLSOAP_BASE64_FLAGS
38 [ emitidl(restricted
) ];
50 #include <atlstencil.h>
52 #include <atlhttp.inl>
55 #pragma warning(disable: 4625) // copy constructor could not be generated because a base class copy constructor is inaccessible
56 #pragma warning(disable: 4626) // assignment operator could not be generated because a base class assignment operator is inaccessible
57 #pragma warning(disable: 4061) // enumerate 'enum value' in switch of enum 'enum type' is not explicitly handled by a case label
60 #pragma warning(disable: 4702) // unreachable code
63 #ifndef ATLSOAP_NOWININET
65 #ifndef ATLSOAPINET_CLIENT
66 #define ATLSOAPINET_CLIENT _T("VCSoapClient")
70 #ifndef _ATL_NO_DEFAULT_LIBS
71 #pragma comment(lib, "msxml2.lib")
72 #ifndef ATLSOAP_NOWININET
73 #pragma comment(lib, "wininet.lib")
77 #define _ATLSOAP_MAKEWIDESTR( str ) L ## str
78 #define ATLSOAP_MAKEWIDESTR( str ) _ATLSOAP_MAKEWIDESTR( str )
81 #pragma pack(push,_ATL_PACKING)
85 ATL_NOINLINE
inline void AtlSoapTraceXML(LPBYTE pdwData
, DWORD dwLen
)
87 HANDLE hStdOut
= GetStdHandle(STD_OUTPUT_HANDLE
);
88 if (hStdOut
!= INVALID_HANDLE_VALUE
)
92 "\n-----------------------------------------------------------------\n",
93 sizeof("\n-----------------------------------------------------------------\n")-1,
96 WriteFile(hStdOut
, pdwData
, dwLen
, &dwWritten
, NULL
);
99 "\n-----------------------------------------------------------------\n",
100 sizeof("\n-----------------------------------------------------------------\n")-1,
105 ////////////////////////////////////////////////////////////////////////////////
107 // IStreamImpl - stub IStream implementation class
109 ////////////////////////////////////////////////////////////////////////////////
111 class IStreamImpl
: public IStream
115 HRESULT __stdcall
Read(void * /*pDest*/, ULONG
/*nMaxLen*/, ULONG
* /*pnRead*/)
120 HRESULT __stdcall
Write(const void * /*pv*/, ULONG
/*cb*/, ULONG
* /*pcbWritten*/)
125 HRESULT __stdcall
Seek(LARGE_INTEGER
/*dlibMove*/, DWORD
/*dwOrigin*/,
126 ULARGE_INTEGER
* /*pLibNewPosition*/)
131 HRESULT __stdcall
SetSize(ULARGE_INTEGER
/*libNewSize*/)
136 HRESULT __stdcall
CopyTo(IStream
* /*pStream*/, ULARGE_INTEGER
/*cb*/,
137 ULARGE_INTEGER
* /*pcbRead*/, ULARGE_INTEGER
* /*pcbWritten*/)
142 HRESULT __stdcall
Commit(DWORD
/*grfCommitFlags*/)
147 HRESULT __stdcall
Revert()
152 HRESULT __stdcall
LockRegion(ULARGE_INTEGER
/*libOffset*/, ULARGE_INTEGER
/*cb*/, DWORD
/*dwLockType*/)
157 HRESULT __stdcall
UnlockRegion(ULARGE_INTEGER
/*libOffset*/, ULARGE_INTEGER
/*cb*/, DWORD
/*dwLockType*/)
162 HRESULT __stdcall
Stat(STATSTG
* /*pstatstg*/, DWORD
/*grfStatFlag*/)
167 HRESULT __stdcall
Clone(IStream
** /*ppstm*/)
171 }; // class IStreamImpl
173 ////////////////////////////////////////////////////////////////////////////////
175 // CStreamOnServerContext
177 ////////////////////////////////////////////////////////////////////////////////
179 class CStreamOnServerContext
: public IStreamImpl
183 HRESULT __stdcall
QueryInterface(REFIID riid
, void **ppv
)
192 if (InlineIsEqualGUID(riid
, IID_IUnknown
) ||
193 InlineIsEqualGUID(riid
, IID_IStream
) ||
194 InlineIsEqualGUID(riid
, IID_ISequentialStream
))
196 *ppv
= static_cast<IStream
*>(this);
200 return E_NOINTERFACE
;
203 ULONG __stdcall
AddRef()
208 ULONG __stdcall
Release()
215 IHttpServerContext
* m_pServerContext
;
220 CStreamOnServerContext(IHttpServerContext
*pServerContext
= NULL
)
221 : m_pServerContext(pServerContext
), m_dwBytesRead(0)
225 void SetServerContext(IHttpServerContext
*pServerContext
)
227 ATLASSUME( m_pServerContext
== NULL
);
229 m_pServerContext
= pServerContext
;
232 HRESULT __stdcall
Read(void *pDest
, ULONG nMaxLen
, ULONG
*pnRead
)
234 ATLENSURE( pDest
!= NULL
);
235 ATLASSUME( m_pServerContext
!= NULL
);
237 DWORD dwToRead
= __min(m_pServerContext
->GetTotalBytes()-m_dwBytesRead
, nMaxLen
);
238 if (ReadClientData(m_pServerContext
, (LPSTR
) pDest
, &dwToRead
, m_dwBytesRead
) != FALSE
)
240 m_dwBytesRead
+= dwToRead
;
250 ATLTRACE( _T("ATLSOAP: CStreamOnServerContext::Read -- ReadClientData failed.\r\n") );
254 }; // class CStreamOnServerContext
256 ////////////////////////////////////////////////////////////////////////////////
258 // CReadStreamOnSocket
260 ////////////////////////////////////////////////////////////////////////////////
262 template <typename TSocketClass
>
263 class CReadStreamOnSocket
: public IStreamImpl
267 HRESULT __stdcall
QueryInterface(REFIID riid
, void **ppv
)
276 if (InlineIsEqualGUID(riid
, IID_IUnknown
) ||
277 InlineIsEqualGUID(riid
, IID_IStream
) ||
278 InlineIsEqualGUID(riid
, IID_ISequentialStream
))
280 *ppv
= static_cast<IStream
*>(this);
284 return E_NOINTERFACE
;
287 ULONG __stdcall
AddRef()
292 ULONG __stdcall
Release()
299 CAtlHttpClientT
<TSocketClass
> * m_pSocket
;
306 CReadStreamOnSocket()
307 : m_pSocket(NULL
), m_szBuffer(NULL
), m_szCurr(NULL
), m_nBodyLen(0)
311 BOOL
Init(CAtlHttpClientT
<TSocketClass
> *pSocket
)
313 ATLENSURE( pSocket
!= NULL
);
316 m_szBuffer
= (LPCSTR
) pSocket
->GetBody();
318 ATLSOAP_TRACE( (LPBYTE
) pSocket
->GetBody(), pSocket
->GetBodyLength() );
320 if (m_szBuffer
!= NULL
)
322 m_szCurr
= m_szBuffer
;
323 m_nBodyLen
= pSocket
->GetBodyLength();
330 ATLTRACE( _T("ATLSOAP: CReadStreamOnSocket::Init failed.\r\n") );
335 HRESULT __stdcall
Read(void *pDest
, ULONG nMaxLen
, ULONG
*pnRead
)
337 ATLASSERT( pDest
!= NULL
);
338 ATLASSUME( m_pSocket
!= NULL
);
339 ATLASSUME( m_szBuffer
!= NULL
);
346 long nRead
= (int) (m_szCurr
-m_szBuffer
);
347 if (nRead
< m_nBodyLen
)
349 long nLength
= __min((int)(m_nBodyLen
-nRead
), (LONG
) nMaxLen
);
350 Checked::memcpy_s(pDest
, nMaxLen
, m_szCurr
, nLength
);
355 *pnRead
= (ULONG
) nLength
;
361 }; // class CReadStreamOnSocket
363 ////////////////////////////////////////////////////////////////////////////////
365 // CWriteStreamOnCString
367 ////////////////////////////////////////////////////////////////////////////////
369 class CWriteStreamOnCString
: public IWriteStream
375 virtual ~CWriteStreamOnCString()
379 HRESULT
WriteStream(LPCSTR szOut
, int nLen
, LPDWORD pdwWritten
)
381 ATLENSURE_RETURN( szOut
!= NULL
);
385 nLen
= (int) strlen(szOut
);
390 m_str
.Append(szOut
, nLen
);
394 return E_OUTOFMEMORY
;
397 if (pdwWritten
!= NULL
)
399 *pdwWritten
= (DWORD
) nLen
;
405 HRESULT
FlushStream()
414 }; // class CWriteStreamOnCString
416 ////////////////////////////////////////////////////////////////////////////////
420 ////////////////////////////////////////////////////////////////////////////////
422 #define SOAPENV_NAMESPACEA "http://schemas.xmlsoap.org/soap/envelope/"
423 #define SOAPENV_NAMESPACEW ATLSOAP_MAKEWIDESTR( SOAPENV_NAMESPACEA )
425 #define SOAPENC_NAMESPACEA "http://schemas.xmlsoap.org/soap/encoding/"
426 #define SOAPENC_NAMESPACEW ATLSOAP_MAKEWIDESTR( SOAPENC_NAMESPACEA )
428 #define XSI_NAMESPACEA "http://www.w3.org/2001/XMLSchema-instance"
429 #define XSI_NAMESPACEW ATLSOAP_MAKEWIDESTR( XSI_NAMESPACEA )
431 #define XSD_NAMESPACEA "http://www.w3.org/2001/XMLSchema"
432 #define XSD_NAMESPACEW ATLSOAP_MAKEWIDESTR( XSD_NAMESPACEA )
434 #ifndef ATLSOAP_GENERIC_NAMESPACE
435 #define ATLSOAP_GENERIC_NAMESPACE L"http://www.tempuri.org"
438 ////////////////////////////////////////////////////////////////////////////////
442 ////////////////////////////////////////////////////////////////////////////////
444 inline HRESULT
GetAttribute(
445 __in ISAXAttributes
*pAttributes
,
446 __in_ecount(cchName
) const wchar_t *wszAttrName
, __in
int cchName
,
447 __out_ecount_part(*pcchValue
, *pcchValue
) const wchar_t **pwszValue
, __inout
int *pcchValue
,
448 __in_ecount_opt(cchNamespace
) wchar_t *wszNamespace
= NULL
, __in
int cchNamespace
= 0)
450 if (!pAttributes
|| !wszAttrName
|| !pwszValue
|| !pcchValue
)
459 return (pAttributes
->getValueFromQName(wszAttrName
, cchName
, pwszValue
, pcchValue
) == S_OK
? S_OK
: E_FAIL
);
461 return (pAttributes
->getValueFromName(wszNamespace
, cchNamespace
,
462 wszAttrName
, cchName
, pwszValue
, pcchValue
) == S_OK
? S_OK
: E_FAIL
);
465 inline HRESULT
GetAttribute(
466 __in ISAXAttributes
*pAttributes
,
467 __in_ecount(cchName
) const wchar_t *wszAttrName
, __in
int cchName
,
468 __inout CStringW
&strValue
,
469 __in_ecount_opt(cchNamespace
) wchar_t *wszNamespace
= NULL
, __in
int cchNamespace
= 0)
471 const wchar_t *wszValue
= NULL
;
474 if (!pAttributes
|| !wszAttrName
)
482 hr
= (pAttributes
->getValueFromQName(wszAttrName
, cchName
, &wszValue
, &cchValue
) == S_OK
? S_OK
: E_FAIL
);
486 hr
= (pAttributes
->getValueFromName(wszNamespace
, cchNamespace
,
487 wszAttrName
, cchName
, &wszValue
, &cchValue
) == S_OK
? S_OK
: E_FAIL
);
494 strValue
.SetString(wszValue
, cchValue
);
498 ATLTRACE( _T("ATLSOAP: GetAttribute -- out of memory.\r\n") );
507 inline const wchar_t *SkipWhitespace(const wchar_t *wsz
)
509 while (*wsz
&& iswspace(*wsz
))
517 ////////////////////////////////////////////////////////////////////////////////
519 // BLOB data type - use this struct when you want to send BLOB data
520 // the attribute provider and proxy generator will only properly special
521 // case blob data when using this struct.
523 ////////////////////////////////////////////////////////////////////////////////
526 typedef struct _tagATLSOAP_BLOB
532 #ifndef _ATL_SOAP_NO_PARAMETER_VALIDATIONS
533 #define _ATL_VALIDATE_PARAMETER_END(p)\
540 #define _ATL_VALIDATE_PARAMETER_END(p)
543 // All non-integral types have specializations which
544 // will be called. The following function will be called
545 // only for integral types
547 #pragma push_macro("max")
548 #pragma push_macro("min")
551 template <typename T
>
552 inline HRESULT
AtlGetSAXValue(T
* pVal
, const wchar_t * wsz
, int cch
)
554 __int64 nVal
= *pVal
;
555 if (FAILED(AtlGetSAXValue(&nVal
, wsz
, cch
)))
558 #ifndef _ATL_SOAP_NO_PARAMETER_VALIDATIONS
559 if(nVal
< std::numeric_limits
<T
>::min() || nVal
> std::numeric_limits
<T
>::max())
568 #pragma pop_macro("max")
569 #pragma pop_macro("min")
571 ////////////////////////////////////////////////////////////////////////////////
573 // AtlGetXMLValue (for IXMLDOMDocument) - get the real type from the XML data
575 ///////////////////////////////////////////////////////////////////////////////
578 // generic IXMLDOMNode template function
579 // delegates to AtlGetSAXValue
581 template <typename T
>
582 inline HRESULT
AtlGetXMLValue(IXMLDOMNode
*pParam
, T
*pVal
)
585 HRESULT hr
= AtlGetXMLValue(pParam
, &bstrVal
);
588 hr
= AtlGetSAXValue(pVal
, bstrVal
, bstrVal
.Length());
594 // specialization for BSTR
596 inline HRESULT AtlGetXMLValue
<BSTR
>(IXMLDOMNode
*pParam
, BSTR
*pbstrVal
)
602 if (pbstrVal
== NULL
)
607 CComPtr
<IXMLDOMNode
> spChild
;
608 if (pParam
->get_firstChild(&spChild
) == S_OK
)
610 CComPtr
<IXMLDOMNode
> spXmlChild
;
611 if (spChild
->get_firstChild(&spXmlChild
) == S_OK
)
613 return (pParam
->get_xml(pbstrVal
) == S_OK
? S_OK
: E_FAIL
);
617 return (pParam
->get_text(pbstrVal
) == S_OK
) ? S_OK
: E_FAIL
;
620 ////////////////////////////////////////////////////////////////////////////////
622 // AtlGetSAXValue - (for SAX or generic) get the real type from the XML data
624 ////////////////////////////////////////////////////////////////////////////////
627 inline HRESULT AtlGetSAXValue
<bool>(bool *pVal
, __in_z
const wchar_t *wsz
, int cch
)
629 ATLENSURE( wsz
!= NULL
);
661 if (cch
==sizeof("true")-1 && !wcsncmp(wsz
, L
"true", cch
))
670 if (cch
==sizeof("false")-1 && !wcsncmp(wsz
, L
"false", cch
))
683 inline HRESULT AtlGetSAXValue
<__int64
>(__int64
*pVal
, __in_z
const wchar_t *wsz
, int cch
)
685 ATLENSURE_RETURN( wsz
!= NULL
);
694 CFixedStringT
<CStringW
, 1024> wstr(wsz
, cch
);
695 const wchar_t *pStart
= ATL::SkipWhitespace(static_cast<LPCWSTR
>(wstr
));
699 errno_t errnoValue
= AtlStrToNum(&i
, pStart
, const_cast<wchar_t **>(&pEnd
), 10);
700 if (errnoValue
== ERANGE
)
702 return E_FAIL
;//overflow or underflow case
704 pEnd
= ATL::SkipWhitespace(pEnd
);
705 _ATL_VALIDATE_PARAMETER_END(pEnd
);
710 return E_OUTOFMEMORY
;
717 inline HRESULT AtlGetSAXValue
<unsigned __int64
>(unsigned __int64
*pVal
, __in_z
const wchar_t *wsz
, int cch
)
719 ATLENSURE_RETURN( wsz
!= NULL
);
728 CFixedStringT
<CStringW
, 1024> wstr(wsz
, cch
);
729 const wchar_t *pStart
= ATL::SkipWhitespace(static_cast<LPCWSTR
>(wstr
));
732 unsigned __int64 i
= 0;
733 errno_t errnoValue
= AtlStrToNum(&i
, pStart
, const_cast<wchar_t **>(&pEnd
), 10);
734 if (errnoValue
== ERANGE
)
736 return E_FAIL
;//overflow or underflow case
738 pEnd
= ATL::SkipWhitespace(pEnd
);
739 _ATL_VALIDATE_PARAMETER_END(pEnd
);
744 return E_OUTOFMEMORY
;
750 inline HRESULT AtlGetSAXValue
<double>(double *pVal
, __in_z
const wchar_t *wsz
, int cch
)
752 ATLENSURE_RETURN( wsz
!= NULL
);
759 if ((cch
== 3) && (wsz
[0]==L
'I') && (!wcsncmp(wsz
, L
"INF", cch
)))
761 *(((int *) pVal
)+0) = 0x0000000;
762 *(((int *) pVal
)+1) = 0x7FF00000;
764 else if ((cch
== 3) && (wsz
[0]==L
'N') && (!wcsncmp(wsz
, L
"NaN", cch
)))
766 *(((int *) pVal
)+0) = 0x0000000;
767 *(((int *) pVal
)+1) = 0xFFF80000;
769 else if ((cch
== 4) && (wsz
[1]==L
'I') && (!wcsncmp(wsz
, L
"-INF", cch
)))
771 *(((int *) pVal
)+0) = 0x0000000;
772 *(((int *) pVal
)+1) = 0xFFF00000;
776 errno_t errnoValue
= 0;
780 CFixedStringT
<CStringW
, 1024> wstr(wsz
, cch
);
781 const wchar_t *pStart
= ATL::SkipWhitespace(static_cast<LPCWSTR
>(wstr
));
784 errnoValue
= AtlStrToNum(&d
, pStart
, const_cast<wchar_t **>(&pEnd
));
785 pEnd
= ATL::SkipWhitespace(pEnd
);
786 _ATL_VALIDATE_PARAMETER_END(pEnd
);
791 return E_OUTOFMEMORY
;
794 if ((*pVal
== -HUGE_VAL
) || (*pVal
== HUGE_VAL
) || (errnoValue
== ERANGE
))
804 inline HRESULT AtlGetSAXValue
<float>(float *pVal
, __in_z
const wchar_t *wsz
, int cch
)
806 ATLASSERT( wsz
!= NULL
);
814 if (SUCCEEDED(AtlGetSAXValue(&d
, wsz
, cch
)))
816 #ifdef _ATL_SOAP_PARAMETER_VALIDATIONS
817 if(d
> FLT_MAX
|| d
< -FLT_MAX
)
828 inline HRESULT AtlGetSAXValue
<BSTR
>(BSTR
*pVal
, __in_z
const wchar_t *wsz
, int cch
)
830 ATLASSERT( wsz
!= NULL
);
837 *pVal
= SysAllocStringLen(wsz
, cch
);
839 return ((*pVal
!= NULL
) ? S_OK
: E_OUTOFMEMORY
);
842 inline HRESULT
AtlGetSAXBlobValue(
849 ATLENSURE_RETURN( wsz
!= NULL
);
850 ATLENSURE_RETURN( pMemMgr
!= NULL
);
857 if (pVal
->data
!= NULL
)
865 int nLength
= AtlUnicodeToUTF8(wsz
, cch
, NULL
, 0);
869 char * pSrc
= (char *) pMemMgr
->Allocate(nLength
);
872 nLength
= AtlUnicodeToUTF8(wsz
, cch
, pSrc
, nLength
);
875 pVal
->data
= (unsigned char *) pMemMgr
->Allocate(nLength
);
876 if (pVal
->data
!= NULL
)
879 int nDataLength
= nLength
;
882 bRet
= Base64Decode(pSrc
, nLength
, pVal
->data
, &nDataLength
);
886 bRet
= AtlHexDecode(pSrc
, nLength
, pVal
->data
, &nDataLength
);
890 pVal
->size
= nDataLength
;
901 if (pVal
->data
!= NULL
)
903 pMemMgr
->Free(pVal
->data
);
911 ////////////////////////////////////////////////////////////////////////////////
913 // AtlGenXMLValue template and specializations
915 ////////////////////////////////////////////////////////////////////////////////
917 template <typename T
>
918 inline HRESULT
AtlGenXMLValue(__in IWriteStream
*pStream
, __in T
*pVal
)
920 if ((pStream
== NULL
) || (pVal
== NULL
))
926 // delegate to CWriteStreamHelper
928 CWriteStreamHelper
s(pStream
);
930 return (s
.Write(*pVal
) == TRUE
? S_OK
: E_FAIL
);
933 #ifdef _NATIVE_WCHAR_T_DEFINED
935 inline HRESULT AtlGenXMLValue
<wchar_t>(__in IWriteStream
*pStream
, __in
wchar_t *pVal
)
937 return AtlGenXMLValue(pStream
, (unsigned short *)pVal
);
942 inline HRESULT AtlGenXMLValue
<wchar_t *>(__in IWriteStream
*pStream
, __deref_inout_z
wchar_t **pVal
)
944 if ((pStream
== NULL
) || (*pVal
== NULL
))
949 wchar_t *wszWrite
= *pVal
;
950 int nSrcLen
= (int)wcslen(*pVal
);
951 int nCnt
= EscapeXML(*pVal
, nSrcLen
, NULL
, 0);
955 wszWrite
= (wchar_t *)calloc((nCnt
),sizeof(wchar_t));
956 if (wszWrite
== NULL
)
958 return E_OUTOFMEMORY
;
961 nCnt
= EscapeXML(*pVal
, nSrcLen
, wszWrite
, nCnt
);
967 wszWrite
[nCnt
] = L
'\0';
971 nCnt
= AtlUnicodeToUTF8(wszWrite
, nSrcLen
, NULL
, 0);
973 if ((nCnt
== 0) || (nCnt
== nSrcLen
))
975 CWriteStreamHelper
s(pStream
);
977 hr
= (s
.Write(wszWrite
) == TRUE
? S_OK
: E_FAIL
);
982 CHeapPtr
<char> szWrite
;
983 szWrite
.AllocateBytes((size_t)(nCnt
));
986 nCnt
= AtlUnicodeToUTF8(wszWrite
, nSrcLen
, szWrite
, nCnt
);
989 hr
= pStream
->WriteStream(szWrite
, nCnt
, NULL
);
994 ATLTRACE( _T("ATLSOAP: AtlGenXMLValue<wchar_t *> -- out of memory.\r\n") );
1000 if (wszWrite
!= *pVal
)
1009 inline HRESULT AtlGenXMLValue
<double>(IWriteStream
*pStream
, double *pVal
)
1011 if ((pStream
== NULL
) || (pVal
== NULL
))
1013 return E_INVALIDARG
;
1017 switch (_fpclass(*pVal
))
1022 hr
= pStream
->WriteStream("NaN", 3, NULL
);
1027 hr
= pStream
->WriteStream("-INF", 4, NULL
);
1032 hr
= pStream
->WriteStream("INF", 3, NULL
);
1037 hr
= pStream
->WriteStream("-0", 2, NULL
);
1043 * 2 = sign + decimal point
1044 * ndec = decimal digits
1045 * 5 = exponent letter (e or E), exponent sign, three digits exponent
1046 * 1 = extra space for rounding
1047 * 1 = string terminator '\0'
1049 const int ndec
= 512;
1052 Checked::gcvt_s(szBuf
, _countof(szBuf
), *pVal
, ndec
);
1053 size_t nLen
= strlen(szBuf
);
1054 if (nLen
&& szBuf
[nLen
-1] == '.')
1056 szBuf
[--nLen
] = '\0';
1059 hr
= pStream
->WriteStream(szBuf
, (int)nLen
, NULL
);
1068 inline HRESULT AtlGenXMLValue
<float>(IWriteStream
*pStream
, float *pVal
)
1070 if ((pStream
== NULL
) || (pVal
== NULL
))
1072 return E_INVALIDARG
;
1077 return AtlGenXMLValue(pStream
, &d
);
1081 inline HRESULT AtlGenXMLValue
<bool>(IWriteStream
*pStream
, bool *pVal
)
1083 if ((pStream
== NULL
) || (pVal
== NULL
))
1085 return E_INVALIDARG
;
1090 return pStream
->WriteStream("true", sizeof("true")-1, NULL
);
1093 return pStream
->WriteStream("false", sizeof("false")-1, NULL
);
1096 inline HRESULT
AtlGenXMLBlobValue(
1097 IWriteStream
*pStream
,
1099 IAtlMemMgr
*pMemMgr
,
1102 if ((pStream
== NULL
) || (pVal
== NULL
) || (pMemMgr
== NULL
))
1104 return E_INVALIDARG
;
1107 HRESULT hr
= E_FAIL
;
1111 nLength
= Base64EncodeGetRequiredLength(pVal
->size
, ATLSOAP_BASE64_FLAGS
);
1115 nLength
= AtlHexEncodeGetRequiredLength(pVal
->size
);
1118 char *pEnc
= (char *) pMemMgr
->Allocate(nLength
);
1124 bRet
= Base64Encode(pVal
->data
, pVal
->size
, pEnc
, &nLength
, ATLSOAP_BASE64_FLAGS
);
1128 bRet
= AtlHexEncode(pVal
->data
, pVal
->size
, pEnc
, &nLength
);
1132 hr
= pStream
->WriteStream(pEnc
, nLength
, NULL
);
1135 pMemMgr
->Free(pEnc
);
1141 template <typename T
>
1142 inline HRESULT
AtlCleanupValue(T
* /*pVal*/)
1147 inline HRESULT
AtlCleanupBlobValue(ATLSOAP_BLOB
*pVal
, IAtlMemMgr
*pMemMgr
)
1149 if ((pVal
== NULL
) || (pMemMgr
== NULL
))
1151 return E_INVALIDARG
;
1154 if (pVal
->data
!= NULL
)
1156 pMemMgr
->Free(pVal
->data
);
1165 inline HRESULT AtlCleanupValue
<ATLSOAP_BLOB
>(ATLSOAP_BLOB
*pVal
)
1167 ATLTRACE( _T("Warning: AtlCleanupValue<ATLSOAP_BLOB> was called -- assuming CRT allocator.\r\n") );
1171 return E_INVALIDARG
;
1174 if (pVal
->data
!= NULL
)
1185 inline HRESULT AtlCleanupValue
<BSTR
>(BSTR
*pVal
)
1189 // should never happen
1191 return E_INVALIDARG
;
1194 if ((*pVal
) != NULL
)
1196 // null strings are okay
1197 SysFreeString(*pVal
);
1204 template <typename T
>
1205 inline HRESULT
AtlCleanupValueEx(T
*pVal
, IAtlMemMgr
*pMemMgr
)
1209 return AtlCleanupValue(pVal
);
1213 inline HRESULT AtlCleanupValueEx
<ATLSOAP_BLOB
>(ATLSOAP_BLOB
*pVal
, IAtlMemMgr
*pMemMgr
)
1215 return AtlCleanupBlobValue(pVal
, pMemMgr
);
1218 // single dimensional arrays
1219 template <typename T
>
1220 inline HRESULT
AtlCleanupArray(T
*pArray
, int nCnt
)
1224 return E_INVALIDARG
;
1227 for (int i
=0; i
<nCnt
; i
++)
1229 AtlCleanupValue(&pArray
[i
]);
1236 template <typename T
>
1237 inline HRESULT
AtlCleanupArrayEx(T
*pArray
, int nCnt
, IAtlMemMgr
*pMemMgr
)
1241 return E_INVALIDARG
;
1244 for (int i
=0; i
<nCnt
; i
++)
1246 AtlCleanupValueEx(&pArray
[i
], pMemMgr
);
1253 // multi-dimensional arrays
1254 template <typename T
>
1255 inline HRESULT
AtlCleanupArrayMD(T
*pArray
, const int *pDims
)
1257 if ((pArray
== NULL
) || (pDims
== NULL
))
1259 return E_INVALIDARG
;
1264 for (int i
=1; i
<=pDims
[0]; i
++)
1269 return AtlCleanupArray(pArray
, nCnt
);
1272 template <typename T
>
1273 inline HRESULT
AtlCleanupArrayMDEx(T
*pArray
, const int *pDims
, IAtlMemMgr
*pMemMgr
)
1275 if ((pArray
== NULL
) || (pDims
== NULL
))
1277 return E_INVALIDARG
;
1282 for (int i
=1; i
<=pDims
[0]; i
++)
1287 return AtlCleanupArrayEx(pArray
, nCnt
, pMemMgr
);
1291 #pragma pack(push,_ATL_PACKING)
1295 ////////////////////////////////////////////////////////////////////////////////
1297 // CSAXSoapErrorHandler
1299 ////////////////////////////////////////////////////////////////////////////////
1301 class CSAXSoapErrorHandler
: public ISAXErrorHandler
1305 CFixedStringT
<CStringW
, 256> m_strParseError
;
1308 virtual ~CSAXSoapErrorHandler()
1312 HRESULT __stdcall
QueryInterface(REFIID riid
, void **ppv
)
1319 if (InlineIsEqualGUID(riid
, __uuidof(ISAXErrorHandler
)) ||
1320 InlineIsEqualGUID(riid
, __uuidof(IUnknown
)))
1322 *ppv
= static_cast<ISAXErrorHandler
*>(this);
1325 return E_NOINTERFACE
;
1328 ULONG __stdcall
AddRef()
1333 ULONG __stdcall
Release()
1338 const CStringW
& GetParseError()
1340 return m_strParseError
;
1343 HRESULT __stdcall
error(
1344 ISAXLocator
*pLocator
,
1345 const wchar_t *wszErrorMessage
,
1346 HRESULT hrErrorCode
)
1352 ATLTRACE( _T("ATLSOAP: parse error: %ws\r\n"), wszErrorMessage
);
1356 m_strParseError
= wszErrorMessage
;
1366 HRESULT __stdcall
fatalError(
1367 ISAXLocator
*pLocator
,
1368 const wchar_t *wszErrorMessage
,
1369 HRESULT hrErrorCode
)
1375 ATLTRACE( _T("ATLSOAP: fatal parse error: %ws\r\n"), wszErrorMessage
);
1379 m_strParseError
= wszErrorMessage
;
1389 HRESULT __stdcall
ignorableWarning(
1390 ISAXLocator
*pLocator
,
1391 const wchar_t *wszErrorMessage
,
1392 HRESULT hrErrorCode
)
1398 ATLTRACE( _T("ATLSOAP: ignorable warning: %ws\r\n"), wszErrorMessage
);
1404 ////////////////////////////////////////////////////////////////////////////////
1406 // ISAXContentHandlerImpl
1408 ////////////////////////////////////////////////////////////////////////////////
1410 class ISAXContentHandlerImpl
:
1411 public ISAXContentHandler
1416 // ISAXContentHandler interface
1419 HRESULT __stdcall
putDocumentLocator(ISAXLocator
* /*pLocator*/)
1424 HRESULT __stdcall
startDocument()
1429 HRESULT __stdcall
endDocument()
1434 HRESULT __stdcall
startPrefixMapping(
1435 const wchar_t * /*wszPrefix*/,
1437 const wchar_t * /*wszUri*/,
1443 HRESULT __stdcall
endPrefixMapping(
1444 const wchar_t * /*wszPrefix*/,
1450 HRESULT __stdcall
startElement(
1451 const wchar_t * /*wszNamespaceUri*/,
1452 int /*cchNamespaceUri*/,
1453 const wchar_t * /*wszLocalName*/,
1454 int /*cchLocalName*/,
1455 const wchar_t * /*wszQName*/,
1457 ISAXAttributes
* /*pAttributes*/)
1462 HRESULT __stdcall
endElement(
1463 const wchar_t * /*wszNamespaceUri*/,
1464 int /*cchNamespaceUri*/,
1465 const wchar_t * /*wszLocalName*/,
1466 int /*cchLocalName*/,
1467 const wchar_t * /*wszQName*/,
1473 HRESULT __stdcall
characters(
1474 const wchar_t * /*wszChars*/,
1480 HRESULT __stdcall
ignorableWhitespace(
1481 const wchar_t * /*wszChars*/,
1487 HRESULT __stdcall
processingInstruction(
1488 const wchar_t * /*wszTarget*/,
1490 const wchar_t * /*wszData*/,
1496 HRESULT __stdcall
skippedEntity(
1497 const wchar_t * /*wszName*/,
1502 }; // class ISAXContentHandlerImpl
1504 ////////////////////////////////////////////////////////////////////////////////
1506 // SAX skip element handler utility class
1507 // (skip an element and all its child elements)
1509 ////////////////////////////////////////////////////////////////////////////////
1511 class CSkipHandler
: public ISAXContentHandlerImpl
1514 virtual ~CSkipHandler()
1518 HRESULT __stdcall
QueryInterface(REFIID riid
, void **ppv
)
1527 if (InlineIsEqualGUID(riid
, IID_IUnknown
) ||
1528 InlineIsEqualGUID(riid
, IID_ISAXContentHandler
))
1530 *ppv
= static_cast<ISAXContentHandler
*>(this);
1534 return E_NOINTERFACE
;
1537 ULONG __stdcall
AddRef()
1542 ULONG __stdcall
Release()
1550 CComPtr
<ISAXXMLReader
> m_spReader
;
1551 CComPtr
<ISAXContentHandler
> m_spParent
;
1553 DWORD
DisableReset(DWORD dwCnt
= 1)
1572 CSkipHandler(ISAXContentHandler
*pParent
= NULL
, ISAXXMLReader
*pReader
= NULL
)
1573 : m_spParent(pParent
), m_spReader(pReader
), m_dwReset(1)
1577 void SetParent(ISAXContentHandler
*pParent
)
1579 m_spParent
= pParent
;
1583 m_spParent
.Detach();
1586 void SetReader(ISAXXMLReader
*pReader
)
1588 m_spReader
= pReader
;
1591 HRESULT __stdcall
startElement(
1592 const wchar_t * /*wszNamespaceUri*/,
1593 int /*cchNamespaceUri*/,
1594 const wchar_t * /*wszLocalName*/,
1595 int /*cchLocalName*/,
1596 const wchar_t * /*wszQName*/,
1598 ISAXAttributes
* /*pAttributes*/)
1604 HRESULT __stdcall
endElement(
1605 const wchar_t * /*wszNamespaceUri*/,
1606 int /*cchNamespaceUri*/,
1607 const wchar_t * /*wszLocalName*/,
1608 int /*cchLocalName*/,
1609 const wchar_t * /*wszQName*/,
1612 if (EnableReset() == 0)
1614 m_spReader
->putContentHandler(m_spParent
);
1619 }; // class CSkipHandler
1622 ////////////////////////////////////////////////////////////////////////////////
1624 // SAX string builder class
1626 ////////////////////////////////////////////////////////////////////////////////
1628 class CSAXStringBuilder
: public ISAXContentHandlerImpl
1632 HRESULT __stdcall
QueryInterface(REFIID riid
, void **ppv
)
1641 if (InlineIsEqualGUID(riid
, IID_IUnknown
) ||
1642 InlineIsEqualGUID(riid
, IID_ISAXContentHandler
))
1644 *ppv
= static_cast<ISAXContentHandler
*>(this);
1648 return E_NOINTERFACE
;
1651 ULONG __stdcall
AddRef()
1656 ULONG __stdcall
Release()
1663 ISAXContentHandler
* m_pParent
;
1664 ISAXXMLReader
* m_pReader
;
1666 CFixedStringT
<CStringW
, 64> m_str
;
1668 DWORD
DisableReset(DWORD dwReset
= 1)
1670 m_dwReset
+= dwReset
;
1687 CSAXStringBuilder(ISAXXMLReader
*pReader
= NULL
, ISAXContentHandler
*pParent
= NULL
)
1688 :m_pReader(pReader
), m_pParent(pParent
), m_dwReset(0)
1692 virtual ~CSAXStringBuilder()
1696 void SetReader(ISAXXMLReader
*pReader
)
1698 m_pReader
= pReader
;
1701 void SetParent(ISAXContentHandler
*pParent
)
1703 m_pParent
= pParent
;
1706 const CStringW
& GetString()
1717 HRESULT __stdcall
startElement(
1718 const wchar_t * /*wszNamespaceUri*/,
1719 int /*cchNamespaceUri*/,
1720 const wchar_t * /*wszLocalName*/,
1721 int /*cchLocalName*/,
1722 const wchar_t *wszQName
,
1724 ISAXAttributes
*pAttributes
)
1728 // if there is unescaped, nested XML, must disable
1729 // an additional time for the first element
1735 HRESULT hr
= pAttributes
->getLength(&nAttrs
);
1741 m_str
.Append(L
"<", 1);
1742 m_str
.Append(wszQName
, cchQName
);
1744 const wchar_t *wszAttrNamespaceUri
= NULL
;
1745 const wchar_t *wszAttrLocalName
= NULL
;
1746 const wchar_t *wszAttrQName
= NULL
;
1747 const wchar_t *wszAttrValue
= NULL
;
1749 int cchAttrLocalName
= 0;
1750 int cchAttrQName
= 0;
1751 int cchAttrValue
= 0;
1753 for (int i
=0; i
<nAttrs
; i
++)
1755 hr
= pAttributes
->getName(i
, &wszAttrNamespaceUri
, &cchAttrUri
,
1756 &wszAttrLocalName
, &cchAttrLocalName
, &wszAttrQName
, &cchAttrQName
);
1760 ATLTRACE( _T("ATLSOAP: CSAXStringBuilder::startElement -- MSXML error.\r\n") );
1765 m_str
.Append(L
" ", 1);
1766 m_str
.Append(wszAttrQName
, cchAttrQName
);
1768 hr
= pAttributes
->getValue(i
, &wszAttrValue
, &cchAttrValue
);
1772 ATLTRACE( _T("ATLSOAP: CSAXStringBuilder::startElement -- MSXML error.\r\n") );
1777 m_str
.Append(L
"=\"", sizeof("=\"")-1);
1778 if (cchAttrValue
!= 0)
1780 m_str
.Append(wszAttrValue
, cchAttrValue
);
1782 m_str
.Append(L
"\"", 1);
1787 m_str
.Append(L
">", 1);
1793 ATLTRACE( _T("ATLSOAP: CSAXStringBuilder::startElement -- out of memory.\r\n") );
1801 HRESULT __stdcall
endElement(
1802 const wchar_t * wszNamespaceUri
,
1803 int cchNamespaceUri
,
1804 const wchar_t * wszLocalName
,
1806 const wchar_t *wszQName
,
1812 if (EnableReset() == 0)
1814 hr
= m_pParent
->characters((LPCWSTR
) m_str
, m_str
.GetLength());
1817 hr
= m_pParent
->endElement(wszNamespaceUri
, cchNamespaceUri
,
1818 wszLocalName
, cchLocalName
, wszQName
, cchQName
);
1821 m_pReader
->putContentHandler(m_pParent
);
1826 m_str
.Append(L
"</", 2);
1827 m_str
.Append(wszQName
, cchQName
);
1828 m_str
.Append(L
">", 1);
1833 ATLTRACE( _T("ATLSOAP: CSAXStringBuilder::endElement -- out of memory.\r\n") );
1841 HRESULT __stdcall
characters(
1842 const wchar_t *wszChars
,
1847 m_str
.Append(wszChars
, cchChars
);
1851 ATLTRACE( _T("ATLSOAP: CSAXStringBuilder::characters -- out of memory.\r\n") );
1853 return E_OUTOFMEMORY
;
1859 HRESULT __stdcall
ignorableWhitespace(
1860 const wchar_t *wszChars
,
1865 m_str
.Append(wszChars
, cchChars
);
1869 ATLTRACE( _T("ATLSOAP: CSAXStringBuilder::ignorableWhitespace -- out of memory.\r\n") );
1871 return E_OUTOFMEMORY
;
1876 }; // class CSAXStringBuilder
1881 ////////////////////////////////////////////////////////////////////////////////
1883 // SOAP data structure definitions
1885 ////////////////////////////////////////////////////////////////////////////////
1888 // ***************************** WARNING *****************************
1889 // THESE STRUCTURES ARE INTERNAL ONLY, FOR USE WITH THE ATL SERVER SOAP
1890 // ATTRIBUTES. USERS SHOULD NOT USE THESE TYPES DIRECTLY. ABSOLUTELY NO
1891 // GUARANTEES ARE MADE ABOUT BACKWARD COMPATIBILITY FOR DIRECT USE OF
1895 ////////////////////////////////////////////////////////////////////////////////
1897 // BEGIN PRIVATE DEFINITIONS
1899 ////////////////////////////////////////////////////////////////////////////////
1901 inline HRESULT
AtlSoapGetArraySize(ISAXAttributes
*pAttributes
, size_t *pnSize
,
1902 const wchar_t **pwszTypeStart
= NULL
, const wchar_t **pwszTypeEnd
= NULL
)
1909 if (pAttributes
== NULL
)
1911 return E_INVALIDARG
;
1920 const wchar_t *wszTmp
;
1923 hr
= GetAttribute(pAttributes
, L
"arrayType", sizeof("arrayType")-1,
1924 &wszTmp
, &cch
, SOAPENC_NAMESPACEW
, sizeof(SOAPENC_NAMESPACEA
)-1);
1926 if ((SUCCEEDED(hr
)) && (wszTmp
!= NULL
))
1930 CFixedStringT
<CStringW
, 1024> wstrArrayType(wszTmp
, cch
);
1931 const wchar_t *wsz
= static_cast<LPCWSTR
>(wstrArrayType
);
1933 const wchar_t *wszTypeStart
= NULL
;
1934 const wchar_t *wszTypeEnd
= NULL
;
1937 while (iswspace(*wsz
) != 0)
1942 // no need to walk the string if the caller is not interested
1943 if ((pwszTypeStart
!= NULL
) && (pwszTypeEnd
!= NULL
))
1946 wszTypeEnd
= wcschr(wszTypeStart
, L
':');
1947 if (wszTypeEnd
!= NULL
)
1949 wszTypeStart
= wszTypeEnd
+1;
1953 // SOAP Section 5 encodings are of the form:
1954 // <soap_enc namespace>:arrayType="<type_qname>[dim1(,dim_i)*]
1955 // for example: SOAP-ENC:arrayType="xsd:string[2,4]"
1957 wsz
= wcschr(wsz
, L
'[');
1968 // get the size of each dimension
1972 int nDim
= _wtoi(wsz
);
1978 *pnSize
*= (size_t) nDim
;
1984 wsz
= wcschr(wsz
, L
',');
1987 if ((pwszTypeStart
!= NULL
) && (pwszTypeEnd
!= NULL
))
1989 *pwszTypeStart
= wszTypeStart
;
1990 *pwszTypeEnd
= wszTypeEnd
;
1998 // not a section-5 encoding
2010 inline size_t AtlSoapGetArrayDims(const int *pDims
)
2018 for (int i
=1; i
<=pDims
[0]; i
++)
2028 SOAPFLAG_NONE
= 0x00000000,
2029 SOAPFLAG_IN
= 0x00000001,
2030 SOAPFLAG_OUT
= 0x00000002,
2031 SOAPFLAG_RETVAL
= 0x00000004,
2032 SOAPFLAG_DYNARR
= 0x00000008,
2033 SOAPFLAG_FIXEDARR
= 0x00000010,
2034 SOAPFLAG_MUSTUNDERSTAND
= 0x00000020,
2035 SOAPFLAG_UNKSIZE
= 0x00000040,
2036 SOAPFLAG_READYSTATE
= 0x00000080,
2037 SOAPFLAG_FIELD
= 0x00000100,
2038 SOAPFLAG_NOMARSHAL
= 0x00000200,
2039 SOAPFLAG_NULLABLE
= 0x00000400,
2040 SOAPFLAG_DOCUMENT
= 0x00000800,
2041 SOAPFLAG_RPC
= 0x00001000,
2042 SOAPFLAG_LITERAL
= 0x00002000,
2043 SOAPFLAG_ENCODED
= 0x00004000,
2044 SOAPFLAG_PID
= 0x00008000,
2045 SOAPFLAG_PAD
= 0x00010000,
2046 SOAPFLAG_CHAIN
= 0x00020000,
2047 SOAPFLAG_SIZEIS
= 0x00040000,
2048 SOAPFLAG_DYNARRWRAPPER
= 0x00080000
2064 struct _soapmapentry
2067 const char * szField
;
2068 const WCHAR
* wszField
;
2076 const _soapmap
* pChain
;
2080 ULONG nNamespaceHash
;
2081 const char *szNamespace
;
2082 const wchar_t *wszNamespace
;
2089 const char * szName
;
2090 const wchar_t * wszName
;
2093 SOAPMAPTYPE mapType
;
2094 const _soapmapentry
* pEntries
;
2095 size_t nElementSize
;
2101 ULONG nNamespaceHash
;
2102 const char *szNamespace
;
2103 const wchar_t *wszNamespace
;
2111 SOAPTYPE_STRING
= 0,
2118 SOAPTYPE_BASE64BINARY
,
2125 SOAPTYPE_NORMALIZEDSTRING
,
2135 SOAPTYPE_NONPOSITIVEINTEGER
,
2136 SOAPTYPE_NEGATIVEINTEGER
,
2141 SOAPTYPE_NONNEGATIVEINTEGER
,
2142 SOAPTYPE_UNSIGNEDLONG
,
2143 SOAPTYPE_UNSIGNEDINT
,
2144 SOAPTYPE_UNSIGNEDSHORT
,
2145 SOAPTYPE_UNSIGNEDBYTE
,
2146 SOAPTYPE_POSITIVEINTEGER
,
2151 SOAPTYPE_GYEARMONTH
,
2156 SOAPTYPE_USERBASE
= 0x00001000
2159 inline ULONG
AtlSoapHashStr(const char * sz
)
2164 nHash
= (nHash
<<5)+nHash
+(*sz
);
2171 inline ULONG
AtlSoapHashStr(const wchar_t * sz
)
2176 nHash
= (nHash
<<5)+nHash
+(*sz
);
2183 inline ULONG
AtlSoapHashStr(const char * sz
, int cch
)
2186 for (int i
=0; i
<cch
; i
++)
2188 nHash
= (nHash
<<5)+nHash
+(*sz
);
2195 inline ULONG
AtlSoapHashStr(const wchar_t * sz
, int cch
)
2198 for (int i
=0; i
<cch
; i
++)
2200 nHash
= (nHash
<<5)+nHash
+(*sz
);
2207 inline size_t AtlSoapGetElementSize(SOAPTYPES type
)
2212 case SOAPTYPE_BOOLEAN
:
2213 nRet
= sizeof(bool);
2215 case SOAPTYPE_FLOAT
:
2216 nRet
= sizeof(float);
2218 case SOAPTYPE_DOUBLE
:
2219 case SOAPTYPE_DECIMAL
:
2220 nRet
= sizeof(double);
2222 case SOAPTYPE_HEXBINARY
:
2223 case SOAPTYPE_BASE64BINARY
:
2224 nRet
= sizeof(ATLSOAP_BLOB
);
2226 case SOAPTYPE_INTEGER
:
2227 case SOAPTYPE_NONPOSITIVEINTEGER
:
2228 case SOAPTYPE_NEGATIVEINTEGER
:
2230 nRet
= sizeof(__int64
);
2235 case SOAPTYPE_SHORT
:
2236 nRet
= sizeof(short);
2239 nRet
= sizeof(char);
2241 case SOAPTYPE_POSITIVEINTEGER
:
2242 case SOAPTYPE_NONNEGATIVEINTEGER
:
2243 case SOAPTYPE_UNSIGNEDLONG
:
2244 nRet
= sizeof(unsigned __int64
);
2246 case SOAPTYPE_UNSIGNEDINT
:
2247 nRet
= sizeof(unsigned int);
2249 case SOAPTYPE_UNSIGNEDSHORT
:
2250 nRet
= sizeof(unsigned short);
2252 case SOAPTYPE_UNSIGNEDBYTE
:
2253 nRet
= sizeof(unsigned char);
2256 if ((type
!= SOAPTYPE_ERR
) && (type
!= SOAPTYPE_UNK
) && (type
!= SOAPTYPE_USERBASE
))
2259 nRet
= sizeof(BSTR
);
2263 ATLTRACE( _T("ATLSOAP: AtlSoapGetElementSize -- internal error.\r\n") );
2264 // should never get here
2274 inline HRESULT
AtlSoapGetElementValue(const wchar_t *wsz
, int cch
,
2275 void *pVal
, SOAPTYPES type
, IAtlMemMgr
*pMemMgr
)
2277 HRESULT hr
= E_FAIL
;
2281 case SOAPTYPE_BOOLEAN
:
2282 hr
= AtlGetSAXValue((bool *)pVal
, wsz
, cch
);
2284 case SOAPTYPE_FLOAT
:
2285 hr
= AtlGetSAXValue((float *)pVal
, wsz
, cch
);
2287 case SOAPTYPE_DOUBLE
:
2288 case SOAPTYPE_DECIMAL
:
2289 hr
= AtlGetSAXValue((double *)pVal
, wsz
, cch
);
2291 case SOAPTYPE_HEXBINARY
:
2292 hr
= AtlGetSAXBlobValue((ATLSOAP_BLOB
*)pVal
, wsz
, cch
, pMemMgr
, true);
2294 case SOAPTYPE_BASE64BINARY
:
2295 hr
= AtlGetSAXBlobValue((ATLSOAP_BLOB
*)pVal
, wsz
, cch
, pMemMgr
, false);
2298 case SOAPTYPE_INTEGER
:
2299 case SOAPTYPE_NONPOSITIVEINTEGER
:
2300 case SOAPTYPE_NEGATIVEINTEGER
:
2302 hr
= AtlGetSAXValue((__int64
*)pVal
, wsz
, cch
);
2305 hr
= AtlGetSAXValue((int *)pVal
, wsz
, cch
);
2307 case SOAPTYPE_SHORT
:
2308 hr
= AtlGetSAXValue((short *)pVal
, wsz
, cch
);
2311 hr
= AtlGetSAXValue((char *)pVal
, wsz
, cch
);
2313 case SOAPTYPE_POSITIVEINTEGER
:
2314 case SOAPTYPE_NONNEGATIVEINTEGER
:
2315 case SOAPTYPE_UNSIGNEDLONG
:
2316 hr
= AtlGetSAXValue((unsigned __int64
*)pVal
, wsz
, cch
);
2318 case SOAPTYPE_UNSIGNEDINT
:
2319 hr
= AtlGetSAXValue((unsigned int *)pVal
, wsz
, cch
);
2321 case SOAPTYPE_UNSIGNEDSHORT
:
2322 hr
= AtlGetSAXValue((unsigned short *)pVal
, wsz
, cch
);
2324 case SOAPTYPE_UNSIGNEDBYTE
:
2325 hr
= AtlGetSAXValue((unsigned char *)pVal
, wsz
, cch
);
2328 if ((type
!= SOAPTYPE_ERR
) && (type
!= SOAPTYPE_UNK
) && (type
!= SOAPTYPE_USERBASE
))
2330 hr
= AtlGetSAXValue((BSTR
*)pVal
, wsz
, cch
);
2335 ATLTRACE( _T("ATLSOAP: AtlSoapGetElementValue -- internal error.\r\n") );
2337 // should never get here
2347 inline HRESULT
AtlSoapGenElementValue(void *pVal
, IWriteStream
*pStream
, SOAPTYPES type
, IAtlMemMgr
*pMemMgr
)
2349 HRESULT hr
= E_FAIL
;
2353 case SOAPTYPE_BOOLEAN
:
2354 hr
= AtlGenXMLValue(pStream
, (bool *)pVal
);
2356 case SOAPTYPE_FLOAT
:
2357 hr
= AtlGenXMLValue(pStream
, (float *)pVal
);
2359 case SOAPTYPE_DOUBLE
:
2360 case SOAPTYPE_DECIMAL
:
2361 hr
= AtlGenXMLValue(pStream
, (double *)pVal
);
2363 case SOAPTYPE_HEXBINARY
:
2364 hr
= AtlGenXMLBlobValue(pStream
, (ATLSOAP_BLOB
*)pVal
, pMemMgr
, true);
2366 case SOAPTYPE_BASE64BINARY
:
2367 hr
= AtlGenXMLBlobValue(pStream
, (ATLSOAP_BLOB
*)pVal
, pMemMgr
, false);
2370 case SOAPTYPE_INTEGER
:
2371 case SOAPTYPE_NONPOSITIVEINTEGER
:
2372 case SOAPTYPE_NEGATIVEINTEGER
:
2374 hr
= AtlGenXMLValue(pStream
, (__int64
*)pVal
);
2377 hr
= AtlGenXMLValue(pStream
, (int *)pVal
);
2379 case SOAPTYPE_SHORT
:
2380 hr
= AtlGenXMLValue(pStream
, (short *)pVal
);
2383 hr
= AtlGenXMLValue(pStream
, (char *)pVal
);
2385 case SOAPTYPE_POSITIVEINTEGER
:
2386 case SOAPTYPE_NONNEGATIVEINTEGER
:
2387 case SOAPTYPE_UNSIGNEDLONG
:
2388 hr
= AtlGenXMLValue(pStream
, (unsigned __int64
*)pVal
);
2390 case SOAPTYPE_UNSIGNEDINT
:
2391 hr
= AtlGenXMLValue(pStream
, (unsigned int *)pVal
);
2393 case SOAPTYPE_UNSIGNEDSHORT
:
2394 hr
= AtlGenXMLValue(pStream
, (unsigned short *)pVal
);
2396 case SOAPTYPE_UNSIGNEDBYTE
:
2397 hr
= AtlGenXMLValue(pStream
, (unsigned char *)pVal
);
2400 if ((type
!= SOAPTYPE_ERR
) && (type
!= SOAPTYPE_UNK
) && (type
!= SOAPTYPE_USERBASE
))
2402 hr
= AtlGenXMLValue(pStream
, (BSTR
*)pVal
);
2407 ATLTRACE( _T("ATLSOAP: AtlSoapGenElementValue -- internal error.\r\n" ) );
2409 // should never get here
2418 inline HRESULT
AtlSoapCleanupElement(void *pVal
, SOAPTYPES type
, IAtlMemMgr
*pMemMgr
)
2424 case SOAPTYPE_BOOLEAN
:
2425 case SOAPTYPE_FLOAT
:
2426 case SOAPTYPE_DOUBLE
:
2427 case SOAPTYPE_DECIMAL
:
2429 case SOAPTYPE_INTEGER
:
2430 case SOAPTYPE_NONPOSITIVEINTEGER
:
2431 case SOAPTYPE_NEGATIVEINTEGER
:
2433 case SOAPTYPE_SHORT
:
2435 case SOAPTYPE_POSITIVEINTEGER
:
2436 case SOAPTYPE_NONNEGATIVEINTEGER
:
2437 case SOAPTYPE_UNSIGNEDLONG
:
2438 case SOAPTYPE_UNSIGNEDINT
:
2439 case SOAPTYPE_UNSIGNEDSHORT
:
2440 case SOAPTYPE_UNSIGNEDBYTE
:
2443 case SOAPTYPE_HEXBINARY
:
2444 case SOAPTYPE_BASE64BINARY
:
2445 hr
= AtlCleanupBlobValue((ATLSOAP_BLOB
*)pVal
, pMemMgr
);
2449 if ((type
!= SOAPTYPE_ERR
) && (type
!= SOAPTYPE_UNK
) && (type
!= SOAPTYPE_USERBASE
))
2452 hr
= AtlCleanupValue((BSTR
*)pVal
);
2457 ATLTRACE( _T("ATLSOAP: AtlSoapCleanupElement -- internal error.\r\n" ) );
2459 // should never get here
2469 ////////////////////////////////////////////////////////////////////////////////
2471 // END PRIVATE DEFINITIONS
2473 ////////////////////////////////////////////////////////////////////////////////
2475 #define SOAP_ENVELOPEA "Envelope"
2476 #define SOAP_ENVELOPEW ATLSOAP_MAKEWIDESTR( SOAP_ENVELOPEA )
2478 #define SOAP_HEADERA "Header"
2479 #define SOAP_HEADERW ATLSOAP_MAKEWIDESTR( SOAP_HEADERA )
2481 #define SOAP_BODYA "Body"
2482 #define SOAP_BODYW ATLSOAP_MAKEWIDESTR( SOAP_BODYA )
2485 #pragma pack(push,_ATL_PACKING)
2490 // SOAP fault helpers
2493 enum SOAP_ERROR_CODE
2496 SOAP_E_VERSION_MISMATCH
=100,
2497 SOAP_E_MUST_UNDERSTAND
=200,
2502 // forward declaration of CSoapFault
2505 class CSoapFaultParser
: public ISAXContentHandlerImpl
2509 CSoapFault
*m_pFault
;
2513 const static DWORD STATE_ERROR
= 0;
2514 const static DWORD STATE_ENVELOPE
= 1;
2515 const static DWORD STATE_BODY
= 2;
2516 const static DWORD STATE_START
= 4;
2517 const static DWORD STATE_FAULTCODE
= 8;
2518 const static DWORD STATE_FAULTSTRING
= 16;
2519 const static DWORD STATE_FAULTACTOR
= 32;
2520 const static DWORD STATE_DETAIL
= 64;
2521 const static DWORD STATE_RESET
= 128;
2522 const static DWORD STATE_SKIP
= 256;
2525 CComPtr
<ISAXXMLReader
> m_spReader
;
2526 CSAXStringBuilder m_stringBuilder
;
2527 CSkipHandler m_skipHandler
;
2529 const wchar_t *m_wszSoapPrefix
;
2530 int m_cchSoapPrefix
;
2533 virtual ~CSoapFaultParser()
2535 m_skipHandler
.DetachParent();
2538 // IUnknown interface
2539 HRESULT __stdcall
QueryInterface(REFIID riid
, void **ppv
)
2548 if (InlineIsEqualGUID(riid
, IID_IUnknown
) ||
2549 InlineIsEqualGUID(riid
, IID_ISAXContentHandler
))
2551 *ppv
= static_cast<ISAXContentHandler
*>(this);
2555 return E_NOINTERFACE
;
2558 ULONG __stdcall
AddRef()
2563 ULONG __stdcall
Release()
2570 CSoapFaultParser(CSoapFault
*pFault
, ISAXXMLReader
*pReader
)
2571 :m_pFault(pFault
), m_dwState(STATE_ERROR
), m_spReader(pReader
)
2573 ATLASSERT( pFault
!= NULL
);
2574 ATLASSERT( pReader
!= NULL
);
2577 // ISAXContentHandler interface
2578 HRESULT __stdcall
startElement(
2579 const wchar_t * wszNamespaceUri
,
2580 int cchNamespaceUri
,
2581 const wchar_t * wszLocalName
,
2583 const wchar_t * /*wszQName*/,
2585 ISAXAttributes
* /*pAttributes*/)
2589 const wchar_t *wszTag
;
2594 const static _faultmap s_faultParseMap
[] =
2596 { L
"Envelope", sizeof("Envelope")-1, CSoapFaultParser::STATE_ENVELOPE
},
2597 { L
"Body", sizeof("Body")-1, CSoapFaultParser::STATE_BODY
},
2598 { L
"Header", sizeof("Header")-1, CSoapFaultParser::STATE_BODY
},
2599 { L
"Fault", sizeof("Fault")-1, CSoapFaultParser::STATE_START
},
2600 { L
"faultcode", sizeof("faultcode")-1, CSoapFaultParser::STATE_FAULTCODE
},
2601 { L
"faultstring", sizeof("faultstring")-1, CSoapFaultParser::STATE_FAULTSTRING
},
2602 { L
"faultactor", sizeof("faultactor")-1, CSoapFaultParser::STATE_FAULTACTOR
},
2603 { L
"detail", sizeof("detail")-1, CSoapFaultParser::STATE_DETAIL
}
2606 if (m_spReader
.p
== NULL
)
2608 ATLTRACE( _T("ATLSOAP: CSoapFaultParser::startElement -- ISAXXMLReader is NULL.\r\n" ) );
2610 return E_INVALIDARG
;
2613 m_dwState
&= ~STATE_RESET
;
2614 for (int i
=0; i
<(sizeof(s_faultParseMap
)/sizeof(s_faultParseMap
[0])); i
++)
2616 if ((cchLocalName
== s_faultParseMap
[i
].cchTag
) &&
2617 (!wcsncmp(wszLocalName
, s_faultParseMap
[i
].wszTag
, cchLocalName
)))
2619 DWORD dwState
= s_faultParseMap
[i
].dwState
;
2620 if ((dwState
& (STATE_START
| STATE_ENVELOPE
| STATE_BODY
)) == 0)
2622 m_stringBuilder
.SetReader(m_spReader
);
2623 m_stringBuilder
.SetParent(this);
2625 m_stringBuilder
.Clear();
2626 m_spReader
->putContentHandler( &m_stringBuilder
);
2630 if ((dwState
<= m_dwState
) ||
2631 (cchNamespaceUri
!= sizeof(SOAPENV_NAMESPACEA
)-1) ||
2632 (wcsncmp(wszNamespaceUri
, SOAPENV_NAMESPACEW
, cchNamespaceUri
)))
2634 ATLTRACE( _T("ATLSOAP: CSoapFaultParser::startElement -- malformed SOAP fault.\r\n" ) );
2640 m_dwState
= dwState
;
2644 if (m_dwState
> STATE_START
)
2646 m_dwState
= STATE_SKIP
;
2647 m_skipHandler
.SetReader(m_spReader
);
2648 m_skipHandler
.SetParent(this);
2650 m_spReader
->putContentHandler( &m_skipHandler
);
2654 ATLTRACE( _T("ATLSOAP: CSoapFaultParser::startElement -- malformed SOAP fault.\r\n" ) );
2659 HRESULT __stdcall
startPrefixMapping(
2660 const wchar_t * wszPrefix
,
2662 const wchar_t * wszUri
,
2665 if ((cchUri
== sizeof(SOAPENV_NAMESPACEA
)-1) &&
2666 (!wcsncmp(wszUri
, SOAPENV_NAMESPACEW
, cchUri
)))
2668 m_wszSoapPrefix
= wszPrefix
;
2669 m_cchSoapPrefix
= cchPrefix
;
2675 HRESULT __stdcall
characters(
2676 const wchar_t * wszChars
,
2680 extern __declspec(selectany
) const int ATLS_SOAPFAULT_CNT
= 4;
2690 const wchar_t *wszFaultString
;
2692 SOAP_ERROR_CODE errCode
;
2695 static const _faultcode s_faultCodes
[];
2700 SOAP_ERROR_CODE m_soapErrCode
;
2701 CStringW m_strFaultCode
;
2702 CStringW m_strFaultString
;
2703 CStringW m_strFaultActor
;
2704 CStringW m_strDetail
;
2707 : m_soapErrCode(SOAP_E_UNK
)
2711 HRESULT
SetErrorCode(
2713 const wchar_t *wszSoapPrefix
,
2715 int cchSoapPrefix
= -1,
2716 bool bSetFaultString
= true)
2718 if ((wsz
== NULL
) || (wszSoapPrefix
== NULL
))
2720 return E_INVALIDARG
;
2725 cch
= (int) wcslen(wsz
);
2728 while (*wsz
&& iswspace(*wsz
))
2734 if (cchSoapPrefix
== -1)
2736 cchSoapPrefix
= (int) wcslen(wszSoapPrefix
);
2739 const wchar_t *wszLocalName
= wcschr(wsz
, L
':');
2740 if (wszLocalName
== NULL
)
2742 // faultCode must be QName
2744 ATLTRACE( _T("ATLSOAP: CSoapFault::SetErrorCode -- faultCode is not a QName.\r\n" ) );
2749 // make sure the namespace of the fault is the
2750 // SOAPENV namespace
2751 if ((cchSoapPrefix
!= (int)(wszLocalName
-wsz
)) ||
2752 (wcsncmp(wsz
, wszSoapPrefix
, cchSoapPrefix
)))
2754 ATLTRACE( _T("ATLSOAP: CSoapFault::SetErrorCode -- fault namespace is incorrect.\r\n" ) );
2760 cch
-= (int) (wszLocalName
-wsz
);
2764 for (int i
=0; i
<ATLS_SOAPFAULT_CNT
; i
++)
2766 if ((cch
== s_faultCodes
[i
].cch
) &&
2767 (!wcsncmp(wszLocalName
, s_faultCodes
[i
].wsz
, cch
)))
2769 m_soapErrCode
= s_faultCodes
[i
].errCode
;
2770 if (bSetFaultString
!= false)
2772 m_strFaultString
.SetString(s_faultCodes
[i
].wszFaultString
, s_faultCodes
[i
].cchFaultString
);
2777 if (m_strFaultString
.GetLength() == 0)
2779 m_strFaultCode
.SetString(wszLocalName
, cch
);
2784 ATLTRACE( _T("ATLSOAP: CSoapFault::SetErrorCode -- out of memory.\r\n" ) );
2786 return E_OUTOFMEMORY
;
2792 HRESULT
ParseFault(IStream
*pStream
, ISAXXMLReader
*pReader
= NULL
)
2794 if (pStream
== NULL
)
2796 ATLTRACE( _T("ATLSOAP: CSoapFault::ParseFault -- NULL IStream was passed.\r\n" ) );
2798 return E_INVALIDARG
;
2801 CComPtr
<ISAXXMLReader
> spReader
;
2802 if (pReader
!= NULL
)
2808 if (FAILED(spReader
.CoCreateInstance(ATLS_SAXXMLREADER_CLSID
, NULL
, CLSCTX_INPROC_SERVER
)))
2810 ATLTRACE( _T("ATLSOAP: CSoapFault::ParseFault -- CoCreateInstance of SAXXMLReader failed.\r\n" ) );
2817 CSoapFaultParser
parser(const_cast<CSoapFault
*>(this), spReader
);
2818 spReader
->putContentHandler(&parser
);
2820 CComVariant varStream
;
2821 varStream
= static_cast<IUnknown
*>(pStream
);
2823 HRESULT hr
= spReader
->parse(varStream
);
2824 spReader
->putContentHandler(NULL
);
2828 HRESULT
GenerateFault(IWriteStream
*pWriteStream
)
2830 if ((pWriteStream
== NULL
) || (m_soapErrCode
== SOAP_E_UNK
))
2832 return E_INVALIDARG
;
2835 ATLASSERT( (m_soapErrCode
== SOAP_E_UNK
) ||
2836 (m_soapErrCode
== SOAP_E_VERSION_MISMATCH
) ||
2837 (m_soapErrCode
== SOAP_E_MUST_UNDERSTAND
) ||
2838 (m_soapErrCode
== SOAP_E_CLIENT
) ||
2839 (m_soapErrCode
== SOAP_E_SERVER
) );
2844 const wchar_t *wszFaultCode
= NULL
;
2845 if (m_strFaultCode
.GetLength() == 0)
2847 for (int i
=0; i
<4; i
++)
2849 if (s_faultCodes
[i
].errCode
== m_soapErrCode
)
2851 if (m_strFaultString
.GetLength() == 0)
2853 m_strFaultString
.SetString(s_faultCodes
[i
].wszFaultString
,
2854 s_faultCodes
[i
].cchFaultString
);
2857 wszFaultCode
= s_faultCodes
[i
].wsz
;
2863 if (wszFaultCode
== NULL
)
2865 if (m_strFaultCode
.GetLength() != 0)
2867 wszFaultCode
= m_strFaultCode
;
2871 ATLTRACE( _T("CSoapFault::GenerateFault -- missing/invalid fault code.\r\n") );
2876 const LPCSTR s_szErrorFormat
=
2877 "<SOAP:Envelope xmlns:SOAP=\"" SOAPENV_NAMESPACEA
"\">"
2880 "<faultcode>SOAP:%ws</faultcode>"
2881 "<faultstring>%ws</faultstring>"
2883 "<detail>%ws</detail>"
2889 strFault
.Format(s_szErrorFormat
, wszFaultCode
, m_strFaultString
,
2890 m_strFaultActor
.GetLength() ? "<faultactor>" : "", m_strFaultActor
,
2891 m_strFaultActor
.GetLength() ? "</faultactor>" : "",
2894 hr
= pWriteStream
->WriteStream(strFault
, strFault
.GetLength(), NULL
);
2898 ATLTRACE( _T("ATLSOAP: CSoapFault::GenerateFault -- out of memory.\r\n" ) );
2907 m_soapErrCode
= SOAP_E_UNK
;
2908 m_strFaultCode
.Empty();
2909 m_strFaultString
.Empty();
2910 m_strFaultActor
.Empty();
2911 m_strDetail
.Empty();
2913 }; // class CSoapFault
2915 #define DECLARE_SOAP_FAULT(__name, __faultstring, __errcode) \
2916 { L ## __name, sizeof(__name)-1, L ## __faultstring, sizeof(__faultstring), __errcode },
2918 __declspec(selectany
) const CSoapFault::_faultcode
CSoapFault::s_faultCodes
[] =
2920 DECLARE_SOAP_FAULT("VersionMismatch", "SOAP Version Mismatch Error", SOAP_E_VERSION_MISMATCH
)
2921 DECLARE_SOAP_FAULT("MustUnderstand", "SOAP Must Understand Error", SOAP_E_MUST_UNDERSTAND
)
2922 DECLARE_SOAP_FAULT("Client", "SOAP Invalid Request", SOAP_E_CLIENT
)
2923 DECLARE_SOAP_FAULT("Server", "SOAP Server Application Faulted", SOAP_E_SERVER
)
2926 ATL_NOINLINE
inline HRESULT __stdcall
CSoapFaultParser::characters(
2927 const wchar_t * wszChars
,
2930 if (m_pFault
== NULL
)
2932 return E_INVALIDARG
;
2935 if (m_dwState
& STATE_RESET
)
2940 HRESULT hr
= E_FAIL
;
2945 case STATE_FAULTCODE
:
2946 if (m_pFault
->m_soapErrCode
== SOAP_E_UNK
)
2948 hr
= m_pFault
->SetErrorCode(wszChars
, m_wszSoapPrefix
,
2949 cchChars
, m_cchSoapPrefix
, false);
2952 case STATE_FAULTSTRING
:
2953 if (m_pFault
->m_strFaultString
.GetLength() == 0)
2955 m_pFault
->m_strFaultString
.SetString(wszChars
, cchChars
);
2959 case STATE_FAULTACTOR
:
2960 if (m_pFault
->m_strFaultActor
.GetLength() == 0)
2962 m_pFault
->m_strFaultActor
.SetString(wszChars
, cchChars
);
2967 if (m_pFault
->m_strDetail
.GetLength() == 0)
2969 m_pFault
->m_strDetail
.SetString(wszChars
, cchChars
);
2973 case STATE_START
: case STATE_ENVELOPE
: case STATE_BODY
: case STATE_SKIP
:
2977 // should never get here
2984 ATLTRACE( _T("ATLSOAP: CSoapFaultParser::characters -- out of memory.\r\n" ) );
2989 m_dwState
|= STATE_RESET
;
2994 ////////////////////////////////////////////////////////////////////////////////
2996 // CSoapRootHandler - the class that does most of the work
2998 ////////////////////////////////////////////////////////////////////////////////
3000 #ifndef ATLSOAP_STACKSIZE
3001 // 16 will be plenty for the 99% case
3002 #define ATLSOAP_STACKSIZE 16
3005 #ifndef ATLSOAP_GROWARRAY
3006 #define ATLSOAP_GROWARRAY 10
3009 class CSoapRootHandler
: public ISAXContentHandlerImpl
3013 friend class _CSDLGenerator
;
3018 const static DWORD SOAP_START
= 0;
3019 const static DWORD SOAP_ENVELOPE
= 1;
3020 const static DWORD SOAP_HEADERS
= 2;
3021 const static DWORD SOAP_BODY
= 3;
3022 const static DWORD SOAP_PARAMS
= 4;
3023 const static DWORD SOAP_CALLED
= 5;
3024 const static DWORD SOAP_RESPONSE
= 6;
3025 const static DWORD SOAP_HEADERS_DONE
= 7;
3028 // hash values for SOAP namespaces and elements
3030 const static ULONG SOAP_ENV
= 0x5D3574E2;
3031 const static ULONG SOAP_ENC
= 0xBD62724B;
3032 const static ULONG ENVELOPE
= 0xDBE6009E;
3033 const static ULONG HEADER
= 0xAF4DFFC9;
3034 const static ULONG BODY
= 0x0026168E;
3046 const static XSDEntry s_xsdNames
[];
3049 // CBitVector - a dynamically sized bit vector class
3055 // 64 bits will handle the 99% case
3056 unsigned __int64 m_nBits
;
3058 // when we need to grow
3059 unsigned __int64
* m_pBits
;
3063 bool Grow(size_t nIndex
)
3066 // In our current implementation, CHAR_BIT==8, and sizeof(m_nBits)==8. Easy to confuse the two.
3068 // We do math in bits, so this is our max size
3069 ATLENSURE(nIndex
<SIZE_MAX
/((sizeof(m_nBits
)*CHAR_BIT
)));
3071 // round up to nearest 64 bits
3072 size_t nAllocSizeBits
= nIndex
+((sizeof(m_nBits
)*CHAR_BIT
)-(nIndex
%(sizeof(m_nBits
)*CHAR_BIT
)));
3073 size_t nAllocSizeBytes
= nAllocSizeBits
/CHAR_BIT
;
3075 if (m_pBits
!= &m_nBits
)
3077 unsigned __int64
* pNewBits
=NULL
;
3078 pNewBits
= (unsigned __int64
*) realloc(m_pBits
, nAllocSizeBytes
);
3087 m_pBits
= (unsigned __int64
*) malloc(nAllocSizeBytes
);
3088 if (m_pBits
!= NULL
)
3090 Checked::memcpy_s(m_pBits
, nAllocSizeBytes
, &m_nBits
, sizeof(m_nBits
));
3094 if (m_pBits
!= NULL
)
3096 // set new bits to 0
3097 memset(m_pBits
+(m_nSize
/(CHAR_BIT
*sizeof(m_nBits
))), 0x00, (nAllocSizeBits
-m_nSize
)/CHAR_BIT
);
3098 m_nSize
= nAllocSizeBits
;
3102 ATLTRACE( _T("ATLSOAP: CBitVector::Grow -- out of memory.\r\n" ) );
3110 : m_nBits(0), m_nSize(sizeof(m_nBits
)*CHAR_BIT
)
3115 CBitVector(const CBitVector
&)
3120 const CBitVector
& operator=(const CBitVector
& that
)
3130 bool GetBit(size_t nIndex
) const
3132 if (nIndex
>= m_nSize
)
3137 size_t i
= nIndex
/(sizeof(m_nBits
)*CHAR_BIT
);
3138 size_t nBits
= nIndex
-i
*(sizeof(m_nBits
)*CHAR_BIT
);
3139 return ((m_pBits
[i
] >> nBits
) & 0x01);
3142 bool SetBit(size_t nIndex
)
3144 if (nIndex
>= m_nSize
)
3152 size_t i
= nIndex
/(sizeof(m_nBits
)*CHAR_BIT
);
3153 size_t nBits
= nIndex
-i
*(sizeof(m_nBits
)*CHAR_BIT
);
3154 m_pBits
[i
] |= (((unsigned __int64
) 1) << nBits
);
3161 if (m_pBits
== &m_nBits
)
3167 memset(m_pBits
, 0x00, (m_nSize
/CHAR_BIT
));
3173 if (m_pBits
!= &m_nBits
)
3179 m_nSize
= sizeof(m_nBits
)*CHAR_BIT
;
3182 void RelocateFixup()
3184 if (m_nSize
<= sizeof(m_nBits
)*CHAR_BIT
)
3189 }; // class CBitVector
3199 size_t nExpectedElements
;
3201 const _soapmap
*pMap
;
3202 const _soapmapentry
*pEntry
;
3204 // mark when we get an item
3209 ParseState(void *pvElement_
= NULL
, DWORD dwFlags_
= 0,
3210 size_t nAllocSize_
= 0, size_t nExpectedElements_
= 0,
3211 size_t nElement_
= 0, const _soapmap
*pMap_
= NULL
,
3212 const _soapmapentry
*pEntry_
= NULL
)
3213 : pvElement(pvElement_
), dwFlags(dwFlags_
), nAllocSize(nAllocSize_
),
3214 nExpectedElements(nExpectedElements_
), nElement(nElement_
), pMap(pMap_
),
3215 pEntry(pEntry_
), nDepth(0)
3220 ParseState(const ParseState
& that
)
3222 pvElement
= that
.pvElement
;
3223 dwFlags
= that
.dwFlags
;
3224 nAllocSize
= that
.nAllocSize
;
3225 nExpectedElements
= that
.nExpectedElements
;
3226 nElement
= that
.nElement
;
3228 pEntry
= that
.pEntry
;
3229 nDepth
= that
.nDepth
;
3238 nExpectedElements
= 0;
3246 void RelocateFixup()
3248 vec
.RelocateFixup();
3250 }; // struct ParseState
3252 class CParseStateElementTraits
: public CDefaultElementTraits
<ParseState
>
3255 // CBitVector relocate fixup
3256 static void RelocateElements( ParseState
* pDest
, ParseState
* pSrc
, size_t nElements
)
3258 CDefaultElementTraits
<ParseState
>::RelocateElements(pDest
, pSrc
, nElements
);
3261 for (size_t i
=0; i
<nElements
; i
++)
3263 pDest
[i
].RelocateFixup();
3268 class CResponseGenerator
3271 HRESULT
StartEnvelope(IWriteStream
*pStream
)
3273 ATLENSURE_RETURN( pStream
!= NULL
);
3275 return pStream
->WriteStream("<soap:Envelope "
3276 "xmlns:soap=\"" SOAPENV_NAMESPACEA
"\" "
3277 "xmlns:xsi=\"" XSI_NAMESPACEA
"\" "
3278 "xmlns:xsd=\"" XSD_NAMESPACEA
"\" "
3279 "xmlns:soapenc=\"" SOAPENC_NAMESPACEA
"\">",
3281 sizeof("<soap:Envelope "
3282 "xmlns:soap=\"" SOAPENV_NAMESPACEA
"\" "
3283 "xmlns:xsi=\"" XSI_NAMESPACEA
"\" "
3284 "xmlns:xsd=\"" XSD_NAMESPACEA
"\" "
3285 "xmlns:soapenc=\"" SOAPENC_NAMESPACEA
"\">")-1,
3290 HRESULT
StartHeaders(IWriteStream
*pStream
, const _soapmap
*pMap
)
3292 ATLENSURE_RETURN( pStream
!= NULL
);
3293 ATLENSURE_RETURN( pMap
!= NULL
);
3295 HRESULT hr
= pStream
->WriteStream("<soap:Header", sizeof("<soap:Header")-1, NULL
);
3298 if ((pMap
->dwCallFlags
& (SOAPFLAG_RPC
| SOAPFLAG_ENCODED
)) !=
3299 (SOAPFLAG_RPC
| SOAPFLAG_ENCODED
))
3301 // qualify document/literal by default
3302 // For this version, ATL Server will not respect
3303 // the elementForm* attributes in an XSD schema
3305 hr
= pStream
->WriteStream(" xmlns=\"", sizeof(" xmlns=\"")-1, NULL
);
3308 hr
= pStream
->WriteStream(pMap
->szNamespace
, pMap
->cchNamespace
, NULL
);
3311 hr
= pStream
->WriteStream("\">", sizeof("\">")-1, NULL
);
3318 hr
= pStream
->WriteStream(">", sizeof(">")-1, NULL
);
3324 HRESULT
EndHeaders(IWriteStream
*pStream
)
3326 ATLENSURE_RETURN( pStream
!= NULL
);
3328 return pStream
->WriteStream("</soap:Header>", sizeof("</soap:Header>")-1, NULL
);
3331 virtual HRESULT
StartBody(IWriteStream
*pStream
)
3333 ATLENSURE_RETURN( pStream
!= NULL
);
3335 return pStream
->WriteStream(
3336 "<soap:Body>", sizeof("<soap:Body>")-1, NULL
);
3339 HRESULT
EndBody(IWriteStream
*pStream
)
3341 ATLENSURE_RETURN( pStream
!= NULL
);
3343 return pStream
->WriteStream("</soap:Body>", sizeof("</soap:Body>")-1, NULL
);
3346 HRESULT
EndEnvelope(IWriteStream
*pStream
)
3348 ATLENSURE_RETURN( pStream
!= NULL
);
3350 return pStream
->WriteStream("</soap:Envelope>", sizeof("</soap:Envelope>")-1, NULL
);
3353 virtual HRESULT
StartMap(IWriteStream
*pStream
, const _soapmap
*pMap
, bool bClient
) = 0;
3354 virtual HRESULT
EndMap(IWriteStream
*pStream
, const _soapmap
*pMap
, bool bClient
) = 0;
3356 virtual HRESULT
StartEntry(IWriteStream
*pStream
, const _soapmap
*pMap
, const _soapmapentry
*pEntry
)
3358 ATLENSURE_RETURN( pStream
!= NULL
);
3359 ATLENSURE_RETURN( pEntry
!= NULL
);
3362 HRESULT hr
= pStream
->WriteStream("<", 1, NULL
);
3365 const char *szHeaderNamespace
= NULL
;
3366 int cchHeaderNamespace
= 0;
3368 if ((pMap
!= NULL
) && (pMap
->mapType
== SOAPMAP_HEADER
) &&
3369 ((pEntry
->pChain
!= NULL
) &&
3370 (pEntry
->pChain
->szNamespace
!=NULL
)) ||
3371 (pEntry
->szNamespace
!= NULL
))
3373 hr
= pStream
->WriteStream("snp:", sizeof("snp:")-1, NULL
);
3376 szHeaderNamespace
= pEntry
->pChain
?
3377 pEntry
->pChain
->szNamespace
: pEntry
->szNamespace
;
3379 cchHeaderNamespace
= pEntry
->pChain
?
3380 pEntry
->pChain
->cchNamespace
: pEntry
->cchNamespace
;
3386 if ((pEntry
->dwFlags
& SOAPFLAG_RETVAL
)==0)
3388 hr
= pStream
->WriteStream(pEntry
->szField
, pEntry
->cchField
, NULL
);
3392 hr
= pStream
->WriteStream("return", sizeof("return")-1, NULL
);
3396 if (szHeaderNamespace
!= NULL
)
3398 ATLASSERT( cchHeaderNamespace
!= 0 );
3400 hr
= pStream
->WriteStream(" xmlns:snp=\"", sizeof(" xmlns:snp=\"")-1, NULL
);
3403 hr
= pStream
->WriteStream(szHeaderNamespace
, cchHeaderNamespace
, NULL
);
3406 hr
= pStream
->WriteStream("\"", sizeof("\"")-1, NULL
);
3415 if (pEntry
->dwFlags
& SOAPFLAG_MUSTUNDERSTAND
)
3417 // output mustUnderstand
3418 hr
= pStream
->WriteStream(" soap:mustUnderstand=\"1\"", sizeof(" soap:mustUnderstand=\"1\"")-1, NULL
);
3424 HRESULT
EndEntry(IWriteStream
*pStream
, const _soapmap
*pMap
, const _soapmapentry
*pEntry
)
3426 ATLENSURE_RETURN( pStream
!= NULL
);
3427 ATLENSURE_RETURN( pEntry
!= NULL
);
3429 HRESULT hr
= pStream
->WriteStream("</", 2, NULL
);
3432 if ((pMap
!= NULL
) &&
3433 (pMap
->mapType
== SOAPMAP_HEADER
) &&
3434 ((pEntry
->pChain
!= NULL
) &&
3435 (pEntry
->pChain
->szNamespace
!=NULL
)) ||
3436 (pEntry
->szNamespace
!= NULL
))
3438 hr
= pStream
->WriteStream("snp:", sizeof("snp:")-1, NULL
);
3440 if ((pEntry
->dwFlags
& SOAPFLAG_RETVAL
)==0)
3442 hr
= pStream
->WriteStream(pEntry
->szField
, pEntry
->cchField
, NULL
);
3446 hr
= pStream
->WriteStream("return", sizeof("return")-1, NULL
);
3450 hr
= pStream
->WriteStream(">", 1, NULL
);
3455 }; // class CResponseGenerator
3457 class CDocLiteralGenerator
: public CResponseGenerator
3461 HRESULT
StartMap(IWriteStream
*pStream
, const _soapmap
*pMap
, bool bClient
)
3463 ATLENSURE_RETURN( pStream
!= NULL
);
3464 ATLENSURE_RETURN( pMap
!= NULL
);
3468 hr
= pStream
->WriteStream("<", 1, NULL
);
3471 hr
= pStream
->WriteStream(pMap
->szName
, pMap
->cchName
, NULL
);
3474 if ((pMap
->mapType
== SOAPMAP_FUNC
) &&
3475 (bClient
== false) &&
3476 (pMap
->dwCallFlags
& SOAPFLAG_PID
))
3478 hr
= pStream
->WriteStream("Response", sizeof("Response")-1, NULL
);
3485 if (pMap
->mapType
== SOAPMAP_FUNC
)
3487 hr
= pStream
->WriteStream(" xmlns=\"", sizeof(" xmlns=\"")-1, NULL
);
3490 hr
= pStream
->WriteStream(pMap
->szNamespace
, pMap
->cchNamespace
, NULL
);
3493 hr
= pStream
->WriteStream("\">", sizeof("\">")-1, NULL
);
3499 hr
= pStream
->WriteStream(">", 1, NULL
);
3506 HRESULT
EndMap(IWriteStream
*pStream
, const _soapmap
*pMap
, bool bClient
)
3508 ATLENSURE_RETURN( pStream
!= NULL
);
3509 ATLENSURE_RETURN( pMap
!= NULL
);
3511 HRESULT hr
= pStream
->WriteStream("</", sizeof("</")-1, NULL
);
3514 hr
= pStream
->WriteStream(pMap
->szName
, pMap
->cchName
, NULL
);
3517 if ((pMap
->mapType
== SOAPMAP_FUNC
) &&
3518 (bClient
== false) &&
3519 (pMap
->dwCallFlags
& SOAPFLAG_PID
))
3521 hr
= pStream
->WriteStream("Response", sizeof("Response")-1, NULL
);
3527 hr
= pStream
->WriteStream(">", 1, NULL
);
3534 }; // class CDocLiteralGenerator
3536 class CPIDGenerator
: public CDocLiteralGenerator
3540 class CPADGenerator
: public CDocLiteralGenerator
3544 virtual HRESULT
StartEntry(IWriteStream
*pStream
, const _soapmap
*pMap
, const _soapmapentry
*pEntry
)
3546 ATLENSURE_RETURN( pStream
!= NULL
);
3547 ATLENSURE_RETURN( pEntry
!= NULL
);
3549 HRESULT hr
= __super::StartEntry(pStream
, pMap
, pEntry
);
3550 if (SUCCEEDED(hr
) && (pMap
->dwCallFlags
& SOAPFLAG_PAD
))
3552 hr
= pStream
->WriteStream(" xmlns=\"", sizeof(" xmlns=\"")-1, NULL
);
3555 hr
= pStream
->WriteStream(pMap
->szNamespace
, pMap
->cchNamespace
, NULL
);
3558 hr
= pStream
->WriteStream("\"", sizeof("\"")-1, NULL
);
3565 }; // class CPADGenerator
3567 class CRpcEncodedGenerator
: public CResponseGenerator
3571 HRESULT
StartBody(IWriteStream
*pStream
)
3573 ATLENSURE_RETURN( pStream
!= NULL
);
3575 return pStream
->WriteStream(
3576 "<soap:Body soap:encodingStyle=\"" SOAPENC_NAMESPACEA
"\">",
3577 sizeof("<soap:Body soap:encodingStyle=\"" SOAPENC_NAMESPACEA
"\">")-1, NULL
);
3580 HRESULT
StartMap(IWriteStream
*pStream
, const _soapmap
*pMap
, bool bClient
)
3582 ATLENSURE_RETURN( pStream
!= NULL
);
3583 ATLENSURE_RETURN( pMap
!= NULL
);
3585 (bClient
); // unused for rpc/encoded
3587 HRESULT hr
= pStream
->WriteStream("<snp:", sizeof("<snp:")-1, NULL
);
3590 hr
= pStream
->WriteStream(pMap
->szName
, pMap
->cchName
, NULL
);
3593 if (pMap
->mapType
== SOAPMAP_FUNC
)
3595 hr
= pStream
->WriteStream(" xmlns:snp=\"", sizeof(" xmlns:snp=\"")-1, NULL
);
3598 ATLASSERT( pMap
->szNamespace
!= NULL
);
3599 hr
= pStream
->WriteStream(pMap
->szNamespace
, pMap
->cchNamespace
, NULL
);
3602 hr
= pStream
->WriteStream("\">", sizeof("\">")-1, NULL
);
3608 hr
= pStream
->WriteStream(">", 1, NULL
);
3615 HRESULT
EndMap(IWriteStream
*pStream
, const _soapmap
*pMap
, bool bClient
)
3617 ATLENSURE_RETURN( pStream
!= NULL
);
3618 ATLENSURE_RETURN( pMap
!= NULL
);
3620 (bClient
); // unused for rpc/encoded
3622 HRESULT hr
= pStream
->WriteStream("</snp:", sizeof("</snp:")-1, NULL
);
3625 hr
= pStream
->WriteStream(pMap
->szName
, pMap
->cchName
, NULL
);
3628 hr
= pStream
->WriteStream(">", 1, NULL
);
3634 }; // class CRpcEncodedGenerator
3639 CAtlArray
<ParseState
, CParseStateElementTraits
> m_stateStack
;
3644 CComPtr
<ISAXXMLReader
> m_spReader
;
3646 CSAXStringBuilder m_stringBuilder
;
3647 CSkipHandler m_skipHandler
;
3649 IAtlMemMgr
* m_pMemMgr
;
3651 static CCRTHeap m_crtHeap
;
3662 typedef CFixedStringT
<CStringW
, 16> REFSTRING
;
3664 // used for rpc/encoded messages with href's
3665 typedef CAtlMap
<REFSTRING
, ParseState
, CStringRefElementTraits
<REFSTRING
> > REFMAP
;
3669 // Implementation helpers
3672 HRESULT
PushState(void *pvElement
= NULL
, const _soapmap
*pMap
= NULL
,
3673 const _soapmapentry
*pEntry
= NULL
, DWORD dwFlags
= 0, size_t nAllocSize
= 0,
3674 size_t nExpectedElements
= 0, size_t nElement
= 0)
3676 if (m_stateStack
.IsEmpty())
3678 // 16 will be plenty for the 99% case
3679 if (!m_stateStack
.SetCount(0, 16))
3681 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::PushState -- out of memory.\r\n" ) );
3683 return E_OUTOFMEMORY
;
3687 size_t nCnt
= m_stateStack
.GetCount();
3688 m_nState
= m_stateStack
.Add();
3689 if (m_stateStack
.GetCount() <= nCnt
)
3691 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::PushState -- out of memory.\r\n" ) );
3693 return E_OUTOFMEMORY
;
3696 ParseState
&state
= m_stateStack
[m_nState
];
3698 state
.pvElement
= pvElement
;
3699 state
.dwFlags
= dwFlags
;
3700 state
.nAllocSize
= nAllocSize
;
3701 state
.nExpectedElements
= nExpectedElements
;
3702 state
.nElement
= nElement
;
3704 state
.pEntry
= pEntry
;
3705 state
.nDepth
= m_nDepth
;
3710 ParseState
& GetState()
3712 return m_stateStack
[m_nState
];
3715 void PopState(bool bForce
= false)
3717 if ((m_nState
!= 0) || (bForce
!= false))
3719 m_stateStack
.RemoveAt(m_nState
);
3724 BOOL
IsEqualElement(int cchLocalNameCheck
, const wchar_t *wszLocalNameCheck
,
3725 int cchNamespaceUriCheck
, const wchar_t *wszNamespaceUriCheck
,
3726 int cchLocalName
, const wchar_t *wszLocalName
,
3727 int cchNamespaceUri
, const wchar_t *wszNamespaceUri
)
3729 ATLENSURE(wszLocalName
);
3730 ATLENSURE(wszLocalNameCheck
);
3731 ATLENSURE(wszNamespaceUri
);
3732 ATLENSURE(wszNamespaceUriCheck
);
3734 if (cchLocalName
== cchLocalNameCheck
&&
3735 cchNamespaceUri
== cchNamespaceUriCheck
&&
3736 !wcsncmp(wszLocalName
, wszLocalNameCheck
, cchLocalName
) &&
3737 !wcsncmp(wszNamespaceUri
, wszNamespaceUriCheck
, cchNamespaceUri
))
3745 ATL_FORCEINLINE BOOL
IsEqualString(const wchar_t *wszStr1
, int cchStr1
, const wchar_t *wszStr2
, int cchStr2
)
3747 ATLENSURE( wszStr1
!= NULL
);
3748 ATLENSURE( wszStr2
!= NULL
);
3749 ATLENSURE( cchStr1
>= 0 );
3750 ATLENSURE( cchStr2
>= 0 );
3752 if (cchStr1
== cchStr2
)
3754 return !wcsncmp(wszStr1
, wszStr2
, cchStr2
);
3759 ATL_FORCEINLINE BOOL
IsEqualStringHash(const wchar_t *wszStr1
, int cchStr1
, ULONG nHash1
,
3760 const wchar_t *wszStr2
, int cchStr2
, ULONG nHash2
)
3762 ATLENSURE( wszStr1
!= NULL
);
3763 ATLENSURE( wszStr2
!= NULL
);
3764 ATLENSURE( cchStr1
>= 0 );
3765 ATLENSURE( cchStr2
>= 0 );
3767 if (nHash1
== nHash2
)
3769 return IsEqualString(wszStr1
, cchStr1
, wszStr2
, cchStr2
);
3775 BOOL
IsEqualElement(int cchLocalNameCheck
, const wchar_t *wszLocalNameCheck
,
3776 int cchLocalName
, const wchar_t *wszLocalName
)
3778 if (cchLocalName
== cchLocalNameCheck
&&
3779 !wcsncmp(wszLocalName
, wszLocalNameCheck
, cchLocalName
))
3787 void SetOffsetValue(void *pBase
, void *pSrc
, size_t nOffset
)
3789 void **ppDest
= (void **)(((unsigned char *)pBase
)+nOffset
);
3795 if ((m_stateStack
[0].pMap
->dwCallFlags
& (SOAPFLAG_RPC
| SOAPFLAG_ENCODED
)) ==
3796 (SOAPFLAG_RPC
| SOAPFLAG_ENCODED
))
3804 HRESULT
ValidateArrayEntry(
3806 const wchar_t *wszLocalName
,
3812 ATLASSERT( state
.pEntry
!= NULL
);
3814 // SOAP Section 5.4.2
3816 // check number of elements
3817 if (state
.nElement
== state
.nExpectedElements
)
3819 // too many elements
3820 if ((state
.dwFlags
& SOAPFLAG_UNKSIZE
)==0)
3822 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::ValidateArrayEntry -- too many elements.\r\n" ) );
3826 ATLASSERT( IsRpcEncoded() == false );
3828 // see if we need to allocate more
3829 if (state
.nElement
== state
.nAllocSize
)
3831 unsigned char **ppArr
= (unsigned char **)state
.pvElement
;
3832 size_t nNewElement
=0;
3834 if(FAILED(hr
=::ATL::AtlMultiply(&nNewElement
, state
.nElement
, static_cast<size_t>(2))))
3838 hr
= AllocateArray(state
.pEntry
, (void **)ppArr
, __max(nNewElement
, ATLSOAP_GROWARRAY
), state
.nElement
);
3842 state
.nAllocSize
= __max((state
.nElement
)*2, ATLSOAP_GROWARRAY
);
3853 const wchar_t *wszNamespaceUri
,
3854 const wchar_t *wszLocalName
,
3856 ISAXAttributes
*pAttributes
)
3861 ATLASSERT( pAttributes
!= NULL
);
3863 const wchar_t *wsz
= NULL
;
3866 HRESULT hr
= GetAttribute(pAttributes
, L
"id", sizeof("id")-1, &wsz
, &cch
);
3867 if ((hr
== S_OK
) && (wsz
!= NULL
))
3869 const REFMAP::CPair
*p
= NULL
;
3872 REFSTRING
strRef(wsz
, cch
);
3873 p
= m_refMap
.Lookup(strRef
);
3881 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::CheckID -- out of memory.\r\n" ) );
3883 return E_OUTOFMEMORY
;
3886 ATLASSERT( IsRpcEncoded() == true );
3888 const ParseState
& state
= p
->m_value
;
3890 // disallow href-chaining
3891 hr
= CheckHref(state
.pEntry
, state
.pvElement
, pAttributes
);
3900 if (state
.dwFlags
& (SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
))
3902 hr
= GetSection5Info(state
, state
.pEntry
, pAttributes
);
3906 // only structs and arrays are allowed for hrefs
3907 ATLASSERT( state
.pEntry
->pChain
!= NULL
);
3908 ATLASSERT( state
.pEntry
->pChain
->mapType
== SOAPMAP_STRUCT
);
3910 // structs must have child entries
3911 m_bChildCheck
= state
.pEntry
->pChain
->nElements
!= 0;
3913 if (S_OK
!= PushState(state
.pvElement
, state
.pEntry
->pChain
, state
.pEntry
,
3914 state
.dwFlags
, 0, state
.pEntry
->pChain
->nElements
))
3916 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::CheckID -- out of memory.\n" ) );
3921 m_refMap
.DisableAutoRehash();
3922 m_refMap
.RemoveAtPos(const_cast<REFMAP::CPair
*>(p
));
3923 m_refMap
.EnableAutoRehash();
3931 HRESULT
GetElementEntry(
3933 const wchar_t *wszNamespaceUri
,
3934 const wchar_t *wszLocalName
,
3936 ISAXAttributes
*pAttributes
,
3937 const _soapmapentry
**ppEntry
)
3939 ATLENSURE_RETURN( state
.pMap
!= NULL
);
3940 ATLENSURE_RETURN( ppEntry
!= NULL
);
3943 const _soapmapentry
*pEntries
= state
.pMap
->pEntries
;
3944 DWORD dwIncludeFlags
;
3945 DWORD dwExcludeFlags
;
3947 HRESULT hr
= CheckID(wszNamespaceUri
, wszLocalName
, cchLocalName
, pAttributes
);
3957 if (m_bClient
!= false)
3959 dwIncludeFlags
= SOAPFLAG_OUT
;
3960 dwExcludeFlags
= SOAPFLAG_IN
;
3964 dwIncludeFlags
= SOAPFLAG_IN
;
3965 dwExcludeFlags
= SOAPFLAG_OUT
;
3968 ULONG nHash
= AtlSoapHashStr(wszLocalName
, cchLocalName
);
3970 for (size_t i
=0; pEntries
[i
].nHash
!= 0; i
++)
3972 if (nHash
== pEntries
[i
].nHash
&&
3973 ((pEntries
[i
].dwFlags
& dwIncludeFlags
) ||
3974 ((pEntries
[i
].dwFlags
& dwExcludeFlags
) == 0)) &&
3975 IsEqualElement(pEntries
[i
].cchField
, pEntries
[i
].wszField
,
3976 cchLocalName
, wszLocalName
)/* &&
3977 !wcscmp(wszNamespaceUri, wszNamespace)*/)
3981 if (state
.vec
.GetBit(i
) == false)
3983 if (state
.vec
.SetBit(i
) == false)
3985 return E_OUTOFMEMORY
;
3990 // already received this element
3991 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::GetElementEntry -- duplicate element was sent.\r\n" ) );
3997 *ppEntry
= &pEntries
[i
];
4003 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::GetElementEntry -- element not found: %.*ws.\r\n" ), cchLocalName
, wszLocalName
);
4008 HRESULT
CheckMustUnderstandHeader(ISAXAttributes
*pAttributes
)
4010 ATLASSERT( pAttributes
!= NULL
);
4012 const wchar_t* wszMustUnderstand
;
4013 int cchMustUnderstand
;
4014 bool bMustUnderstand
= false;
4016 if (SUCCEEDED(GetAttribute(pAttributes
, L
"mustUnderstand", sizeof("mustUnderstand")-1,
4017 &wszMustUnderstand
, &cchMustUnderstand
,
4018 SOAPENV_NAMESPACEW
, sizeof(SOAPENV_NAMESPACEA
)-1)) &&
4019 (wszMustUnderstand
!= NULL
))
4021 if (FAILED(AtlGetSAXValue(&bMustUnderstand
, wszMustUnderstand
, cchMustUnderstand
)))
4023 bMustUnderstand
= true;
4027 if (bMustUnderstand
== false)
4029 ATLASSERT( GetReader() != NULL
);
4031 m_skipHandler
.SetReader(GetReader());
4032 m_skipHandler
.SetParent(this);
4034 return GetReader()->putContentHandler( &m_skipHandler
);
4038 SoapFault(SOAP_E_MUST_UNDERSTAND
, NULL
, 0);
4041 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::CheckMustUnderstandHeader -- unknown \"mustUnderstand\" SOAP Header was received.\r\n" ) );
4046 HRESULT
AllocateArray(
4047 const _soapmapentry
*pEntry
,
4048 void **ppArr
, size_t nElements
,
4049 size_t nCurrElements
= 0)
4051 ATLENSURE_RETURN( ppArr
!= NULL
);
4052 ATLENSURE_RETURN( pEntry
!= NULL
);
4054 size_t nElementSize
;
4055 if (pEntry
->nVal
!= SOAPTYPE_UNK
)
4057 nElementSize
= AtlSoapGetElementSize((SOAPTYPES
) pEntry
->nVal
);
4061 ATLENSURE_RETURN( pEntry
->pChain
!= NULL
);
4062 nElementSize
= pEntry
->pChain
->nElementSize
;
4064 if (nElementSize
!= 0)
4068 ATLASSERT( nCurrElements
== 0 );
4071 if( FAILED(hr
=::ATL::AtlMultiply(&nBytes
, nElementSize
, nElements
)))
4075 *ppArr
= m_pMemMgr
->Allocate(nBytes
);
4077 else // *ppArr != NULL
4079 ATLASSERT( nCurrElements
!= 0 );
4082 if( FAILED(hr
=::ATL::AtlAdd(&nBytes
, nElements
, nCurrElements
)) ||
4083 FAILED(hr
=::ATL::AtlMultiply(&nBytes
, nElementSize
, nBytes
)))
4087 *ppArr
= m_pMemMgr
->Reallocate(*ppArr
, nBytes
);
4099 return E_OUTOFMEMORY
;
4102 memset(((unsigned char *)(*ppArr
))+(nCurrElements
*nElementSize
), 0x00, nElements
*nElementSize
);
4107 HRESULT
GetSection5Info(
4108 const ParseState
& state
,
4109 const _soapmapentry
*pEntry
,
4110 ISAXAttributes
*pAttributes
)
4112 ATLENSURE_RETURN( pEntry
!= NULL
);
4113 ATLENSURE_RETURN( pAttributes
!= NULL
);
4116 if (IsRpcEncoded() != false)
4119 // we ONLY do this for rpc/encoded (required for interop)
4120 // NOTE: ATL Server does not support object graphs, so
4121 // only single-reference elements are allowed
4122 hr
= CheckHref(pEntry
, state
.pvElement
, pAttributes
,
4123 pEntry
->dwFlags
, SOAPFLAG_READYSTATE
);
4132 hr
= AtlSoapGetArraySize(pAttributes
, &nElements
);
4138 size_t nAllocSize
= 0;
4139 size_t nElementsPush
= 0;
4141 if (pEntry
->dwFlags
& SOAPFLAG_DYNARR
)
4143 // set size_is value
4144 ATLENSURE_RETURN( state
.pMap
!= NULL
);
4145 int *pnSizeIs
= (int *)(((unsigned char *)state
.pvElement
)+
4146 (state
.pMap
->pEntries
[pEntry
->nSizeIs
].nOffset
));
4152 // rpc/encoded requires soapenc:arrayType attribute
4156 nElements
= ATLSOAP_GROWARRAY
;
4157 nAllocSize
= ATLSOAP_GROWARRAY
;
4158 dwFlags
|= SOAPFLAG_UNKSIZE
;
4163 *pnSizeIs
= (int)nElements
;
4166 // soapenc:arrayType="type[0]"
4167 // treat as null array
4169 m_bNullCheck
= true;
4171 // push an emtpy state
4175 nElementsPush
= nElements
;
4178 hr
= AllocateArray(pEntry
, &p
, nElements
);
4184 SetOffsetValue(state
.pvElement
, p
, pEntry
->nOffset
);
4188 // for fixed-size arrays, we know the number of elements
4189 ATLASSERT( pEntry
->dwFlags
& SOAPFLAG_FIXEDARR
);
4192 if (nElements
!= AtlSoapGetArrayDims(pEntry
->pDims
))
4200 nElements
= AtlSoapGetArrayDims(pEntry
->pDims
);
4202 nElementsPush
= nElements
;
4205 dwFlags
|= pEntry
->dwFlags
;
4207 // push element with array flag
4209 if (S_OK
!= PushState(((unsigned char *)state
.pvElement
)+pEntry
->nOffset
,
4210 state
.pMap
, pEntry
, dwFlags
& ~SOAPFLAG_READYSTATE
, nAllocSize
, nElementsPush
))
4212 return E_OUTOFMEMORY
;
4215 m_bChildCheck
= true;
4220 void * UpdateArray(ParseState
& state
, const _soapmapentry
*pEntry
)
4227 if (pEntry
->nVal
!= SOAPTYPE_UNK
)
4229 nSize
= AtlSoapGetElementSize((SOAPTYPES
) pEntry
->nVal
);
4233 ATLENSURE( pEntry
->pChain
!= NULL
);
4235 nSize
= pEntry
->pChain
->nElementSize
;
4238 if (state
.dwFlags
& SOAPFLAG_FIXEDARR
)
4240 unsigned char *ppArr
= (unsigned char *)state
.pvElement
;
4241 pVal
= ppArr
+(state
.nElement
*nSize
);
4245 ATLASSERT( state
.dwFlags
& SOAPFLAG_DYNARR
);
4247 unsigned char **ppArr
= (unsigned char **)state
.pvElement
;
4248 pVal
= (*ppArr
)+(state
.nElement
*nSize
);
4249 if (state
.dwFlags
& SOAPFLAG_UNKSIZE
)
4251 ATLASSERT( IsRpcEncoded() == false );
4253 // need to use the previous state's pvElement to update the size_is value
4254 ATLASSUME( m_nState
> 0 );
4255 int *pnSizeIs
= (int *)(((unsigned char *)m_stateStack
[m_nState
-1].pvElement
)+
4256 (state
.pMap
->pEntries
[pEntry
->nSizeIs
].nOffset
));
4258 // update size_is parameter
4259 *pnSizeIs
= (int)(state
.nElement
+1);
4260 state
.nExpectedElements
++;
4268 HRESULT
ProcessString(const _soapmapentry
*pEntry
, void *pVal
)
4270 ATLENSURE_RETURN( pEntry
!= NULL
);
4272 // set to the string builder class
4274 ATLASSERT( GetReader() != NULL
);
4276 m_stringBuilder
.SetReader(GetReader());
4277 m_stringBuilder
.SetParent(this);
4279 m_stringBuilder
.Clear();
4280 GetReader()->putContentHandler( &m_stringBuilder
);
4282 if (S_OK
!= PushState(pVal
, NULL
, pEntry
, SOAPFLAG_READYSTATE
| pEntry
->dwFlags
))
4284 return E_OUTOFMEMORY
;
4292 const _soapmapentry
*pEntry
,
4294 ISAXAttributes
*pAttributes
,
4295 DWORD dwIncludeFlags
= 0,
4296 DWORD dwExcludeFlags
= 0)
4298 ATLASSERT( pEntry
!= NULL
);
4299 ATLASSERT( pVal
!= NULL
);
4300 ATLASSERT( pAttributes
!= NULL
);
4302 const wchar_t *wsz
= NULL
;
4305 HRESULT hr
= GetAttribute(pAttributes
, L
"href", sizeof("href")-1, &wsz
, &cch
);
4306 if ((hr
== S_OK
) && (wsz
!= NULL
))
4308 // only allow hrefs on structs and arrays
4309 if (((pEntry
->dwFlags
& (SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
))==0) &&
4310 (pEntry
->pChain
== NULL
|| pEntry
->pChain
->mapType
!= SOAPMAP_STRUCT
))
4312 ATLTRACE( _T("ATL Server only allows href's on arrays and structs.\r\n") );
4317 ATLASSERT( IsRpcEncoded() == true );
4327 REFSTRING
strRef(wsz
, cch
);
4328 if (m_refMap
.Lookup(strRef
) != NULL
)
4330 // ATL Server does not support multi-reference objects
4335 ParseState
& currState
= GetState();
4336 if ((currState
.pEntry
!= NULL
) && (currState
.pEntry
->dwFlags
& (SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
)))
4338 // it is an array item
4339 ATLASSERT( currState
.nElement
!= 0 );
4341 // exclude array flags for href'd array elements
4342 dwExcludeFlags
|= SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
;
4346 state
.pvElement
= pVal
;
4347 state
.dwFlags
= (pEntry
->dwFlags
| dwIncludeFlags
) & ~dwExcludeFlags
;
4348 state
.nExpectedElements
= 0;
4351 state
.pMap
= GetState().pMap
;
4352 state
.pEntry
= pEntry
;
4354 if (!m_refMap
.SetAt(strRef
, state
))
4356 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::CheckHref -- out of memory.\r\n" ) );
4358 return E_OUTOFMEMORY
;
4361 // make sure there are no child elements
4362 m_bNullCheck
= true;
4364 // push an emtpy state
4369 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::CheckHref -- out of memory.\r\n" ) );
4371 return E_OUTOFMEMORY
;
4379 const _soapmapentry
*pEntry
,
4382 ATLENSURE_RETURN( pEntry
!= NULL
);
4383 ATLENSURE_RETURN( pVal
!= NULL
);
4384 ATLENSURE_RETURN( pEntry
->nVal
!= SOAPTYPE_ERR
);
4385 ATLENSURE_RETURN( pEntry
->nVal
!= SOAPTYPE_USERBASE
);
4387 // if it is a complex type, get the chain entry
4388 // and push the new state on the stack
4390 DWORD dwFlags
= pEntry
->dwFlags
;
4391 if (pEntry
->pChain
->mapType
!= SOAPMAP_ENUM
)
4394 dwFlags
&= ~(SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
);
4395 m_bChildCheck
= pEntry
->pChain
->nElements
!= 0;
4400 dwFlags
|= SOAPFLAG_READYSTATE
;
4402 // enums must not have child elements
4403 m_bNullCheck
= true;
4405 // enums must be specified
4406 m_bCharacters
= true;
4409 if (S_OK
!= PushState(pVal
, pEntry
->pChain
, pEntry
, dwFlags
, 0, pEntry
->pChain
->nElements
))
4411 return E_OUTOFMEMORY
;
4418 const ParseState
& state
,
4419 const wchar_t *wszNamespaceUri
,
4420 int cchNamespaceUri
,
4421 const wchar_t *wszLocalName
,
4423 ISAXAttributes
*pAttributes
)
4425 ATLENSURE_RETURN( state
.pMap
!= NULL
);
4427 // PAD is only supported on the client
4428 const _soapmap
*pMap
= state
.pMap
;
4429 if ((pMap
->dwCallFlags
& SOAPFLAG_CHAIN
)==0)
4434 ATLENSURE_RETURN( pMap
->dwCallFlags
& SOAPFLAG_PAD
);
4435 ATLASSUME( m_bClient
== true );
4436 ATLENSURE_RETURN( pMap
->nElements
== 1 );
4437 const _soapmapentry
*pEntries
= pMap
->pEntries
;
4438 ATLENSURE_RETURN( pEntries
!= NULL
);
4441 if (pEntries
[0].dwFlags
& SOAPFLAG_OUT
)
4450 const _soapmapentry
*pEntry
= &pEntries
[nIndex
];
4451 ATLENSURE_RETURN( pEntry
->nHash
!= 0 );
4452 ATLENSURE_RETURN( pEntry
->pChain
!= NULL
);
4454 if (S_OK
!= PushState(state
.pvElement
, pEntry
->pChain
, pEntry
, pEntry
->dwFlags
, 0, pEntry
->pChain
->nElements
))
4456 return E_OUTOFMEMORY
;
4459 return ProcessParams(wszNamespaceUri
, cchNamespaceUri
, wszLocalName
, cchLocalName
, pAttributes
);
4462 HRESULT
IsNullEntry(const _soapmapentry
*pEntry
, ISAXAttributes
*pAttributes
)
4464 ATLASSERT( pEntry
!= NULL
);
4465 ATLASSERT( pAttributes
!= NULL
);
4467 HRESULT hr
= E_FAIL
;
4469 const wchar_t *wszNull
= NULL
;
4471 hr
= GetAttribute(pAttributes
, L
"nil", sizeof("nil")-1, &wszNull
, &cchNull
,
4472 XSI_NAMESPACEW
, sizeof(XSI_NAMESPACEA
)-1);
4473 if ((hr
== S_OK
) && (wszNull
!= NULL
))
4475 hr
= AtlGetSAXValue(&bNull
, wszNull
, cchNull
);
4480 if (pEntry
->dwFlags
& SOAPFLAG_NULLABLE
)
4482 m_bNullCheck
= true;
4484 // push an emtpy state
4488 // non-nullable element
4497 HRESULT
ProcessParams(
4498 const wchar_t *wszNamespaceUri
,
4499 int cchNamespaceUri
,
4500 const wchar_t *wszLocalName
,
4502 ISAXAttributes
*pAttributes
)
4507 if (m_stateStack
.IsEmpty())
4509 if (m_dwState
== SOAP_HEADERS
)
4511 return CheckMustUnderstandHeader(pAttributes
);
4517 ParseState
&state
= GetState();
4519 ATLASSERT( state
.pvElement
!= NULL
);
4520 HRESULT hr
= E_FAIL
;
4521 const _soapmapentry
*pEntry
= NULL
;
4524 if (state
.dwFlags
& (SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
))
4526 hr
= ValidateArrayEntry(state
, wszLocalName
, cchLocalName
);
4530 pEntry
= state
.pEntry
;
4537 else // not an array element
4539 // special-case for PAD with type=
4540 hr
= ChainEntry(state
, wszNamespaceUri
, cchNamespaceUri
,
4541 wszLocalName
, cchLocalName
, pAttributes
);
4545 hr
= GetElementEntry(state
, wszNamespaceUri
, wszLocalName
, cchLocalName
, pAttributes
, &pEntry
);
4552 else if (m_dwState
== SOAP_HEADERS
)
4554 hr
= CheckMustUnderstandHeader(pAttributes
);
4559 ATLASSERT( pEntry
!= NULL
);
4567 hr
= IsNullEntry(pEntry
, pAttributes
);
4573 ATLENSURE_RETURN(pEntry
);
4575 if (((pEntry
->pDims
!= NULL
) || (pEntry
->dwFlags
& (SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
))) &&
4576 ((state
.dwFlags
& (SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
)) == 0))
4578 // get SOAP section-5 info (if it is there)
4579 return GetSection5Info(state
, pEntry
, pAttributes
);
4583 // if it is a simple type, push a new (ready) state on the stack
4585 if (state
.dwFlags
& (SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
))
4587 pVal
= UpdateArray(state
, pEntry
);
4588 ATLASSERT( pVal
!= NULL
);
4592 pVal
= (((unsigned char *)state
.pvElement
)+pEntry
->nOffset
);
4595 if (IsRpcEncoded() != false)
4598 // we ONLY do this for rpc/encoded (required for interop)
4599 // NOTE: ATL Server does not support object graphs, so
4600 // only single-reference elements are allowed
4601 hr
= CheckHref(pEntry
, pVal
, pAttributes
);
4609 if (pEntry
->nVal
!= SOAPTYPE_UNK
)
4611 // simple types should not have child elements
4612 m_bNullCheck
= true;
4614 // if it is a string
4615 if ((pEntry
->nVal
== SOAPTYPE_STRING
) || (pEntry
->nVal
== SOAPTYPE_BASE64BINARY
))
4617 hr
= ProcessString(pEntry
, pVal
);
4621 // expect characters for all non-string simple types
4622 m_bCharacters
= true;
4624 // basic simple type
4625 if (S_OK
!= PushState(pVal
, NULL
, pEntry
, SOAPFLAG_READYSTATE
| pEntry
->dwFlags
))
4633 hr
= ProcessUDT(pEntry
, pVal
);
4634 if (pEntry
->dwFlags
& (SOAPFLAG_DYNARRWRAPPER
))
4636 // We're moving to the **first** entry in the dynamic array wrapper.
4637 // We know it is the first entry because the dynamic array wrapper is created
4638 // by sproxy and it guarantees this layouts.
4640 ProcessParams (wszNamespaceUri
, cchNamespaceUri
, pEntry
->pChain
->pEntries
[0].wszField
,
4641 pEntry
->pChain
->pEntries
[0].cchField
, pAttributes
);
4649 size_t GetSizeIsValue(void *pvParam
, const _soapmap
*pMap
, const _soapmapentry
*pEntry
)
4651 ATLENSURE( pvParam
!= NULL
);
4652 ATLENSURE( pMap
!= NULL
);
4653 ATLENSURE( pEntry
!= NULL
);
4655 int nSizeIs
= pEntry
->nSizeIs
;
4656 size_t nOffset
= pMap
->pEntries
[nSizeIs
].nOffset
;
4657 void *pVal
= ((unsigned char *)pvParam
)+nOffset
;
4660 switch(pMap
->pEntries
[nSizeIs
].nVal
)
4662 case SOAPTYPE_INTEGER
:
4663 case SOAPTYPE_NONPOSITIVEINTEGER
:
4664 case SOAPTYPE_NEGATIVEINTEGER
:
4666 nVal
= *((__int64
*)pVal
);
4669 nVal
= *((int *)pVal
);
4671 case SOAPTYPE_SHORT
:
4672 nVal
= *((short *)pVal
);
4675 nVal
= *((char *)pVal
);
4677 case SOAPTYPE_POSITIVEINTEGER
:
4678 case SOAPTYPE_NONNEGATIVEINTEGER
:
4679 case SOAPTYPE_UNSIGNEDLONG
:
4681 n
= *((unsigned __int64
*)pVal
);
4692 case SOAPTYPE_UNSIGNEDINT
:
4693 nVal
= *((unsigned int *)pVal
);
4695 case SOAPTYPE_UNSIGNEDSHORT
:
4696 nVal
= *((unsigned short *)pVal
);
4698 case SOAPTYPE_UNSIGNEDBYTE
:
4699 nVal
= *((unsigned char *)pVal
);
4710 return (size_t) nVal
;
4713 HRESULT
GenerateArrayInfo(const _soapmapentry
*pEntry
, const int *pDims
, IWriteStream
*pStream
)
4715 ATLENSURE_RETURN( pEntry
!= NULL
);
4716 ATLENSURE_RETURN( pStream
!= NULL
);
4719 if (pEntry
->nVal
!= SOAPTYPE_UNK
)
4722 hr
= pStream
->WriteStream(" soapenc:arrayType=\"xsd:",
4723 sizeof(" soapenc:arrayType=\"xsd:")-1, NULL
);
4727 ATLENSURE_RETURN( pEntry
->pChain
!= NULL
);
4729 hr
= pStream
->WriteStream(" xmlns:q1=\"", sizeof(" xmlns:q1=\"")-1, NULL
);
4732 if (pEntry
->pChain
->szNamespace
!= NULL
)
4734 hr
= pStream
->WriteStream(pEntry
->pChain
->szNamespace
, pEntry
->pChain
->cchNamespace
, NULL
);
4738 hr
= pStream
->WriteStream(GetNamespaceUriA(), -1, NULL
);
4742 hr
= pStream
->WriteStream("\"", 1, NULL
);
4745 hr
= pStream
->WriteStream(" soapenc:arrayType=\"q1:",
4746 sizeof(" soapenc:arrayType=\"q1:")-1, NULL
);
4757 if (pEntry
->nVal
!= SOAPTYPE_UNK
)
4759 hr
= pStream
->WriteStream(s_xsdNames
[pEntry
->nVal
].szName
,
4760 s_xsdNames
[pEntry
->nVal
].cchName
, NULL
);
4764 ATLASSERT( pEntry
->pChain
!= NULL
);
4766 hr
= pStream
->WriteStream(pEntry
->pChain
->szName
, pEntry
->pChain
->cchName
, NULL
);
4774 hr
= pStream
->WriteStream("[", 1, NULL
);
4780 CWriteStreamHelper
s( pStream
);
4781 for (int i
=1; i
<=pDims
[0]; i
++)
4783 if (!s
.Write(pDims
[i
]) ||
4784 ((i
< pDims
[0]) && (S_OK
!= pStream
->WriteStream(", ", 2, NULL
))))
4790 hr
= pStream
->WriteStream("]\"", 2, NULL
);
4799 HRESULT
GenerateXSDWrapper(bool bStart
, int nVal
, bool bNull
, IWriteStream
*pStream
)
4801 ATLENSURE_RETURN( pStream
!= NULL
);
4803 HRESULT hr
= pStream
->WriteStream((bStart
!= false) ? "<" : "</",
4804 (bStart
!= false) ? 1 : 2, NULL
);
4807 hr
= pStream
->WriteStream(s_xsdNames
[nVal
].szName
,
4808 s_xsdNames
[nVal
].cchName
, NULL
);
4809 if ((bNull
!= false) && (SUCCEEDED(hr
)))
4811 hr
= pStream
->WriteStream(" xsi:nil=\"1\"", sizeof(" xsi:nil=\"1\"")-1, NULL
);
4815 hr
= pStream
->WriteStream(">", 1, NULL
);
4822 HRESULT
GenerateGenericWrapper(bool bStart
, const _soapmap
*pMap
, IWriteStream
*pStream
)
4824 ATLENSURE_RETURN( pStream
!= NULL
);
4825 ATLENSURE_RETURN( pMap
!= NULL
);
4827 HRESULT hr
= pStream
->WriteStream((bStart
!= false) ? "<" : "</",
4828 (bStart
!= false) ? 1 : 2, NULL
);
4831 hr
= pStream
->WriteStream(pMap
->szName
, pMap
->cchName
, NULL
);
4834 hr
= pStream
->WriteStream(">", 1, NULL
);
4841 HRESULT
GetArrayInformation(
4842 IWriteStream
*pStream
,
4843 const _soapmap
*pMap
,
4844 const _soapmapentry
*pEntry
,
4847 size_t &nElementSize
)
4849 ATLENSURE_RETURN( pStream
!= NULL
);
4850 ATLENSURE_RETURN( pMap
!= NULL
);
4851 ATLENSURE_RETURN( pEntry
!= NULL
);
4852 ATLENSURE_RETURN( pvParam
!= NULL
);
4854 const int *pDims
= NULL
;
4855 int arrDims
[2] = { 0 };
4857 if (pEntry
->dwFlags
& SOAPFLAG_FIXEDARR
)
4859 pDims
= pEntry
->pDims
;
4863 ATLASSERT( pEntry
->dwFlags
& SOAPFLAG_DYNARR
);
4864 nCnt
= GetSizeIsValue(pvParam
, pMap
, pEntry
);
4868 // array size should only be zero if array is NULL
4869 // did you forget to set the array size?
4875 arrDims
[1] = (int) nCnt
;
4880 // output array information
4881 HRESULT hr
= GenerateArrayInfo(pEntry
, pDims
, pStream
);
4888 nCnt
= AtlSoapGetArrayDims(pDims
);
4890 // did you forget to set the size_is value?
4891 ATLASSERT( nCnt
!= 0 );
4893 if (pEntry
->nVal
!= SOAPTYPE_UNK
)
4895 nElementSize
= AtlSoapGetElementSize((SOAPTYPES
) pEntry
->nVal
);
4899 ATLENSURE_RETURN( pEntry
->pChain
!= NULL
);
4901 nElementSize
= pEntry
->pChain
->nElementSize
;
4908 HRESULT
GenerateEnum(IWriteStream
*pStream
, void *pVal
, const _soapmapentry
*pEntry
, bool bArray
)
4910 ATLENSURE_RETURN( pStream
!= NULL
);
4911 ATLENSURE_RETURN( pVal
!= NULL
);
4912 ATLENSURE_RETURN( pEntry
!= NULL
);
4914 int nVal
= *((int *)pVal
);
4915 const _soapmapentry
*pEnumEntries
= pEntry
->pChain
->pEntries
;
4917 ATLENSURE_RETURN( pEnumEntries
!= NULL
);
4919 HRESULT hr
= E_FAIL
;
4920 for (j
=0; pEnumEntries
[j
].nHash
!= 0; j
++)
4922 if (nVal
== pEnumEntries
[j
].nVal
)
4924 hr
= pStream
->WriteStream(pEnumEntries
[j
].szField
, pEnumEntries
[j
].cchField
, NULL
);
4925 if ((bArray
!= false) && (SUCCEEDED(hr
)))
4927 hr
= GenerateGenericWrapper(false, pEntry
->pChain
, pStream
);
4936 HRESULT
GenerateHeaders(CResponseGenerator
*pGenerator
, const _soapmap
*pMap
, IWriteStream
*pStream
)
4938 ATLENSURE_RETURN( pStream
!= NULL
);
4939 ATLENSURE_RETURN( pMap
!= NULL
);
4941 ATLENSURE_RETURN( pGenerator
!= NULL
);
4943 DWORD dwIncludeFlags
= SOAPFLAG_OUT
;
4944 if (m_bClient
!= false)
4946 dwIncludeFlags
= SOAPFLAG_IN
;
4950 for (size_t i
=0; pMap
->pEntries
[i
].nHash
!= 0; i
++)
4952 if (pMap
->pEntries
[i
].dwFlags
& dwIncludeFlags
)
4958 // no headers to be sent
4964 HRESULT hr
= pGenerator
->StartHeaders(pStream
, pMap
);
4967 hr
= GenerateResponseHelper(pGenerator
, pMap
, GetHeaderValue(), pStream
);
4970 hr
= pGenerator
->EndHeaders(pStream
);
4977 bool IsNullElement(const _soapmapentry
*pEntry
, void *pVal
, DWORD dwExcludeFlags
=0)
4979 ATLENSURE( pEntry
!= NULL
);
4980 ATLENSURE( pVal
!= NULL
);
4984 DWORD dwFlags
= pEntry
->dwFlags
& ~dwExcludeFlags
;
4986 if (dwFlags
& SOAPFLAG_DYNARR
)
4988 unsigned char **ppArr
= (unsigned char **)pVal
;
4994 else if (pEntry
->nVal
== SOAPTYPE_STRING
)
4996 BSTR
*pBSTR
= (BSTR
*)pVal
;
5002 else if ((pEntry
->nVal
== SOAPTYPE_BASE64BINARY
) || (pEntry
->nVal
== SOAPTYPE_HEXBINARY
))
5004 if (((ATLSOAP_BLOB
*)pVal
)->data
== NULL
)
5013 HRESULT
GenerateNull(IWriteStream
*pStream
)
5015 ATLENSURE_RETURN( pStream
!= NULL
);
5016 return pStream
->WriteStream(" xsi:nil=\"1\"/>", sizeof(" xsi:nil=\"1\"/>")-1, NULL
);
5019 HRESULT
GenerateResponseHelper(CResponseGenerator
*pGenerator
, const _soapmap
*pMap
, void *pvParam
, IWriteStream
*pStream
,
5020 bool bArrayElement
= false)
5022 ATLENSURE_RETURN( pGenerator
!= NULL
);
5023 ATLENSURE_RETURN( pMap
!= NULL
);
5024 ATLENSURE_RETURN( pStream
!= NULL
);
5028 if ((bArrayElement
!= false) &&
5029 ((pMap
->dwCallFlags
& SOAPFLAG_PAD
)==0))
5031 hr
= pGenerator
->StartMap(pStream
, pMap
, m_bClient
);
5038 ATLENSURE_RETURN( pMap
->pEntries
!= NULL
);
5040 const _soapmapentry
*pEntries
= pMap
->pEntries
;
5043 DWORD dwIncludeFlags
;
5044 DWORD dwExcludeFlags
;
5045 if (m_bClient
!= false)
5047 dwIncludeFlags
= SOAPFLAG_IN
;
5048 dwExcludeFlags
= SOAPFLAG_OUT
;
5052 dwIncludeFlags
= SOAPFLAG_OUT
;
5053 dwExcludeFlags
= SOAPFLAG_IN
;
5056 for (i
=0; pEntries
[i
].nHash
!= 0; i
++)
5058 if (((pEntries
[i
].dwFlags
& dwIncludeFlags
) ||
5059 ((pEntries
[i
].dwFlags
& dwExcludeFlags
)==0)) &&
5060 ((pEntries
[i
].dwFlags
& SOAPFLAG_NOMARSHAL
)==0))
5062 hr
= pGenerator
->StartEntry(pStream
, pMap
, &pEntries
[i
]);
5068 size_t nElementSize
= 0;
5071 ATLASSERT( pvParam
!= NULL
);
5073 void *pvCurrent
= ((unsigned char *)pvParam
)+pEntries
[i
].nOffset
;
5075 if (IsNullElement(&pEntries
[i
], pvCurrent
))
5077 hr
= GenerateNull(pStream
);
5085 bool bArray
= (pEntries
[i
].dwFlags
& (SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
)) != 0;
5086 if (bArray
!= false)
5088 hr
= GetArrayInformation(pStream
, pMap
, &pEntries
[i
], pvParam
, nCnt
, nElementSize
);
5091 hr
= pStream
->WriteStream(">", 1, NULL
);
5097 for (size_t nElement
=0; nElement
<nCnt
; nElement
++)
5101 // get updated value
5102 if (bArray
!= false)
5104 if (pEntries
[i
].dwFlags
& SOAPFLAG_FIXEDARR
)
5106 unsigned char *ppArr
= (unsigned char *)pvCurrent
;
5107 pVal
= ppArr
+(nElement
*nElementSize
);
5111 ATLASSERT( pEntries
[i
].dwFlags
& SOAPFLAG_DYNARR
);
5113 unsigned char **ppArr
= (unsigned char **)pvCurrent
;
5114 pVal
= (*ppArr
)+(nElement
*nElementSize
);
5122 if (pEntries
[i
].nVal
!= SOAPTYPE_UNK
)
5125 if (bArray
!= false)
5127 bNull
= IsNullElement(&pEntries
[i
], pVal
, SOAPFLAG_DYNARR
| SOAPFLAG_FIXEDARR
);
5128 hr
= GenerateXSDWrapper(true, pEntries
[i
].nVal
, bNull
, pStream
);
5136 hr
= AtlSoapGenElementValue(pVal
, pStream
, (SOAPTYPES
) pEntries
[i
].nVal
, GetMemMgr());
5138 if ((SUCCEEDED(hr
)) && (bArray
!= false))
5140 hr
= GenerateXSDWrapper(false, pEntries
[i
].nVal
, false, pStream
);
5150 ATLASSERT( pEntries
[i
].pChain
!= NULL
);
5152 if (pEntries
[i
].pChain
->mapType
!= SOAPMAP_ENUM
)
5155 hr
= GenerateResponseHelper(pGenerator
, pEntries
[i
].pChain
, pVal
, pStream
, bArray
);
5159 if (bArray
!= false)
5161 hr
= GenerateGenericWrapper(true, pEntries
[i
].pChain
, pStream
);
5168 hr
= GenerateEnum(pStream
, pVal
, &pEntries
[i
], bArray
);
5173 // output element close
5176 hr
= pGenerator
->EndEntry(pStream
, pMap
, &pEntries
[i
]);
5186 if ((bArrayElement
!= false) &&
5187 ((pMap
->dwCallFlags
& SOAPFLAG_PAD
)==0))
5190 hr
= pGenerator
->EndMap(pStream
, pMap
, m_bClient
);
5196 void CleanupHelper(const _soapmap
*pMap
, void *pvParam
)
5198 ATLENSURE( pMap
!= NULL
);
5199 ATLENSURE( pMap
->pEntries
!= NULL
);
5201 if (pvParam
== NULL
)
5206 const _soapmapentry
*pEntries
= pMap
->pEntries
;
5209 for (i
=0; pEntries
[i
].nHash
!= 0; i
++)
5211 if ((m_bClient
!= false) && ((pEntries
[i
].dwFlags
& SOAPFLAG_OUT
)==0))
5213 // skip in-only headers on the client
5217 void *pvCheck
= ((unsigned char *)pvParam
)+pEntries
[i
].nOffset
;
5218 if (IsNullElement(&pEntries
[i
], pvCheck
))
5223 size_t nElementSize
= 0;
5226 const int *pDims
= NULL
;
5227 int arrDims
[2] = { 0 };
5229 bool bArray
= (pEntries
[i
].dwFlags
& (SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
)) != 0;
5231 if (bArray
!= false)
5233 if (pEntries
[i
].dwFlags
& SOAPFLAG_FIXEDARR
)
5235 pDims
= pEntries
[i
].pDims
;
5239 ATLASSERT( pEntries
[i
].dwFlags
& SOAPFLAG_DYNARR
);
5240 nCnt
= GetSizeIsValue(pvParam
, pMap
, &pEntries
[i
]);
5243 arrDims
[1] = (int) nCnt
;
5248 nCnt
= AtlSoapGetArrayDims(pDims
);
5250 if (pEntries
[i
].nVal
!= SOAPTYPE_UNK
)
5252 nElementSize
= AtlSoapGetElementSize((SOAPTYPES
) pEntries
[i
].nVal
);
5256 ATLENSURE( pEntries
[i
].pChain
!= NULL
);
5258 nElementSize
= pEntries
[i
].pChain
->nElementSize
;
5262 void *pvCurrent
= ((unsigned char *)pvParam
)+pEntries
[i
].nOffset
;
5264 for (size_t nElement
=0; nElement
<nCnt
; nElement
++)
5268 // get updated value
5269 if (bArray
!= false)
5271 if (pEntries
[i
].dwFlags
& SOAPFLAG_FIXEDARR
)
5273 unsigned char *ppArr
= (unsigned char *)pvCurrent
;
5274 pVal
= ppArr
+(nElement
*nElementSize
);
5278 ATLASSERT( pEntries
[i
].dwFlags
& SOAPFLAG_DYNARR
);
5280 unsigned char **ppArr
= (unsigned char **)pvCurrent
;
5285 pVal
= (*ppArr
)+(nElement
*nElementSize
);
5293 if (pEntries
[i
].nVal
!= SOAPTYPE_UNK
)
5295 AtlSoapCleanupElement(pVal
, (SOAPTYPES
) pEntries
[i
].nVal
, GetMemMgr());
5299 ATLENSURE( pEntries
[i
].pChain
!= NULL
);
5301 if (pEntries
[i
].pChain
->mapType
!= SOAPMAP_ENUM
)
5303 CleanupHelper(pEntries
[i
].pChain
, pVal
);
5308 if (pEntries
[i
].dwFlags
& SOAPFLAG_DYNARR
)
5311 unsigned char **ppArr
= (unsigned char **)pvCurrent
;
5313 ATLENSURE( ppArr
!= NULL
);
5317 m_pMemMgr
->Free(*ppArr
);
5324 const _soapmap
* GetSoapMapFromName(
5325 const wchar_t * wszName
,
5327 const wchar_t * wszNamespaceUri
= NULL
,
5328 int cchNamespaceUri
= -1,
5330 bool bHeader
= false)
5334 const _soapmap
** pEntry
= NULL
;
5336 if (bHeader
== false)
5338 pEntry
= GetFunctionMap();
5342 pEntry
= GetHeaderMap();
5352 cchName
= (int)wcslen(wszName
);
5354 if ((cchNamespaceUri
< 0) && (wszNamespaceUri
!= NULL
))
5356 cchNamespaceUri
= (int)wcslen(wszNamespaceUri
);
5359 ULONG nFunctionHash
= AtlSoapHashStr(wszName
, cchName
);
5360 ULONG nNamespaceHash
= wszNamespaceUri
? AtlSoapHashStr(wszNamespaceUri
, cchNamespaceUri
) : 0;
5363 for (i
=0; pEntry
[i
] != NULL
; i
++)
5365 if ((IsEqualStringHash(wszName
, cchName
, nFunctionHash
,
5366 pEntry
[i
]->wszName
, pEntry
[i
]->cchWName
, pEntry
[i
]->nHash
) != FALSE
) &&
5367 (!wszNamespaceUri
||
5368 IsEqualStringHash(wszNamespaceUri
, cchNamespaceUri
, nNamespaceHash
,
5369 pEntry
[i
]->wszNamespace
, pEntry
[i
]->cchNamespace
, pEntry
[i
]->nNamespaceHash
) != FALSE
))
5382 HRESULT
CheckEndElement(const ParseState
& state
)
5384 // check for all elements
5385 if (state
.nElement
== state
.nExpectedElements
)
5390 // error check for fixed arrays
5391 if (state
.dwFlags
& SOAPFLAG_FIXEDARR
)
5396 // check for dynamic arrays
5397 if (state
.dwFlags
& SOAPFLAG_DYNARR
)
5399 // check for dynamic arrays with known size
5400 // (from soap:arrayType attribute)
5401 if ((state
.dwFlags
& SOAPFLAG_UNKSIZE
)==0)
5407 DWORD dwIncludeFlags
;
5408 DWORD dwExcludeFlags
;
5410 if (m_bClient
!= false)
5412 dwIncludeFlags
= SOAPFLAG_OUT
;
5413 dwExcludeFlags
= SOAPFLAG_IN
;
5417 dwIncludeFlags
= SOAPFLAG_IN
;
5418 dwExcludeFlags
= SOAPFLAG_OUT
;
5421 if (state
.pMap
!= NULL
)
5423 // ensure all omitted elements were nullable elements or nomarshal elements
5424 const _soapmapentry
*pEntries
= state
.pMap
->pEntries
;
5425 for (size_t i
=0; pEntries
[i
].nHash
!= 0; i
++)
5427 if ((pEntries
[i
].dwFlags
& dwIncludeFlags
) ||
5428 ((pEntries
[i
].dwFlags
& dwExcludeFlags
)==0))
5430 if (state
.vec
.GetBit(i
) == false)
5432 if (((pEntries
[i
].dwFlags
& (SOAPFLAG_NULLABLE
| SOAPFLAG_NOMARSHAL
))==0) && (pEntries
[i
].nVal
!= SOAPTYPE_UNK
))
5434 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::CheckEndElement -- invalid number of elements for parameter/field\r\n") );
5445 HRESULT
CheckSoapHeaders(const ParseState
&state
)
5447 DWORD dwIncludeFlags
;
5448 DWORD dwExcludeFlags
;
5450 if (m_bClient
!= false)
5452 dwIncludeFlags
= SOAPFLAG_OUT
;
5453 dwExcludeFlags
= SOAPFLAG_IN
;
5457 dwIncludeFlags
= SOAPFLAG_IN
;
5458 dwExcludeFlags
= SOAPFLAG_OUT
;
5461 if (state
.pMap
!= NULL
)
5463 ATLASSERT( state
.pMap
->mapType
== SOAPMAP_HEADER
);
5465 // ensure all omitted elements were nullable elements, nomarshal elements, or non-required elements
5466 const _soapmapentry
*pEntries
= state
.pMap
->pEntries
;
5467 for (size_t i
=0; pEntries
[i
].nHash
!= 0; i
++)
5469 if ((pEntries
[i
].dwFlags
& dwIncludeFlags
) ||
5470 ((pEntries
[i
].dwFlags
& dwExcludeFlags
)==0))
5472 if (state
.vec
.GetBit(i
) == false)
5474 bool bNoOmit
= (pEntries
[i
].dwFlags
& (SOAPFLAG_NULLABLE
| SOAPFLAG_NOMARSHAL
))==0;
5476 if ((bNoOmit
!= false) ||
5477 ((bNoOmit
!= false) && (pEntries
[i
].dwFlags
& SOAPFLAG_MUSTUNDERSTAND
)))
5479 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::CheckSoapHeaders -- missing header\r\n") );
5490 HRESULT
CheckEndHeaders(
5491 const wchar_t * wszNamespaceUri
,
5492 int cchNamespaceUri
,
5493 const wchar_t * wszLocalName
,
5496 if (IsEqualElement(sizeof(SOAP_HEADERA
)-1, SOAP_HEADERW
,
5497 sizeof(SOAPENV_NAMESPACEA
)-1, SOAPENV_NAMESPACEW
,
5498 cchLocalName
, wszLocalName
,
5499 cchNamespaceUri
, wszNamespaceUri
))
5501 m_dwState
= SOAP_HEADERS_DONE
;
5505 // some sort of error
5506 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::endElement -- invalid SOAP message format while processing headers.\r\n" ) );
5513 ISAXXMLReader
* SetReader(ISAXXMLReader
*pReader
)
5515 ISAXXMLReader
*pPrevRdr
= m_spReader
;
5516 m_spReader
= pReader
;
5521 ISAXXMLReader
* GetReader()
5526 HRESULT
SetSoapMapFromName(
5527 const wchar_t * wszName
,
5529 const wchar_t * wszNamespaceUri
= NULL
,
5530 int cchNamespaceUri
= -1,
5531 bool bHeader
= false)
5533 ATLENSURE_RETURN( wszName
!= NULL
);
5536 const _soapmap
*pMap
= NULL
;
5537 if (m_stateStack
.GetCount() != 0)
5539 ATLASSUME( m_stateStack
[0].pMap
!= NULL
);
5540 nVal
= (int) m_stateStack
[0].nAllocSize
;
5541 ATLASSERT( GetFunctionMap() != NULL
);
5542 pMap
= GetFunctionMap()[nVal
];
5546 pMap
= GetSoapMapFromName(wszName
, cchName
,
5547 wszNamespaceUri
, cchNamespaceUri
, &nVal
, bHeader
);
5552 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::SetSoapMapFromName -- _soapmap not found for: %.*ws, with namespace %.*ws\r\n"),
5553 (int)wcslen(wszName
), wszName
, wszNamespaceUri
? (int)wcslen(wszNamespaceUri
) : 0, wszNamespaceUri
? wszNamespaceUri
: L
"");
5558 HRESULT hr
= E_OUTOFMEMORY
;
5560 // allocate the parameter struct
5562 void *pvParam
= NULL
;
5563 if (bHeader
!= false)
5565 pvParam
= GetHeaderValue();
5569 if (m_bClient
== false)
5571 m_pvParam
= m_pMemMgr
->Allocate(pMap
->nElementSize
);
5573 pvParam
= m_pvParam
;
5576 if (pvParam
!= NULL
)
5578 if (bHeader
== false)
5580 memset(pvParam
, 0x00, pMap
->nElementSize
);
5583 // push initial state
5585 if (m_stateStack
.GetCount() != 0)
5587 m_stateStack
.RemoveAll();
5590 hr
= PushState(pvParam
, pMap
, NULL
, 0, nVal
, pMap
->nElements
);
5594 if ((m_bClient
== false) && (bHeader
== false))
5596 m_pMemMgr
->Free(pvParam
);
5602 if (hr
== E_OUTOFMEMORY
)
5604 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::SetSoapMapFromName -- out of memory.\r\n" ) );
5612 virtual const _soapmap
** GetFunctionMap() = 0;
5613 virtual const _soapmap
** GetHeaderMap() = 0;
5614 virtual const wchar_t * GetNamespaceUri() = 0;
5615 virtual const char * GetServiceName() = 0;
5616 virtual const char * GetNamespaceUriA() = 0;
5617 virtual HRESULT
CallFunction(
5619 const wchar_t *wszLocalName
, int cchLocalName
,
5621 virtual void * GetHeaderValue() = 0;
5625 CSoapRootHandler(ISAXXMLReader
*pReader
= NULL
)
5626 : m_pMemMgr(&m_crtHeap
), m_spReader(pReader
), m_bClient(false),
5627 m_nState(0), m_pvParam(NULL
), m_nDepth(0)
5631 virtual ~CSoapRootHandler()
5633 m_skipHandler
.DetachParent();
5636 IAtlMemMgr
* SetMemMgr(IAtlMemMgr
*pMemMgr
)
5638 IAtlMemMgr
*pPrevMgr
= m_pMemMgr
;
5639 m_pMemMgr
= pMemMgr
;
5644 IAtlMemMgr
* GetMemMgr()
5649 // override this function to do SOAP Fault handling
5650 virtual HRESULT
SoapFault(
5651 SOAP_ERROR_CODE
/*errCode*/,
5652 const wchar_t * /*wszDetail*/,
5655 if (m_bClient
!= false)
5660 // SOAP servers must implement this function
5669 void InitHandlerState()
5671 m_bNullCheck
= false;
5672 m_bCharacters
= false;
5673 m_bChildCheck
= false;
5674 m_dwState
= SOAP_START
;
5676 HRESULT __stdcall
startDocument()
5682 HRESULT __stdcall
startElement(
5683 const wchar_t *wszNamespaceUri
,
5684 int cchNamespaceUri
,
5685 const wchar_t *wszLocalName
,
5687 const wchar_t * wszQName
,
5689 ISAXAttributes
*pAttributes
)
5691 if (m_bNullCheck
|| m_bCharacters
)
5693 // make sure elements that aren't supposed to have child elements
5694 // do not have child elements, and where we were expecting
5695 // characters, we got them
5699 m_bChildCheck
= false;
5705 case SOAP_PARAMS
: case SOAP_HEADERS
:
5707 hr
= ProcessParams(wszNamespaceUri
, cchNamespaceUri
, wszLocalName
,
5708 cchLocalName
, pAttributes
);
5712 case SOAP_START
: case SOAP_ENVELOPE
: case SOAP_HEADERS_DONE
:
5714 ULONG nNamespaceHash
= AtlSoapHashStr(wszNamespaceUri
,
5716 if (nNamespaceHash
!= SOAP_ENV
)
5718 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::startElement -- incorrect SOAP-ENV namespace.\r\n" ) );
5723 ULONG nElementHash
= AtlSoapHashStr(wszLocalName
, cchLocalName
);
5725 if (nElementHash
== ENVELOPE
&&
5727 sizeof(SOAP_ENVELOPEA
)-1, SOAP_ENVELOPEW
,
5728 sizeof(SOAPENV_NAMESPACEA
)-1, SOAPENV_NAMESPACEW
,
5729 cchLocalName
, wszLocalName
,
5730 cchNamespaceUri
, wszNamespaceUri
))
5732 // Envelope must be first element in package
5734 if (m_dwState
!= SOAP_START
)
5736 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::startElement -- invalid SOAP message format: \"Envelope\" in unexpected location.\r\n" ) );
5740 m_dwState
= SOAP_ENVELOPE
;
5742 else if (nElementHash
== HEADER
&&
5743 IsEqualElement(sizeof(SOAP_HEADERA
)-1, SOAP_HEADERW
,
5744 sizeof(SOAPENV_NAMESPACEA
)-1, SOAPENV_NAMESPACEW
,
5745 cchLocalName
, wszLocalName
,
5746 cchNamespaceUri
, wszNamespaceUri
))
5748 if (m_dwState
!= SOAP_ENVELOPE
)
5750 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::startElement -- invalid SOAP message format: \"Headers\" in unexpected location.\r\n" ) );
5755 m_dwState
= SOAP_HEADERS
;
5757 else if (nElementHash
== BODY
&&
5758 IsEqualElement(sizeof(SOAP_BODYA
)-1, SOAP_BODYW
,
5759 sizeof(SOAPENV_NAMESPACEA
)-1, SOAPENV_NAMESPACEW
,
5760 cchLocalName
, wszLocalName
,
5761 cchNamespaceUri
, wszNamespaceUri
))
5763 if (m_dwState
== SOAP_START
)
5765 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::startElement -- invalid SOAP message format: \"Body\" in unexpected location.\r\n" ) );
5769 m_dwState
= SOAP_BODY
;
5776 hr
= DispatchSoapCall(wszNamespaceUri
, cchNamespaceUri
,
5777 wszLocalName
, cchLocalName
);
5779 m_dwState
= SOAP_PARAMS
;
5783 if (GetState().pMap
->dwCallFlags
& SOAPFLAG_PAD
)
5785 hr
= startElement(wszNamespaceUri
, cchNamespaceUri
,
5786 wszLocalName
, cchLocalName
, wszQName
, cchQName
,
5798 // should never get here -- internal error
5808 HRESULT __stdcall
characters(
5809 const wchar_t *wszChars
,
5812 m_bCharacters
= false;
5814 // if it is a ready state, get the value
5815 if (m_stateStack
.IsEmpty() == false)
5817 ParseState
& state
= GetState();
5818 if ((state
.dwFlags
& SOAPFLAG_READYSTATE
) &&
5819 ((state
.dwFlags
& SOAPFLAG_SIZEIS
)==0)) // don't marshal struct size_is elements -- should be filled in by array marshaling code
5821 if ((state
.pMap
== NULL
) || (state
.pMap
->mapType
!= SOAPMAP_ENUM
))
5823 return AtlSoapGetElementValue(wszChars
, cchChars
,
5824 state
.pvElement
, (SOAPTYPES
)state
.pEntry
->nVal
, GetMemMgr());
5830 ATLASSERT( state
.pMap
!= NULL
);
5831 ATLASSERT( state
.pMap
->pEntries
!= NULL
);
5833 ULONG nHash
= AtlSoapHashStr(wszChars
, cchChars
);
5834 const _soapmapentry
*pEntries
= state
.pMap
->pEntries
;
5837 for (i
=0; pEntries
[i
].nHash
!= 0; i
++)
5839 if ((nHash
== pEntries
[i
].nHash
) &&
5840 (cchChars
== pEntries
[i
].cchField
) &&
5841 (!wcsncmp(wszChars
, pEntries
[i
].wszField
, cchChars
)))
5847 if (pEntries
[i
].nHash
!= 0)
5849 *((int *)state
.pvElement
) = pEntries
[i
].nVal
;
5854 // no matching enum entry found
5855 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::characters -- no matching enum entry found for: %.*ws.\r\n" ), cchChars
, wszChars
);
5862 // otherwise, ignore
5867 HRESULT __stdcall
endElement(
5868 const wchar_t * wszNamespaceUri
,
5869 int cchNamespaceUri
,
5870 const wchar_t * wszLocalName
,
5872 const wchar_t * /*wszQName*/,
5875 static bool bDynArrWrapper
= false;
5881 m_bNullCheck
= false;
5883 if (m_stateStack
.IsEmpty() != false)
5888 if (!bDynArrWrapper
&& (m_nState
> 1))
5890 ParseState prevState
= m_stateStack
.GetAt(m_nState
- 1);
5891 ParseState curState
= m_stateStack
.GetAt(m_nState
);
5892 if (prevState
.dwFlags
& SOAPFLAG_DYNARRWRAPPER
)
5894 bDynArrWrapper
= true;
5895 endElement (wszNamespaceUri
, cchNamespaceUri
, curState
.pEntry
->wszField
,
5896 curState
.pEntry
->cchField
, NULL
, 0);
5901 bDynArrWrapper
= false;
5906 const ParseState
& state
= GetState();
5908 if ((m_dwState
== SOAP_HEADERS
) && (m_stateStack
.GetCount() == 1))
5910 return CheckEndHeaders(wszNamespaceUri
, cchNamespaceUri
, wszLocalName
, cchLocalName
);
5913 if (state
.dwFlags
& (SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
))
5915 if (state
.dwFlags
& SOAPFLAG_READYSTATE
)
5920 const ParseState
& currstate
= GetState();
5921 ATLENSURE_RETURN( currstate
.pEntry
!= NULL
);
5923 if (m_nDepth
== (currstate
.nDepth
-1))
5925 if (S_OK
!= CheckEndElement(currstate
))
5927 // invalid number of elements
5928 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::endElement -- invalid number of array elements for array parameter %.*ws.\r\n"),
5929 currstate
.pEntry
->cchField
, currstate
.pEntry
->wszField
);
5939 if (S_OK
!= CheckEndElement(state
))
5950 HRESULT
SetClientStruct(void *pvParam
, int nMapIndex
)
5952 ATLENSURE_RETURN( pvParam
!= NULL
);
5953 ATLENSURE_RETURN( nMapIndex
>= 0 );
5955 // this is the params struct
5956 // store for later use
5957 m_pvParam
= pvParam
;
5959 const _soapmap
** pEntries
= GetHeaderMap();
5960 ATLENSURE_RETURN( pEntries
!= NULL
);
5962 // push header value
5963 return PushState(GetHeaderValue(), pEntries
[nMapIndex
], NULL
, 0, nMapIndex
, pEntries
[nMapIndex
]->nElements
);
5966 void ResetClientState(bool bFull
= false)
5968 m_stateStack
.RemoveAll();
5972 m_dwState
= SOAP_START
;
5977 HRESULT
CreateReader()
5979 return m_spReader
.CoCreateInstance(ATLS_SAXXMLREADER_CLSID
, NULL
, CLSCTX_INPROC_SERVER
);
5982 HRESULT
InitializeSOAP(IServiceProvider
*pProvider
)
5986 if (m_spReader
.p
== NULL
)
5989 if (pProvider
!= NULL
)
5991 IAtlMemMgr
*pMemMgr
= NULL
;
5992 hr
= pProvider
->QueryService(__uuidof(IAtlMemMgr
),
5993 __uuidof(IAtlMemMgr
), (void **)&pMemMgr
);
5994 if ((SUCCEEDED(hr
)) && (pMemMgr
!= NULL
))
5999 hr
= pProvider
->QueryService(__uuidof(ISAXXMLReader
),
6000 __uuidof(ISAXXMLReader
), (void **)&m_spReader
);
6005 hr
= CreateReader();
6011 hr
= m_spReader
->putContentHandler(this);
6017 ATLTRACE( _T("ATLSOAP: CSoapRootHandler::InitializeSOAP -- failed to get SAXXMLReader.\r\n" ) );
6024 void UninitializeSOAP()
6026 if (m_spReader
.p
!= NULL
)
6028 m_spReader
->putContentHandler(NULL
);
6029 m_spReader
.Release();
6033 virtual HRESULT
DispatchSoapCall(const wchar_t *wszNamespaceUri
,
6034 int cchNamespaceUri
, const wchar_t *wszLocalName
,
6039 if (m_stateStack
.IsEmpty() == false)
6041 ATLASSUME( m_stateStack
[0].pMap
!= NULL
);
6043 // check to see if all required and non-nullable SOAP headers were sent
6044 if (m_stateStack
[0].pMap
->mapType
== SOAPMAP_HEADER
)
6046 hr
= CheckSoapHeaders(m_stateStack
[0]);
6050 hr
= SetSoapMapFromName(wszLocalName
, cchLocalName
,
6051 wszNamespaceUri
, cchNamespaceUri
);
6056 // get the appropriate function map
6057 hr
= SetSoapMapFromName(wszLocalName
, cchLocalName
,
6058 wszNamespaceUri
, cchNamespaceUri
);
6062 // set the SOAP Header map for the function
6063 ATLASSUME( m_stateStack
.IsEmpty() == false );
6065 const _soapmap
**ppHeaderMap
= GetHeaderMap();
6066 ATLENSURE_RETURN( ppHeaderMap
!= NULL
);
6068 // create a temporary parse state for checking headers
6070 state
.pMap
= ppHeaderMap
[m_stateStack
[0].nAllocSize
];
6071 ATLENSURE_RETURN( state
.pMap
!= NULL
);
6073 // check to see if all required and non-nullable SOAP headers were sent
6074 hr
= CheckSoapHeaders(state
);
6081 virtual HRESULT
BeginParse(IStream
*pStream
)
6083 ATLASSERT( pStream
!= NULL
);
6085 CComVariant varStream
;
6086 varStream
= static_cast<IUnknown
*>(pStream
);
6088 HRESULT hr
= m_spReader
->parse(varStream
);
6091 if (m_refMap
.GetCount() != 0)
6099 HRESULT
CallFunctionInternal()
6101 HRESULT hr
= E_FAIL
;
6102 const ParseState
& state
= m_stateStack
[0];
6105 state
.pMap
->wszName
,
6106 state
.pMap
->cchWName
,
6112 virtual HRESULT
GenerateResponse(IWriteStream
*pStream
)
6114 ATLASSUME( m_stateStack
.IsEmpty() == false );
6115 ATLASSUME( m_stateStack
[0].pMap
!= NULL
);
6116 ATLASSUME( m_stateStack
[0].pvElement
!= NULL
);
6118 const ParseState
& state
= m_stateStack
[0];
6120 const _soapmap
*pHeaderMap
= NULL
;
6121 if (m_bClient
== false)
6123 const _soapmap
**ppHeaderMap
= GetHeaderMap();
6124 if (ppHeaderMap
!= NULL
)
6126 pHeaderMap
= ppHeaderMap
[state
.nAllocSize
];
6131 pHeaderMap
= state
.pMap
;
6134 const _soapmap
*pFuncMap
= NULL
;
6135 if (m_bClient
== false)
6137 pFuncMap
= state
.pMap
;
6141 const _soapmap
**ppFuncMap
= GetFunctionMap();
6142 ATLENSURE_RETURN( ppFuncMap
!= NULL
);
6143 pFuncMap
= ppFuncMap
[state
.nAllocSize
];
6146 ATLENSURE_RETURN( pFuncMap
!= NULL
);
6148 CRpcEncodedGenerator rpcGen
;
6149 CPADGenerator padGen
;
6150 CPIDGenerator pidGen
;
6152 CResponseGenerator
*pGenerator
= NULL
;
6154 if ((pFuncMap
->dwCallFlags
& (SOAPFLAG_RPC
| SOAPFLAG_ENCODED
)) == (SOAPFLAG_RPC
| SOAPFLAG_ENCODED
))
6156 pGenerator
= &rpcGen
;
6158 else if (pFuncMap
->dwCallFlags
& SOAPFLAG_PID
)
6160 ATLASSERT( (pFuncMap
->dwCallFlags
& (SOAPFLAG_DOCUMENT
| SOAPFLAG_LITERAL
)) == (SOAPFLAG_DOCUMENT
| SOAPFLAG_LITERAL
) );
6161 pGenerator
= &pidGen
;
6165 ATLASSERT( (pFuncMap
->dwCallFlags
& (SOAPFLAG_DOCUMENT
| SOAPFLAG_LITERAL
)) == (SOAPFLAG_DOCUMENT
| SOAPFLAG_LITERAL
) );
6166 ATLASSERT( pFuncMap
->dwCallFlags
& SOAPFLAG_PAD
);
6167 pGenerator
= &padGen
;
6170 HRESULT hr
= pGenerator
->StartEnvelope(pStream
);
6173 // generate headers if necessary
6174 hr
= GenerateHeaders(pGenerator
, pHeaderMap
, pStream
);
6177 hr
= pGenerator
->StartBody(pStream
);
6180 hr
= GenerateResponseHelper(pGenerator
, pFuncMap
, m_pvParam
, pStream
, true);
6183 hr
= pGenerator
->EndBody(pStream
);
6186 hr
= pGenerator
->EndEnvelope(pStream
);
6196 virtual void Cleanup()
6201 if ((m_stateStack
.IsEmpty() == false) && (m_pvParam
!= NULL
))
6203 const _soapmap
**ppFuncMap
= GetFunctionMap();
6204 ATLENSURE( ppFuncMap
!= NULL
);
6206 const _soapmap
*pFuncMap
= ppFuncMap
[m_stateStack
[0].nAllocSize
];
6207 ATLENSURE( pFuncMap
!= NULL
);
6209 CleanupHelper(pFuncMap
, m_pvParam
);
6210 if (m_bClient
== false)
6212 m_pMemMgr
->Free(m_pvParam
);
6213 m_stateStack
.RemoveAll();
6218 virtual void CleanupHeaders()
6220 if (m_stateStack
.IsEmpty() == false)
6222 const _soapmap
**ppHeaderMap
= GetHeaderMap();
6223 ATLENSURE( ppHeaderMap
!= NULL
);
6225 const _soapmap
*pHeaderMap
= ppHeaderMap
[m_stateStack
[0].nAllocSize
];
6226 ATLENSURE( pHeaderMap
!= NULL
);
6228 CleanupHelper(pHeaderMap
, GetHeaderValue());
6232 void SetClient(bool bClient
)
6234 m_bClient
= bClient
;
6237 }; // class CSoapRootHandler
6239 #define DECLARE_XSD_ENTRY( __name ) \
6240 { L ## __name, __name, sizeof(__name)-1 },
6242 __declspec(selectany
) const CSoapRootHandler::XSDEntry
CSoapRootHandler::s_xsdNames
[] =
6244 DECLARE_XSD_ENTRY("string")
6245 DECLARE_XSD_ENTRY("boolean")
6246 DECLARE_XSD_ENTRY("float")
6247 DECLARE_XSD_ENTRY("double")
6248 DECLARE_XSD_ENTRY("decimal")
6249 DECLARE_XSD_ENTRY("duration")
6250 DECLARE_XSD_ENTRY("hexBinary")
6251 DECLARE_XSD_ENTRY("base64Binary")
6252 DECLARE_XSD_ENTRY("anyURI")
6253 DECLARE_XSD_ENTRY("ID")
6254 DECLARE_XSD_ENTRY("IDREF")
6255 DECLARE_XSD_ENTRY("ENTITY")
6256 DECLARE_XSD_ENTRY("NOTATION")
6257 DECLARE_XSD_ENTRY("QName")
6258 DECLARE_XSD_ENTRY("normalizedString")
6259 DECLARE_XSD_ENTRY("token")
6260 DECLARE_XSD_ENTRY("language")
6261 DECLARE_XSD_ENTRY("IDREFS")
6262 DECLARE_XSD_ENTRY("ENTITIES")
6263 DECLARE_XSD_ENTRY("NMTOKEN")
6264 DECLARE_XSD_ENTRY("NMTOKENS")
6265 DECLARE_XSD_ENTRY("Name")
6266 DECLARE_XSD_ENTRY("NCName")
6267 DECLARE_XSD_ENTRY("integer")
6268 DECLARE_XSD_ENTRY("nonPositiveInteger")
6269 DECLARE_XSD_ENTRY("negativeInteger")
6270 DECLARE_XSD_ENTRY("long")
6271 DECLARE_XSD_ENTRY("int")
6272 DECLARE_XSD_ENTRY("short")
6273 DECLARE_XSD_ENTRY("byte")
6274 DECLARE_XSD_ENTRY("nonNegativeInteger")
6275 DECLARE_XSD_ENTRY("unsignedLong")
6276 DECLARE_XSD_ENTRY("unsignedInt")
6277 DECLARE_XSD_ENTRY("unsignedShort")
6278 DECLARE_XSD_ENTRY("unsignedByte")
6279 DECLARE_XSD_ENTRY("positiveInteger")
6280 DECLARE_XSD_ENTRY("dateTime")
6281 DECLARE_XSD_ENTRY("time")
6282 DECLARE_XSD_ENTRY("date")
6283 DECLARE_XSD_ENTRY("gMonth")
6284 DECLARE_XSD_ENTRY("gYearMonth")
6285 DECLARE_XSD_ENTRY("gYear")
6286 DECLARE_XSD_ENTRY("gMonthDay")
6287 DECLARE_XSD_ENTRY("gDay")
6290 __declspec(selectany
) CCRTHeap
CSoapRootHandler::m_crtHeap
;
6292 template <typename THandler
>
6293 class CSoapHandler
:
6294 public CSoapRootHandler
,
6295 public CComObjectRootEx
<CComMultiThreadModel
>,
6296 public IRequestHandlerImpl
<THandler
>
6301 CHttpResponse
*m_pHttpResponse
;
6303 // heap for SOAP requests
6306 // default heap is COM heap (SOAP Servers can double as COM objects)
6311 BEGIN_COM_MAP(CSoapHandler
<THandler
>)
6312 COM_INTERFACE_ENTRY(ISAXContentHandler
)
6313 COM_INTERFACE_ENTRY(IRequestHandler
)
6317 :m_pHttpResponse(NULL
), m_hcErr(HTTP_SUCCESS
)
6319 SetMemMgr(&m_comHeap
);
6322 void SetHttpError(HTTP_CODE hcErr
)
6328 SOAP_ERROR_CODE errCode
,
6329 const wchar_t *wszDetail
,
6332 ATLASSUME( m_pHttpResponse
!= NULL
);
6334 SetHttpError(AtlsHttpError(500, SUBERR_NO_PROCESS
));
6336 m_pHttpResponse
->ClearHeaders();
6337 m_pHttpResponse
->ClearContent();
6338 m_pHttpResponse
->SetContentType("text/xml");
6339 m_pHttpResponse
->SetStatusCode(500);
6342 if (wszDetail
!= NULL
)
6346 cchDetail
= (int) wcslen(wszDetail
);
6351 fault
.m_strDetail
.SetString(wszDetail
, cchDetail
);
6355 ATLTRACE( _T("CSoapHandler::SoapFault -- out of memory.\r\n" ) );
6357 return E_OUTOFMEMORY
;
6361 fault
.m_soapErrCode
= errCode
;
6362 fault
.GenerateFault(m_pHttpResponse
);
6366 HTTP_CODE
InitializeHandler(AtlServerRequest
*pRequestInfo
, IServiceProvider
*pProvider
)
6368 m_hcErr
= IRequestHandlerImpl
<THandler
>::InitializeHandler(pRequestInfo
, pProvider
);
6369 if (m_hcErr
== HTTP_SUCCESS
)
6371 HRESULT hr
= InitializeSOAP(m_spServiceProvider
);
6374 // try to use the per-thread heap
6375 CIsapiWorker
*pWorker
= pRequestInfo
->pExtension
->GetThreadWorker();
6376 if (pWorker
!= NULL
)
6378 m_heap
.Attach(pWorker
->m_hHeap
, false);
6386 // some initialization failure
6387 CHttpResponse
HttpResponse(pRequestInfo
->pServerContext
);
6388 m_pHttpResponse
= &HttpResponse
;
6390 SoapFault(SOAP_E_SERVER
, NULL
, 0);
6392 m_pHttpResponse
= NULL
;
6397 HTTP_CODE
HandleRequest(AtlServerRequest
*pRequestInfo
, IServiceProvider
* /*pProvider*/)
6399 // SOAPACTION header is required per the SOAP 1.1
6400 // mainly so firewalls can filter on it.
6401 char szBuf
[ATL_URL_MAX_URL_LENGTH
+1];
6403 DWORD dwLen
= ATL_URL_MAX_URL_LENGTH
;
6404 if ( m_spServerContext
->GetServerVariable("HTTP_SOAPACTION", szBuf
, &dwLen
) != FALSE
)
6409 szBuf
[dwLen
-2] = '\0';
6410 char *szMethod
= strrchr(szBuf
, '#');
6411 if (szMethod
!= NULL
)
6415 // ignore return code here
6416 SetSoapMapFromName(CA2W( szMethod
+1 ), -1, GetNamespaceUri(), -1, true);
6420 return AtlsHttpError(500, ISE_SUBERR_OUTOFMEM
);
6427 // SOAP requestion that use the HTTP transport
6428 // must have a SOAPACTION header.
6429 return HTTP_ERROR(500, ISE_SUBERR_SOAPNOSOAPACTION
);
6432 // set the header map
6433 CHttpResponse
HttpResponse(pRequestInfo
->pServerContext
);
6434 m_pHttpResponse
= &HttpResponse
;
6436 CStreamOnServerContext
s(pRequestInfo
->pServerContext
);
6440 CSAXSoapErrorHandler err
;
6441 GetReader()->putErrorHandler(&err
);
6445 HRESULT hr
= BeginParse(&s
);
6448 // release the error handler
6449 GetReader()->putErrorHandler(NULL
);
6455 if (m_hcErr
== HTTP_SUCCESS
)
6457 SoapFault(SOAP_E_CLIENT
, NULL
, NULL
);
6465 hr
= CallFunctionInternal();
6469 // cleanup before propagating user exception
6471 HttpResponse
.Detach();
6478 HttpResponse
.ClearHeaders();
6479 HttpResponse
.ClearContent();
6480 if (m_hcErr
!= HTTP_SUCCESS
)
6482 HttpResponse
.SetStatusCode(HTTP_ERROR_CODE(m_hcErr
));
6483 return HTTP_SUCCESS_NO_PROCESS
;
6485 HttpResponse
.SetStatusCode(500);
6486 GenerateAppError(&HttpResponse
, hr
);
6487 return AtlsHttpError(500, SUBERR_NO_PROCESS
);
6490 HttpResponse
.SetContentType("text/xml");
6491 hr
= GenerateResponse(&HttpResponse
);
6495 SoapFault(SOAP_E_SERVER
, NULL
, 0);
6499 return HTTP_SUCCESS
;
6502 virtual ATL_NOINLINE HRESULT
GenerateAppError(IWriteStream
*pStream
, HRESULT hr
)
6504 if (pStream
== NULL
)
6506 return E_INVALIDARG
;
6509 LPWSTR pwszMessage
= NULL
;
6510 DWORD dwLen
= ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
|FORMAT_MESSAGE_FROM_SYSTEM
,
6511 NULL
, hr
, 0, (LPWSTR
) &pwszMessage
, 0, NULL
);
6515 pwszMessage
= L
"Application Error";
6518 hr
= SoapFault(SOAP_E_SERVER
, pwszMessage
, dwLen
? dwLen
: -1);
6521 ::LocalFree(pwszMessage
);
6527 void UninitializeHandler()
6534 // client error states
6535 enum SOAPCLIENT_ERROR
6537 SOAPCLIENT_SUCCESS
=0, // everything succeeded
6538 SOAPCLIENT_INITIALIZE_ERROR
, // initialization failed -- most likely an MSXML installation problem
6539 SOAPCLIENT_OUTOFMEMORY
, // out of memory
6540 SOAPCLIENT_GENERATE_ERROR
, // failed in generating the response
6541 SOAPCLIENT_CONNECT_ERROR
, // failed connecting to server
6542 SOAPCLIENT_SEND_ERROR
, // failed in sending message
6543 SOAPCLIENT_SERVER_ERROR
, // server error
6544 SOAPCLIENT_SOAPFAULT
, // a SOAP Fault was returned by the server
6545 SOAPCLIENT_PARSEFAULT_ERROR
, // failed in parsing SOAP fault
6546 SOAPCLIENT_READ_ERROR
, // failed in reading response
6547 SOAPCLIENT_PARSE_ERROR
// failed in parsing response
6550 template <typename TSocketClass
= ZEvtSyncSocket
>
6551 class CSoapSocketClientT
6556 CWriteStreamOnCString m_writeStream
;
6557 CReadStreamOnSocket
<TSocketClass
> m_readStream
;
6560 SOAPCLIENT_ERROR m_errorState
;
6564 virtual HRESULT
GetClientReader(ISAXXMLReader
**pReader
)
6566 if (pReader
== NULL
)
6572 CComPtr
<ISAXXMLReader
> spReader
;
6573 HRESULT hr
= spReader
.CoCreateInstance(ATLS_SAXXMLREADER_CLSID
, NULL
, CLSCTX_INPROC_SERVER
);
6576 *pReader
= spReader
.Detach();
6583 // note : not shared across stock client implementations
6584 CAtlHttpClientT
<TSocketClass
> m_socket
;
6589 CSoapSocketClientT(LPCTSTR szUrl
)
6590 : m_dwTimeout(0), m_errorState(SOAPCLIENT_SUCCESS
)
6592 TCHAR szTmp
[ATL_URL_MAX_URL_LENGTH
];
6593 if(AtlEscapeUrl(szUrl
,szTmp
,0,ATL_URL_MAX_URL_LENGTH
-1,ATL_URL_BROWSER_MODE
))
6594 m_url
.CrackUrl(szTmp
);
6597 CSoapSocketClientT(LPCTSTR szServer
, LPCTSTR szUri
, ATL_URL_PORT nPort
=80)
6598 : m_dwTimeout(0), m_errorState(SOAPCLIENT_SUCCESS
)
6600 ATLASSERT( szServer
!= NULL
);
6601 ATLASSERT( szUri
!= NULL
);
6603 m_url
.SetUrlPath(szUri
);
6604 m_url
.SetHostName(szServer
);
6605 m_url
.SetPortNumber(nPort
);
6608 ~CSoapSocketClientT()
6613 SOAPCLIENT_ERROR
GetClientError()
6615 return m_errorState
;
6618 void SetClientError(SOAPCLIENT_ERROR errorState
)
6620 m_errorState
= errorState
;
6623 IWriteStream
* GetWriteStream()
6625 return &m_writeStream
;
6628 HRESULT
GetReadStream(IStream
**ppStream
)
6630 if (ppStream
== NULL
)
6635 *ppStream
= &m_readStream
;
6639 void CleanupClient()
6641 m_writeStream
.Cleanup();
6643 SetClientError(SOAPCLIENT_SUCCESS
);
6646 HRESULT
SendRequest(LPCTSTR szAction
)
6648 HRESULT hr
= E_FAIL
;
6651 // create extra headers to send with request
6652 CFixedStringT
<CString
, 256> strExtraHeaders(szAction
);
6653 strExtraHeaders
.Append(_T("Accept: text/xml\r\n"), sizeof("Accept: text/xml\r\n")-1);
6654 CAtlNavigateData navData
;
6655 navData
.SetMethod(ATL_HTTP_METHOD_POST
);
6656 navData
.SetPort(m_url
.GetPortNumber());
6657 navData
.SetExtraHeaders(strExtraHeaders
);
6658 navData
.SetPostData((LPBYTE
)(LPCSTR
) m_writeStream
.m_str
, m_writeStream
.m_str
.GetLength(), _T("text/xml; charset=utf-8"));
6660 ATLSOAP_TRACE( (LPBYTE
)(LPCSTR
)m_writeStream
.m_str
, m_writeStream
.m_str
.GetLength() );
6662 if (m_dwTimeout
!= 0)
6664 navData
.SetSocketTimeout(m_dwTimeout
);
6667 if (m_socket
.Navigate(&m_url
, &navData
) != false)
6669 if (GetStatusCode() == 200)
6671 hr
= (m_readStream
.Init(&m_socket
) != FALSE
? S_OK
: E_FAIL
);
6674 SetClientError(SOAPCLIENT_READ_ERROR
);
6677 else if (GetStatusCode() == 202)
6679 // for one-way methods
6684 SetClientError(SOAPCLIENT_SERVER_ERROR
);
6687 else if (GetStatusCode() == 500)
6689 SetClientError(SOAPCLIENT_SOAPFAULT
);
6691 // if returned 500, get the SOAP fault
6692 if (m_readStream
.Init(&m_socket
) != FALSE
)
6694 CComPtr
<ISAXXMLReader
> spReader
;
6695 if (SUCCEEDED(GetClientReader(&spReader
)))
6697 CComPtr
<IStream
> spReadStream
;
6698 if (SUCCEEDED(GetReadStream(&spReadStream
)))
6700 if (FAILED(m_fault
.ParseFault(spReadStream
, spReader
)))
6702 SetClientError(SOAPCLIENT_PARSEFAULT_ERROR
);
6710 SetClientError(SOAPCLIENT_SEND_ERROR
);
6721 HRESULT
SetUrl(LPCTSTR szUrl
)
6723 TCHAR szTmp
[ATL_URL_MAX_URL_LENGTH
];
6724 if(!AtlEscapeUrl(szUrl
,szTmp
,0,ATL_URL_MAX_URL_LENGTH
-1,ATL_URL_BROWSER_MODE
))
6729 return (m_url
.CrackUrl(szTmp
) != FALSE
) ? S_OK
: E_FAIL
;
6732 HRESULT
GetUrl(__out_ecount_part_z(*pdwLen
, *pdwLen
) LPTSTR szUrl
, __inout LPDWORD pdwLen
)
6734 if ((szUrl
== NULL
) || (pdwLen
== NULL
))
6736 return E_INVALIDARG
;
6739 return (m_url
.CreateUrl(szUrl
, pdwLen
) != FALSE
) ? S_OK
: E_FAIL
;
6742 HRESULT
SetProxy(LPCTSTR szProxy
= NULL
, short nProxyPort
= 80)
6744 BOOL bRet
= m_socket
.SetProxy(szProxy
, nProxyPort
);
6745 return (bRet
!= FALSE
) ? S_OK
: E_FAIL
;
6748 void SetTimeout(DWORD dwTimeout
)
6750 m_dwTimeout
= dwTimeout
;
6755 return m_socket
.GetStatus();
6758 }; // CSoapSocketClientT
6760 #ifndef ATLSOAP_NOWININET
6762 class CReadStreamOnInet
: public IStreamImpl
6766 HRESULT __stdcall
QueryInterface(REFIID riid
, void **ppv
)
6775 if (InlineIsEqualGUID(riid
, IID_IUnknown
) ||
6776 InlineIsEqualGUID(riid
, IID_IStream
) ||
6777 InlineIsEqualGUID(riid
, IID_ISequentialStream
))
6779 *ppv
= static_cast<IStream
*>(this);
6783 return E_NOINTERFACE
;
6786 ULONG __stdcall
AddRef()
6791 ULONG __stdcall
Release()
6807 void Init(HINTERNET hFile
)
6812 HRESULT STDMETHODCALLTYPE
Read(void *pDest
, ULONG dwMaxLen
, ULONG
*pdwRead
)
6814 BOOL bRet
= InternetReadFile(m_hFile
, pDest
, dwMaxLen
, pdwRead
);
6815 return (bRet
!= FALSE
) ? S_OK
: E_FAIL
;
6820 class CSoapWininetClient
6825 CWriteStreamOnCString m_writeStream
;
6826 CReadStreamOnInet m_readStream
;
6829 CFixedStringT
<CString
, ATL_URL_MAX_URL_LENGTH
+1> m_strUrl
;
6830 SOAPCLIENT_ERROR m_errorState
;
6834 if (m_hRequest
!= NULL
)
6836 InternetCloseHandle(m_hRequest
);
6839 if (m_hConnection
!= NULL
)
6841 InternetCloseHandle(m_hConnection
);
6842 m_hConnection
= NULL
;
6844 if (m_hInternet
!= NULL
)
6846 InternetCloseHandle(m_hInternet
);
6851 HRESULT
ConnectToServer()
6853 if (m_hConnection
!= NULL
)
6858 m_hInternet
= InternetOpen(
6860 m_strProxy
.GetLength() ? (INTERNET_OPEN_TYPE_PRECONFIG
| INTERNET_OPEN_TYPE_PROXY
) : INTERNET_OPEN_TYPE_PRECONFIG
,
6861 m_strProxy
.GetLength() ? (LPCTSTR
) m_strProxy
: NULL
,
6864 if (m_hInternet
!= NULL
)
6866 if (m_dwTimeout
!= 0)
6868 InternetSetOption(m_hInternet
, INTERNET_OPTION_CONNECT_TIMEOUT
,
6869 &m_dwTimeout
, sizeof(m_dwTimeout
));
6870 InternetSetOption(m_hInternet
, INTERNET_OPTION_RECEIVE_TIMEOUT
,
6871 &m_dwTimeout
, sizeof(m_dwTimeout
));
6872 InternetSetOption(m_hInternet
, INTERNET_OPTION_SEND_TIMEOUT
,
6873 &m_dwTimeout
, sizeof(m_dwTimeout
));
6875 m_hConnection
= InternetConnect(m_hInternet
, m_url
.GetHostName(),
6876 (INTERNET_PORT
) m_url
.GetPortNumber(), NULL
, NULL
,
6877 INTERNET_SERVICE_HTTP
, 0, NULL
);
6879 if (m_hConnection
!= NULL
)
6890 virtual HRESULT
GetClientReader(ISAXXMLReader
**pReader
)
6892 if (pReader
== NULL
)
6898 CComPtr
<ISAXXMLReader
> spReader
;
6899 HRESULT hr
= spReader
.CoCreateInstance(ATLS_SAXXMLREADER_CLSID
, NULL
, CLSCTX_INPROC_SERVER
);
6902 *pReader
= spReader
.Detach();
6909 // note : not shared across stock client implementations
6910 HINTERNET m_hInternet
;
6911 HINTERNET m_hConnection
;
6912 HINTERNET m_hRequest
;
6916 CSoapWininetClient(LPCTSTR szUrl
)
6917 :m_hInternet(NULL
), m_hConnection(NULL
), m_hRequest(NULL
), m_dwTimeout(0), m_errorState(SOAPCLIENT_SUCCESS
)
6919 TCHAR szTmp
[ATL_URL_MAX_URL_LENGTH
];
6920 if(AtlEscapeUrl(szUrl
,szTmp
,0,ATL_URL_MAX_URL_LENGTH
-1,ATL_URL_BROWSER_MODE
))
6922 if (m_url
.CrackUrl(szTmp
) != FALSE
)
6927 m_strUrl
.SetString(m_url
.GetUrlPath(), m_url
.GetUrlPathLength());
6928 m_strUrl
.Append(m_url
.GetExtraInfo(), m_url
.GetExtraInfoLength());
6937 CSoapWininetClient(LPCTSTR szServer
, LPCTSTR szUri
, short nPort
=80)
6938 :m_hInternet(NULL
), m_hConnection(NULL
), m_hRequest(NULL
), m_dwTimeout(0), m_errorState(SOAPCLIENT_SUCCESS
)
6940 if (m_url
.SetHostName(szServer
) != FALSE
)
6942 if (m_url
.SetUrlPath(szUri
) != FALSE
)
6944 if (m_url
.SetPortNumber((ATL_URL_PORT
) nPort
) != FALSE
)
6948 m_strUrl
.SetString(m_url
.GetUrlPath(), m_url
.GetUrlPathLength());
6949 m_strUrl
.Append(m_url
.GetExtraInfo(), m_url
.GetExtraInfoLength());
6959 virtual ~CSoapWininetClient()
6965 SOAPCLIENT_ERROR
GetClientError()
6967 return m_errorState
;
6970 void SetClientError(SOAPCLIENT_ERROR errorState
)
6972 m_errorState
= errorState
;
6975 IWriteStream
* GetWriteStream()
6977 return &m_writeStream
;
6980 HRESULT
GetReadStream(IStream
**ppStream
)
6982 if (ppStream
== NULL
)
6987 *ppStream
= &m_readStream
;
6991 void CleanupClient()
6993 m_writeStream
.Cleanup();
6994 if (m_hRequest
!= NULL
)
6996 InternetCloseHandle(m_hRequest
);
7000 SetClientError(SOAPCLIENT_SUCCESS
);
7003 HRESULT
SendRequest(LPCTSTR szAction
)
7005 if (ConnectToServer() != S_OK
)
7007 SetClientError(SOAPCLIENT_CONNECT_ERROR
);
7014 strHeaders
.Append(szAction
);
7015 strHeaders
.Append(_T("Content-Type: text/xml; charset=utf-8\r\n"));
7019 return E_OUTOFMEMORY
;
7022 static LPCTSTR s_szAcceptTypes
[] = { _T("text/*"), NULL
};
7023 m_hRequest
= HttpOpenRequest(m_hConnection
, _T("POST"),
7024 m_strUrl
, _T("HTTP/1.0"), NULL
,
7026 INTERNET_FLAG_NO_UI
| INTERNET_FLAG_KEEP_CONNECTION
| ((m_url
.GetScheme() == ATL_URL_SCHEME_HTTPS
) ? INTERNET_FLAG_SECURE
: 0)
7029 if (m_hRequest
!= NULL
)
7031 if (FALSE
!= HttpSendRequest(m_hRequest
, strHeaders
, (DWORD
) strHeaders
.GetLength(),
7032 (void *)(LPCSTR
)m_writeStream
.m_str
, m_writeStream
.m_str
.GetLength()))
7034 m_readStream
.Init(m_hRequest
);
7035 if (GetStatusCode() != HTTP_STATUS_SERVER_ERROR
)
7041 SetClientError(SOAPCLIENT_SOAPFAULT
);
7043 CComPtr
<ISAXXMLReader
> spReader
;
7044 if (SUCCEEDED(GetClientReader(&spReader
)))
7046 CComPtr
<IStream
> spReadStream
;
7047 if (SUCCEEDED(GetReadStream(&spReadStream
)))
7049 if (FAILED(m_fault
.ParseFault(spReadStream
, spReader
)))
7051 SetClientError(SOAPCLIENT_PARSEFAULT_ERROR
);
7060 SetClientError(SOAPCLIENT_SEND_ERROR
);
7066 HRESULT
SetUrl(LPCTSTR szUrl
)
7069 TCHAR szTmp
[ATL_URL_MAX_URL_LENGTH
];
7070 if(!AtlEscapeUrl(szUrl
,szTmp
,0,ATL_URL_MAX_URL_LENGTH
-1,ATL_URL_BROWSER_MODE
))
7075 if (m_url
.CrackUrl(szTmp
) != FALSE
)
7079 m_strUrl
.SetString(m_url
.GetUrlPath(), m_url
.GetUrlPathLength());
7080 m_strUrl
.Append(m_url
.GetExtraInfo(), m_url
.GetExtraInfoLength());
7084 return E_OUTOFMEMORY
;
7091 HRESULT
GetUrl(LPTSTR szUrl
, LPDWORD pdwLen
)
7093 if ((szUrl
== NULL
) || (pdwLen
== NULL
))
7095 return E_INVALIDARG
;
7098 return (m_url
.CreateUrl(szUrl
, pdwLen
) != FALSE
) ? S_OK
: E_FAIL
;
7101 HRESULT
SetProxy(LPCTSTR szProxy
= NULL
, short nProxyPort
= 80)
7105 if (szProxy
&& szProxy
[0])
7107 m_strProxy
.Format(_T("http=http://%s:%d https=http://%s:%d"), szProxy
, nProxyPort
, szProxy
, nProxyPort
);
7116 return E_OUTOFMEMORY
;
7122 void SetTimeout(DWORD dwTimeout
)
7124 m_dwTimeout
= dwTimeout
;
7131 if (HttpQueryInfo(m_hRequest
, HTTP_QUERY_STATUS_CODE
, szBuf
, &dwLen
, NULL
))
7133 szBuf
[dwLen
] = '\0';
7134 return _ttoi(szBuf
);
7138 }; // CSoapWininetClient
7141 #ifndef ATLSOAP_NOMSXML_INET
7142 class CSoapMSXMLInetClient
7147 CWriteStreamOnCString m_writeStream
;
7149 SOAPCLIENT_ERROR m_errorState
;
7151 HRESULT
ConnectToServer()
7153 TCHAR szURL
[ATL_URL_MAX_URL_LENGTH
];
7154 DWORD dwLen
= ATL_URL_MAX_URL_LENGTH
;
7155 HRESULT hr
= E_FAIL
;
7157 if (m_spHttpRequest
)
7160 if (!m_url
.CreateUrl(szURL
, &dwLen
))
7164 hr
= m_spHttpRequest
.CoCreateInstance(__uuidof(ServerXMLHTTP30
));
7169 hr
= m_spHttpRequest
->open( CComBSTR(L
"POST"),
7171 CComVariant(VARIANT_BOOL(VARIANT_FALSE
)),
7176 m_spHttpRequest
.Release();
7185 virtual HRESULT
GetClientReader(ISAXXMLReader
**pReader
)
7187 if (pReader
== NULL
)
7193 CComPtr
<ISAXXMLReader
> spReader
;
7194 HRESULT hr
= spReader
.CoCreateInstance(ATLS_SAXXMLREADER_CLSID
, NULL
, CLSCTX_INPROC_SERVER
);
7197 *pReader
= spReader
.Detach();
7204 // note : not shared across stock client implementations
7205 CComPtr
<IServerXMLHTTPRequest
> m_spHttpRequest
;
7209 CSoapMSXMLInetClient(LPCTSTR szUrl
)
7210 :m_dwTimeout(0), m_errorState(SOAPCLIENT_SUCCESS
)
7212 m_url
.CrackUrl(szUrl
);
7215 CSoapMSXMLInetClient(LPCTSTR szServer
, LPCTSTR szUri
, short nPort
=80)
7216 : m_dwTimeout(0), m_errorState(SOAPCLIENT_SUCCESS
)
7218 m_url
.SetHostName(szServer
);
7219 m_url
.SetUrlPath(szUri
);
7220 m_url
.SetPortNumber((ATL_URL_PORT
) nPort
);
7223 virtual ~CSoapMSXMLInetClient()
7228 SOAPCLIENT_ERROR
GetClientError()
7230 return m_errorState
;
7233 void SetClientError(SOAPCLIENT_ERROR errorState
)
7235 m_errorState
= errorState
;
7238 IWriteStream
* GetWriteStream()
7240 return &m_writeStream
;
7243 HRESULT
GetReadStream(IStream
**ppStream
)
7245 if (ppStream
== NULL
)
7251 HRESULT hr
= E_FAIL
;
7253 if (m_spHttpRequest
)
7255 VARIANT vResponseStream
;
7256 VariantInit(&vResponseStream
);
7257 hr
= m_spHttpRequest
->get_responseStream(&vResponseStream
);
7261 if ((vResponseStream
.vt
== VT_UNKNOWN
) && (vResponseStream
.punkVal
!= NULL
))
7263 // we return the refcount with the pointer!
7264 hr
= vResponseStream
.punkVal
->QueryInterface(__uuidof(IStream
), (void **)ppStream
);
7268 SetClientError(SOAPCLIENT_READ_ERROR
);
7271 VariantClear(&vResponseStream
);
7276 void CleanupClient()
7278 m_writeStream
.Cleanup();
7279 m_spHttpRequest
.Release();
7281 SetClientError(SOAPCLIENT_SUCCESS
);
7284 HRESULT
SendRequest(LPCTSTR szAction
)
7286 if (ConnectToServer() != S_OK
)
7288 SetClientError(SOAPCLIENT_CONNECT_ERROR
);
7292 // set the action header
7293 LPCTSTR szColon
= _tcschr(szAction
, _T(':'));
7294 if (szColon
!= NULL
)
7299 } while (_istspace(static_cast<unsigned char>(*szColon
)));
7301 if (FAILED(m_spHttpRequest
->setRequestHeader(
7302 CComBSTR( L
"SOAPAction" ), CComBSTR( szColon
))))
7304 SetClientError(SOAPCLIENT_SEND_ERROR
);
7307 } // if SOAPAction header not properly formed, attempt to send anyway
7309 if (FAILED(m_spHttpRequest
->setRequestHeader(CComBSTR( L
"Content-Type" ), CComBSTR(L
"text/xml; charset=utf-8"))))
7311 SetClientError(SOAPCLIENT_SEND_ERROR
);
7316 if (m_dwTimeout
!= 0)
7318 long nTimeout
= (long) m_dwTimeout
;
7319 m_spHttpRequest
->setTimeouts(nTimeout
, nTimeout
, nTimeout
, nTimeout
);
7324 CComVariant
vBody(m_writeStream
.m_str
);
7325 HRESULT hr
= m_spHttpRequest
->send(vBody
);
7326 if ((SUCCEEDED(hr
)) && (GetStatusCode() == 500))
7329 CComPtr
<ISAXXMLReader
> spReader
;
7330 if (SUCCEEDED(GetClientReader(&spReader
)))
7332 SetClientError(SOAPCLIENT_SOAPFAULT
);
7334 CComPtr
<IStream
> spReadStream
;
7335 if (SUCCEEDED(GetReadStream(&spReadStream
)))
7337 if (FAILED(m_fault
.ParseFault(spReadStream
, spReader
)))
7339 SetClientError(SOAPCLIENT_PARSEFAULT_ERROR
);
7344 else if (FAILED(hr
))
7346 SetClientError(SOAPCLIENT_SEND_ERROR
);
7352 HRESULT
SetUrl(LPCTSTR szUrl
)
7355 return (m_url
.CrackUrl(szUrl
) != FALSE
? S_OK
: E_FAIL
);
7358 HRESULT
GetUrl(LPTSTR szUrl
, LPDWORD pdwLen
)
7360 if ((szUrl
== NULL
) || (pdwLen
== NULL
))
7362 return E_INVALIDARG
;
7365 return (m_url
.CreateUrl(szUrl
, pdwLen
) != FALSE
) ? S_OK
: E_FAIL
;
7368 void SetTimeout(DWORD dwTimeout
)
7370 m_dwTimeout
= dwTimeout
;
7376 if (m_spHttpRequest
->get_status(&lStatus
) == S_OK
)
7378 return (int) lStatus
;
7383 HRESULT
SetProxy(LPCTSTR szProxy
= NULL
, short nProxyPort
= 80)
7388 ATLTRACE( _T("CSoapMSXMLInetClient does not support SetProxy") );
7392 }; // CSoapMSXMLInetClient
7396 class _CSDLGenerator
: public ITagReplacerImpl
<_CSDLGenerator
>
7400 typedef CAtlMap
<CStringA
, const _soapmap
*, CStringElementTraits
<CStringA
> > WSDLMAP
;
7401 typedef CAtlMap
<CStringA
, const _soapmapentry
*, CStringElementTraits
<CStringA
> > HEADERMAP
;
7403 HRESULT
GenerateWSDLHelper(const _soapmap
*pMap
, WSDLMAP
& structMap
, WSDLMAP
& enumMap
)
7405 ATLENSURE_RETURN( pMap
!= NULL
);
7407 const _soapmapentry
*pEntries
= pMap
->pEntries
;
7408 ATLENSURE_RETURN( pEntries
!= NULL
);
7412 for (int i
=0; pEntries
[i
].nHash
!= 0; i
++)
7414 if (pEntries
[i
].nVal
== SOAPTYPE_UNK
)
7416 ATLENSURE_RETURN( pEntries
[i
].pChain
!= NULL
);
7420 POSITION pos
= NULL
;
7421 CStringA
strName(pEntries
[i
].pChain
->szName
, pEntries
[i
].pChain
->cchName
);
7422 if (pEntries
[i
].pChain
->mapType
== SOAPMAP_STRUCT
)
7424 pos
= structMap
.SetAt(strName
, pEntries
[i
].pChain
);
7426 else if (pEntries
[i
].pChain
->mapType
== SOAPMAP_ENUM
)
7428 pos
= enumMap
.SetAt(strName
, pEntries
[i
].pChain
);
7442 hr
= GenerateWSDLHelper(pEntries
[i
].pChain
, structMap
, enumMap
);
7453 HTTP_CODE
IsUDT(const _soapmapentry
*pEntry
)
7455 ATLENSURE( pEntry
!= NULL
);
7456 return (pEntry
->nVal
!= SOAPTYPE_UNK
) ? HTTP_S_FALSE
: HTTP_SUCCESS
;
7459 HTTP_CODE
GetSoapDims(const _soapmapentry
*pEntry
)
7461 ATLENSURE( pEntry
!= NULL
);
7462 if (pEntry
->pDims
[0] != 0)
7464 if (SUCCEEDED(m_pWriteStream
->WriteStream("[", 1, NULL
)))
7466 for (int i
=1; i
<=pEntry
->pDims
[0]; i
++)
7468 if (m_writeHelper
.Write(pEntry
->pDims
[i
]) != FALSE
)
7470 if (i
< pEntry
->pDims
[0])
7472 if (FAILED(m_pWriteStream
->WriteStream(", ", 2, NULL
)))
7479 if (SUCCEEDED(m_pWriteStream
->WriteStream("]", 1, NULL
)))
7481 return HTTP_SUCCESS
;
7488 const _soapmap
**m_pFuncs
;
7489 const _soapmap
**m_pHeaders
;
7493 WSDLMAP m_structMap
;
7495 POSITION m_currUDTPos
;
7496 int m_nCurrUDTField
;
7498 HEADERMAP m_headerMap
;
7499 POSITION m_currHeaderPos
;
7501 CWriteStreamHelper m_writeHelper
;
7503 CStringA m_strServiceName
;
7504 CStringA m_strNamespaceUri
;
7506 IWriteStream
*m_pWriteStream
;
7508 CComPtr
<IHttpServerContext
> m_spHttpServerContext
;
7510 DWORD m_dwCallFlags
;
7514 void SetWriteStream(IWriteStream
*pStream
)
7516 m_pWriteStream
= pStream
;
7517 m_writeHelper
.Attach(m_pWriteStream
);
7520 void SetHttpServerContext(IHttpServerContext
*pServerContext
)
7522 m_spHttpServerContext
= pServerContext
;
7525 static HTTP_CODE
GetSoapType(int nVal
, IWriteStream
*pStream
)
7527 return (pStream
->WriteStream(CSoapRootHandler::s_xsdNames
[nVal
].szName
,
7528 CSoapRootHandler::s_xsdNames
[nVal
].cchName
, NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_FAIL
;
7532 HRESULT
InitializeSDL(CSoapRootHandler
*pHdlr
)
7534 m_pFuncs
= pHdlr
->GetFunctionMap();
7536 if (m_pFuncs
== NULL
)
7541 ATLASSUME( m_pFuncs
[0] != NULL
);
7543 m_dwCallFlags
= m_pFuncs
[0]->dwCallFlags
;
7546 for (i
=0; m_pFuncs
[i
] != NULL
; i
++)
7548 const _soapmap
*pMap
= m_pFuncs
[i
];
7549 HRESULT hr
= GenerateWSDLHelper(pMap
, m_structMap
, m_enumMap
);
7556 m_pHeaders
= pHdlr
->GetHeaderMap();
7557 if (m_pHeaders
!= NULL
)
7559 for (i
=0; m_pHeaders
[i
] != NULL
; i
++)
7561 const _soapmap
*pMap
= m_pHeaders
[i
];
7562 HRESULT hr
= GenerateWSDLHelper(pMap
, m_structMap
, m_enumMap
);
7569 for (i
=0; m_pHeaders
[i
] != NULL
; i
++)
7571 const _soapmap
*pMap
= m_pHeaders
[i
];
7572 for (size_t j
=0; pMap
->pEntries
[j
].nHash
!= 0; j
++)
7577 if (m_headerMap
.SetAt(pMap
->pEntries
[j
].szField
, &pMap
->pEntries
[j
]) == NULL
)
7596 m_strServiceName
= pHdlr
->GetServiceName();
7597 m_strNamespaceUri
= pHdlr
->GetNamespaceUriA();
7601 return E_OUTOFMEMORY
;
7606 virtual const char * GetHandlerName() = 0;
7611 :m_pFuncs(NULL
), m_nFunc(-1), m_nParam(-1),
7612 m_currUDTPos(NULL
), m_nCurrUDTField(-1),
7613 m_pWriteStream(NULL
), m_nHeader(-1), m_currHeaderPos(NULL
)
7616 virtual ~_CSDLGenerator()
7620 HTTP_CODE
OnGetURL()
7622 char szURL
[ATL_URL_MAX_URL_LENGTH
];
7623 DWORD dwUrlSize
= sizeof(szURL
);
7624 char szServer
[ATL_URL_MAX_HOST_NAME_LENGTH
];
7625 DWORD dwServerSize
= sizeof(szServer
);
7627 DWORD dwHttpsLen
= sizeof(szHttps
);
7628 char szPort
[ATL_URL_MAX_PORT_NUMBER_LENGTH
+1];
7629 DWORD dwPortLen
= sizeof(szPort
);
7631 if (m_spHttpServerContext
->GetServerVariable("URL", szURL
, &dwUrlSize
) != FALSE
)
7633 if (m_spHttpServerContext
->GetServerVariable("SERVER_NAME", szServer
, &dwServerSize
) != FALSE
)
7635 bool bHttps
= false;
7636 if ((m_spHttpServerContext
->GetServerVariable("HTTPS", szHttps
, &dwHttpsLen
) != FALSE
) &&
7637 (!_stricmp(szHttps
, "ON")))
7642 if (m_spHttpServerContext
->GetServerVariable("SERVER_PORT", szPort
, &dwPortLen
) != FALSE
)
7647 strUrl
.Format("http%s://%s:%s%s?Handler=%s", bHttps
? "s" : "", szServer
, szPort
, szURL
, GetHandlerName());
7649 CA2W
wszUrl(strUrl
);
7650 wchar_t *pwszUrl
= wszUrl
;
7651 HRESULT hr
= AtlGenXMLValue(m_pWriteStream
, &pwszUrl
);
7652 return SUCCEEDED(hr
) ? HTTP_SUCCESS
: HTTP_FAIL
;
7664 HTTP_CODE
OnGetNamespace()
7666 return (m_pWriteStream
->WriteStream(m_strNamespaceUri
,
7667 m_strNamespaceUri
.GetLength(), NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_FAIL
;
7670 HTTP_CODE
OnGetNextFunction()
7673 if (m_pFuncs
[m_nFunc
] == NULL
)
7676 return HTTP_S_FALSE
;
7678 return HTTP_SUCCESS
;
7681 HTTP_CODE
OnGetFunctionName()
7683 return (m_pWriteStream
->WriteStream(m_pFuncs
[m_nFunc
]->szName
,
7684 m_pFuncs
[m_nFunc
]->cchName
, NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7687 HTTP_CODE
OnGetNextParameter()
7690 if (m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].nHash
!= 0)
7692 if (m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].dwFlags
& SOAPFLAG_NOMARSHAL
)
7694 return OnGetNextParameter();
7696 return HTTP_SUCCESS
;
7699 return HTTP_S_FALSE
;
7702 HTTP_CODE
OnIsInParameter()
7704 return (m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].dwFlags
& SOAPFLAG_IN
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7707 HTTP_CODE
OnGetParameterName()
7710 if (m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].dwFlags
& SOAPFLAG_RETVAL
)
7712 hr
= m_pWriteStream
->WriteStream("return", sizeof("return")-1, NULL
);
7716 hr
= m_pWriteStream
->WriteStream(m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].szField
,
7717 m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].cchField
, NULL
);
7720 return (hr
== S_OK
) ? HTTP_SUCCESS
: HTTP_FAIL
;
7723 HTTP_CODE
OnNotIsArrayParameter()
7725 return (m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].dwFlags
& (SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
))
7726 ? HTTP_S_FALSE
: HTTP_SUCCESS
;
7729 HTTP_CODE
OnIsParameterUDT()
7731 return IsUDT(&m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
]);
7734 HTTP_CODE
OnGetParameterSoapType()
7736 if (m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].nVal
!= SOAPTYPE_UNK
)
7738 return GetSoapType(m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].nVal
, m_pWriteStream
);
7740 ATLASSUME( m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].pChain
!= NULL
);
7741 return (m_pWriteStream
->WriteStream(m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].pChain
->szName
,
7742 m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].pChain
->cchName
, NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7745 HTTP_CODE
OnIsParameterDynamicArray()
7747 return (m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].dwFlags
& SOAPFLAG_DYNARR
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7750 HTTP_CODE
OnIsArrayParameter()
7752 return (OnNotIsArrayParameter() != HTTP_SUCCESS
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7755 HTTP_CODE
OnIsParameterOneDimensional()
7757 return (m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].pDims
[0] == 1) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7760 HTTP_CODE
OnGetParameterArraySize()
7762 return (m_writeHelper
.Write(m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].pDims
[1]) != FALSE
)
7763 ? HTTP_SUCCESS
: HTTP_FAIL
;
7766 HTTP_CODE
OnGetParameterArraySoapDims()
7768 return GetSoapDims(&m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
]);
7771 HTTP_CODE
OnIsOutParameter()
7773 return (m_pFuncs
[m_nFunc
]->pEntries
[m_nParam
].dwFlags
& SOAPFLAG_OUT
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7776 HTTP_CODE
OnGetNextEnum()
7778 if (m_currUDTPos
== NULL
)
7780 m_currUDTPos
= m_enumMap
.GetStartPosition();
7784 m_enumMap
.GetNext(m_currUDTPos
);
7787 return (m_currUDTPos
!= NULL
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7790 HTTP_CODE
OnGetEnumName()
7792 const _soapmap
*pMap
= m_enumMap
.GetValueAt(m_currUDTPos
);
7793 return (m_pWriteStream
->WriteStream(pMap
->szName
, pMap
->cchName
, NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7796 HTTP_CODE
OnGetNextEnumElement()
7798 const _soapmap
*pMap
= m_enumMap
.GetValueAt(m_currUDTPos
);
7800 if (pMap
->pEntries
[m_nCurrUDTField
].nHash
!= 0)
7802 return HTTP_SUCCESS
;
7804 m_nCurrUDTField
= -1;
7805 return HTTP_S_FALSE
;
7808 HTTP_CODE
OnGetEnumElementName()
7810 const _soapmap
*pMap
= m_enumMap
.GetValueAt(m_currUDTPos
);
7811 return (m_pWriteStream
->WriteStream(pMap
->pEntries
[m_nCurrUDTField
].szField
,
7812 pMap
->pEntries
[m_nCurrUDTField
].cchField
, NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7815 HTTP_CODE
OnGetNextStruct()
7817 if (m_currUDTPos
== NULL
)
7819 m_currUDTPos
= m_structMap
.GetStartPosition();
7823 m_structMap
.GetNext(m_currUDTPos
);
7826 return (m_currUDTPos
!= NULL
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7829 HTTP_CODE
OnGetStructName()
7831 const _soapmap
*pMap
= m_enumMap
.GetValueAt(m_currUDTPos
);
7832 return (m_pWriteStream
->WriteStream(pMap
->szName
, pMap
->cchName
, NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7835 HTTP_CODE
OnGetNextStructField()
7837 const _soapmap
*pMap
= m_structMap
.GetValueAt(m_currUDTPos
);
7839 if (pMap
->pEntries
[m_nCurrUDTField
].nHash
!= 0)
7841 return HTTP_SUCCESS
;
7843 m_nCurrUDTField
= -1;
7844 return HTTP_S_FALSE
;
7847 HTTP_CODE
OnGetStructFieldName()
7849 const _soapmap
*pMap
= m_structMap
.GetValueAt(m_currUDTPos
);
7850 return (m_pWriteStream
->WriteStream(pMap
->pEntries
[m_nCurrUDTField
].szField
,
7851 pMap
->pEntries
[m_nCurrUDTField
].cchField
, NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7854 HTTP_CODE
OnNotIsArrayField()
7856 const _soapmap
*pMap
= m_structMap
.GetValueAt(m_currUDTPos
);
7857 return (pMap
->pEntries
[m_nCurrUDTField
].dwFlags
& (SOAPFLAG_FIXEDARR
| SOAPFLAG_DYNARR
)) ? HTTP_S_FALSE
: HTTP_SUCCESS
;
7860 HTTP_CODE
OnIsFieldUDT()
7862 const _soapmap
*pMap
= m_structMap
.GetValueAt(m_currUDTPos
);
7863 return IsUDT(&pMap
->pEntries
[m_nCurrUDTField
]);
7866 HTTP_CODE
OnGetStructFieldSoapType()
7868 const _soapmap
*pMap
= m_structMap
.GetValueAt(m_currUDTPos
);
7869 if (pMap
->pEntries
[m_nCurrUDTField
].nVal
!= SOAPTYPE_UNK
)
7871 return GetSoapType(pMap
->pEntries
[m_nCurrUDTField
].nVal
, m_pWriteStream
);
7873 ATLASSERT( pMap
->pEntries
[m_nCurrUDTField
].pChain
!= NULL
);
7874 return (m_pWriteStream
->WriteStream(pMap
->pEntries
[m_nCurrUDTField
].pChain
->szName
,
7875 pMap
->pEntries
[m_nCurrUDTField
].pChain
->cchName
, NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7878 HTTP_CODE
OnIsArrayField()
7880 return (OnNotIsArrayField() != HTTP_SUCCESS
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7883 HTTP_CODE
OnIsFieldDynamicArray()
7885 const _soapmap
*pMap
= m_structMap
.GetValueAt(m_currUDTPos
);
7886 return (pMap
->pEntries
[m_nCurrUDTField
].dwFlags
& SOAPFLAG_DYNARR
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7889 HTTP_CODE
OnGetFieldSizeIsName()
7891 const _soapmap
*pMap
= m_structMap
.GetValueAt(m_currUDTPos
);
7892 int nIndex
= pMap
->pEntries
[m_nCurrUDTField
].nSizeIs
;
7893 ATLASSERT( nIndex
>= 0 );
7894 return (m_pStream
->WriteStream(pMap
->pEntries
[nIndex
].szField
,
7895 pMap
->pEntries
[nIndex
].cchField
, NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7898 HTTP_CODE
OnIsFieldOneDimensional()
7900 const _soapmap
*pMap
= m_structMap
.GetValueAt(m_currUDTPos
);
7901 return (pMap
->pEntries
[m_nCurrUDTField
].pDims
[0] == 1) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7904 HTTP_CODE
OnGetFieldArraySize()
7906 const _soapmap
*pMap
= m_structMap
.GetValueAt(m_currUDTPos
);
7907 return (m_writeHelper
.Write(pMap
->pEntries
[m_nCurrUDTField
].pDims
[1]) != FALSE
) ?
7908 HTTP_SUCCESS
: HTTP_S_FALSE
;
7911 HTTP_CODE
OnGetFieldArraySoapDims()
7913 const _soapmap
*pMap
= m_structMap
.GetValueAt(m_currUDTPos
);
7914 return GetSoapDims(&pMap
->pEntries
[m_nCurrUDTField
]);
7917 HTTP_CODE
OnGetServiceName()
7919 return (m_pWriteStream
->WriteStream(m_strServiceName
,
7920 m_strServiceName
.GetLength(), NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_FAIL
;
7923 HTTP_CODE
OnGetNextHeader()
7925 if (m_currHeaderPos
== NULL
)
7927 m_currHeaderPos
= m_headerMap
.GetStartPosition();
7931 m_headerMap
.GetNext(m_currHeaderPos
);
7934 return (m_currHeaderPos
!= NULL
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7937 HTTP_CODE
OnIsInHeader()
7939 return (m_pHeaders
[m_nFunc
]->pEntries
[m_nHeader
].dwFlags
& SOAPFLAG_IN
)
7940 ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7943 HTTP_CODE
OnIsOutHeader()
7945 return (m_pHeaders
[m_nFunc
]->pEntries
[m_nHeader
].dwFlags
& SOAPFLAG_OUT
)
7946 ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7949 HTTP_CODE
OnIsRequiredHeader()
7951 return (m_pHeaders
[m_nFunc
]->pEntries
[m_nHeader
].dwFlags
& SOAPFLAG_MUSTUNDERSTAND
)
7952 ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7955 HTTP_CODE
OnGetHeaderName()
7957 const _soapmapentry
*pEntry
= m_headerMap
.GetValueAt(m_currHeaderPos
);
7958 return (m_pWriteStream
->WriteStream(pEntry
->szField
,
7959 pEntry
->cchField
, NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_FAIL
;
7962 HTTP_CODE
OnNotIsArrayHeader()
7964 const _soapmapentry
*pEntry
= m_headerMap
.GetValueAt(m_currHeaderPos
);
7965 return (pEntry
->dwFlags
& SOAPFLAG_FIXEDARR
) ? HTTP_S_FALSE
: HTTP_SUCCESS
;
7968 HTTP_CODE
OnIsHeaderUDT()
7970 return IsUDT(m_headerMap
.GetValueAt(m_currHeaderPos
));
7973 HTTP_CODE
OnGetHeaderSoapType()
7975 const _soapmapentry
*pEntry
= m_headerMap
.GetValueAt(m_currHeaderPos
);
7976 if (pEntry
->nVal
!= SOAPTYPE_UNK
)
7978 return GetSoapType(pEntry
->nVal
, m_pWriteStream
);
7980 ATLENSURE( pEntry
->pChain
!= NULL
);
7981 return (m_pWriteStream
->WriteStream(pEntry
->pChain
->szName
,
7982 pEntry
->pChain
->cchName
, NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7985 HTTP_CODE
OnIsHeaderOneDimensional()
7987 const _soapmapentry
*pEntry
= m_headerMap
.GetValueAt(m_currHeaderPos
);
7988 return (pEntry
->pDims
[0] == 1) ? HTTP_SUCCESS
: HTTP_S_FALSE
;
7991 HTTP_CODE
OnGetHeaderArraySize()
7993 const _soapmapentry
*pEntry
= m_headerMap
.GetValueAt(m_currHeaderPos
);
7994 return (m_writeHelper
.Write(pEntry
->pDims
[1]) != FALSE
) ?
7995 HTTP_SUCCESS
: HTTP_S_FALSE
;
7998 HTTP_CODE
OnGetHeaderArraySoapDims()
8000 return GetSoapDims(m_headerMap
.GetValueAt(m_currHeaderPos
));
8003 HTTP_CODE
OnGetNextFunctionHeader()
8006 if (m_pHeaders
[m_nFunc
]->pEntries
[m_nHeader
].nHash
!= 0)
8008 if (m_pHeaders
[m_nFunc
]->pEntries
[m_nHeader
].dwFlags
& SOAPFLAG_NOMARSHAL
)
8010 return OnGetNextHeader();
8012 return HTTP_SUCCESS
;
8015 return HTTP_S_FALSE
;
8018 HTTP_CODE
OnGetFunctionHeaderName()
8020 return (m_pWriteStream
->WriteStream(
8021 m_pHeaders
[m_nFunc
]->pEntries
[m_nHeader
].szField
,
8022 m_pHeaders
[m_nFunc
]->pEntries
[m_nHeader
].cchField
,
8023 NULL
) == S_OK
) ? HTTP_SUCCESS
: HTTP_FAIL
;
8026 HTTP_CODE
OnIsArrayHeader()
8028 return (OnNotIsArrayHeader() == HTTP_SUCCESS
) ? HTTP_S_FALSE
: HTTP_SUCCESS
;
8031 HTTP_CODE
OnIsDocumentLiteral()
8033 if ((m_dwCallFlags
& (SOAPFLAG_DOCUMENT
| SOAPFLAG_LITERAL
)) ==
8034 (SOAPFLAG_DOCUMENT
| SOAPFLAG_LITERAL
))
8036 return HTTP_SUCCESS
;
8038 return HTTP_S_FALSE
;
8041 HTTP_CODE
OnIsRpcEncoded()
8043 if ((m_dwCallFlags
& (SOAPFLAG_RPC
| SOAPFLAG_ENCODED
)) ==
8044 (SOAPFLAG_RPC
| SOAPFLAG_ENCODED
))
8046 return HTTP_SUCCESS
;
8048 return HTTP_S_FALSE
;
8051 #pragma warning (push)
8052 #pragma warning (disable : 4640) // construction of local static object is not thread-safe
8054 BEGIN_REPLACEMENT_METHOD_MAP(_CSDLGenerator
)
8055 REPLACEMENT_METHOD_ENTRY("GetNamespace", OnGetNamespace
)
8056 REPLACEMENT_METHOD_ENTRY("GetNextFunction", OnGetNextFunction
)
8057 REPLACEMENT_METHOD_ENTRY("GetFunctionName", OnGetFunctionName
)
8058 REPLACEMENT_METHOD_ENTRY("GetNextParameter", OnGetNextParameter
)
8059 REPLACEMENT_METHOD_ENTRY("IsInParameter", OnIsInParameter
)
8060 REPLACEMENT_METHOD_ENTRY("GetParameterName", OnGetParameterName
)
8061 REPLACEMENT_METHOD_ENTRY("NotIsArrayParameter", OnNotIsArrayParameter
)
8062 REPLACEMENT_METHOD_ENTRY("IsParameterUDT", OnIsParameterUDT
)
8063 REPLACEMENT_METHOD_ENTRY("GetParameterSoapType", OnGetParameterSoapType
)
8064 REPLACEMENT_METHOD_ENTRY("IsParameterDynamicArray", OnIsParameterDynamicArray
)
8065 REPLACEMENT_METHOD_ENTRY("IsArrayParameter", OnIsArrayParameter
)
8066 REPLACEMENT_METHOD_ENTRY("IsParameterOneDimensional", OnIsParameterOneDimensional
)
8067 REPLACEMENT_METHOD_ENTRY("GetParameterArraySize", OnGetParameterArraySize
)
8068 REPLACEMENT_METHOD_ENTRY("GetParameterArraySoapDims", OnGetParameterArraySoapDims
)
8069 REPLACEMENT_METHOD_ENTRY("IsOutParameter", OnIsOutParameter
)
8070 REPLACEMENT_METHOD_ENTRY("GetNextEnum", OnGetNextEnum
)
8071 REPLACEMENT_METHOD_ENTRY("GetEnumName", OnGetEnumName
)
8072 REPLACEMENT_METHOD_ENTRY("GetNextEnumElement", OnGetNextEnumElement
)
8073 REPLACEMENT_METHOD_ENTRY("GetEnumElementName", OnGetEnumElementName
)
8074 REPLACEMENT_METHOD_ENTRY("GetNextStruct", OnGetNextStruct
)
8075 REPLACEMENT_METHOD_ENTRY("GetStructName", OnGetStructName
)
8076 REPLACEMENT_METHOD_ENTRY("GetNextStructField", OnGetNextStructField
)
8077 REPLACEMENT_METHOD_ENTRY("GetStructFieldName", OnGetStructFieldName
)
8078 REPLACEMENT_METHOD_ENTRY("NotIsArrayField", OnNotIsArrayField
)
8079 REPLACEMENT_METHOD_ENTRY("IsFieldUDT", OnIsFieldUDT
)
8080 REPLACEMENT_METHOD_ENTRY("GetStructFieldSoapType", OnGetStructFieldSoapType
)
8081 REPLACEMENT_METHOD_ENTRY("IsArrayField", OnIsArrayField
)
8082 REPLACEMENT_METHOD_ENTRY("IsFieldOneDimensional", OnIsFieldOneDimensional
)
8083 REPLACEMENT_METHOD_ENTRY("GetFieldArraySize", OnGetFieldArraySize
)
8084 REPLACEMENT_METHOD_ENTRY("GetFieldArraySoapDims", OnGetFieldArraySoapDims
)
8085 REPLACEMENT_METHOD_ENTRY("GetServiceName", OnGetServiceName
)
8086 REPLACEMENT_METHOD_ENTRY("GetURL", OnGetURL
)
8088 REPLACEMENT_METHOD_ENTRY("GetNextHeader", OnGetNextHeader
)
8089 REPLACEMENT_METHOD_ENTRY("GetHeaderName", OnGetHeaderName
)
8090 REPLACEMENT_METHOD_ENTRY("NotIsArrayHeader", OnNotIsArrayHeader
)
8091 REPLACEMENT_METHOD_ENTRY("IsArrayHeader", OnIsArrayHeader
)
8092 REPLACEMENT_METHOD_ENTRY("IsHeaderUDT", OnIsHeaderUDT
)
8093 REPLACEMENT_METHOD_ENTRY("GetHeaderSoapType", OnGetHeaderSoapType
)
8094 REPLACEMENT_METHOD_ENTRY("IsHeaderOneDimensional", OnIsHeaderOneDimensional
)
8095 REPLACEMENT_METHOD_ENTRY("GetHeaderArraySize", OnGetHeaderArraySize
)
8096 REPLACEMENT_METHOD_ENTRY("GetHeaderArraySoapDims", OnGetHeaderArraySoapDims
)
8097 REPLACEMENT_METHOD_ENTRY("GetNextFunctionHeader", OnGetNextFunctionHeader
)
8098 REPLACEMENT_METHOD_ENTRY("GetFunctionHeaderName", OnGetFunctionHeaderName
)
8099 REPLACEMENT_METHOD_ENTRY("IsInHeader", OnIsInHeader
)
8100 REPLACEMENT_METHOD_ENTRY("IsOutHeader", OnIsOutHeader
)
8101 REPLACEMENT_METHOD_ENTRY("IsRequiredHeader", OnIsRequiredHeader
)
8103 REPLACEMENT_METHOD_ENTRY("IsDocumentLiteral", OnIsDocumentLiteral
)
8104 REPLACEMENT_METHOD_ENTRY("IsRpcEncoded", OnIsRpcEncoded
)
8105 REPLACEMENT_METHOD_ENTRY("IsFieldDynamicArray", OnIsFieldDynamicArray
)
8106 REPLACEMENT_METHOD_ENTRY("GetFieldSizeIsName", OnGetFieldSizeIsName
)
8107 END_REPLACEMENT_METHOD_MAP()
8109 #pragma warning (pop)
8111 }; // class _CSDLGenerator
8113 template <class THandler
, const char *szHandlerName
>
8114 class CSDLGenerator
:
8115 public _CSDLGenerator
,
8116 public IRequestHandlerImpl
< CSDLGenerator
<THandler
,szHandlerName
> >,
8117 public CComObjectRootEx
<CComSingleThreadModel
>
8122 typedef CSDLGenerator
<THandler
, szHandlerName
> _sdlGenerator
;
8124 BEGIN_COM_MAP(_sdlGenerator
)
8125 COM_INTERFACE_ENTRY(IRequestHandler
)
8126 COM_INTERFACE_ENTRY(ITagReplacer
)
8129 HTTP_CODE
InitializeHandler(AtlServerRequest
*pRequestInfo
, IServiceProvider
*pServiceProvider
)
8131 IRequestHandlerImpl
<CSDLGenerator
>::InitializeHandler(pRequestInfo
, pServiceProvider
);
8133 CComObjectStack
<THandler
> handler
;
8134 if (FAILED(InitializeSDL(&handler
)))
8140 HTTP_CODE hcErr
= s
.LoadFromString(s_szAtlsWSDLSrf
, (DWORD
) strlen(s_szAtlsWSDLSrf
));
8141 if (hcErr
== HTTP_SUCCESS
)
8144 CHttpResponse
HttpResponse(pRequestInfo
->pServerContext
);
8145 HttpResponse
.SetContentType("text/xml");
8146 if (s
.ParseReplacements(this) != false)
8148 s
.FinishParseReplacements();
8150 SetStream(&HttpResponse
);
8151 SetWriteStream(&HttpResponse
);
8152 SetHttpServerContext(m_spServerContext
);
8154 ATLASSERT( s
.ParseSuccessful() != false );
8156 hcErr
= s
.Render(this, &HttpResponse
);
8163 const char * GetHandlerName()
8165 return szHandlerName
;
8167 }; // class CSDLGenerator
8172 #pragma warning(pop)
8174 #endif // __ATLSOAP_H__