gecko-dev/webshell/embed/ActiveX/xml/ParseExpat.cpp

172 строки
3.9 KiB
C++
Исходник Обычный вид История

1999-06-22 01:50:58 +04:00
#include "stdafx.h"
1999-06-24 00:43:27 +04:00
#define XML_UNICODE
1999-06-22 01:50:58 +04:00
#include "xmlparse.h"
1999-06-24 00:43:27 +04:00
#ifdef XML_UNICODE
#define X2OLE W2COLE
#define X2T W2T
#else
#define X2OLE A2COLE
#define X2T A2T
#endif
1999-06-22 01:50:58 +04:00
struct ParserState
{
CComQIPtr<IXMLDocument, &IID_IXMLDocument> spXMLDocument;
1999-06-24 00:43:27 +04:00
CComQIPtr<IXMLElement, &IID_IXMLElement> spXMLRoot;
1999-06-22 01:50:58 +04:00
CComQIPtr<IXMLElement, &IID_IXMLElement> spXMLParent;
};
1999-06-24 00:43:27 +04:00
static ParserState cParserState;
1999-06-22 01:50:58 +04:00
1999-06-24 00:43:27 +04:00
// XML data handlers
1999-06-22 01:50:58 +04:00
static void OnStartElement(void *userData, const XML_Char *name, const XML_Char **atts);
static void OnEndElement(void *userData, const XML_Char *name);
static void OnCharacterData(void *userData, const XML_Char *s, int len);
1999-06-24 00:43:27 +04:00
static void OnDefault(void *userData, const XML_Char *s, int len);
1999-06-22 01:50:58 +04:00
1999-06-24 00:43:27 +04:00
struct ParseData
{
CComQIPtr<IXMLDocument, &IID_IXMLDocument> spDocument;
CComQIPtr<IXMLElement, &IID_IXMLElement> spRoot;
};
HRESULT ParseExpat(const char *pBuffer, unsigned long cbBufSize, IXMLDocument *pDocument, IXMLElement **ppElement)
1999-06-22 01:50:58 +04:00
{
if (pDocument == NULL)
{
return E_INVALIDARG;
}
XML_Parser parser = XML_ParserCreate(NULL);
HRESULT hr = S_OK;
cParserState.spXMLDocument = pDocument;
1999-06-24 00:43:27 +04:00
pDocument->get_root(&cParserState.spXMLParent);
1999-06-22 01:50:58 +04:00
// Initialise the XML parser
XML_SetUserData(parser, &cParserState);
1999-06-24 00:43:27 +04:00
// Initialise the data handlers
1999-06-22 01:50:58 +04:00
XML_SetElementHandler(parser, OnStartElement, OnEndElement);
XML_SetCharacterDataHandler(parser, OnCharacterData);
1999-06-24 00:43:27 +04:00
XML_SetDefaultHandler(parser, OnDefault);
1999-06-22 01:50:58 +04:00
// Parse the data
if (!XML_Parse(parser, pBuffer, cbBufSize, 1))
{
1999-06-24 00:43:27 +04:00
/* TODO Create error code
1999-06-22 01:50:58 +04:00
fprintf(stderr,
"%s at line %d\n",
XML_ErrorString(XML_GetErrorCode(parser)),
XML_GetCurrentLineNumber(parser));
*/
hr = E_FAIL;
}
// Cleanup
XML_ParserFree(parser);
1999-06-24 00:43:27 +04:00
cParserState.spXMLRoot->QueryInterface(IID_IXMLElement, (void **) ppElement);
1999-06-22 01:50:58 +04:00
cParserState.spXMLDocument.Release();
cParserState.spXMLParent.Release();
return S_OK;
}
1999-06-24 00:43:27 +04:00
///////////////////////////////////////////////////////////////////////////////
1999-06-22 01:50:58 +04:00
void OnStartElement(void *userData, const XML_Char *name, const XML_Char **atts)
{
ParserState *pState = (ParserState *) userData;
if (pState)
{
USES_CONVERSION;
CComQIPtr<IXMLElement, &IID_IXMLElement> spXMLElement;
// Create a new element
pState->spXMLDocument->createElement(
CComVariant(XMLELEMTYPE_ELEMENT),
1999-06-24 00:43:27 +04:00
CComVariant(X2OLE(name)),
1999-06-22 01:50:58 +04:00
&spXMLElement);
if (spXMLElement)
{
// Create each attribute
for (int i = 0; atts[i] != NULL; i += 2)
{
const XML_Char *pszName = atts[i];
const XML_Char *pszValue = atts[i+1];
1999-06-24 00:43:27 +04:00
spXMLElement->setAttribute((BSTR) X2OLE(pszName), CComVariant(X2OLE(pszValue)));
1999-06-22 01:50:58 +04:00
}
1999-06-24 00:43:27 +04:00
if (pState->spXMLRoot == NULL)
{
pState->spXMLRoot = spXMLElement;
}
if (pState->spXMLParent)
{
// Add the element to the end of the list
pState->spXMLParent->addChild(spXMLElement, -1, -1);
}
pState->spXMLParent = spXMLElement;
1999-06-22 01:50:58 +04:00
}
}
}
void OnEndElement(void *userData, const XML_Char *name)
1999-06-24 00:43:27 +04:00
{
ParserState *pState = (ParserState *) userData;
if (pState)
{
CComQIPtr<IXMLElement, &IID_IXMLElement> spNewParent;
if (pState->spXMLParent)
{
pState->spXMLParent->get_parent(&spNewParent);
pState->spXMLParent = spNewParent;
}
}
}
void OnDefault(void *userData, const XML_Char *s, int len)
1999-06-22 01:50:58 +04:00
{
1999-07-01 02:41:39 +04:00
XML_Char *pString = new XML_Char[len + 1];
memset(pString, 0, sizeof(XML_Char) * (len + 1));
memcpy(pString, s, sizeof(XML_Char) * len);
USES_CONVERSION;
ATLTRACE(_T("OnDefault: \"%s\"\n"), X2T(pString));
// TODO test if the buffer contains <?xml version="X"?>
// and store version in XML document
// TODO test if the buffer contains DTD and store it
// in the XML document
// TODO test if the buffer contains a comment, i.e. <!--.*-->
// and create a comment XML element
delete []pString;
1999-06-22 01:50:58 +04:00
}
void OnCharacterData(void *userData, const XML_Char *s, int len)
{
ParserState *pState = (ParserState *) userData;
if (pState)
{
// TODO create TEXT element
}
}