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
;
282 int attr_alloc_count
;
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
)/sizeof(msg
[0]), 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
->attr_count
;
1088 TRACE("Length set to %d\n", *length
);
1092 static inline BOOL
is_valid_attr_index(const saxlocator
*locator
, int index
)
1094 return index
< locator
->attr_count
&& index
>= 0;
1097 static HRESULT WINAPI
isaxattributes_getURI(
1098 ISAXAttributes
* iface
,
1103 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1104 TRACE("(%p)->(%d)\n", This
, index
);
1106 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1107 if(!url
|| !size
) return E_POINTER
;
1109 *size
= SysStringLen(This
->attributes
[index
].szURI
);
1110 *url
= This
->attributes
[index
].szURI
;
1112 TRACE("(%s:%d)\n", debugstr_w(This
->attributes
[index
].szURI
), *size
);
1117 static HRESULT WINAPI
isaxattributes_getLocalName(
1118 ISAXAttributes
* iface
,
1120 const WCHAR
**pLocalName
,
1121 int *pLocalNameLength
)
1123 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1124 TRACE("(%p)->(%d)\n", This
, index
);
1126 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1127 if(!pLocalName
|| !pLocalNameLength
) return E_POINTER
;
1129 *pLocalNameLength
= SysStringLen(This
->attributes
[index
].szLocalname
);
1130 *pLocalName
= This
->attributes
[index
].szLocalname
;
1135 static HRESULT WINAPI
isaxattributes_getQName(
1136 ISAXAttributes
* iface
,
1138 const WCHAR
**pQName
,
1141 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1142 TRACE("(%p)->(%d)\n", This
, index
);
1144 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1145 if(!pQName
|| !pQNameLength
) return E_POINTER
;
1147 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1148 *pQName
= This
->attributes
[index
].szQName
;
1153 static HRESULT WINAPI
isaxattributes_getName(
1154 ISAXAttributes
* iface
,
1158 const WCHAR
**localName
,
1159 int *pLocalNameSize
,
1160 const WCHAR
**QName
,
1163 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1164 TRACE("(%p)->(%d)\n", This
, index
);
1166 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1167 if(!uri
|| !pUriLength
|| !localName
|| !pLocalNameSize
1168 || !QName
|| !pQNameLength
) return E_POINTER
;
1170 *pUriLength
= SysStringLen(This
->attributes
[index
].szURI
);
1171 *uri
= This
->attributes
[index
].szURI
;
1172 *pLocalNameSize
= SysStringLen(This
->attributes
[index
].szLocalname
);
1173 *localName
= This
->attributes
[index
].szLocalname
;
1174 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1175 *QName
= This
->attributes
[index
].szQName
;
1177 TRACE("(%s, %s, %s)\n", debugstr_w(*uri
), debugstr_w(*localName
), debugstr_w(*QName
));
1182 static HRESULT WINAPI
isaxattributes_getIndexFromName(
1183 ISAXAttributes
* iface
,
1186 const WCHAR
*pLocalName
,
1187 int cocalNameLength
,
1190 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1192 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), cUriLength
,
1193 debugstr_w(pLocalName
), cocalNameLength
);
1195 if(!pUri
|| !pLocalName
|| !index
) return E_POINTER
;
1197 for(i
=0; i
<This
->attr_count
; i
++)
1199 if(cUriLength
!=SysStringLen(This
->attributes
[i
].szURI
)
1200 || cocalNameLength
!=SysStringLen(This
->attributes
[i
].szLocalname
))
1202 if(cUriLength
&& memcmp(pUri
, This
->attributes
[i
].szURI
,
1203 sizeof(WCHAR
)*cUriLength
))
1205 if(cocalNameLength
&& memcmp(pLocalName
, This
->attributes
[i
].szLocalname
,
1206 sizeof(WCHAR
)*cocalNameLength
))
1213 return E_INVALIDARG
;
1216 static HRESULT WINAPI
isaxattributes_getIndexFromQName(
1217 ISAXAttributes
* iface
,
1218 const WCHAR
*pQName
,
1222 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1224 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQNameLength
);
1226 if(!pQName
|| !index
) return E_POINTER
;
1227 if(!nQNameLength
) return E_INVALIDARG
;
1229 for(i
=0; i
<This
->attr_count
; i
++)
1231 if(nQNameLength
!=SysStringLen(This
->attributes
[i
].szQName
)) continue;
1232 if(memcmp(pQName
, This
->attributes
[i
].szQName
, sizeof(WCHAR
)*nQNameLength
)) continue;
1238 return E_INVALIDARG
;
1241 static HRESULT WINAPI
isaxattributes_getType(
1242 ISAXAttributes
* iface
,
1244 const WCHAR
**pType
,
1247 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1249 FIXME("(%p)->(%d) stub\n", This
, nIndex
);
1253 static HRESULT WINAPI
isaxattributes_getTypeFromName(
1254 ISAXAttributes
* iface
,
1257 const WCHAR
*pLocalName
,
1259 const WCHAR
**pType
,
1262 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1264 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This
, debugstr_w(pUri
), nUri
,
1265 debugstr_w(pLocalName
), nLocalName
);
1269 static HRESULT WINAPI
isaxattributes_getTypeFromQName(
1270 ISAXAttributes
* iface
,
1271 const WCHAR
*pQName
,
1273 const WCHAR
**pType
,
1276 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1278 FIXME("(%p)->(%s, %d) stub\n", This
, debugstr_w(pQName
), nQName
);
1282 static HRESULT WINAPI
isaxattributes_getValue(
1283 ISAXAttributes
* iface
,
1285 const WCHAR
**value
,
1288 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1289 TRACE("(%p)->(%d)\n", This
, index
);
1291 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1292 if(!value
|| !nValue
) return E_POINTER
;
1294 *nValue
= SysStringLen(This
->attributes
[index
].szValue
);
1295 *value
= This
->attributes
[index
].szValue
;
1297 TRACE("(%s:%d)\n", debugstr_w(*value
), *nValue
);
1302 static HRESULT WINAPI
isaxattributes_getValueFromName(
1303 ISAXAttributes
* iface
,
1306 const WCHAR
*pLocalName
,
1308 const WCHAR
**pValue
,
1313 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1314 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), nUri
,
1315 debugstr_w(pLocalName
), nLocalName
);
1317 hr
= ISAXAttributes_getIndexFromName(iface
,
1318 pUri
, nUri
, pLocalName
, nLocalName
, &index
);
1319 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1324 static HRESULT WINAPI
isaxattributes_getValueFromQName(
1325 ISAXAttributes
* iface
,
1326 const WCHAR
*pQName
,
1328 const WCHAR
**pValue
,
1333 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1334 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQName
);
1336 hr
= ISAXAttributes_getIndexFromQName(iface
, pQName
, nQName
, &index
);
1337 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1342 static const struct ISAXAttributesVtbl isaxattributes_vtbl
=
1344 isaxattributes_QueryInterface
,
1345 isaxattributes_AddRef
,
1346 isaxattributes_Release
,
1347 isaxattributes_getLength
,
1348 isaxattributes_getURI
,
1349 isaxattributes_getLocalName
,
1350 isaxattributes_getQName
,
1351 isaxattributes_getName
,
1352 isaxattributes_getIndexFromName
,
1353 isaxattributes_getIndexFromQName
,
1354 isaxattributes_getType
,
1355 isaxattributes_getTypeFromName
,
1356 isaxattributes_getTypeFromQName
,
1357 isaxattributes_getValue
,
1358 isaxattributes_getValueFromName
,
1359 isaxattributes_getValueFromQName
1362 /* Libxml2 escapes '&' back to char reference '&' in attribute value,
1363 so when document has escaped value with '&' it's parsed to '&' and then
1364 escaped to '&'. This function takes care of ampersands only. */
1365 static BSTR
saxreader_get_unescaped_value(const xmlChar
*buf
, int len
)
1367 static const WCHAR ampescW
[] = {'&','#','3','8',';',0};
1368 WCHAR
*dest
, *ptrW
, *str
;
1375 str_len
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
1376 if (len
!= -1) str_len
++;
1378 str
= heap_alloc(str_len
*sizeof(WCHAR
));
1379 if (!str
) return NULL
;
1381 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, str
, str_len
);
1382 if (len
!= -1) str
[str_len
-1] = 0;
1385 while ((dest
= strstrW(ptrW
, ampescW
)))
1389 /* leave first '&' from a reference as a value */
1390 src
= dest
+ (sizeof(ampescW
)/sizeof(WCHAR
) - 1);
1393 /* move together with null terminator */
1394 memmove(dest
, src
, (strlenW(src
) + 1)*sizeof(WCHAR
));
1399 bstr
= SysAllocString(str
);
1405 static void free_attribute_values(saxlocator
*locator
)
1409 for (i
= 0; i
< locator
->attr_count
; i
++)
1411 SysFreeString(locator
->attributes
[i
].szLocalname
);
1412 locator
->attributes
[i
].szLocalname
= NULL
;
1414 SysFreeString(locator
->attributes
[i
].szValue
);
1415 locator
->attributes
[i
].szValue
= NULL
;
1417 SysFreeString(locator
->attributes
[i
].szQName
);
1418 locator
->attributes
[i
].szQName
= NULL
;
1422 static HRESULT
SAXAttributes_populate(saxlocator
*locator
,
1423 int nb_namespaces
, const xmlChar
**xmlNamespaces
,
1424 int nb_attributes
, const xmlChar
**xmlAttributes
)
1426 static const xmlChar xmlns
[] = "xmlns";
1427 static const WCHAR xmlnsW
[] = { 'x','m','l','n','s',0 };
1429 struct _attributes
*attrs
;
1432 /* skip namespace definitions */
1433 if ((locator
->saxreader
->features
& NamespacePrefixes
) == 0)
1436 locator
->attr_count
= nb_namespaces
+ nb_attributes
;
1437 if(locator
->attr_count
> locator
->attr_alloc_count
)
1439 int new_size
= locator
->attr_count
* 2;
1440 attrs
= heap_realloc_zero(locator
->attributes
, new_size
* sizeof(struct _attributes
));
1443 free_attribute_values(locator
);
1444 locator
->attr_count
= 0;
1445 return E_OUTOFMEMORY
;
1447 locator
->attributes
= attrs
;
1448 locator
->attr_alloc_count
= new_size
;
1452 attrs
= locator
->attributes
;
1455 for (i
= 0; i
< nb_namespaces
; i
++)
1457 SysFreeString(attrs
[nb_attributes
+i
].szLocalname
);
1458 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1460 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1462 SysFreeString(attrs
[nb_attributes
+i
].szValue
);
1463 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1465 SysFreeString(attrs
[nb_attributes
+i
].szQName
);
1466 if(!xmlNamespaces
[2*i
])
1467 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1469 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1472 for (i
= 0; i
< nb_attributes
; i
++)
1474 static const xmlChar xmlA
[] = "xml";
1476 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1477 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1479 /* that's an important feature to keep same uri pointer for every reported attribute */
1480 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1482 SysFreeString(attrs
[i
].szLocalname
);
1483 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1485 SysFreeString(attrs
[i
].szValue
);
1486 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1488 SysFreeString(attrs
[i
].szQName
);
1489 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1], xmlAttributes
[i
*5]);
1495 /*** LibXML callbacks ***/
1496 static void libxmlStartDocument(void *ctx
)
1498 saxlocator
*This
= ctx
;
1499 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1502 if (This
->saxreader
->version
>= MSXML4
)
1504 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1505 update_position(This
, FALSE
);
1506 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1508 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1513 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1517 /* store version value, declaration has to contain version attribute */
1518 if (This
->pParserCtxt
->standalone
!= -1)
1520 SysFreeString(This
->saxreader
->xmldecl_version
);
1521 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1524 if (saxreader_has_handler(This
, SAXContentHandler
))
1526 if(This
->vbInterface
)
1527 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1529 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1531 if (sax_callback_failed(This
, hr
))
1532 format_error_message_from_id(This
, hr
);
1536 static void libxmlEndDocument(void *ctx
)
1538 saxlocator
*This
= ctx
;
1539 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1542 if (This
->saxreader
->version
>= MSXML4
) {
1543 update_position(This
, FALSE
);
1544 if(This
->column
> 1)
1552 if(This
->ret
!= S_OK
) return;
1554 if (saxreader_has_handler(This
, SAXContentHandler
))
1556 if(This
->vbInterface
)
1557 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1559 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1561 if (sax_callback_failed(This
, hr
))
1562 format_error_message_from_id(This
, hr
);
1566 static void libxmlStartElementNS(
1568 const xmlChar
*localname
,
1569 const xmlChar
*prefix
,
1572 const xmlChar
**namespaces
,
1575 const xmlChar
**attributes
)
1577 saxlocator
*This
= ctx
;
1578 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1579 element_entry
*element
;
1583 update_position(This
, TRUE
);
1584 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1586 if(This
->saxreader
->version
< MSXML4
)
1589 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1590 push_element_ns(This
, element
);
1592 if (is_namespaces_enabled(This
->saxreader
))
1596 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1598 if (This
->vbInterface
)
1599 hr
= IVBSAXContentHandler_startPrefixMapping(
1601 &element
->ns
[i
].prefix
,
1602 &element
->ns
[i
].uri
);
1604 hr
= ISAXContentHandler_startPrefixMapping(
1606 element
->ns
[i
].prefix
,
1607 SysStringLen(element
->ns
[i
].prefix
),
1609 SysStringLen(element
->ns
[i
].uri
));
1611 if (sax_callback_failed(This
, hr
))
1613 format_error_message_from_id(This
, hr
);
1619 uri
= find_element_uri(This
, URI
);
1620 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1621 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1625 if (is_namespaces_enabled(This
->saxreader
))
1626 local
= element
->local
;
1630 if (This
->vbInterface
)
1631 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1632 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1634 hr
= ISAXContentHandler_startElement(handler
->handler
,
1635 uri
, SysStringLen(uri
),
1636 local
, SysStringLen(local
),
1637 element
->qname
, SysStringLen(element
->qname
),
1638 &This
->ISAXAttributes_iface
);
1640 if (sax_callback_failed(This
, hr
))
1641 format_error_message_from_id(This
, hr
);
1645 static void libxmlEndElementNS(
1647 const xmlChar
*localname
,
1648 const xmlChar
*prefix
,
1651 saxlocator
*This
= ctx
;
1652 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1653 element_entry
*element
;
1658 update_position(This
, FALSE
);
1659 p
= This
->pParserCtxt
->input
->cur
;
1661 if (This
->saxreader
->version
>= MSXML4
)
1664 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1666 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1671 else if(*(p
-1)!='>' || *(p
-2)!='/')
1674 while(p
-2>=This
->pParserCtxt
->input
->base
1675 && *(p
-2)!='<' && *(p
-1)!='/')
1677 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1683 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1686 uri
= find_element_uri(This
, URI
);
1687 element
= pop_element_ns(This
);
1689 if (!saxreader_has_handler(This
, SAXContentHandler
))
1691 free_attribute_values(This
);
1692 This
->attr_count
= 0;
1693 free_element_entry(element
);
1697 if (is_namespaces_enabled(This
->saxreader
))
1698 local
= element
->local
;
1702 if (This
->vbInterface
)
1703 hr
= IVBSAXContentHandler_endElement(
1705 &uri
, &local
, &element
->qname
);
1707 hr
= ISAXContentHandler_endElement(
1709 uri
, SysStringLen(uri
),
1710 local
, SysStringLen(local
),
1711 element
->qname
, SysStringLen(element
->qname
));
1713 free_attribute_values(This
);
1714 This
->attr_count
= 0;
1716 if (sax_callback_failed(This
, hr
))
1718 format_error_message_from_id(This
, hr
);
1719 free_element_entry(element
);
1723 if (is_namespaces_enabled(This
->saxreader
))
1726 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1728 if (This
->vbInterface
)
1729 hr
= IVBSAXContentHandler_endPrefixMapping(
1730 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1732 hr
= ISAXContentHandler_endPrefixMapping(
1733 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1735 if (sax_callback_failed(This
, hr
)) break;
1738 if (sax_callback_failed(This
, hr
))
1739 format_error_message_from_id(This
, hr
);
1742 free_element_entry(element
);
1745 static void libxmlCharacters(
1750 saxlocator
*This
= ctx
;
1754 BOOL lastEvent
= FALSE
;
1756 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1758 update_position(This
, FALSE
);
1759 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1760 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1762 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1767 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1771 if(*(ch
-1)=='\r') cur
--;
1776 while(end
-ch
<len
&& *end
!='\r') end
++;
1787 if (This
->saxreader
->version
>= MSXML4
)
1791 for(p
=cur
; p
!=end
; p
++)
1808 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1809 hr
= saxreader_saxcharacters(This
, Chars
);
1811 if (sax_callback_failed(This
, hr
))
1813 format_error_message_from_id(This
, hr
);
1817 if (This
->saxreader
->version
< MSXML4
)
1818 This
->column
+= end
-cur
;
1831 if(end
-ch
== len
) break;
1835 static void libxmlSetDocumentLocator(
1837 xmlSAXLocatorPtr loc
)
1839 saxlocator
*This
= ctx
;
1840 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1843 if (saxreader_has_handler(This
, SAXContentHandler
))
1845 if(This
->vbInterface
)
1846 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1847 &This
->IVBSAXLocator_iface
);
1849 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1853 format_error_message_from_id(This
, hr
);
1856 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1858 saxlocator
*This
= ctx
;
1859 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1862 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1864 update_position(This
, FALSE
);
1865 while(p
-4>=This
->pParserCtxt
->input
->base
1866 && memcmp(p
-4, "<!--", sizeof(char[4])))
1868 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1874 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1877 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1879 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1881 if (This
->vbInterface
)
1882 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1884 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1887 format_error_message_from_id(This
, hr
);
1890 static void libxmlFatalError(void *ctx
, const char *msg
, ...)
1892 saxlocator
*This
= ctx
;
1893 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1899 if(This
->ret
!= S_OK
) {
1900 xmlStopParser(This
->pParserCtxt
);
1904 va_start(args
, msg
);
1905 vsprintf(message
, msg
, args
);
1908 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1909 error
= heap_alloc(sizeof(WCHAR
)*len
);
1912 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1913 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1916 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1918 xmlStopParser(This
->pParserCtxt
);
1924 FIXME("Error handling is not compatible.\n");
1926 if(This
->vbInterface
)
1928 BSTR bstrError
= SysAllocString(error
);
1929 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1930 &bstrError
, E_FAIL
);
1931 SysFreeString(bstrError
);
1934 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1938 xmlStopParser(This
->pParserCtxt
);
1942 /* The only reason this helper exists is that CDATA section are reported by chunks,
1943 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1945 This helper should be called for substring with trailing newlines.
1947 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1949 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1952 ptr
= bstr
+ len
- 1;
1953 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1958 /* replace returns as:
1960 - "\r<char>" -> "\n<char>"
1966 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
1969 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
1976 ret
= SysAllocStringLen(bstr
, len
);
1977 SysFreeString(bstr
);
1981 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
1983 const xmlChar
*start
, *end
;
1984 saxlocator
*locator
= ctx
;
1985 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
1990 update_position(locator
, FALSE
);
1991 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
1993 if (locator
->vbInterface
)
1994 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
1996 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
2001 format_error_message_from_id(locator
, hr
);
2011 /* scan for newlines */
2012 if (value
[i
] == '\r' || value
[i
] == '\n')
2014 /* skip newlines/linefeeds */
2017 if (value
[i
] != '\r' && value
[i
] != '\n') break;
2023 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
2024 TRACE("(chunk %s)\n", debugstr_w(chars
));
2025 hr
= saxreader_saxcharacters(locator
, chars
);
2026 SysFreeString(chars
);
2035 /* no newline chars (or last chunk) report as a whole */
2036 if (!end
&& start
== value
)
2039 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
2040 TRACE("(%s)\n", debugstr_w(chars
));
2041 hr
= saxreader_saxcharacters(locator
, chars
);
2042 SysFreeString(chars
);
2045 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2047 if (locator
->vbInterface
)
2048 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
2050 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
2054 format_error_message_from_id(locator
, hr
);
2057 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
2059 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
2060 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
2063 /*** IVBSAXLocator interface ***/
2064 /*** IUnknown methods ***/
2065 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2067 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2069 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2073 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2074 IsEqualGUID( riid
, &IID_IDispatch
) ||
2075 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
2079 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
2081 *ppvObject
= &This
->IVBSAXAttributes_iface
;
2085 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2086 return E_NOINTERFACE
;
2089 IVBSAXLocator_AddRef( iface
);
2094 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
2096 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2097 TRACE("%p\n", This
);
2098 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
2101 static ULONG WINAPI
ivbsaxlocator_Release(IVBSAXLocator
* iface
)
2103 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2104 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
2107 /*** IDispatch methods ***/
2108 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
2110 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2112 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2119 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
2120 IVBSAXLocator
*iface
,
2121 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2123 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2125 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2127 return get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2130 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2131 IVBSAXLocator
*iface
,
2133 LPOLESTR
* rgszNames
,
2138 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2139 ITypeInfo
*typeinfo
;
2142 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
2145 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2146 return E_INVALIDARG
;
2148 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2151 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2152 ITypeInfo_Release(typeinfo
);
2158 static HRESULT WINAPI
ivbsaxlocator_Invoke(
2159 IVBSAXLocator
*iface
,
2160 DISPID dispIdMember
,
2164 DISPPARAMS
* pDispParams
,
2165 VARIANT
* pVarResult
,
2166 EXCEPINFO
* pExcepInfo
,
2169 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2170 ITypeInfo
*typeinfo
;
2173 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2174 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2176 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2179 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXLocator_iface
, dispIdMember
, wFlags
,
2180 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2181 ITypeInfo_Release(typeinfo
);
2187 /*** IVBSAXLocator methods ***/
2188 static HRESULT WINAPI
ivbsaxlocator_get_columnNumber(
2189 IVBSAXLocator
* iface
,
2192 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2193 return ISAXLocator_getColumnNumber(&This
->ISAXLocator_iface
, pnColumn
);
2196 static HRESULT WINAPI
ivbsaxlocator_get_lineNumber(
2197 IVBSAXLocator
* iface
,
2200 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2201 return ISAXLocator_getLineNumber(&This
->ISAXLocator_iface
, pnLine
);
2204 static HRESULT WINAPI
ivbsaxlocator_get_publicId(IVBSAXLocator
* iface
, BSTR
*ret
)
2206 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2207 const WCHAR
*publicidW
;
2210 TRACE("(%p)->(%p)\n", This
, ret
);
2216 hr
= ISAXLocator_getPublicId(&This
->ISAXLocator_iface
, &publicidW
);
2220 return return_bstr(publicidW
, ret
);
2223 static HRESULT WINAPI
ivbsaxlocator_get_systemId(IVBSAXLocator
* iface
, BSTR
*ret
)
2225 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2226 const WCHAR
*systemidW
;
2229 TRACE("(%p)->(%p)\n", This
, ret
);
2235 hr
= ISAXLocator_getSystemId(&This
->ISAXLocator_iface
, &systemidW
);
2239 return return_bstr(systemidW
, ret
);
2242 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl
=
2244 ivbsaxlocator_QueryInterface
,
2245 ivbsaxlocator_AddRef
,
2246 ivbsaxlocator_Release
,
2247 ivbsaxlocator_GetTypeInfoCount
,
2248 ivbsaxlocator_GetTypeInfo
,
2249 ivbsaxlocator_GetIDsOfNames
,
2250 ivbsaxlocator_Invoke
,
2251 ivbsaxlocator_get_columnNumber
,
2252 ivbsaxlocator_get_lineNumber
,
2253 ivbsaxlocator_get_publicId
,
2254 ivbsaxlocator_get_systemId
2257 /*** ISAXLocator interface ***/
2258 /*** IUnknown methods ***/
2259 static HRESULT WINAPI
isaxlocator_QueryInterface(ISAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2261 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2263 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2267 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2268 IsEqualGUID( riid
, &IID_ISAXLocator
))
2272 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
2274 *ppvObject
= &This
->ISAXAttributes_iface
;
2278 WARN("interface %s not implemented\n", debugstr_guid(riid
));
2279 return E_NOINTERFACE
;
2282 ISAXLocator_AddRef( iface
);
2287 static ULONG WINAPI
isaxlocator_AddRef(ISAXLocator
* iface
)
2289 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2290 ULONG ref
= InterlockedIncrement( &This
->ref
);
2291 TRACE("(%p)->(%d)\n", This
, ref
);
2295 static ULONG WINAPI
isaxlocator_Release(
2298 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2299 LONG ref
= InterlockedDecrement( &This
->ref
);
2301 TRACE("(%p)->(%d)\n", This
, ref
);
2305 element_entry
*element
, *element2
;
2308 SysFreeString(This
->publicId
);
2309 SysFreeString(This
->systemId
);
2310 SysFreeString(This
->namespaceUri
);
2312 for(index
= 0; index
< This
->attr_alloc_count
; index
++)
2314 SysFreeString(This
->attributes
[index
].szLocalname
);
2315 SysFreeString(This
->attributes
[index
].szValue
);
2316 SysFreeString(This
->attributes
[index
].szQName
);
2318 heap_free(This
->attributes
);
2321 LIST_FOR_EACH_ENTRY_SAFE(element
, element2
, &This
->elements
, element_entry
, entry
)
2323 list_remove(&element
->entry
);
2324 free_element_entry(element
);
2327 ISAXXMLReader_Release(&This
->saxreader
->ISAXXMLReader_iface
);
2334 /*** ISAXLocator methods ***/
2335 static HRESULT WINAPI
isaxlocator_getColumnNumber(
2339 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2341 *pnColumn
= This
->column
;
2345 static HRESULT WINAPI
isaxlocator_getLineNumber(
2349 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2351 *pnLine
= This
->line
;
2355 static HRESULT WINAPI
isaxlocator_getPublicId(
2357 const WCHAR
** ppwchPublicId
)
2360 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2362 SysFreeString(This
->publicId
);
2364 publicId
= bstr_from_xmlChar(xmlSAX2GetPublicId(This
->pParserCtxt
));
2365 if(SysStringLen(publicId
))
2366 This
->publicId
= publicId
;
2369 SysFreeString(publicId
);
2370 This
->publicId
= NULL
;
2373 *ppwchPublicId
= This
->publicId
;
2377 static HRESULT WINAPI
isaxlocator_getSystemId(
2379 const WCHAR
** ppwchSystemId
)
2382 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2384 SysFreeString(This
->systemId
);
2386 systemId
= bstr_from_xmlChar(xmlSAX2GetSystemId(This
->pParserCtxt
));
2387 if(SysStringLen(systemId
))
2388 This
->systemId
= systemId
;
2391 SysFreeString(systemId
);
2392 This
->systemId
= NULL
;
2395 *ppwchSystemId
= This
->systemId
;
2399 static const struct ISAXLocatorVtbl SAXLocatorVtbl
=
2401 isaxlocator_QueryInterface
,
2403 isaxlocator_Release
,
2404 isaxlocator_getColumnNumber
,
2405 isaxlocator_getLineNumber
,
2406 isaxlocator_getPublicId
,
2407 isaxlocator_getSystemId
2410 static HRESULT
SAXLocator_create(saxreader
*reader
, saxlocator
**ppsaxlocator
, BOOL vbInterface
)
2412 static const WCHAR w3xmlns
[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2413 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2415 saxlocator
*locator
;
2417 locator
= heap_alloc( sizeof (*locator
) );
2419 return E_OUTOFMEMORY
;
2421 locator
->IVBSAXLocator_iface
.lpVtbl
= &VBSAXLocatorVtbl
;
2422 locator
->ISAXLocator_iface
.lpVtbl
= &SAXLocatorVtbl
;
2423 locator
->IVBSAXAttributes_iface
.lpVtbl
= &ivbsaxattributes_vtbl
;
2424 locator
->ISAXAttributes_iface
.lpVtbl
= &isaxattributes_vtbl
;
2426 locator
->vbInterface
= vbInterface
;
2428 locator
->saxreader
= reader
;
2429 ISAXXMLReader_AddRef(&reader
->ISAXXMLReader_iface
);
2431 locator
->pParserCtxt
= NULL
;
2432 locator
->publicId
= NULL
;
2433 locator
->systemId
= NULL
;
2434 locator
->line
= reader
->version
< MSXML4
? 0 : 1;
2435 locator
->column
= 0;
2436 locator
->ret
= S_OK
;
2437 if (locator
->saxreader
->version
>= MSXML6
)
2438 locator
->namespaceUri
= SysAllocString(w3xmlns
);
2440 locator
->namespaceUri
= SysAllocStringLen(NULL
, 0);
2441 if(!locator
->namespaceUri
)
2443 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2445 return E_OUTOFMEMORY
;
2448 locator
->attr_alloc_count
= 8;
2449 locator
->attr_count
= 0;
2450 locator
->attributes
= heap_alloc_zero(sizeof(struct _attributes
)*locator
->attr_alloc_count
);
2451 if(!locator
->attributes
)
2453 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2454 SysFreeString(locator
->namespaceUri
);
2456 return E_OUTOFMEMORY
;
2459 list_init(&locator
->elements
);
2461 *ppsaxlocator
= locator
;
2463 TRACE("returning %p\n", *ppsaxlocator
);
2468 /*** SAXXMLReader internal functions ***/
2469 static HRESULT
internal_parseBuffer(saxreader
*This
, const char *buffer
, int size
, BOOL vbInterface
)
2471 xmlCharEncoding encoding
= XML_CHAR_ENCODING_NONE
;
2472 xmlChar
*enc_name
= NULL
;
2473 saxlocator
*locator
;
2476 TRACE("(%p)->(%p %d)\n", This
, buffer
, size
);
2478 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2484 const unsigned char *buff
= (unsigned char*)buffer
;
2486 encoding
= xmlDetectCharEncoding((xmlChar
*)buffer
, 4);
2487 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2488 TRACE("detected encoding: %s\n", enc_name
);
2489 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2490 if ((encoding
== XML_CHAR_ENCODING_UTF8
) &&
2491 buff
[0] == 0xEF && buff
[1] == 0xBB && buff
[2] == 0xBF)
2498 /* if libxml2 detection failed try to guess */
2499 if (encoding
== XML_CHAR_ENCODING_NONE
)
2501 const WCHAR
*ptr
= (WCHAR
*)buffer
;
2502 /* xml declaration with possibly specfied encoding will be still handled by parser */
2503 if ((size
>= 2) && *ptr
== '<' && ptr
[1] != '?')
2505 enc_name
= (xmlChar
*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE
);
2506 encoding
= XML_CHAR_ENCODING_UTF16LE
;
2509 else if (encoding
== XML_CHAR_ENCODING_UTF8
)
2510 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2514 locator
->pParserCtxt
= xmlCreateMemoryParserCtxt(buffer
, size
);
2515 if (!locator
->pParserCtxt
)
2517 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2523 locator
->pParserCtxt
->encoding
= xmlStrdup(enc_name
);
2524 if (encoding
== XML_CHAR_ENCODING_UTF16LE
) {
2525 TRACE("switching to %s\n", enc_name
);
2526 xmlSwitchEncoding(locator
->pParserCtxt
, encoding
);
2530 xmlFree(locator
->pParserCtxt
->sax
);
2531 locator
->pParserCtxt
->sax
= &locator
->saxreader
->sax
;
2532 locator
->pParserCtxt
->userData
= locator
;
2534 This
->isParsing
= TRUE
;
2535 if(xmlParseDocument(locator
->pParserCtxt
) == -1 && locator
->ret
== S_OK
)
2539 This
->isParsing
= FALSE
;
2541 if(locator
->pParserCtxt
)
2543 locator
->pParserCtxt
->sax
= NULL
;
2544 xmlFreeParserCtxt(locator
->pParserCtxt
);
2545 locator
->pParserCtxt
= NULL
;
2548 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2552 static HRESULT
internal_parseStream(saxreader
*This
, ISequentialStream
*stream
, BOOL vbInterface
)
2554 saxlocator
*locator
;
2561 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2562 if(FAILED(hr
)) return hr
;
2564 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2565 if(FAILED(hr
)) return hr
;
2567 locator
->pParserCtxt
= xmlCreatePushParserCtxt(
2568 &locator
->saxreader
->sax
, locator
,
2569 data
, dataRead
, NULL
);
2570 if(!locator
->pParserCtxt
)
2572 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2576 This
->isParsing
= TRUE
;
2580 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2581 if (FAILED(hr
) || !dataRead
) break;
2583 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, dataRead
, 0);
2584 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2589 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2590 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2594 This
->isParsing
= FALSE
;
2596 xmlFreeParserCtxt(locator
->pParserCtxt
);
2597 locator
->pParserCtxt
= NULL
;
2598 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2602 static HRESULT
internal_parse(
2609 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varInput
));
2611 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2612 free_bstr_pool(&This
->pool
);
2614 switch(V_VT(&varInput
))
2617 case VT_BSTR
|VT_BYREF
:
2619 BSTR str
= V_ISBYREF(&varInput
) ? *V_BSTRREF(&varInput
) : V_BSTR(&varInput
);
2620 hr
= internal_parseBuffer(This
, (const char*)str
, strlenW(str
)*sizeof(WCHAR
), vbInterface
);
2623 case VT_ARRAY
|VT_UI1
: {
2625 LONG lBound
, uBound
;
2628 hr
= SafeArrayGetLBound(V_ARRAY(&varInput
), 1, &lBound
);
2629 if(hr
!= S_OK
) break;
2630 hr
= SafeArrayGetUBound(V_ARRAY(&varInput
), 1, &uBound
);
2631 if(hr
!= S_OK
) break;
2632 dataRead
= (uBound
-lBound
)*SafeArrayGetElemsize(V_ARRAY(&varInput
));
2633 hr
= SafeArrayAccessData(V_ARRAY(&varInput
), &pSAData
);
2634 if(hr
!= S_OK
) break;
2635 hr
= internal_parseBuffer(This
, pSAData
, dataRead
, vbInterface
);
2636 SafeArrayUnaccessData(V_ARRAY(&varInput
));
2641 IPersistStream
*persistStream
;
2642 ISequentialStream
*stream
= NULL
;
2643 IXMLDOMDocument
*xmlDoc
;
2645 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2646 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2650 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2651 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2652 SysStringByteLen(bstrData
), vbInterface
);
2653 IXMLDOMDocument_Release(xmlDoc
);
2654 SysFreeString(bstrData
);
2658 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2659 &IID_IPersistStream
, (void**)&persistStream
) == S_OK
)
2661 IStream
*stream_copy
;
2663 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream_copy
);
2666 IPersistStream_Release(persistStream
);
2670 hr
= IPersistStream_Save(persistStream
, stream_copy
, TRUE
);
2671 IPersistStream_Release(persistStream
);
2673 IStream_QueryInterface(stream_copy
, &IID_ISequentialStream
, (void**)&stream
);
2675 IStream_Release(stream_copy
);
2678 /* try base interface first */
2681 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2683 /* this should never happen if IStream is implemented properly, but just in case */
2684 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2689 hr
= internal_parseStream(This
, stream
, vbInterface
);
2690 ISequentialStream_Release(stream
);
2694 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2701 WARN("vt %d not implemented\n", V_VT(&varInput
));
2708 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2710 saxreader
*This
= obj
;
2712 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2715 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2717 saxreader
*This
= obj
;
2719 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2722 static HRESULT
internal_parseURL(
2731 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
2733 hr
= create_moniker_from_url(url
, &mon
);
2737 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, This
, &bsc
);
2738 else hr
= bind_url(mon
, internal_onDataAvailable
, This
, &bsc
);
2739 IMoniker_Release(mon
);
2744 return detach_bsc(bsc
);
2747 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2751 if (V_VT(v
) == VT_EMPTY
)
2752 return saxreader_put_handler(This
, type
, NULL
, vb
);
2756 case SAXDeclHandler
:
2757 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2759 case SAXLexicalHandler
:
2760 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2763 ERR("wrong handler type %d\n", type
);
2772 IUnknown
*handler
= NULL
;
2776 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2777 if (FAILED(hr
)) return hr
;
2780 saxreader_put_handler(This
, type
, handler
, vb
);
2781 if (handler
) IUnknown_Release(handler
);
2785 ERR("value type %d not supported\n", V_VT(v
));
2786 return E_INVALIDARG
;
2792 static HRESULT
internal_putProperty(
2800 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2802 if (This
->isParsing
) return E_FAIL
;
2804 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2805 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2806 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2808 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2809 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2811 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2813 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2814 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2818 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2820 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2821 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2825 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2827 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2830 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2833 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2836 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2839 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2842 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2845 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2848 return E_INVALIDARG
;
2851 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2853 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2855 if (!value
) return E_POINTER
;
2857 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2859 V_VT(value
) = VT_UNKNOWN
;
2860 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2864 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2866 V_VT(value
) = VT_UNKNOWN
;
2867 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2871 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2873 V_VT(value
) = VT_BSTR
;
2874 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2878 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2883 /*** IVBSAXXMLReader interface ***/
2884 /*** IUnknown methods ***/
2885 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2887 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2889 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2893 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2894 IsEqualGUID( riid
, &IID_IDispatch
) ||
2895 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2899 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2901 *ppvObject
= &This
->ISAXXMLReader_iface
;
2903 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2905 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2909 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2910 return E_NOINTERFACE
;
2913 IVBSAXXMLReader_AddRef( iface
);
2918 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2920 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2921 TRACE("%p\n", This
);
2922 return InterlockedIncrement( &This
->ref
);
2925 static ULONG WINAPI
saxxmlreader_Release(
2926 IVBSAXXMLReader
* iface
)
2928 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2931 TRACE("%p\n", This
);
2933 ref
= InterlockedDecrement( &This
->ref
);
2938 for (i
= 0; i
< SAXHandler_Last
; i
++)
2940 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2942 if (saxiface
->handler
)
2943 IUnknown_Release(saxiface
->handler
);
2945 if (saxiface
->vbhandler
)
2946 IUnknown_Release(saxiface
->vbhandler
);
2949 SysFreeString(This
->xmldecl_version
);
2950 free_bstr_pool(&This
->pool
);
2958 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2960 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2961 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2964 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2965 IVBSAXXMLReader
*iface
,
2966 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2968 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2969 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2970 iTInfo
, lcid
, ppTInfo
);
2973 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2974 IVBSAXXMLReader
*iface
,
2976 LPOLESTR
* rgszNames
,
2981 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2982 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
2983 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
2986 static HRESULT WINAPI
saxxmlreader_Invoke(
2987 IVBSAXXMLReader
*iface
,
2988 DISPID dispIdMember
,
2992 DISPPARAMS
* pDispParams
,
2993 VARIANT
* pVarResult
,
2994 EXCEPINFO
* pExcepInfo
,
2997 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2998 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
2999 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3002 /*** IVBSAXXMLReader methods ***/
3003 static HRESULT WINAPI
saxxmlreader_getFeature(
3004 IVBSAXXMLReader
* iface
,
3006 VARIANT_BOOL
*value
)
3008 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3009 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3012 static HRESULT WINAPI
saxxmlreader_putFeature(
3013 IVBSAXXMLReader
* iface
,
3017 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3018 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3021 static HRESULT WINAPI
saxxmlreader_getProperty(
3022 IVBSAXXMLReader
* iface
,
3026 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3027 return internal_getProperty(This
, prop
, value
, TRUE
);
3030 static HRESULT WINAPI
saxxmlreader_putProperty(
3031 IVBSAXXMLReader
* iface
,
3035 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3036 return internal_putProperty(This
, pProp
, value
, TRUE
);
3039 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3040 IVBSAXXMLReader
* iface
,
3041 IVBSAXEntityResolver
**resolver
)
3043 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3044 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3047 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3048 IVBSAXXMLReader
* iface
,
3049 IVBSAXEntityResolver
*resolver
)
3051 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3052 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3055 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3056 IVBSAXXMLReader
* iface
,
3057 IVBSAXContentHandler
**handler
)
3059 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3060 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3063 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3064 IVBSAXXMLReader
* iface
,
3065 IVBSAXContentHandler
*handler
)
3067 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3068 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3071 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3072 IVBSAXXMLReader
* iface
,
3073 IVBSAXDTDHandler
**handler
)
3075 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3076 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3079 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3080 IVBSAXXMLReader
* iface
,
3081 IVBSAXDTDHandler
*handler
)
3083 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3084 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3087 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3088 IVBSAXXMLReader
* iface
,
3089 IVBSAXErrorHandler
**handler
)
3091 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3092 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3095 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3096 IVBSAXXMLReader
* iface
,
3097 IVBSAXErrorHandler
*handler
)
3099 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3100 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3103 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3104 IVBSAXXMLReader
* iface
,
3107 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3109 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3113 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3114 IVBSAXXMLReader
* iface
,
3117 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3118 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3121 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3122 IVBSAXXMLReader
* iface
,
3123 BSTR
*pSecureBaseUrl
)
3125 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3127 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3131 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3132 IVBSAXXMLReader
* iface
,
3135 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3136 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3139 static HRESULT WINAPI
saxxmlreader_parse(
3140 IVBSAXXMLReader
* iface
,
3143 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3144 return internal_parse(This
, varInput
, TRUE
);
3147 static HRESULT WINAPI
saxxmlreader_parseURL(
3148 IVBSAXXMLReader
* iface
,
3151 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3152 return internal_parseURL(This
, url
, TRUE
);
3155 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3157 saxxmlreader_QueryInterface
,
3158 saxxmlreader_AddRef
,
3159 saxxmlreader_Release
,
3160 saxxmlreader_GetTypeInfoCount
,
3161 saxxmlreader_GetTypeInfo
,
3162 saxxmlreader_GetIDsOfNames
,
3163 saxxmlreader_Invoke
,
3164 saxxmlreader_getFeature
,
3165 saxxmlreader_putFeature
,
3166 saxxmlreader_getProperty
,
3167 saxxmlreader_putProperty
,
3168 saxxmlreader_get_entityResolver
,
3169 saxxmlreader_put_entityResolver
,
3170 saxxmlreader_get_contentHandler
,
3171 saxxmlreader_put_contentHandler
,
3172 saxxmlreader_get_dtdHandler
,
3173 saxxmlreader_put_dtdHandler
,
3174 saxxmlreader_get_errorHandler
,
3175 saxxmlreader_put_errorHandler
,
3176 saxxmlreader_get_baseURL
,
3177 saxxmlreader_put_baseURL
,
3178 saxxmlreader_get_secureBaseURL
,
3179 saxxmlreader_put_secureBaseURL
,
3181 saxxmlreader_parseURL
3184 /*** ISAXXMLReader interface ***/
3185 /*** IUnknown methods ***/
3186 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3188 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3189 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3192 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3194 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3195 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3198 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3200 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3201 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3204 /*** ISAXXMLReader methods ***/
3205 static HRESULT WINAPI
isaxxmlreader_getFeature(
3206 ISAXXMLReader
* iface
,
3207 const WCHAR
*feature_name
,
3208 VARIANT_BOOL
*value
)
3210 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3211 saxreader_feature feature
;
3213 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3215 feature
= get_saxreader_feature(feature_name
);
3216 if (feature
== Namespaces
|| feature
== NamespacePrefixes
)
3217 return get_feature_value(This
, feature
, value
);
3219 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3223 static HRESULT WINAPI
isaxxmlreader_putFeature(
3224 ISAXXMLReader
* iface
,
3225 const WCHAR
*feature_name
,
3228 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3229 saxreader_feature feature
;
3231 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3233 feature
= get_saxreader_feature(feature_name
);
3235 /* accepted cases */
3236 if ((feature
== ExternalGeneralEntities
&& value
== VARIANT_FALSE
) ||
3237 (feature
== ExternalParameterEntities
&& value
== VARIANT_FALSE
) ||
3238 feature
== Namespaces
||
3239 feature
== NamespacePrefixes
)
3241 return set_feature_value(This
, feature
, value
);
3244 if (feature
== LexicalHandlerParEntities
|| feature
== ProhibitDTD
)
3246 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3247 return set_feature_value(This
, feature
, value
);
3250 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3254 static HRESULT WINAPI
isaxxmlreader_getProperty(
3255 ISAXXMLReader
* iface
,
3259 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3260 return internal_getProperty(This
, prop
, value
, FALSE
);
3263 static HRESULT WINAPI
isaxxmlreader_putProperty(
3264 ISAXXMLReader
* iface
,
3268 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3269 return internal_putProperty(This
, pProp
, value
, FALSE
);
3272 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3273 ISAXXMLReader
* iface
,
3274 ISAXEntityResolver
**resolver
)
3276 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3277 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3280 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3281 ISAXXMLReader
* iface
,
3282 ISAXEntityResolver
*resolver
)
3284 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3285 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3288 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3289 ISAXXMLReader
* iface
,
3290 ISAXContentHandler
**handler
)
3292 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3293 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3296 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3297 ISAXXMLReader
* iface
,
3298 ISAXContentHandler
*handler
)
3300 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3301 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3304 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3305 ISAXXMLReader
* iface
,
3306 ISAXDTDHandler
**handler
)
3308 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3309 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3312 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3313 ISAXXMLReader
* iface
,
3314 ISAXDTDHandler
*handler
)
3316 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3317 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3320 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3321 ISAXXMLReader
* iface
,
3322 ISAXErrorHandler
**handler
)
3324 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3325 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3328 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3330 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3331 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3334 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3335 ISAXXMLReader
* iface
,
3336 const WCHAR
**base_url
)
3338 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3340 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3344 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3345 ISAXXMLReader
* iface
,
3346 const WCHAR
*pBaseUrl
)
3348 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3350 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3354 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3355 ISAXXMLReader
* iface
,
3356 const WCHAR
**pSecureBaseUrl
)
3358 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3359 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3363 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3364 ISAXXMLReader
* iface
,
3365 const WCHAR
*secureBaseUrl
)
3367 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3369 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3373 static HRESULT WINAPI
isaxxmlreader_parse(
3374 ISAXXMLReader
* iface
,
3377 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3378 return internal_parse(This
, varInput
, FALSE
);
3381 static HRESULT WINAPI
isaxxmlreader_parseURL(
3382 ISAXXMLReader
* iface
,
3385 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3386 return internal_parseURL(This
, url
, FALSE
);
3389 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3391 isaxxmlreader_QueryInterface
,
3392 isaxxmlreader_AddRef
,
3393 isaxxmlreader_Release
,
3394 isaxxmlreader_getFeature
,
3395 isaxxmlreader_putFeature
,
3396 isaxxmlreader_getProperty
,
3397 isaxxmlreader_putProperty
,
3398 isaxxmlreader_getEntityResolver
,
3399 isaxxmlreader_putEntityResolver
,
3400 isaxxmlreader_getContentHandler
,
3401 isaxxmlreader_putContentHandler
,
3402 isaxxmlreader_getDTDHandler
,
3403 isaxxmlreader_putDTDHandler
,
3404 isaxxmlreader_getErrorHandler
,
3405 isaxxmlreader_putErrorHandler
,
3406 isaxxmlreader_getBaseURL
,
3407 isaxxmlreader_putBaseURL
,
3408 isaxxmlreader_getSecureBaseURL
,
3409 isaxxmlreader_putSecureBaseURL
,
3410 isaxxmlreader_parse
,
3411 isaxxmlreader_parseURL
3414 static const tid_t saxreader_iface_tids
[] = {
3415 IVBSAXXMLReader_tid
,
3418 static dispex_static_data_t saxreader_dispex
= {
3420 IVBSAXXMLReader_tid
,
3422 saxreader_iface_tids
3425 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3429 TRACE("(%p)\n", ppObj
);
3431 reader
= heap_alloc( sizeof (*reader
) );
3433 return E_OUTOFMEMORY
;
3435 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3436 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3438 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3439 reader
->isParsing
= FALSE
;
3440 reader
->xmldecl_version
= NULL
;
3441 reader
->pool
.pool
= NULL
;
3442 reader
->pool
.index
= 0;
3443 reader
->pool
.len
= 0;
3444 reader
->features
= Namespaces
| NamespacePrefixes
;
3445 reader
->version
= version
;
3447 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3449 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3450 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3451 reader
->sax
.startDocument
= libxmlStartDocument
;
3452 reader
->sax
.endDocument
= libxmlEndDocument
;
3453 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3454 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3455 reader
->sax
.characters
= libxmlCharacters
;
3456 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3457 reader
->sax
.comment
= libxmlComment
;
3458 reader
->sax
.error
= libxmlFatalError
;
3459 reader
->sax
.fatalError
= libxmlFatalError
;
3460 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3461 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3463 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3465 TRACE("returning iface %p\n", *ppObj
);
3472 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3474 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3475 "libxml2 support was not present at compile time.\n");