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
;
171 ns
*ns
; /* namespaces defined in this particular element */
177 SAXContentHandler
= 0,
186 struct saxanyhandler_iface
192 struct saxcontenthandler_iface
194 ISAXContentHandler
*handler
;
195 IVBSAXContentHandler
*vbhandler
;
198 struct saxerrorhandler_iface
200 ISAXErrorHandler
*handler
;
201 IVBSAXErrorHandler
*vbhandler
;
204 struct saxlexicalhandler_iface
206 ISAXLexicalHandler
*handler
;
207 IVBSAXLexicalHandler
*vbhandler
;
210 struct saxentityresolver_iface
212 ISAXEntityResolver
*handler
;
213 IVBSAXEntityResolver
*vbhandler
;
216 struct saxhandler_iface
219 struct saxcontenthandler_iface content
;
220 struct saxentityresolver_iface entityresolver
;
221 struct saxerrorhandler_iface error
;
222 struct saxlexicalhandler_iface lexical
;
223 struct saxanyhandler_iface anyhandler
;
230 IVBSAXXMLReader IVBSAXXMLReader_iface
;
231 ISAXXMLReader ISAXXMLReader_iface
;
234 struct saxhandler_iface saxhandlers
[SAXHandler_Last
];
237 struct bstrpool pool
;
238 saxreader_feature features
;
239 BSTR xmldecl_version
;
240 MSXML_VERSION version
;
243 static HRESULT
saxreader_put_handler(saxreader
*reader
, enum saxhandler_type type
, void *ptr
, BOOL vb
)
245 struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
246 IUnknown
*unk
= (IUnknown
*)ptr
;
249 IUnknown_AddRef(unk
);
251 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
252 IUnknown_Release(vb
? iface
->vbhandler
: iface
->handler
);
255 iface
->vbhandler
= unk
;
257 iface
->handler
= unk
;
262 static HRESULT
saxreader_get_handler(const saxreader
*reader
, enum saxhandler_type type
, BOOL vb
, void **ret
)
264 const struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
266 if (!ret
) return E_POINTER
;
268 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
271 IUnknown_AddRef(iface
->vbhandler
);
273 IUnknown_AddRef(iface
->handler
);
276 *ret
= vb
? iface
->vbhandler
: iface
->handler
;
281 static struct saxcontenthandler_iface
*saxreader_get_contenthandler(saxreader
*reader
)
283 return &reader
->saxhandlers
[SAXContentHandler
].u
.content
;
286 static struct saxerrorhandler_iface
*saxreader_get_errorhandler(saxreader
*reader
)
288 return &reader
->saxhandlers
[SAXErrorHandler
].u
.error
;
291 static struct saxlexicalhandler_iface
*saxreader_get_lexicalhandler(saxreader
*reader
)
293 return &reader
->saxhandlers
[SAXLexicalHandler
].u
.lexical
;
298 IVBSAXLocator IVBSAXLocator_iface
;
299 ISAXLocator ISAXLocator_iface
;
300 IVBSAXAttributes IVBSAXAttributes_iface
;
301 ISAXAttributes ISAXAttributes_iface
;
303 saxreader
*saxreader
;
305 xmlParserCtxtPtr pParserCtxt
;
311 struct list elements
;
314 int attr_alloc_count
;
325 static inline saxreader
*impl_from_IVBSAXXMLReader( IVBSAXXMLReader
*iface
)
327 return CONTAINING_RECORD(iface
, saxreader
, IVBSAXXMLReader_iface
);
330 static inline saxreader
*impl_from_ISAXXMLReader( ISAXXMLReader
*iface
)
332 return CONTAINING_RECORD(iface
, saxreader
, ISAXXMLReader_iface
);
335 static inline saxlocator
*impl_from_IVBSAXLocator( IVBSAXLocator
*iface
)
337 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXLocator_iface
);
340 static inline saxlocator
*impl_from_ISAXLocator( ISAXLocator
*iface
)
342 return CONTAINING_RECORD(iface
, saxlocator
, ISAXLocator_iface
);
345 static inline saxlocator
*impl_from_IVBSAXAttributes( IVBSAXAttributes
*iface
)
347 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXAttributes_iface
);
350 static inline saxlocator
*impl_from_ISAXAttributes( ISAXAttributes
*iface
)
352 return CONTAINING_RECORD(iface
, saxlocator
, ISAXAttributes_iface
);
355 static inline BOOL
saxreader_has_handler(const saxlocator
*locator
, enum saxhandler_type type
)
357 struct saxanyhandler_iface
*iface
= &locator
->saxreader
->saxhandlers
[type
].u
.anyhandler
;
358 return (locator
->vbInterface
&& iface
->vbhandler
) || (!locator
->vbInterface
&& iface
->handler
);
361 static HRESULT
saxreader_saxcharacters(saxlocator
*locator
, BSTR chars
)
363 struct saxcontenthandler_iface
*content
= saxreader_get_contenthandler(locator
->saxreader
);
366 if (!saxreader_has_handler(locator
, SAXContentHandler
)) return S_OK
;
368 if (locator
->vbInterface
)
369 hr
= IVBSAXContentHandler_characters(content
->vbhandler
, &chars
);
371 hr
= ISAXContentHandler_characters(content
->handler
, chars
, SysStringLen(chars
));
377 static const WCHAR PropertyCharsetW
[] = {
378 'c','h','a','r','s','e','t',0
380 static const WCHAR PropertyXmlDeclVersionW
[] = {
381 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
383 static const WCHAR PropertyDeclHandlerW
[] = {
384 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
385 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
386 'd','e','c','l','a','r','a','t','i','o','n',
387 '-','h','a','n','d','l','e','r',0
389 static const WCHAR PropertyDomNodeW
[] = {
390 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
391 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
392 'd','o','m','-','n','o','d','e',0
394 static const WCHAR PropertyInputSourceW
[] = {
395 'i','n','p','u','t','-','s','o','u','r','c','e',0
397 static const WCHAR PropertyLexicalHandlerW
[] = {
398 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
399 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
400 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
402 static const WCHAR PropertyMaxElementDepthW
[] = {
403 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
405 static const WCHAR PropertyMaxXMLSizeW
[] = {
406 'm','a','x','-','x','m','l','-','s','i','z','e',0
408 static const WCHAR PropertySchemaDeclHandlerW
[] = {
409 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
410 'h','a','n','d','l','e','r',0
412 static const WCHAR PropertyXMLDeclEncodingW
[] = {
413 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
415 static const WCHAR PropertyXMLDeclStandaloneW
[] = {
416 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
418 static const WCHAR PropertyXMLDeclVersionW
[] = {
419 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
422 static inline HRESULT
set_feature_value(saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL value
)
424 /* handling of non-VARIANT_* values is version dependent */
425 if ((reader
->version
< MSXML4
) && (value
!= VARIANT_TRUE
))
426 value
= VARIANT_FALSE
;
427 if ((reader
->version
>= MSXML4
) && (value
!= VARIANT_FALSE
))
428 value
= VARIANT_TRUE
;
430 if (value
== VARIANT_TRUE
)
431 reader
->features
|= feature
;
433 reader
->features
&= ~feature
;
438 static inline HRESULT
get_feature_value(const saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL
*value
)
440 *value
= reader
->features
& feature
? VARIANT_TRUE
: VARIANT_FALSE
;
444 static BOOL
is_namespaces_enabled(const saxreader
*reader
)
446 return (reader
->version
< MSXML4
) || (reader
->features
& Namespaces
);
449 static BSTR
build_qname(BSTR prefix
, BSTR local
)
451 if (prefix
&& *prefix
)
453 BSTR qname
= SysAllocStringLen(NULL
, SysStringLen(prefix
) + SysStringLen(local
) + 1);
457 strcpyW(ptr
, prefix
);
458 ptr
+= SysStringLen(prefix
);
464 return SysAllocString(local
);
467 static element_entry
* alloc_element_entry(const xmlChar
*local
, const xmlChar
*prefix
, int nb_ns
,
468 const xmlChar
**namespaces
)
473 ret
= heap_alloc(sizeof(*ret
));
474 if (!ret
) return ret
;
476 ret
->local
= bstr_from_xmlChar(local
);
477 ret
->prefix
= bstr_from_xmlChar(prefix
);
478 ret
->qname
= build_qname(ret
->prefix
, ret
->local
);
479 ret
->ns
= nb_ns
? heap_alloc(nb_ns
*sizeof(ns
)) : NULL
;
480 ret
->ns_count
= nb_ns
;
482 for (i
=0; i
< nb_ns
; i
++)
484 ret
->ns
[i
].prefix
= bstr_from_xmlChar(namespaces
[2*i
]);
485 ret
->ns
[i
].uri
= bstr_from_xmlChar(namespaces
[2*i
+1]);
491 static void free_element_entry(element_entry
*element
)
495 for (i
=0; i
<element
->ns_count
;i
++)
497 SysFreeString(element
->ns
[i
].prefix
);
498 SysFreeString(element
->ns
[i
].uri
);
501 SysFreeString(element
->prefix
);
502 SysFreeString(element
->local
);
503 SysFreeString(element
->qname
);
505 heap_free(element
->ns
);
509 static void push_element_ns(saxlocator
*locator
, element_entry
*element
)
511 list_add_head(&locator
->elements
, &element
->entry
);
514 static element_entry
* pop_element_ns(saxlocator
*locator
)
516 element_entry
*element
= LIST_ENTRY(list_head(&locator
->elements
), element_entry
, entry
);
519 list_remove(&element
->entry
);
524 static BSTR
find_element_uri(saxlocator
*locator
, const xmlChar
*uri
)
526 element_entry
*element
;
530 if (!uri
) return NULL
;
532 uriW
= bstr_from_xmlChar(uri
);
534 LIST_FOR_EACH_ENTRY(element
, &locator
->elements
, element_entry
, entry
)
536 for (i
=0; i
< element
->ns_count
; i
++)
537 if (!strcmpW(uriW
, element
->ns
[i
].uri
))
540 return element
->ns
[i
].uri
;
545 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri
));
549 /* used to localize version dependent error check behaviour */
550 static inline BOOL
sax_callback_failed(saxlocator
*This
, HRESULT hr
)
552 return This
->saxreader
->version
>= MSXML4
? FAILED(hr
) : hr
!= S_OK
;
555 /* index value -1 means it tries to loop for a first time */
556 static inline BOOL
iterate_endprefix_index(saxlocator
*This
, const element_entry
*element
, int *i
)
558 if (This
->saxreader
->version
>= MSXML4
)
560 if (*i
== -1) *i
= 0; else ++*i
;
561 return *i
< element
->ns_count
;
565 if (*i
== -1) *i
= element
->ns_count
-1; else --*i
;
570 static BOOL
bstr_pool_insert(struct bstrpool
*pool
, BSTR pool_entry
)
574 pool
->pool
= heap_alloc(16 * sizeof(*pool
->pool
));
581 else if (pool
->index
== pool
->len
)
583 BSTR
*realloc
= heap_realloc(pool
->pool
, pool
->len
* 2 * sizeof(*realloc
));
588 pool
->pool
= realloc
;
592 pool
->pool
[pool
->index
++] = pool_entry
;
596 static void free_bstr_pool(struct bstrpool
*pool
)
600 for (i
= 0; i
< pool
->index
; i
++)
601 SysFreeString(pool
->pool
[i
]);
603 heap_free(pool
->pool
);
606 pool
->index
= pool
->len
= 0;
609 static BSTR
bstr_from_xmlCharN(const xmlChar
*buf
, int len
)
617 dLen
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
618 if(len
!= -1) dLen
++;
619 bstr
= SysAllocStringLen(NULL
, dLen
-1);
622 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, bstr
, dLen
);
623 if(len
!= -1) bstr
[dLen
-1] = '\0';
628 static BSTR
QName_from_xmlChar(const xmlChar
*prefix
, const xmlChar
*name
)
633 if(!name
) return NULL
;
635 if(!prefix
|| !*prefix
)
636 return bstr_from_xmlChar(name
);
638 qname
= xmlBuildQName(name
, prefix
, NULL
, 0);
639 bstr
= bstr_from_xmlChar(qname
);
645 static BSTR
pooled_bstr_from_xmlChar(struct bstrpool
*pool
, const xmlChar
*buf
)
647 BSTR pool_entry
= bstr_from_xmlChar(buf
);
649 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
651 SysFreeString(pool_entry
);
658 static BSTR
pooled_bstr_from_xmlCharN(struct bstrpool
*pool
, const xmlChar
*buf
, int len
)
660 BSTR pool_entry
= bstr_from_xmlCharN(buf
, len
);
662 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
664 SysFreeString(pool_entry
);
671 static void format_error_message_from_id(saxlocator
*This
, HRESULT hr
)
673 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
674 xmlStopParser(This
->pParserCtxt
);
677 if (saxreader_has_handler(This
, SAXErrorHandler
))
680 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
,
681 NULL
, hr
, 0, msg
, ARRAY_SIZE(msg
), NULL
))
683 FIXME("MSXML errors not yet supported.\n");
687 if(This
->vbInterface
)
689 BSTR bstrMsg
= SysAllocString(msg
);
690 IVBSAXErrorHandler_fatalError(handler
->vbhandler
,
691 &This
->IVBSAXLocator_iface
, &bstrMsg
, hr
);
692 SysFreeString(bstrMsg
);
695 ISAXErrorHandler_fatalError(handler
->handler
,
696 &This
->ISAXLocator_iface
, msg
, hr
);
700 static void update_position(saxlocator
*This
, BOOL fix_column
)
702 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
703 const xmlChar
*baseP
= This
->pParserCtxt
->input
->base
;
705 This
->line
= xmlSAX2GetLineNumber(This
->pParserCtxt
);
709 for(;p
>=baseP
&& *p
!='\n' && *p
!='\r'; p
--)
714 This
->column
= xmlSAX2GetColumnNumber(This
->pParserCtxt
);
718 /*** IVBSAXAttributes interface ***/
719 static HRESULT WINAPI
ivbsaxattributes_QueryInterface(
720 IVBSAXAttributes
* iface
,
724 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
725 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
726 return IVBSAXLocator_QueryInterface(&This
->IVBSAXLocator_iface
, riid
, ppvObject
);
729 static ULONG WINAPI
ivbsaxattributes_AddRef(IVBSAXAttributes
* iface
)
731 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
732 return IVBSAXLocator_AddRef(&This
->IVBSAXLocator_iface
);
735 static ULONG WINAPI
ivbsaxattributes_Release(IVBSAXAttributes
* iface
)
737 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
738 return IVBSAXLocator_Release(&This
->IVBSAXLocator_iface
);
741 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes
*iface
, UINT
* pctinfo
)
743 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
745 TRACE("(%p)->(%p)\n", This
, pctinfo
);
752 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfo(
753 IVBSAXAttributes
*iface
,
754 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
756 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
758 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
760 return get_typeinfo(IVBSAXAttributes_tid
, ppTInfo
);
763 static HRESULT WINAPI
ivbsaxattributes_GetIDsOfNames(
764 IVBSAXAttributes
*iface
,
771 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
775 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
778 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
781 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
784 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
785 ITypeInfo_Release(typeinfo
);
791 static HRESULT WINAPI
ivbsaxattributes_Invoke(
792 IVBSAXAttributes
*iface
,
797 DISPPARAMS
* pDispParams
,
799 EXCEPINFO
* pExcepInfo
,
802 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
806 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
807 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
809 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
812 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXAttributes_iface
, dispIdMember
, wFlags
,
813 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
814 ITypeInfo_Release(typeinfo
);
820 /*** IVBSAXAttributes methods ***/
821 static HRESULT WINAPI
ivbsaxattributes_get_length(
822 IVBSAXAttributes
* iface
,
825 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
826 return ISAXAttributes_getLength(&This
->ISAXAttributes_iface
, nLength
);
829 static HRESULT WINAPI
ivbsaxattributes_getURI(
830 IVBSAXAttributes
* iface
,
834 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
839 TRACE("(%p)->(%d %p)\n", This
, nIndex
, uri
);
845 hr
= ISAXAttributes_getURI(&This
->ISAXAttributes_iface
, nIndex
, &uriW
, &len
);
849 return return_bstrn(uriW
, len
, uri
);
852 static HRESULT WINAPI
ivbsaxattributes_getLocalName(
853 IVBSAXAttributes
* iface
,
857 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
862 TRACE("(%p)->(%d %p)\n", This
, nIndex
, name
);
868 hr
= ISAXAttributes_getLocalName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
872 return return_bstrn(nameW
, len
, name
);
875 static HRESULT WINAPI
ivbsaxattributes_getQName(
876 IVBSAXAttributes
* iface
,
880 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
885 TRACE("(%p)->(%d %p)\n", This
, nIndex
, QName
);
891 hr
= ISAXAttributes_getQName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
895 return return_bstrn(nameW
, len
, QName
);
898 static HRESULT WINAPI
ivbsaxattributes_getIndexFromName(
899 IVBSAXAttributes
* iface
,
904 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
905 return ISAXAttributes_getIndexFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
906 localName
, SysStringLen(localName
), index
);
909 static HRESULT WINAPI
ivbsaxattributes_getIndexFromQName(
910 IVBSAXAttributes
* iface
,
914 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
915 return ISAXAttributes_getIndexFromQName(&This
->ISAXAttributes_iface
, QName
,
916 SysStringLen(QName
), index
);
919 static HRESULT WINAPI
ivbsaxattributes_getType(
920 IVBSAXAttributes
* iface
,
924 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
929 TRACE("(%p)->(%d %p)\n", This
, nIndex
, type
);
935 hr
= ISAXAttributes_getType(&This
->ISAXAttributes_iface
, nIndex
, &typeW
, &len
);
939 return return_bstrn(typeW
, len
, type
);
942 static HRESULT WINAPI
ivbsaxattributes_getTypeFromName(
943 IVBSAXAttributes
* iface
,
948 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
953 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), type
);
959 hr
= ISAXAttributes_getTypeFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
960 localName
, SysStringLen(localName
), &typeW
, &len
);
964 return return_bstrn(typeW
, len
, type
);
967 static HRESULT WINAPI
ivbsaxattributes_getTypeFromQName(
968 IVBSAXAttributes
* iface
,
972 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
977 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), type
);
983 hr
= ISAXAttributes_getTypeFromQName(&This
->ISAXAttributes_iface
, QName
, SysStringLen(QName
),
988 return return_bstrn(typeW
, len
, type
);
991 static HRESULT WINAPI
ivbsaxattributes_getValue(
992 IVBSAXAttributes
* iface
,
996 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1001 TRACE("(%p)->(%d %p)\n", This
, nIndex
, value
);
1007 hr
= ISAXAttributes_getValue(&This
->ISAXAttributes_iface
, nIndex
, &valueW
, &len
);
1011 return return_bstrn(valueW
, len
, value
);
1014 static HRESULT WINAPI
ivbsaxattributes_getValueFromName(
1015 IVBSAXAttributes
* iface
,
1020 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1021 const WCHAR
*valueW
;
1025 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), value
);
1031 hr
= ISAXAttributes_getValueFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
1032 localName
, SysStringLen(localName
), &valueW
, &len
);
1036 return return_bstrn(valueW
, len
, value
);
1039 static HRESULT WINAPI
ivbsaxattributes_getValueFromQName(
1040 IVBSAXAttributes
* iface
,
1044 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1045 const WCHAR
*valueW
;
1049 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), value
);
1055 hr
= ISAXAttributes_getValueFromQName(&This
->ISAXAttributes_iface
, QName
,
1056 SysStringLen(QName
), &valueW
, &len
);
1060 return return_bstrn(valueW
, len
, value
);
1063 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl
=
1065 ivbsaxattributes_QueryInterface
,
1066 ivbsaxattributes_AddRef
,
1067 ivbsaxattributes_Release
,
1068 ivbsaxattributes_GetTypeInfoCount
,
1069 ivbsaxattributes_GetTypeInfo
,
1070 ivbsaxattributes_GetIDsOfNames
,
1071 ivbsaxattributes_Invoke
,
1072 ivbsaxattributes_get_length
,
1073 ivbsaxattributes_getURI
,
1074 ivbsaxattributes_getLocalName
,
1075 ivbsaxattributes_getQName
,
1076 ivbsaxattributes_getIndexFromName
,
1077 ivbsaxattributes_getIndexFromQName
,
1078 ivbsaxattributes_getType
,
1079 ivbsaxattributes_getTypeFromName
,
1080 ivbsaxattributes_getTypeFromQName
,
1081 ivbsaxattributes_getValue
,
1082 ivbsaxattributes_getValueFromName
,
1083 ivbsaxattributes_getValueFromQName
1086 /*** ISAXAttributes interface ***/
1087 /*** IUnknown methods ***/
1088 static HRESULT WINAPI
isaxattributes_QueryInterface(
1089 ISAXAttributes
* iface
,
1093 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1094 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
1095 return ISAXLocator_QueryInterface(&This
->ISAXLocator_iface
, riid
, ppvObject
);
1098 static ULONG WINAPI
isaxattributes_AddRef(ISAXAttributes
* iface
)
1100 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1101 TRACE("%p\n", This
);
1102 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
1105 static ULONG WINAPI
isaxattributes_Release(ISAXAttributes
* iface
)
1107 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1109 TRACE("%p\n", This
);
1110 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
1113 /*** ISAXAttributes methods ***/
1114 static HRESULT WINAPI
isaxattributes_getLength(
1115 ISAXAttributes
* iface
,
1118 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1120 *length
= This
->attr_count
;
1121 TRACE("Length set to %d\n", *length
);
1125 static inline BOOL
is_valid_attr_index(const saxlocator
*locator
, int index
)
1127 return index
< locator
->attr_count
&& index
>= 0;
1130 static HRESULT WINAPI
isaxattributes_getURI(
1131 ISAXAttributes
* iface
,
1136 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1137 TRACE("(%p)->(%d)\n", This
, index
);
1139 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1140 if(!url
|| !size
) return E_POINTER
;
1142 *size
= SysStringLen(This
->attributes
[index
].szURI
);
1143 *url
= This
->attributes
[index
].szURI
;
1145 TRACE("(%s:%d)\n", debugstr_w(This
->attributes
[index
].szURI
), *size
);
1150 static HRESULT WINAPI
isaxattributes_getLocalName(
1151 ISAXAttributes
* iface
,
1153 const WCHAR
**pLocalName
,
1154 int *pLocalNameLength
)
1156 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1157 TRACE("(%p)->(%d)\n", This
, index
);
1159 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1160 if(!pLocalName
|| !pLocalNameLength
) return E_POINTER
;
1162 *pLocalNameLength
= SysStringLen(This
->attributes
[index
].szLocalname
);
1163 *pLocalName
= This
->attributes
[index
].szLocalname
;
1168 static HRESULT WINAPI
isaxattributes_getQName(
1169 ISAXAttributes
* iface
,
1171 const WCHAR
**pQName
,
1174 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1175 TRACE("(%p)->(%d)\n", This
, index
);
1177 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1178 if(!pQName
|| !pQNameLength
) return E_POINTER
;
1180 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1181 *pQName
= This
->attributes
[index
].szQName
;
1186 static HRESULT WINAPI
isaxattributes_getName(
1187 ISAXAttributes
* iface
,
1191 const WCHAR
**localName
,
1192 int *pLocalNameSize
,
1193 const WCHAR
**QName
,
1196 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1197 TRACE("(%p)->(%d)\n", This
, index
);
1199 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1200 if(!uri
|| !pUriLength
|| !localName
|| !pLocalNameSize
1201 || !QName
|| !pQNameLength
) return E_POINTER
;
1203 *pUriLength
= SysStringLen(This
->attributes
[index
].szURI
);
1204 *uri
= This
->attributes
[index
].szURI
;
1205 *pLocalNameSize
= SysStringLen(This
->attributes
[index
].szLocalname
);
1206 *localName
= This
->attributes
[index
].szLocalname
;
1207 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1208 *QName
= This
->attributes
[index
].szQName
;
1210 TRACE("(%s, %s, %s)\n", debugstr_w(*uri
), debugstr_w(*localName
), debugstr_w(*QName
));
1215 static HRESULT WINAPI
isaxattributes_getIndexFromName(
1216 ISAXAttributes
* iface
,
1219 const WCHAR
*pLocalName
,
1220 int cocalNameLength
,
1223 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1225 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), cUriLength
,
1226 debugstr_w(pLocalName
), cocalNameLength
);
1228 if(!pUri
|| !pLocalName
|| !index
) return E_POINTER
;
1230 for(i
=0; i
<This
->attr_count
; i
++)
1232 if(cUriLength
!=SysStringLen(This
->attributes
[i
].szURI
)
1233 || cocalNameLength
!=SysStringLen(This
->attributes
[i
].szLocalname
))
1235 if(cUriLength
&& memcmp(pUri
, This
->attributes
[i
].szURI
,
1236 sizeof(WCHAR
)*cUriLength
))
1238 if(cocalNameLength
&& memcmp(pLocalName
, This
->attributes
[i
].szLocalname
,
1239 sizeof(WCHAR
)*cocalNameLength
))
1246 return E_INVALIDARG
;
1249 static HRESULT WINAPI
isaxattributes_getIndexFromQName(
1250 ISAXAttributes
* iface
,
1251 const WCHAR
*pQName
,
1255 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1257 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQNameLength
);
1259 if(!pQName
|| !index
) return E_POINTER
;
1260 if(!nQNameLength
) return E_INVALIDARG
;
1262 for(i
=0; i
<This
->attr_count
; i
++)
1264 if(nQNameLength
!=SysStringLen(This
->attributes
[i
].szQName
)) continue;
1265 if(memcmp(pQName
, This
->attributes
[i
].szQName
, sizeof(WCHAR
)*nQNameLength
)) continue;
1271 return E_INVALIDARG
;
1274 static HRESULT WINAPI
isaxattributes_getType(
1275 ISAXAttributes
* iface
,
1277 const WCHAR
**pType
,
1280 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1282 FIXME("(%p)->(%d) stub\n", This
, nIndex
);
1286 static HRESULT WINAPI
isaxattributes_getTypeFromName(
1287 ISAXAttributes
* iface
,
1290 const WCHAR
*pLocalName
,
1292 const WCHAR
**pType
,
1295 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1297 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This
, debugstr_w(pUri
), nUri
,
1298 debugstr_w(pLocalName
), nLocalName
);
1302 static HRESULT WINAPI
isaxattributes_getTypeFromQName(
1303 ISAXAttributes
* iface
,
1304 const WCHAR
*pQName
,
1306 const WCHAR
**pType
,
1309 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1311 FIXME("(%p)->(%s, %d) stub\n", This
, debugstr_w(pQName
), nQName
);
1315 static HRESULT WINAPI
isaxattributes_getValue(
1316 ISAXAttributes
* iface
,
1318 const WCHAR
**value
,
1321 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1322 TRACE("(%p)->(%d)\n", This
, index
);
1324 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1325 if(!value
|| !nValue
) return E_POINTER
;
1327 *nValue
= SysStringLen(This
->attributes
[index
].szValue
);
1328 *value
= This
->attributes
[index
].szValue
;
1330 TRACE("(%s:%d)\n", debugstr_w(*value
), *nValue
);
1335 static HRESULT WINAPI
isaxattributes_getValueFromName(
1336 ISAXAttributes
* iface
,
1339 const WCHAR
*pLocalName
,
1341 const WCHAR
**pValue
,
1346 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1347 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), nUri
,
1348 debugstr_w(pLocalName
), nLocalName
);
1350 hr
= ISAXAttributes_getIndexFromName(iface
,
1351 pUri
, nUri
, pLocalName
, nLocalName
, &index
);
1352 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1357 static HRESULT WINAPI
isaxattributes_getValueFromQName(
1358 ISAXAttributes
* iface
,
1359 const WCHAR
*pQName
,
1361 const WCHAR
**pValue
,
1366 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1367 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQName
);
1369 hr
= ISAXAttributes_getIndexFromQName(iface
, pQName
, nQName
, &index
);
1370 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1375 static const struct ISAXAttributesVtbl isaxattributes_vtbl
=
1377 isaxattributes_QueryInterface
,
1378 isaxattributes_AddRef
,
1379 isaxattributes_Release
,
1380 isaxattributes_getLength
,
1381 isaxattributes_getURI
,
1382 isaxattributes_getLocalName
,
1383 isaxattributes_getQName
,
1384 isaxattributes_getName
,
1385 isaxattributes_getIndexFromName
,
1386 isaxattributes_getIndexFromQName
,
1387 isaxattributes_getType
,
1388 isaxattributes_getTypeFromName
,
1389 isaxattributes_getTypeFromQName
,
1390 isaxattributes_getValue
,
1391 isaxattributes_getValueFromName
,
1392 isaxattributes_getValueFromQName
1395 /* Libxml2 escapes '&' back to char reference '&' in attribute value,
1396 so when document has escaped value with '&' it's parsed to '&' and then
1397 escaped to '&'. This function takes care of ampersands only. */
1398 static BSTR
saxreader_get_unescaped_value(const xmlChar
*buf
, int len
)
1400 static const WCHAR ampescW
[] = {'&','#','3','8',';',0};
1401 WCHAR
*dest
, *ptrW
, *str
;
1408 str_len
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
1409 if (len
!= -1) str_len
++;
1411 str
= heap_alloc(str_len
*sizeof(WCHAR
));
1412 if (!str
) return NULL
;
1414 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, str
, str_len
);
1415 if (len
!= -1) str
[str_len
-1] = 0;
1418 while ((dest
= strstrW(ptrW
, ampescW
)))
1422 /* leave first '&' from a reference as a value */
1423 src
= dest
+ ARRAY_SIZE(ampescW
) - 1;
1426 /* move together with null terminator */
1427 memmove(dest
, src
, (strlenW(src
) + 1)*sizeof(WCHAR
));
1432 bstr
= SysAllocString(str
);
1438 static void free_attribute_values(saxlocator
*locator
)
1442 for (i
= 0; i
< locator
->attr_count
; i
++)
1444 SysFreeString(locator
->attributes
[i
].szLocalname
);
1445 locator
->attributes
[i
].szLocalname
= NULL
;
1447 SysFreeString(locator
->attributes
[i
].szValue
);
1448 locator
->attributes
[i
].szValue
= NULL
;
1450 SysFreeString(locator
->attributes
[i
].szQName
);
1451 locator
->attributes
[i
].szQName
= NULL
;
1455 static HRESULT
SAXAttributes_populate(saxlocator
*locator
,
1456 int nb_namespaces
, const xmlChar
**xmlNamespaces
,
1457 int nb_attributes
, const xmlChar
**xmlAttributes
)
1459 static const xmlChar xmlns
[] = "xmlns";
1460 static const WCHAR xmlnsW
[] = { 'x','m','l','n','s',0 };
1462 struct _attributes
*attrs
;
1465 /* skip namespace definitions */
1466 if ((locator
->saxreader
->features
& NamespacePrefixes
) == 0)
1469 locator
->attr_count
= nb_namespaces
+ nb_attributes
;
1470 if(locator
->attr_count
> locator
->attr_alloc_count
)
1472 int new_size
= locator
->attr_count
* 2;
1473 attrs
= heap_realloc_zero(locator
->attributes
, new_size
* sizeof(struct _attributes
));
1476 free_attribute_values(locator
);
1477 locator
->attr_count
= 0;
1478 return E_OUTOFMEMORY
;
1480 locator
->attributes
= attrs
;
1481 locator
->attr_alloc_count
= new_size
;
1485 attrs
= locator
->attributes
;
1488 for (i
= 0; i
< nb_namespaces
; i
++)
1490 SysFreeString(attrs
[nb_attributes
+i
].szLocalname
);
1491 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1493 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1495 SysFreeString(attrs
[nb_attributes
+i
].szValue
);
1496 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1498 SysFreeString(attrs
[nb_attributes
+i
].szQName
);
1499 if(!xmlNamespaces
[2*i
])
1500 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1502 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1505 for (i
= 0; i
< nb_attributes
; i
++)
1507 static const xmlChar xmlA
[] = "xml";
1509 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1510 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1512 /* that's an important feature to keep same uri pointer for every reported attribute */
1513 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1515 SysFreeString(attrs
[i
].szLocalname
);
1516 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1518 SysFreeString(attrs
[i
].szValue
);
1519 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1521 SysFreeString(attrs
[i
].szQName
);
1522 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1], xmlAttributes
[i
*5]);
1528 /*** LibXML callbacks ***/
1529 static void libxmlStartDocument(void *ctx
)
1531 saxlocator
*This
= ctx
;
1532 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1535 if (This
->saxreader
->version
>= MSXML4
)
1537 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1538 update_position(This
, FALSE
);
1539 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1541 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1546 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1550 /* store version value, declaration has to contain version attribute */
1551 if (This
->pParserCtxt
->standalone
!= -1)
1553 SysFreeString(This
->saxreader
->xmldecl_version
);
1554 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1557 if (saxreader_has_handler(This
, SAXContentHandler
))
1559 if(This
->vbInterface
)
1560 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1562 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1564 if (sax_callback_failed(This
, hr
))
1565 format_error_message_from_id(This
, hr
);
1569 static void libxmlEndDocument(void *ctx
)
1571 saxlocator
*This
= ctx
;
1572 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1575 if (This
->saxreader
->version
>= MSXML4
) {
1576 update_position(This
, FALSE
);
1577 if(This
->column
> 1)
1585 if(This
->ret
!= S_OK
) return;
1587 if (saxreader_has_handler(This
, SAXContentHandler
))
1589 if(This
->vbInterface
)
1590 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1592 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1594 if (sax_callback_failed(This
, hr
))
1595 format_error_message_from_id(This
, hr
);
1599 static void libxmlStartElementNS(
1601 const xmlChar
*localname
,
1602 const xmlChar
*prefix
,
1605 const xmlChar
**namespaces
,
1608 const xmlChar
**attributes
)
1610 saxlocator
*This
= ctx
;
1611 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1612 element_entry
*element
;
1616 update_position(This
, TRUE
);
1617 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1619 if(This
->saxreader
->version
< MSXML4
)
1622 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1623 push_element_ns(This
, element
);
1625 if (is_namespaces_enabled(This
->saxreader
))
1629 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1631 if (This
->vbInterface
)
1632 hr
= IVBSAXContentHandler_startPrefixMapping(
1634 &element
->ns
[i
].prefix
,
1635 &element
->ns
[i
].uri
);
1637 hr
= ISAXContentHandler_startPrefixMapping(
1639 element
->ns
[i
].prefix
,
1640 SysStringLen(element
->ns
[i
].prefix
),
1642 SysStringLen(element
->ns
[i
].uri
));
1644 if (sax_callback_failed(This
, hr
))
1646 format_error_message_from_id(This
, hr
);
1652 uri
= find_element_uri(This
, URI
);
1653 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1654 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1658 if (is_namespaces_enabled(This
->saxreader
))
1659 local
= element
->local
;
1663 if (This
->vbInterface
)
1664 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1665 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1667 hr
= ISAXContentHandler_startElement(handler
->handler
,
1668 uri
, SysStringLen(uri
),
1669 local
, SysStringLen(local
),
1670 element
->qname
, SysStringLen(element
->qname
),
1671 &This
->ISAXAttributes_iface
);
1673 if (sax_callback_failed(This
, hr
))
1674 format_error_message_from_id(This
, hr
);
1678 static void libxmlEndElementNS(
1680 const xmlChar
*localname
,
1681 const xmlChar
*prefix
,
1684 saxlocator
*This
= ctx
;
1685 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1686 element_entry
*element
;
1691 update_position(This
, FALSE
);
1692 p
= This
->pParserCtxt
->input
->cur
;
1694 if (This
->saxreader
->version
>= MSXML4
)
1697 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1699 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1704 else if(*(p
-1)!='>' || *(p
-2)!='/')
1707 while(p
-2>=This
->pParserCtxt
->input
->base
1708 && *(p
-2)!='<' && *(p
-1)!='/')
1710 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1716 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1719 uri
= find_element_uri(This
, URI
);
1720 element
= pop_element_ns(This
);
1722 if (!saxreader_has_handler(This
, SAXContentHandler
))
1724 free_attribute_values(This
);
1725 This
->attr_count
= 0;
1726 free_element_entry(element
);
1730 if (is_namespaces_enabled(This
->saxreader
))
1731 local
= element
->local
;
1735 if (This
->vbInterface
)
1736 hr
= IVBSAXContentHandler_endElement(
1738 &uri
, &local
, &element
->qname
);
1740 hr
= ISAXContentHandler_endElement(
1742 uri
, SysStringLen(uri
),
1743 local
, SysStringLen(local
),
1744 element
->qname
, SysStringLen(element
->qname
));
1746 free_attribute_values(This
);
1747 This
->attr_count
= 0;
1749 if (sax_callback_failed(This
, hr
))
1751 format_error_message_from_id(This
, hr
);
1752 free_element_entry(element
);
1756 if (is_namespaces_enabled(This
->saxreader
))
1759 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1761 if (This
->vbInterface
)
1762 hr
= IVBSAXContentHandler_endPrefixMapping(
1763 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1765 hr
= ISAXContentHandler_endPrefixMapping(
1766 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1768 if (sax_callback_failed(This
, hr
)) break;
1771 if (sax_callback_failed(This
, hr
))
1772 format_error_message_from_id(This
, hr
);
1775 free_element_entry(element
);
1778 static void libxmlCharacters(
1783 saxlocator
*This
= ctx
;
1787 BOOL lastEvent
= FALSE
;
1789 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1791 update_position(This
, FALSE
);
1792 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1793 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1795 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1800 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1804 if(*(ch
-1)=='\r') cur
--;
1809 while(end
-ch
<len
&& *end
!='\r') end
++;
1820 if (This
->saxreader
->version
>= MSXML4
)
1824 for(p
=cur
; p
!=end
; p
++)
1841 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1842 hr
= saxreader_saxcharacters(This
, Chars
);
1844 if (sax_callback_failed(This
, hr
))
1846 format_error_message_from_id(This
, hr
);
1850 if (This
->saxreader
->version
< MSXML4
)
1851 This
->column
+= end
-cur
;
1864 if(end
-ch
== len
) break;
1868 static void libxmlSetDocumentLocator(
1870 xmlSAXLocatorPtr loc
)
1872 saxlocator
*This
= ctx
;
1873 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1876 if (saxreader_has_handler(This
, SAXContentHandler
))
1878 if(This
->vbInterface
)
1879 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1880 &This
->IVBSAXLocator_iface
);
1882 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1886 format_error_message_from_id(This
, hr
);
1889 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1891 saxlocator
*This
= ctx
;
1892 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1895 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1897 update_position(This
, FALSE
);
1898 while(p
-4>=This
->pParserCtxt
->input
->base
1899 && memcmp(p
-4, "<!--", sizeof(char[4])))
1901 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1907 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1910 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1912 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1914 if (This
->vbInterface
)
1915 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1917 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1920 format_error_message_from_id(This
, hr
);
1923 static void libxmlFatalError(void *ctx
, const char *msg
, ...)
1925 saxlocator
*This
= ctx
;
1926 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1932 if(This
->ret
!= S_OK
) {
1933 xmlStopParser(This
->pParserCtxt
);
1937 va_start(args
, msg
);
1938 vsprintf(message
, msg
, args
);
1941 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1942 error
= heap_alloc(sizeof(WCHAR
)*len
);
1945 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1946 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1949 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1951 xmlStopParser(This
->pParserCtxt
);
1957 FIXME("Error handling is not compatible.\n");
1959 if(This
->vbInterface
)
1961 BSTR bstrError
= SysAllocString(error
);
1962 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1963 &bstrError
, E_FAIL
);
1964 SysFreeString(bstrError
);
1967 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1971 xmlStopParser(This
->pParserCtxt
);
1975 /* The only reason this helper exists is that CDATA section are reported by chunks,
1976 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1978 This helper should be called for substring with trailing newlines.
1980 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1982 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1985 len
= SysStringLen(bstr
);
1986 ptr
= bstr
+ len
- 1;
1987 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1992 /* replace returns as:
1994 - "\r<char>" -> "\n<char>"
2000 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
2003 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
2010 ret
= SysAllocStringLen(bstr
, len
);
2011 SysFreeString(bstr
);
2015 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
2017 const xmlChar
*start
, *end
;
2018 saxlocator
*locator
= ctx
;
2019 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
2024 update_position(locator
, FALSE
);
2025 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2027 if (locator
->vbInterface
)
2028 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
2030 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
2035 format_error_message_from_id(locator
, hr
);
2045 /* scan for newlines */
2046 if (value
[i
] == '\r' || value
[i
] == '\n')
2048 /* skip newlines/linefeeds */
2051 if (value
[i
] != '\r' && value
[i
] != '\n') break;
2057 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
2058 TRACE("(chunk %s)\n", debugstr_w(chars
));
2059 hr
= saxreader_saxcharacters(locator
, chars
);
2060 SysFreeString(chars
);
2069 /* no newline chars (or last chunk) report as a whole */
2070 if (!end
&& start
== value
)
2073 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
2074 TRACE("(%s)\n", debugstr_w(chars
));
2075 hr
= saxreader_saxcharacters(locator
, chars
);
2076 SysFreeString(chars
);
2079 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2081 if (locator
->vbInterface
)
2082 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
2084 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
2088 format_error_message_from_id(locator
, hr
);
2091 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
2093 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
2094 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
2097 /*** IVBSAXLocator interface ***/
2098 /*** IUnknown methods ***/
2099 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2101 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2103 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2107 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2108 IsEqualGUID( riid
, &IID_IDispatch
) ||
2109 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
2113 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
2115 *ppvObject
= &This
->IVBSAXAttributes_iface
;
2119 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2120 return E_NOINTERFACE
;
2123 IVBSAXLocator_AddRef( iface
);
2128 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
2130 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2131 TRACE("%p\n", This
);
2132 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
2135 static ULONG WINAPI
ivbsaxlocator_Release(IVBSAXLocator
* iface
)
2137 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2138 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
2141 /*** IDispatch methods ***/
2142 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
2144 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2146 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2153 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
2154 IVBSAXLocator
*iface
,
2155 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2157 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2159 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2161 return get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2164 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2165 IVBSAXLocator
*iface
,
2167 LPOLESTR
* rgszNames
,
2172 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2173 ITypeInfo
*typeinfo
;
2176 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
2179 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2180 return E_INVALIDARG
;
2182 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2185 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2186 ITypeInfo_Release(typeinfo
);
2192 static HRESULT WINAPI
ivbsaxlocator_Invoke(
2193 IVBSAXLocator
*iface
,
2194 DISPID dispIdMember
,
2198 DISPPARAMS
* pDispParams
,
2199 VARIANT
* pVarResult
,
2200 EXCEPINFO
* pExcepInfo
,
2203 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2204 ITypeInfo
*typeinfo
;
2207 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2208 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2210 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2213 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXLocator_iface
, dispIdMember
, wFlags
,
2214 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2215 ITypeInfo_Release(typeinfo
);
2221 /*** IVBSAXLocator methods ***/
2222 static HRESULT WINAPI
ivbsaxlocator_get_columnNumber(
2223 IVBSAXLocator
* iface
,
2226 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2227 return ISAXLocator_getColumnNumber(&This
->ISAXLocator_iface
, pnColumn
);
2230 static HRESULT WINAPI
ivbsaxlocator_get_lineNumber(
2231 IVBSAXLocator
* iface
,
2234 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2235 return ISAXLocator_getLineNumber(&This
->ISAXLocator_iface
, pnLine
);
2238 static HRESULT WINAPI
ivbsaxlocator_get_publicId(IVBSAXLocator
* iface
, BSTR
*ret
)
2240 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2241 const WCHAR
*publicidW
;
2244 TRACE("(%p)->(%p)\n", This
, ret
);
2250 hr
= ISAXLocator_getPublicId(&This
->ISAXLocator_iface
, &publicidW
);
2254 return return_bstr(publicidW
, ret
);
2257 static HRESULT WINAPI
ivbsaxlocator_get_systemId(IVBSAXLocator
* iface
, BSTR
*ret
)
2259 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2260 const WCHAR
*systemidW
;
2263 TRACE("(%p)->(%p)\n", This
, ret
);
2269 hr
= ISAXLocator_getSystemId(&This
->ISAXLocator_iface
, &systemidW
);
2273 return return_bstr(systemidW
, ret
);
2276 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl
=
2278 ivbsaxlocator_QueryInterface
,
2279 ivbsaxlocator_AddRef
,
2280 ivbsaxlocator_Release
,
2281 ivbsaxlocator_GetTypeInfoCount
,
2282 ivbsaxlocator_GetTypeInfo
,
2283 ivbsaxlocator_GetIDsOfNames
,
2284 ivbsaxlocator_Invoke
,
2285 ivbsaxlocator_get_columnNumber
,
2286 ivbsaxlocator_get_lineNumber
,
2287 ivbsaxlocator_get_publicId
,
2288 ivbsaxlocator_get_systemId
2291 /*** ISAXLocator interface ***/
2292 /*** IUnknown methods ***/
2293 static HRESULT WINAPI
isaxlocator_QueryInterface(ISAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2295 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2297 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2301 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2302 IsEqualGUID( riid
, &IID_ISAXLocator
))
2306 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
2308 *ppvObject
= &This
->ISAXAttributes_iface
;
2312 WARN("interface %s not implemented\n", debugstr_guid(riid
));
2313 return E_NOINTERFACE
;
2316 ISAXLocator_AddRef( iface
);
2321 static ULONG WINAPI
isaxlocator_AddRef(ISAXLocator
* iface
)
2323 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2324 ULONG ref
= InterlockedIncrement( &This
->ref
);
2325 TRACE("(%p)->(%d)\n", This
, ref
);
2329 static ULONG WINAPI
isaxlocator_Release(
2332 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2333 LONG ref
= InterlockedDecrement( &This
->ref
);
2335 TRACE("(%p)->(%d)\n", This
, ref
);
2339 element_entry
*element
, *element2
;
2342 SysFreeString(This
->publicId
);
2343 SysFreeString(This
->systemId
);
2344 SysFreeString(This
->namespaceUri
);
2346 for(index
= 0; index
< This
->attr_alloc_count
; index
++)
2348 SysFreeString(This
->attributes
[index
].szLocalname
);
2349 SysFreeString(This
->attributes
[index
].szValue
);
2350 SysFreeString(This
->attributes
[index
].szQName
);
2352 heap_free(This
->attributes
);
2355 LIST_FOR_EACH_ENTRY_SAFE(element
, element2
, &This
->elements
, element_entry
, entry
)
2357 list_remove(&element
->entry
);
2358 free_element_entry(element
);
2361 ISAXXMLReader_Release(&This
->saxreader
->ISAXXMLReader_iface
);
2368 /*** ISAXLocator methods ***/
2369 static HRESULT WINAPI
isaxlocator_getColumnNumber(
2373 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2375 *pnColumn
= This
->column
;
2379 static HRESULT WINAPI
isaxlocator_getLineNumber(
2383 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2385 *pnLine
= This
->line
;
2389 static HRESULT WINAPI
isaxlocator_getPublicId(
2391 const WCHAR
** ppwchPublicId
)
2394 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2396 SysFreeString(This
->publicId
);
2398 publicId
= bstr_from_xmlChar(xmlSAX2GetPublicId(This
->pParserCtxt
));
2399 if(SysStringLen(publicId
))
2400 This
->publicId
= publicId
;
2403 SysFreeString(publicId
);
2404 This
->publicId
= NULL
;
2407 *ppwchPublicId
= This
->publicId
;
2411 static HRESULT WINAPI
isaxlocator_getSystemId(
2413 const WCHAR
** ppwchSystemId
)
2416 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2418 SysFreeString(This
->systemId
);
2420 systemId
= bstr_from_xmlChar(xmlSAX2GetSystemId(This
->pParserCtxt
));
2421 if(SysStringLen(systemId
))
2422 This
->systemId
= systemId
;
2425 SysFreeString(systemId
);
2426 This
->systemId
= NULL
;
2429 *ppwchSystemId
= This
->systemId
;
2433 static const struct ISAXLocatorVtbl SAXLocatorVtbl
=
2435 isaxlocator_QueryInterface
,
2437 isaxlocator_Release
,
2438 isaxlocator_getColumnNumber
,
2439 isaxlocator_getLineNumber
,
2440 isaxlocator_getPublicId
,
2441 isaxlocator_getSystemId
2444 static HRESULT
SAXLocator_create(saxreader
*reader
, saxlocator
**ppsaxlocator
, BOOL vbInterface
)
2446 static const WCHAR w3xmlns
[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2447 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2449 saxlocator
*locator
;
2451 locator
= heap_alloc( sizeof (*locator
) );
2453 return E_OUTOFMEMORY
;
2455 locator
->IVBSAXLocator_iface
.lpVtbl
= &VBSAXLocatorVtbl
;
2456 locator
->ISAXLocator_iface
.lpVtbl
= &SAXLocatorVtbl
;
2457 locator
->IVBSAXAttributes_iface
.lpVtbl
= &ivbsaxattributes_vtbl
;
2458 locator
->ISAXAttributes_iface
.lpVtbl
= &isaxattributes_vtbl
;
2460 locator
->vbInterface
= vbInterface
;
2462 locator
->saxreader
= reader
;
2463 ISAXXMLReader_AddRef(&reader
->ISAXXMLReader_iface
);
2465 locator
->pParserCtxt
= NULL
;
2466 locator
->publicId
= NULL
;
2467 locator
->systemId
= NULL
;
2468 locator
->line
= reader
->version
< MSXML4
? 0 : 1;
2469 locator
->column
= 0;
2470 locator
->ret
= S_OK
;
2471 if (locator
->saxreader
->version
>= MSXML6
)
2472 locator
->namespaceUri
= SysAllocString(w3xmlns
);
2474 locator
->namespaceUri
= SysAllocStringLen(NULL
, 0);
2475 if(!locator
->namespaceUri
)
2477 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2479 return E_OUTOFMEMORY
;
2482 locator
->attr_alloc_count
= 8;
2483 locator
->attr_count
= 0;
2484 locator
->attributes
= heap_alloc_zero(sizeof(struct _attributes
)*locator
->attr_alloc_count
);
2485 if(!locator
->attributes
)
2487 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2488 SysFreeString(locator
->namespaceUri
);
2490 return E_OUTOFMEMORY
;
2493 list_init(&locator
->elements
);
2495 *ppsaxlocator
= locator
;
2497 TRACE("returning %p\n", *ppsaxlocator
);
2502 /*** SAXXMLReader internal functions ***/
2503 static HRESULT
internal_parseBuffer(saxreader
*This
, const char *buffer
, int size
, BOOL vbInterface
)
2505 xmlCharEncoding encoding
= XML_CHAR_ENCODING_NONE
;
2506 xmlChar
*enc_name
= NULL
;
2507 saxlocator
*locator
;
2510 TRACE("(%p)->(%p %d)\n", This
, buffer
, size
);
2512 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2518 const unsigned char *buff
= (unsigned char*)buffer
;
2520 encoding
= xmlDetectCharEncoding((xmlChar
*)buffer
, 4);
2521 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2522 TRACE("detected encoding: %s\n", enc_name
);
2523 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2524 if ((encoding
== XML_CHAR_ENCODING_UTF8
) &&
2525 buff
[0] == 0xEF && buff
[1] == 0xBB && buff
[2] == 0xBF)
2532 /* if libxml2 detection failed try to guess */
2533 if (encoding
== XML_CHAR_ENCODING_NONE
)
2535 const WCHAR
*ptr
= (WCHAR
*)buffer
;
2536 /* an xml declaration with optional encoding will still be handled by the parser */
2537 if ((size
>= 2) && *ptr
== '<' && ptr
[1] != '?')
2539 enc_name
= (xmlChar
*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE
);
2540 encoding
= XML_CHAR_ENCODING_UTF16LE
;
2543 else if (encoding
== XML_CHAR_ENCODING_UTF8
)
2544 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2548 locator
->pParserCtxt
= xmlCreateMemoryParserCtxt(buffer
, size
);
2549 if (!locator
->pParserCtxt
)
2551 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2557 locator
->pParserCtxt
->encoding
= xmlStrdup(enc_name
);
2558 if (encoding
== XML_CHAR_ENCODING_UTF16LE
) {
2559 TRACE("switching to %s\n", enc_name
);
2560 xmlSwitchEncoding(locator
->pParserCtxt
, encoding
);
2564 xmlFree(locator
->pParserCtxt
->sax
);
2565 locator
->pParserCtxt
->sax
= &locator
->saxreader
->sax
;
2566 locator
->pParserCtxt
->userData
= locator
;
2568 This
->isParsing
= TRUE
;
2569 if(xmlParseDocument(locator
->pParserCtxt
) == -1 && locator
->ret
== S_OK
)
2573 This
->isParsing
= FALSE
;
2575 if(locator
->pParserCtxt
)
2577 locator
->pParserCtxt
->sax
= NULL
;
2578 xmlFreeParserCtxt(locator
->pParserCtxt
);
2579 locator
->pParserCtxt
= NULL
;
2582 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2586 static HRESULT
internal_parseStream(saxreader
*This
, ISequentialStream
*stream
, BOOL vbInterface
)
2588 saxlocator
*locator
;
2595 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2596 if(FAILED(hr
)) return hr
;
2598 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2599 if(FAILED(hr
)) return hr
;
2601 locator
->pParserCtxt
= xmlCreatePushParserCtxt(
2602 &locator
->saxreader
->sax
, locator
,
2603 data
, dataRead
, NULL
);
2604 if(!locator
->pParserCtxt
)
2606 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2610 This
->isParsing
= TRUE
;
2614 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2615 if (FAILED(hr
) || !dataRead
) break;
2617 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, dataRead
, 0);
2618 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2623 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2624 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2628 This
->isParsing
= FALSE
;
2630 xmlFreeParserCtxt(locator
->pParserCtxt
);
2631 locator
->pParserCtxt
= NULL
;
2632 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2636 static HRESULT
internal_parse(
2643 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varInput
));
2645 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2646 free_bstr_pool(&This
->pool
);
2648 switch(V_VT(&varInput
))
2651 case VT_BSTR
|VT_BYREF
:
2653 BSTR str
= V_ISBYREF(&varInput
) ? *V_BSTRREF(&varInput
) : V_BSTR(&varInput
);
2654 hr
= internal_parseBuffer(This
, (const char*)str
, strlenW(str
)*sizeof(WCHAR
), vbInterface
);
2657 case VT_ARRAY
|VT_UI1
: {
2659 LONG lBound
, uBound
;
2662 hr
= SafeArrayGetLBound(V_ARRAY(&varInput
), 1, &lBound
);
2663 if(hr
!= S_OK
) break;
2664 hr
= SafeArrayGetUBound(V_ARRAY(&varInput
), 1, &uBound
);
2665 if(hr
!= S_OK
) break;
2666 dataRead
= (uBound
-lBound
)*SafeArrayGetElemsize(V_ARRAY(&varInput
));
2667 hr
= SafeArrayAccessData(V_ARRAY(&varInput
), &pSAData
);
2668 if(hr
!= S_OK
) break;
2669 hr
= internal_parseBuffer(This
, pSAData
, dataRead
, vbInterface
);
2670 SafeArrayUnaccessData(V_ARRAY(&varInput
));
2675 ISequentialStream
*stream
= NULL
;
2676 IXMLDOMDocument
*xmlDoc
;
2678 if (!V_UNKNOWN(&varInput
))
2679 return E_INVALIDARG
;
2681 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2682 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2686 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2687 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2688 SysStringByteLen(bstrData
), vbInterface
);
2689 IXMLDOMDocument_Release(xmlDoc
);
2690 SysFreeString(bstrData
);
2694 /* try base interface first */
2695 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2697 /* this should never happen if IStream is implemented properly, but just in case */
2698 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2702 hr
= internal_parseStream(This
, stream
, vbInterface
);
2703 ISequentialStream_Release(stream
);
2707 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2714 WARN("vt %d not implemented\n", V_VT(&varInput
));
2721 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2723 saxreader
*This
= obj
;
2725 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2728 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2730 saxreader
*This
= obj
;
2732 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2735 static HRESULT
internal_parseURL(
2744 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
2746 hr
= create_moniker_from_url(url
, &mon
);
2750 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, This
, &bsc
);
2751 else hr
= bind_url(mon
, internal_onDataAvailable
, This
, &bsc
);
2752 IMoniker_Release(mon
);
2757 return detach_bsc(bsc
);
2760 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2764 if (V_VT(v
) == VT_EMPTY
)
2765 return saxreader_put_handler(This
, type
, NULL
, vb
);
2769 case SAXDeclHandler
:
2770 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2772 case SAXLexicalHandler
:
2773 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2776 ERR("wrong handler type %d\n", type
);
2785 IUnknown
*handler
= NULL
;
2789 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2790 if (FAILED(hr
)) return hr
;
2793 saxreader_put_handler(This
, type
, handler
, vb
);
2794 if (handler
) IUnknown_Release(handler
);
2798 ERR("value type %d not supported\n", V_VT(v
));
2799 return E_INVALIDARG
;
2805 static HRESULT
internal_putProperty(
2813 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2815 if (This
->isParsing
) return E_FAIL
;
2817 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2818 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2819 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2821 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2822 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2824 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2826 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2827 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2831 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2833 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2834 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2838 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2840 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2843 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2846 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2849 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2852 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2855 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2858 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2861 return E_INVALIDARG
;
2864 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2866 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2868 if (!value
) return E_POINTER
;
2870 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2872 V_VT(value
) = VT_UNKNOWN
;
2873 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2877 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2879 V_VT(value
) = VT_UNKNOWN
;
2880 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2884 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2886 V_VT(value
) = VT_BSTR
;
2887 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2891 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2896 /*** IVBSAXXMLReader interface ***/
2897 /*** IUnknown methods ***/
2898 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2900 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2902 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2906 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2907 IsEqualGUID( riid
, &IID_IDispatch
) ||
2908 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2912 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2914 *ppvObject
= &This
->ISAXXMLReader_iface
;
2916 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2918 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2922 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2923 return E_NOINTERFACE
;
2926 IVBSAXXMLReader_AddRef( iface
);
2931 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2933 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2934 TRACE("%p\n", This
);
2935 return InterlockedIncrement( &This
->ref
);
2938 static ULONG WINAPI
saxxmlreader_Release(
2939 IVBSAXXMLReader
* iface
)
2941 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2944 TRACE("%p\n", This
);
2946 ref
= InterlockedDecrement( &This
->ref
);
2951 for (i
= 0; i
< SAXHandler_Last
; i
++)
2953 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2955 if (saxiface
->handler
)
2956 IUnknown_Release(saxiface
->handler
);
2958 if (saxiface
->vbhandler
)
2959 IUnknown_Release(saxiface
->vbhandler
);
2962 SysFreeString(This
->xmldecl_version
);
2963 free_bstr_pool(&This
->pool
);
2971 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2973 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2974 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2977 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2978 IVBSAXXMLReader
*iface
,
2979 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2981 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2982 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2983 iTInfo
, lcid
, ppTInfo
);
2986 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2987 IVBSAXXMLReader
*iface
,
2989 LPOLESTR
* rgszNames
,
2994 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2995 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
2996 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
2999 static HRESULT WINAPI
saxxmlreader_Invoke(
3000 IVBSAXXMLReader
*iface
,
3001 DISPID dispIdMember
,
3005 DISPPARAMS
* pDispParams
,
3006 VARIANT
* pVarResult
,
3007 EXCEPINFO
* pExcepInfo
,
3010 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3011 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
3012 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3015 /*** IVBSAXXMLReader methods ***/
3016 static HRESULT WINAPI
saxxmlreader_getFeature(
3017 IVBSAXXMLReader
* iface
,
3019 VARIANT_BOOL
*value
)
3021 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3022 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3025 static HRESULT WINAPI
saxxmlreader_putFeature(
3026 IVBSAXXMLReader
* iface
,
3030 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3031 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3034 static HRESULT WINAPI
saxxmlreader_getProperty(
3035 IVBSAXXMLReader
* iface
,
3039 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3040 return internal_getProperty(This
, prop
, value
, TRUE
);
3043 static HRESULT WINAPI
saxxmlreader_putProperty(
3044 IVBSAXXMLReader
* iface
,
3048 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3049 return internal_putProperty(This
, pProp
, value
, TRUE
);
3052 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3053 IVBSAXXMLReader
* iface
,
3054 IVBSAXEntityResolver
**resolver
)
3056 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3057 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3060 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3061 IVBSAXXMLReader
* iface
,
3062 IVBSAXEntityResolver
*resolver
)
3064 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3065 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3068 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3069 IVBSAXXMLReader
* iface
,
3070 IVBSAXContentHandler
**handler
)
3072 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3073 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3076 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3077 IVBSAXXMLReader
* iface
,
3078 IVBSAXContentHandler
*handler
)
3080 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3081 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3084 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3085 IVBSAXXMLReader
* iface
,
3086 IVBSAXDTDHandler
**handler
)
3088 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3089 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3092 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3093 IVBSAXXMLReader
* iface
,
3094 IVBSAXDTDHandler
*handler
)
3096 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3097 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3100 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3101 IVBSAXXMLReader
* iface
,
3102 IVBSAXErrorHandler
**handler
)
3104 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3105 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3108 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3109 IVBSAXXMLReader
* iface
,
3110 IVBSAXErrorHandler
*handler
)
3112 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3113 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3116 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3117 IVBSAXXMLReader
* iface
,
3120 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3122 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3126 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3127 IVBSAXXMLReader
* iface
,
3130 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3131 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3134 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3135 IVBSAXXMLReader
* iface
,
3136 BSTR
*pSecureBaseUrl
)
3138 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3140 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3144 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3145 IVBSAXXMLReader
* iface
,
3148 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3149 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3152 static HRESULT WINAPI
saxxmlreader_parse(
3153 IVBSAXXMLReader
* iface
,
3156 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3157 return internal_parse(This
, varInput
, TRUE
);
3160 static HRESULT WINAPI
saxxmlreader_parseURL(
3161 IVBSAXXMLReader
* iface
,
3164 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3165 return internal_parseURL(This
, url
, TRUE
);
3168 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3170 saxxmlreader_QueryInterface
,
3171 saxxmlreader_AddRef
,
3172 saxxmlreader_Release
,
3173 saxxmlreader_GetTypeInfoCount
,
3174 saxxmlreader_GetTypeInfo
,
3175 saxxmlreader_GetIDsOfNames
,
3176 saxxmlreader_Invoke
,
3177 saxxmlreader_getFeature
,
3178 saxxmlreader_putFeature
,
3179 saxxmlreader_getProperty
,
3180 saxxmlreader_putProperty
,
3181 saxxmlreader_get_entityResolver
,
3182 saxxmlreader_put_entityResolver
,
3183 saxxmlreader_get_contentHandler
,
3184 saxxmlreader_put_contentHandler
,
3185 saxxmlreader_get_dtdHandler
,
3186 saxxmlreader_put_dtdHandler
,
3187 saxxmlreader_get_errorHandler
,
3188 saxxmlreader_put_errorHandler
,
3189 saxxmlreader_get_baseURL
,
3190 saxxmlreader_put_baseURL
,
3191 saxxmlreader_get_secureBaseURL
,
3192 saxxmlreader_put_secureBaseURL
,
3194 saxxmlreader_parseURL
3197 /*** ISAXXMLReader interface ***/
3198 /*** IUnknown methods ***/
3199 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3201 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3202 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3205 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3207 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3208 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3211 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3213 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3214 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3217 /*** ISAXXMLReader methods ***/
3218 static HRESULT WINAPI
isaxxmlreader_getFeature(
3219 ISAXXMLReader
* iface
,
3220 const WCHAR
*feature_name
,
3221 VARIANT_BOOL
*value
)
3223 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3224 saxreader_feature feature
;
3226 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3228 feature
= get_saxreader_feature(feature_name
);
3230 if (This
->version
< MSXML4
&& (feature
== ExhaustiveErrors
|| feature
== SchemaValidation
))
3231 return E_INVALIDARG
;
3233 if (feature
== Namespaces
||
3234 feature
== NamespacePrefixes
||
3235 feature
== ExhaustiveErrors
||
3236 feature
== SchemaValidation
)
3237 return get_feature_value(This
, feature
, value
);
3239 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3243 static HRESULT WINAPI
isaxxmlreader_putFeature(
3244 ISAXXMLReader
* iface
,
3245 const WCHAR
*feature_name
,
3248 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3249 saxreader_feature feature
;
3251 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3253 feature
= get_saxreader_feature(feature_name
);
3255 /* accepted cases */
3256 if ((feature
== ExhaustiveErrors
&& value
== VARIANT_FALSE
) ||
3257 (feature
== SchemaValidation
&& value
== VARIANT_FALSE
) ||
3258 feature
== Namespaces
||
3259 feature
== NamespacePrefixes
)
3261 return set_feature_value(This
, feature
, value
);
3264 if (feature
== LexicalHandlerParEntities
||
3265 feature
== ProhibitDTD
||
3266 feature
== ExternalGeneralEntities
||
3267 feature
== ExternalParameterEntities
)
3269 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3270 return set_feature_value(This
, feature
, value
);
3273 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3277 static HRESULT WINAPI
isaxxmlreader_getProperty(
3278 ISAXXMLReader
* iface
,
3282 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3283 return internal_getProperty(This
, prop
, value
, FALSE
);
3286 static HRESULT WINAPI
isaxxmlreader_putProperty(
3287 ISAXXMLReader
* iface
,
3291 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3292 return internal_putProperty(This
, pProp
, value
, FALSE
);
3295 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3296 ISAXXMLReader
* iface
,
3297 ISAXEntityResolver
**resolver
)
3299 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3300 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3303 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3304 ISAXXMLReader
* iface
,
3305 ISAXEntityResolver
*resolver
)
3307 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3308 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3311 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3312 ISAXXMLReader
* iface
,
3313 ISAXContentHandler
**handler
)
3315 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3316 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3319 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3320 ISAXXMLReader
* iface
,
3321 ISAXContentHandler
*handler
)
3323 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3324 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3327 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3328 ISAXXMLReader
* iface
,
3329 ISAXDTDHandler
**handler
)
3331 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3332 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3335 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3336 ISAXXMLReader
* iface
,
3337 ISAXDTDHandler
*handler
)
3339 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3340 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3343 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3344 ISAXXMLReader
* iface
,
3345 ISAXErrorHandler
**handler
)
3347 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3348 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3351 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3353 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3354 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3357 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3358 ISAXXMLReader
* iface
,
3359 const WCHAR
**base_url
)
3361 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3363 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3367 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3368 ISAXXMLReader
* iface
,
3369 const WCHAR
*pBaseUrl
)
3371 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3373 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3377 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3378 ISAXXMLReader
* iface
,
3379 const WCHAR
**pSecureBaseUrl
)
3381 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3382 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3386 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3387 ISAXXMLReader
* iface
,
3388 const WCHAR
*secureBaseUrl
)
3390 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3392 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3396 static HRESULT WINAPI
isaxxmlreader_parse(
3397 ISAXXMLReader
* iface
,
3400 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3401 return internal_parse(This
, varInput
, FALSE
);
3404 static HRESULT WINAPI
isaxxmlreader_parseURL(
3405 ISAXXMLReader
* iface
,
3408 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3409 return internal_parseURL(This
, url
, FALSE
);
3412 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3414 isaxxmlreader_QueryInterface
,
3415 isaxxmlreader_AddRef
,
3416 isaxxmlreader_Release
,
3417 isaxxmlreader_getFeature
,
3418 isaxxmlreader_putFeature
,
3419 isaxxmlreader_getProperty
,
3420 isaxxmlreader_putProperty
,
3421 isaxxmlreader_getEntityResolver
,
3422 isaxxmlreader_putEntityResolver
,
3423 isaxxmlreader_getContentHandler
,
3424 isaxxmlreader_putContentHandler
,
3425 isaxxmlreader_getDTDHandler
,
3426 isaxxmlreader_putDTDHandler
,
3427 isaxxmlreader_getErrorHandler
,
3428 isaxxmlreader_putErrorHandler
,
3429 isaxxmlreader_getBaseURL
,
3430 isaxxmlreader_putBaseURL
,
3431 isaxxmlreader_getSecureBaseURL
,
3432 isaxxmlreader_putSecureBaseURL
,
3433 isaxxmlreader_parse
,
3434 isaxxmlreader_parseURL
3437 static const tid_t saxreader_iface_tids
[] = {
3438 IVBSAXXMLReader_tid
,
3441 static dispex_static_data_t saxreader_dispex
= {
3443 IVBSAXXMLReader_tid
,
3445 saxreader_iface_tids
3448 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3452 TRACE("(%p)\n", ppObj
);
3454 reader
= heap_alloc( sizeof (*reader
) );
3456 return E_OUTOFMEMORY
;
3458 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3459 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3461 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3462 reader
->isParsing
= FALSE
;
3463 reader
->xmldecl_version
= NULL
;
3464 reader
->pool
.pool
= NULL
;
3465 reader
->pool
.index
= 0;
3466 reader
->pool
.len
= 0;
3467 reader
->features
= Namespaces
| NamespacePrefixes
;
3468 reader
->version
= version
;
3470 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3472 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3473 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3474 reader
->sax
.startDocument
= libxmlStartDocument
;
3475 reader
->sax
.endDocument
= libxmlEndDocument
;
3476 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3477 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3478 reader
->sax
.characters
= libxmlCharacters
;
3479 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3480 reader
->sax
.comment
= libxmlComment
;
3481 reader
->sax
.error
= libxmlFatalError
;
3482 reader
->sax
.fatalError
= libxmlFatalError
;
3483 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3484 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3486 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3488 TRACE("returning iface %p\n", *ppObj
);
3495 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3497 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3498 "libxml2 support was not present at compile time.\n");