From: Shaun Ren shaun.ren@linux.com
--- dlls/sapi/Makefile.in | 3 +- dlls/sapi/xml.c | 90 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 3 deletions(-)
diff --git a/dlls/sapi/Makefile.in b/dlls/sapi/Makefile.in index da91eca5b8c..f77f8a55eae 100644 --- a/dlls/sapi/Makefile.in +++ b/dlls/sapi/Makefile.in @@ -1,5 +1,6 @@ MODULE = sapi.dll -IMPORTS = uuid ole32 oleaut32 user32 advapi32 +IMPORTS = $(XML2_PE_LIBS) uuid ole32 oleaut32 user32 advapi32 +EXTRAINCL = $(XML2_PE_CFLAGS) DELAYIMPORTS = winmm
SOURCES = \ diff --git a/dlls/sapi/xml.c b/dlls/sapi/xml.c index eca8f9810bb..a440d90eca1 100644 --- a/dlls/sapi/xml.c +++ b/dlls/sapi/xml.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <libxml/parser.h> +#include <libxml/parserInternals.h> +#include <libxml/xmlerror.h> +#include <libxml/xmlstring.h> + #define COBJMACROS
#include "objbase.h" @@ -30,8 +35,89 @@
WINE_DEFAULT_DEBUG_CHANNEL(sapi);
+struct sapi_xml_parser +{ + xmlParserCtxtPtr ctxt; + HRESULT hr; +}; + +static void sax_startElementNs(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *uri, + int nb_namespaces, const xmlChar **namespaces, int nb_attrs, int nb_defaulted, const xmlChar **attrs) +{ + struct sapi_xml_parser *parser = ctx; + + FIXME("(%p, %s, %s, %s, %d, %p, %d, %d, %p): stub.\n", ctx, + debugstr_a((char *)localname), debugstr_a((char *)prefix), debugstr_a((char *)uri), + nb_namespaces, namespaces, nb_attrs, nb_defaulted, attrs); + + parser->hr = E_NOTIMPL; + xmlStopParser(parser->ctxt); +} + +static void sax_endElementNs(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *uri) +{ + struct sapi_xml_parser *parser = ctx; + + FIXME("(%p, %s, %s, %s): stub.\n", ctx, + debugstr_a((char *)localname), debugstr_a((char *)prefix), debugstr_a((char *)uri)); + + parser->hr = E_NOTIMPL; + xmlStopParser(parser->ctxt); +} + +static void sax_characters(void *ctx, const xmlChar *s, int len) +{ + struct sapi_xml_parser *parser = ctx; + + FIXME("(%p, %p, %d): stub.\n", ctx, s, len); + + parser->hr = E_NOTIMPL; + xmlStopParser(parser->ctxt); +} + +static HRESULT parse_contents(const WCHAR *contents, SPVTEXTFRAG **frag_list) +{ + struct sapi_xml_parser parser; + xmlSAXHandler sax = {0}; + xmlParserCtxtPtr ctxt; + HRESULT hr; + + sax.startElementNs = sax_startElementNs; + sax.endElementNs = sax_endElementNs; + sax.characters = sax_characters; + sax.ignorableWhitespace = sax_characters; + sax.initialized = XML_SAX2_MAGIC; + + if (!(ctxt = xmlCreateMemoryParserCtxt((char *)contents, wcslen(contents) * sizeof(WCHAR)))) + return E_FAIL; + xmlCtxtUseOptions(ctxt, XML_PARSE_HUGE); + xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_UTF16LE); + ctxt->encoding = xmlStrdup((xmlChar *)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE)); + ctxt->sax = &sax; + ctxt->userData = &parser; + + parser.ctxt = ctxt; + parser.hr = S_OK; + + if (xmlParseDocument(ctxt) == -1) + hr = FAILED(parser.hr) ? parser.hr : E_FAIL; + else + hr = parser.hr; + + ctxt->sax = NULL; + xmlFreeParserCtxt(ctxt); + return hr; +} + HRESULT parse_sapi_xml(const WCHAR *contents, DWORD parse_flag, SPVTEXTFRAG **frag_list) { - FIXME("(%p, %#lx, %p): stub.\n", contents, parse_flag, frag_list); - return E_NOTIMPL; + TRACE("(%p, %#lx, %p).\n", contents, parse_flag, frag_list); + + if (parse_flag == SPF_PARSE_SAPI) + { + ERR("SAPI XML is not supported.\n"); + return E_NOTIMPL; + } + + return parse_contents(contents, frag_list); }