📄 soapser.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//+----------------------------------------------------------------------------
//
//
// File: soapser.cpp
//
// Contents:
//
// implementation file
//
// ISoapMapper Interface implemenation
//
//
//-----------------------------------------------------------------------------
#include "headers.h"
#include "soapstream.h"
#include "soapser.h"
#include "mssoap.h"
TYPEINFOIDS(ISoapSerializer, MSSOAPLib)
BEGIN_INTERFACE_MAP(CSoapSerializer)
ADD_IUNKNOWN(CSoapSerializer, ISoapSerializer)
ADD_INTERFACE(CSoapSerializer, ISoapSerializer)
ADD_INTERFACE(CSoapSerializer, IDispatch)
END_INTERFACE_MAP(CSoapSerializer)
static const WCHAR *acXMLencdef = L"UTF-8";
// shortcut to check the m_eState
#define chks(s) (m_eState == (s))
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapSerializer::CSoapSerializer()
//
// parameters:
//
// description: Constructor
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
CSoapSerializer::CSoapSerializer() :
m_pcSoapPrefix(NULL),
m_pcDefaultNamespaceURI((WCHAR*)g_pwstrEmpty),
m_eState(created),
m_bElementOpen(false),
m_bFaultOccured(FALSE),
m_pEncodingStream(NULL)
{
TRACEL( (2,"%5d: Serializer created\n", GetCurrentThreadId()) );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapSerializer::~CSoapSerializer()
//
// parameters:
//
// description: Destructor
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
CSoapSerializer::~CSoapSerializer()
{
TRACEL( (2,"%5d: Serializer shutdown\n", GetCurrentThreadId()) );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapSerializer::Init(VARIANT vIn)
//
// parameters:
//
// description:
//
// returns: initialize the serializer with a destination stream
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CSoapSerializer::Init(VARIANT vIn)
{
#ifndef CE_NO_EXCEPTIONS
try
{
#endif
HRESULT hr(S_OK);
#ifndef UNDER_CE
IUnknown *pTemp(NULL);
#else
IUnknown *pTemp = NULL;
#endif
CAutoRefc<IUnknown> pRefTemp(NULL);
CAutoRefc<IStream> pIStream(NULL);
CAutoRefc<IResponse> pIResponse(NULL);
CAutoP<CStreamShell> pStreamShell(NULL);
if (!m_pEncodingStream)
m_pEncodingStream = new CEncodingStream();
#ifdef UNDER_CE
CHK_BOOL(m_pEncodingStream, E_OUTOFMEMORY);
#endif
if (!(vIn.vt & (VT_UNKNOWN | VT_DISPATCH)))
return E_INVALIDARG;
// handle byref case
if (vIn.vt & VT_BYREF)
pTemp = *(vIn.ppunkVal);
else
pTemp = vIn.punkVal;
if (vIn.vt & VT_DISPATCH)
{
// we got a dispatch object here, get the IUnknown in an AutoPtr
CHK ( pTemp->QueryInterface(IID_IUnknown, (void**)&pRefTemp) );
pTemp = pRefTemp;
}
CHK_BOOL(pTemp, E_INVALIDARG);
pStreamShell = new CStreamShell();
CHK_BOOL(pStreamShell, E_OUTOFMEMORY);
// see if we can get a stream
if (SUCCEEDED (pTemp->QueryInterface(IID_IStream, (void**)&pIStream)) )
{
// we got a stream
CHK(pStreamShell->InitStream(pIStream));
pIStream.PvReturn();
CHK (m_pEncodingStream->Init(pStreamShell.PvReturn()));
goto Cleanup;
}
// see if we can get a stream
if (SUCCEEDED (pTemp->QueryInterface(IID_IResponse, (void**)&pIResponse)) )
{
// we got a stream
CHK(pStreamShell->InitResponse(pIResponse));
pIResponse.PvReturn();
CHK (m_pEncodingStream->Init(pStreamShell.PvReturn()));
goto Cleanup;
}
hr = E_FAIL;
Cleanup:
ASSERT (hr == S_OK);
return hr;
#ifndef CE_NO_EXCEPTIONS
}
catch (...)
{
ASSERTTEXT (FALSE, "CSoapSerializer::Init - Unhandled Exception");
return E_FAIL;
}
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapSerializer::startEnvelope(env_Prefix, enc_style_uri, xml_encoding)
//
// parameters:
//
// description: Open a new envelope, can overwrite the default SOAP-ENV
// prefix, allows definition of an encoding style
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CSoapSerializer::startEnvelope(
BSTR env_Prefix,
BSTR enc_style_uri,
BSTR xml_encoding)
{
#ifdef _DEBUG
DWORD handle = GetCurrentThreadId();
#endif
TRACEL((2, "%5d: Env::startEnvelope -this:%d\n", handle, this));
#ifndef CE_NO_EXCEPTIONS
try
{
#endif
HRESULT hr;
CHK( Initialized() );
// the only legal state we should be in here is 'initialized'
CHK_BOOL (chks(initialized), E_FAIL);
// the current level has to be 0 at this point
// if not we already created some stuff before the envelope started
CHK_BOOL (m_nsHelper.getLevel() == 0, E_FAIL);
if ( (!xml_encoding) || (wcslen(xml_encoding) == 0))
{
CAutoBSTR bstrTemp;
CHK(bstrTemp.Assign((BSTR) acXMLencdef));
CHK(_WriterStartDocument(bstrTemp));
}
else
{
CHK(_WriterStartDocument(xml_encoding));
}
// we are at a new level
m_nsHelper.PushLevel();
if ( (env_Prefix) && (wcslen(env_Prefix)) )
{
CHK ( m_nsHelper.AddNamespace(env_Prefix, g_pwstrEnvNS) );
}
else
{
CHK ( m_nsHelper.AddNamespace(g_pwstrEnvPrefix, g_pwstrEnvNS) );
}
m_pcSoapPrefix = (m_nsHelper.FindNamespace(g_pwstrEnvNS, NULL))->getPrefix();
ASSERT (m_pcSoapPrefix);
// we need this set before we can open an element
m_eState = envelope_opened;
m_bFaultOccured = FALSE;
CHK (startElement((WCHAR *) g_pwstrEnv, (WCHAR *) g_pwstrEnvNS, enc_style_uri, m_pcSoapPrefix) );
// make sure we have an attribute for this namespace definition
CHK (m_ElementStack.AddAttribute((WCHAR *)g_pwstrXmlns, (WCHAR *)g_pwstrEmpty, m_pcSoapPrefix, (WCHAR *)g_pwstrEnvNS) );
Cleanup:
TRACEL((2, "%5d: Env::startEnvelope --- exit, HR=%x", handle, hr));
ASSERT(hr==S_OK);
return (hr);
#ifndef CE_NO_EXCEPTIONS
}
catch (...)
{
ASSERTTEXT (FALSE, "CSoapSerializer::startEnvelope - Unhandled Exception");
return E_FAIL;
}
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapSerializer::endEnvelope()
//
// parameters:
//
// description: end of envelope
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CSoapSerializer::endEnvelope( void )
{
#ifndef CE_NO_EXCEPTIONS
try
#else
__try
#endif
{
HRESULT hr;
CHK (Initialized());
CHK ( FlushElement() );
// check the state
CHK_BOOL (chks(envelope_opened) || chks(header_closed) || chks(body_closed), E_FAIL);
// need to manipulate the state, since we can not write a 'endElement'
// in the header_closed or body_closed state
m_eState = envelope_opened;
// we are ending the document
CHK(endElement());
m_nsHelper.PopLevel();
// we now have to be at level 0
CHK_BOOL(m_nsHelper.getLevel() == 0, E_FAIL);
CHK(_WriterEndDocument());
m_eState = envelope_closed;
// release the encoding stream, to close the stream
delete (CEncodingStream*) (m_pEncodingStream.PvReturn());
Cleanup:
ASSERT(hr==S_OK);
return (hr);
}
#ifndef CE_NO_EXCEPTIONS
catch (...)
#else
__except(1)
#endif
{
ASSERTTEXT (FALSE, "CSoapSerializer::endEnvelope - Unhandled Exception");
return E_FAIL;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapSerializer::startHeader(BSTR enc_style_uri)
//
// parameters:
//
// description: Start header in soap envelope
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CSoapSerializer::startHeader( BSTR enc_style_uri )
{
#ifndef CE_NO_EXCEPTIONS
try
{
#endif
HRESULT hr;
CHK (Initialized());
CHK (FlushElement() );
// check the state
CHK_BOOL (chks(envelope_opened), E_FAIL);
m_eState = header_opened;
CHK (startElement((WCHAR *) g_pwstrHeader, (WCHAR *)g_pwstrEnvNS, enc_style_uri, m_pcSoapPrefix) );
Cleanup:
ASSERT(hr==S_OK);
return (hr);
#ifndef CE_NO_EXCEPTIONS
}
catch (...)
{
ASSERTTEXT (FALSE, "CSoapSerializer::startHeader - Unhandled Exception");
return E_FAIL;
}
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapSerializer::startHeaderElement( BSTR name, BSTR ns_uri, int mustUnderstand,
// BSTR actor_uri, BSTR enc_style_uri, BSTR prefix)
//
// parameters:
//
// description: adding a header element, will create namespace if needed
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CSoapSerializer::startHeaderElement(
BSTR name,
BSTR ns_uri,
int mustUnderstand,
BSTR actor_uri,
BSTR enc_style_uri,
BSTR prefix)
{
#ifndef CE_NO_EXCEPTIONS
try
{
#endif
HRESULT hr;
#ifndef UNDER_CE
WCHAR * pPrefix;
#endif
CHK (Initialized());
CHK (FlushElement() );
// check the state
CHK_BOOL (chks(header_opened), E_FAIL);
CHK (startElement( name , ns_uri, enc_style_uri,prefix) );
if (mustUnderstand == 1)
{
CHK (m_ElementStack.AddAttribute(m_pcSoapPrefix, (WCHAR *)g_pwstrEnvNS, (WCHAR *)g_pwstrMustUnderstand, L"1") );
}
if ( (actor_uri != NULL) && (wcslen((WCHAR*)actor_uri) > 0))
{
CHK (m_ElementStack.AddAttribute(m_pcSoapPrefix, (WCHAR *)g_pwstrEnvNS, (WCHAR *)g_pwstrActor, (WCHAR *)actor_uri) );
}
Cleanup:
ASSERT(hr==S_OK);
return (hr);
#ifndef CE_NO_EXCEPTIONS
}
catch (...)
{
ASSERTTEXT (FALSE, "CSoapSerializer::startHeaderElement - Unhandled Exception");
return E_FAIL;
}
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapSerializer::endHeaderElement()
//
// parameters:
//
// description: close a header element, no parameter needed
//
// returns:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -