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 ISequentialStream
*stream
= NULL
;
2643 IXMLDOMDocument
*xmlDoc
;
2645 if (!V_UNKNOWN(&varInput
))
2646 return E_INVALIDARG
;
2648 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2649 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2653 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2654 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2655 SysStringByteLen(bstrData
), vbInterface
);
2656 IXMLDOMDocument_Release(xmlDoc
);
2657 SysFreeString(bstrData
);
2661 /* try base interface first */
2662 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2664 /* this should never happen if IStream is implemented properly, but just in case */
2665 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2669 hr
= internal_parseStream(This
, stream
, vbInterface
);
2670 ISequentialStream_Release(stream
);
2674 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2681 WARN("vt %d not implemented\n", V_VT(&varInput
));
2688 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2690 saxreader
*This
= obj
;
2692 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2695 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2697 saxreader
*This
= obj
;
2699 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2702 static HRESULT
internal_parseURL(
2711 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
2713 hr
= create_moniker_from_url(url
, &mon
);
2717 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, This
, &bsc
);
2718 else hr
= bind_url(mon
, internal_onDataAvailable
, This
, &bsc
);
2719 IMoniker_Release(mon
);
2724 return detach_bsc(bsc
);
2727 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2731 if (V_VT(v
) == VT_EMPTY
)
2732 return saxreader_put_handler(This
, type
, NULL
, vb
);
2736 case SAXDeclHandler
:
2737 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2739 case SAXLexicalHandler
:
2740 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2743 ERR("wrong handler type %d\n", type
);
2752 IUnknown
*handler
= NULL
;
2756 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2757 if (FAILED(hr
)) return hr
;
2760 saxreader_put_handler(This
, type
, handler
, vb
);
2761 if (handler
) IUnknown_Release(handler
);
2765 ERR("value type %d not supported\n", V_VT(v
));
2766 return E_INVALIDARG
;
2772 static HRESULT
internal_putProperty(
2780 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2782 if (This
->isParsing
) return E_FAIL
;
2784 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2785 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2786 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2788 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2789 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2791 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2793 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2794 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2798 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2800 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2801 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2805 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2807 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2810 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2813 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2816 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2819 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2822 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2825 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2828 return E_INVALIDARG
;
2831 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2833 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2835 if (!value
) return E_POINTER
;
2837 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2839 V_VT(value
) = VT_UNKNOWN
;
2840 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2844 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2846 V_VT(value
) = VT_UNKNOWN
;
2847 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2851 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2853 V_VT(value
) = VT_BSTR
;
2854 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2858 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2863 /*** IVBSAXXMLReader interface ***/
2864 /*** IUnknown methods ***/
2865 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2867 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2869 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2873 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2874 IsEqualGUID( riid
, &IID_IDispatch
) ||
2875 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2879 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2881 *ppvObject
= &This
->ISAXXMLReader_iface
;
2883 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2885 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2889 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2890 return E_NOINTERFACE
;
2893 IVBSAXXMLReader_AddRef( iface
);
2898 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2900 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2901 TRACE("%p\n", This
);
2902 return InterlockedIncrement( &This
->ref
);
2905 static ULONG WINAPI
saxxmlreader_Release(
2906 IVBSAXXMLReader
* iface
)
2908 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2911 TRACE("%p\n", This
);
2913 ref
= InterlockedDecrement( &This
->ref
);
2918 for (i
= 0; i
< SAXHandler_Last
; i
++)
2920 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2922 if (saxiface
->handler
)
2923 IUnknown_Release(saxiface
->handler
);
2925 if (saxiface
->vbhandler
)
2926 IUnknown_Release(saxiface
->vbhandler
);
2929 SysFreeString(This
->xmldecl_version
);
2930 free_bstr_pool(&This
->pool
);
2938 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2940 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2941 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2944 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2945 IVBSAXXMLReader
*iface
,
2946 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2948 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2949 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2950 iTInfo
, lcid
, ppTInfo
);
2953 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2954 IVBSAXXMLReader
*iface
,
2956 LPOLESTR
* rgszNames
,
2961 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2962 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
2963 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
2966 static HRESULT WINAPI
saxxmlreader_Invoke(
2967 IVBSAXXMLReader
*iface
,
2968 DISPID dispIdMember
,
2972 DISPPARAMS
* pDispParams
,
2973 VARIANT
* pVarResult
,
2974 EXCEPINFO
* pExcepInfo
,
2977 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2978 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
2979 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2982 /*** IVBSAXXMLReader methods ***/
2983 static HRESULT WINAPI
saxxmlreader_getFeature(
2984 IVBSAXXMLReader
* iface
,
2986 VARIANT_BOOL
*value
)
2988 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2989 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
2992 static HRESULT WINAPI
saxxmlreader_putFeature(
2993 IVBSAXXMLReader
* iface
,
2997 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2998 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3001 static HRESULT WINAPI
saxxmlreader_getProperty(
3002 IVBSAXXMLReader
* iface
,
3006 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3007 return internal_getProperty(This
, prop
, value
, TRUE
);
3010 static HRESULT WINAPI
saxxmlreader_putProperty(
3011 IVBSAXXMLReader
* iface
,
3015 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3016 return internal_putProperty(This
, pProp
, value
, TRUE
);
3019 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3020 IVBSAXXMLReader
* iface
,
3021 IVBSAXEntityResolver
**resolver
)
3023 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3024 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3027 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3028 IVBSAXXMLReader
* iface
,
3029 IVBSAXEntityResolver
*resolver
)
3031 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3032 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3035 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3036 IVBSAXXMLReader
* iface
,
3037 IVBSAXContentHandler
**handler
)
3039 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3040 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3043 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3044 IVBSAXXMLReader
* iface
,
3045 IVBSAXContentHandler
*handler
)
3047 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3048 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3051 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3052 IVBSAXXMLReader
* iface
,
3053 IVBSAXDTDHandler
**handler
)
3055 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3056 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3059 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3060 IVBSAXXMLReader
* iface
,
3061 IVBSAXDTDHandler
*handler
)
3063 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3064 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3067 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3068 IVBSAXXMLReader
* iface
,
3069 IVBSAXErrorHandler
**handler
)
3071 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3072 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3075 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3076 IVBSAXXMLReader
* iface
,
3077 IVBSAXErrorHandler
*handler
)
3079 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3080 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3083 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3084 IVBSAXXMLReader
* iface
,
3087 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3089 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3093 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3094 IVBSAXXMLReader
* iface
,
3097 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3098 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3101 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3102 IVBSAXXMLReader
* iface
,
3103 BSTR
*pSecureBaseUrl
)
3105 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3107 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3111 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3112 IVBSAXXMLReader
* iface
,
3115 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3116 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3119 static HRESULT WINAPI
saxxmlreader_parse(
3120 IVBSAXXMLReader
* iface
,
3123 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3124 return internal_parse(This
, varInput
, TRUE
);
3127 static HRESULT WINAPI
saxxmlreader_parseURL(
3128 IVBSAXXMLReader
* iface
,
3131 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3132 return internal_parseURL(This
, url
, TRUE
);
3135 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3137 saxxmlreader_QueryInterface
,
3138 saxxmlreader_AddRef
,
3139 saxxmlreader_Release
,
3140 saxxmlreader_GetTypeInfoCount
,
3141 saxxmlreader_GetTypeInfo
,
3142 saxxmlreader_GetIDsOfNames
,
3143 saxxmlreader_Invoke
,
3144 saxxmlreader_getFeature
,
3145 saxxmlreader_putFeature
,
3146 saxxmlreader_getProperty
,
3147 saxxmlreader_putProperty
,
3148 saxxmlreader_get_entityResolver
,
3149 saxxmlreader_put_entityResolver
,
3150 saxxmlreader_get_contentHandler
,
3151 saxxmlreader_put_contentHandler
,
3152 saxxmlreader_get_dtdHandler
,
3153 saxxmlreader_put_dtdHandler
,
3154 saxxmlreader_get_errorHandler
,
3155 saxxmlreader_put_errorHandler
,
3156 saxxmlreader_get_baseURL
,
3157 saxxmlreader_put_baseURL
,
3158 saxxmlreader_get_secureBaseURL
,
3159 saxxmlreader_put_secureBaseURL
,
3161 saxxmlreader_parseURL
3164 /*** ISAXXMLReader interface ***/
3165 /*** IUnknown methods ***/
3166 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3168 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3169 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3172 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3174 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3175 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3178 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3180 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3181 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3184 /*** ISAXXMLReader methods ***/
3185 static HRESULT WINAPI
isaxxmlreader_getFeature(
3186 ISAXXMLReader
* iface
,
3187 const WCHAR
*feature_name
,
3188 VARIANT_BOOL
*value
)
3190 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3191 saxreader_feature feature
;
3193 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3195 feature
= get_saxreader_feature(feature_name
);
3196 if (feature
== Namespaces
|| feature
== NamespacePrefixes
)
3197 return get_feature_value(This
, feature
, value
);
3199 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3203 static HRESULT WINAPI
isaxxmlreader_putFeature(
3204 ISAXXMLReader
* iface
,
3205 const WCHAR
*feature_name
,
3208 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3209 saxreader_feature feature
;
3211 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3213 feature
= get_saxreader_feature(feature_name
);
3215 /* accepted cases */
3216 if ((feature
== ExternalGeneralEntities
&& value
== VARIANT_FALSE
) ||
3217 (feature
== ExternalParameterEntities
&& value
== VARIANT_FALSE
) ||
3218 feature
== Namespaces
||
3219 feature
== NamespacePrefixes
)
3221 return set_feature_value(This
, feature
, value
);
3224 if (feature
== LexicalHandlerParEntities
|| feature
== ProhibitDTD
)
3226 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3227 return set_feature_value(This
, feature
, value
);
3230 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3234 static HRESULT WINAPI
isaxxmlreader_getProperty(
3235 ISAXXMLReader
* iface
,
3239 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3240 return internal_getProperty(This
, prop
, value
, FALSE
);
3243 static HRESULT WINAPI
isaxxmlreader_putProperty(
3244 ISAXXMLReader
* iface
,
3248 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3249 return internal_putProperty(This
, pProp
, value
, FALSE
);
3252 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3253 ISAXXMLReader
* iface
,
3254 ISAXEntityResolver
**resolver
)
3256 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3257 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3260 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3261 ISAXXMLReader
* iface
,
3262 ISAXEntityResolver
*resolver
)
3264 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3265 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3268 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3269 ISAXXMLReader
* iface
,
3270 ISAXContentHandler
**handler
)
3272 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3273 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3276 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3277 ISAXXMLReader
* iface
,
3278 ISAXContentHandler
*handler
)
3280 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3281 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3284 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3285 ISAXXMLReader
* iface
,
3286 ISAXDTDHandler
**handler
)
3288 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3289 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3292 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3293 ISAXXMLReader
* iface
,
3294 ISAXDTDHandler
*handler
)
3296 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3297 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3300 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3301 ISAXXMLReader
* iface
,
3302 ISAXErrorHandler
**handler
)
3304 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3305 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3308 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3310 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3311 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3314 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3315 ISAXXMLReader
* iface
,
3316 const WCHAR
**base_url
)
3318 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3320 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3324 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3325 ISAXXMLReader
* iface
,
3326 const WCHAR
*pBaseUrl
)
3328 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3330 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3334 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3335 ISAXXMLReader
* iface
,
3336 const WCHAR
**pSecureBaseUrl
)
3338 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3339 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3343 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3344 ISAXXMLReader
* iface
,
3345 const WCHAR
*secureBaseUrl
)
3347 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3349 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3353 static HRESULT WINAPI
isaxxmlreader_parse(
3354 ISAXXMLReader
* iface
,
3357 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3358 return internal_parse(This
, varInput
, FALSE
);
3361 static HRESULT WINAPI
isaxxmlreader_parseURL(
3362 ISAXXMLReader
* iface
,
3365 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3366 return internal_parseURL(This
, url
, FALSE
);
3369 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3371 isaxxmlreader_QueryInterface
,
3372 isaxxmlreader_AddRef
,
3373 isaxxmlreader_Release
,
3374 isaxxmlreader_getFeature
,
3375 isaxxmlreader_putFeature
,
3376 isaxxmlreader_getProperty
,
3377 isaxxmlreader_putProperty
,
3378 isaxxmlreader_getEntityResolver
,
3379 isaxxmlreader_putEntityResolver
,
3380 isaxxmlreader_getContentHandler
,
3381 isaxxmlreader_putContentHandler
,
3382 isaxxmlreader_getDTDHandler
,
3383 isaxxmlreader_putDTDHandler
,
3384 isaxxmlreader_getErrorHandler
,
3385 isaxxmlreader_putErrorHandler
,
3386 isaxxmlreader_getBaseURL
,
3387 isaxxmlreader_putBaseURL
,
3388 isaxxmlreader_getSecureBaseURL
,
3389 isaxxmlreader_putSecureBaseURL
,
3390 isaxxmlreader_parse
,
3391 isaxxmlreader_parseURL
3394 static const tid_t saxreader_iface_tids
[] = {
3395 IVBSAXXMLReader_tid
,
3398 static dispex_static_data_t saxreader_dispex
= {
3400 IVBSAXXMLReader_tid
,
3402 saxreader_iface_tids
3405 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3409 TRACE("(%p)\n", ppObj
);
3411 reader
= heap_alloc( sizeof (*reader
) );
3413 return E_OUTOFMEMORY
;
3415 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3416 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3418 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3419 reader
->isParsing
= FALSE
;
3420 reader
->xmldecl_version
= NULL
;
3421 reader
->pool
.pool
= NULL
;
3422 reader
->pool
.index
= 0;
3423 reader
->pool
.len
= 0;
3424 reader
->features
= Namespaces
| NamespacePrefixes
;
3425 reader
->version
= version
;
3427 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3429 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3430 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3431 reader
->sax
.startDocument
= libxmlStartDocument
;
3432 reader
->sax
.endDocument
= libxmlEndDocument
;
3433 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3434 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3435 reader
->sax
.characters
= libxmlCharacters
;
3436 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3437 reader
->sax
.comment
= libxmlComment
;
3438 reader
->sax
.error
= libxmlFatalError
;
3439 reader
->sax
.fatalError
= libxmlFatalError
;
3440 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3441 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3443 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3445 TRACE("returning iface %p\n", *ppObj
);
3452 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3454 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3455 "libxml2 support was not present at compile time.\n");