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
25 # include <libxml/parserInternals.h>
33 ExhaustiveErrors
= 1 << 1,
34 ExternalGeneralEntities
= 1 << 2,
35 ExternalParameterEntities
= 1 << 3,
36 ForcedResync
= 1 << 4,
37 NamespacePrefixes
= 1 << 5,
39 ParameterEntities
= 1 << 7,
40 PreserveSystemIndentifiers
= 1 << 8,
42 SchemaValidation
= 1 << 10,
43 ServerHttpRequest
= 1 << 11,
44 SuppressValidationfatalError
= 1 << 12,
45 UseInlineSchema
= 1 << 13,
46 UseSchemaLocation
= 1 << 14,
47 LexicalHandlerParEntities
= 1 << 15
51 static const WCHAR FeatureExternalGeneralEntitiesW
[] = {
52 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/',
53 'f','e','a','t','u','r','e','s','/','e','x','t','e','r','n','a','l','-','g','e','n','e','r','a','l',
54 '-','e','n','t','i','t','i','e','s',0
57 static const WCHAR FeatureExternalParameterEntitiesW
[] = {
58 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
59 '/','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
62 static const WCHAR FeatureLexicalHandlerParEntitiesW
[] = {
63 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
64 '/','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
67 static const WCHAR FeatureProhibitDTDW
[] = {
68 'p','r','o','h','i','b','i','t','-','d','t','d',0
71 static const WCHAR FeatureNamespacesW
[] = {
72 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
73 '/','n','a','m','e','s','p','a','c','e','s',0
76 static const WCHAR FeatureNamespacePrefixesW
[] = {
77 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
78 '/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0
81 struct saxreader_feature_pair
83 saxreader_feature feature
;
87 static const struct saxreader_feature_pair saxreader_feature_map
[] = {
88 { ExternalGeneralEntities
, FeatureExternalGeneralEntitiesW
},
89 { ExternalParameterEntities
, FeatureExternalParameterEntitiesW
},
90 { LexicalHandlerParEntities
, FeatureLexicalHandlerParEntitiesW
},
91 { NamespacePrefixes
, FeatureNamespacePrefixesW
},
92 { Namespaces
, FeatureNamespacesW
},
93 { ProhibitDTD
, FeatureProhibitDTDW
}
96 static saxreader_feature
get_saxreader_feature(const WCHAR
*name
)
101 max
= sizeof(saxreader_feature_map
)/sizeof(struct saxreader_feature_pair
) - 1;
107 c
= strcmpW(saxreader_feature_map
[n
].name
, name
);
109 return saxreader_feature_map
[n
].feature
;
117 return FeatureUnknown
;
139 ns
*ns
; /* namespaces defined in this particular element */
145 SAXContentHandler
= 0,
154 struct saxanyhandler_iface
160 struct saxcontenthandler_iface
162 ISAXContentHandler
*handler
;
163 IVBSAXContentHandler
*vbhandler
;
166 struct saxerrorhandler_iface
168 ISAXErrorHandler
*handler
;
169 IVBSAXErrorHandler
*vbhandler
;
172 struct saxlexicalhandler_iface
174 ISAXLexicalHandler
*handler
;
175 IVBSAXLexicalHandler
*vbhandler
;
178 struct saxentityresolver_iface
180 ISAXEntityResolver
*handler
;
181 IVBSAXEntityResolver
*vbhandler
;
184 struct saxhandler_iface
187 struct saxcontenthandler_iface content
;
188 struct saxentityresolver_iface entityresolver
;
189 struct saxerrorhandler_iface error
;
190 struct saxlexicalhandler_iface lexical
;
191 struct saxanyhandler_iface anyhandler
;
198 IVBSAXXMLReader IVBSAXXMLReader_iface
;
199 ISAXXMLReader ISAXXMLReader_iface
;
202 struct saxhandler_iface saxhandlers
[SAXHandler_Last
];
205 struct bstrpool pool
;
206 saxreader_feature features
;
207 BSTR xmldecl_version
;
208 MSXML_VERSION version
;
211 static HRESULT
saxreader_put_handler(saxreader
*reader
, enum saxhandler_type type
, void *ptr
, BOOL vb
)
213 struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
214 IUnknown
*unk
= (IUnknown
*)ptr
;
217 IUnknown_AddRef(unk
);
219 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
220 IUnknown_Release(vb
? iface
->vbhandler
: iface
->handler
);
223 iface
->vbhandler
= unk
;
225 iface
->handler
= unk
;
230 static HRESULT
saxreader_get_handler(const saxreader
*reader
, enum saxhandler_type type
, BOOL vb
, void **ret
)
232 const struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
234 if (!ret
) return E_POINTER
;
236 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
239 IUnknown_AddRef(iface
->vbhandler
);
241 IUnknown_AddRef(iface
->handler
);
244 *ret
= vb
? iface
->vbhandler
: iface
->handler
;
249 static struct saxcontenthandler_iface
*saxreader_get_contenthandler(saxreader
*reader
)
251 return &reader
->saxhandlers
[SAXContentHandler
].u
.content
;
254 static struct saxerrorhandler_iface
*saxreader_get_errorhandler(saxreader
*reader
)
256 return &reader
->saxhandlers
[SAXErrorHandler
].u
.error
;
259 static struct saxlexicalhandler_iface
*saxreader_get_lexicalhandler(saxreader
*reader
)
261 return &reader
->saxhandlers
[SAXLexicalHandler
].u
.lexical
;
266 IVBSAXLocator IVBSAXLocator_iface
;
267 ISAXLocator ISAXLocator_iface
;
268 IVBSAXAttributes IVBSAXAttributes_iface
;
269 ISAXAttributes ISAXAttributes_iface
;
271 saxreader
*saxreader
;
273 xmlParserCtxtPtr pParserCtxt
;
279 struct list elements
;
293 static inline saxreader
*impl_from_IVBSAXXMLReader( IVBSAXXMLReader
*iface
)
295 return CONTAINING_RECORD(iface
, saxreader
, IVBSAXXMLReader_iface
);
298 static inline saxreader
*impl_from_ISAXXMLReader( ISAXXMLReader
*iface
)
300 return CONTAINING_RECORD(iface
, saxreader
, ISAXXMLReader_iface
);
303 static inline saxlocator
*impl_from_IVBSAXLocator( IVBSAXLocator
*iface
)
305 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXLocator_iface
);
308 static inline saxlocator
*impl_from_ISAXLocator( ISAXLocator
*iface
)
310 return CONTAINING_RECORD(iface
, saxlocator
, ISAXLocator_iface
);
313 static inline saxlocator
*impl_from_IVBSAXAttributes( IVBSAXAttributes
*iface
)
315 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXAttributes_iface
);
318 static inline saxlocator
*impl_from_ISAXAttributes( ISAXAttributes
*iface
)
320 return CONTAINING_RECORD(iface
, saxlocator
, ISAXAttributes_iface
);
323 static inline BOOL
saxreader_has_handler(const saxlocator
*locator
, enum saxhandler_type type
)
325 struct saxanyhandler_iface
*iface
= &locator
->saxreader
->saxhandlers
[type
].u
.anyhandler
;
326 return (locator
->vbInterface
&& iface
->vbhandler
) || (!locator
->vbInterface
&& iface
->handler
);
329 static HRESULT
saxreader_saxcharacters(saxlocator
*locator
, BSTR chars
)
331 struct saxcontenthandler_iface
*content
= saxreader_get_contenthandler(locator
->saxreader
);
334 if (!saxreader_has_handler(locator
, SAXContentHandler
)) return S_OK
;
336 if (locator
->vbInterface
)
337 hr
= IVBSAXContentHandler_characters(content
->vbhandler
, &chars
);
339 hr
= ISAXContentHandler_characters(content
->handler
, chars
, SysStringLen(chars
));
345 static const WCHAR PropertyCharsetW
[] = {
346 'c','h','a','r','s','e','t',0
348 static const WCHAR PropertyXmlDeclVersionW
[] = {
349 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
351 static const WCHAR PropertyDeclHandlerW
[] = {
352 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
353 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
354 'd','e','c','l','a','r','a','t','i','o','n',
355 '-','h','a','n','d','l','e','r',0
357 static const WCHAR PropertyDomNodeW
[] = {
358 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
359 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
360 'd','o','m','-','n','o','d','e',0
362 static const WCHAR PropertyInputSourceW
[] = {
363 'i','n','p','u','t','-','s','o','u','r','c','e',0
365 static const WCHAR PropertyLexicalHandlerW
[] = {
366 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
367 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
368 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
370 static const WCHAR PropertyMaxElementDepthW
[] = {
371 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
373 static const WCHAR PropertyMaxXMLSizeW
[] = {
374 'm','a','x','-','x','m','l','-','s','i','z','e',0
376 static const WCHAR PropertySchemaDeclHandlerW
[] = {
377 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
378 'h','a','n','d','l','e','r',0
380 static const WCHAR PropertyXMLDeclEncodingW
[] = {
381 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
383 static const WCHAR PropertyXMLDeclStandaloneW
[] = {
384 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
386 static const WCHAR PropertyXMLDeclVersionW
[] = {
387 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
390 static inline HRESULT
set_feature_value(saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL value
)
392 /* handling of non-VARIANT_* values is version dependent */
393 if ((reader
->version
< MSXML4
) && (value
!= VARIANT_TRUE
))
394 value
= VARIANT_FALSE
;
395 if ((reader
->version
>= MSXML4
) && (value
!= VARIANT_FALSE
))
396 value
= VARIANT_TRUE
;
398 if (value
== VARIANT_TRUE
)
399 reader
->features
|= feature
;
401 reader
->features
&= ~feature
;
406 static inline HRESULT
get_feature_value(const saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL
*value
)
408 *value
= reader
->features
& feature
? VARIANT_TRUE
: VARIANT_FALSE
;
412 static BOOL
is_namespaces_enabled(const saxreader
*reader
)
414 return (reader
->version
< MSXML4
) || (reader
->features
& Namespaces
);
417 static BSTR
build_qname(BSTR prefix
, BSTR local
)
419 if (prefix
&& *prefix
)
421 BSTR qname
= SysAllocStringLen(NULL
, SysStringLen(prefix
) + SysStringLen(local
) + 1);
425 strcpyW(ptr
, prefix
);
426 ptr
+= SysStringLen(prefix
);
432 return SysAllocString(local
);
435 static element_entry
* alloc_element_entry(const xmlChar
*local
, const xmlChar
*prefix
, int nb_ns
,
436 const xmlChar
**namespaces
)
441 ret
= heap_alloc(sizeof(*ret
));
442 if (!ret
) return ret
;
444 ret
->local
= bstr_from_xmlChar(local
);
445 ret
->prefix
= bstr_from_xmlChar(prefix
);
446 ret
->qname
= build_qname(ret
->prefix
, ret
->local
);
447 ret
->ns
= nb_ns
? heap_alloc(nb_ns
*sizeof(ns
)) : NULL
;
448 ret
->ns_count
= nb_ns
;
450 for (i
=0; i
< nb_ns
; i
++)
452 ret
->ns
[i
].prefix
= bstr_from_xmlChar(namespaces
[2*i
]);
453 ret
->ns
[i
].uri
= bstr_from_xmlChar(namespaces
[2*i
+1]);
459 static void free_element_entry(element_entry
*element
)
463 for (i
=0; i
<element
->ns_count
;i
++)
465 SysFreeString(element
->ns
[i
].prefix
);
466 SysFreeString(element
->ns
[i
].uri
);
469 SysFreeString(element
->prefix
);
470 SysFreeString(element
->local
);
471 SysFreeString(element
->qname
);
473 heap_free(element
->ns
);
477 static void push_element_ns(saxlocator
*locator
, element_entry
*element
)
479 list_add_head(&locator
->elements
, &element
->entry
);
482 static element_entry
* pop_element_ns(saxlocator
*locator
)
484 element_entry
*element
= LIST_ENTRY(list_head(&locator
->elements
), element_entry
, entry
);
487 list_remove(&element
->entry
);
492 static BSTR
find_element_uri(saxlocator
*locator
, const xmlChar
*uri
)
494 element_entry
*element
;
498 if (!uri
) return NULL
;
500 uriW
= bstr_from_xmlChar(uri
);
502 LIST_FOR_EACH_ENTRY(element
, &locator
->elements
, element_entry
, entry
)
504 for (i
=0; i
< element
->ns_count
; i
++)
505 if (!strcmpW(uriW
, element
->ns
[i
].uri
))
508 return element
->ns
[i
].uri
;
513 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri
));
517 /* used to localize version dependent error check behaviour */
518 static inline BOOL
sax_callback_failed(saxlocator
*This
, HRESULT hr
)
520 return This
->saxreader
->version
>= MSXML4
? FAILED(hr
) : hr
!= S_OK
;
523 /* index value -1 means it tries to loop for a first time */
524 static inline BOOL
iterate_endprefix_index(saxlocator
*This
, const element_entry
*element
, int *i
)
526 if (This
->saxreader
->version
>= MSXML4
)
528 if (*i
== -1) *i
= 0; else ++*i
;
529 return *i
< element
->ns_count
;
533 if (*i
== -1) *i
= element
->ns_count
-1; else --*i
;
538 static BOOL
bstr_pool_insert(struct bstrpool
*pool
, BSTR pool_entry
)
542 pool
->pool
= HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(*pool
->pool
));
549 else if (pool
->index
== pool
->len
)
551 BSTR
*realloc
= HeapReAlloc(GetProcessHeap(), 0, pool
->pool
, pool
->len
* 2 * sizeof(*realloc
));
556 pool
->pool
= realloc
;
560 pool
->pool
[pool
->index
++] = pool_entry
;
564 static void free_bstr_pool(struct bstrpool
*pool
)
568 for (i
= 0; i
< pool
->index
; i
++)
569 SysFreeString(pool
->pool
[i
]);
571 HeapFree(GetProcessHeap(), 0, pool
->pool
);
574 pool
->index
= pool
->len
= 0;
577 static BSTR
bstr_from_xmlCharN(const xmlChar
*buf
, int len
)
585 dLen
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
586 if(len
!= -1) dLen
++;
587 bstr
= SysAllocStringLen(NULL
, dLen
-1);
590 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, bstr
, dLen
);
591 if(len
!= -1) bstr
[dLen
-1] = '\0';
596 static BSTR
QName_from_xmlChar(const xmlChar
*prefix
, const xmlChar
*name
)
601 if(!name
) return NULL
;
603 if(!prefix
|| !*prefix
)
604 return bstr_from_xmlChar(name
);
606 qname
= xmlBuildQName(name
, prefix
, NULL
, 0);
607 bstr
= bstr_from_xmlChar(qname
);
613 static BSTR
pooled_bstr_from_xmlChar(struct bstrpool
*pool
, const xmlChar
*buf
)
615 BSTR pool_entry
= bstr_from_xmlChar(buf
);
617 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
619 SysFreeString(pool_entry
);
626 static BSTR
pooled_bstr_from_xmlCharN(struct bstrpool
*pool
, const xmlChar
*buf
, int len
)
628 BSTR pool_entry
= bstr_from_xmlCharN(buf
, len
);
630 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
632 SysFreeString(pool_entry
);
639 static void format_error_message_from_id(saxlocator
*This
, HRESULT hr
)
641 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
642 xmlStopParser(This
->pParserCtxt
);
645 if (saxreader_has_handler(This
, SAXErrorHandler
))
648 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
,
649 NULL
, hr
, 0, msg
, sizeof(msg
), NULL
))
651 FIXME("MSXML errors not yet supported.\n");
655 if(This
->vbInterface
)
657 BSTR bstrMsg
= SysAllocString(msg
);
658 IVBSAXErrorHandler_fatalError(handler
->vbhandler
,
659 &This
->IVBSAXLocator_iface
, &bstrMsg
, hr
);
660 SysFreeString(bstrMsg
);
663 ISAXErrorHandler_fatalError(handler
->handler
,
664 &This
->ISAXLocator_iface
, msg
, hr
);
668 static void update_position(saxlocator
*This
, BOOL fix_column
)
670 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
672 This
->line
= xmlSAX2GetLineNumber(This
->pParserCtxt
);
676 for(; *p
!='\n' && *p
!='\r' && p
>=This
->pParserCtxt
->input
->base
; p
--)
681 This
->column
= xmlSAX2GetColumnNumber(This
->pParserCtxt
);
685 /*** IVBSAXAttributes interface ***/
686 static HRESULT WINAPI
ivbsaxattributes_QueryInterface(
687 IVBSAXAttributes
* iface
,
691 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
692 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
693 return IVBSAXLocator_QueryInterface(&This
->IVBSAXLocator_iface
, riid
, ppvObject
);
696 static ULONG WINAPI
ivbsaxattributes_AddRef(IVBSAXAttributes
* iface
)
698 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
699 return IVBSAXLocator_AddRef(&This
->IVBSAXLocator_iface
);
702 static ULONG WINAPI
ivbsaxattributes_Release(IVBSAXAttributes
* iface
)
704 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
705 return IVBSAXLocator_Release(&This
->IVBSAXLocator_iface
);
708 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes
*iface
, UINT
* pctinfo
)
710 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
712 TRACE("(%p)->(%p)\n", This
, pctinfo
);
719 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfo(
720 IVBSAXAttributes
*iface
,
721 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
723 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
725 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
727 return get_typeinfo(IVBSAXAttributes_tid
, ppTInfo
);
730 static HRESULT WINAPI
ivbsaxattributes_GetIDsOfNames(
731 IVBSAXAttributes
*iface
,
738 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
742 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
745 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
748 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
751 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
752 ITypeInfo_Release(typeinfo
);
758 static HRESULT WINAPI
ivbsaxattributes_Invoke(
759 IVBSAXAttributes
*iface
,
764 DISPPARAMS
* pDispParams
,
766 EXCEPINFO
* pExcepInfo
,
769 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
773 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
774 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
776 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
779 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXAttributes_iface
, dispIdMember
, wFlags
,
780 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
781 ITypeInfo_Release(typeinfo
);
787 /*** IVBSAXAttributes methods ***/
788 static HRESULT WINAPI
ivbsaxattributes_get_length(
789 IVBSAXAttributes
* iface
,
792 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
793 return ISAXAttributes_getLength(&This
->ISAXAttributes_iface
, nLength
);
796 static HRESULT WINAPI
ivbsaxattributes_getURI(
797 IVBSAXAttributes
* iface
,
801 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
806 TRACE("(%p)->(%d %p)\n", This
, nIndex
, uri
);
812 hr
= ISAXAttributes_getURI(&This
->ISAXAttributes_iface
, nIndex
, &uriW
, &len
);
816 return return_bstrn(uriW
, len
, uri
);
819 static HRESULT WINAPI
ivbsaxattributes_getLocalName(
820 IVBSAXAttributes
* iface
,
824 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
829 TRACE("(%p)->(%d %p)\n", This
, nIndex
, name
);
835 hr
= ISAXAttributes_getLocalName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
839 return return_bstrn(nameW
, len
, name
);
842 static HRESULT WINAPI
ivbsaxattributes_getQName(
843 IVBSAXAttributes
* iface
,
847 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
852 TRACE("(%p)->(%d %p)\n", This
, nIndex
, QName
);
858 hr
= ISAXAttributes_getQName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
862 return return_bstrn(nameW
, len
, QName
);
865 static HRESULT WINAPI
ivbsaxattributes_getIndexFromName(
866 IVBSAXAttributes
* iface
,
871 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
872 return ISAXAttributes_getIndexFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
873 localName
, SysStringLen(localName
), index
);
876 static HRESULT WINAPI
ivbsaxattributes_getIndexFromQName(
877 IVBSAXAttributes
* iface
,
881 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
882 return ISAXAttributes_getIndexFromQName(&This
->ISAXAttributes_iface
, QName
,
883 SysStringLen(QName
), index
);
886 static HRESULT WINAPI
ivbsaxattributes_getType(
887 IVBSAXAttributes
* iface
,
891 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
896 TRACE("(%p)->(%d %p)\n", This
, nIndex
, type
);
902 hr
= ISAXAttributes_getType(&This
->ISAXAttributes_iface
, nIndex
, &typeW
, &len
);
906 return return_bstrn(typeW
, len
, type
);
909 static HRESULT WINAPI
ivbsaxattributes_getTypeFromName(
910 IVBSAXAttributes
* iface
,
915 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
920 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), type
);
926 hr
= ISAXAttributes_getTypeFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
927 localName
, SysStringLen(localName
), &typeW
, &len
);
931 return return_bstrn(typeW
, len
, type
);
934 static HRESULT WINAPI
ivbsaxattributes_getTypeFromQName(
935 IVBSAXAttributes
* iface
,
939 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
944 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), type
);
950 hr
= ISAXAttributes_getTypeFromQName(&This
->ISAXAttributes_iface
, QName
, SysStringLen(QName
),
955 return return_bstrn(typeW
, len
, type
);
958 static HRESULT WINAPI
ivbsaxattributes_getValue(
959 IVBSAXAttributes
* iface
,
963 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
968 TRACE("(%p)->(%d %p)\n", This
, nIndex
, value
);
974 hr
= ISAXAttributes_getValue(&This
->ISAXAttributes_iface
, nIndex
, &valueW
, &len
);
978 return return_bstrn(valueW
, len
, value
);
981 static HRESULT WINAPI
ivbsaxattributes_getValueFromName(
982 IVBSAXAttributes
* iface
,
987 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
992 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), value
);
998 hr
= ISAXAttributes_getValueFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
999 localName
, SysStringLen(localName
), &valueW
, &len
);
1003 return return_bstrn(valueW
, len
, value
);
1006 static HRESULT WINAPI
ivbsaxattributes_getValueFromQName(
1007 IVBSAXAttributes
* iface
,
1011 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1012 const WCHAR
*valueW
;
1016 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), value
);
1022 hr
= ISAXAttributes_getValueFromQName(&This
->ISAXAttributes_iface
, QName
,
1023 SysStringLen(QName
), &valueW
, &len
);
1027 return return_bstrn(valueW
, len
, value
);
1030 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl
=
1032 ivbsaxattributes_QueryInterface
,
1033 ivbsaxattributes_AddRef
,
1034 ivbsaxattributes_Release
,
1035 ivbsaxattributes_GetTypeInfoCount
,
1036 ivbsaxattributes_GetTypeInfo
,
1037 ivbsaxattributes_GetIDsOfNames
,
1038 ivbsaxattributes_Invoke
,
1039 ivbsaxattributes_get_length
,
1040 ivbsaxattributes_getURI
,
1041 ivbsaxattributes_getLocalName
,
1042 ivbsaxattributes_getQName
,
1043 ivbsaxattributes_getIndexFromName
,
1044 ivbsaxattributes_getIndexFromQName
,
1045 ivbsaxattributes_getType
,
1046 ivbsaxattributes_getTypeFromName
,
1047 ivbsaxattributes_getTypeFromQName
,
1048 ivbsaxattributes_getValue
,
1049 ivbsaxattributes_getValueFromName
,
1050 ivbsaxattributes_getValueFromQName
1053 /*** ISAXAttributes interface ***/
1054 /*** IUnknown methods ***/
1055 static HRESULT WINAPI
isaxattributes_QueryInterface(
1056 ISAXAttributes
* iface
,
1060 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1061 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
1062 return ISAXLocator_QueryInterface(&This
->ISAXLocator_iface
, riid
, ppvObject
);
1065 static ULONG WINAPI
isaxattributes_AddRef(ISAXAttributes
* iface
)
1067 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1068 TRACE("%p\n", This
);
1069 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
1072 static ULONG WINAPI
isaxattributes_Release(ISAXAttributes
* iface
)
1074 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1076 TRACE("%p\n", This
);
1077 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
1080 /*** ISAXAttributes methods ***/
1081 static HRESULT WINAPI
isaxattributes_getLength(
1082 ISAXAttributes
* iface
,
1085 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1087 *length
= This
->nb_attributes
;
1088 TRACE("Length set to %d\n", *length
);
1092 static HRESULT WINAPI
isaxattributes_getURI(
1093 ISAXAttributes
* iface
,
1098 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1099 TRACE("(%p)->(%d)\n", This
, index
);
1101 if(index
>= This
->nb_attributes
|| index
< 0) return E_INVALIDARG
;
1102 if(!url
|| !size
) return E_POINTER
;
1104 *size
= SysStringLen(This
->attributes
[index
].szURI
);
1105 *url
= This
->attributes
[index
].szURI
;
1107 TRACE("(%s:%d)\n", debugstr_w(This
->attributes
[index
].szURI
), *size
);
1112 static HRESULT WINAPI
isaxattributes_getLocalName(
1113 ISAXAttributes
* iface
,
1115 const WCHAR
**pLocalName
,
1116 int *pLocalNameLength
)
1118 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1119 TRACE("(%p)->(%d)\n", This
, nIndex
);
1121 if(nIndex
>=This
->nb_attributes
|| nIndex
<0) return E_INVALIDARG
;
1122 if(!pLocalName
|| !pLocalNameLength
) return E_POINTER
;
1124 *pLocalNameLength
= SysStringLen(This
->attributes
[nIndex
].szLocalname
);
1125 *pLocalName
= This
->attributes
[nIndex
].szLocalname
;
1130 static HRESULT WINAPI
isaxattributes_getQName(
1131 ISAXAttributes
* iface
,
1133 const WCHAR
**pQName
,
1136 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1137 TRACE("(%p)->(%d)\n", This
, nIndex
);
1139 if(nIndex
>=This
->nb_attributes
|| nIndex
<0) return E_INVALIDARG
;
1140 if(!pQName
|| !pQNameLength
) return E_POINTER
;
1142 *pQNameLength
= SysStringLen(This
->attributes
[nIndex
].szQName
);
1143 *pQName
= This
->attributes
[nIndex
].szQName
;
1148 static HRESULT WINAPI
isaxattributes_getName(
1149 ISAXAttributes
* iface
,
1153 const WCHAR
**localName
,
1154 int *pLocalNameSize
,
1155 const WCHAR
**QName
,
1158 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1159 TRACE("(%p)->(%d)\n", This
, index
);
1161 if(index
>=This
->nb_attributes
|| index
<0) return E_INVALIDARG
;
1162 if(!uri
|| !pUriLength
|| !localName
|| !pLocalNameSize
1163 || !QName
|| !pQNameLength
) return E_POINTER
;
1165 *pUriLength
= SysStringLen(This
->attributes
[index
].szURI
);
1166 *uri
= This
->attributes
[index
].szURI
;
1167 *pLocalNameSize
= SysStringLen(This
->attributes
[index
].szLocalname
);
1168 *localName
= This
->attributes
[index
].szLocalname
;
1169 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1170 *QName
= This
->attributes
[index
].szQName
;
1172 TRACE("(%s, %s, %s)\n", debugstr_w(*uri
), debugstr_w(*localName
), debugstr_w(*QName
));
1177 static HRESULT WINAPI
isaxattributes_getIndexFromName(
1178 ISAXAttributes
* iface
,
1181 const WCHAR
*pLocalName
,
1182 int cocalNameLength
,
1185 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1187 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), cUriLength
,
1188 debugstr_w(pLocalName
), cocalNameLength
);
1190 if(!pUri
|| !pLocalName
|| !index
) return E_POINTER
;
1192 for(i
=0; i
<This
->nb_attributes
; i
++)
1194 if(cUriLength
!=SysStringLen(This
->attributes
[i
].szURI
)
1195 || cocalNameLength
!=SysStringLen(This
->attributes
[i
].szLocalname
))
1197 if(cUriLength
&& memcmp(pUri
, This
->attributes
[i
].szURI
,
1198 sizeof(WCHAR
)*cUriLength
))
1200 if(cocalNameLength
&& memcmp(pLocalName
, This
->attributes
[i
].szLocalname
,
1201 sizeof(WCHAR
)*cocalNameLength
))
1208 return E_INVALIDARG
;
1211 static HRESULT WINAPI
isaxattributes_getIndexFromQName(
1212 ISAXAttributes
* iface
,
1213 const WCHAR
*pQName
,
1217 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1219 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQNameLength
);
1221 if(!pQName
|| !index
) return E_POINTER
;
1222 if(!nQNameLength
) return E_INVALIDARG
;
1224 for(i
=0; i
<This
->nb_attributes
; i
++)
1226 if(nQNameLength
!=SysStringLen(This
->attributes
[i
].szQName
)) continue;
1227 if(memcmp(pQName
, This
->attributes
[i
].szQName
, sizeof(WCHAR
)*nQNameLength
)) continue;
1233 return E_INVALIDARG
;
1236 static HRESULT WINAPI
isaxattributes_getType(
1237 ISAXAttributes
* iface
,
1239 const WCHAR
**pType
,
1242 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1244 FIXME("(%p)->(%d) stub\n", This
, nIndex
);
1248 static HRESULT WINAPI
isaxattributes_getTypeFromName(
1249 ISAXAttributes
* iface
,
1252 const WCHAR
*pLocalName
,
1254 const WCHAR
**pType
,
1257 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1259 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This
, debugstr_w(pUri
), nUri
,
1260 debugstr_w(pLocalName
), nLocalName
);
1264 static HRESULT WINAPI
isaxattributes_getTypeFromQName(
1265 ISAXAttributes
* iface
,
1266 const WCHAR
*pQName
,
1268 const WCHAR
**pType
,
1271 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1273 FIXME("(%p)->(%s, %d) stub\n", This
, debugstr_w(pQName
), nQName
);
1277 static HRESULT WINAPI
isaxattributes_getValue(
1278 ISAXAttributes
* iface
,
1280 const WCHAR
**value
,
1283 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1284 TRACE("(%p)->(%d)\n", This
, index
);
1286 if(index
>=This
->nb_attributes
|| index
<0) return E_INVALIDARG
;
1287 if(!value
|| !nValue
) return E_POINTER
;
1289 *nValue
= SysStringLen(This
->attributes
[index
].szValue
);
1290 *value
= This
->attributes
[index
].szValue
;
1292 TRACE("(%s:%d)\n", debugstr_w(*value
), *nValue
);
1297 static HRESULT WINAPI
isaxattributes_getValueFromName(
1298 ISAXAttributes
* iface
,
1301 const WCHAR
*pLocalName
,
1303 const WCHAR
**pValue
,
1308 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1309 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), nUri
,
1310 debugstr_w(pLocalName
), nLocalName
);
1312 hr
= ISAXAttributes_getIndexFromName(iface
,
1313 pUri
, nUri
, pLocalName
, nLocalName
, &index
);
1314 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1319 static HRESULT WINAPI
isaxattributes_getValueFromQName(
1320 ISAXAttributes
* iface
,
1321 const WCHAR
*pQName
,
1323 const WCHAR
**pValue
,
1328 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1329 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQName
);
1331 hr
= ISAXAttributes_getIndexFromQName(iface
, pQName
, nQName
, &index
);
1332 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1337 static const struct ISAXAttributesVtbl isaxattributes_vtbl
=
1339 isaxattributes_QueryInterface
,
1340 isaxattributes_AddRef
,
1341 isaxattributes_Release
,
1342 isaxattributes_getLength
,
1343 isaxattributes_getURI
,
1344 isaxattributes_getLocalName
,
1345 isaxattributes_getQName
,
1346 isaxattributes_getName
,
1347 isaxattributes_getIndexFromName
,
1348 isaxattributes_getIndexFromQName
,
1349 isaxattributes_getType
,
1350 isaxattributes_getTypeFromName
,
1351 isaxattributes_getTypeFromQName
,
1352 isaxattributes_getValue
,
1353 isaxattributes_getValueFromName
,
1354 isaxattributes_getValueFromQName
1357 /* Libxml2 escapes '&' back to char reference '&' in attribute value,
1358 so when document has escaped value with '&' it's parsed to '&' and then
1359 escaped to '&'. This function takes care of ampersands only. */
1360 static BSTR
saxreader_get_unescaped_value(const xmlChar
*buf
, int len
)
1362 static const WCHAR ampescW
[] = {'&','#','3','8',';',0};
1363 WCHAR
*dest
, *ptrW
, *str
;
1370 str_len
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
1371 if (len
!= -1) str_len
++;
1373 str
= heap_alloc(str_len
*sizeof(WCHAR
));
1374 if (!str
) return NULL
;
1376 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, str
, str_len
);
1377 if (len
!= -1) str
[str_len
-1] = 0;
1380 while ((dest
= strstrW(ptrW
, ampescW
)))
1384 /* leave first '&' from a reference as a value */
1385 src
= dest
+ (sizeof(ampescW
)/sizeof(WCHAR
) - 1);
1388 /* move together with null terminator */
1389 memmove(dest
, src
, (strlenW(src
) + 1)*sizeof(WCHAR
));
1394 bstr
= SysAllocString(str
);
1400 static void free_attribute_values(saxlocator
*locator
)
1404 for (i
= 0; i
< locator
->nb_attributes
; i
++)
1406 SysFreeString(locator
->attributes
[i
].szLocalname
);
1407 locator
->attributes
[i
].szLocalname
= NULL
;
1409 SysFreeString(locator
->attributes
[i
].szValue
);
1410 locator
->attributes
[i
].szValue
= NULL
;
1412 SysFreeString(locator
->attributes
[i
].szQName
);
1413 locator
->attributes
[i
].szQName
= NULL
;
1417 static HRESULT
SAXAttributes_populate(saxlocator
*locator
,
1418 int nb_namespaces
, const xmlChar
**xmlNamespaces
,
1419 int nb_attributes
, const xmlChar
**xmlAttributes
)
1421 static const xmlChar xmlns
[] = "xmlns";
1422 static const WCHAR xmlnsW
[] = { 'x','m','l','n','s',0 };
1424 struct _attributes
*attrs
;
1427 /* skip namespace definitions */
1428 if ((locator
->saxreader
->features
& NamespacePrefixes
) == 0)
1431 locator
->nb_attributes
= nb_namespaces
+ nb_attributes
;
1432 if(locator
->nb_attributes
> locator
->attributesSize
)
1434 int new_size
= locator
->attributesSize
* 2;
1435 attrs
= heap_realloc_zero(locator
->attributes
, new_size
* sizeof(struct _attributes
));
1438 free_attribute_values(locator
);
1439 locator
->nb_attributes
= 0;
1440 return E_OUTOFMEMORY
;
1442 locator
->attributes
= attrs
;
1443 locator
->attributesSize
= new_size
;
1447 attrs
= locator
->attributes
;
1450 for (i
= 0; i
< nb_namespaces
; i
++)
1452 SysFreeString(attrs
[nb_attributes
+i
].szLocalname
);
1453 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1455 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1457 SysFreeString(attrs
[nb_attributes
+i
].szValue
);
1458 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1460 SysFreeString(attrs
[nb_attributes
+i
].szQName
);
1461 if(!xmlNamespaces
[2*i
])
1462 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1464 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1467 for (i
= 0; i
< nb_attributes
; i
++)
1469 static const xmlChar xmlA
[] = "xml";
1471 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1472 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1474 /* that's an important feature to keep same uri pointer for every reported attribute */
1475 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1477 SysFreeString(attrs
[i
].szLocalname
);
1478 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1480 SysFreeString(attrs
[i
].szValue
);
1481 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1483 SysFreeString(attrs
[i
].szQName
);
1484 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1], xmlAttributes
[i
*5]);
1490 /*** LibXML callbacks ***/
1491 static void libxmlStartDocument(void *ctx
)
1493 saxlocator
*This
= ctx
;
1494 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1497 if (This
->saxreader
->version
>= MSXML4
)
1499 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1500 update_position(This
, FALSE
);
1501 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1503 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1508 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1512 /* store version value, declaration has to contain version attribute */
1513 if (This
->pParserCtxt
->standalone
!= -1)
1515 SysFreeString(This
->saxreader
->xmldecl_version
);
1516 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1519 if (saxreader_has_handler(This
, SAXContentHandler
))
1521 if(This
->vbInterface
)
1522 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1524 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1526 if (sax_callback_failed(This
, hr
))
1527 format_error_message_from_id(This
, hr
);
1531 static void libxmlEndDocument(void *ctx
)
1533 saxlocator
*This
= ctx
;
1534 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1537 if (This
->saxreader
->version
>= MSXML4
) {
1538 update_position(This
, FALSE
);
1539 if(This
->column
> 1)
1547 if(This
->ret
!= S_OK
) return;
1549 if (saxreader_has_handler(This
, SAXContentHandler
))
1551 if(This
->vbInterface
)
1552 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1554 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1556 if (sax_callback_failed(This
, hr
))
1557 format_error_message_from_id(This
, hr
);
1561 static void libxmlStartElementNS(
1563 const xmlChar
*localname
,
1564 const xmlChar
*prefix
,
1567 const xmlChar
**namespaces
,
1570 const xmlChar
**attributes
)
1572 saxlocator
*This
= ctx
;
1573 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1574 element_entry
*element
;
1578 update_position(This
, TRUE
);
1579 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1581 if(This
->saxreader
->version
< MSXML4
)
1584 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1585 push_element_ns(This
, element
);
1587 if (is_namespaces_enabled(This
->saxreader
))
1591 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1593 if (This
->vbInterface
)
1594 hr
= IVBSAXContentHandler_startPrefixMapping(
1596 &element
->ns
[i
].prefix
,
1597 &element
->ns
[i
].uri
);
1599 hr
= ISAXContentHandler_startPrefixMapping(
1601 element
->ns
[i
].prefix
,
1602 SysStringLen(element
->ns
[i
].prefix
),
1604 SysStringLen(element
->ns
[i
].uri
));
1606 if (sax_callback_failed(This
, hr
))
1608 format_error_message_from_id(This
, hr
);
1614 uri
= find_element_uri(This
, URI
);
1615 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1616 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1620 if (is_namespaces_enabled(This
->saxreader
))
1621 local
= element
->local
;
1625 if (This
->vbInterface
)
1626 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1627 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1629 hr
= ISAXContentHandler_startElement(handler
->handler
,
1630 uri
, SysStringLen(uri
),
1631 local
, SysStringLen(local
),
1632 element
->qname
, SysStringLen(element
->qname
),
1633 &This
->ISAXAttributes_iface
);
1635 if (sax_callback_failed(This
, hr
))
1636 format_error_message_from_id(This
, hr
);
1640 static void libxmlEndElementNS(
1642 const xmlChar
*localname
,
1643 const xmlChar
*prefix
,
1646 saxlocator
*This
= ctx
;
1647 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1648 element_entry
*element
;
1653 update_position(This
, FALSE
);
1654 p
= This
->pParserCtxt
->input
->cur
;
1656 if (This
->saxreader
->version
>= MSXML4
)
1659 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1661 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1666 else if(*(p
-1)!='>' || *(p
-2)!='/')
1669 while(p
-2>=This
->pParserCtxt
->input
->base
1670 && *(p
-2)!='<' && *(p
-1)!='/')
1672 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1678 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1681 uri
= find_element_uri(This
, URI
);
1682 element
= pop_element_ns(This
);
1684 if (!saxreader_has_handler(This
, SAXContentHandler
))
1686 free_attribute_values(This
);
1687 This
->nb_attributes
= 0;
1688 free_element_entry(element
);
1692 if (is_namespaces_enabled(This
->saxreader
))
1693 local
= element
->local
;
1697 if (This
->vbInterface
)
1698 hr
= IVBSAXContentHandler_endElement(
1700 &uri
, &local
, &element
->qname
);
1702 hr
= ISAXContentHandler_endElement(
1704 uri
, SysStringLen(uri
),
1705 local
, SysStringLen(local
),
1706 element
->qname
, SysStringLen(element
->qname
));
1708 free_attribute_values(This
);
1709 This
->nb_attributes
= 0;
1711 if (sax_callback_failed(This
, hr
))
1713 format_error_message_from_id(This
, hr
);
1714 free_element_entry(element
);
1718 if (is_namespaces_enabled(This
->saxreader
))
1721 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1723 if (This
->vbInterface
)
1724 hr
= IVBSAXContentHandler_endPrefixMapping(
1725 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1727 hr
= ISAXContentHandler_endPrefixMapping(
1728 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1730 if (sax_callback_failed(This
, hr
)) break;
1733 if (sax_callback_failed(This
, hr
))
1734 format_error_message_from_id(This
, hr
);
1737 free_element_entry(element
);
1740 static void libxmlCharacters(
1745 saxlocator
*This
= ctx
;
1749 BOOL lastEvent
= FALSE
;
1751 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1753 update_position(This
, FALSE
);
1754 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1755 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1757 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1762 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1766 if(*(ch
-1)=='\r') cur
--;
1771 while(end
-ch
<len
&& *end
!='\r') end
++;
1782 if (This
->saxreader
->version
>= MSXML4
)
1786 for(p
=cur
; p
!=end
; p
++)
1803 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1804 hr
= saxreader_saxcharacters(This
, Chars
);
1806 if (sax_callback_failed(This
, hr
))
1808 format_error_message_from_id(This
, hr
);
1812 if (This
->saxreader
->version
< MSXML4
)
1813 This
->column
+= end
-cur
;
1826 if(end
-ch
== len
) break;
1830 static void libxmlSetDocumentLocator(
1832 xmlSAXLocatorPtr loc
)
1834 saxlocator
*This
= ctx
;
1835 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1838 if (saxreader_has_handler(This
, SAXContentHandler
))
1840 if(This
->vbInterface
)
1841 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1842 &This
->IVBSAXLocator_iface
);
1844 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1848 format_error_message_from_id(This
, hr
);
1851 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1853 saxlocator
*This
= ctx
;
1854 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1857 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1859 update_position(This
, FALSE
);
1860 while(p
-4>=This
->pParserCtxt
->input
->base
1861 && memcmp(p
-4, "<!--", sizeof(char[4])))
1863 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1869 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1872 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1874 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1876 if (This
->vbInterface
)
1877 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1879 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1882 format_error_message_from_id(This
, hr
);
1885 static void libxmlFatalError(void *ctx
, const char *msg
, ...)
1887 saxlocator
*This
= ctx
;
1888 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1894 if(This
->ret
!= S_OK
) {
1895 xmlStopParser(This
->pParserCtxt
);
1899 va_start(args
, msg
);
1900 vsprintf(message
, msg
, args
);
1903 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1904 error
= heap_alloc(sizeof(WCHAR
)*len
);
1907 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1908 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1911 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1913 xmlStopParser(This
->pParserCtxt
);
1919 FIXME("Error handling is not compatible.\n");
1921 if(This
->vbInterface
)
1923 BSTR bstrError
= SysAllocString(error
);
1924 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1925 &bstrError
, E_FAIL
);
1926 SysFreeString(bstrError
);
1929 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1933 xmlStopParser(This
->pParserCtxt
);
1937 /* The only reason this helper exists is that CDATA section are reported by chunks,
1938 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1940 This helper should be called for substring with trailing newlines.
1942 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1944 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1947 ptr
= bstr
+ len
- 1;
1948 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1953 /* replace returns as:
1955 - "\r<char>" -> "\n<char>"
1961 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
1964 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
1971 ret
= SysAllocStringLen(bstr
, len
);
1972 SysFreeString(bstr
);
1976 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
1978 const xmlChar
*start
, *end
;
1979 saxlocator
*locator
= ctx
;
1980 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
1985 update_position(locator
, FALSE
);
1986 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
1988 if (locator
->vbInterface
)
1989 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
1991 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
1996 format_error_message_from_id(locator
, hr
);
2006 /* scan for newlines */
2007 if (value
[i
] == '\r' || value
[i
] == '\n')
2009 /* skip newlines/linefeeds */
2012 if (value
[i
] != '\r' && value
[i
] != '\n') break;
2018 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
2019 TRACE("(chunk %s)\n", debugstr_w(chars
));
2020 hr
= saxreader_saxcharacters(locator
, chars
);
2021 SysFreeString(chars
);
2030 /* no newline chars (or last chunk) report as a whole */
2031 if (!end
&& start
== value
)
2034 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
2035 TRACE("(%s)\n", debugstr_w(chars
));
2036 hr
= saxreader_saxcharacters(locator
, chars
);
2037 SysFreeString(chars
);
2040 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2042 if (locator
->vbInterface
)
2043 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
2045 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
2049 format_error_message_from_id(locator
, hr
);
2052 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
2054 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
2055 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
2058 /*** IVBSAXLocator interface ***/
2059 /*** IUnknown methods ***/
2060 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2062 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2064 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2068 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2069 IsEqualGUID( riid
, &IID_IDispatch
) ||
2070 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
2074 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
2076 *ppvObject
= &This
->IVBSAXAttributes_iface
;
2080 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2081 return E_NOINTERFACE
;
2084 IVBSAXLocator_AddRef( iface
);
2089 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
2091 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2092 TRACE("%p\n", This
);
2093 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
2096 static ULONG WINAPI
ivbsaxlocator_Release(IVBSAXLocator
* iface
)
2098 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2099 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
2102 /*** IDispatch methods ***/
2103 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
2105 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2107 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2114 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
2115 IVBSAXLocator
*iface
,
2116 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2118 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2120 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2122 return get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2125 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2126 IVBSAXLocator
*iface
,
2128 LPOLESTR
* rgszNames
,
2133 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2134 ITypeInfo
*typeinfo
;
2137 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
2140 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2141 return E_INVALIDARG
;
2143 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2146 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2147 ITypeInfo_Release(typeinfo
);
2153 static HRESULT WINAPI
ivbsaxlocator_Invoke(
2154 IVBSAXLocator
*iface
,
2155 DISPID dispIdMember
,
2159 DISPPARAMS
* pDispParams
,
2160 VARIANT
* pVarResult
,
2161 EXCEPINFO
* pExcepInfo
,
2164 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2165 ITypeInfo
*typeinfo
;
2168 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2169 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2171 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2174 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXLocator_iface
, dispIdMember
, wFlags
,
2175 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2176 ITypeInfo_Release(typeinfo
);
2182 /*** IVBSAXLocator methods ***/
2183 static HRESULT WINAPI
ivbsaxlocator_get_columnNumber(
2184 IVBSAXLocator
* iface
,
2187 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2188 return ISAXLocator_getColumnNumber(&This
->ISAXLocator_iface
, pnColumn
);
2191 static HRESULT WINAPI
ivbsaxlocator_get_lineNumber(
2192 IVBSAXLocator
* iface
,
2195 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2196 return ISAXLocator_getLineNumber(&This
->ISAXLocator_iface
, pnLine
);
2199 static HRESULT WINAPI
ivbsaxlocator_get_publicId(IVBSAXLocator
* iface
, BSTR
*ret
)
2201 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2202 const WCHAR
*publicidW
;
2205 TRACE("(%p)->(%p)\n", This
, ret
);
2211 hr
= ISAXLocator_getPublicId(&This
->ISAXLocator_iface
, &publicidW
);
2215 return return_bstr(publicidW
, ret
);
2218 static HRESULT WINAPI
ivbsaxlocator_get_systemId(IVBSAXLocator
* iface
, BSTR
*ret
)
2220 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2221 const WCHAR
*systemidW
;
2224 TRACE("(%p)->(%p)\n", This
, ret
);
2230 hr
= ISAXLocator_getSystemId(&This
->ISAXLocator_iface
, &systemidW
);
2234 return return_bstr(systemidW
, ret
);
2237 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl
=
2239 ivbsaxlocator_QueryInterface
,
2240 ivbsaxlocator_AddRef
,
2241 ivbsaxlocator_Release
,
2242 ivbsaxlocator_GetTypeInfoCount
,
2243 ivbsaxlocator_GetTypeInfo
,
2244 ivbsaxlocator_GetIDsOfNames
,
2245 ivbsaxlocator_Invoke
,
2246 ivbsaxlocator_get_columnNumber
,
2247 ivbsaxlocator_get_lineNumber
,
2248 ivbsaxlocator_get_publicId
,
2249 ivbsaxlocator_get_systemId
2252 /*** ISAXLocator interface ***/
2253 /*** IUnknown methods ***/
2254 static HRESULT WINAPI
isaxlocator_QueryInterface(ISAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2256 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2258 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2262 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2263 IsEqualGUID( riid
, &IID_ISAXLocator
))
2267 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
2269 *ppvObject
= &This
->ISAXAttributes_iface
;
2273 WARN("interface %s not implemented\n", debugstr_guid(riid
));
2274 return E_NOINTERFACE
;
2277 ISAXLocator_AddRef( iface
);
2282 static ULONG WINAPI
isaxlocator_AddRef(ISAXLocator
* iface
)
2284 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2285 ULONG ref
= InterlockedIncrement( &This
->ref
);
2286 TRACE("(%p)->(%d)\n", This
, ref
);
2290 static ULONG WINAPI
isaxlocator_Release(
2293 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2294 LONG ref
= InterlockedDecrement( &This
->ref
);
2296 TRACE("(%p)->(%d)\n", This
, ref
);
2300 element_entry
*element
, *element2
;
2303 SysFreeString(This
->publicId
);
2304 SysFreeString(This
->systemId
);
2305 SysFreeString(This
->namespaceUri
);
2307 for(index
=0; index
<This
->attributesSize
; index
++)
2309 SysFreeString(This
->attributes
[index
].szLocalname
);
2310 SysFreeString(This
->attributes
[index
].szValue
);
2311 SysFreeString(This
->attributes
[index
].szQName
);
2313 heap_free(This
->attributes
);
2316 LIST_FOR_EACH_ENTRY_SAFE(element
, element2
, &This
->elements
, element_entry
, entry
)
2318 list_remove(&element
->entry
);
2319 free_element_entry(element
);
2322 ISAXXMLReader_Release(&This
->saxreader
->ISAXXMLReader_iface
);
2329 /*** ISAXLocator methods ***/
2330 static HRESULT WINAPI
isaxlocator_getColumnNumber(
2334 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2336 *pnColumn
= This
->column
;
2340 static HRESULT WINAPI
isaxlocator_getLineNumber(
2344 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2346 *pnLine
= This
->line
;
2350 static HRESULT WINAPI
isaxlocator_getPublicId(
2352 const WCHAR
** ppwchPublicId
)
2355 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2357 SysFreeString(This
->publicId
);
2359 publicId
= bstr_from_xmlChar(xmlSAX2GetPublicId(This
->pParserCtxt
));
2360 if(SysStringLen(publicId
))
2361 This
->publicId
= publicId
;
2364 SysFreeString(publicId
);
2365 This
->publicId
= NULL
;
2368 *ppwchPublicId
= This
->publicId
;
2372 static HRESULT WINAPI
isaxlocator_getSystemId(
2374 const WCHAR
** ppwchSystemId
)
2377 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2379 SysFreeString(This
->systemId
);
2381 systemId
= bstr_from_xmlChar(xmlSAX2GetSystemId(This
->pParserCtxt
));
2382 if(SysStringLen(systemId
))
2383 This
->systemId
= systemId
;
2386 SysFreeString(systemId
);
2387 This
->systemId
= NULL
;
2390 *ppwchSystemId
= This
->systemId
;
2394 static const struct ISAXLocatorVtbl SAXLocatorVtbl
=
2396 isaxlocator_QueryInterface
,
2398 isaxlocator_Release
,
2399 isaxlocator_getColumnNumber
,
2400 isaxlocator_getLineNumber
,
2401 isaxlocator_getPublicId
,
2402 isaxlocator_getSystemId
2405 static HRESULT
SAXLocator_create(saxreader
*reader
, saxlocator
**ppsaxlocator
, BOOL vbInterface
)
2407 static const WCHAR w3xmlns
[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2408 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2410 saxlocator
*locator
;
2412 locator
= heap_alloc( sizeof (*locator
) );
2414 return E_OUTOFMEMORY
;
2416 locator
->IVBSAXLocator_iface
.lpVtbl
= &VBSAXLocatorVtbl
;
2417 locator
->ISAXLocator_iface
.lpVtbl
= &SAXLocatorVtbl
;
2418 locator
->IVBSAXAttributes_iface
.lpVtbl
= &ivbsaxattributes_vtbl
;
2419 locator
->ISAXAttributes_iface
.lpVtbl
= &isaxattributes_vtbl
;
2421 locator
->vbInterface
= vbInterface
;
2423 locator
->saxreader
= reader
;
2424 ISAXXMLReader_AddRef(&reader
->ISAXXMLReader_iface
);
2426 locator
->pParserCtxt
= NULL
;
2427 locator
->publicId
= NULL
;
2428 locator
->systemId
= NULL
;
2429 locator
->line
= reader
->version
< MSXML4
? 0 : 1;
2430 locator
->column
= 0;
2431 locator
->ret
= S_OK
;
2432 if (locator
->saxreader
->version
>= MSXML6
)
2433 locator
->namespaceUri
= SysAllocString(w3xmlns
);
2435 locator
->namespaceUri
= SysAllocStringLen(NULL
, 0);
2436 if(!locator
->namespaceUri
)
2438 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2440 return E_OUTOFMEMORY
;
2443 locator
->attributesSize
= 8;
2444 locator
->nb_attributes
= 0;
2445 locator
->attributes
= heap_alloc_zero(sizeof(struct _attributes
)*locator
->attributesSize
);
2446 if(!locator
->attributes
)
2448 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2449 SysFreeString(locator
->namespaceUri
);
2451 return E_OUTOFMEMORY
;
2454 list_init(&locator
->elements
);
2456 *ppsaxlocator
= locator
;
2458 TRACE("returning %p\n", *ppsaxlocator
);
2463 /*** SAXXMLReader internal functions ***/
2464 static HRESULT
internal_parseBuffer(saxreader
*This
, const char *buffer
, int size
, BOOL vbInterface
)
2466 xmlCharEncoding encoding
= XML_CHAR_ENCODING_NONE
;
2467 xmlChar
*enc_name
= NULL
;
2468 saxlocator
*locator
;
2471 TRACE("(%p)->(%p %d)\n", This
, buffer
, size
);
2473 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2479 const unsigned char *buff
= (unsigned char*)buffer
;
2481 encoding
= xmlDetectCharEncoding((xmlChar
*)buffer
, 4);
2482 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2483 TRACE("detected encoding: %s\n", enc_name
);
2484 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2485 if ((encoding
== XML_CHAR_ENCODING_UTF8
) &&
2486 buff
[0] == 0xEF && buff
[1] == 0xBB && buff
[2] == 0xBF)
2493 /* if libxml2 detection failed try to guess */
2494 if (encoding
== XML_CHAR_ENCODING_NONE
)
2496 const WCHAR
*ptr
= (WCHAR
*)buffer
;
2497 /* xml declaration with possibly specfied encoding will be still handled by parser */
2498 if ((size
>= 2) && *ptr
== '<' && ptr
[1] != '?')
2500 enc_name
= (xmlChar
*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE
);
2501 encoding
= XML_CHAR_ENCODING_UTF16LE
;
2504 else if (encoding
== XML_CHAR_ENCODING_UTF8
)
2505 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2509 locator
->pParserCtxt
= xmlCreateMemoryParserCtxt(buffer
, size
);
2510 if (!locator
->pParserCtxt
)
2512 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2518 locator
->pParserCtxt
->encoding
= xmlStrdup(enc_name
);
2519 if (encoding
== XML_CHAR_ENCODING_UTF16LE
) {
2520 TRACE("switching to %s\n", enc_name
);
2521 xmlSwitchEncoding(locator
->pParserCtxt
, encoding
);
2525 xmlFree(locator
->pParserCtxt
->sax
);
2526 locator
->pParserCtxt
->sax
= &locator
->saxreader
->sax
;
2527 locator
->pParserCtxt
->userData
= locator
;
2529 This
->isParsing
= TRUE
;
2530 if(xmlParseDocument(locator
->pParserCtxt
) == -1 && locator
->ret
== S_OK
)
2534 This
->isParsing
= FALSE
;
2536 if(locator
->pParserCtxt
)
2538 locator
->pParserCtxt
->sax
= NULL
;
2539 xmlFreeParserCtxt(locator
->pParserCtxt
);
2540 locator
->pParserCtxt
= NULL
;
2543 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2547 static HRESULT
internal_parseStream(saxreader
*This
, ISequentialStream
*stream
, BOOL vbInterface
)
2549 saxlocator
*locator
;
2556 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2557 if(FAILED(hr
)) return hr
;
2559 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2560 if(FAILED(hr
)) return hr
;
2562 locator
->pParserCtxt
= xmlCreatePushParserCtxt(
2563 &locator
->saxreader
->sax
, locator
,
2564 data
, dataRead
, NULL
);
2565 if(!locator
->pParserCtxt
)
2567 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2571 This
->isParsing
= TRUE
;
2575 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2576 if (FAILED(hr
) || !dataRead
) break;
2578 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, dataRead
, 0);
2579 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2584 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2585 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2589 This
->isParsing
= FALSE
;
2591 xmlFreeParserCtxt(locator
->pParserCtxt
);
2592 locator
->pParserCtxt
= NULL
;
2593 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2597 static HRESULT
internal_parse(
2604 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varInput
));
2606 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2607 free_bstr_pool(&This
->pool
);
2609 switch(V_VT(&varInput
))
2612 case VT_BSTR
|VT_BYREF
:
2614 BSTR str
= V_ISBYREF(&varInput
) ? *V_BSTRREF(&varInput
) : V_BSTR(&varInput
);
2615 hr
= internal_parseBuffer(This
, (const char*)str
, strlenW(str
)*sizeof(WCHAR
), vbInterface
);
2618 case VT_ARRAY
|VT_UI1
: {
2620 LONG lBound
, uBound
;
2623 hr
= SafeArrayGetLBound(V_ARRAY(&varInput
), 1, &lBound
);
2624 if(hr
!= S_OK
) break;
2625 hr
= SafeArrayGetUBound(V_ARRAY(&varInput
), 1, &uBound
);
2626 if(hr
!= S_OK
) break;
2627 dataRead
= (uBound
-lBound
)*SafeArrayGetElemsize(V_ARRAY(&varInput
));
2628 hr
= SafeArrayAccessData(V_ARRAY(&varInput
), &pSAData
);
2629 if(hr
!= S_OK
) break;
2630 hr
= internal_parseBuffer(This
, pSAData
, dataRead
, vbInterface
);
2631 SafeArrayUnaccessData(V_ARRAY(&varInput
));
2636 IPersistStream
*persistStream
;
2637 ISequentialStream
*stream
= NULL
;
2638 IXMLDOMDocument
*xmlDoc
;
2640 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2641 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2645 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2646 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2647 SysStringByteLen(bstrData
), vbInterface
);
2648 IXMLDOMDocument_Release(xmlDoc
);
2649 SysFreeString(bstrData
);
2653 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2654 &IID_IPersistStream
, (void**)&persistStream
) == S_OK
)
2656 IStream
*stream_copy
;
2658 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream_copy
);
2661 IPersistStream_Release(persistStream
);
2665 hr
= IPersistStream_Save(persistStream
, stream_copy
, TRUE
);
2666 IPersistStream_Release(persistStream
);
2668 IStream_QueryInterface(stream_copy
, &IID_ISequentialStream
, (void**)&stream
);
2670 IStream_Release(stream_copy
);
2673 /* try base interface first */
2676 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2678 /* this should never happen if IStream is implemented properly, but just in case */
2679 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2684 hr
= internal_parseStream(This
, stream
, vbInterface
);
2685 ISequentialStream_Release(stream
);
2689 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2696 WARN("vt %d not implemented\n", V_VT(&varInput
));
2703 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2705 saxreader
*This
= obj
;
2707 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2710 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2712 saxreader
*This
= obj
;
2714 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2717 static HRESULT
internal_parseURL(
2726 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
2728 hr
= create_moniker_from_url(url
, &mon
);
2732 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, This
, &bsc
);
2733 else hr
= bind_url(mon
, internal_onDataAvailable
, This
, &bsc
);
2734 IMoniker_Release(mon
);
2739 return detach_bsc(bsc
);
2742 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2746 if (V_VT(v
) == VT_EMPTY
)
2747 return saxreader_put_handler(This
, type
, NULL
, vb
);
2751 case SAXDeclHandler
:
2752 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2754 case SAXLexicalHandler
:
2755 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2758 ERR("wrong handler type %d\n", type
);
2767 IUnknown
*handler
= NULL
;
2771 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2772 if (FAILED(hr
)) return hr
;
2775 saxreader_put_handler(This
, type
, handler
, vb
);
2776 if (handler
) IUnknown_Release(handler
);
2780 ERR("value type %d not supported\n", V_VT(v
));
2781 return E_INVALIDARG
;
2787 static HRESULT
internal_putProperty(
2795 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2797 if (This
->isParsing
) return E_FAIL
;
2799 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2800 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2801 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2803 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2804 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2806 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2808 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2809 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2813 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2815 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2816 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2820 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2822 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2825 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2828 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2831 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2834 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2837 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2840 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2843 return E_INVALIDARG
;
2846 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2848 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2850 if (!value
) return E_POINTER
;
2852 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2854 V_VT(value
) = VT_UNKNOWN
;
2855 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2859 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2861 V_VT(value
) = VT_UNKNOWN
;
2862 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2866 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2868 V_VT(value
) = VT_BSTR
;
2869 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2873 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2878 /*** IVBSAXXMLReader interface ***/
2879 /*** IUnknown methods ***/
2880 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2882 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2884 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2888 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2889 IsEqualGUID( riid
, &IID_IDispatch
) ||
2890 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2894 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2896 *ppvObject
= &This
->ISAXXMLReader_iface
;
2898 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2900 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2904 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2905 return E_NOINTERFACE
;
2908 IVBSAXXMLReader_AddRef( iface
);
2913 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2915 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2916 TRACE("%p\n", This
);
2917 return InterlockedIncrement( &This
->ref
);
2920 static ULONG WINAPI
saxxmlreader_Release(
2921 IVBSAXXMLReader
* iface
)
2923 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2926 TRACE("%p\n", This
);
2928 ref
= InterlockedDecrement( &This
->ref
);
2933 for (i
= 0; i
< SAXHandler_Last
; i
++)
2935 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2937 if (saxiface
->handler
)
2938 IUnknown_Release(saxiface
->handler
);
2940 if (saxiface
->vbhandler
)
2941 IUnknown_Release(saxiface
->vbhandler
);
2944 SysFreeString(This
->xmldecl_version
);
2945 free_bstr_pool(&This
->pool
);
2953 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2955 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2956 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2959 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2960 IVBSAXXMLReader
*iface
,
2961 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2963 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2964 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2965 iTInfo
, lcid
, ppTInfo
);
2968 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2969 IVBSAXXMLReader
*iface
,
2971 LPOLESTR
* rgszNames
,
2976 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2977 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
2978 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
2981 static HRESULT WINAPI
saxxmlreader_Invoke(
2982 IVBSAXXMLReader
*iface
,
2983 DISPID dispIdMember
,
2987 DISPPARAMS
* pDispParams
,
2988 VARIANT
* pVarResult
,
2989 EXCEPINFO
* pExcepInfo
,
2992 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2993 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
2994 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2997 /*** IVBSAXXMLReader methods ***/
2998 static HRESULT WINAPI
saxxmlreader_getFeature(
2999 IVBSAXXMLReader
* iface
,
3001 VARIANT_BOOL
*value
)
3003 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3004 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3007 static HRESULT WINAPI
saxxmlreader_putFeature(
3008 IVBSAXXMLReader
* iface
,
3012 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3013 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3016 static HRESULT WINAPI
saxxmlreader_getProperty(
3017 IVBSAXXMLReader
* iface
,
3021 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3022 return internal_getProperty(This
, prop
, value
, TRUE
);
3025 static HRESULT WINAPI
saxxmlreader_putProperty(
3026 IVBSAXXMLReader
* iface
,
3030 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3031 return internal_putProperty(This
, pProp
, value
, TRUE
);
3034 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3035 IVBSAXXMLReader
* iface
,
3036 IVBSAXEntityResolver
**resolver
)
3038 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3039 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3042 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3043 IVBSAXXMLReader
* iface
,
3044 IVBSAXEntityResolver
*resolver
)
3046 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3047 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3050 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3051 IVBSAXXMLReader
* iface
,
3052 IVBSAXContentHandler
**handler
)
3054 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3055 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3058 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3059 IVBSAXXMLReader
* iface
,
3060 IVBSAXContentHandler
*handler
)
3062 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3063 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3066 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3067 IVBSAXXMLReader
* iface
,
3068 IVBSAXDTDHandler
**handler
)
3070 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3071 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3074 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3075 IVBSAXXMLReader
* iface
,
3076 IVBSAXDTDHandler
*handler
)
3078 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3079 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3082 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3083 IVBSAXXMLReader
* iface
,
3084 IVBSAXErrorHandler
**handler
)
3086 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3087 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3090 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3091 IVBSAXXMLReader
* iface
,
3092 IVBSAXErrorHandler
*handler
)
3094 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3095 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3098 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3099 IVBSAXXMLReader
* iface
,
3102 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3104 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3108 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3109 IVBSAXXMLReader
* iface
,
3112 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3113 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3116 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3117 IVBSAXXMLReader
* iface
,
3118 BSTR
*pSecureBaseUrl
)
3120 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3122 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3126 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3127 IVBSAXXMLReader
* iface
,
3130 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3131 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3134 static HRESULT WINAPI
saxxmlreader_parse(
3135 IVBSAXXMLReader
* iface
,
3138 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3139 return internal_parse(This
, varInput
, TRUE
);
3142 static HRESULT WINAPI
saxxmlreader_parseURL(
3143 IVBSAXXMLReader
* iface
,
3146 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3147 return internal_parseURL(This
, url
, TRUE
);
3150 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3152 saxxmlreader_QueryInterface
,
3153 saxxmlreader_AddRef
,
3154 saxxmlreader_Release
,
3155 saxxmlreader_GetTypeInfoCount
,
3156 saxxmlreader_GetTypeInfo
,
3157 saxxmlreader_GetIDsOfNames
,
3158 saxxmlreader_Invoke
,
3159 saxxmlreader_getFeature
,
3160 saxxmlreader_putFeature
,
3161 saxxmlreader_getProperty
,
3162 saxxmlreader_putProperty
,
3163 saxxmlreader_get_entityResolver
,
3164 saxxmlreader_put_entityResolver
,
3165 saxxmlreader_get_contentHandler
,
3166 saxxmlreader_put_contentHandler
,
3167 saxxmlreader_get_dtdHandler
,
3168 saxxmlreader_put_dtdHandler
,
3169 saxxmlreader_get_errorHandler
,
3170 saxxmlreader_put_errorHandler
,
3171 saxxmlreader_get_baseURL
,
3172 saxxmlreader_put_baseURL
,
3173 saxxmlreader_get_secureBaseURL
,
3174 saxxmlreader_put_secureBaseURL
,
3176 saxxmlreader_parseURL
3179 /*** ISAXXMLReader interface ***/
3180 /*** IUnknown methods ***/
3181 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3183 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3184 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3187 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3189 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3190 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3193 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3195 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3196 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3199 /*** ISAXXMLReader methods ***/
3200 static HRESULT WINAPI
isaxxmlreader_getFeature(
3201 ISAXXMLReader
* iface
,
3202 const WCHAR
*feature_name
,
3203 VARIANT_BOOL
*value
)
3205 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3206 saxreader_feature feature
;
3208 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3210 feature
= get_saxreader_feature(feature_name
);
3211 if (feature
== Namespaces
|| feature
== NamespacePrefixes
)
3212 return get_feature_value(This
, feature
, value
);
3214 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3218 static HRESULT WINAPI
isaxxmlreader_putFeature(
3219 ISAXXMLReader
* iface
,
3220 const WCHAR
*feature_name
,
3223 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3224 saxreader_feature feature
;
3226 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3228 feature
= get_saxreader_feature(feature_name
);
3230 /* accepted cases */
3231 if ((feature
== ExternalGeneralEntities
&& value
== VARIANT_FALSE
) ||
3232 (feature
== ExternalParameterEntities
&& value
== VARIANT_FALSE
) ||
3233 feature
== Namespaces
||
3234 feature
== NamespacePrefixes
)
3236 return set_feature_value(This
, feature
, value
);
3239 if (feature
== LexicalHandlerParEntities
|| feature
== ProhibitDTD
)
3241 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3242 return set_feature_value(This
, feature
, value
);
3245 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3249 static HRESULT WINAPI
isaxxmlreader_getProperty(
3250 ISAXXMLReader
* iface
,
3254 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3255 return internal_getProperty(This
, prop
, value
, FALSE
);
3258 static HRESULT WINAPI
isaxxmlreader_putProperty(
3259 ISAXXMLReader
* iface
,
3263 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3264 return internal_putProperty(This
, pProp
, value
, FALSE
);
3267 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3268 ISAXXMLReader
* iface
,
3269 ISAXEntityResolver
**resolver
)
3271 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3272 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3275 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3276 ISAXXMLReader
* iface
,
3277 ISAXEntityResolver
*resolver
)
3279 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3280 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3283 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3284 ISAXXMLReader
* iface
,
3285 ISAXContentHandler
**handler
)
3287 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3288 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3291 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3292 ISAXXMLReader
* iface
,
3293 ISAXContentHandler
*handler
)
3295 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3296 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3299 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3300 ISAXXMLReader
* iface
,
3301 ISAXDTDHandler
**handler
)
3303 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3304 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3307 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3308 ISAXXMLReader
* iface
,
3309 ISAXDTDHandler
*handler
)
3311 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3312 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3315 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3316 ISAXXMLReader
* iface
,
3317 ISAXErrorHandler
**handler
)
3319 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3320 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3323 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3325 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3326 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3329 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3330 ISAXXMLReader
* iface
,
3331 const WCHAR
**base_url
)
3333 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3335 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3339 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3340 ISAXXMLReader
* iface
,
3341 const WCHAR
*pBaseUrl
)
3343 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3345 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3349 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3350 ISAXXMLReader
* iface
,
3351 const WCHAR
**pSecureBaseUrl
)
3353 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3354 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3358 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3359 ISAXXMLReader
* iface
,
3360 const WCHAR
*secureBaseUrl
)
3362 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3364 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3368 static HRESULT WINAPI
isaxxmlreader_parse(
3369 ISAXXMLReader
* iface
,
3372 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3373 return internal_parse(This
, varInput
, FALSE
);
3376 static HRESULT WINAPI
isaxxmlreader_parseURL(
3377 ISAXXMLReader
* iface
,
3380 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3381 return internal_parseURL(This
, url
, FALSE
);
3384 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3386 isaxxmlreader_QueryInterface
,
3387 isaxxmlreader_AddRef
,
3388 isaxxmlreader_Release
,
3389 isaxxmlreader_getFeature
,
3390 isaxxmlreader_putFeature
,
3391 isaxxmlreader_getProperty
,
3392 isaxxmlreader_putProperty
,
3393 isaxxmlreader_getEntityResolver
,
3394 isaxxmlreader_putEntityResolver
,
3395 isaxxmlreader_getContentHandler
,
3396 isaxxmlreader_putContentHandler
,
3397 isaxxmlreader_getDTDHandler
,
3398 isaxxmlreader_putDTDHandler
,
3399 isaxxmlreader_getErrorHandler
,
3400 isaxxmlreader_putErrorHandler
,
3401 isaxxmlreader_getBaseURL
,
3402 isaxxmlreader_putBaseURL
,
3403 isaxxmlreader_getSecureBaseURL
,
3404 isaxxmlreader_putSecureBaseURL
,
3405 isaxxmlreader_parse
,
3406 isaxxmlreader_parseURL
3409 static const tid_t saxreader_iface_tids
[] = {
3410 IVBSAXXMLReader_tid
,
3413 static dispex_static_data_t saxreader_dispex
= {
3415 IVBSAXXMLReader_tid
,
3417 saxreader_iface_tids
3420 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3424 TRACE("(%p)\n", ppObj
);
3426 reader
= heap_alloc( sizeof (*reader
) );
3428 return E_OUTOFMEMORY
;
3430 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3431 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3433 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3434 reader
->isParsing
= FALSE
;
3435 reader
->xmldecl_version
= NULL
;
3436 reader
->pool
.pool
= NULL
;
3437 reader
->pool
.index
= 0;
3438 reader
->pool
.len
= 0;
3439 reader
->features
= Namespaces
| NamespacePrefixes
;
3440 reader
->version
= version
;
3442 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3444 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3445 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3446 reader
->sax
.startDocument
= libxmlStartDocument
;
3447 reader
->sax
.endDocument
= libxmlEndDocument
;
3448 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3449 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3450 reader
->sax
.characters
= libxmlCharacters
;
3451 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3452 reader
->sax
.comment
= libxmlComment
;
3453 reader
->sax
.error
= libxmlFatalError
;
3454 reader
->sax
.fatalError
= libxmlFatalError
;
3455 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3456 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3458 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3460 TRACE("returning iface %p\n", *ppObj
);
3467 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3469 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3470 "libxml2 support was not present at compile time.\n");