Files
Slnkdwf/ATL90/source/SProxy/Parser.h
Jos Groot Lipman 0e37d774d2 Merge SLNKDWF64 branch
svn path=/Slnkdwf/trunk/; revision=23911
2015-01-21 12:09:31 +00:00

517 lines
13 KiB
C++

//
// Parser.h
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#pragma once
#include "stdafx.h"
#include "XMLDocument.h"
#include "XSDElement.h"
#include "Emit.h"
#include "SproxyColl.h"
#define PTM_WARNING_DISABLE \
__pragma(warning( push )) \
__pragma(warning( disable : 4867 ))
#define PTM_WARNING_RESTORE \
__pragma(warning( pop ))
#define EMPTY_XMLTAG_MAP() \
virtual const XMLTAG * GetXMLTAGMap() \
{ \
return NULL; \
}
#define EMPTY_XMLATTR_MAP() \
virtual const XMLATTR * GetXMLATTRMap() \
{ \
return NULL; \
}
#define BEGIN_XMLTAG_MAP() \
virtual const XMLTAG * GetXMLTAGMap() \
{ \
PTM_WARNING_DISABLE \
static const XMLTAG map[] = \
{
#define END_XMLTAG_MAP() \
{ NULL, NULL } }; \
PTM_WARNING_RESTORE \
return map; \
}
#define _XMLTAG_ENTRY_EX(elementName, elementNamespace, elementFunc) \
{ L ## elementName, elementName, sizeof(elementName)-1, \
L ## elementNamespace, elementNamespace, sizeof(elementNamespace)-1, \
static_cast<TAG_DISPATCH_FUNC>(elementFunc), NULL, FALSE },
#define XMLTAG_ENTRY_EX(elementName, elementNamespace, elementFunc) _XMLTAG_ENTRY_EX(elementName, elementNamespace, elementFunc)
#define _XMLTAG_ENTRY(elementName, elementFunc) \
{ L ## elementName, elementName, sizeof(elementName)-1, \
NULL, NULL, 0, \
static_cast<TAG_DISPATCH_FUNC>(elementFunc), NULL, FALSE },
#define XMLTAG_ENTRY(elementName, elementFunc) _XMLTAG_ENTRY(elementName, elementFunc)
#define BEGIN_XMLATTR_MAP() \
virtual const XMLATTR * GetXMLATTRMap() \
{ \
PTM_WARNING_DISABLE \
static const XMLTAG map[] = \
{
#define END_XMLATTR_MAP() \
{ NULL, NULL } }; \
PTM_WARNING_RESTORE \
return map; \
}
#define _XMLATTR_ENTRY_EX(elementName, elementNamespace, elementFunc, required) \
{ L ## elementName, elementName, sizeof(elementName)-1, \
L ## elementNamespace, elementNamespace, sizeof(elementNamespace)-1, \
NULL, static_cast<ATTR_DISPATCH_FUNC>(elementFunc), required },
#define XMLATTR_ENTRY_EX(elementName, elementNamespace, elementFunc) \
_XMLATTR_ENTRY_EX(elementName, elementNamespace, elementFunc, FALSE)
#define XMLATTR_ENTRY_EX2(elementName, elementNamespace, elementFunc, required) \
_XMLATTR_ENTRY_EX(elementName, elementNamespace, elementFunc, required)
#define _XMLATTR_ENTRY(elementName, elementFunc, required) \
{ L ## elementName, elementName, sizeof(elementName)-1, \
NULL, NULL, 0, \
NULL, static_cast<ATTR_DISPATCH_FUNC>(elementFunc), required },
#define XMLATTR_ENTRY(elementName, elementFunc) _XMLATTR_ENTRY(elementName, elementFunc, FALSE)
#define XMLATTR_ENTRY2(elementName, elementFunc, required) _XMLATTR_ENTRY(elementName, elementFunc, required)
class CParserBase;
typedef HRESULT (CParserBase::*TAG_DISPATCH_FUNC)(
const wchar_t *wszNamespaceUri, int cchNamespaceUri,
const wchar_t *wszLocalName, int cchLocalName,
const wchar_t *wszQName, int cchQName,
ISAXAttributes *pAttributes);
typedef HRESULT (CParserBase::*ATTR_DISPATCH_FUNC)(
const wchar_t *wszNamespaceUri, int cchNamespaceUri,
const wchar_t *wszLocalName, int cchLocalName,
const wchar_t *wszQName, int cchQName,
const wchar_t *wszValue, int cchValue,
ISAXAttributes *pAttributes);
#define TAG_METHOD_DECL( name ) \
HRESULT name(const wchar_t *wszNamespaceUri, int cchNamespaceUri, \
const wchar_t *wszLocalName, int cchLocalName, \
const wchar_t *wszQName, int cchQName, \
ISAXAttributes *pAttributes)
#define TAG_METHOD_IMPL( class, name ) \
HRESULT class ## :: ## name(const wchar_t *wszNamespaceUri, int cchNamespaceUri, \
const wchar_t *wszLocalName, int cchLocalName, \
const wchar_t *wszQName, int cchQName, \
ISAXAttributes *pAttributes)
#define ATTR_METHOD_DECL( name ) \
HRESULT name(const wchar_t *wszNamespaceUri, int cchNamespaceUri, \
const wchar_t *wszLocalName, int cchLocalName, \
const wchar_t *wszQName, int cchQName, \
const wchar_t *wszValue, int cchValue, \
ISAXAttributes *pAttributes)
#define ATTR_METHOD_IMPL( class, name ) \
HRESULT class ## :: ## name(const wchar_t *wszNamespaceUri, int cchNamespaceUri, \
const wchar_t *wszLocalName, int cchLocalName, \
const wchar_t *wszQName, int cchQName, \
const wchar_t *wszValue, int cchValue, \
ISAXAttributes *pAttributes)
typedef NAMESPACEMAP URIMAP;
#ifndef _PREFIX_
#define TRACE_PARSE_ENTRY() \
ATLTRACE( _T("%s") __FUNCTION__ _T("\n"), GetTabs(GetLevel()))
#else
#define TRACE_PARSE_ENTRY() \
ATLTRACE( _T("%s") _T("\n"), GetTabs(GetLevel()))
#endif // _PREFIX_
//
// XMLTAG struct
// used for dispatching XML entries
//
struct XMLTAG
{
LPCWSTR wszElemName;
LPCSTR szElemName;
int cchElem;
LPCWSTR wszElemNamespace;
LPCSTR szElemNamespace;
int cchNamespaceUri;
//
// REVIEW: union doesn't work for initialization
//
TAG_DISPATCH_FUNC pfnTag;
ATTR_DISPATCH_FUNC pfnAttr;
//
// attribute must be present
//
BOOL bRequired;
};
typedef XMLTAG XMLATTR;
//
// dummy classes for multiple inheritance
// (tell compiler to use big pointers for CParserBase member function pointers)
//
class CDummy1 {};
class CDummy2 {};
//
// The base parser class
//
class CParserBase : public ISAXContentHandler, public CDummy1, public CDummy2
{
private:
CComPtr<CParserBase> m_spParent;
CComPtr<ISAXXMLReader> m_spReader;
CComPtr<ISAXLocator> m_spLocator;
//
// how many levels deep
//
DWORD m_dwLevel;
//
// reset to parent handler on endElement
//
DWORD m_dwReset;
//
// get only top-level attributes
//
BOOL m_bGotAttributes;
//
// dynamically allocated
//
BOOL m_bDynamicAlloc;
private:
HRESULT DispatchElement(
const XMLTAG *pMap,
const wchar_t *wszNamespaceUri, int cchNamespaceUri,
const wchar_t *wszLocalName, int cchLocalName,
const wchar_t *wszQName, int cchQName,
ISAXAttributes *pAttributes) throw ();
HRESULT GetAttributes(const XMLATTR *pMap, ISAXAttributes *pAttributes);
BOOL CheckTagElement(
const XMLTAG *pTag,
const wchar_t *wszNamespaceUri, int cchNamespaceUri,
const wchar_t *wszLocalName, int cchLocalName,
const wchar_t *wszQName, int cchQName);
void CrackQName(const wchar_t *wszQName, int cchQName,
wchar_t **pwszNs, int *pcchNs,
wchar_t **pwszName, int *pcchName);
public:
//
// CParserBase interface
//
inline CParserBase()
:m_dwLevel(0), m_dwReset(0), m_bDynamicAlloc(TRUE), m_bGotAttributes(FALSE)
{
}
inline CParserBase(ISAXXMLReader *pReader, CParserBase *pParent, DWORD dwLevel)
:m_spReader(pReader), m_spParent(pParent), m_dwLevel(dwLevel+1), m_dwReset(0), m_bDynamicAlloc(TRUE), m_bGotAttributes(FALSE)
{
if (m_spReader.p != NULL)
{
m_spReader->putContentHandler(this);
}
}
inline HRESULT Initialize(ISAXXMLReader *pReader, CParserBase *pParent, DWORD dwLevel, BOOL bDynamicAlloc = FALSE)
{
m_spReader = pReader;
m_spParent = pParent;
m_dwLevel = dwLevel+1;
m_bDynamicAlloc = bDynamicAlloc;
m_bGotAttributes = FALSE;
m_dwReset = 0;
if (m_spReader.p != NULL)
{
return m_spReader->putContentHandler(this);
}
return E_FAIL;
}
virtual ~CParserBase()
{
if ((m_spParent.p != NULL) && (m_spReader.p != NULL))
{
m_spReader->putContentHandler(m_spParent);
}
}
EMPTY_XMLTAG_MAP()
EMPTY_XMLATTR_MAP()
HRESULT DispatchElement(
const wchar_t *wszNamespaceUri, int cchNamespaceUri,
const wchar_t *wszLocalName, int cchLocalName,
const wchar_t *wszQName, int cchQName,
ISAXAttributes *pAttributes) throw ();
HRESULT GetAttributes(ISAXAttributes *pAttributes);
inline CParserBase * GetParentHandler()
{
return m_spParent;
}
inline void SetParentHandler(CParserBase *pParent)
{
m_spParent = pParent;
}
ISAXXMLReader * GetReader()
{
return m_spReader;
}
inline void SetReader(ISAXXMLReader *pReader)
{
m_spReader = pReader;
}
inline DWORD GetLevel()
{
return m_dwLevel;
}
inline void SetLevel(DWORD dwLevel)
{
m_dwLevel = dwLevel;
}
virtual HRESULT OnUnrecognizedTag(
const wchar_t *wszNamespaceUri, int cchNamespaceUri,
const wchar_t *wszLocalName, int cchLocalName,
const wchar_t *wszQName, int cchQName,
ISAXAttributes *pAttributes) throw ();
virtual HRESULT OnMissingAttribute(BOOL bRequired,
const wchar_t *wszName, int cchName,
const wchar_t *wszNamespace, int cchNamespace);
HRESULT SkipElement();
void EmitInvalidValue(const char *szName, const wchar_t *wszValue);
void EmitUnsupported(UINT nID, const wchar_t *wszUri, const wchar_t *wszName);
void EmitSkip(const wchar_t *wszUri, const wchar_t *wszName);
void EmitString(const wchar_t *wszUri, const wchar_t *wszName);
inline ISAXLocator * GetLocator()
{
if (m_spLocator.p != NULL)
{
return m_spLocator;
}
if (m_spParent.p != NULL)
{
return m_spParent->GetLocator();
}
return NULL;
}
virtual HRESULT ValidateElement()
{
return S_OK;
}
inline void SetGotAttributes(BOOL bGotAttributes)
{
m_bGotAttributes = bGotAttributes;
}
inline BOOL GetGotAttributes()
{
return m_bGotAttributes;
}
inline DWORD GetReset()
{
return m_dwReset;
}
inline void EnableReset(BOOL bForce = FALSE)
{
if (bForce != FALSE)
{
m_dwReset = 0;
}
else if (m_dwReset > 0)
{
m_dwReset--;
}
}
inline void DisableReset(DWORD dwCnt = 1)
{
m_dwReset+= dwCnt;
}
inline BOOL GetDynamicAlloc()
{
return m_bDynamicAlloc;
}
inline void SetDynamicAlloc(BOOL bDynamicAlloc)
{
m_bDynamicAlloc = bDynamicAlloc;
}
//
// IUnknown interface
//
HRESULT __stdcall QueryInterface(REFIID riid, void **ppv);
ULONG __stdcall AddRef();
ULONG __stdcall Release();
//
// ISAXContentHandler interface
//
HRESULT __stdcall putDocumentLocator(ISAXLocator *pLocator);
HRESULT __stdcall startDocument();
HRESULT __stdcall endDocument();
HRESULT __stdcall startPrefixMapping(
const wchar_t *wszPrefix,
int cchPrefix,
const wchar_t *wszUri,
int cchUri);
HRESULT __stdcall endPrefixMapping(
const wchar_t *wszPrefix,
int cchPrefix);
HRESULT __stdcall startElement(
const wchar_t *wszNamespaceUri,
int cchNamespaceUri,
const wchar_t *wszLocalName,
int cchLocalName,
const wchar_t *wszQName,
int cchQName,
ISAXAttributes *pAttributes);
HRESULT __stdcall endElement(
const wchar_t *wszNamespaceUri,
int cchNamespaceUri,
const wchar_t *wszLocalName,
int cchLocalName,
const wchar_t *wszQName,
int cchQName);
HRESULT __stdcall characters(
const wchar_t *wszChars,
int cchChars);
HRESULT __stdcall ignorableWhitespace(
const wchar_t *wszChars,
int cchChars);
HRESULT __stdcall processingInstruction(
const wchar_t *wszTarget,
int cchTarget,
const wchar_t *wszData,
int cchData);
HRESULT __stdcall skippedEntity(
const wchar_t *wszName,
int cchName);
};
inline HRESULT CopyNamespaceMap(const NAMESPACEMAP& in, NAMESPACEMAP& out)
{
out.InitHashTable(in.GetHashTableSize());
out.DisableAutoRehash();
POSITION pos = in.GetStartPosition();
while (pos != NULL)
{
const NAMESPACEMAP::CPair *p = in.GetNext(pos);
if (!out.SetAt(p->m_key, p->m_value))
{
return E_FAIL;
}
}
out.EnableAutoRehash();
return S_OK;
}
// for cleanup purposes
#ifndef _PREFIX_
__declspec(selectany) CAtlPtrList<CParserBase *> g_ParserList;
#else
CAtlPtrList<CParserBase *> g_ParserList;
#endif // _PREFIX_
inline void SetLocatorInfo(CXMLElement *pElem, ISAXLocator *pLocator)
{
ATLASSERT( pLocator != NULL );
ATLASSERT( pElem != NULL );
int nLine = 0;
int nCol = 0;
pLocator->getLineNumber(&nLine);
pLocator->getColumnNumber(&nCol);
pElem->SetLineNumber(nLine);
pElem->SetColumnNumber(nCol);
}
ATL_NOINLINE inline void SetXMLElementInfo(CXMLElement *pElem, CXMLElement *pParent, ISAXLocator *pLocator)
{
ATLASSERT( pElem != NULL );
ATLASSERT( pParent != NULL );
ATLASSERT( pLocator != NULL );
pElem->SetParentElement(pParent);
pElem->SetParentDocument(pParent->GetParentDocument());
SetLocatorInfo(pElem, pLocator);
}
ATL_NOINLINE inline void SetXSDElementInfo(CXSDElement *pElem, CXSDElement *pParent, ISAXLocator *pLocator)
{
ATLASSERT( pElem != NULL );
ATLASSERT( pParent != NULL );
ATLASSERT( pLocator != NULL );
pElem->SetParentSchema(pParent->GetParentSchema());
pElem->SetParentElement(pParent);
pElem->SetParentDocument(pParent->GetParentDocument());
SetLocatorInfo(pElem, pLocator);
}