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;
671 const xmlChar
*baseP
= This
->pParserCtxt
->input
->base
;
673 This
->line
= xmlSAX2GetLineNumber(This
->pParserCtxt
);
677 for(;p
>=baseP
&& *p
!='\n' && *p
!='\r'; p
--)
682 This
->column
= xmlSAX2GetColumnNumber(This
->pParserCtxt
);
686 /*** IVBSAXAttributes interface ***/
687 static HRESULT WINAPI
ivbsaxattributes_QueryInterface(
688 IVBSAXAttributes
* iface
,
692 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
693 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
694 return IVBSAXLocator_QueryInterface(&This
->IVBSAXLocator_iface
, riid
, ppvObject
);
697 static ULONG WINAPI
ivbsaxattributes_AddRef(IVBSAXAttributes
* iface
)
699 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
700 return IVBSAXLocator_AddRef(&This
->IVBSAXLocator_iface
);
703 static ULONG WINAPI
ivbsaxattributes_Release(IVBSAXAttributes
* iface
)
705 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
706 return IVBSAXLocator_Release(&This
->IVBSAXLocator_iface
);
709 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes
*iface
, UINT
* pctinfo
)
711 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
713 TRACE("(%p)->(%p)\n", This
, pctinfo
);
720 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfo(
721 IVBSAXAttributes
*iface
,
722 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
724 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
726 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
728 return get_typeinfo(IVBSAXAttributes_tid
, ppTInfo
);
731 static HRESULT WINAPI
ivbsaxattributes_GetIDsOfNames(
732 IVBSAXAttributes
*iface
,
739 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
743 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
746 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
749 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
752 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
753 ITypeInfo_Release(typeinfo
);
759 static HRESULT WINAPI
ivbsaxattributes_Invoke(
760 IVBSAXAttributes
*iface
,
765 DISPPARAMS
* pDispParams
,
767 EXCEPINFO
* pExcepInfo
,
770 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
774 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
775 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
777 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
780 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXAttributes_iface
, dispIdMember
, wFlags
,
781 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
782 ITypeInfo_Release(typeinfo
);
788 /*** IVBSAXAttributes methods ***/
789 static HRESULT WINAPI
ivbsaxattributes_get_length(
790 IVBSAXAttributes
* iface
,
793 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
794 return ISAXAttributes_getLength(&This
->ISAXAttributes_iface
, nLength
);
797 static HRESULT WINAPI
ivbsaxattributes_getURI(
798 IVBSAXAttributes
* iface
,
802 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
807 TRACE("(%p)->(%d %p)\n", This
, nIndex
, uri
);
813 hr
= ISAXAttributes_getURI(&This
->ISAXAttributes_iface
, nIndex
, &uriW
, &len
);
817 return return_bstrn(uriW
, len
, uri
);
820 static HRESULT WINAPI
ivbsaxattributes_getLocalName(
821 IVBSAXAttributes
* iface
,
825 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
830 TRACE("(%p)->(%d %p)\n", This
, nIndex
, name
);
836 hr
= ISAXAttributes_getLocalName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
840 return return_bstrn(nameW
, len
, name
);
843 static HRESULT WINAPI
ivbsaxattributes_getQName(
844 IVBSAXAttributes
* iface
,
848 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
853 TRACE("(%p)->(%d %p)\n", This
, nIndex
, QName
);
859 hr
= ISAXAttributes_getQName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
863 return return_bstrn(nameW
, len
, QName
);
866 static HRESULT WINAPI
ivbsaxattributes_getIndexFromName(
867 IVBSAXAttributes
* iface
,
872 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
873 return ISAXAttributes_getIndexFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
874 localName
, SysStringLen(localName
), index
);
877 static HRESULT WINAPI
ivbsaxattributes_getIndexFromQName(
878 IVBSAXAttributes
* iface
,
882 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
883 return ISAXAttributes_getIndexFromQName(&This
->ISAXAttributes_iface
, QName
,
884 SysStringLen(QName
), index
);
887 static HRESULT WINAPI
ivbsaxattributes_getType(
888 IVBSAXAttributes
* iface
,
892 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
897 TRACE("(%p)->(%d %p)\n", This
, nIndex
, type
);
903 hr
= ISAXAttributes_getType(&This
->ISAXAttributes_iface
, nIndex
, &typeW
, &len
);
907 return return_bstrn(typeW
, len
, type
);
910 static HRESULT WINAPI
ivbsaxattributes_getTypeFromName(
911 IVBSAXAttributes
* iface
,
916 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
921 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), type
);
927 hr
= ISAXAttributes_getTypeFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
928 localName
, SysStringLen(localName
), &typeW
, &len
);
932 return return_bstrn(typeW
, len
, type
);
935 static HRESULT WINAPI
ivbsaxattributes_getTypeFromQName(
936 IVBSAXAttributes
* iface
,
940 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
945 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), type
);
951 hr
= ISAXAttributes_getTypeFromQName(&This
->ISAXAttributes_iface
, QName
, SysStringLen(QName
),
956 return return_bstrn(typeW
, len
, type
);
959 static HRESULT WINAPI
ivbsaxattributes_getValue(
960 IVBSAXAttributes
* iface
,
964 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
969 TRACE("(%p)->(%d %p)\n", This
, nIndex
, value
);
975 hr
= ISAXAttributes_getValue(&This
->ISAXAttributes_iface
, nIndex
, &valueW
, &len
);
979 return return_bstrn(valueW
, len
, value
);
982 static HRESULT WINAPI
ivbsaxattributes_getValueFromName(
983 IVBSAXAttributes
* iface
,
988 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
993 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), value
);
999 hr
= ISAXAttributes_getValueFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
1000 localName
, SysStringLen(localName
), &valueW
, &len
);
1004 return return_bstrn(valueW
, len
, value
);
1007 static HRESULT WINAPI
ivbsaxattributes_getValueFromQName(
1008 IVBSAXAttributes
* iface
,
1012 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1013 const WCHAR
*valueW
;
1017 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), value
);
1023 hr
= ISAXAttributes_getValueFromQName(&This
->ISAXAttributes_iface
, QName
,
1024 SysStringLen(QName
), &valueW
, &len
);
1028 return return_bstrn(valueW
, len
, value
);
1031 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl
=
1033 ivbsaxattributes_QueryInterface
,
1034 ivbsaxattributes_AddRef
,
1035 ivbsaxattributes_Release
,
1036 ivbsaxattributes_GetTypeInfoCount
,
1037 ivbsaxattributes_GetTypeInfo
,
1038 ivbsaxattributes_GetIDsOfNames
,
1039 ivbsaxattributes_Invoke
,
1040 ivbsaxattributes_get_length
,
1041 ivbsaxattributes_getURI
,
1042 ivbsaxattributes_getLocalName
,
1043 ivbsaxattributes_getQName
,
1044 ivbsaxattributes_getIndexFromName
,
1045 ivbsaxattributes_getIndexFromQName
,
1046 ivbsaxattributes_getType
,
1047 ivbsaxattributes_getTypeFromName
,
1048 ivbsaxattributes_getTypeFromQName
,
1049 ivbsaxattributes_getValue
,
1050 ivbsaxattributes_getValueFromName
,
1051 ivbsaxattributes_getValueFromQName
1054 /*** ISAXAttributes interface ***/
1055 /*** IUnknown methods ***/
1056 static HRESULT WINAPI
isaxattributes_QueryInterface(
1057 ISAXAttributes
* iface
,
1061 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1062 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
1063 return ISAXLocator_QueryInterface(&This
->ISAXLocator_iface
, riid
, ppvObject
);
1066 static ULONG WINAPI
isaxattributes_AddRef(ISAXAttributes
* iface
)
1068 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1069 TRACE("%p\n", This
);
1070 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
1073 static ULONG WINAPI
isaxattributes_Release(ISAXAttributes
* iface
)
1075 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1077 TRACE("%p\n", This
);
1078 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
1081 /*** ISAXAttributes methods ***/
1082 static HRESULT WINAPI
isaxattributes_getLength(
1083 ISAXAttributes
* iface
,
1086 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1088 *length
= This
->attr_count
;
1089 TRACE("Length set to %d\n", *length
);
1093 static inline BOOL
is_valid_attr_index(const saxlocator
*locator
, int index
)
1095 return index
< locator
->attr_count
&& index
>= 0;
1098 static HRESULT WINAPI
isaxattributes_getURI(
1099 ISAXAttributes
* iface
,
1104 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1105 TRACE("(%p)->(%d)\n", This
, index
);
1107 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1108 if(!url
|| !size
) return E_POINTER
;
1110 *size
= SysStringLen(This
->attributes
[index
].szURI
);
1111 *url
= This
->attributes
[index
].szURI
;
1113 TRACE("(%s:%d)\n", debugstr_w(This
->attributes
[index
].szURI
), *size
);
1118 static HRESULT WINAPI
isaxattributes_getLocalName(
1119 ISAXAttributes
* iface
,
1121 const WCHAR
**pLocalName
,
1122 int *pLocalNameLength
)
1124 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1125 TRACE("(%p)->(%d)\n", This
, index
);
1127 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1128 if(!pLocalName
|| !pLocalNameLength
) return E_POINTER
;
1130 *pLocalNameLength
= SysStringLen(This
->attributes
[index
].szLocalname
);
1131 *pLocalName
= This
->attributes
[index
].szLocalname
;
1136 static HRESULT WINAPI
isaxattributes_getQName(
1137 ISAXAttributes
* iface
,
1139 const WCHAR
**pQName
,
1142 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1143 TRACE("(%p)->(%d)\n", This
, index
);
1145 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1146 if(!pQName
|| !pQNameLength
) return E_POINTER
;
1148 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1149 *pQName
= This
->attributes
[index
].szQName
;
1154 static HRESULT WINAPI
isaxattributes_getName(
1155 ISAXAttributes
* iface
,
1159 const WCHAR
**localName
,
1160 int *pLocalNameSize
,
1161 const WCHAR
**QName
,
1164 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1165 TRACE("(%p)->(%d)\n", This
, index
);
1167 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1168 if(!uri
|| !pUriLength
|| !localName
|| !pLocalNameSize
1169 || !QName
|| !pQNameLength
) return E_POINTER
;
1171 *pUriLength
= SysStringLen(This
->attributes
[index
].szURI
);
1172 *uri
= This
->attributes
[index
].szURI
;
1173 *pLocalNameSize
= SysStringLen(This
->attributes
[index
].szLocalname
);
1174 *localName
= This
->attributes
[index
].szLocalname
;
1175 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1176 *QName
= This
->attributes
[index
].szQName
;
1178 TRACE("(%s, %s, %s)\n", debugstr_w(*uri
), debugstr_w(*localName
), debugstr_w(*QName
));
1183 static HRESULT WINAPI
isaxattributes_getIndexFromName(
1184 ISAXAttributes
* iface
,
1187 const WCHAR
*pLocalName
,
1188 int cocalNameLength
,
1191 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1193 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), cUriLength
,
1194 debugstr_w(pLocalName
), cocalNameLength
);
1196 if(!pUri
|| !pLocalName
|| !index
) return E_POINTER
;
1198 for(i
=0; i
<This
->attr_count
; i
++)
1200 if(cUriLength
!=SysStringLen(This
->attributes
[i
].szURI
)
1201 || cocalNameLength
!=SysStringLen(This
->attributes
[i
].szLocalname
))
1203 if(cUriLength
&& memcmp(pUri
, This
->attributes
[i
].szURI
,
1204 sizeof(WCHAR
)*cUriLength
))
1206 if(cocalNameLength
&& memcmp(pLocalName
, This
->attributes
[i
].szLocalname
,
1207 sizeof(WCHAR
)*cocalNameLength
))
1214 return E_INVALIDARG
;
1217 static HRESULT WINAPI
isaxattributes_getIndexFromQName(
1218 ISAXAttributes
* iface
,
1219 const WCHAR
*pQName
,
1223 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1225 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQNameLength
);
1227 if(!pQName
|| !index
) return E_POINTER
;
1228 if(!nQNameLength
) return E_INVALIDARG
;
1230 for(i
=0; i
<This
->attr_count
; i
++)
1232 if(nQNameLength
!=SysStringLen(This
->attributes
[i
].szQName
)) continue;
1233 if(memcmp(pQName
, This
->attributes
[i
].szQName
, sizeof(WCHAR
)*nQNameLength
)) continue;
1239 return E_INVALIDARG
;
1242 static HRESULT WINAPI
isaxattributes_getType(
1243 ISAXAttributes
* iface
,
1245 const WCHAR
**pType
,
1248 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1250 FIXME("(%p)->(%d) stub\n", This
, nIndex
);
1254 static HRESULT WINAPI
isaxattributes_getTypeFromName(
1255 ISAXAttributes
* iface
,
1258 const WCHAR
*pLocalName
,
1260 const WCHAR
**pType
,
1263 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1265 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This
, debugstr_w(pUri
), nUri
,
1266 debugstr_w(pLocalName
), nLocalName
);
1270 static HRESULT WINAPI
isaxattributes_getTypeFromQName(
1271 ISAXAttributes
* iface
,
1272 const WCHAR
*pQName
,
1274 const WCHAR
**pType
,
1277 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1279 FIXME("(%p)->(%s, %d) stub\n", This
, debugstr_w(pQName
), nQName
);
1283 static HRESULT WINAPI
isaxattributes_getValue(
1284 ISAXAttributes
* iface
,
1286 const WCHAR
**value
,
1289 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1290 TRACE("(%p)->(%d)\n", This
, index
);
1292 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1293 if(!value
|| !nValue
) return E_POINTER
;
1295 *nValue
= SysStringLen(This
->attributes
[index
].szValue
);
1296 *value
= This
->attributes
[index
].szValue
;
1298 TRACE("(%s:%d)\n", debugstr_w(*value
), *nValue
);
1303 static HRESULT WINAPI
isaxattributes_getValueFromName(
1304 ISAXAttributes
* iface
,
1307 const WCHAR
*pLocalName
,
1309 const WCHAR
**pValue
,
1314 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1315 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), nUri
,
1316 debugstr_w(pLocalName
), nLocalName
);
1318 hr
= ISAXAttributes_getIndexFromName(iface
,
1319 pUri
, nUri
, pLocalName
, nLocalName
, &index
);
1320 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1325 static HRESULT WINAPI
isaxattributes_getValueFromQName(
1326 ISAXAttributes
* iface
,
1327 const WCHAR
*pQName
,
1329 const WCHAR
**pValue
,
1334 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1335 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQName
);
1337 hr
= ISAXAttributes_getIndexFromQName(iface
, pQName
, nQName
, &index
);
1338 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1343 static const struct ISAXAttributesVtbl isaxattributes_vtbl
=
1345 isaxattributes_QueryInterface
,
1346 isaxattributes_AddRef
,
1347 isaxattributes_Release
,
1348 isaxattributes_getLength
,
1349 isaxattributes_getURI
,
1350 isaxattributes_getLocalName
,
1351 isaxattributes_getQName
,
1352 isaxattributes_getName
,
1353 isaxattributes_getIndexFromName
,
1354 isaxattributes_getIndexFromQName
,
1355 isaxattributes_getType
,
1356 isaxattributes_getTypeFromName
,
1357 isaxattributes_getTypeFromQName
,
1358 isaxattributes_getValue
,
1359 isaxattributes_getValueFromName
,
1360 isaxattributes_getValueFromQName
1363 /* Libxml2 escapes '&' back to char reference '&' in attribute value,
1364 so when document has escaped value with '&' it's parsed to '&' and then
1365 escaped to '&'. This function takes care of ampersands only. */
1366 static BSTR
saxreader_get_unescaped_value(const xmlChar
*buf
, int len
)
1368 static const WCHAR ampescW
[] = {'&','#','3','8',';',0};
1369 WCHAR
*dest
, *ptrW
, *str
;
1376 str_len
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
1377 if (len
!= -1) str_len
++;
1379 str
= heap_alloc(str_len
*sizeof(WCHAR
));
1380 if (!str
) return NULL
;
1382 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, str
, str_len
);
1383 if (len
!= -1) str
[str_len
-1] = 0;
1386 while ((dest
= strstrW(ptrW
, ampescW
)))
1390 /* leave first '&' from a reference as a value */
1391 src
= dest
+ (sizeof(ampescW
)/sizeof(WCHAR
) - 1);
1394 /* move together with null terminator */
1395 memmove(dest
, src
, (strlenW(src
) + 1)*sizeof(WCHAR
));
1400 bstr
= SysAllocString(str
);
1406 static void free_attribute_values(saxlocator
*locator
)
1410 for (i
= 0; i
< locator
->attr_count
; i
++)
1412 SysFreeString(locator
->attributes
[i
].szLocalname
);
1413 locator
->attributes
[i
].szLocalname
= NULL
;
1415 SysFreeString(locator
->attributes
[i
].szValue
);
1416 locator
->attributes
[i
].szValue
= NULL
;
1418 SysFreeString(locator
->attributes
[i
].szQName
);
1419 locator
->attributes
[i
].szQName
= NULL
;
1423 static HRESULT
SAXAttributes_populate(saxlocator
*locator
,
1424 int nb_namespaces
, const xmlChar
**xmlNamespaces
,
1425 int nb_attributes
, const xmlChar
**xmlAttributes
)
1427 static const xmlChar xmlns
[] = "xmlns";
1428 static const WCHAR xmlnsW
[] = { 'x','m','l','n','s',0 };
1430 struct _attributes
*attrs
;
1433 /* skip namespace definitions */
1434 if ((locator
->saxreader
->features
& NamespacePrefixes
) == 0)
1437 locator
->attr_count
= nb_namespaces
+ nb_attributes
;
1438 if(locator
->attr_count
> locator
->attr_alloc_count
)
1440 int new_size
= locator
->attr_count
* 2;
1441 attrs
= heap_realloc_zero(locator
->attributes
, new_size
* sizeof(struct _attributes
));
1444 free_attribute_values(locator
);
1445 locator
->attr_count
= 0;
1446 return E_OUTOFMEMORY
;
1448 locator
->attributes
= attrs
;
1449 locator
->attr_alloc_count
= new_size
;
1453 attrs
= locator
->attributes
;
1456 for (i
= 0; i
< nb_namespaces
; i
++)
1458 SysFreeString(attrs
[nb_attributes
+i
].szLocalname
);
1459 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1461 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1463 SysFreeString(attrs
[nb_attributes
+i
].szValue
);
1464 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1466 SysFreeString(attrs
[nb_attributes
+i
].szQName
);
1467 if(!xmlNamespaces
[2*i
])
1468 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1470 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1473 for (i
= 0; i
< nb_attributes
; i
++)
1475 static const xmlChar xmlA
[] = "xml";
1477 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1478 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1480 /* that's an important feature to keep same uri pointer for every reported attribute */
1481 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1483 SysFreeString(attrs
[i
].szLocalname
);
1484 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1486 SysFreeString(attrs
[i
].szValue
);
1487 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1489 SysFreeString(attrs
[i
].szQName
);
1490 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1], xmlAttributes
[i
*5]);
1496 /*** LibXML callbacks ***/
1497 static void libxmlStartDocument(void *ctx
)
1499 saxlocator
*This
= ctx
;
1500 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1503 if (This
->saxreader
->version
>= MSXML4
)
1505 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1506 update_position(This
, FALSE
);
1507 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1509 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1514 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1518 /* store version value, declaration has to contain version attribute */
1519 if (This
->pParserCtxt
->standalone
!= -1)
1521 SysFreeString(This
->saxreader
->xmldecl_version
);
1522 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1525 if (saxreader_has_handler(This
, SAXContentHandler
))
1527 if(This
->vbInterface
)
1528 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1530 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1532 if (sax_callback_failed(This
, hr
))
1533 format_error_message_from_id(This
, hr
);
1537 static void libxmlEndDocument(void *ctx
)
1539 saxlocator
*This
= ctx
;
1540 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1543 if (This
->saxreader
->version
>= MSXML4
) {
1544 update_position(This
, FALSE
);
1545 if(This
->column
> 1)
1553 if(This
->ret
!= S_OK
) return;
1555 if (saxreader_has_handler(This
, SAXContentHandler
))
1557 if(This
->vbInterface
)
1558 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1560 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1562 if (sax_callback_failed(This
, hr
))
1563 format_error_message_from_id(This
, hr
);
1567 static void libxmlStartElementNS(
1569 const xmlChar
*localname
,
1570 const xmlChar
*prefix
,
1573 const xmlChar
**namespaces
,
1576 const xmlChar
**attributes
)
1578 saxlocator
*This
= ctx
;
1579 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1580 element_entry
*element
;
1584 update_position(This
, TRUE
);
1585 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1587 if(This
->saxreader
->version
< MSXML4
)
1590 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1591 push_element_ns(This
, element
);
1593 if (is_namespaces_enabled(This
->saxreader
))
1597 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1599 if (This
->vbInterface
)
1600 hr
= IVBSAXContentHandler_startPrefixMapping(
1602 &element
->ns
[i
].prefix
,
1603 &element
->ns
[i
].uri
);
1605 hr
= ISAXContentHandler_startPrefixMapping(
1607 element
->ns
[i
].prefix
,
1608 SysStringLen(element
->ns
[i
].prefix
),
1610 SysStringLen(element
->ns
[i
].uri
));
1612 if (sax_callback_failed(This
, hr
))
1614 format_error_message_from_id(This
, hr
);
1620 uri
= find_element_uri(This
, URI
);
1621 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1622 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1626 if (is_namespaces_enabled(This
->saxreader
))
1627 local
= element
->local
;
1631 if (This
->vbInterface
)
1632 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1633 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1635 hr
= ISAXContentHandler_startElement(handler
->handler
,
1636 uri
, SysStringLen(uri
),
1637 local
, SysStringLen(local
),
1638 element
->qname
, SysStringLen(element
->qname
),
1639 &This
->ISAXAttributes_iface
);
1641 if (sax_callback_failed(This
, hr
))
1642 format_error_message_from_id(This
, hr
);
1646 static void libxmlEndElementNS(
1648 const xmlChar
*localname
,
1649 const xmlChar
*prefix
,
1652 saxlocator
*This
= ctx
;
1653 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1654 element_entry
*element
;
1659 update_position(This
, FALSE
);
1660 p
= This
->pParserCtxt
->input
->cur
;
1662 if (This
->saxreader
->version
>= MSXML4
)
1665 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1667 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1672 else if(*(p
-1)!='>' || *(p
-2)!='/')
1675 while(p
-2>=This
->pParserCtxt
->input
->base
1676 && *(p
-2)!='<' && *(p
-1)!='/')
1678 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1684 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1687 uri
= find_element_uri(This
, URI
);
1688 element
= pop_element_ns(This
);
1690 if (!saxreader_has_handler(This
, SAXContentHandler
))
1692 free_attribute_values(This
);
1693 This
->attr_count
= 0;
1694 free_element_entry(element
);
1698 if (is_namespaces_enabled(This
->saxreader
))
1699 local
= element
->local
;
1703 if (This
->vbInterface
)
1704 hr
= IVBSAXContentHandler_endElement(
1706 &uri
, &local
, &element
->qname
);
1708 hr
= ISAXContentHandler_endElement(
1710 uri
, SysStringLen(uri
),
1711 local
, SysStringLen(local
),
1712 element
->qname
, SysStringLen(element
->qname
));
1714 free_attribute_values(This
);
1715 This
->attr_count
= 0;
1717 if (sax_callback_failed(This
, hr
))
1719 format_error_message_from_id(This
, hr
);
1720 free_element_entry(element
);
1724 if (is_namespaces_enabled(This
->saxreader
))
1727 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1729 if (This
->vbInterface
)
1730 hr
= IVBSAXContentHandler_endPrefixMapping(
1731 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1733 hr
= ISAXContentHandler_endPrefixMapping(
1734 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1736 if (sax_callback_failed(This
, hr
)) break;
1739 if (sax_callback_failed(This
, hr
))
1740 format_error_message_from_id(This
, hr
);
1743 free_element_entry(element
);
1746 static void libxmlCharacters(
1751 saxlocator
*This
= ctx
;
1755 BOOL lastEvent
= FALSE
;
1757 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1759 update_position(This
, FALSE
);
1760 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1761 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1763 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1768 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1772 if(*(ch
-1)=='\r') cur
--;
1777 while(end
-ch
<len
&& *end
!='\r') end
++;
1788 if (This
->saxreader
->version
>= MSXML4
)
1792 for(p
=cur
; p
!=end
; p
++)
1809 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1810 hr
= saxreader_saxcharacters(This
, Chars
);
1812 if (sax_callback_failed(This
, hr
))
1814 format_error_message_from_id(This
, hr
);
1818 if (This
->saxreader
->version
< MSXML4
)
1819 This
->column
+= end
-cur
;
1832 if(end
-ch
== len
) break;
1836 static void libxmlSetDocumentLocator(
1838 xmlSAXLocatorPtr loc
)
1840 saxlocator
*This
= ctx
;
1841 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1844 if (saxreader_has_handler(This
, SAXContentHandler
))
1846 if(This
->vbInterface
)
1847 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1848 &This
->IVBSAXLocator_iface
);
1850 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1854 format_error_message_from_id(This
, hr
);
1857 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1859 saxlocator
*This
= ctx
;
1860 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1863 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1865 update_position(This
, FALSE
);
1866 while(p
-4>=This
->pParserCtxt
->input
->base
1867 && memcmp(p
-4, "<!--", sizeof(char[4])))
1869 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1875 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1878 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1880 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1882 if (This
->vbInterface
)
1883 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1885 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1888 format_error_message_from_id(This
, hr
);
1891 static void libxmlFatalError(void *ctx
, const char *msg
, ...)
1893 saxlocator
*This
= ctx
;
1894 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1900 if(This
->ret
!= S_OK
) {
1901 xmlStopParser(This
->pParserCtxt
);
1905 va_start(args
, msg
);
1906 vsprintf(message
, msg
, args
);
1909 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1910 error
= heap_alloc(sizeof(WCHAR
)*len
);
1913 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1914 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1917 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1919 xmlStopParser(This
->pParserCtxt
);
1925 FIXME("Error handling is not compatible.\n");
1927 if(This
->vbInterface
)
1929 BSTR bstrError
= SysAllocString(error
);
1930 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1931 &bstrError
, E_FAIL
);
1932 SysFreeString(bstrError
);
1935 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1939 xmlStopParser(This
->pParserCtxt
);
1943 /* The only reason this helper exists is that CDATA section are reported by chunks,
1944 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1946 This helper should be called for substring with trailing newlines.
1948 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1950 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1953 ptr
= bstr
+ len
- 1;
1954 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1959 /* replace returns as:
1961 - "\r<char>" -> "\n<char>"
1967 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
1970 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
1977 ret
= SysAllocStringLen(bstr
, len
);
1978 SysFreeString(bstr
);
1982 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
1984 const xmlChar
*start
, *end
;
1985 saxlocator
*locator
= ctx
;
1986 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
1991 update_position(locator
, FALSE
);
1992 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
1994 if (locator
->vbInterface
)
1995 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
1997 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
2002 format_error_message_from_id(locator
, hr
);
2012 /* scan for newlines */
2013 if (value
[i
] == '\r' || value
[i
] == '\n')
2015 /* skip newlines/linefeeds */
2018 if (value
[i
] != '\r' && value
[i
] != '\n') break;
2024 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
2025 TRACE("(chunk %s)\n", debugstr_w(chars
));
2026 hr
= saxreader_saxcharacters(locator
, chars
);
2027 SysFreeString(chars
);
2036 /* no newline chars (or last chunk) report as a whole */
2037 if (!end
&& start
== value
)
2040 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
2041 TRACE("(%s)\n", debugstr_w(chars
));
2042 hr
= saxreader_saxcharacters(locator
, chars
);
2043 SysFreeString(chars
);
2046 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2048 if (locator
->vbInterface
)
2049 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
2051 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
2055 format_error_message_from_id(locator
, hr
);
2058 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
2060 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
2061 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
2064 /*** IVBSAXLocator interface ***/
2065 /*** IUnknown methods ***/
2066 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2068 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2070 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2074 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2075 IsEqualGUID( riid
, &IID_IDispatch
) ||
2076 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
2080 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
2082 *ppvObject
= &This
->IVBSAXAttributes_iface
;
2086 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2087 return E_NOINTERFACE
;
2090 IVBSAXLocator_AddRef( iface
);
2095 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
2097 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2098 TRACE("%p\n", This
);
2099 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
2102 static ULONG WINAPI
ivbsaxlocator_Release(IVBSAXLocator
* iface
)
2104 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2105 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
2108 /*** IDispatch methods ***/
2109 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
2111 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2113 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2120 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
2121 IVBSAXLocator
*iface
,
2122 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2124 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2126 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2128 return get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2131 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2132 IVBSAXLocator
*iface
,
2134 LPOLESTR
* rgszNames
,
2139 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2140 ITypeInfo
*typeinfo
;
2143 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
2146 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2147 return E_INVALIDARG
;
2149 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2152 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2153 ITypeInfo_Release(typeinfo
);
2159 static HRESULT WINAPI
ivbsaxlocator_Invoke(
2160 IVBSAXLocator
*iface
,
2161 DISPID dispIdMember
,
2165 DISPPARAMS
* pDispParams
,
2166 VARIANT
* pVarResult
,
2167 EXCEPINFO
* pExcepInfo
,
2170 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2171 ITypeInfo
*typeinfo
;
2174 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2175 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2177 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2180 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXLocator_iface
, dispIdMember
, wFlags
,
2181 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2182 ITypeInfo_Release(typeinfo
);
2188 /*** IVBSAXLocator methods ***/
2189 static HRESULT WINAPI
ivbsaxlocator_get_columnNumber(
2190 IVBSAXLocator
* iface
,
2193 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2194 return ISAXLocator_getColumnNumber(&This
->ISAXLocator_iface
, pnColumn
);
2197 static HRESULT WINAPI
ivbsaxlocator_get_lineNumber(
2198 IVBSAXLocator
* iface
,
2201 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2202 return ISAXLocator_getLineNumber(&This
->ISAXLocator_iface
, pnLine
);
2205 static HRESULT WINAPI
ivbsaxlocator_get_publicId(IVBSAXLocator
* iface
, BSTR
*ret
)
2207 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2208 const WCHAR
*publicidW
;
2211 TRACE("(%p)->(%p)\n", This
, ret
);
2217 hr
= ISAXLocator_getPublicId(&This
->ISAXLocator_iface
, &publicidW
);
2221 return return_bstr(publicidW
, ret
);
2224 static HRESULT WINAPI
ivbsaxlocator_get_systemId(IVBSAXLocator
* iface
, BSTR
*ret
)
2226 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2227 const WCHAR
*systemidW
;
2230 TRACE("(%p)->(%p)\n", This
, ret
);
2236 hr
= ISAXLocator_getSystemId(&This
->ISAXLocator_iface
, &systemidW
);
2240 return return_bstr(systemidW
, ret
);
2243 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl
=
2245 ivbsaxlocator_QueryInterface
,
2246 ivbsaxlocator_AddRef
,
2247 ivbsaxlocator_Release
,
2248 ivbsaxlocator_GetTypeInfoCount
,
2249 ivbsaxlocator_GetTypeInfo
,
2250 ivbsaxlocator_GetIDsOfNames
,
2251 ivbsaxlocator_Invoke
,
2252 ivbsaxlocator_get_columnNumber
,
2253 ivbsaxlocator_get_lineNumber
,
2254 ivbsaxlocator_get_publicId
,
2255 ivbsaxlocator_get_systemId
2258 /*** ISAXLocator interface ***/
2259 /*** IUnknown methods ***/
2260 static HRESULT WINAPI
isaxlocator_QueryInterface(ISAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2262 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2264 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2268 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2269 IsEqualGUID( riid
, &IID_ISAXLocator
))
2273 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
2275 *ppvObject
= &This
->ISAXAttributes_iface
;
2279 WARN("interface %s not implemented\n", debugstr_guid(riid
));
2280 return E_NOINTERFACE
;
2283 ISAXLocator_AddRef( iface
);
2288 static ULONG WINAPI
isaxlocator_AddRef(ISAXLocator
* iface
)
2290 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2291 ULONG ref
= InterlockedIncrement( &This
->ref
);
2292 TRACE("(%p)->(%d)\n", This
, ref
);
2296 static ULONG WINAPI
isaxlocator_Release(
2299 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2300 LONG ref
= InterlockedDecrement( &This
->ref
);
2302 TRACE("(%p)->(%d)\n", This
, ref
);
2306 element_entry
*element
, *element2
;
2309 SysFreeString(This
->publicId
);
2310 SysFreeString(This
->systemId
);
2311 SysFreeString(This
->namespaceUri
);
2313 for(index
= 0; index
< This
->attr_alloc_count
; index
++)
2315 SysFreeString(This
->attributes
[index
].szLocalname
);
2316 SysFreeString(This
->attributes
[index
].szValue
);
2317 SysFreeString(This
->attributes
[index
].szQName
);
2319 heap_free(This
->attributes
);
2322 LIST_FOR_EACH_ENTRY_SAFE(element
, element2
, &This
->elements
, element_entry
, entry
)
2324 list_remove(&element
->entry
);
2325 free_element_entry(element
);
2328 ISAXXMLReader_Release(&This
->saxreader
->ISAXXMLReader_iface
);
2335 /*** ISAXLocator methods ***/
2336 static HRESULT WINAPI
isaxlocator_getColumnNumber(
2340 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2342 *pnColumn
= This
->column
;
2346 static HRESULT WINAPI
isaxlocator_getLineNumber(
2350 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2352 *pnLine
= This
->line
;
2356 static HRESULT WINAPI
isaxlocator_getPublicId(
2358 const WCHAR
** ppwchPublicId
)
2361 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2363 SysFreeString(This
->publicId
);
2365 publicId
= bstr_from_xmlChar(xmlSAX2GetPublicId(This
->pParserCtxt
));
2366 if(SysStringLen(publicId
))
2367 This
->publicId
= publicId
;
2370 SysFreeString(publicId
);
2371 This
->publicId
= NULL
;
2374 *ppwchPublicId
= This
->publicId
;
2378 static HRESULT WINAPI
isaxlocator_getSystemId(
2380 const WCHAR
** ppwchSystemId
)
2383 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2385 SysFreeString(This
->systemId
);
2387 systemId
= bstr_from_xmlChar(xmlSAX2GetSystemId(This
->pParserCtxt
));
2388 if(SysStringLen(systemId
))
2389 This
->systemId
= systemId
;
2392 SysFreeString(systemId
);
2393 This
->systemId
= NULL
;
2396 *ppwchSystemId
= This
->systemId
;
2400 static const struct ISAXLocatorVtbl SAXLocatorVtbl
=
2402 isaxlocator_QueryInterface
,
2404 isaxlocator_Release
,
2405 isaxlocator_getColumnNumber
,
2406 isaxlocator_getLineNumber
,
2407 isaxlocator_getPublicId
,
2408 isaxlocator_getSystemId
2411 static HRESULT
SAXLocator_create(saxreader
*reader
, saxlocator
**ppsaxlocator
, BOOL vbInterface
)
2413 static const WCHAR w3xmlns
[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2414 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2416 saxlocator
*locator
;
2418 locator
= heap_alloc( sizeof (*locator
) );
2420 return E_OUTOFMEMORY
;
2422 locator
->IVBSAXLocator_iface
.lpVtbl
= &VBSAXLocatorVtbl
;
2423 locator
->ISAXLocator_iface
.lpVtbl
= &SAXLocatorVtbl
;
2424 locator
->IVBSAXAttributes_iface
.lpVtbl
= &ivbsaxattributes_vtbl
;
2425 locator
->ISAXAttributes_iface
.lpVtbl
= &isaxattributes_vtbl
;
2427 locator
->vbInterface
= vbInterface
;
2429 locator
->saxreader
= reader
;
2430 ISAXXMLReader_AddRef(&reader
->ISAXXMLReader_iface
);
2432 locator
->pParserCtxt
= NULL
;
2433 locator
->publicId
= NULL
;
2434 locator
->systemId
= NULL
;
2435 locator
->line
= reader
->version
< MSXML4
? 0 : 1;
2436 locator
->column
= 0;
2437 locator
->ret
= S_OK
;
2438 if (locator
->saxreader
->version
>= MSXML6
)
2439 locator
->namespaceUri
= SysAllocString(w3xmlns
);
2441 locator
->namespaceUri
= SysAllocStringLen(NULL
, 0);
2442 if(!locator
->namespaceUri
)
2444 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2446 return E_OUTOFMEMORY
;
2449 locator
->attr_alloc_count
= 8;
2450 locator
->attr_count
= 0;
2451 locator
->attributes
= heap_alloc_zero(sizeof(struct _attributes
)*locator
->attr_alloc_count
);
2452 if(!locator
->attributes
)
2454 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2455 SysFreeString(locator
->namespaceUri
);
2457 return E_OUTOFMEMORY
;
2460 list_init(&locator
->elements
);
2462 *ppsaxlocator
= locator
;
2464 TRACE("returning %p\n", *ppsaxlocator
);
2469 /*** SAXXMLReader internal functions ***/
2470 static HRESULT
internal_parseBuffer(saxreader
*This
, const char *buffer
, int size
, BOOL vbInterface
)
2472 xmlCharEncoding encoding
= XML_CHAR_ENCODING_NONE
;
2473 xmlChar
*enc_name
= NULL
;
2474 saxlocator
*locator
;
2477 TRACE("(%p)->(%p %d)\n", This
, buffer
, size
);
2479 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2485 const unsigned char *buff
= (unsigned char*)buffer
;
2487 encoding
= xmlDetectCharEncoding((xmlChar
*)buffer
, 4);
2488 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2489 TRACE("detected encoding: %s\n", enc_name
);
2490 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2491 if ((encoding
== XML_CHAR_ENCODING_UTF8
) &&
2492 buff
[0] == 0xEF && buff
[1] == 0xBB && buff
[2] == 0xBF)
2499 /* if libxml2 detection failed try to guess */
2500 if (encoding
== XML_CHAR_ENCODING_NONE
)
2502 const WCHAR
*ptr
= (WCHAR
*)buffer
;
2503 /* an xml declaration with optional encoding will still be handled by the parser */
2504 if ((size
>= 2) && *ptr
== '<' && ptr
[1] != '?')
2506 enc_name
= (xmlChar
*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE
);
2507 encoding
= XML_CHAR_ENCODING_UTF16LE
;
2510 else if (encoding
== XML_CHAR_ENCODING_UTF8
)
2511 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2515 locator
->pParserCtxt
= xmlCreateMemoryParserCtxt(buffer
, size
);
2516 if (!locator
->pParserCtxt
)
2518 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2524 locator
->pParserCtxt
->encoding
= xmlStrdup(enc_name
);
2525 if (encoding
== XML_CHAR_ENCODING_UTF16LE
) {
2526 TRACE("switching to %s\n", enc_name
);
2527 xmlSwitchEncoding(locator
->pParserCtxt
, encoding
);
2531 xmlFree(locator
->pParserCtxt
->sax
);
2532 locator
->pParserCtxt
->sax
= &locator
->saxreader
->sax
;
2533 locator
->pParserCtxt
->userData
= locator
;
2535 This
->isParsing
= TRUE
;
2536 if(xmlParseDocument(locator
->pParserCtxt
) == -1 && locator
->ret
== S_OK
)
2540 This
->isParsing
= FALSE
;
2542 if(locator
->pParserCtxt
)
2544 locator
->pParserCtxt
->sax
= NULL
;
2545 xmlFreeParserCtxt(locator
->pParserCtxt
);
2546 locator
->pParserCtxt
= NULL
;
2549 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2553 static HRESULT
internal_parseStream(saxreader
*This
, ISequentialStream
*stream
, BOOL vbInterface
)
2555 saxlocator
*locator
;
2562 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2563 if(FAILED(hr
)) return hr
;
2565 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2566 if(FAILED(hr
)) return hr
;
2568 locator
->pParserCtxt
= xmlCreatePushParserCtxt(
2569 &locator
->saxreader
->sax
, locator
,
2570 data
, dataRead
, NULL
);
2571 if(!locator
->pParserCtxt
)
2573 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2577 This
->isParsing
= TRUE
;
2581 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2582 if (FAILED(hr
) || !dataRead
) break;
2584 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, dataRead
, 0);
2585 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2590 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2591 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2595 This
->isParsing
= FALSE
;
2597 xmlFreeParserCtxt(locator
->pParserCtxt
);
2598 locator
->pParserCtxt
= NULL
;
2599 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2603 static HRESULT
internal_parse(
2610 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varInput
));
2612 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2613 free_bstr_pool(&This
->pool
);
2615 switch(V_VT(&varInput
))
2618 case VT_BSTR
|VT_BYREF
:
2620 BSTR str
= V_ISBYREF(&varInput
) ? *V_BSTRREF(&varInput
) : V_BSTR(&varInput
);
2621 hr
= internal_parseBuffer(This
, (const char*)str
, strlenW(str
)*sizeof(WCHAR
), vbInterface
);
2624 case VT_ARRAY
|VT_UI1
: {
2626 LONG lBound
, uBound
;
2629 hr
= SafeArrayGetLBound(V_ARRAY(&varInput
), 1, &lBound
);
2630 if(hr
!= S_OK
) break;
2631 hr
= SafeArrayGetUBound(V_ARRAY(&varInput
), 1, &uBound
);
2632 if(hr
!= S_OK
) break;
2633 dataRead
= (uBound
-lBound
)*SafeArrayGetElemsize(V_ARRAY(&varInput
));
2634 hr
= SafeArrayAccessData(V_ARRAY(&varInput
), &pSAData
);
2635 if(hr
!= S_OK
) break;
2636 hr
= internal_parseBuffer(This
, pSAData
, dataRead
, vbInterface
);
2637 SafeArrayUnaccessData(V_ARRAY(&varInput
));
2642 IPersistStream
*persistStream
;
2643 ISequentialStream
*stream
= NULL
;
2644 IXMLDOMDocument
*xmlDoc
;
2646 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2647 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2651 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2652 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2653 SysStringByteLen(bstrData
), vbInterface
);
2654 IXMLDOMDocument_Release(xmlDoc
);
2655 SysFreeString(bstrData
);
2659 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2660 &IID_IPersistStream
, (void**)&persistStream
) == S_OK
)
2662 IStream
*stream_copy
;
2664 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream_copy
);
2667 IPersistStream_Release(persistStream
);
2671 hr
= IPersistStream_Save(persistStream
, stream_copy
, TRUE
);
2672 IPersistStream_Release(persistStream
);
2674 IStream_QueryInterface(stream_copy
, &IID_ISequentialStream
, (void**)&stream
);
2676 IStream_Release(stream_copy
);
2679 /* try base interface first */
2682 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2684 /* this should never happen if IStream is implemented properly, but just in case */
2685 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2690 hr
= internal_parseStream(This
, stream
, vbInterface
);
2691 ISequentialStream_Release(stream
);
2695 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2702 WARN("vt %d not implemented\n", V_VT(&varInput
));
2709 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2711 saxreader
*This
= obj
;
2713 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2716 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2718 saxreader
*This
= obj
;
2720 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2723 static HRESULT
internal_parseURL(
2732 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
2734 hr
= create_moniker_from_url(url
, &mon
);
2738 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, This
, &bsc
);
2739 else hr
= bind_url(mon
, internal_onDataAvailable
, This
, &bsc
);
2740 IMoniker_Release(mon
);
2745 return detach_bsc(bsc
);
2748 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2752 if (V_VT(v
) == VT_EMPTY
)
2753 return saxreader_put_handler(This
, type
, NULL
, vb
);
2757 case SAXDeclHandler
:
2758 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2760 case SAXLexicalHandler
:
2761 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2764 ERR("wrong handler type %d\n", type
);
2773 IUnknown
*handler
= NULL
;
2777 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2778 if (FAILED(hr
)) return hr
;
2781 saxreader_put_handler(This
, type
, handler
, vb
);
2782 if (handler
) IUnknown_Release(handler
);
2786 ERR("value type %d not supported\n", V_VT(v
));
2787 return E_INVALIDARG
;
2793 static HRESULT
internal_putProperty(
2801 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2803 if (This
->isParsing
) return E_FAIL
;
2805 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2806 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2807 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2809 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2810 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2812 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2814 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2815 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2819 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2821 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2822 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2826 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2828 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2831 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2834 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2837 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2840 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2843 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2846 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2849 return E_INVALIDARG
;
2852 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2854 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2856 if (!value
) return E_POINTER
;
2858 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2860 V_VT(value
) = VT_UNKNOWN
;
2861 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2865 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2867 V_VT(value
) = VT_UNKNOWN
;
2868 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2872 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2874 V_VT(value
) = VT_BSTR
;
2875 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2879 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2884 /*** IVBSAXXMLReader interface ***/
2885 /*** IUnknown methods ***/
2886 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2888 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2890 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2894 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2895 IsEqualGUID( riid
, &IID_IDispatch
) ||
2896 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2900 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2902 *ppvObject
= &This
->ISAXXMLReader_iface
;
2904 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2906 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2910 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2911 return E_NOINTERFACE
;
2914 IVBSAXXMLReader_AddRef( iface
);
2919 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2921 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2922 TRACE("%p\n", This
);
2923 return InterlockedIncrement( &This
->ref
);
2926 static ULONG WINAPI
saxxmlreader_Release(
2927 IVBSAXXMLReader
* iface
)
2929 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2932 TRACE("%p\n", This
);
2934 ref
= InterlockedDecrement( &This
->ref
);
2939 for (i
= 0; i
< SAXHandler_Last
; i
++)
2941 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2943 if (saxiface
->handler
)
2944 IUnknown_Release(saxiface
->handler
);
2946 if (saxiface
->vbhandler
)
2947 IUnknown_Release(saxiface
->vbhandler
);
2950 SysFreeString(This
->xmldecl_version
);
2951 free_bstr_pool(&This
->pool
);
2959 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2961 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2962 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2965 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2966 IVBSAXXMLReader
*iface
,
2967 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2969 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2970 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2971 iTInfo
, lcid
, ppTInfo
);
2974 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2975 IVBSAXXMLReader
*iface
,
2977 LPOLESTR
* rgszNames
,
2982 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2983 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
2984 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
2987 static HRESULT WINAPI
saxxmlreader_Invoke(
2988 IVBSAXXMLReader
*iface
,
2989 DISPID dispIdMember
,
2993 DISPPARAMS
* pDispParams
,
2994 VARIANT
* pVarResult
,
2995 EXCEPINFO
* pExcepInfo
,
2998 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2999 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
3000 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3003 /*** IVBSAXXMLReader methods ***/
3004 static HRESULT WINAPI
saxxmlreader_getFeature(
3005 IVBSAXXMLReader
* iface
,
3007 VARIANT_BOOL
*value
)
3009 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3010 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3013 static HRESULT WINAPI
saxxmlreader_putFeature(
3014 IVBSAXXMLReader
* iface
,
3018 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3019 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3022 static HRESULT WINAPI
saxxmlreader_getProperty(
3023 IVBSAXXMLReader
* iface
,
3027 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3028 return internal_getProperty(This
, prop
, value
, TRUE
);
3031 static HRESULT WINAPI
saxxmlreader_putProperty(
3032 IVBSAXXMLReader
* iface
,
3036 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3037 return internal_putProperty(This
, pProp
, value
, TRUE
);
3040 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3041 IVBSAXXMLReader
* iface
,
3042 IVBSAXEntityResolver
**resolver
)
3044 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3045 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3048 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3049 IVBSAXXMLReader
* iface
,
3050 IVBSAXEntityResolver
*resolver
)
3052 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3053 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3056 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3057 IVBSAXXMLReader
* iface
,
3058 IVBSAXContentHandler
**handler
)
3060 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3061 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3064 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3065 IVBSAXXMLReader
* iface
,
3066 IVBSAXContentHandler
*handler
)
3068 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3069 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3072 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3073 IVBSAXXMLReader
* iface
,
3074 IVBSAXDTDHandler
**handler
)
3076 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3077 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3080 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3081 IVBSAXXMLReader
* iface
,
3082 IVBSAXDTDHandler
*handler
)
3084 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3085 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3088 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3089 IVBSAXXMLReader
* iface
,
3090 IVBSAXErrorHandler
**handler
)
3092 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3093 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3096 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3097 IVBSAXXMLReader
* iface
,
3098 IVBSAXErrorHandler
*handler
)
3100 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3101 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3104 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3105 IVBSAXXMLReader
* iface
,
3108 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3110 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3114 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3115 IVBSAXXMLReader
* iface
,
3118 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3119 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3122 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3123 IVBSAXXMLReader
* iface
,
3124 BSTR
*pSecureBaseUrl
)
3126 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3128 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3132 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3133 IVBSAXXMLReader
* iface
,
3136 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3137 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3140 static HRESULT WINAPI
saxxmlreader_parse(
3141 IVBSAXXMLReader
* iface
,
3144 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3145 return internal_parse(This
, varInput
, TRUE
);
3148 static HRESULT WINAPI
saxxmlreader_parseURL(
3149 IVBSAXXMLReader
* iface
,
3152 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3153 return internal_parseURL(This
, url
, TRUE
);
3156 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3158 saxxmlreader_QueryInterface
,
3159 saxxmlreader_AddRef
,
3160 saxxmlreader_Release
,
3161 saxxmlreader_GetTypeInfoCount
,
3162 saxxmlreader_GetTypeInfo
,
3163 saxxmlreader_GetIDsOfNames
,
3164 saxxmlreader_Invoke
,
3165 saxxmlreader_getFeature
,
3166 saxxmlreader_putFeature
,
3167 saxxmlreader_getProperty
,
3168 saxxmlreader_putProperty
,
3169 saxxmlreader_get_entityResolver
,
3170 saxxmlreader_put_entityResolver
,
3171 saxxmlreader_get_contentHandler
,
3172 saxxmlreader_put_contentHandler
,
3173 saxxmlreader_get_dtdHandler
,
3174 saxxmlreader_put_dtdHandler
,
3175 saxxmlreader_get_errorHandler
,
3176 saxxmlreader_put_errorHandler
,
3177 saxxmlreader_get_baseURL
,
3178 saxxmlreader_put_baseURL
,
3179 saxxmlreader_get_secureBaseURL
,
3180 saxxmlreader_put_secureBaseURL
,
3182 saxxmlreader_parseURL
3185 /*** ISAXXMLReader interface ***/
3186 /*** IUnknown methods ***/
3187 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3189 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3190 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3193 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3195 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3196 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3199 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3201 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3202 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3205 /*** ISAXXMLReader methods ***/
3206 static HRESULT WINAPI
isaxxmlreader_getFeature(
3207 ISAXXMLReader
* iface
,
3208 const WCHAR
*feature_name
,
3209 VARIANT_BOOL
*value
)
3211 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3212 saxreader_feature feature
;
3214 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3216 feature
= get_saxreader_feature(feature_name
);
3217 if (feature
== Namespaces
|| feature
== NamespacePrefixes
)
3218 return get_feature_value(This
, feature
, value
);
3220 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3224 static HRESULT WINAPI
isaxxmlreader_putFeature(
3225 ISAXXMLReader
* iface
,
3226 const WCHAR
*feature_name
,
3229 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3230 saxreader_feature feature
;
3232 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3234 feature
= get_saxreader_feature(feature_name
);
3236 /* accepted cases */
3237 if ((feature
== ExternalGeneralEntities
&& value
== VARIANT_FALSE
) ||
3238 (feature
== ExternalParameterEntities
&& value
== VARIANT_FALSE
) ||
3239 feature
== Namespaces
||
3240 feature
== NamespacePrefixes
)
3242 return set_feature_value(This
, feature
, value
);
3245 if (feature
== LexicalHandlerParEntities
|| feature
== ProhibitDTD
)
3247 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3248 return set_feature_value(This
, feature
, value
);
3251 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3255 static HRESULT WINAPI
isaxxmlreader_getProperty(
3256 ISAXXMLReader
* iface
,
3260 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3261 return internal_getProperty(This
, prop
, value
, FALSE
);
3264 static HRESULT WINAPI
isaxxmlreader_putProperty(
3265 ISAXXMLReader
* iface
,
3269 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3270 return internal_putProperty(This
, pProp
, value
, FALSE
);
3273 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3274 ISAXXMLReader
* iface
,
3275 ISAXEntityResolver
**resolver
)
3277 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3278 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3281 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3282 ISAXXMLReader
* iface
,
3283 ISAXEntityResolver
*resolver
)
3285 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3286 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3289 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3290 ISAXXMLReader
* iface
,
3291 ISAXContentHandler
**handler
)
3293 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3294 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3297 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3298 ISAXXMLReader
* iface
,
3299 ISAXContentHandler
*handler
)
3301 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3302 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3305 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3306 ISAXXMLReader
* iface
,
3307 ISAXDTDHandler
**handler
)
3309 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3310 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3313 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3314 ISAXXMLReader
* iface
,
3315 ISAXDTDHandler
*handler
)
3317 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3318 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3321 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3322 ISAXXMLReader
* iface
,
3323 ISAXErrorHandler
**handler
)
3325 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3326 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3329 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3331 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3332 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3335 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3336 ISAXXMLReader
* iface
,
3337 const WCHAR
**base_url
)
3339 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3341 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3345 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3346 ISAXXMLReader
* iface
,
3347 const WCHAR
*pBaseUrl
)
3349 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3351 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3355 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3356 ISAXXMLReader
* iface
,
3357 const WCHAR
**pSecureBaseUrl
)
3359 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3360 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3364 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3365 ISAXXMLReader
* iface
,
3366 const WCHAR
*secureBaseUrl
)
3368 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3370 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3374 static HRESULT WINAPI
isaxxmlreader_parse(
3375 ISAXXMLReader
* iface
,
3378 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3379 return internal_parse(This
, varInput
, FALSE
);
3382 static HRESULT WINAPI
isaxxmlreader_parseURL(
3383 ISAXXMLReader
* iface
,
3386 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3387 return internal_parseURL(This
, url
, FALSE
);
3390 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3392 isaxxmlreader_QueryInterface
,
3393 isaxxmlreader_AddRef
,
3394 isaxxmlreader_Release
,
3395 isaxxmlreader_getFeature
,
3396 isaxxmlreader_putFeature
,
3397 isaxxmlreader_getProperty
,
3398 isaxxmlreader_putProperty
,
3399 isaxxmlreader_getEntityResolver
,
3400 isaxxmlreader_putEntityResolver
,
3401 isaxxmlreader_getContentHandler
,
3402 isaxxmlreader_putContentHandler
,
3403 isaxxmlreader_getDTDHandler
,
3404 isaxxmlreader_putDTDHandler
,
3405 isaxxmlreader_getErrorHandler
,
3406 isaxxmlreader_putErrorHandler
,
3407 isaxxmlreader_getBaseURL
,
3408 isaxxmlreader_putBaseURL
,
3409 isaxxmlreader_getSecureBaseURL
,
3410 isaxxmlreader_putSecureBaseURL
,
3411 isaxxmlreader_parse
,
3412 isaxxmlreader_parseURL
3415 static const tid_t saxreader_iface_tids
[] = {
3416 IVBSAXXMLReader_tid
,
3419 static dispex_static_data_t saxreader_dispex
= {
3421 IVBSAXXMLReader_tid
,
3423 saxreader_iface_tids
3426 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3430 TRACE("(%p)\n", ppObj
);
3432 reader
= heap_alloc( sizeof (*reader
) );
3434 return E_OUTOFMEMORY
;
3436 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3437 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3439 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3440 reader
->isParsing
= FALSE
;
3441 reader
->xmldecl_version
= NULL
;
3442 reader
->pool
.pool
= NULL
;
3443 reader
->pool
.index
= 0;
3444 reader
->pool
.len
= 0;
3445 reader
->features
= Namespaces
| NamespacePrefixes
;
3446 reader
->version
= version
;
3448 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3450 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3451 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3452 reader
->sax
.startDocument
= libxmlStartDocument
;
3453 reader
->sax
.endDocument
= libxmlEndDocument
;
3454 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3455 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3456 reader
->sax
.characters
= libxmlCharacters
;
3457 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3458 reader
->sax
.comment
= libxmlComment
;
3459 reader
->sax
.error
= libxmlFatalError
;
3460 reader
->sax
.fatalError
= libxmlFatalError
;
3461 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3462 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3464 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3466 TRACE("returning iface %p\n", *ppObj
);
3473 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3475 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3476 "libxml2 support was not present at compile time.\n");