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"
46 #include "msxml_private.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
55 ExhaustiveErrors
= 1 << 1,
56 ExternalGeneralEntities
= 1 << 2,
57 ExternalParameterEntities
= 1 << 3,
58 ForcedResync
= 1 << 4,
59 NamespacePrefixes
= 1 << 5,
61 ParameterEntities
= 1 << 7,
62 PreserveSystemIndentifiers
= 1 << 8,
64 SchemaValidation
= 1 << 10,
65 ServerHttpRequest
= 1 << 11,
66 SuppressValidationfatalError
= 1 << 12,
67 UseInlineSchema
= 1 << 13,
68 UseSchemaLocation
= 1 << 14,
69 LexicalHandlerParEntities
= 1 << 15
73 static const WCHAR FeatureExternalGeneralEntitiesW
[] = {
74 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/',
75 'f','e','a','t','u','r','e','s','/','e','x','t','e','r','n','a','l','-','g','e','n','e','r','a','l',
76 '-','e','n','t','i','t','i','e','s',0
79 static const WCHAR FeatureExternalParameterEntitiesW
[] = {
80 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
81 '/','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
84 static const WCHAR FeatureLexicalHandlerParEntitiesW
[] = {
85 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
86 '/','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
89 static const WCHAR FeatureProhibitDTDW
[] = {
90 'p','r','o','h','i','b','i','t','-','d','t','d',0
93 static const WCHAR FeatureNamespacesW
[] = {
94 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
95 '/','n','a','m','e','s','p','a','c','e','s',0
98 static const WCHAR FeatureNamespacePrefixesW
[] = {
99 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
100 '/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0
103 static const WCHAR ExhaustiveErrorsW
[] = {
104 'e','x','h','a','u','s','t','i','v','e','-','e','r','r','o','r','s',0
107 static const WCHAR SchemaValidationW
[] = {
108 's','c','h','e','m','a','-','v','a','l','i','d','a','t','i','o','n',0
111 struct saxreader_feature_pair
113 saxreader_feature feature
;
117 static const struct saxreader_feature_pair saxreader_feature_map
[] = {
118 { ExhaustiveErrors
, ExhaustiveErrorsW
},
119 { ExternalGeneralEntities
, FeatureExternalGeneralEntitiesW
},
120 { ExternalParameterEntities
, FeatureExternalParameterEntitiesW
},
121 { LexicalHandlerParEntities
, FeatureLexicalHandlerParEntitiesW
},
122 { NamespacePrefixes
, FeatureNamespacePrefixesW
},
123 { Namespaces
, FeatureNamespacesW
},
124 { ProhibitDTD
, FeatureProhibitDTDW
},
125 { SchemaValidation
, SchemaValidationW
},
128 static saxreader_feature
get_saxreader_feature(const WCHAR
*name
)
133 max
= ARRAY_SIZE(saxreader_feature_map
) - 1;
139 c
= strcmpW(saxreader_feature_map
[n
].name
, name
);
141 return saxreader_feature_map
[n
].feature
;
149 return FeatureUnknown
;
152 static const WCHAR empty_str
;
173 ns
*ns
; /* namespaces defined in this particular element */
179 SAXContentHandler
= 0,
188 struct saxanyhandler_iface
194 struct saxcontenthandler_iface
196 ISAXContentHandler
*handler
;
197 IVBSAXContentHandler
*vbhandler
;
200 struct saxerrorhandler_iface
202 ISAXErrorHandler
*handler
;
203 IVBSAXErrorHandler
*vbhandler
;
206 struct saxlexicalhandler_iface
208 ISAXLexicalHandler
*handler
;
209 IVBSAXLexicalHandler
*vbhandler
;
212 struct saxentityresolver_iface
214 ISAXEntityResolver
*handler
;
215 IVBSAXEntityResolver
*vbhandler
;
218 struct saxhandler_iface
221 struct saxcontenthandler_iface content
;
222 struct saxentityresolver_iface entityresolver
;
223 struct saxerrorhandler_iface error
;
224 struct saxlexicalhandler_iface lexical
;
225 struct saxanyhandler_iface anyhandler
;
232 IVBSAXXMLReader IVBSAXXMLReader_iface
;
233 ISAXXMLReader ISAXXMLReader_iface
;
236 struct saxhandler_iface saxhandlers
[SAXHandler_Last
];
239 struct bstrpool pool
;
240 saxreader_feature features
;
241 BSTR xmldecl_version
;
242 MSXML_VERSION version
;
245 static HRESULT
saxreader_put_handler(saxreader
*reader
, enum saxhandler_type type
, void *ptr
, BOOL vb
)
247 struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
248 IUnknown
*unk
= (IUnknown
*)ptr
;
251 IUnknown_AddRef(unk
);
253 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
254 IUnknown_Release(vb
? iface
->vbhandler
: iface
->handler
);
257 iface
->vbhandler
= unk
;
259 iface
->handler
= unk
;
264 static HRESULT
saxreader_get_handler(const saxreader
*reader
, enum saxhandler_type type
, BOOL vb
, void **ret
)
266 const struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
268 if (!ret
) return E_POINTER
;
270 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
273 IUnknown_AddRef(iface
->vbhandler
);
275 IUnknown_AddRef(iface
->handler
);
278 *ret
= vb
? iface
->vbhandler
: iface
->handler
;
283 static struct saxcontenthandler_iface
*saxreader_get_contenthandler(saxreader
*reader
)
285 return &reader
->saxhandlers
[SAXContentHandler
].u
.content
;
288 static struct saxerrorhandler_iface
*saxreader_get_errorhandler(saxreader
*reader
)
290 return &reader
->saxhandlers
[SAXErrorHandler
].u
.error
;
293 static struct saxlexicalhandler_iface
*saxreader_get_lexicalhandler(saxreader
*reader
)
295 return &reader
->saxhandlers
[SAXLexicalHandler
].u
.lexical
;
300 IVBSAXLocator IVBSAXLocator_iface
;
301 ISAXLocator ISAXLocator_iface
;
302 IVBSAXAttributes IVBSAXAttributes_iface
;
303 ISAXAttributes ISAXAttributes_iface
;
305 saxreader
*saxreader
;
307 xmlParserCtxtPtr pParserCtxt
;
313 struct list elements
;
316 int attr_alloc_count
;
327 static inline saxreader
*impl_from_IVBSAXXMLReader( IVBSAXXMLReader
*iface
)
329 return CONTAINING_RECORD(iface
, saxreader
, IVBSAXXMLReader_iface
);
332 static inline saxreader
*impl_from_ISAXXMLReader( ISAXXMLReader
*iface
)
334 return CONTAINING_RECORD(iface
, saxreader
, ISAXXMLReader_iface
);
337 static inline saxlocator
*impl_from_IVBSAXLocator( IVBSAXLocator
*iface
)
339 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXLocator_iface
);
342 static inline saxlocator
*impl_from_ISAXLocator( ISAXLocator
*iface
)
344 return CONTAINING_RECORD(iface
, saxlocator
, ISAXLocator_iface
);
347 static inline saxlocator
*impl_from_IVBSAXAttributes( IVBSAXAttributes
*iface
)
349 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXAttributes_iface
);
352 static inline saxlocator
*impl_from_ISAXAttributes( ISAXAttributes
*iface
)
354 return CONTAINING_RECORD(iface
, saxlocator
, ISAXAttributes_iface
);
357 static inline BOOL
saxreader_has_handler(const saxlocator
*locator
, enum saxhandler_type type
)
359 struct saxanyhandler_iface
*iface
= &locator
->saxreader
->saxhandlers
[type
].u
.anyhandler
;
360 return (locator
->vbInterface
&& iface
->vbhandler
) || (!locator
->vbInterface
&& iface
->handler
);
363 static HRESULT
saxreader_saxcharacters(saxlocator
*locator
, BSTR chars
)
365 struct saxcontenthandler_iface
*content
= saxreader_get_contenthandler(locator
->saxreader
);
368 if (!saxreader_has_handler(locator
, SAXContentHandler
)) return S_OK
;
370 if (locator
->vbInterface
)
371 hr
= IVBSAXContentHandler_characters(content
->vbhandler
, &chars
);
373 hr
= ISAXContentHandler_characters(content
->handler
, chars
, SysStringLen(chars
));
379 static const WCHAR PropertyCharsetW
[] = {
380 'c','h','a','r','s','e','t',0
382 static const WCHAR PropertyXmlDeclVersionW
[] = {
383 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
385 static const WCHAR PropertyDeclHandlerW
[] = {
386 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
387 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
388 'd','e','c','l','a','r','a','t','i','o','n',
389 '-','h','a','n','d','l','e','r',0
391 static const WCHAR PropertyDomNodeW
[] = {
392 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
393 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
394 'd','o','m','-','n','o','d','e',0
396 static const WCHAR PropertyInputSourceW
[] = {
397 'i','n','p','u','t','-','s','o','u','r','c','e',0
399 static const WCHAR PropertyLexicalHandlerW
[] = {
400 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
401 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
402 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
404 static const WCHAR PropertyMaxElementDepthW
[] = {
405 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
407 static const WCHAR PropertyMaxXMLSizeW
[] = {
408 'm','a','x','-','x','m','l','-','s','i','z','e',0
410 static const WCHAR PropertySchemaDeclHandlerW
[] = {
411 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
412 'h','a','n','d','l','e','r',0
414 static const WCHAR PropertyXMLDeclEncodingW
[] = {
415 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
417 static const WCHAR PropertyXMLDeclStandaloneW
[] = {
418 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
420 static const WCHAR PropertyXMLDeclVersionW
[] = {
421 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
424 static inline HRESULT
set_feature_value(saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL value
)
426 /* handling of non-VARIANT_* values is version dependent */
427 if ((reader
->version
< MSXML4
) && (value
!= VARIANT_TRUE
))
428 value
= VARIANT_FALSE
;
429 if ((reader
->version
>= MSXML4
) && (value
!= VARIANT_FALSE
))
430 value
= VARIANT_TRUE
;
432 if (value
== VARIANT_TRUE
)
433 reader
->features
|= feature
;
435 reader
->features
&= ~feature
;
440 static inline HRESULT
get_feature_value(const saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL
*value
)
442 *value
= reader
->features
& feature
? VARIANT_TRUE
: VARIANT_FALSE
;
446 static BOOL
is_namespaces_enabled(const saxreader
*reader
)
448 return (reader
->version
< MSXML4
) || (reader
->features
& Namespaces
);
451 static BSTR
build_qname(BSTR prefix
, BSTR local
)
453 if (prefix
&& *prefix
)
455 BSTR qname
= SysAllocStringLen(NULL
, SysStringLen(prefix
) + SysStringLen(local
) + 1);
459 strcpyW(ptr
, prefix
);
460 ptr
+= SysStringLen(prefix
);
466 return SysAllocString(local
);
469 static element_entry
* alloc_element_entry(const xmlChar
*local
, const xmlChar
*prefix
, int nb_ns
,
470 const xmlChar
**namespaces
)
475 ret
= heap_alloc(sizeof(*ret
));
476 if (!ret
) return ret
;
478 ret
->local
= bstr_from_xmlChar(local
);
479 ret
->prefix
= bstr_from_xmlChar(prefix
);
480 ret
->qname
= build_qname(ret
->prefix
, ret
->local
);
481 ret
->ns
= nb_ns
? heap_alloc(nb_ns
*sizeof(ns
)) : NULL
;
482 ret
->ns_count
= nb_ns
;
484 for (i
=0; i
< nb_ns
; i
++)
486 ret
->ns
[i
].prefix
= bstr_from_xmlChar(namespaces
[2*i
]);
487 ret
->ns
[i
].uri
= bstr_from_xmlChar(namespaces
[2*i
+1]);
493 static void free_element_entry(element_entry
*element
)
497 for (i
=0; i
<element
->ns_count
;i
++)
499 SysFreeString(element
->ns
[i
].prefix
);
500 SysFreeString(element
->ns
[i
].uri
);
503 SysFreeString(element
->prefix
);
504 SysFreeString(element
->local
);
505 SysFreeString(element
->qname
);
507 heap_free(element
->ns
);
511 static void push_element_ns(saxlocator
*locator
, element_entry
*element
)
513 list_add_head(&locator
->elements
, &element
->entry
);
516 static element_entry
* pop_element_ns(saxlocator
*locator
)
518 element_entry
*element
= LIST_ENTRY(list_head(&locator
->elements
), element_entry
, entry
);
521 list_remove(&element
->entry
);
526 static BSTR
find_element_uri(saxlocator
*locator
, const xmlChar
*uri
)
528 element_entry
*element
;
532 if (!uri
) return NULL
;
534 uriW
= bstr_from_xmlChar(uri
);
536 LIST_FOR_EACH_ENTRY(element
, &locator
->elements
, element_entry
, entry
)
538 for (i
=0; i
< element
->ns_count
; i
++)
539 if (!strcmpW(uriW
, element
->ns
[i
].uri
))
542 return element
->ns
[i
].uri
;
547 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri
));
551 /* used to localize version dependent error check behaviour */
552 static inline BOOL
sax_callback_failed(saxlocator
*This
, HRESULT hr
)
554 return This
->saxreader
->version
>= MSXML4
? FAILED(hr
) : hr
!= S_OK
;
557 /* index value -1 means it tries to loop for a first time */
558 static inline BOOL
iterate_endprefix_index(saxlocator
*This
, const element_entry
*element
, int *i
)
560 if (This
->saxreader
->version
>= MSXML4
)
562 if (*i
== -1) *i
= 0; else ++*i
;
563 return *i
< element
->ns_count
;
567 if (*i
== -1) *i
= element
->ns_count
-1; else --*i
;
572 static BOOL
bstr_pool_insert(struct bstrpool
*pool
, BSTR pool_entry
)
576 pool
->pool
= heap_alloc(16 * sizeof(*pool
->pool
));
583 else if (pool
->index
== pool
->len
)
585 BSTR
*realloc
= heap_realloc(pool
->pool
, pool
->len
* 2 * sizeof(*realloc
));
590 pool
->pool
= realloc
;
594 pool
->pool
[pool
->index
++] = pool_entry
;
598 static void free_bstr_pool(struct bstrpool
*pool
)
602 for (i
= 0; i
< pool
->index
; i
++)
603 SysFreeString(pool
->pool
[i
]);
605 heap_free(pool
->pool
);
608 pool
->index
= pool
->len
= 0;
611 static BSTR
bstr_from_xmlCharN(const xmlChar
*buf
, int len
)
619 dLen
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
620 if(len
!= -1) dLen
++;
621 bstr
= SysAllocStringLen(NULL
, dLen
-1);
624 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, bstr
, dLen
);
625 if(len
!= -1) bstr
[dLen
-1] = '\0';
630 static BSTR
QName_from_xmlChar(const xmlChar
*prefix
, const xmlChar
*name
)
635 if(!name
) return NULL
;
637 if(!prefix
|| !*prefix
)
638 return bstr_from_xmlChar(name
);
640 qname
= xmlBuildQName(name
, prefix
, NULL
, 0);
641 bstr
= bstr_from_xmlChar(qname
);
647 static BSTR
pooled_bstr_from_xmlChar(struct bstrpool
*pool
, const xmlChar
*buf
)
649 BSTR pool_entry
= bstr_from_xmlChar(buf
);
651 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
653 SysFreeString(pool_entry
);
660 static BSTR
pooled_bstr_from_xmlCharN(struct bstrpool
*pool
, const xmlChar
*buf
, int len
)
662 BSTR pool_entry
= bstr_from_xmlCharN(buf
, len
);
664 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
666 SysFreeString(pool_entry
);
673 static void format_error_message_from_id(saxlocator
*This
, HRESULT hr
)
675 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
676 xmlStopParser(This
->pParserCtxt
);
679 if (saxreader_has_handler(This
, SAXErrorHandler
))
682 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
,
683 NULL
, hr
, 0, msg
, ARRAY_SIZE(msg
), NULL
))
685 FIXME("MSXML errors not yet supported.\n");
689 if(This
->vbInterface
)
691 BSTR bstrMsg
= SysAllocString(msg
);
692 IVBSAXErrorHandler_fatalError(handler
->vbhandler
,
693 &This
->IVBSAXLocator_iface
, &bstrMsg
, hr
);
694 SysFreeString(bstrMsg
);
697 ISAXErrorHandler_fatalError(handler
->handler
,
698 &This
->ISAXLocator_iface
, msg
, hr
);
702 static void update_position(saxlocator
*This
, BOOL fix_column
)
704 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
705 const xmlChar
*baseP
= This
->pParserCtxt
->input
->base
;
707 This
->line
= xmlSAX2GetLineNumber(This
->pParserCtxt
);
711 for(;p
>=baseP
&& *p
!='\n' && *p
!='\r'; p
--)
716 This
->column
= xmlSAX2GetColumnNumber(This
->pParserCtxt
);
720 /*** IVBSAXAttributes interface ***/
721 static HRESULT WINAPI
ivbsaxattributes_QueryInterface(
722 IVBSAXAttributes
* iface
,
726 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
727 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
728 return IVBSAXLocator_QueryInterface(&This
->IVBSAXLocator_iface
, riid
, ppvObject
);
731 static ULONG WINAPI
ivbsaxattributes_AddRef(IVBSAXAttributes
* iface
)
733 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
734 return IVBSAXLocator_AddRef(&This
->IVBSAXLocator_iface
);
737 static ULONG WINAPI
ivbsaxattributes_Release(IVBSAXAttributes
* iface
)
739 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
740 return IVBSAXLocator_Release(&This
->IVBSAXLocator_iface
);
743 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes
*iface
, UINT
* pctinfo
)
745 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
747 TRACE("(%p)->(%p)\n", This
, pctinfo
);
754 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfo(
755 IVBSAXAttributes
*iface
,
756 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
758 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
760 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
762 return get_typeinfo(IVBSAXAttributes_tid
, ppTInfo
);
765 static HRESULT WINAPI
ivbsaxattributes_GetIDsOfNames(
766 IVBSAXAttributes
*iface
,
773 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
777 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
780 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
783 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
786 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
787 ITypeInfo_Release(typeinfo
);
793 static HRESULT WINAPI
ivbsaxattributes_Invoke(
794 IVBSAXAttributes
*iface
,
799 DISPPARAMS
* pDispParams
,
801 EXCEPINFO
* pExcepInfo
,
804 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
808 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
809 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
811 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
814 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXAttributes_iface
, dispIdMember
, wFlags
,
815 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
816 ITypeInfo_Release(typeinfo
);
822 /*** IVBSAXAttributes methods ***/
823 static HRESULT WINAPI
ivbsaxattributes_get_length(
824 IVBSAXAttributes
* iface
,
827 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
828 return ISAXAttributes_getLength(&This
->ISAXAttributes_iface
, nLength
);
831 static HRESULT WINAPI
ivbsaxattributes_getURI(
832 IVBSAXAttributes
* iface
,
836 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
841 TRACE("(%p)->(%d %p)\n", This
, nIndex
, uri
);
847 hr
= ISAXAttributes_getURI(&This
->ISAXAttributes_iface
, nIndex
, &uriW
, &len
);
851 return return_bstrn(uriW
, len
, uri
);
854 static HRESULT WINAPI
ivbsaxattributes_getLocalName(
855 IVBSAXAttributes
* iface
,
859 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
864 TRACE("(%p)->(%d %p)\n", This
, nIndex
, name
);
870 hr
= ISAXAttributes_getLocalName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
874 return return_bstrn(nameW
, len
, name
);
877 static HRESULT WINAPI
ivbsaxattributes_getQName(
878 IVBSAXAttributes
* iface
,
882 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
887 TRACE("(%p)->(%d %p)\n", This
, nIndex
, QName
);
893 hr
= ISAXAttributes_getQName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
897 return return_bstrn(nameW
, len
, QName
);
900 static HRESULT WINAPI
ivbsaxattributes_getIndexFromName(
901 IVBSAXAttributes
* iface
,
906 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
907 return ISAXAttributes_getIndexFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
908 localName
, SysStringLen(localName
), index
);
911 static HRESULT WINAPI
ivbsaxattributes_getIndexFromQName(
912 IVBSAXAttributes
* iface
,
916 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
917 return ISAXAttributes_getIndexFromQName(&This
->ISAXAttributes_iface
, QName
,
918 SysStringLen(QName
), index
);
921 static HRESULT WINAPI
ivbsaxattributes_getType(
922 IVBSAXAttributes
* iface
,
926 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
931 TRACE("(%p)->(%d %p)\n", This
, nIndex
, type
);
937 hr
= ISAXAttributes_getType(&This
->ISAXAttributes_iface
, nIndex
, &typeW
, &len
);
941 return return_bstrn(typeW
, len
, type
);
944 static HRESULT WINAPI
ivbsaxattributes_getTypeFromName(
945 IVBSAXAttributes
* iface
,
950 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
955 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), type
);
961 hr
= ISAXAttributes_getTypeFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
962 localName
, SysStringLen(localName
), &typeW
, &len
);
966 return return_bstrn(typeW
, len
, type
);
969 static HRESULT WINAPI
ivbsaxattributes_getTypeFromQName(
970 IVBSAXAttributes
* iface
,
974 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
979 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), type
);
985 hr
= ISAXAttributes_getTypeFromQName(&This
->ISAXAttributes_iface
, QName
, SysStringLen(QName
),
990 return return_bstrn(typeW
, len
, type
);
993 static HRESULT WINAPI
ivbsaxattributes_getValue(
994 IVBSAXAttributes
* iface
,
998 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1003 TRACE("(%p)->(%d %p)\n", This
, nIndex
, value
);
1009 hr
= ISAXAttributes_getValue(&This
->ISAXAttributes_iface
, nIndex
, &valueW
, &len
);
1013 return return_bstrn(valueW
, len
, value
);
1016 static HRESULT WINAPI
ivbsaxattributes_getValueFromName(
1017 IVBSAXAttributes
* iface
,
1022 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1023 const WCHAR
*valueW
;
1027 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), value
);
1033 hr
= ISAXAttributes_getValueFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
1034 localName
, SysStringLen(localName
), &valueW
, &len
);
1038 return return_bstrn(valueW
, len
, value
);
1041 static HRESULT WINAPI
ivbsaxattributes_getValueFromQName(
1042 IVBSAXAttributes
* iface
,
1046 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1047 const WCHAR
*valueW
;
1051 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), value
);
1057 hr
= ISAXAttributes_getValueFromQName(&This
->ISAXAttributes_iface
, QName
,
1058 SysStringLen(QName
), &valueW
, &len
);
1062 return return_bstrn(valueW
, len
, value
);
1065 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl
=
1067 ivbsaxattributes_QueryInterface
,
1068 ivbsaxattributes_AddRef
,
1069 ivbsaxattributes_Release
,
1070 ivbsaxattributes_GetTypeInfoCount
,
1071 ivbsaxattributes_GetTypeInfo
,
1072 ivbsaxattributes_GetIDsOfNames
,
1073 ivbsaxattributes_Invoke
,
1074 ivbsaxattributes_get_length
,
1075 ivbsaxattributes_getURI
,
1076 ivbsaxattributes_getLocalName
,
1077 ivbsaxattributes_getQName
,
1078 ivbsaxattributes_getIndexFromName
,
1079 ivbsaxattributes_getIndexFromQName
,
1080 ivbsaxattributes_getType
,
1081 ivbsaxattributes_getTypeFromName
,
1082 ivbsaxattributes_getTypeFromQName
,
1083 ivbsaxattributes_getValue
,
1084 ivbsaxattributes_getValueFromName
,
1085 ivbsaxattributes_getValueFromQName
1088 /*** ISAXAttributes interface ***/
1089 /*** IUnknown methods ***/
1090 static HRESULT WINAPI
isaxattributes_QueryInterface(
1091 ISAXAttributes
* iface
,
1095 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1096 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
1097 return ISAXLocator_QueryInterface(&This
->ISAXLocator_iface
, riid
, ppvObject
);
1100 static ULONG WINAPI
isaxattributes_AddRef(ISAXAttributes
* iface
)
1102 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1103 TRACE("%p\n", This
);
1104 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
1107 static ULONG WINAPI
isaxattributes_Release(ISAXAttributes
* iface
)
1109 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1111 TRACE("%p\n", This
);
1112 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
1115 /*** ISAXAttributes methods ***/
1116 static HRESULT WINAPI
isaxattributes_getLength(
1117 ISAXAttributes
* iface
,
1120 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1122 *length
= This
->attr_count
;
1123 TRACE("Length set to %d\n", *length
);
1127 static inline BOOL
is_valid_attr_index(const saxlocator
*locator
, int index
)
1129 return index
< locator
->attr_count
&& index
>= 0;
1132 static HRESULT WINAPI
isaxattributes_getURI(
1133 ISAXAttributes
* iface
,
1138 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1139 TRACE("(%p)->(%d)\n", This
, index
);
1141 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1142 if(!url
|| !size
) return E_POINTER
;
1144 *size
= SysStringLen(This
->attributes
[index
].szURI
);
1145 *url
= This
->attributes
[index
].szURI
;
1147 TRACE("(%s:%d)\n", debugstr_w(This
->attributes
[index
].szURI
), *size
);
1152 static HRESULT WINAPI
isaxattributes_getLocalName(
1153 ISAXAttributes
* iface
,
1155 const WCHAR
**pLocalName
,
1156 int *pLocalNameLength
)
1158 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1159 TRACE("(%p)->(%d)\n", This
, index
);
1161 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1162 if(!pLocalName
|| !pLocalNameLength
) return E_POINTER
;
1164 *pLocalNameLength
= SysStringLen(This
->attributes
[index
].szLocalname
);
1165 *pLocalName
= This
->attributes
[index
].szLocalname
;
1170 static HRESULT WINAPI
isaxattributes_getQName(
1171 ISAXAttributes
* iface
,
1173 const WCHAR
**pQName
,
1176 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1177 TRACE("(%p)->(%d)\n", This
, index
);
1179 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1180 if(!pQName
|| !pQNameLength
) return E_POINTER
;
1182 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1183 *pQName
= This
->attributes
[index
].szQName
;
1188 static HRESULT WINAPI
isaxattributes_getName(
1189 ISAXAttributes
* iface
,
1193 const WCHAR
**localName
,
1194 int *pLocalNameSize
,
1195 const WCHAR
**QName
,
1198 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1199 TRACE("(%p)->(%d)\n", This
, index
);
1201 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1202 if(!uri
|| !pUriLength
|| !localName
|| !pLocalNameSize
1203 || !QName
|| !pQNameLength
) return E_POINTER
;
1205 *pUriLength
= SysStringLen(This
->attributes
[index
].szURI
);
1206 *uri
= This
->attributes
[index
].szURI
;
1207 *pLocalNameSize
= SysStringLen(This
->attributes
[index
].szLocalname
);
1208 *localName
= This
->attributes
[index
].szLocalname
;
1209 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1210 *QName
= This
->attributes
[index
].szQName
;
1212 TRACE("(%s, %s, %s)\n", debugstr_w(*uri
), debugstr_w(*localName
), debugstr_w(*QName
));
1217 static HRESULT WINAPI
isaxattributes_getIndexFromName(
1218 ISAXAttributes
* iface
,
1221 const WCHAR
*pLocalName
,
1222 int cocalNameLength
,
1225 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1227 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), cUriLength
,
1228 debugstr_w(pLocalName
), cocalNameLength
);
1230 if(!pUri
|| !pLocalName
|| !index
) return E_POINTER
;
1232 for(i
=0; i
<This
->attr_count
; i
++)
1234 if(cUriLength
!=SysStringLen(This
->attributes
[i
].szURI
)
1235 || cocalNameLength
!=SysStringLen(This
->attributes
[i
].szLocalname
))
1237 if(cUriLength
&& memcmp(pUri
, This
->attributes
[i
].szURI
,
1238 sizeof(WCHAR
)*cUriLength
))
1240 if(cocalNameLength
&& memcmp(pLocalName
, This
->attributes
[i
].szLocalname
,
1241 sizeof(WCHAR
)*cocalNameLength
))
1248 return E_INVALIDARG
;
1251 static HRESULT WINAPI
isaxattributes_getIndexFromQName(
1252 ISAXAttributes
* iface
,
1253 const WCHAR
*pQName
,
1257 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1259 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQNameLength
);
1261 if(!pQName
|| !index
) return E_POINTER
;
1262 if(!nQNameLength
) return E_INVALIDARG
;
1264 for(i
=0; i
<This
->attr_count
; i
++)
1266 if(nQNameLength
!=SysStringLen(This
->attributes
[i
].szQName
)) continue;
1267 if(memcmp(pQName
, This
->attributes
[i
].szQName
, sizeof(WCHAR
)*nQNameLength
)) continue;
1273 return E_INVALIDARG
;
1276 static HRESULT WINAPI
isaxattributes_getType(
1277 ISAXAttributes
* iface
,
1279 const WCHAR
**pType
,
1282 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1284 FIXME("(%p)->(%d) stub\n", This
, nIndex
);
1288 static HRESULT WINAPI
isaxattributes_getTypeFromName(
1289 ISAXAttributes
* iface
,
1292 const WCHAR
*pLocalName
,
1294 const WCHAR
**pType
,
1297 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1299 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This
, debugstr_w(pUri
), nUri
,
1300 debugstr_w(pLocalName
), nLocalName
);
1304 static HRESULT WINAPI
isaxattributes_getTypeFromQName(
1305 ISAXAttributes
* iface
,
1306 const WCHAR
*pQName
,
1308 const WCHAR
**pType
,
1311 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1313 FIXME("(%p)->(%s, %d) stub\n", This
, debugstr_w(pQName
), nQName
);
1317 static HRESULT WINAPI
isaxattributes_getValue(
1318 ISAXAttributes
* iface
,
1320 const WCHAR
**value
,
1323 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1324 TRACE("(%p)->(%d)\n", This
, index
);
1326 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1327 if(!value
|| !nValue
) return E_POINTER
;
1329 *nValue
= SysStringLen(This
->attributes
[index
].szValue
);
1330 *value
= This
->attributes
[index
].szValue
;
1332 TRACE("(%s:%d)\n", debugstr_w(*value
), *nValue
);
1337 static HRESULT WINAPI
isaxattributes_getValueFromName(
1338 ISAXAttributes
* iface
,
1341 const WCHAR
*pLocalName
,
1343 const WCHAR
**pValue
,
1348 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1349 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), nUri
,
1350 debugstr_w(pLocalName
), nLocalName
);
1352 hr
= ISAXAttributes_getIndexFromName(iface
,
1353 pUri
, nUri
, pLocalName
, nLocalName
, &index
);
1354 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1359 static HRESULT WINAPI
isaxattributes_getValueFromQName(
1360 ISAXAttributes
* iface
,
1361 const WCHAR
*pQName
,
1363 const WCHAR
**pValue
,
1368 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1369 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQName
);
1371 hr
= ISAXAttributes_getIndexFromQName(iface
, pQName
, nQName
, &index
);
1372 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1377 static const struct ISAXAttributesVtbl isaxattributes_vtbl
=
1379 isaxattributes_QueryInterface
,
1380 isaxattributes_AddRef
,
1381 isaxattributes_Release
,
1382 isaxattributes_getLength
,
1383 isaxattributes_getURI
,
1384 isaxattributes_getLocalName
,
1385 isaxattributes_getQName
,
1386 isaxattributes_getName
,
1387 isaxattributes_getIndexFromName
,
1388 isaxattributes_getIndexFromQName
,
1389 isaxattributes_getType
,
1390 isaxattributes_getTypeFromName
,
1391 isaxattributes_getTypeFromQName
,
1392 isaxattributes_getValue
,
1393 isaxattributes_getValueFromName
,
1394 isaxattributes_getValueFromQName
1397 /* Libxml2 escapes '&' back to char reference '&' in attribute value,
1398 so when document has escaped value with '&' it's parsed to '&' and then
1399 escaped to '&'. This function takes care of ampersands only. */
1400 static BSTR
saxreader_get_unescaped_value(const xmlChar
*buf
, int len
)
1402 static const WCHAR ampescW
[] = {'&','#','3','8',';',0};
1403 WCHAR
*dest
, *ptrW
, *str
;
1410 str_len
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
1411 if (len
!= -1) str_len
++;
1413 str
= heap_alloc(str_len
*sizeof(WCHAR
));
1414 if (!str
) return NULL
;
1416 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, str
, str_len
);
1417 if (len
!= -1) str
[str_len
-1] = 0;
1420 while ((dest
= strstrW(ptrW
, ampescW
)))
1424 /* leave first '&' from a reference as a value */
1425 src
= dest
+ ARRAY_SIZE(ampescW
) - 1;
1428 /* move together with null terminator */
1429 memmove(dest
, src
, (strlenW(src
) + 1)*sizeof(WCHAR
));
1434 bstr
= SysAllocString(str
);
1440 static void free_attribute_values(saxlocator
*locator
)
1444 for (i
= 0; i
< locator
->attr_count
; i
++)
1446 SysFreeString(locator
->attributes
[i
].szLocalname
);
1447 locator
->attributes
[i
].szLocalname
= NULL
;
1449 SysFreeString(locator
->attributes
[i
].szValue
);
1450 locator
->attributes
[i
].szValue
= NULL
;
1452 SysFreeString(locator
->attributes
[i
].szQName
);
1453 locator
->attributes
[i
].szQName
= NULL
;
1457 static HRESULT
SAXAttributes_populate(saxlocator
*locator
,
1458 int nb_namespaces
, const xmlChar
**xmlNamespaces
,
1459 int nb_attributes
, const xmlChar
**xmlAttributes
)
1461 static const xmlChar xmlns
[] = "xmlns";
1462 static const WCHAR xmlnsW
[] = { 'x','m','l','n','s',0 };
1464 struct _attributes
*attrs
;
1467 /* skip namespace definitions */
1468 if ((locator
->saxreader
->features
& NamespacePrefixes
) == 0)
1471 locator
->attr_count
= nb_namespaces
+ nb_attributes
;
1472 if(locator
->attr_count
> locator
->attr_alloc_count
)
1474 int new_size
= locator
->attr_count
* 2;
1475 attrs
= heap_realloc_zero(locator
->attributes
, new_size
* sizeof(struct _attributes
));
1478 free_attribute_values(locator
);
1479 locator
->attr_count
= 0;
1480 return E_OUTOFMEMORY
;
1482 locator
->attributes
= attrs
;
1483 locator
->attr_alloc_count
= new_size
;
1487 attrs
= locator
->attributes
;
1490 for (i
= 0; i
< nb_namespaces
; i
++)
1492 SysFreeString(attrs
[nb_attributes
+i
].szLocalname
);
1493 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1495 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1497 SysFreeString(attrs
[nb_attributes
+i
].szValue
);
1498 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1500 SysFreeString(attrs
[nb_attributes
+i
].szQName
);
1501 if(!xmlNamespaces
[2*i
])
1502 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1504 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1507 for (i
= 0; i
< nb_attributes
; i
++)
1509 static const xmlChar xmlA
[] = "xml";
1511 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1512 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1514 /* that's an important feature to keep same uri pointer for every reported attribute */
1515 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1517 SysFreeString(attrs
[i
].szLocalname
);
1518 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1520 SysFreeString(attrs
[i
].szValue
);
1521 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1523 SysFreeString(attrs
[i
].szQName
);
1524 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1], xmlAttributes
[i
*5]);
1530 /*** LibXML callbacks ***/
1531 static void libxmlStartDocument(void *ctx
)
1533 saxlocator
*This
= ctx
;
1534 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1537 if (This
->saxreader
->version
>= MSXML4
)
1539 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1540 update_position(This
, FALSE
);
1541 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1543 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1548 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1552 /* store version value, declaration has to contain version attribute */
1553 if (This
->pParserCtxt
->standalone
!= -1)
1555 SysFreeString(This
->saxreader
->xmldecl_version
);
1556 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1559 if (saxreader_has_handler(This
, SAXContentHandler
))
1561 if(This
->vbInterface
)
1562 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1564 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1566 if (sax_callback_failed(This
, hr
))
1567 format_error_message_from_id(This
, hr
);
1571 static void libxmlEndDocument(void *ctx
)
1573 saxlocator
*This
= ctx
;
1574 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1577 if (This
->saxreader
->version
>= MSXML4
) {
1578 update_position(This
, FALSE
);
1579 if(This
->column
> 1)
1587 if(This
->ret
!= S_OK
) return;
1589 if (saxreader_has_handler(This
, SAXContentHandler
))
1591 if(This
->vbInterface
)
1592 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1594 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1596 if (sax_callback_failed(This
, hr
))
1597 format_error_message_from_id(This
, hr
);
1601 static void libxmlStartElementNS(
1603 const xmlChar
*localname
,
1604 const xmlChar
*prefix
,
1607 const xmlChar
**namespaces
,
1610 const xmlChar
**attributes
)
1612 saxlocator
*This
= ctx
;
1613 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1614 element_entry
*element
;
1618 update_position(This
, TRUE
);
1619 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1621 if(This
->saxreader
->version
< MSXML4
)
1624 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1625 push_element_ns(This
, element
);
1627 if (is_namespaces_enabled(This
->saxreader
))
1631 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1633 if (This
->vbInterface
)
1634 hr
= IVBSAXContentHandler_startPrefixMapping(
1636 &element
->ns
[i
].prefix
,
1637 &element
->ns
[i
].uri
);
1639 hr
= ISAXContentHandler_startPrefixMapping(
1641 element
->ns
[i
].prefix
,
1642 SysStringLen(element
->ns
[i
].prefix
),
1644 SysStringLen(element
->ns
[i
].uri
));
1646 if (sax_callback_failed(This
, hr
))
1648 format_error_message_from_id(This
, hr
);
1654 uri
= find_element_uri(This
, URI
);
1655 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1656 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1660 if (is_namespaces_enabled(This
->saxreader
))
1661 local
= element
->local
;
1665 if (This
->vbInterface
)
1666 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1667 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1669 hr
= ISAXContentHandler_startElement(handler
->handler
,
1670 uri
? uri
: &empty_str
, SysStringLen(uri
),
1671 local
? local
: &empty_str
, SysStringLen(local
),
1672 element
->qname
, SysStringLen(element
->qname
),
1673 &This
->ISAXAttributes_iface
);
1675 if (sax_callback_failed(This
, hr
))
1676 format_error_message_from_id(This
, hr
);
1680 static void libxmlEndElementNS(
1682 const xmlChar
*localname
,
1683 const xmlChar
*prefix
,
1686 saxlocator
*This
= ctx
;
1687 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1688 element_entry
*element
;
1693 update_position(This
, FALSE
);
1694 p
= This
->pParserCtxt
->input
->cur
;
1696 if (This
->saxreader
->version
>= MSXML4
)
1699 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1701 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1706 else if(*(p
-1)!='>' || *(p
-2)!='/')
1709 while(p
-2>=This
->pParserCtxt
->input
->base
1710 && *(p
-2)!='<' && *(p
-1)!='/')
1712 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1718 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1721 uri
= find_element_uri(This
, URI
);
1722 element
= pop_element_ns(This
);
1724 if (!saxreader_has_handler(This
, SAXContentHandler
))
1726 free_attribute_values(This
);
1727 This
->attr_count
= 0;
1728 free_element_entry(element
);
1732 if (is_namespaces_enabled(This
->saxreader
))
1733 local
= element
->local
;
1737 if (This
->vbInterface
)
1738 hr
= IVBSAXContentHandler_endElement(
1740 &uri
, &local
, &element
->qname
);
1742 hr
= ISAXContentHandler_endElement(
1744 uri
? uri
: &empty_str
, SysStringLen(uri
),
1745 local
? local
: &empty_str
, SysStringLen(local
),
1746 element
->qname
, SysStringLen(element
->qname
));
1748 free_attribute_values(This
);
1749 This
->attr_count
= 0;
1751 if (sax_callback_failed(This
, hr
))
1753 format_error_message_from_id(This
, hr
);
1754 free_element_entry(element
);
1758 if (is_namespaces_enabled(This
->saxreader
))
1761 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1763 if (This
->vbInterface
)
1764 hr
= IVBSAXContentHandler_endPrefixMapping(
1765 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1767 hr
= ISAXContentHandler_endPrefixMapping(
1768 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1770 if (sax_callback_failed(This
, hr
)) break;
1773 if (sax_callback_failed(This
, hr
))
1774 format_error_message_from_id(This
, hr
);
1777 free_element_entry(element
);
1780 static void libxmlCharacters(
1785 saxlocator
*This
= ctx
;
1789 BOOL lastEvent
= FALSE
;
1791 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1793 update_position(This
, FALSE
);
1794 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1795 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1797 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1802 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1806 if(*(ch
-1)=='\r') cur
--;
1811 while(end
-ch
<len
&& *end
!='\r') end
++;
1822 if (This
->saxreader
->version
>= MSXML4
)
1826 for(p
=cur
; p
!=end
; p
++)
1843 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1844 hr
= saxreader_saxcharacters(This
, Chars
);
1846 if (sax_callback_failed(This
, hr
))
1848 format_error_message_from_id(This
, hr
);
1852 if (This
->saxreader
->version
< MSXML4
)
1853 This
->column
+= end
-cur
;
1866 if(end
-ch
== len
) break;
1870 static void libxmlSetDocumentLocator(
1872 xmlSAXLocatorPtr loc
)
1874 saxlocator
*This
= ctx
;
1875 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1878 if (saxreader_has_handler(This
, SAXContentHandler
))
1880 if(This
->vbInterface
)
1881 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1882 &This
->IVBSAXLocator_iface
);
1884 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1888 format_error_message_from_id(This
, hr
);
1891 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1893 saxlocator
*This
= ctx
;
1894 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1897 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1899 update_position(This
, FALSE
);
1900 while(p
-4>=This
->pParserCtxt
->input
->base
1901 && memcmp(p
-4, "<!--", sizeof(char[4])))
1903 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1909 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1912 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1914 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1916 if (This
->vbInterface
)
1917 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1919 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1922 format_error_message_from_id(This
, hr
);
1925 static void libxmlFatalError(void *ctx
, const char *msg
, ...)
1927 saxlocator
*This
= ctx
;
1928 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1934 if(This
->ret
!= S_OK
) {
1935 xmlStopParser(This
->pParserCtxt
);
1939 va_start(args
, msg
);
1940 vsprintf(message
, msg
, args
);
1943 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1944 error
= heap_alloc(sizeof(WCHAR
)*len
);
1947 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1948 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1951 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1953 xmlStopParser(This
->pParserCtxt
);
1959 FIXME("Error handling is not compatible.\n");
1961 if(This
->vbInterface
)
1963 BSTR bstrError
= SysAllocString(error
);
1964 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1965 &bstrError
, E_FAIL
);
1966 SysFreeString(bstrError
);
1969 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1973 xmlStopParser(This
->pParserCtxt
);
1977 /* The only reason this helper exists is that CDATA section are reported by chunks,
1978 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1980 This helper should be called for substring with trailing newlines.
1982 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1984 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1987 len
= SysStringLen(bstr
);
1988 ptr
= bstr
+ len
- 1;
1989 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1994 /* replace returns as:
1996 - "\r<char>" -> "\n<char>"
2002 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
2005 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
2012 ret
= SysAllocStringLen(bstr
, len
);
2013 SysFreeString(bstr
);
2017 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
2019 const xmlChar
*start
, *end
;
2020 saxlocator
*locator
= ctx
;
2021 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
2026 update_position(locator
, FALSE
);
2027 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2029 if (locator
->vbInterface
)
2030 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
2032 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
2037 format_error_message_from_id(locator
, hr
);
2047 /* scan for newlines */
2048 if (value
[i
] == '\r' || value
[i
] == '\n')
2050 /* skip newlines/linefeeds */
2053 if (value
[i
] != '\r' && value
[i
] != '\n') break;
2059 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
2060 TRACE("(chunk %s)\n", debugstr_w(chars
));
2061 hr
= saxreader_saxcharacters(locator
, chars
);
2062 SysFreeString(chars
);
2071 /* no newline chars (or last chunk) report as a whole */
2072 if (!end
&& start
== value
)
2075 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
2076 TRACE("(%s)\n", debugstr_w(chars
));
2077 hr
= saxreader_saxcharacters(locator
, chars
);
2078 SysFreeString(chars
);
2081 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2083 if (locator
->vbInterface
)
2084 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
2086 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
2090 format_error_message_from_id(locator
, hr
);
2093 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
2095 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
2096 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
2099 /*** IVBSAXLocator interface ***/
2100 /*** IUnknown methods ***/
2101 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2103 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2105 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2109 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2110 IsEqualGUID( riid
, &IID_IDispatch
) ||
2111 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
2115 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
2117 *ppvObject
= &This
->IVBSAXAttributes_iface
;
2121 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2122 return E_NOINTERFACE
;
2125 IVBSAXLocator_AddRef( iface
);
2130 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
2132 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2133 TRACE("%p\n", This
);
2134 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
2137 static ULONG WINAPI
ivbsaxlocator_Release(IVBSAXLocator
* iface
)
2139 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2140 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
2143 /*** IDispatch methods ***/
2144 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
2146 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2148 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2155 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
2156 IVBSAXLocator
*iface
,
2157 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2159 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2161 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2163 return get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2166 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2167 IVBSAXLocator
*iface
,
2169 LPOLESTR
* rgszNames
,
2174 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2175 ITypeInfo
*typeinfo
;
2178 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
2181 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2182 return E_INVALIDARG
;
2184 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2187 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2188 ITypeInfo_Release(typeinfo
);
2194 static HRESULT WINAPI
ivbsaxlocator_Invoke(
2195 IVBSAXLocator
*iface
,
2196 DISPID dispIdMember
,
2200 DISPPARAMS
* pDispParams
,
2201 VARIANT
* pVarResult
,
2202 EXCEPINFO
* pExcepInfo
,
2205 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2206 ITypeInfo
*typeinfo
;
2209 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2210 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2212 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2215 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXLocator_iface
, dispIdMember
, wFlags
,
2216 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2217 ITypeInfo_Release(typeinfo
);
2223 /*** IVBSAXLocator methods ***/
2224 static HRESULT WINAPI
ivbsaxlocator_get_columnNumber(
2225 IVBSAXLocator
* iface
,
2228 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2229 return ISAXLocator_getColumnNumber(&This
->ISAXLocator_iface
, pnColumn
);
2232 static HRESULT WINAPI
ivbsaxlocator_get_lineNumber(
2233 IVBSAXLocator
* iface
,
2236 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2237 return ISAXLocator_getLineNumber(&This
->ISAXLocator_iface
, pnLine
);
2240 static HRESULT WINAPI
ivbsaxlocator_get_publicId(IVBSAXLocator
* iface
, BSTR
*ret
)
2242 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2243 const WCHAR
*publicidW
;
2246 TRACE("(%p)->(%p)\n", This
, ret
);
2252 hr
= ISAXLocator_getPublicId(&This
->ISAXLocator_iface
, &publicidW
);
2256 return return_bstr(publicidW
, ret
);
2259 static HRESULT WINAPI
ivbsaxlocator_get_systemId(IVBSAXLocator
* iface
, BSTR
*ret
)
2261 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2262 const WCHAR
*systemidW
;
2265 TRACE("(%p)->(%p)\n", This
, ret
);
2271 hr
= ISAXLocator_getSystemId(&This
->ISAXLocator_iface
, &systemidW
);
2275 return return_bstr(systemidW
, ret
);
2278 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl
=
2280 ivbsaxlocator_QueryInterface
,
2281 ivbsaxlocator_AddRef
,
2282 ivbsaxlocator_Release
,
2283 ivbsaxlocator_GetTypeInfoCount
,
2284 ivbsaxlocator_GetTypeInfo
,
2285 ivbsaxlocator_GetIDsOfNames
,
2286 ivbsaxlocator_Invoke
,
2287 ivbsaxlocator_get_columnNumber
,
2288 ivbsaxlocator_get_lineNumber
,
2289 ivbsaxlocator_get_publicId
,
2290 ivbsaxlocator_get_systemId
2293 /*** ISAXLocator interface ***/
2294 /*** IUnknown methods ***/
2295 static HRESULT WINAPI
isaxlocator_QueryInterface(ISAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2297 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2299 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2303 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2304 IsEqualGUID( riid
, &IID_ISAXLocator
))
2308 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
2310 *ppvObject
= &This
->ISAXAttributes_iface
;
2314 WARN("interface %s not implemented\n", debugstr_guid(riid
));
2315 return E_NOINTERFACE
;
2318 ISAXLocator_AddRef( iface
);
2323 static ULONG WINAPI
isaxlocator_AddRef(ISAXLocator
* iface
)
2325 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2326 ULONG ref
= InterlockedIncrement( &This
->ref
);
2327 TRACE("(%p)->(%d)\n", This
, ref
);
2331 static ULONG WINAPI
isaxlocator_Release(
2334 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2335 LONG ref
= InterlockedDecrement( &This
->ref
);
2337 TRACE("(%p)->(%d)\n", This
, ref
);
2341 element_entry
*element
, *element2
;
2344 SysFreeString(This
->publicId
);
2345 SysFreeString(This
->systemId
);
2346 SysFreeString(This
->namespaceUri
);
2348 for(index
= 0; index
< This
->attr_alloc_count
; index
++)
2350 SysFreeString(This
->attributes
[index
].szLocalname
);
2351 SysFreeString(This
->attributes
[index
].szValue
);
2352 SysFreeString(This
->attributes
[index
].szQName
);
2354 heap_free(This
->attributes
);
2357 LIST_FOR_EACH_ENTRY_SAFE(element
, element2
, &This
->elements
, element_entry
, entry
)
2359 list_remove(&element
->entry
);
2360 free_element_entry(element
);
2363 ISAXXMLReader_Release(&This
->saxreader
->ISAXXMLReader_iface
);
2370 /*** ISAXLocator methods ***/
2371 static HRESULT WINAPI
isaxlocator_getColumnNumber(
2375 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2377 *pnColumn
= This
->column
;
2381 static HRESULT WINAPI
isaxlocator_getLineNumber(
2385 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2387 *pnLine
= This
->line
;
2391 static HRESULT WINAPI
isaxlocator_getPublicId(
2393 const WCHAR
** ppwchPublicId
)
2396 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2398 SysFreeString(This
->publicId
);
2400 publicId
= bstr_from_xmlChar(xmlSAX2GetPublicId(This
->pParserCtxt
));
2401 if(SysStringLen(publicId
))
2402 This
->publicId
= publicId
;
2405 SysFreeString(publicId
);
2406 This
->publicId
= NULL
;
2409 *ppwchPublicId
= This
->publicId
;
2413 static HRESULT WINAPI
isaxlocator_getSystemId(
2415 const WCHAR
** ppwchSystemId
)
2418 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2420 SysFreeString(This
->systemId
);
2422 systemId
= bstr_from_xmlChar(xmlSAX2GetSystemId(This
->pParserCtxt
));
2423 if(SysStringLen(systemId
))
2424 This
->systemId
= systemId
;
2427 SysFreeString(systemId
);
2428 This
->systemId
= NULL
;
2431 *ppwchSystemId
= This
->systemId
;
2435 static const struct ISAXLocatorVtbl SAXLocatorVtbl
=
2437 isaxlocator_QueryInterface
,
2439 isaxlocator_Release
,
2440 isaxlocator_getColumnNumber
,
2441 isaxlocator_getLineNumber
,
2442 isaxlocator_getPublicId
,
2443 isaxlocator_getSystemId
2446 static HRESULT
SAXLocator_create(saxreader
*reader
, saxlocator
**ppsaxlocator
, BOOL vbInterface
)
2448 static const WCHAR w3xmlns
[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2449 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2451 saxlocator
*locator
;
2453 locator
= heap_alloc( sizeof (*locator
) );
2455 return E_OUTOFMEMORY
;
2457 locator
->IVBSAXLocator_iface
.lpVtbl
= &VBSAXLocatorVtbl
;
2458 locator
->ISAXLocator_iface
.lpVtbl
= &SAXLocatorVtbl
;
2459 locator
->IVBSAXAttributes_iface
.lpVtbl
= &ivbsaxattributes_vtbl
;
2460 locator
->ISAXAttributes_iface
.lpVtbl
= &isaxattributes_vtbl
;
2462 locator
->vbInterface
= vbInterface
;
2464 locator
->saxreader
= reader
;
2465 ISAXXMLReader_AddRef(&reader
->ISAXXMLReader_iface
);
2467 locator
->pParserCtxt
= NULL
;
2468 locator
->publicId
= NULL
;
2469 locator
->systemId
= NULL
;
2470 locator
->line
= reader
->version
< MSXML4
? 0 : 1;
2471 locator
->column
= 0;
2472 locator
->ret
= S_OK
;
2473 if (locator
->saxreader
->version
>= MSXML6
)
2474 locator
->namespaceUri
= SysAllocString(w3xmlns
);
2476 locator
->namespaceUri
= SysAllocStringLen(NULL
, 0);
2477 if(!locator
->namespaceUri
)
2479 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2481 return E_OUTOFMEMORY
;
2484 locator
->attr_alloc_count
= 8;
2485 locator
->attr_count
= 0;
2486 locator
->attributes
= heap_alloc_zero(sizeof(struct _attributes
)*locator
->attr_alloc_count
);
2487 if(!locator
->attributes
)
2489 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2490 SysFreeString(locator
->namespaceUri
);
2492 return E_OUTOFMEMORY
;
2495 list_init(&locator
->elements
);
2497 *ppsaxlocator
= locator
;
2499 TRACE("returning %p\n", *ppsaxlocator
);
2504 /*** SAXXMLReader internal functions ***/
2505 static HRESULT
internal_parseBuffer(saxreader
*This
, const char *buffer
, int size
, BOOL vbInterface
)
2507 xmlCharEncoding encoding
= XML_CHAR_ENCODING_NONE
;
2508 xmlChar
*enc_name
= NULL
;
2509 saxlocator
*locator
;
2512 TRACE("(%p)->(%p %d)\n", This
, buffer
, size
);
2514 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2520 const unsigned char *buff
= (unsigned char*)buffer
;
2522 encoding
= xmlDetectCharEncoding((xmlChar
*)buffer
, 4);
2523 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2524 TRACE("detected encoding: %s\n", enc_name
);
2525 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2526 if ((encoding
== XML_CHAR_ENCODING_UTF8
) &&
2527 buff
[0] == 0xEF && buff
[1] == 0xBB && buff
[2] == 0xBF)
2534 /* if libxml2 detection failed try to guess */
2535 if (encoding
== XML_CHAR_ENCODING_NONE
)
2537 const WCHAR
*ptr
= (WCHAR
*)buffer
;
2538 /* an xml declaration with optional encoding will still be handled by the parser */
2539 if ((size
>= 2) && *ptr
== '<' && ptr
[1] != '?')
2541 enc_name
= (xmlChar
*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE
);
2542 encoding
= XML_CHAR_ENCODING_UTF16LE
;
2545 else if (encoding
== XML_CHAR_ENCODING_UTF8
)
2546 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2550 locator
->pParserCtxt
= xmlCreateMemoryParserCtxt(buffer
, size
);
2551 if (!locator
->pParserCtxt
)
2553 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2559 locator
->pParserCtxt
->encoding
= xmlStrdup(enc_name
);
2560 if (encoding
== XML_CHAR_ENCODING_UTF16LE
) {
2561 TRACE("switching to %s\n", enc_name
);
2562 xmlSwitchEncoding(locator
->pParserCtxt
, encoding
);
2566 xmlFree(locator
->pParserCtxt
->sax
);
2567 locator
->pParserCtxt
->sax
= &locator
->saxreader
->sax
;
2568 locator
->pParserCtxt
->userData
= locator
;
2570 This
->isParsing
= TRUE
;
2571 if(xmlParseDocument(locator
->pParserCtxt
) == -1 && locator
->ret
== S_OK
)
2575 This
->isParsing
= FALSE
;
2577 if(locator
->pParserCtxt
)
2579 locator
->pParserCtxt
->sax
= NULL
;
2580 xmlFreeParserCtxt(locator
->pParserCtxt
);
2581 locator
->pParserCtxt
= NULL
;
2584 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2588 static HRESULT
internal_parseStream(saxreader
*This
, ISequentialStream
*stream
, BOOL vbInterface
)
2590 saxlocator
*locator
;
2597 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2598 if(FAILED(hr
)) return hr
;
2600 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2601 if(FAILED(hr
)) return hr
;
2603 locator
->pParserCtxt
= xmlCreatePushParserCtxt(
2604 &locator
->saxreader
->sax
, locator
,
2605 data
, dataRead
, NULL
);
2606 if(!locator
->pParserCtxt
)
2608 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2612 This
->isParsing
= TRUE
;
2616 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2617 if (FAILED(hr
) || !dataRead
) break;
2619 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, dataRead
, 0);
2620 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2625 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2626 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2630 This
->isParsing
= FALSE
;
2632 xmlFreeParserCtxt(locator
->pParserCtxt
);
2633 locator
->pParserCtxt
= NULL
;
2634 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2638 static HRESULT
internal_parse(
2645 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varInput
));
2647 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2648 free_bstr_pool(&This
->pool
);
2650 switch(V_VT(&varInput
))
2653 case VT_BSTR
|VT_BYREF
:
2655 BSTR str
= V_ISBYREF(&varInput
) ? *V_BSTRREF(&varInput
) : V_BSTR(&varInput
);
2656 hr
= internal_parseBuffer(This
, (const char*)str
, strlenW(str
)*sizeof(WCHAR
), vbInterface
);
2659 case VT_ARRAY
|VT_UI1
: {
2661 LONG lBound
, uBound
;
2664 hr
= SafeArrayGetLBound(V_ARRAY(&varInput
), 1, &lBound
);
2665 if(hr
!= S_OK
) break;
2666 hr
= SafeArrayGetUBound(V_ARRAY(&varInput
), 1, &uBound
);
2667 if(hr
!= S_OK
) break;
2668 dataRead
= (uBound
-lBound
)*SafeArrayGetElemsize(V_ARRAY(&varInput
));
2669 hr
= SafeArrayAccessData(V_ARRAY(&varInput
), &pSAData
);
2670 if(hr
!= S_OK
) break;
2671 hr
= internal_parseBuffer(This
, pSAData
, dataRead
, vbInterface
);
2672 SafeArrayUnaccessData(V_ARRAY(&varInput
));
2677 ISequentialStream
*stream
= NULL
;
2678 IXMLDOMDocument
*xmlDoc
;
2680 if (!V_UNKNOWN(&varInput
))
2681 return E_INVALIDARG
;
2683 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2684 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2688 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2689 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2690 SysStringByteLen(bstrData
), vbInterface
);
2691 IXMLDOMDocument_Release(xmlDoc
);
2692 SysFreeString(bstrData
);
2696 /* try base interface first */
2697 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2699 /* this should never happen if IStream is implemented properly, but just in case */
2700 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2704 hr
= internal_parseStream(This
, stream
, vbInterface
);
2705 ISequentialStream_Release(stream
);
2709 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2716 WARN("vt %d not implemented\n", V_VT(&varInput
));
2723 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2725 saxreader
*This
= obj
;
2727 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2730 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2732 saxreader
*This
= obj
;
2734 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2737 static HRESULT
internal_parseURL(
2746 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
2748 hr
= create_moniker_from_url(url
, &mon
);
2752 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, This
, &bsc
);
2753 else hr
= bind_url(mon
, internal_onDataAvailable
, This
, &bsc
);
2754 IMoniker_Release(mon
);
2759 return detach_bsc(bsc
);
2762 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2766 if (V_VT(v
) == VT_EMPTY
)
2767 return saxreader_put_handler(This
, type
, NULL
, vb
);
2771 case SAXDeclHandler
:
2772 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2774 case SAXLexicalHandler
:
2775 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2778 ERR("wrong handler type %d\n", type
);
2787 IUnknown
*handler
= NULL
;
2791 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2792 if (FAILED(hr
)) return hr
;
2795 saxreader_put_handler(This
, type
, handler
, vb
);
2796 if (handler
) IUnknown_Release(handler
);
2800 ERR("value type %d not supported\n", V_VT(v
));
2801 return E_INVALIDARG
;
2807 static HRESULT
internal_putProperty(
2815 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2817 if (This
->isParsing
) return E_FAIL
;
2819 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2820 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2821 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2823 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2824 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2826 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2828 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2829 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2833 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2835 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2836 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2840 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2842 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2845 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2848 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2851 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2854 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2857 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2860 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2863 return E_INVALIDARG
;
2866 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2868 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2870 if (!value
) return E_POINTER
;
2872 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2874 V_VT(value
) = VT_UNKNOWN
;
2875 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2879 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2881 V_VT(value
) = VT_UNKNOWN
;
2882 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2886 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2888 V_VT(value
) = VT_BSTR
;
2889 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2893 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2898 /*** IVBSAXXMLReader interface ***/
2899 /*** IUnknown methods ***/
2900 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2902 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2904 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2908 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2909 IsEqualGUID( riid
, &IID_IDispatch
) ||
2910 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2914 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2916 *ppvObject
= &This
->ISAXXMLReader_iface
;
2918 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2920 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2924 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2925 return E_NOINTERFACE
;
2928 IVBSAXXMLReader_AddRef( iface
);
2933 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2935 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2936 TRACE("%p\n", This
);
2937 return InterlockedIncrement( &This
->ref
);
2940 static ULONG WINAPI
saxxmlreader_Release(
2941 IVBSAXXMLReader
* iface
)
2943 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2946 TRACE("%p\n", This
);
2948 ref
= InterlockedDecrement( &This
->ref
);
2953 for (i
= 0; i
< SAXHandler_Last
; i
++)
2955 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2957 if (saxiface
->handler
)
2958 IUnknown_Release(saxiface
->handler
);
2960 if (saxiface
->vbhandler
)
2961 IUnknown_Release(saxiface
->vbhandler
);
2964 SysFreeString(This
->xmldecl_version
);
2965 free_bstr_pool(&This
->pool
);
2973 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2975 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2976 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2979 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2980 IVBSAXXMLReader
*iface
,
2981 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2983 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2984 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2985 iTInfo
, lcid
, ppTInfo
);
2988 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2989 IVBSAXXMLReader
*iface
,
2991 LPOLESTR
* rgszNames
,
2996 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2997 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
2998 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
3001 static HRESULT WINAPI
saxxmlreader_Invoke(
3002 IVBSAXXMLReader
*iface
,
3003 DISPID dispIdMember
,
3007 DISPPARAMS
* pDispParams
,
3008 VARIANT
* pVarResult
,
3009 EXCEPINFO
* pExcepInfo
,
3012 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3013 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
3014 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3017 /*** IVBSAXXMLReader methods ***/
3018 static HRESULT WINAPI
saxxmlreader_getFeature(
3019 IVBSAXXMLReader
* iface
,
3021 VARIANT_BOOL
*value
)
3023 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3024 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3027 static HRESULT WINAPI
saxxmlreader_putFeature(
3028 IVBSAXXMLReader
* iface
,
3032 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3033 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3036 static HRESULT WINAPI
saxxmlreader_getProperty(
3037 IVBSAXXMLReader
* iface
,
3041 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3042 return internal_getProperty(This
, prop
, value
, TRUE
);
3045 static HRESULT WINAPI
saxxmlreader_putProperty(
3046 IVBSAXXMLReader
* iface
,
3050 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3051 return internal_putProperty(This
, pProp
, value
, TRUE
);
3054 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3055 IVBSAXXMLReader
* iface
,
3056 IVBSAXEntityResolver
**resolver
)
3058 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3059 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3062 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3063 IVBSAXXMLReader
* iface
,
3064 IVBSAXEntityResolver
*resolver
)
3066 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3067 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3070 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3071 IVBSAXXMLReader
* iface
,
3072 IVBSAXContentHandler
**handler
)
3074 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3075 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3078 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3079 IVBSAXXMLReader
* iface
,
3080 IVBSAXContentHandler
*handler
)
3082 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3083 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3086 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3087 IVBSAXXMLReader
* iface
,
3088 IVBSAXDTDHandler
**handler
)
3090 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3091 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3094 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3095 IVBSAXXMLReader
* iface
,
3096 IVBSAXDTDHandler
*handler
)
3098 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3099 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3102 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3103 IVBSAXXMLReader
* iface
,
3104 IVBSAXErrorHandler
**handler
)
3106 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3107 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3110 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3111 IVBSAXXMLReader
* iface
,
3112 IVBSAXErrorHandler
*handler
)
3114 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3115 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3118 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3119 IVBSAXXMLReader
* iface
,
3122 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3124 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3128 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3129 IVBSAXXMLReader
* iface
,
3132 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3133 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3136 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3137 IVBSAXXMLReader
* iface
,
3138 BSTR
*pSecureBaseUrl
)
3140 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3142 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3146 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3147 IVBSAXXMLReader
* iface
,
3150 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3151 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3154 static HRESULT WINAPI
saxxmlreader_parse(
3155 IVBSAXXMLReader
* iface
,
3158 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3159 return internal_parse(This
, varInput
, TRUE
);
3162 static HRESULT WINAPI
saxxmlreader_parseURL(
3163 IVBSAXXMLReader
* iface
,
3166 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3167 return internal_parseURL(This
, url
, TRUE
);
3170 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3172 saxxmlreader_QueryInterface
,
3173 saxxmlreader_AddRef
,
3174 saxxmlreader_Release
,
3175 saxxmlreader_GetTypeInfoCount
,
3176 saxxmlreader_GetTypeInfo
,
3177 saxxmlreader_GetIDsOfNames
,
3178 saxxmlreader_Invoke
,
3179 saxxmlreader_getFeature
,
3180 saxxmlreader_putFeature
,
3181 saxxmlreader_getProperty
,
3182 saxxmlreader_putProperty
,
3183 saxxmlreader_get_entityResolver
,
3184 saxxmlreader_put_entityResolver
,
3185 saxxmlreader_get_contentHandler
,
3186 saxxmlreader_put_contentHandler
,
3187 saxxmlreader_get_dtdHandler
,
3188 saxxmlreader_put_dtdHandler
,
3189 saxxmlreader_get_errorHandler
,
3190 saxxmlreader_put_errorHandler
,
3191 saxxmlreader_get_baseURL
,
3192 saxxmlreader_put_baseURL
,
3193 saxxmlreader_get_secureBaseURL
,
3194 saxxmlreader_put_secureBaseURL
,
3196 saxxmlreader_parseURL
3199 /*** ISAXXMLReader interface ***/
3200 /*** IUnknown methods ***/
3201 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3203 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3204 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3207 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3209 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3210 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3213 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3215 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3216 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3219 /*** ISAXXMLReader methods ***/
3220 static HRESULT WINAPI
isaxxmlreader_getFeature(
3221 ISAXXMLReader
* iface
,
3222 const WCHAR
*feature_name
,
3223 VARIANT_BOOL
*value
)
3225 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3226 saxreader_feature feature
;
3228 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3230 feature
= get_saxreader_feature(feature_name
);
3232 if (This
->version
< MSXML4
&& (feature
== ExhaustiveErrors
|| feature
== SchemaValidation
))
3233 return E_INVALIDARG
;
3235 if (feature
== Namespaces
||
3236 feature
== NamespacePrefixes
||
3237 feature
== ExhaustiveErrors
||
3238 feature
== SchemaValidation
)
3239 return get_feature_value(This
, feature
, value
);
3241 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3245 static HRESULT WINAPI
isaxxmlreader_putFeature(
3246 ISAXXMLReader
* iface
,
3247 const WCHAR
*feature_name
,
3250 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3251 saxreader_feature feature
;
3253 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3255 feature
= get_saxreader_feature(feature_name
);
3257 /* accepted cases */
3258 if ((feature
== ExhaustiveErrors
&& value
== VARIANT_FALSE
) ||
3259 (feature
== SchemaValidation
&& value
== VARIANT_FALSE
) ||
3260 feature
== Namespaces
||
3261 feature
== NamespacePrefixes
)
3263 return set_feature_value(This
, feature
, value
);
3266 if (feature
== LexicalHandlerParEntities
||
3267 feature
== ProhibitDTD
||
3268 feature
== ExternalGeneralEntities
||
3269 feature
== ExternalParameterEntities
)
3271 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3272 return set_feature_value(This
, feature
, value
);
3275 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3279 static HRESULT WINAPI
isaxxmlreader_getProperty(
3280 ISAXXMLReader
* iface
,
3284 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3285 return internal_getProperty(This
, prop
, value
, FALSE
);
3288 static HRESULT WINAPI
isaxxmlreader_putProperty(
3289 ISAXXMLReader
* iface
,
3293 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3294 return internal_putProperty(This
, pProp
, value
, FALSE
);
3297 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3298 ISAXXMLReader
* iface
,
3299 ISAXEntityResolver
**resolver
)
3301 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3302 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3305 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3306 ISAXXMLReader
* iface
,
3307 ISAXEntityResolver
*resolver
)
3309 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3310 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3313 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3314 ISAXXMLReader
* iface
,
3315 ISAXContentHandler
**handler
)
3317 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3318 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3321 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3322 ISAXXMLReader
* iface
,
3323 ISAXContentHandler
*handler
)
3325 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3326 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3329 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3330 ISAXXMLReader
* iface
,
3331 ISAXDTDHandler
**handler
)
3333 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3334 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3337 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3338 ISAXXMLReader
* iface
,
3339 ISAXDTDHandler
*handler
)
3341 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3342 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3345 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3346 ISAXXMLReader
* iface
,
3347 ISAXErrorHandler
**handler
)
3349 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3350 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3353 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3355 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3356 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3359 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3360 ISAXXMLReader
* iface
,
3361 const WCHAR
**base_url
)
3363 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3365 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3369 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3370 ISAXXMLReader
* iface
,
3371 const WCHAR
*pBaseUrl
)
3373 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3375 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3379 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3380 ISAXXMLReader
* iface
,
3381 const WCHAR
**pSecureBaseUrl
)
3383 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3384 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3388 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3389 ISAXXMLReader
* iface
,
3390 const WCHAR
*secureBaseUrl
)
3392 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3394 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3398 static HRESULT WINAPI
isaxxmlreader_parse(
3399 ISAXXMLReader
* iface
,
3402 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3403 return internal_parse(This
, varInput
, FALSE
);
3406 static HRESULT WINAPI
isaxxmlreader_parseURL(
3407 ISAXXMLReader
* iface
,
3410 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3411 return internal_parseURL(This
, url
, FALSE
);
3414 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3416 isaxxmlreader_QueryInterface
,
3417 isaxxmlreader_AddRef
,
3418 isaxxmlreader_Release
,
3419 isaxxmlreader_getFeature
,
3420 isaxxmlreader_putFeature
,
3421 isaxxmlreader_getProperty
,
3422 isaxxmlreader_putProperty
,
3423 isaxxmlreader_getEntityResolver
,
3424 isaxxmlreader_putEntityResolver
,
3425 isaxxmlreader_getContentHandler
,
3426 isaxxmlreader_putContentHandler
,
3427 isaxxmlreader_getDTDHandler
,
3428 isaxxmlreader_putDTDHandler
,
3429 isaxxmlreader_getErrorHandler
,
3430 isaxxmlreader_putErrorHandler
,
3431 isaxxmlreader_getBaseURL
,
3432 isaxxmlreader_putBaseURL
,
3433 isaxxmlreader_getSecureBaseURL
,
3434 isaxxmlreader_putSecureBaseURL
,
3435 isaxxmlreader_parse
,
3436 isaxxmlreader_parseURL
3439 static const tid_t saxreader_iface_tids
[] = {
3440 IVBSAXXMLReader_tid
,
3443 static dispex_static_data_t saxreader_dispex
= {
3445 IVBSAXXMLReader_tid
,
3447 saxreader_iface_tids
3450 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3454 TRACE("(%p)\n", ppObj
);
3456 reader
= heap_alloc( sizeof (*reader
) );
3458 return E_OUTOFMEMORY
;
3460 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3461 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3463 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3464 reader
->isParsing
= FALSE
;
3465 reader
->xmldecl_version
= NULL
;
3466 reader
->pool
.pool
= NULL
;
3467 reader
->pool
.index
= 0;
3468 reader
->pool
.len
= 0;
3469 reader
->features
= Namespaces
| NamespacePrefixes
;
3470 reader
->version
= version
;
3472 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3474 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3475 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3476 reader
->sax
.startDocument
= libxmlStartDocument
;
3477 reader
->sax
.endDocument
= libxmlEndDocument
;
3478 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3479 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3480 reader
->sax
.characters
= libxmlCharacters
;
3481 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3482 reader
->sax
.comment
= libxmlComment
;
3483 reader
->sax
.error
= libxmlFatalError
;
3484 reader
->sax
.fatalError
= libxmlFatalError
;
3485 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3486 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3488 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3490 TRACE("returning iface %p\n", *ppObj
);
3497 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3499 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3500 "libxml2 support was not present at compile time.\n");