2 * SAX Reader implementation
4 * Copyright 2008 Alistair Leslie-Hughes
5 * Copyright 2008 Piotr Caban
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
29 # include <libxml/SAX2.h>
30 # include <libxml/parserInternals.h>
44 #include "wine/debug.h"
45 #include "wine/list.h"
47 #include "msxml_private.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
56 ExhaustiveErrors = 1 << 1,
57 ExternalGeneralEntities = 1 << 2,
58 ExternalParameterEntities = 1 << 3,
59 ForcedResync = 1 << 4,
60 NamespacePrefixes = 1 << 5,
62 ParameterEntities = 1 << 7,
63 PreserveSystemIndentifiers = 1 << 8,
65 SchemaValidation = 1 << 10,
66 ServerHttpRequest = 1 << 11,
67 SuppressValidationfatalError = 1 << 12,
68 UseInlineSchema = 1 << 13,
69 UseSchemaLocation = 1 << 14,
70 LexicalHandlerParEntities = 1 << 15
74 static const WCHAR FeatureExternalGeneralEntitiesW[] = {
75 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/',
76 'f','e','a','t','u','r','e','s','/','e','x','t','e','r','n','a','l','-','g','e','n','e','r','a','l',
77 '-','e','n','t','i','t','i','e','s',0
80 static const WCHAR FeatureExternalParameterEntitiesW[] = {
81 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
82 '/','e','x','t','e','r','n','a','l','-','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0
85 static const WCHAR FeatureLexicalHandlerParEntitiesW[] = {
86 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
87 '/','l','e','x','i','c','a','l','-','h','a','n','d','l','e','r','/','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0
90 static const WCHAR FeatureProhibitDTDW[] = {
91 'p','r','o','h','i','b','i','t','-','d','t','d',0
94 static const WCHAR FeatureNamespacesW[] = {
95 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
96 '/','n','a','m','e','s','p','a','c','e','s',0
99 static const WCHAR FeatureNamespacePrefixesW[] = {
100 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
101 '/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0
104 struct saxreader_feature_pair
106 saxreader_feature feature;
110 static const struct saxreader_feature_pair saxreader_feature_map[] = {
111 { ExternalGeneralEntities, FeatureExternalGeneralEntitiesW },
112 { ExternalParameterEntities, FeatureExternalParameterEntitiesW },
113 { LexicalHandlerParEntities, FeatureLexicalHandlerParEntitiesW },
114 { NamespacePrefixes, FeatureNamespacePrefixesW },
115 { Namespaces, FeatureNamespacesW },
116 { ProhibitDTD, FeatureProhibitDTDW }
119 static saxreader_feature get_saxreader_feature(const WCHAR *name)
124 max = sizeof(saxreader_feature_map)/sizeof(struct saxreader_feature_pair) - 1;
130 c = strcmpW(saxreader_feature_map[n].name, name);
132 return saxreader_feature_map[n].feature;
140 return FeatureUnknown;
162 ns *ns; /* namespaces defined in this particular element */
168 SAXContentHandler = 0,
177 struct saxanyhandler_iface
183 struct saxcontenthandler_iface
185 ISAXContentHandler *handler;
186 IVBSAXContentHandler *vbhandler;
189 struct saxerrorhandler_iface
191 ISAXErrorHandler *handler;
192 IVBSAXErrorHandler *vbhandler;
195 struct saxlexicalhandler_iface
197 ISAXLexicalHandler *handler;
198 IVBSAXLexicalHandler *vbhandler;
201 struct saxentityresolver_iface
203 ISAXEntityResolver *handler;
204 IVBSAXEntityResolver *vbhandler;
207 struct saxhandler_iface
210 struct saxcontenthandler_iface content;
211 struct saxentityresolver_iface entityresolver;
212 struct saxerrorhandler_iface error;
213 struct saxlexicalhandler_iface lexical;
214 struct saxanyhandler_iface anyhandler;
221 IVBSAXXMLReader IVBSAXXMLReader_iface;
222 ISAXXMLReader ISAXXMLReader_iface;
225 struct saxhandler_iface saxhandlers[SAXHandler_Last];
228 struct bstrpool pool;
229 saxreader_feature features;
230 BSTR xmldecl_version;
231 MSXML_VERSION version;
234 static HRESULT saxreader_put_handler(saxreader *reader, enum saxhandler_type type, void *ptr, BOOL vb)
236 struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler;
237 IUnknown *unk = (IUnknown*)ptr;
240 IUnknown_AddRef(unk);
242 if ((vb && iface->vbhandler) || (!vb && iface->handler))
243 IUnknown_Release(vb ? iface->vbhandler : iface->handler);
246 iface->vbhandler = unk;
248 iface->handler = unk;
253 static HRESULT saxreader_get_handler(const saxreader *reader, enum saxhandler_type type, BOOL vb, void **ret)
255 const struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler;
257 if (!ret) return E_POINTER;
259 if ((vb && iface->vbhandler) || (!vb && iface->handler))
262 IUnknown_AddRef(iface->vbhandler);
264 IUnknown_AddRef(iface->handler);
267 *ret = vb ? iface->vbhandler : iface->handler;
272 static struct saxcontenthandler_iface *saxreader_get_contenthandler(saxreader *reader)
274 return &reader->saxhandlers[SAXContentHandler].u.content;
277 static struct saxerrorhandler_iface *saxreader_get_errorhandler(saxreader *reader)
279 return &reader->saxhandlers[SAXErrorHandler].u.error;
282 static struct saxlexicalhandler_iface *saxreader_get_lexicalhandler(saxreader *reader)
284 return &reader->saxhandlers[SAXLexicalHandler].u.lexical;
289 IVBSAXLocator IVBSAXLocator_iface;
290 ISAXLocator ISAXLocator_iface;
291 IVBSAXAttributes IVBSAXAttributes_iface;
292 ISAXAttributes ISAXAttributes_iface;
294 saxreader *saxreader;
296 xmlParserCtxtPtr pParserCtxt;
302 struct list elements;
316 static inline saxreader *impl_from_IVBSAXXMLReader( IVBSAXXMLReader *iface )
318 return CONTAINING_RECORD(iface, saxreader, IVBSAXXMLReader_iface);
321 static inline saxreader *impl_from_ISAXXMLReader( ISAXXMLReader *iface )
323 return CONTAINING_RECORD(iface, saxreader, ISAXXMLReader_iface);
326 static inline saxlocator *impl_from_IVBSAXLocator( IVBSAXLocator *iface )
328 return CONTAINING_RECORD(iface, saxlocator, IVBSAXLocator_iface);
331 static inline saxlocator *impl_from_ISAXLocator( ISAXLocator *iface )
333 return CONTAINING_RECORD(iface, saxlocator, ISAXLocator_iface);
336 static inline saxlocator *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
338 return CONTAINING_RECORD(iface, saxlocator, IVBSAXAttributes_iface);
341 static inline saxlocator *impl_from_ISAXAttributes( ISAXAttributes *iface )
343 return CONTAINING_RECORD(iface, saxlocator, ISAXAttributes_iface);
346 static inline int saxreader_has_handler(const saxlocator *locator, enum saxhandler_type type)
348 struct saxanyhandler_iface *iface = &locator->saxreader->saxhandlers[type].u.anyhandler;
349 return (locator->vbInterface && iface->vbhandler) || (!locator->vbInterface && iface->handler);
352 static HRESULT saxreader_saxcharacters(saxlocator *locator, BSTR chars)
354 struct saxcontenthandler_iface *content = saxreader_get_contenthandler(locator->saxreader);
357 if (!saxreader_has_handler(locator, SAXContentHandler)) return S_OK;
359 if (locator->vbInterface)
360 hr = IVBSAXContentHandler_characters(content->vbhandler, &chars);
362 hr = ISAXContentHandler_characters(content->handler, chars, SysStringLen(chars));
368 static const WCHAR PropertyCharsetW[] = {
369 'c','h','a','r','s','e','t',0
371 static const WCHAR PropertyXmlDeclVersionW[] = {
372 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
374 static const WCHAR PropertyDeclHandlerW[] = {
375 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
376 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
377 'd','e','c','l','a','r','a','t','i','o','n',
378 '-','h','a','n','d','l','e','r',0
380 static const WCHAR PropertyDomNodeW[] = {
381 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
382 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
383 'd','o','m','-','n','o','d','e',0
385 static const WCHAR PropertyInputSourceW[] = {
386 'i','n','p','u','t','-','s','o','u','r','c','e',0
388 static const WCHAR PropertyLexicalHandlerW[] = {
389 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
390 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
391 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
393 static const WCHAR PropertyMaxElementDepthW[] = {
394 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
396 static const WCHAR PropertyMaxXMLSizeW[] = {
397 'm','a','x','-','x','m','l','-','s','i','z','e',0
399 static const WCHAR PropertySchemaDeclHandlerW[] = {
400 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
401 'h','a','n','d','l','e','r',0
403 static const WCHAR PropertyXMLDeclEncodingW[] = {
404 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
406 static const WCHAR PropertyXMLDeclStandaloneW[] = {
407 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
409 static const WCHAR PropertyXMLDeclVersionW[] = {
410 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
413 static inline HRESULT set_feature_value(saxreader *reader, saxreader_feature feature, VARIANT_BOOL value)
415 /* handling of non-VARIANT_* values is version dependent */
416 if ((reader->version < MSXML4) && (value != VARIANT_TRUE))
417 value = VARIANT_FALSE;
418 if ((reader->version >= MSXML4) && (value != VARIANT_FALSE))
419 value = VARIANT_TRUE;
421 if (value == VARIANT_TRUE)
422 reader->features |= feature;
424 reader->features &= ~feature;
429 static inline HRESULT get_feature_value(const saxreader *reader, saxreader_feature feature, VARIANT_BOOL *value)
431 *value = reader->features & feature ? VARIANT_TRUE : VARIANT_FALSE;
435 static BOOL is_namespaces_enabled(const saxreader *reader)
437 return (reader->version < MSXML4) || (reader->features & Namespaces);
440 static BSTR build_qname(BSTR prefix, BSTR local)
442 if (prefix && *prefix)
444 BSTR qname = SysAllocStringLen(NULL, SysStringLen(prefix) + SysStringLen(local) + 1);
448 strcpyW(ptr, prefix);
449 ptr += SysStringLen(prefix);
455 return SysAllocString(local);
458 static element_entry* alloc_element_entry(const xmlChar *local, const xmlChar *prefix, int nb_ns,
459 const xmlChar **namespaces)
464 ret = heap_alloc(sizeof(*ret));
465 if (!ret) return ret;
467 ret->local = bstr_from_xmlChar(local);
468 ret->prefix = bstr_from_xmlChar(prefix);
469 ret->qname = build_qname(ret->prefix, ret->local);
470 ret->ns = nb_ns ? heap_alloc(nb_ns*sizeof(ns)) : NULL;
471 ret->ns_count = nb_ns;
473 for (i=0; i < nb_ns; i++)
475 ret->ns[i].prefix = bstr_from_xmlChar(namespaces[2*i]);
476 ret->ns[i].uri = bstr_from_xmlChar(namespaces[2*i+1]);
482 static void free_element_entry(element_entry *element)
486 for (i=0; i<element->ns_count;i++)
488 SysFreeString(element->ns[i].prefix);
489 SysFreeString(element->ns[i].uri);
492 SysFreeString(element->prefix);
493 SysFreeString(element->local);
495 heap_free(element->ns);
499 static void push_element_ns(saxlocator *locator, element_entry *element)
501 list_add_head(&locator->elements, &element->entry);
504 static element_entry * pop_element_ns(saxlocator *locator)
506 element_entry *element = LIST_ENTRY(list_head(&locator->elements), element_entry, entry);
509 list_remove(&element->entry);
514 static BSTR find_element_uri(saxlocator *locator, const xmlChar *uri)
516 element_entry *element;
520 if (!uri) return NULL;
522 uriW = bstr_from_xmlChar(uri);
524 LIST_FOR_EACH_ENTRY(element, &locator->elements, element_entry, entry)
526 for (i=0; i < element->ns_count; i++)
527 if (!strcmpW(uriW, element->ns[i].uri))
530 return element->ns[i].uri;
535 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri));
539 /* used to localize version dependent error check behaviour */
540 static inline BOOL sax_callback_failed(saxlocator *This, HRESULT hr)
542 return This->saxreader->version >= MSXML4 ? FAILED(hr) : hr != S_OK;
545 /* index value -1 means it tries to loop for a first time */
546 static inline BOOL iterate_endprefix_index(saxlocator *This, const element_entry *element, int *i)
548 if (This->saxreader->version >= MSXML4)
550 if (*i == -1) *i = 0; else ++*i;
551 return *i < element->ns_count;
555 if (*i == -1) *i = element->ns_count-1; else --*i;
560 static BOOL bstr_pool_insert(struct bstrpool *pool, BSTR pool_entry)
564 pool->pool = HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(*pool->pool));
571 else if (pool->index == pool->len)
573 BSTR *realloc = HeapReAlloc(GetProcessHeap(), 0, pool->pool, pool->len * 2 * sizeof(*realloc));
578 pool->pool = realloc;
582 pool->pool[pool->index++] = pool_entry;
586 static void free_bstr_pool(struct bstrpool *pool)
590 for (i = 0; i < pool->index; i++)
591 SysFreeString(pool->pool[i]);
593 HeapFree(GetProcessHeap(), 0, pool->pool);
596 pool->index = pool->len = 0;
599 static BSTR bstr_from_xmlCharN(const xmlChar *buf, int len)
607 dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0);
608 if(len != -1) dLen++;
609 bstr = SysAllocStringLen(NULL, dLen-1);
612 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, bstr, dLen);
613 if(len != -1) bstr[dLen-1] = '\0';
618 static BSTR QName_from_xmlChar(const xmlChar *prefix, const xmlChar *name)
623 if(!name) return NULL;
625 if(!prefix || !*prefix)
626 return bstr_from_xmlChar(name);
628 qname = xmlBuildQName(name, prefix, NULL, 0);
629 bstr = bstr_from_xmlChar(qname);
635 static BSTR pooled_bstr_from_xmlChar(struct bstrpool *pool, const xmlChar *buf)
637 BSTR pool_entry = bstr_from_xmlChar(buf);
639 if (pool_entry && !bstr_pool_insert(pool, pool_entry))
641 SysFreeString(pool_entry);
648 static BSTR pooled_bstr_from_xmlCharN(struct bstrpool *pool, const xmlChar *buf, int len)
650 BSTR pool_entry = bstr_from_xmlCharN(buf, len);
652 if (pool_entry && !bstr_pool_insert(pool, pool_entry))
654 SysFreeString(pool_entry);
661 static void format_error_message_from_id(saxlocator *This, HRESULT hr)
663 struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader);
664 xmlStopParser(This->pParserCtxt);
667 if (saxreader_has_handler(This, SAXErrorHandler))
670 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
671 NULL, hr, 0, msg, sizeof(msg), NULL))
673 FIXME("MSXML errors not yet supported.\n");
677 if(This->vbInterface)
679 BSTR bstrMsg = SysAllocString(msg);
680 IVBSAXErrorHandler_fatalError(handler->vbhandler,
681 &This->IVBSAXLocator_iface, &bstrMsg, hr);
682 SysFreeString(bstrMsg);
685 ISAXErrorHandler_fatalError(handler->handler,
686 &This->ISAXLocator_iface, msg, hr);
690 static void update_position(saxlocator *This, BOOL fix_column)
692 const xmlChar *p = This->pParserCtxt->input->cur-1;
694 This->line = xmlSAX2GetLineNumber(This->pParserCtxt);
698 for(; *p!='\n' && *p!='\r' && p>=This->pParserCtxt->input->base; p--)
703 This->column = xmlSAX2GetColumnNumber(This->pParserCtxt);
707 /*** IVBSAXAttributes interface ***/
708 /*** IUnknown methods ***/
709 static HRESULT WINAPI ivbsaxattributes_QueryInterface(
710 IVBSAXAttributes* iface,
714 saxlocator *This = impl_from_IVBSAXAttributes(iface);
715 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
716 return IVBSAXLocator_QueryInterface(&This->IVBSAXLocator_iface, riid, ppvObject);
719 static ULONG WINAPI ivbsaxattributes_AddRef(IVBSAXAttributes* iface)
721 saxlocator *This = impl_from_IVBSAXAttributes(iface);
722 return ISAXLocator_AddRef(&This->ISAXLocator_iface);
725 static ULONG WINAPI ivbsaxattributes_Release(IVBSAXAttributes* iface)
727 saxlocator *This = impl_from_IVBSAXAttributes(iface);
728 return ISAXLocator_Release(&This->ISAXLocator_iface);
731 /*** IDispatch methods ***/
732 static HRESULT WINAPI ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
734 saxlocator *This = impl_from_IVBSAXAttributes( iface );
736 TRACE("(%p)->(%p)\n", This, pctinfo);
743 static HRESULT WINAPI ivbsaxattributes_GetTypeInfo(
744 IVBSAXAttributes *iface,
745 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
747 saxlocator *This = impl_from_IVBSAXAttributes( iface );
750 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
752 hr = get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
757 static HRESULT WINAPI ivbsaxattributes_GetIDsOfNames(
758 IVBSAXAttributes *iface,
765 saxlocator *This = impl_from_IVBSAXAttributes( iface );
769 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
772 if(!rgszNames || cNames == 0 || !rgDispId)
775 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
778 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
779 ITypeInfo_Release(typeinfo);
785 static HRESULT WINAPI ivbsaxattributes_Invoke(
786 IVBSAXAttributes *iface,
791 DISPPARAMS* pDispParams,
793 EXCEPINFO* pExcepInfo,
796 saxlocator *This = impl_from_IVBSAXAttributes( iface );
800 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
801 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
803 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
806 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
807 pDispParams, pVarResult, pExcepInfo, puArgErr);
808 ITypeInfo_Release(typeinfo);
814 /*** IVBSAXAttributes methods ***/
815 static HRESULT WINAPI ivbsaxattributes_get_length(
816 IVBSAXAttributes* iface,
819 saxlocator *This = impl_from_IVBSAXAttributes( iface );
820 return ISAXAttributes_getLength(&This->ISAXAttributes_iface, nLength);
823 static HRESULT WINAPI ivbsaxattributes_getURI(
824 IVBSAXAttributes* iface,
829 saxlocator *This = impl_from_IVBSAXAttributes( iface );
830 return ISAXAttributes_getURI(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)uri, &len);
833 static HRESULT WINAPI ivbsaxattributes_getLocalName(
834 IVBSAXAttributes* iface,
839 saxlocator *This = impl_from_IVBSAXAttributes( iface );
840 return ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, nIndex,
841 (const WCHAR**)localName, &len);
844 static HRESULT WINAPI ivbsaxattributes_getQName(
845 IVBSAXAttributes* iface,
850 saxlocator *This = impl_from_IVBSAXAttributes( iface );
851 return ISAXAttributes_getQName(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)QName, &len);
854 static HRESULT WINAPI ivbsaxattributes_getIndexFromName(
855 IVBSAXAttributes* iface,
860 saxlocator *This = impl_from_IVBSAXAttributes( iface );
861 return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
862 localName, SysStringLen(localName), index);
865 static HRESULT WINAPI ivbsaxattributes_getIndexFromQName(
866 IVBSAXAttributes* iface,
870 saxlocator *This = impl_from_IVBSAXAttributes( iface );
871 return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, QName,
872 SysStringLen(QName), index);
875 static HRESULT WINAPI ivbsaxattributes_getType(
876 IVBSAXAttributes* iface,
881 saxlocator *This = impl_from_IVBSAXAttributes( iface );
882 return ISAXAttributes_getType(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)type, &len);
885 static HRESULT WINAPI ivbsaxattributes_getTypeFromName(
886 IVBSAXAttributes* iface,
892 saxlocator *This = impl_from_IVBSAXAttributes( iface );
893 return ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
894 localName, SysStringLen(localName), (const WCHAR**)type, &len);
897 static HRESULT WINAPI ivbsaxattributes_getTypeFromQName(
898 IVBSAXAttributes* iface,
903 saxlocator *This = impl_from_IVBSAXAttributes( iface );
904 return ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, QName, SysStringLen(QName),
905 (const WCHAR**)type, &len);
908 static HRESULT WINAPI ivbsaxattributes_getValue(
909 IVBSAXAttributes* iface,
914 saxlocator *This = impl_from_IVBSAXAttributes( iface );
915 return ISAXAttributes_getValue(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)value, &len);
918 static HRESULT WINAPI ivbsaxattributes_getValueFromName(
919 IVBSAXAttributes* iface,
925 saxlocator *This = impl_from_IVBSAXAttributes( iface );
926 return ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
927 localName, SysStringLen(localName), (const WCHAR**)value, &len);
930 static HRESULT WINAPI ivbsaxattributes_getValueFromQName(
931 IVBSAXAttributes* iface,
936 saxlocator *This = impl_from_IVBSAXAttributes( iface );
937 return ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, QName,
938 SysStringLen(QName), (const WCHAR**)value, &len);
941 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl =
943 ivbsaxattributes_QueryInterface,
944 ivbsaxattributes_AddRef,
945 ivbsaxattributes_Release,
946 ivbsaxattributes_GetTypeInfoCount,
947 ivbsaxattributes_GetTypeInfo,
948 ivbsaxattributes_GetIDsOfNames,
949 ivbsaxattributes_Invoke,
950 ivbsaxattributes_get_length,
951 ivbsaxattributes_getURI,
952 ivbsaxattributes_getLocalName,
953 ivbsaxattributes_getQName,
954 ivbsaxattributes_getIndexFromName,
955 ivbsaxattributes_getIndexFromQName,
956 ivbsaxattributes_getType,
957 ivbsaxattributes_getTypeFromName,
958 ivbsaxattributes_getTypeFromQName,
959 ivbsaxattributes_getValue,
960 ivbsaxattributes_getValueFromName,
961 ivbsaxattributes_getValueFromQName
964 /*** ISAXAttributes interface ***/
965 /*** IUnknown methods ***/
966 static HRESULT WINAPI isaxattributes_QueryInterface(
967 ISAXAttributes* iface,
971 saxlocator *This = impl_from_ISAXAttributes(iface);
972 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
973 return ISAXLocator_QueryInterface(&This->ISAXLocator_iface, riid, ppvObject);
976 static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes* iface)
978 saxlocator *This = impl_from_ISAXAttributes(iface);
980 return ISAXLocator_AddRef(&This->ISAXLocator_iface);
983 static ULONG WINAPI isaxattributes_Release(ISAXAttributes* iface)
985 saxlocator *This = impl_from_ISAXAttributes(iface);
988 return ISAXLocator_Release(&This->ISAXLocator_iface);
991 /*** ISAXAttributes methods ***/
992 static HRESULT WINAPI isaxattributes_getLength(
993 ISAXAttributes* iface,
996 saxlocator *This = impl_from_ISAXAttributes( iface );
998 *length = This->nb_attributes;
999 TRACE("Length set to %d\n", *length);
1003 static HRESULT WINAPI isaxattributes_getURI(
1004 ISAXAttributes* iface,
1009 saxlocator *This = impl_from_ISAXAttributes( iface );
1010 TRACE("(%p)->(%d)\n", This, index);
1012 if(index >= This->nb_attributes || index < 0) return E_INVALIDARG;
1013 if(!url || !size) return E_POINTER;
1015 *size = SysStringLen(This->attributes[index].szURI);
1016 *url = This->attributes[index].szURI;
1018 TRACE("(%s:%d)\n", debugstr_w(This->attributes[index].szURI), *size);
1023 static HRESULT WINAPI isaxattributes_getLocalName(
1024 ISAXAttributes* iface,
1026 const WCHAR **pLocalName,
1027 int *pLocalNameLength)
1029 saxlocator *This = impl_from_ISAXAttributes( iface );
1030 TRACE("(%p)->(%d)\n", This, nIndex);
1032 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
1033 if(!pLocalName || !pLocalNameLength) return E_POINTER;
1035 *pLocalNameLength = SysStringLen(This->attributes[nIndex].szLocalname);
1036 *pLocalName = This->attributes[nIndex].szLocalname;
1041 static HRESULT WINAPI isaxattributes_getQName(
1042 ISAXAttributes* iface,
1044 const WCHAR **pQName,
1047 saxlocator *This = impl_from_ISAXAttributes( iface );
1048 TRACE("(%p)->(%d)\n", This, nIndex);
1050 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
1051 if(!pQName || !pQNameLength) return E_POINTER;
1053 *pQNameLength = SysStringLen(This->attributes[nIndex].szQName);
1054 *pQName = This->attributes[nIndex].szQName;
1059 static HRESULT WINAPI isaxattributes_getName(
1060 ISAXAttributes* iface,
1064 const WCHAR **localName,
1065 int *pLocalNameSize,
1066 const WCHAR **QName,
1069 saxlocator *This = impl_from_ISAXAttributes( iface );
1070 TRACE("(%p)->(%d)\n", This, index);
1072 if(index>=This->nb_attributes || index<0) return E_INVALIDARG;
1073 if(!uri || !pUriLength || !localName || !pLocalNameSize
1074 || !QName || !pQNameLength) return E_POINTER;
1076 *pUriLength = SysStringLen(This->attributes[index].szURI);
1077 *uri = This->attributes[index].szURI;
1078 *pLocalNameSize = SysStringLen(This->attributes[index].szLocalname);
1079 *localName = This->attributes[index].szLocalname;
1080 *pQNameLength = SysStringLen(This->attributes[index].szQName);
1081 *QName = This->attributes[index].szQName;
1083 TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*localName), debugstr_w(*QName));
1088 static HRESULT WINAPI isaxattributes_getIndexFromName(
1089 ISAXAttributes* iface,
1092 const WCHAR *pLocalName,
1093 int cocalNameLength,
1096 saxlocator *This = impl_from_ISAXAttributes( iface );
1098 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), cUriLength,
1099 debugstr_w(pLocalName), cocalNameLength);
1101 if(!pUri || !pLocalName || !index) return E_POINTER;
1103 for(i=0; i<This->nb_attributes; i++)
1105 if(cUriLength!=SysStringLen(This->attributes[i].szURI)
1106 || cocalNameLength!=SysStringLen(This->attributes[i].szLocalname))
1108 if(cUriLength && memcmp(pUri, This->attributes[i].szURI,
1109 sizeof(WCHAR)*cUriLength))
1111 if(cocalNameLength && memcmp(pLocalName, This->attributes[i].szLocalname,
1112 sizeof(WCHAR)*cocalNameLength))
1119 return E_INVALIDARG;
1122 static HRESULT WINAPI isaxattributes_getIndexFromQName(
1123 ISAXAttributes* iface,
1124 const WCHAR *pQName,
1128 saxlocator *This = impl_from_ISAXAttributes( iface );
1130 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQNameLength);
1132 if(!pQName || !index) return E_POINTER;
1133 if(!nQNameLength) return E_INVALIDARG;
1135 for(i=0; i<This->nb_attributes; i++)
1137 if(nQNameLength!=SysStringLen(This->attributes[i].szQName)) continue;
1138 if(memcmp(pQName, This->attributes[i].szQName, sizeof(WCHAR)*nQNameLength)) continue;
1144 return E_INVALIDARG;
1147 static HRESULT WINAPI isaxattributes_getType(
1148 ISAXAttributes* iface,
1150 const WCHAR **pType,
1153 saxlocator *This = impl_from_ISAXAttributes( iface );
1155 FIXME("(%p)->(%d) stub\n", This, nIndex);
1159 static HRESULT WINAPI isaxattributes_getTypeFromName(
1160 ISAXAttributes* iface,
1163 const WCHAR *pLocalName,
1165 const WCHAR **pType,
1168 saxlocator *This = impl_from_ISAXAttributes( iface );
1170 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This, debugstr_w(pUri), nUri,
1171 debugstr_w(pLocalName), nLocalName);
1175 static HRESULT WINAPI isaxattributes_getTypeFromQName(
1176 ISAXAttributes* iface,
1177 const WCHAR *pQName,
1179 const WCHAR **pType,
1182 saxlocator *This = impl_from_ISAXAttributes( iface );
1184 FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(pQName), nQName);
1188 static HRESULT WINAPI isaxattributes_getValue(
1189 ISAXAttributes* iface,
1191 const WCHAR **value,
1194 saxlocator *This = impl_from_ISAXAttributes( iface );
1195 TRACE("(%p)->(%d)\n", This, index);
1197 if(index>=This->nb_attributes || index<0) return E_INVALIDARG;
1198 if(!value || !nValue) return E_POINTER;
1200 *nValue = SysStringLen(This->attributes[index].szValue);
1201 *value = This->attributes[index].szValue;
1203 TRACE("(%s:%d)\n", debugstr_w(*value), *nValue);
1208 static HRESULT WINAPI isaxattributes_getValueFromName(
1209 ISAXAttributes* iface,
1212 const WCHAR *pLocalName,
1214 const WCHAR **pValue,
1219 saxlocator *This = impl_from_ISAXAttributes( iface );
1220 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), nUri,
1221 debugstr_w(pLocalName), nLocalName);
1223 hr = ISAXAttributes_getIndexFromName(iface,
1224 pUri, nUri, pLocalName, nLocalName, &index);
1225 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
1230 static HRESULT WINAPI isaxattributes_getValueFromQName(
1231 ISAXAttributes* iface,
1232 const WCHAR *pQName,
1234 const WCHAR **pValue,
1239 saxlocator *This = impl_from_ISAXAttributes( iface );
1240 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQName);
1242 hr = ISAXAttributes_getIndexFromQName(iface, pQName, nQName, &index);
1243 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
1248 static const struct ISAXAttributesVtbl isaxattributes_vtbl =
1250 isaxattributes_QueryInterface,
1251 isaxattributes_AddRef,
1252 isaxattributes_Release,
1253 isaxattributes_getLength,
1254 isaxattributes_getURI,
1255 isaxattributes_getLocalName,
1256 isaxattributes_getQName,
1257 isaxattributes_getName,
1258 isaxattributes_getIndexFromName,
1259 isaxattributes_getIndexFromQName,
1260 isaxattributes_getType,
1261 isaxattributes_getTypeFromName,
1262 isaxattributes_getTypeFromQName,
1263 isaxattributes_getValue,
1264 isaxattributes_getValueFromName,
1265 isaxattributes_getValueFromQName
1268 static HRESULT SAXAttributes_populate(saxlocator *locator,
1269 int nb_namespaces, const xmlChar **xmlNamespaces,
1270 int nb_attributes, const xmlChar **xmlAttributes)
1272 static const xmlChar xmlns[] = "xmlns";
1273 static const WCHAR xmlnsW[] = { 'x','m','l','n','s',0 };
1275 struct _attributes *attrs;
1278 /* skip namespace definitions */
1279 if ((locator->saxreader->features & NamespacePrefixes) == 0)
1282 locator->nb_attributes = nb_namespaces + nb_attributes;
1283 if(locator->nb_attributes > locator->attributesSize)
1285 attrs = heap_realloc(locator->attributes, sizeof(struct _attributes)*locator->nb_attributes*2);
1288 locator->nb_attributes = 0;
1289 return E_OUTOFMEMORY;
1291 locator->attributes = attrs;
1295 attrs = locator->attributes;
1298 for (i = 0; i < nb_namespaces; i++)
1300 attrs[nb_attributes+i].szLocalname = SysAllocStringLen(NULL, 0);
1301 attrs[nb_attributes+i].szURI = locator->namespaceUri;
1302 attrs[nb_attributes+i].szValue = bstr_from_xmlChar(xmlNamespaces[2*i+1]);
1303 if(!xmlNamespaces[2*i])
1304 attrs[nb_attributes+i].szQName = SysAllocString(xmlnsW);
1306 attrs[nb_attributes+i].szQName = QName_from_xmlChar(xmlns, xmlNamespaces[2*i]);
1309 for (i = 0; i < nb_attributes; i++)
1311 static const xmlChar xmlA[] = "xml";
1313 if (xmlStrEqual(xmlAttributes[i*5+1], xmlA))
1314 attrs[i].szURI = bstr_from_xmlChar(xmlAttributes[i*5+2]);
1316 /* that's an important feature to keep same uri pointer for every reported attribute */
1317 attrs[i].szURI = find_element_uri(locator, xmlAttributes[i*5+2]);
1319 attrs[i].szLocalname = bstr_from_xmlChar(xmlAttributes[i*5]);
1320 attrs[i].szValue = bstr_from_xmlCharN(xmlAttributes[i*5+3],
1321 xmlAttributes[i*5+4]-xmlAttributes[i*5+3]);
1322 attrs[i].szQName = QName_from_xmlChar(xmlAttributes[i*5+1],
1323 xmlAttributes[i*5]);
1329 /*** LibXML callbacks ***/
1330 static void libxmlStartDocument(void *ctx)
1332 saxlocator *This = ctx;
1333 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1336 if (This->saxreader->version >= MSXML4)
1338 const xmlChar *p = This->pParserCtxt->input->cur-1;
1339 update_position(This, FALSE);
1340 while(p>This->pParserCtxt->input->base && *p!='>')
1342 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1347 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1351 /* store version value, declaration has to contain version attribute */
1352 if (This->pParserCtxt->standalone != -1)
1354 SysFreeString(This->saxreader->xmldecl_version);
1355 This->saxreader->xmldecl_version = bstr_from_xmlChar(This->pParserCtxt->version);
1358 if (saxreader_has_handler(This, SAXContentHandler))
1360 if(This->vbInterface)
1361 hr = IVBSAXContentHandler_startDocument(handler->vbhandler);
1363 hr = ISAXContentHandler_startDocument(handler->handler);
1365 if (sax_callback_failed(This, hr))
1366 format_error_message_from_id(This, hr);
1370 static void libxmlEndDocument(void *ctx)
1372 saxlocator *This = ctx;
1373 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1376 if (This->saxreader->version >= MSXML4) {
1377 update_position(This, FALSE);
1378 if(This->column > 1)
1386 if(This->ret != S_OK) return;
1388 if (saxreader_has_handler(This, SAXContentHandler))
1390 if(This->vbInterface)
1391 hr = IVBSAXContentHandler_endDocument(handler->vbhandler);
1393 hr = ISAXContentHandler_endDocument(handler->handler);
1395 if (sax_callback_failed(This, hr))
1396 format_error_message_from_id(This, hr);
1400 static void libxmlStartElementNS(
1402 const xmlChar *localname,
1403 const xmlChar *prefix,
1406 const xmlChar **namespaces,
1409 const xmlChar **attributes)
1411 saxlocator *This = ctx;
1412 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1413 element_entry *element;
1417 update_position(This, TRUE);
1418 if(*(This->pParserCtxt->input->cur) == '/')
1420 if(This->saxreader->version < MSXML4)
1423 element = alloc_element_entry(localname, prefix, nb_namespaces, namespaces);
1424 push_element_ns(This, element);
1426 if (is_namespaces_enabled(This->saxreader))
1430 for (i = 0; i < nb_namespaces && saxreader_has_handler(This, SAXContentHandler); i++)
1432 if (This->vbInterface)
1433 hr = IVBSAXContentHandler_startPrefixMapping(
1435 &element->ns[i].prefix,
1436 &element->ns[i].uri);
1438 hr = ISAXContentHandler_startPrefixMapping(
1440 element->ns[i].prefix,
1441 SysStringLen(element->ns[i].prefix),
1443 SysStringLen(element->ns[i].uri));
1445 if (sax_callback_failed(This, hr))
1447 format_error_message_from_id(This, hr);
1453 uri = find_element_uri(This, URI);
1454 hr = SAXAttributes_populate(This, nb_namespaces, namespaces, nb_attributes, attributes);
1455 if (hr == S_OK && saxreader_has_handler(This, SAXContentHandler))
1459 if (is_namespaces_enabled(This->saxreader))
1460 local = element->local;
1464 if (This->vbInterface)
1465 hr = IVBSAXContentHandler_startElement(handler->vbhandler,
1466 &uri, &local, &element->qname, &This->IVBSAXAttributes_iface);
1468 hr = ISAXContentHandler_startElement(handler->handler,
1469 uri, SysStringLen(uri),
1470 local, SysStringLen(local),
1471 element->qname, SysStringLen(element->qname),
1472 &This->ISAXAttributes_iface);
1474 if (sax_callback_failed(This, hr))
1475 format_error_message_from_id(This, hr);
1479 static void libxmlEndElementNS(
1481 const xmlChar *localname,
1482 const xmlChar *prefix,
1485 saxlocator *This = ctx;
1486 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1487 element_entry *element;
1492 update_position(This, FALSE);
1493 p = This->pParserCtxt->input->cur;
1495 if (This->saxreader->version >= MSXML4)
1498 while(p>This->pParserCtxt->input->base && *p!='>')
1500 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1505 else if(*(p-1)!='>' || *(p-2)!='/')
1508 while(p-2>=This->pParserCtxt->input->base
1509 && *(p-2)!='<' && *(p-1)!='/')
1511 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1517 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1520 uri = find_element_uri(This, URI);
1521 element = pop_element_ns(This);
1523 if (!saxreader_has_handler(This, SAXContentHandler))
1525 This->nb_attributes = 0;
1526 free_element_entry(element);
1530 if (is_namespaces_enabled(This->saxreader))
1531 local = element->local;
1535 if (This->vbInterface)
1536 hr = IVBSAXContentHandler_endElement(
1538 &uri, &local, &element->qname);
1540 hr = ISAXContentHandler_endElement(
1542 uri, SysStringLen(uri),
1543 local, SysStringLen(local),
1544 element->qname, SysStringLen(element->qname));
1546 This->nb_attributes = 0;
1548 if (sax_callback_failed(This, hr))
1550 format_error_message_from_id(This, hr);
1551 free_element_entry(element);
1555 if (is_namespaces_enabled(This->saxreader))
1558 while (iterate_endprefix_index(This, element, &i) && saxreader_has_handler(This, SAXContentHandler))
1560 if (This->vbInterface)
1561 hr = IVBSAXContentHandler_endPrefixMapping(
1562 handler->vbhandler, &element->ns[i].prefix);
1564 hr = ISAXContentHandler_endPrefixMapping(
1565 handler->handler, element->ns[i].prefix, SysStringLen(element->ns[i].prefix));
1567 if (sax_callback_failed(This, hr)) break;
1570 if (sax_callback_failed(This, hr))
1571 format_error_message_from_id(This, hr);
1574 free_element_entry(element);
1577 static void libxmlCharacters(
1582 saxlocator *This = ctx;
1586 BOOL lastEvent = FALSE;
1588 if (!saxreader_has_handler(This, SAXContentHandler)) return;
1590 update_position(This, FALSE);
1591 cur = (xmlChar*)This->pParserCtxt->input->cur;
1592 while(cur>=This->pParserCtxt->input->base && *cur!='>')
1594 if(*cur=='\n' || (*cur=='\r' && *(cur+1)!='\n'))
1599 for(; cur>=This->pParserCtxt->input->base && *cur!='\n' && *cur!='\r'; cur--)
1603 if(*(ch-1)=='\r') cur--;
1608 while(end-ch<len && *end!='\r') end++;
1619 if (This->saxreader->version >= MSXML4)
1623 for(p=cur; p!=end; p++)
1640 Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur);
1641 hr = saxreader_saxcharacters(This, Chars);
1643 if (sax_callback_failed(This, hr))
1645 format_error_message_from_id(This, hr);
1649 if (This->saxreader->version < MSXML4)
1650 This->column += end-cur;
1663 if(end-ch == len) break;
1667 static void libxmlSetDocumentLocator(
1669 xmlSAXLocatorPtr loc)
1671 saxlocator *This = ctx;
1672 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1675 if (saxreader_has_handler(This, SAXContentHandler))
1677 if(This->vbInterface)
1678 hr = IVBSAXContentHandler_putref_documentLocator(handler->vbhandler,
1679 &This->IVBSAXLocator_iface);
1681 hr = ISAXContentHandler_putDocumentLocator(handler->handler, &This->ISAXLocator_iface);
1685 format_error_message_from_id(This, hr);
1688 static void libxmlComment(void *ctx, const xmlChar *value)
1690 saxlocator *This = ctx;
1691 struct saxlexicalhandler_iface *handler = saxreader_get_lexicalhandler(This->saxreader);
1694 const xmlChar *p = This->pParserCtxt->input->cur;
1696 update_position(This, FALSE);
1697 while(p-4>=This->pParserCtxt->input->base
1698 && memcmp(p-4, "<!--", sizeof(char[4])))
1700 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1706 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1709 if (!saxreader_has_handler(This, SAXLexicalHandler)) return;
1711 bValue = pooled_bstr_from_xmlChar(&This->saxreader->pool, value);
1713 if (This->vbInterface)
1714 hr = IVBSAXLexicalHandler_comment(handler->vbhandler, &bValue);
1716 hr = ISAXLexicalHandler_comment(handler->handler, bValue, SysStringLen(bValue));
1719 format_error_message_from_id(This, hr);
1722 static void libxmlFatalError(void *ctx, const char *msg, ...)
1724 saxlocator *This = ctx;
1725 struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader);
1731 if(This->ret != S_OK) {
1732 xmlStopParser(This->pParserCtxt);
1736 va_start(args, msg);
1737 vsprintf(message, msg, args);
1740 len = MultiByteToWideChar(CP_UNIXCP, 0, message, -1, NULL, 0);
1741 error = heap_alloc(sizeof(WCHAR)*len);
1744 MultiByteToWideChar(CP_UNIXCP, 0, message, -1, error, len);
1745 TRACE("fatal error for %p: %s\n", This, debugstr_w(error));
1748 if (!saxreader_has_handler(This, SAXErrorHandler))
1750 xmlStopParser(This->pParserCtxt);
1756 FIXME("Error handling is not compatible.\n");
1758 if(This->vbInterface)
1760 BSTR bstrError = SysAllocString(error);
1761 IVBSAXErrorHandler_fatalError(handler->vbhandler, &This->IVBSAXLocator_iface,
1762 &bstrError, E_FAIL);
1763 SysFreeString(bstrError);
1766 ISAXErrorHandler_fatalError(handler->handler, &This->ISAXLocator_iface, error, E_FAIL);
1770 xmlStopParser(This->pParserCtxt);
1774 /* The only reason this helper exists is that CDATA section are reported by chunks,
1775 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1777 This helper should be called for substring with trailing newlines.
1779 static BSTR saxreader_get_cdata_chunk(const xmlChar *str, int len)
1781 BSTR bstr = bstr_from_xmlCharN(str, len), ret;
1784 ptr = bstr + len - 1;
1785 while ((*ptr == '\r' || *ptr == '\n') && ptr >= bstr)
1790 /* replace returns as:
1792 - "\r<char>" -> "\n<char>"
1798 if (*(ptr+1) == '\r' || *(ptr+1) == '\n')
1801 memmove(ptr, ptr+1, len-- - (ptr-bstr));
1808 ret = SysAllocStringLen(bstr, len);
1809 SysFreeString(bstr);
1813 static void libxml_cdatablock(void *ctx, const xmlChar *value, int len)
1815 const xmlChar *start, *end;
1816 saxlocator *locator = ctx;
1817 struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(locator->saxreader);
1822 update_position(locator, FALSE);
1823 if (saxreader_has_handler(locator, SAXLexicalHandler))
1825 if (locator->vbInterface)
1826 hr = IVBSAXLexicalHandler_startCDATA(lexical->vbhandler);
1828 hr = ISAXLexicalHandler_startCDATA(lexical->handler);
1833 format_error_message_from_id(locator, hr);
1843 /* scan for newlines */
1844 if (value[i] == '\r' || value[i] == '\n')
1846 /* skip newlines/linefeeds */
1849 if (value[i] != '\r' && value[i] != '\n') break;
1855 chars = saxreader_get_cdata_chunk(start, end-start);
1856 TRACE("(chunk %s)\n", debugstr_w(chars));
1857 hr = saxreader_saxcharacters(locator, chars);
1858 SysFreeString(chars);
1867 /* no newline chars (or last chunk) report as a whole */
1868 if (!end && start == value)
1871 chars = bstr_from_xmlCharN(start, len-(start-value));
1872 TRACE("(%s)\n", debugstr_w(chars));
1873 hr = saxreader_saxcharacters(locator, chars);
1874 SysFreeString(chars);
1877 if (saxreader_has_handler(locator, SAXLexicalHandler))
1879 if (locator->vbInterface)
1880 hr = IVBSAXLexicalHandler_endCDATA(lexical->vbhandler);
1882 hr = ISAXLexicalHandler_endCDATA(lexical->handler);
1886 format_error_message_from_id(locator, hr);
1889 static xmlParserInputPtr libxmlresolveentity(void *ctx, const xmlChar *publicid, const xmlChar *systemid)
1891 FIXME("entity resolving not implemented, %s, %s\n", publicid, systemid);
1892 return xmlSAX2ResolveEntity(ctx, publicid, systemid);
1895 /*** IVBSAXLocator interface ***/
1896 /*** IUnknown methods ***/
1897 static HRESULT WINAPI ivbsaxlocator_QueryInterface(IVBSAXLocator* iface, REFIID riid, void **ppvObject)
1899 saxlocator *This = impl_from_IVBSAXLocator( iface );
1901 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject);
1905 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
1906 IsEqualGUID( riid, &IID_IDispatch) ||
1907 IsEqualGUID( riid, &IID_IVBSAXLocator ))
1911 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
1913 *ppvObject = &This->IVBSAXAttributes_iface;
1917 FIXME("interface %s not implemented\n", debugstr_guid(riid));
1918 return E_NOINTERFACE;
1921 IVBSAXLocator_AddRef( iface );
1926 static ULONG WINAPI ivbsaxlocator_AddRef(IVBSAXLocator* iface)
1928 saxlocator *This = impl_from_IVBSAXLocator( iface );
1929 TRACE("%p\n", This );
1930 return InterlockedIncrement( &This->ref );
1933 static ULONG WINAPI ivbsaxlocator_Release(
1934 IVBSAXLocator* iface)
1936 saxlocator *This = impl_from_IVBSAXLocator( iface );
1937 return ISAXLocator_Release((ISAXLocator*)&This->IVBSAXLocator_iface);
1940 /*** IDispatch methods ***/
1941 static HRESULT WINAPI ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator *iface, UINT* pctinfo )
1943 saxlocator *This = impl_from_IVBSAXLocator( iface );
1945 TRACE("(%p)->(%p)\n", This, pctinfo);
1952 static HRESULT WINAPI ivbsaxlocator_GetTypeInfo(
1953 IVBSAXLocator *iface,
1954 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
1956 saxlocator *This = impl_from_IVBSAXLocator( iface );
1959 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1961 hr = get_typeinfo(IVBSAXLocator_tid, ppTInfo);
1966 static HRESULT WINAPI ivbsaxlocator_GetIDsOfNames(
1967 IVBSAXLocator *iface,
1969 LPOLESTR* rgszNames,
1974 saxlocator *This = impl_from_IVBSAXLocator( iface );
1975 ITypeInfo *typeinfo;
1978 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1981 if(!rgszNames || cNames == 0 || !rgDispId)
1982 return E_INVALIDARG;
1984 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo);
1987 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1988 ITypeInfo_Release(typeinfo);
1994 static HRESULT WINAPI ivbsaxlocator_Invoke(
1995 IVBSAXLocator *iface,
1996 DISPID dispIdMember,
2000 DISPPARAMS* pDispParams,
2001 VARIANT* pVarResult,
2002 EXCEPINFO* pExcepInfo,
2005 saxlocator *This = impl_from_IVBSAXLocator( iface );
2006 ITypeInfo *typeinfo;
2009 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2010 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2012 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo);
2015 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXLocator_iface, dispIdMember, wFlags,
2016 pDispParams, pVarResult, pExcepInfo, puArgErr);
2017 ITypeInfo_Release(typeinfo);
2023 /*** IVBSAXLocator methods ***/
2024 static HRESULT WINAPI ivbsaxlocator_get_columnNumber(
2025 IVBSAXLocator* iface,
2028 saxlocator *This = impl_from_IVBSAXLocator( iface );
2029 return ISAXLocator_getColumnNumber((ISAXLocator*)&This->IVBSAXLocator_iface, pnColumn);
2032 static HRESULT WINAPI ivbsaxlocator_get_lineNumber(
2033 IVBSAXLocator* iface,
2036 saxlocator *This = impl_from_IVBSAXLocator( iface );
2037 return ISAXLocator_getLineNumber((ISAXLocator*)&This->IVBSAXLocator_iface, pnLine);
2040 static HRESULT WINAPI ivbsaxlocator_get_publicId(
2041 IVBSAXLocator* iface,
2044 saxlocator *This = impl_from_IVBSAXLocator( iface );
2045 return ISAXLocator_getPublicId((ISAXLocator*)&This->IVBSAXLocator_iface,
2046 (const WCHAR**)publicId);
2049 static HRESULT WINAPI ivbsaxlocator_get_systemId(
2050 IVBSAXLocator* iface,
2053 saxlocator *This = impl_from_IVBSAXLocator( iface );
2054 return ISAXLocator_getSystemId((ISAXLocator*)&This->IVBSAXLocator_iface,
2055 (const WCHAR**)systemId);
2058 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl =
2060 ivbsaxlocator_QueryInterface,
2061 ivbsaxlocator_AddRef,
2062 ivbsaxlocator_Release,
2063 ivbsaxlocator_GetTypeInfoCount,
2064 ivbsaxlocator_GetTypeInfo,
2065 ivbsaxlocator_GetIDsOfNames,
2066 ivbsaxlocator_Invoke,
2067 ivbsaxlocator_get_columnNumber,
2068 ivbsaxlocator_get_lineNumber,
2069 ivbsaxlocator_get_publicId,
2070 ivbsaxlocator_get_systemId
2073 /*** ISAXLocator interface ***/
2074 /*** IUnknown methods ***/
2075 static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject)
2077 saxlocator *This = impl_from_ISAXLocator( iface );
2079 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
2083 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2084 IsEqualGUID( riid, &IID_ISAXLocator ))
2088 else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
2090 *ppvObject = &This->ISAXAttributes_iface;
2094 WARN("interface %s not implemented\n", debugstr_guid(riid));
2095 return E_NOINTERFACE;
2098 ISAXLocator_AddRef( iface );
2103 static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface)
2105 saxlocator *This = impl_from_ISAXLocator( iface );
2106 ULONG ref = InterlockedIncrement( &This->ref );
2107 TRACE("(%p)->(%d)\n", This, ref);
2111 static ULONG WINAPI isaxlocator_Release(
2114 saxlocator *This = impl_from_ISAXLocator( iface );
2115 LONG ref = InterlockedDecrement( &This->ref );
2117 TRACE("(%p)->(%d)\n", This, ref );
2121 element_entry *element, *element2;
2124 SysFreeString(This->publicId);
2125 SysFreeString(This->systemId);
2126 SysFreeString(This->namespaceUri);
2128 for(index=0; index<This->nb_attributes; index++)
2130 SysFreeString(This->attributes[index].szLocalname);
2131 SysFreeString(This->attributes[index].szValue);
2132 SysFreeString(This->attributes[index].szQName);
2134 heap_free(This->attributes);
2137 LIST_FOR_EACH_ENTRY_SAFE(element, element2, &This->elements, element_entry, entry)
2139 list_remove(&element->entry);
2140 free_element_entry(element);
2143 ISAXXMLReader_Release(&This->saxreader->ISAXXMLReader_iface);
2150 /*** ISAXLocator methods ***/
2151 static HRESULT WINAPI isaxlocator_getColumnNumber(
2155 saxlocator *This = impl_from_ISAXLocator( iface );
2157 *pnColumn = This->column;
2161 static HRESULT WINAPI isaxlocator_getLineNumber(
2165 saxlocator *This = impl_from_ISAXLocator( iface );
2167 *pnLine = This->line;
2171 static HRESULT WINAPI isaxlocator_getPublicId(
2173 const WCHAR ** ppwchPublicId)
2176 saxlocator *This = impl_from_ISAXLocator( iface );
2178 SysFreeString(This->publicId);
2180 publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt));
2181 if(SysStringLen(publicId))
2182 This->publicId = publicId;
2185 SysFreeString(publicId);
2186 This->publicId = NULL;
2189 *ppwchPublicId = This->publicId;
2193 static HRESULT WINAPI isaxlocator_getSystemId(
2195 const WCHAR ** ppwchSystemId)
2198 saxlocator *This = impl_from_ISAXLocator( iface );
2200 SysFreeString(This->systemId);
2202 systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt));
2203 if(SysStringLen(systemId))
2204 This->systemId = systemId;
2207 SysFreeString(systemId);
2208 This->systemId = NULL;
2211 *ppwchSystemId = This->systemId;
2215 static const struct ISAXLocatorVtbl SAXLocatorVtbl =
2217 isaxlocator_QueryInterface,
2219 isaxlocator_Release,
2220 isaxlocator_getColumnNumber,
2221 isaxlocator_getLineNumber,
2222 isaxlocator_getPublicId,
2223 isaxlocator_getSystemId
2226 static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator, BOOL vbInterface)
2228 static const WCHAR w3xmlns[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2229 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2231 saxlocator *locator;
2233 locator = heap_alloc( sizeof (*locator) );
2235 return E_OUTOFMEMORY;
2237 locator->IVBSAXLocator_iface.lpVtbl = &VBSAXLocatorVtbl;
2238 locator->ISAXLocator_iface.lpVtbl = &SAXLocatorVtbl;
2239 locator->IVBSAXAttributes_iface.lpVtbl = &ivbsaxattributes_vtbl;
2240 locator->ISAXAttributes_iface.lpVtbl = &isaxattributes_vtbl;
2242 locator->vbInterface = vbInterface;
2244 locator->saxreader = reader;
2245 ISAXXMLReader_AddRef(&reader->ISAXXMLReader_iface);
2247 locator->pParserCtxt = NULL;
2248 locator->publicId = NULL;
2249 locator->systemId = NULL;
2250 locator->line = reader->version < MSXML4 ? 0 : 1;
2251 locator->column = 0;
2252 locator->ret = S_OK;
2253 if (locator->saxreader->version >= MSXML6)
2254 locator->namespaceUri = SysAllocString(w3xmlns);
2256 locator->namespaceUri = SysAllocStringLen(NULL, 0);
2257 if(!locator->namespaceUri)
2259 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2261 return E_OUTOFMEMORY;
2264 locator->attributesSize = 8;
2265 locator->nb_attributes = 0;
2266 locator->attributes = heap_alloc(sizeof(struct _attributes)*locator->attributesSize);
2267 if(!locator->attributes)
2269 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2270 SysFreeString(locator->namespaceUri);
2272 return E_OUTOFMEMORY;
2275 list_init(&locator->elements);
2277 *ppsaxlocator = locator;
2279 TRACE("returning %p\n", *ppsaxlocator);
2284 /*** SAXXMLReader internal functions ***/
2285 static HRESULT internal_parseBuffer(saxreader *This, const char *buffer, int size, BOOL vbInterface)
2287 xmlCharEncoding encoding = XML_CHAR_ENCODING_NONE;
2288 xmlChar *enc_name = NULL;
2289 saxlocator *locator;
2292 TRACE("(%p)->(%p %d)\n", This, buffer, size);
2294 hr = SAXLocator_create(This, &locator, vbInterface);
2300 const unsigned char *buff = (unsigned char*)buffer;
2302 encoding = xmlDetectCharEncoding((xmlChar*)buffer, 4);
2303 enc_name = (xmlChar*)xmlGetCharEncodingName(encoding);
2304 TRACE("detected encoding: %s\n", enc_name);
2305 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2306 if ((encoding == XML_CHAR_ENCODING_UTF8) &&
2307 buff[0] == 0xEF && buff[1] == 0xBB && buff[2] == 0xBF)
2314 /* if libxml2 detection failed try to guess */
2315 if (encoding == XML_CHAR_ENCODING_NONE)
2317 const WCHAR *ptr = (WCHAR*)buffer;
2318 /* xml declaration with possibly specfied encoding will be still handled by parser */
2319 if ((size >= 2) && *ptr == '<' && ptr[1] != '?')
2321 enc_name = (xmlChar*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE);
2322 encoding = XML_CHAR_ENCODING_UTF16LE;
2325 else if (encoding == XML_CHAR_ENCODING_UTF8)
2326 enc_name = (xmlChar*)xmlGetCharEncodingName(encoding);
2330 locator->pParserCtxt = xmlCreateMemoryParserCtxt(buffer, size);
2331 if (!locator->pParserCtxt)
2333 ISAXLocator_Release(&locator->ISAXLocator_iface);
2339 locator->pParserCtxt->encoding = xmlStrdup(enc_name);
2340 if (encoding == XML_CHAR_ENCODING_UTF16LE) {
2341 TRACE("switching to %s\n", enc_name);
2342 xmlSwitchEncoding(locator->pParserCtxt, encoding);
2346 xmlFree(locator->pParserCtxt->sax);
2347 locator->pParserCtxt->sax = &locator->saxreader->sax;
2348 locator->pParserCtxt->userData = locator;
2350 This->isParsing = TRUE;
2351 if(xmlParseDocument(locator->pParserCtxt) == -1 && locator->ret == S_OK)
2355 This->isParsing = FALSE;
2357 if(locator->pParserCtxt)
2359 locator->pParserCtxt->sax = NULL;
2360 xmlFreeParserCtxt(locator->pParserCtxt);
2361 locator->pParserCtxt = NULL;
2364 ISAXLocator_Release(&locator->ISAXLocator_iface);
2368 static HRESULT internal_parseStream(saxreader *This, ISequentialStream *stream, BOOL vbInterface)
2370 saxlocator *locator;
2377 hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead);
2378 if(FAILED(hr)) return hr;
2380 hr = SAXLocator_create(This, &locator, vbInterface);
2381 if(FAILED(hr)) return hr;
2383 locator->pParserCtxt = xmlCreatePushParserCtxt(
2384 &locator->saxreader->sax, locator,
2385 data, dataRead, NULL);
2386 if(!locator->pParserCtxt)
2388 ISAXLocator_Release(&locator->ISAXLocator_iface);
2392 This->isParsing = TRUE;
2394 if(dataRead != sizeof(data))
2396 ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
2397 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2404 hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead);
2405 if (FAILED(hr)) break;
2407 ret = xmlParseChunk(locator->pParserCtxt, data, dataRead, 0);
2408 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2410 if (hr != S_OK) break;
2412 if (dataRead != sizeof(data))
2414 ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
2415 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2421 This->isParsing = FALSE;
2423 xmlFreeParserCtxt(locator->pParserCtxt);
2424 locator->pParserCtxt = NULL;
2425 ISAXLocator_Release(&locator->ISAXLocator_iface);
2429 static HRESULT internal_parse(
2436 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varInput));
2438 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2439 free_bstr_pool(&This->pool);
2441 switch(V_VT(&varInput))
2444 hr = internal_parseBuffer(This, (const char*)V_BSTR(&varInput),
2445 strlenW(V_BSTR(&varInput))*sizeof(WCHAR), vbInterface);
2447 case VT_ARRAY|VT_UI1: {
2449 LONG lBound, uBound;
2452 hr = SafeArrayGetLBound(V_ARRAY(&varInput), 1, &lBound);
2453 if(hr != S_OK) break;
2454 hr = SafeArrayGetUBound(V_ARRAY(&varInput), 1, &uBound);
2455 if(hr != S_OK) break;
2456 dataRead = (uBound-lBound)*SafeArrayGetElemsize(V_ARRAY(&varInput));
2457 hr = SafeArrayAccessData(V_ARRAY(&varInput), &pSAData);
2458 if(hr != S_OK) break;
2459 hr = internal_parseBuffer(This, pSAData, dataRead, vbInterface);
2460 SafeArrayUnaccessData(V_ARRAY(&varInput));
2465 IPersistStream *persistStream;
2466 ISequentialStream *stream = NULL;
2467 IXMLDOMDocument *xmlDoc;
2469 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2470 &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK)
2474 IXMLDOMDocument_get_xml(xmlDoc, &bstrData);
2475 hr = internal_parseBuffer(This, (const char*)bstrData,
2476 SysStringByteLen(bstrData), vbInterface);
2477 IXMLDOMDocument_Release(xmlDoc);
2478 SysFreeString(bstrData);
2482 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2483 &IID_IPersistStream, (void**)&persistStream) == S_OK)
2485 IStream *stream_copy;
2487 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream_copy);
2490 IPersistStream_Release(persistStream);
2494 hr = IPersistStream_Save(persistStream, stream_copy, TRUE);
2495 IPersistStream_Release(persistStream);
2497 IStream_QueryInterface(stream_copy, &IID_ISequentialStream, (void**)&stream);
2499 IStream_Release(stream_copy);
2502 /* try base interface first */
2505 IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_ISequentialStream, (void**)&stream);
2507 /* this should never happen if IStream is implemented properly, but just in case */
2508 IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream);
2513 hr = internal_parseStream(This, stream, vbInterface);
2514 ISequentialStream_Release(stream);
2518 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2525 WARN("vt %d not implemented\n", V_VT(&varInput));
2532 static HRESULT internal_vbonDataAvailable(void *obj, char *ptr, DWORD len)
2534 saxreader *This = obj;
2536 return internal_parseBuffer(This, ptr, len, TRUE);
2539 static HRESULT internal_onDataAvailable(void *obj, char *ptr, DWORD len)
2541 saxreader *This = obj;
2543 return internal_parseBuffer(This, ptr, len, FALSE);
2546 static HRESULT internal_parseURL(
2555 TRACE("(%p)->(%s)\n", This, debugstr_w(url));
2557 hr = create_moniker_from_url(url, &mon);
2561 if(vbInterface) hr = bind_url(mon, internal_vbonDataAvailable, This, &bsc);
2562 else hr = bind_url(mon, internal_onDataAvailable, This, &bsc);
2563 IMoniker_Release(mon);
2568 return detach_bsc(bsc);
2571 static HRESULT internal_putProperty(
2577 TRACE("(%p)->(%s %s)\n", This, debugstr_w(prop), debugstr_variant(&value));
2579 if(!memcmp(prop, PropertyDeclHandlerW, sizeof(PropertyDeclHandlerW)))
2581 if(This->isParsing) return E_FAIL;
2583 switch (V_VT(&value))
2586 saxreader_put_handler(This, SAXDeclHandler, NULL, vbInterface);
2590 IUnknown *handler = NULL;
2592 if (V_UNKNOWN(&value))
2597 hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXDeclHandler, (void**)&handler);
2599 hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_ISAXDeclHandler, (void**)&handler);
2600 if (FAILED(hr)) return hr;
2603 saxreader_put_handler(This, SAXDeclHandler, handler, vbInterface);
2604 if (handler) IUnknown_Release(handler);
2608 return E_INVALIDARG;
2614 if(!memcmp(prop, PropertyLexicalHandlerW, sizeof(PropertyLexicalHandlerW)))
2616 if(This->isParsing) return E_FAIL;
2618 switch (V_VT(&value))
2621 saxreader_put_handler(This, SAXLexicalHandler, NULL, vbInterface);
2625 IUnknown *handler = NULL;
2627 if (V_UNKNOWN(&value))
2632 hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXLexicalHandler, (void**)&handler);
2634 hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_ISAXLexicalHandler, (void**)&handler);
2635 if (FAILED(hr)) return hr;
2638 saxreader_put_handler(This, SAXLexicalHandler, handler, vbInterface);
2639 if (handler) IUnknown_Release(handler);
2643 return E_INVALIDARG;
2649 if(!memcmp(prop, PropertyMaxXMLSizeW, sizeof(PropertyMaxXMLSizeW)))
2651 if (V_VT(&value) == VT_I4 && V_I4(&value) == 0) return S_OK;
2652 FIXME("(%p)->(%s): max-xml-size unsupported\n", This, debugstr_variant(&value));
2656 if(!memcmp(prop, PropertyMaxElementDepthW, sizeof(PropertyMaxElementDepthW)))
2658 if (V_VT(&value) == VT_I4 && V_I4(&value) == 0) return S_OK;
2659 FIXME("(%p)->(%s): max-element-depth unsupported\n", This, debugstr_variant(&value));
2663 FIXME("(%p)->(%s:%s): unsupported property\n", This, debugstr_w(prop), debugstr_variant(&value));
2665 if(!memcmp(prop, PropertyCharsetW, sizeof(PropertyCharsetW)))
2668 if(!memcmp(prop, PropertyDomNodeW, sizeof(PropertyDomNodeW)))
2671 if(!memcmp(prop, PropertyInputSourceW, sizeof(PropertyInputSourceW)))
2674 if(!memcmp(prop, PropertySchemaDeclHandlerW, sizeof(PropertySchemaDeclHandlerW)))
2677 if(!memcmp(prop, PropertyXMLDeclEncodingW, sizeof(PropertyXMLDeclEncodingW)))
2680 if(!memcmp(prop, PropertyXMLDeclStandaloneW, sizeof(PropertyXMLDeclStandaloneW)))
2683 if(!memcmp(prop, PropertyXMLDeclVersionW, sizeof(PropertyXMLDeclVersionW)))
2686 return E_INVALIDARG;
2689 static HRESULT internal_getProperty(const saxreader* This, const WCHAR *prop, VARIANT *value, BOOL vb)
2691 TRACE("(%p)->(%s)\n", This, debugstr_w(prop));
2693 if (!value) return E_POINTER;
2695 if (!memcmp(PropertyLexicalHandlerW, prop, sizeof(PropertyLexicalHandlerW)))
2697 V_VT(value) = VT_UNKNOWN;
2698 saxreader_get_handler(This, SAXLexicalHandler, vb, (void**)&V_UNKNOWN(value));
2702 if (!memcmp(PropertyDeclHandlerW, prop, sizeof(PropertyDeclHandlerW)))
2704 V_VT(value) = VT_UNKNOWN;
2705 saxreader_get_handler(This, SAXDeclHandler, vb, (void**)&V_UNKNOWN(value));
2709 if (!memcmp(PropertyXmlDeclVersionW, prop, sizeof(PropertyXmlDeclVersionW)))
2711 V_VT(value) = VT_BSTR;
2712 V_BSTR(value) = SysAllocString(This->xmldecl_version);
2716 FIXME("(%p)->(%s) unsupported property\n", This, debugstr_w(prop));
2721 /*** IVBSAXXMLReader interface ***/
2722 /*** IUnknown methods ***/
2723 static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject)
2725 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2727 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
2731 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2732 IsEqualGUID( riid, &IID_IDispatch ) ||
2733 IsEqualGUID( riid, &IID_IVBSAXXMLReader ))
2737 else if( IsEqualGUID( riid, &IID_ISAXXMLReader ))
2739 *ppvObject = &This->ISAXXMLReader_iface;
2741 else if (dispex_query_interface(&This->dispex, riid, ppvObject))
2743 return *ppvObject ? S_OK : E_NOINTERFACE;
2747 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2748 return E_NOINTERFACE;
2751 IVBSAXXMLReader_AddRef( iface );
2756 static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface)
2758 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2759 TRACE("%p\n", This );
2760 return InterlockedIncrement( &This->ref );
2763 static ULONG WINAPI saxxmlreader_Release(
2764 IVBSAXXMLReader* iface)
2766 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2769 TRACE("%p\n", This );
2771 ref = InterlockedDecrement( &This->ref );
2776 for (i = 0; i < SAXHandler_Last; i++)
2778 struct saxanyhandler_iface *iface = &This->saxhandlers[i].u.anyhandler;
2781 IUnknown_Release(iface->handler);
2783 if (iface->vbhandler)
2784 IUnknown_Release(iface->vbhandler);
2787 SysFreeString(This->xmldecl_version);
2788 free_bstr_pool(&This->pool);
2790 release_dispex(&This->dispex);
2797 static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo )
2799 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2800 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2803 static HRESULT WINAPI saxxmlreader_GetTypeInfo(
2804 IVBSAXXMLReader *iface,
2805 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
2807 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2808 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
2809 iTInfo, lcid, ppTInfo);
2812 static HRESULT WINAPI saxxmlreader_GetIDsOfNames(
2813 IVBSAXXMLReader *iface,
2815 LPOLESTR* rgszNames,
2820 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2821 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2822 riid, rgszNames, cNames, lcid, rgDispId);
2825 static HRESULT WINAPI saxxmlreader_Invoke(
2826 IVBSAXXMLReader *iface,
2827 DISPID dispIdMember,
2831 DISPPARAMS* pDispParams,
2832 VARIANT* pVarResult,
2833 EXCEPINFO* pExcepInfo,
2836 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2837 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
2838 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2841 /*** IVBSAXXMLReader methods ***/
2842 static HRESULT WINAPI saxxmlreader_getFeature(
2843 IVBSAXXMLReader* iface,
2844 const WCHAR *feature_name,
2845 VARIANT_BOOL *value)
2847 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2848 saxreader_feature feature;
2850 TRACE("(%p)->(%s %p)\n", This, debugstr_w(feature_name), value);
2852 feature = get_saxreader_feature(feature_name);
2853 if (feature == Namespaces || feature == NamespacePrefixes)
2854 return get_feature_value(This, feature, value);
2856 FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(feature_name), value);
2860 static HRESULT WINAPI saxxmlreader_putFeature(
2861 IVBSAXXMLReader* iface,
2862 const WCHAR *feature_name,
2865 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2866 saxreader_feature feature;
2868 TRACE("(%p)->(%s %x)\n", This, debugstr_w(feature_name), value);
2870 feature = get_saxreader_feature(feature_name);
2872 /* accepted cases */
2873 if ((feature == ExternalGeneralEntities && value == VARIANT_FALSE) ||
2874 (feature == ExternalParameterEntities && value == VARIANT_FALSE) ||
2875 feature == Namespaces ||
2876 feature == NamespacePrefixes)
2878 return set_feature_value(This, feature, value);
2881 if (feature == LexicalHandlerParEntities || feature == ProhibitDTD)
2883 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
2884 return set_feature_value(This, feature, value);
2887 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
2891 static HRESULT WINAPI saxxmlreader_getProperty(
2892 IVBSAXXMLReader* iface,
2896 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2897 return internal_getProperty(This, prop, value, TRUE);
2900 static HRESULT WINAPI saxxmlreader_putProperty(
2901 IVBSAXXMLReader* iface,
2905 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2906 return internal_putProperty(This, pProp, value, TRUE);
2909 static HRESULT WINAPI saxxmlreader_get_entityResolver(
2910 IVBSAXXMLReader* iface,
2911 IVBSAXEntityResolver **resolver)
2913 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2914 return saxreader_get_handler(This, SAXEntityResolver, TRUE, (void**)resolver);
2917 static HRESULT WINAPI saxxmlreader_put_entityResolver(
2918 IVBSAXXMLReader* iface,
2919 IVBSAXEntityResolver *resolver)
2921 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2922 return saxreader_put_handler(This, SAXEntityResolver, resolver, TRUE);
2925 static HRESULT WINAPI saxxmlreader_get_contentHandler(
2926 IVBSAXXMLReader* iface,
2927 IVBSAXContentHandler **handler)
2929 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2930 return saxreader_get_handler(This, SAXContentHandler, TRUE, (void**)handler);
2933 static HRESULT WINAPI saxxmlreader_put_contentHandler(
2934 IVBSAXXMLReader* iface,
2935 IVBSAXContentHandler *handler)
2937 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2938 return saxreader_put_handler(This, SAXContentHandler, handler, TRUE);
2941 static HRESULT WINAPI saxxmlreader_get_dtdHandler(
2942 IVBSAXXMLReader* iface,
2943 IVBSAXDTDHandler **handler)
2945 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2946 return saxreader_get_handler(This, SAXDTDHandler, TRUE, (void**)handler);
2949 static HRESULT WINAPI saxxmlreader_put_dtdHandler(
2950 IVBSAXXMLReader* iface,
2951 IVBSAXDTDHandler *handler)
2953 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2954 return saxreader_put_handler(This, SAXDTDHandler, handler, TRUE);
2957 static HRESULT WINAPI saxxmlreader_get_errorHandler(
2958 IVBSAXXMLReader* iface,
2959 IVBSAXErrorHandler **handler)
2961 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2962 return saxreader_get_handler(This, SAXErrorHandler, TRUE, (void**)handler);
2965 static HRESULT WINAPI saxxmlreader_put_errorHandler(
2966 IVBSAXXMLReader* iface,
2967 IVBSAXErrorHandler *handler)
2969 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2970 return saxreader_put_handler(This, SAXErrorHandler, handler, TRUE);
2973 static HRESULT WINAPI saxxmlreader_get_baseURL(
2974 IVBSAXXMLReader* iface,
2975 const WCHAR **pBaseUrl)
2977 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2979 FIXME("(%p)->(%p) stub\n", This, pBaseUrl);
2983 static HRESULT WINAPI saxxmlreader_put_baseURL(
2984 IVBSAXXMLReader* iface,
2985 const WCHAR *pBaseUrl)
2987 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2989 FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
2993 static HRESULT WINAPI saxxmlreader_get_secureBaseURL(
2994 IVBSAXXMLReader* iface,
2995 const WCHAR **pSecureBaseUrl)
2997 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2999 FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
3004 static HRESULT WINAPI saxxmlreader_put_secureBaseURL(
3005 IVBSAXXMLReader* iface,
3006 const WCHAR *secureBaseUrl)
3008 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3010 FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
3014 static HRESULT WINAPI saxxmlreader_parse(
3015 IVBSAXXMLReader* iface,
3018 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3019 return internal_parse(This, varInput, TRUE);
3022 static HRESULT WINAPI saxxmlreader_parseURL(
3023 IVBSAXXMLReader* iface,
3026 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3027 return internal_parseURL(This, url, TRUE);
3030 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl =
3032 saxxmlreader_QueryInterface,
3033 saxxmlreader_AddRef,
3034 saxxmlreader_Release,
3035 saxxmlreader_GetTypeInfoCount,
3036 saxxmlreader_GetTypeInfo,
3037 saxxmlreader_GetIDsOfNames,
3038 saxxmlreader_Invoke,
3039 saxxmlreader_getFeature,
3040 saxxmlreader_putFeature,
3041 saxxmlreader_getProperty,
3042 saxxmlreader_putProperty,
3043 saxxmlreader_get_entityResolver,
3044 saxxmlreader_put_entityResolver,
3045 saxxmlreader_get_contentHandler,
3046 saxxmlreader_put_contentHandler,
3047 saxxmlreader_get_dtdHandler,
3048 saxxmlreader_put_dtdHandler,
3049 saxxmlreader_get_errorHandler,
3050 saxxmlreader_put_errorHandler,
3051 saxxmlreader_get_baseURL,
3052 saxxmlreader_put_baseURL,
3053 saxxmlreader_get_secureBaseURL,
3054 saxxmlreader_put_secureBaseURL,
3056 saxxmlreader_parseURL
3059 /*** ISAXXMLReader interface ***/
3060 /*** IUnknown methods ***/
3061 static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject)
3063 saxreader *This = impl_from_ISAXXMLReader( iface );
3064 return saxxmlreader_QueryInterface(&This->IVBSAXXMLReader_iface, riid, ppvObject);
3067 static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface)
3069 saxreader *This = impl_from_ISAXXMLReader( iface );
3070 return saxxmlreader_AddRef(&This->IVBSAXXMLReader_iface);
3073 static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface)
3075 saxreader *This = impl_from_ISAXXMLReader( iface );
3076 return saxxmlreader_Release(&This->IVBSAXXMLReader_iface);
3079 /*** ISAXXMLReader methods ***/
3080 static HRESULT WINAPI isaxxmlreader_getFeature(
3081 ISAXXMLReader* iface,
3082 const WCHAR *pFeature,
3083 VARIANT_BOOL *pValue)
3085 saxreader *This = impl_from_ISAXXMLReader( iface );
3086 return IVBSAXXMLReader_getFeature(&This->IVBSAXXMLReader_iface, pFeature, pValue);
3089 static HRESULT WINAPI isaxxmlreader_putFeature(
3090 ISAXXMLReader* iface,
3091 const WCHAR *pFeature,
3092 VARIANT_BOOL vfValue)
3094 saxreader *This = impl_from_ISAXXMLReader( iface );
3095 return IVBSAXXMLReader_putFeature(&This->IVBSAXXMLReader_iface, pFeature, vfValue);
3098 static HRESULT WINAPI isaxxmlreader_getProperty(
3099 ISAXXMLReader* iface,
3103 saxreader *This = impl_from_ISAXXMLReader( iface );
3104 return internal_getProperty(This, prop, value, FALSE);
3107 static HRESULT WINAPI isaxxmlreader_putProperty(
3108 ISAXXMLReader* iface,
3112 saxreader *This = impl_from_ISAXXMLReader( iface );
3113 return internal_putProperty(This, pProp, value, FALSE);
3116 static HRESULT WINAPI isaxxmlreader_getEntityResolver(
3117 ISAXXMLReader* iface,
3118 ISAXEntityResolver **resolver)
3120 saxreader *This = impl_from_ISAXXMLReader( iface );
3121 return saxreader_get_handler(This, SAXEntityResolver, FALSE, (void**)resolver);
3124 static HRESULT WINAPI isaxxmlreader_putEntityResolver(
3125 ISAXXMLReader* iface,
3126 ISAXEntityResolver *resolver)
3128 saxreader *This = impl_from_ISAXXMLReader( iface );
3129 return saxreader_put_handler(This, SAXEntityResolver, resolver, FALSE);
3132 static HRESULT WINAPI isaxxmlreader_getContentHandler(
3133 ISAXXMLReader* iface,
3134 ISAXContentHandler **handler)
3136 saxreader *This = impl_from_ISAXXMLReader( iface );
3137 return saxreader_get_handler(This, SAXContentHandler, FALSE, (void**)handler);
3140 static HRESULT WINAPI isaxxmlreader_putContentHandler(
3141 ISAXXMLReader* iface,
3142 ISAXContentHandler *handler)
3144 saxreader *This = impl_from_ISAXXMLReader( iface );
3145 return saxreader_put_handler(This, SAXContentHandler, handler, FALSE);
3148 static HRESULT WINAPI isaxxmlreader_getDTDHandler(
3149 ISAXXMLReader* iface,
3150 ISAXDTDHandler **handler)
3152 saxreader *This = impl_from_ISAXXMLReader( iface );
3153 return saxreader_get_handler(This, SAXDTDHandler, FALSE, (void**)handler);
3156 static HRESULT WINAPI isaxxmlreader_putDTDHandler(
3157 ISAXXMLReader* iface,
3158 ISAXDTDHandler *handler)
3160 saxreader *This = impl_from_ISAXXMLReader( iface );
3161 return saxreader_put_handler(This, SAXDTDHandler, handler, FALSE);
3164 static HRESULT WINAPI isaxxmlreader_getErrorHandler(
3165 ISAXXMLReader* iface,
3166 ISAXErrorHandler **handler)
3168 saxreader *This = impl_from_ISAXXMLReader( iface );
3169 return saxreader_get_handler(This, SAXErrorHandler, FALSE, (void**)handler);
3172 static HRESULT WINAPI isaxxmlreader_putErrorHandler(ISAXXMLReader* iface, ISAXErrorHandler *handler)
3174 saxreader *This = impl_from_ISAXXMLReader( iface );
3175 return saxreader_put_handler(This, SAXErrorHandler, handler, FALSE);
3178 static HRESULT WINAPI isaxxmlreader_getBaseURL(
3179 ISAXXMLReader* iface,
3180 const WCHAR **pBaseUrl)
3182 saxreader *This = impl_from_ISAXXMLReader( iface );
3183 return IVBSAXXMLReader_get_baseURL(&This->IVBSAXXMLReader_iface, pBaseUrl);
3186 static HRESULT WINAPI isaxxmlreader_putBaseURL(
3187 ISAXXMLReader* iface,
3188 const WCHAR *pBaseUrl)
3190 saxreader *This = impl_from_ISAXXMLReader( iface );
3191 return IVBSAXXMLReader_put_baseURL(&This->IVBSAXXMLReader_iface, pBaseUrl);
3194 static HRESULT WINAPI isaxxmlreader_getSecureBaseURL(
3195 ISAXXMLReader* iface,
3196 const WCHAR **pSecureBaseUrl)
3198 saxreader *This = impl_from_ISAXXMLReader( iface );
3199 return IVBSAXXMLReader_get_secureBaseURL(&This->IVBSAXXMLReader_iface, pSecureBaseUrl);
3202 static HRESULT WINAPI isaxxmlreader_putSecureBaseURL(
3203 ISAXXMLReader* iface,
3204 const WCHAR *secureBaseUrl)
3206 saxreader *This = impl_from_ISAXXMLReader( iface );
3207 return IVBSAXXMLReader_put_secureBaseURL(&This->IVBSAXXMLReader_iface, secureBaseUrl);
3210 static HRESULT WINAPI isaxxmlreader_parse(
3211 ISAXXMLReader* iface,
3214 saxreader *This = impl_from_ISAXXMLReader( iface );
3215 return internal_parse(This, varInput, FALSE);
3218 static HRESULT WINAPI isaxxmlreader_parseURL(
3219 ISAXXMLReader* iface,
3222 saxreader *This = impl_from_ISAXXMLReader( iface );
3223 return internal_parseURL(This, url, FALSE);
3226 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl =
3228 isaxxmlreader_QueryInterface,
3229 isaxxmlreader_AddRef,
3230 isaxxmlreader_Release,
3231 isaxxmlreader_getFeature,
3232 isaxxmlreader_putFeature,
3233 isaxxmlreader_getProperty,
3234 isaxxmlreader_putProperty,
3235 isaxxmlreader_getEntityResolver,
3236 isaxxmlreader_putEntityResolver,
3237 isaxxmlreader_getContentHandler,
3238 isaxxmlreader_putContentHandler,
3239 isaxxmlreader_getDTDHandler,
3240 isaxxmlreader_putDTDHandler,
3241 isaxxmlreader_getErrorHandler,
3242 isaxxmlreader_putErrorHandler,
3243 isaxxmlreader_getBaseURL,
3244 isaxxmlreader_putBaseURL,
3245 isaxxmlreader_getSecureBaseURL,
3246 isaxxmlreader_putSecureBaseURL,
3247 isaxxmlreader_parse,
3248 isaxxmlreader_parseURL
3251 static const tid_t saxreader_iface_tids[] = {
3252 IVBSAXXMLReader_tid,
3255 static dispex_static_data_t saxreader_dispex = {
3257 IVBSAXXMLReader_tid,
3259 saxreader_iface_tids
3262 HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *outer, LPVOID *ppObj)
3266 TRACE("(%p, %p)\n", outer, ppObj);
3268 reader = heap_alloc( sizeof (*reader) );
3270 return E_OUTOFMEMORY;
3272 reader->IVBSAXXMLReader_iface.lpVtbl = &VBSAXXMLReaderVtbl;
3273 reader->ISAXXMLReader_iface.lpVtbl = &SAXXMLReaderVtbl;
3275 memset(reader->saxhandlers, 0, sizeof(reader->saxhandlers));
3276 reader->isParsing = FALSE;
3277 reader->xmldecl_version = NULL;
3278 reader->pool.pool = NULL;
3279 reader->pool.index = 0;
3280 reader->pool.len = 0;
3281 reader->features = Namespaces | NamespacePrefixes;
3282 reader->version = version;
3284 init_dispex(&reader->dispex, (IUnknown*)&reader->IVBSAXXMLReader_iface, &saxreader_dispex);
3286 memset(&reader->sax, 0, sizeof(xmlSAXHandler));
3287 reader->sax.initialized = XML_SAX2_MAGIC;
3288 reader->sax.startDocument = libxmlStartDocument;
3289 reader->sax.endDocument = libxmlEndDocument;
3290 reader->sax.startElementNs = libxmlStartElementNS;
3291 reader->sax.endElementNs = libxmlEndElementNS;
3292 reader->sax.characters = libxmlCharacters;
3293 reader->sax.setDocumentLocator = libxmlSetDocumentLocator;
3294 reader->sax.comment = libxmlComment;
3295 reader->sax.error = libxmlFatalError;
3296 reader->sax.fatalError = libxmlFatalError;
3297 reader->sax.cdataBlock = libxml_cdatablock;
3298 reader->sax.resolveEntity = libxmlresolveentity;
3300 *ppObj = &reader->IVBSAXXMLReader_iface;
3302 TRACE("returning iface %p\n", *ppObj);
3309 HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *pUnkOuter, LPVOID *ppObj)
3311 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3312 "libxml2 support was not present at compile time.\n");