mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
356 lines
12 KiB
356 lines
12 KiB
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// fusion\xmlparser\XMLParser.hxx
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
#ifndef _FUSION_XMLPARSER__XMLPARSER_H_INCLUDE_
|
|
#define _FUSION_XMLPARSER__XMLPARSER_H_INCLUDE_
|
|
#pragma once
|
|
|
|
#include <ole2.h>
|
|
#include <xmlparser.h>
|
|
#include "xmlhelper.hxx"
|
|
class XMLStream;
|
|
|
|
typedef _reference<IXMLParser> RXMLParser;
|
|
typedef _reference<IXMLNodeFactory> RNodeFactory;
|
|
typedef _reference<IUnknown> RUnknown;
|
|
typedef _reference<IBindStatusCallback> RIBindStatusCallback;
|
|
|
|
#include "encodingstream.hxx"
|
|
|
|
#include "_rawstack.hxx"
|
|
//#define XMLFLAG_RUNBUFFERONLY 0x1000
|
|
|
|
//------------------------------------------------------------------------
|
|
// An internal Parser IID so that DTDNodeFactory can call internal methods.
|
|
const IID IID_Parser = {0xa79b04fe,0x8b3c,0x11d2,{0x9c, 0xd3,0x00,0x60,0xb0,0xec,0x3d,0x30}};
|
|
|
|
class XMLParser : public _unknown<IXMLParser, &IID_IXMLParser>
|
|
{
|
|
public:
|
|
|
|
XMLParser();
|
|
~XMLParser();
|
|
|
|
// ======= IUnknown override ============================
|
|
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject);
|
|
|
|
virtual ULONG STDMETHODCALLTYPE AddRef(void);
|
|
|
|
virtual ULONG STDMETHODCALLTYPE Release(void);
|
|
|
|
// ====== IXMLNodeSource methods ========================
|
|
virtual HRESULT STDMETHODCALLTYPE SetFactory(
|
|
/* [in] */ IXMLNodeFactory __RPC_FAR *pNodeFactory);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetFactory(
|
|
/* [out] */ IXMLNodeFactory** ppNodeFactory);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Abort(
|
|
/* [in] */ BSTR bstrErrorInfo);
|
|
|
|
virtual ULONG STDMETHODCALLTYPE GetLineNumber(void);
|
|
|
|
virtual ULONG STDMETHODCALLTYPE GetLinePosition(void);
|
|
|
|
virtual ULONG STDMETHODCALLTYPE GetAbsolutePosition(void);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetLineBuffer(
|
|
/* [out] */ const WCHAR **ppwcBuf,
|
|
/* [out] */ ULONG *pulLen,
|
|
/* [out] */ ULONG *pulStartPos);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetLastError(void);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetErrorInfo(/* [out] */ BSTR *pbstrErrorInfo)
|
|
{
|
|
ASSERT_NTC(FALSE);
|
|
UNUSED(pbstrErrorInfo);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual ULONG STDMETHODCALLTYPE GetFlags() {
|
|
return 0;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetURL(
|
|
/* [out] */ const WCHAR **ppwcBuf) {
|
|
UNUSED(ppwcBuf);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
// ====== IXMLParser methods ==============================
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE SetURL(
|
|
/* [in] */ const WCHAR* pszBaseUrl,
|
|
/* [in] */ const WCHAR* pszRelativeUrl,
|
|
/* [in] */ BOOL async) {
|
|
UNUSED(pszBaseUrl);
|
|
UNUSED(pszRelativeUrl);
|
|
UNUSED(async);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Load(
|
|
/* [in] */ BOOL fFullyAvailable,
|
|
/* [in] */ IMoniker *pimkName,
|
|
/* [in] */ LPBC pibc,
|
|
/* [in] */ DWORD grfMode) {
|
|
|
|
UNUSED(fFullyAvailable);
|
|
UNUSED(pimkName);
|
|
UNUSED(pibc);
|
|
UNUSED(grfMode);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE SetInput(
|
|
/* [in] */ IUnknown*pStm);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE PushData(
|
|
/* [in] */ const char *pData,
|
|
/* [in] */ ULONG ulChars,
|
|
/* [in] */ BOOL bLastBuffer);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE LoadEntity(
|
|
/* [in] */ const WCHAR* pszBaseUrl,
|
|
/* [in] */ const WCHAR* pszRelativeUrl,
|
|
/* [in] */ BOOL fpe) {
|
|
UNUSED(pszBaseUrl);
|
|
UNUSED(pszRelativeUrl);
|
|
UNUSED(fpe);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE ParseEntity(
|
|
/* [in] */ const WCHAR* pwcText,
|
|
/* [in] */ ULONG ulLen,
|
|
/* [in] */ BOOL fpe){
|
|
UNUSED(pwcText);
|
|
UNUSED(ulLen);
|
|
UNUSED(fpe);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE ExpandEntity(
|
|
/* [in] */ const WCHAR* pwcText,
|
|
/* [in] */ ULONG ulLen) {
|
|
UNUSED(pwcText);
|
|
UNUSED(ulLen);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE SetRoot(
|
|
/* [in] */ PVOID pRoot) {
|
|
UNUSED(pRoot);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetRoot(
|
|
/* [in] */ PVOID __RPC_FAR *ppRoot){
|
|
UNUSED(ppRoot);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Run(
|
|
/* [in] */ long lChars);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetParserState(void) ;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Suspend(void) ;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Reset(void) ;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE SetFlags(
|
|
/* [in] */ ULONG iFlags) {
|
|
UNUSED(iFlags);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE LoadDTD(
|
|
/* [in] */ const WCHAR * pszBaseUrl,
|
|
/* [in] */ const WCHAR * pszRelativeUrl){
|
|
UNUSED(pszBaseUrl);
|
|
UNUSED(pszRelativeUrl);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE SetSecureBaseURL(
|
|
/* [in] */ const WCHAR* pszBaseUrl){
|
|
UNUSED(pszBaseUrl);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetSecureBaseURL(
|
|
/* [out] */ const WCHAR ** ppwcBuf){
|
|
UNUSED(ppwcBuf);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
// ======= internal only methods for Parser
|
|
#ifdef FUSION_USE_OLD_XML_PARSER_SOURCE
|
|
HRESULT SetCurrentURL(
|
|
/* [in] */ const WCHAR* pszCurrentUrl); // SRC attribute on <SCRIPT island>
|
|
// used by SetInput()
|
|
HRESULT SetBaseURL(
|
|
/* [in] */ const WCHAR* pszBaseUrl); // in case PushData is called.
|
|
#endif
|
|
|
|
HRESULT ErrorCallback(HRESULT hr);
|
|
|
|
private:
|
|
void ctorInit();
|
|
#ifdef FUSION_USE_OLD_XML_PARSER_SOURCE
|
|
HRESULT PushURL(
|
|
/* [in] */ const WCHAR* pszBaseUrl,
|
|
/* [in] */ const WCHAR* pszRelativeUrl,
|
|
/* [in] */ bool async,
|
|
/* [in] */ bool tokenizer,
|
|
/* [in] */ bool dtd,
|
|
/* [in] */ bool fentity,
|
|
/* [in] */ bool fpe );
|
|
// used in SetURL(). LoadDTDDate(), LoadEntity();
|
|
#endif
|
|
|
|
#ifdef FUSION_USE_OLD_XML_PARSER_SOURCE
|
|
HRESULT PushTokenizer(URLStream* stream);
|
|
#else
|
|
HRESULT PushTokenizer();
|
|
#endif
|
|
|
|
#ifdef FUSION_USE_OLD_XML_PARSER_SOURCE
|
|
HRESULT PushDownload(URLStream* stream, XMLStream* tokenizer);
|
|
#else
|
|
HRESULT PushDownload(XMLStream* tokenizer);
|
|
#endif
|
|
|
|
HRESULT PopDownload();
|
|
|
|
XMLStream* _pTokenizer;
|
|
PVOID _pRoot;
|
|
HRESULT _fLastError;
|
|
BSTR _bstrError;
|
|
bool _fWaiting;
|
|
bool _fSuspended;
|
|
bool _fStopped;
|
|
bool _fStarted;
|
|
bool _fInXmlDecl;
|
|
bool _fFoundEncoding;
|
|
USHORT _usFlags;
|
|
bool _fCaseInsensitive;
|
|
//bool _fTokenizerChanged; // used in DTD, tokenizer may change in DTD file
|
|
bool _fGotVersion; // used in XML_VERSION
|
|
long _fRunEntryCount; // used in Run(), counting how many is running the Parsing-While
|
|
|
|
//bool _fInLoading; // used in PushURL(), Load(), HandleData(),
|
|
bool _fInsideRun; // used in Run()
|
|
bool _fFoundRoot;
|
|
|
|
//bool _fSeenDocType; // used in DTD
|
|
bool _fRootLevel; // whether we are at the root level in document.
|
|
bool _fFoundNonWS;
|
|
bool _fPendingBeginChildren;
|
|
bool _fPendingEndChildren;
|
|
|
|
//BSTR _fAttemptedURL; // used in PushURL(), Load(), GetErrorInfo();
|
|
|
|
struct Download
|
|
{
|
|
XMLStream* _pTokenizer;
|
|
//RURLStream _pURLStream;
|
|
REncodingStream _pEncodingStream;
|
|
bool _fAsync;
|
|
bool _fDTD;
|
|
bool _fEntity;
|
|
bool _fPEReference;
|
|
bool _fFoundNonWS;
|
|
bool _fFoundRoot; // saved values in case we're downloading a schema
|
|
bool _fSeenDocType;
|
|
bool _fRootLevel; // whether we are at the root level in document.
|
|
int _fDepth; // current depth of stack.
|
|
};
|
|
_rawstack<Download> _pDownloads;
|
|
Download* _pdc; // current download.
|
|
|
|
|
|
// the Context struct contains members that map to the XML_NODE_INFO struct
|
|
// defined in xmlparser.idl so that we can pass the contents of the Context
|
|
// as a XML_NODE_INFO* pointer in BeginChildren, EndChildren and Error.
|
|
|
|
typedef struct _MY_XML_NODE_INFO : public XML_NODE_INFO
|
|
{
|
|
// DWORD dwSize; // size of this struct
|
|
// DWORD dwType; // node type (XML_NODE_TYPE)
|
|
// DWORD dwSubType; // node sub type (XML_NODE_SUBTYPE)
|
|
// BOOL fTerminal; // whether this node can have any children
|
|
// WCHAR* pwcText; // element names, or text node contents.
|
|
// ULONG ulLen; // length of pwcText
|
|
// ULONG ulNsPrefixLen; // if element name, this is namespace prefix length.
|
|
// PVOID pNode; // optionally created by & returned from node factory
|
|
// PVOID pReserved; // reserved for factories to use between themselves.
|
|
WCHAR* _pwcTagName; // saved tag name
|
|
ULONG _ulBufLen;
|
|
} MY_XML_NODE_INFO;
|
|
typedef MY_XML_NODE_INFO* PMY_XML_NODE_INFO;
|
|
|
|
_rawstack<MY_XML_NODE_INFO> _pStack;
|
|
|
|
long _lCurrentElement;
|
|
PMY_XML_NODE_INFO _pCurrent;
|
|
USHORT _cAttributes; // count of attributes on stack.
|
|
|
|
// And we need a contiguous array of pointers to the XML_NODE_INFO
|
|
// structs for CreateNode.
|
|
PMY_XML_NODE_INFO* _paNodeInfo;
|
|
USHORT _cNodeInfoAllocated;
|
|
USHORT _cNodeInfoCurrent;
|
|
|
|
PVOID _pNode; // current node (== pCurrent->pNode OR _pRoot).
|
|
|
|
// Push saves this factory in the context and pop restores it
|
|
// from the context.
|
|
RNodeFactory _pFactory; // current factory (!= pCurrent->pParentFactory).
|
|
|
|
HRESULT push(XML_NODE_INFO& info);
|
|
HRESULT pushAttribute(XML_NODE_INFO& info);
|
|
HRESULT pushAttributeValue(XML_NODE_INFO& info);
|
|
|
|
HRESULT pop(const WCHAR* tag, ULONG len);
|
|
HRESULT pop();
|
|
HRESULT popAttributes();
|
|
void popAttribute();
|
|
HRESULT popDTDAttribute() { return E_NOTIMPL; }
|
|
|
|
HRESULT CopyContext();
|
|
HRESULT CopyText(PMY_XML_NODE_INFO pNodeInfo);
|
|
HRESULT ReportUnclosedTags(int index);
|
|
HRESULT GrowBuffer(PMY_XML_NODE_INFO pNodeInfo, long newlen);
|
|
HRESULT GrowNodeInfo();
|
|
|
|
|
|
CRITICAL_SECTION _cs;
|
|
|
|
HRESULT init();
|
|
|
|
HRESULT PushStream(IStream* pStm, bool fpe);
|
|
//Download* FindDownload(URLStream* pStream);
|
|
WCHAR* getSecureBaseURL()
|
|
{
|
|
if (_pszSecureBaseURL)
|
|
return _pszSecureBaseURL;
|
|
else if (_dwSafetyOptions)
|
|
return _pszBaseURL;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
WCHAR* _pszSecureBaseURL;
|
|
WCHAR* _pszCurrentURL;
|
|
WCHAR* _pszBaseURL;
|
|
bool _fIgnoreEncodingAttr;
|
|
DWORD _dwSafetyOptions;
|
|
};
|
|
|
|
|
|
#endif // _FUSION_XMLPARSER__XMLPARSER_H_INCLUDE_
|