2 * SAX Reader implementation
4 * Copyright 2008 Alistair Leslie-Hughes
5 * Copyright 2008 Piotr Caban
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
29 # include <libxml/SAX2.h>
30 # include <libxml/parserInternals.h>
44 #include "wine/debug.h"
46 #include "msxml_private.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
55 ExhaustiveErrors
= 1 << 1,
56 ExternalGeneralEntities
= 1 << 2,
57 ExternalParameterEntities
= 1 << 3,
58 ForcedResync
= 1 << 4,
59 NamespacePrefixes
= 1 << 5,
61 ParameterEntities
= 1 << 7,
62 PreserveSystemIndentifiers
= 1 << 8,
64 SchemaValidation
= 1 << 10,
65 ServerHttpRequest
= 1 << 11,
66 SuppressValidationfatalError
= 1 << 12,
67 UseInlineSchema
= 1 << 13,
68 UseSchemaLocation
= 1 << 14,
69 LexicalHandlerParEntities
= 1 << 15
73 static const WCHAR FeatureExternalGeneralEntitiesW
[] = {
74 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/',
75 'f','e','a','t','u','r','e','s','/','e','x','t','e','r','n','a','l','-','g','e','n','e','r','a','l',
76 '-','e','n','t','i','t','i','e','s',0
79 static const WCHAR FeatureExternalParameterEntitiesW
[] = {
80 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
81 '/','e','x','t','e','r','n','a','l','-','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0
84 static const WCHAR FeatureLexicalHandlerParEntitiesW
[] = {
85 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
86 '/','l','e','x','i','c','a','l','-','h','a','n','d','l','e','r','/','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0
89 static const WCHAR FeatureProhibitDTDW
[] = {
90 'p','r','o','h','i','b','i','t','-','d','t','d',0
93 static const WCHAR FeatureNamespacesW
[] = {
94 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
95 '/','n','a','m','e','s','p','a','c','e','s',0
98 static const WCHAR FeatureNamespacePrefixesW
[] = {
99 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
100 '/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0
103 struct saxreader_feature_pair
105 saxreader_feature feature
;
109 static const struct saxreader_feature_pair saxreader_feature_map
[] = {
110 { ExternalGeneralEntities
, FeatureExternalGeneralEntitiesW
},
111 { ExternalParameterEntities
, FeatureExternalParameterEntitiesW
},
112 { LexicalHandlerParEntities
, FeatureLexicalHandlerParEntitiesW
},
113 { NamespacePrefixes
, FeatureNamespacePrefixesW
},
114 { Namespaces
, FeatureNamespacesW
},
115 { ProhibitDTD
, FeatureProhibitDTDW
}
118 static saxreader_feature
get_saxreader_feature(const WCHAR
*name
)
123 max
= sizeof(saxreader_feature_map
)/sizeof(struct saxreader_feature_pair
) - 1;
129 c
= strcmpW(saxreader_feature_map
[n
].name
, name
);
131 return saxreader_feature_map
[n
].feature
;
139 return FeatureUnknown
;
161 ns
*ns
; /* namespaces defined in this particular element */
167 SAXContentHandler
= 0,
176 struct saxanyhandler_iface
182 struct saxcontenthandler_iface
184 ISAXContentHandler
*handler
;
185 IVBSAXContentHandler
*vbhandler
;
188 struct saxerrorhandler_iface
190 ISAXErrorHandler
*handler
;
191 IVBSAXErrorHandler
*vbhandler
;
194 struct saxlexicalhandler_iface
196 ISAXLexicalHandler
*handler
;
197 IVBSAXLexicalHandler
*vbhandler
;
200 struct saxentityresolver_iface
202 ISAXEntityResolver
*handler
;
203 IVBSAXEntityResolver
*vbhandler
;
206 struct saxhandler_iface
209 struct saxcontenthandler_iface content
;
210 struct saxentityresolver_iface entityresolver
;
211 struct saxerrorhandler_iface error
;
212 struct saxlexicalhandler_iface lexical
;
213 struct saxanyhandler_iface anyhandler
;
220 IVBSAXXMLReader IVBSAXXMLReader_iface
;
221 ISAXXMLReader ISAXXMLReader_iface
;
224 struct saxhandler_iface saxhandlers
[SAXHandler_Last
];
227 struct bstrpool pool
;
228 saxreader_feature features
;
229 BSTR xmldecl_version
;
230 MSXML_VERSION version
;
233 static HRESULT
saxreader_put_handler(saxreader
*reader
, enum saxhandler_type type
, void *ptr
, BOOL vb
)
235 struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
236 IUnknown
*unk
= (IUnknown
*)ptr
;
239 IUnknown_AddRef(unk
);
241 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
242 IUnknown_Release(vb
? iface
->vbhandler
: iface
->handler
);
245 iface
->vbhandler
= unk
;
247 iface
->handler
= unk
;
252 static HRESULT
saxreader_get_handler(const saxreader
*reader
, enum saxhandler_type type
, BOOL vb
, void **ret
)
254 const struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
256 if (!ret
) return E_POINTER
;
258 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
261 IUnknown_AddRef(iface
->vbhandler
);
263 IUnknown_AddRef(iface
->handler
);
266 *ret
= vb
? iface
->vbhandler
: iface
->handler
;
271 static struct saxcontenthandler_iface
*saxreader_get_contenthandler(saxreader
*reader
)
273 return &reader
->saxhandlers
[SAXContentHandler
].u
.content
;
276 static struct saxerrorhandler_iface
*saxreader_get_errorhandler(saxreader
*reader
)
278 return &reader
->saxhandlers
[SAXErrorHandler
].u
.error
;
281 static struct saxlexicalhandler_iface
*saxreader_get_lexicalhandler(saxreader
*reader
)
283 return &reader
->saxhandlers
[SAXLexicalHandler
].u
.lexical
;
288 IVBSAXLocator IVBSAXLocator_iface
;
289 ISAXLocator ISAXLocator_iface
;
290 IVBSAXAttributes IVBSAXAttributes_iface
;
291 ISAXAttributes ISAXAttributes_iface
;
293 saxreader
*saxreader
;
295 xmlParserCtxtPtr pParserCtxt
;
301 struct list elements
;
304 int attr_alloc_count
;
315 static inline saxreader
*impl_from_IVBSAXXMLReader( IVBSAXXMLReader
*iface
)
317 return CONTAINING_RECORD(iface
, saxreader
, IVBSAXXMLReader_iface
);
320 static inline saxreader
*impl_from_ISAXXMLReader( ISAXXMLReader
*iface
)
322 return CONTAINING_RECORD(iface
, saxreader
, ISAXXMLReader_iface
);
325 static inline saxlocator
*impl_from_IVBSAXLocator( IVBSAXLocator
*iface
)
327 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXLocator_iface
);
330 static inline saxlocator
*impl_from_ISAXLocator( ISAXLocator
*iface
)
332 return CONTAINING_RECORD(iface
, saxlocator
, ISAXLocator_iface
);
335 static inline saxlocator
*impl_from_IVBSAXAttributes( IVBSAXAttributes
*iface
)
337 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXAttributes_iface
);
340 static inline saxlocator
*impl_from_ISAXAttributes( ISAXAttributes
*iface
)
342 return CONTAINING_RECORD(iface
, saxlocator
, ISAXAttributes_iface
);
345 static inline BOOL
saxreader_has_handler(const saxlocator
*locator
, enum saxhandler_type type
)
347 struct saxanyhandler_iface
*iface
= &locator
->saxreader
->saxhandlers
[type
].u
.anyhandler
;
348 return (locator
->vbInterface
&& iface
->vbhandler
) || (!locator
->vbInterface
&& iface
->handler
);
351 static HRESULT
saxreader_saxcharacters(saxlocator
*locator
, BSTR chars
)
353 struct saxcontenthandler_iface
*content
= saxreader_get_contenthandler(locator
->saxreader
);
356 if (!saxreader_has_handler(locator
, SAXContentHandler
)) return S_OK
;
358 if (locator
->vbInterface
)
359 hr
= IVBSAXContentHandler_characters(content
->vbhandler
, &chars
);
361 hr
= ISAXContentHandler_characters(content
->handler
, chars
, SysStringLen(chars
));
367 static const WCHAR PropertyCharsetW
[] = {
368 'c','h','a','r','s','e','t',0
370 static const WCHAR PropertyXmlDeclVersionW
[] = {
371 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
373 static const WCHAR PropertyDeclHandlerW
[] = {
374 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
375 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
376 'd','e','c','l','a','r','a','t','i','o','n',
377 '-','h','a','n','d','l','e','r',0
379 static const WCHAR PropertyDomNodeW
[] = {
380 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
381 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
382 'd','o','m','-','n','o','d','e',0
384 static const WCHAR PropertyInputSourceW
[] = {
385 'i','n','p','u','t','-','s','o','u','r','c','e',0
387 static const WCHAR PropertyLexicalHandlerW
[] = {
388 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
389 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
390 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
392 static const WCHAR PropertyMaxElementDepthW
[] = {
393 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
395 static const WCHAR PropertyMaxXMLSizeW
[] = {
396 'm','a','x','-','x','m','l','-','s','i','z','e',0
398 static const WCHAR PropertySchemaDeclHandlerW
[] = {
399 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
400 'h','a','n','d','l','e','r',0
402 static const WCHAR PropertyXMLDeclEncodingW
[] = {
403 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
405 static const WCHAR PropertyXMLDeclStandaloneW
[] = {
406 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
408 static const WCHAR PropertyXMLDeclVersionW
[] = {
409 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
412 static inline HRESULT
set_feature_value(saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL value
)
414 /* handling of non-VARIANT_* values is version dependent */
415 if ((reader
->version
< MSXML4
) && (value
!= VARIANT_TRUE
))
416 value
= VARIANT_FALSE
;
417 if ((reader
->version
>= MSXML4
) && (value
!= VARIANT_FALSE
))
418 value
= VARIANT_TRUE
;
420 if (value
== VARIANT_TRUE
)
421 reader
->features
|= feature
;
423 reader
->features
&= ~feature
;
428 static inline HRESULT
get_feature_value(const saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL
*value
)
430 *value
= reader
->features
& feature
? VARIANT_TRUE
: VARIANT_FALSE
;
434 static BOOL
is_namespaces_enabled(const saxreader
*reader
)
436 return (reader
->version
< MSXML4
) || (reader
->features
& Namespaces
);
439 static BSTR
build_qname(BSTR prefix
, BSTR local
)
441 if (prefix
&& *prefix
)
443 BSTR qname
= SysAllocStringLen(NULL
, SysStringLen(prefix
) + SysStringLen(local
) + 1);
447 strcpyW(ptr
, prefix
);
448 ptr
+= SysStringLen(prefix
);
454 return SysAllocString(local
);
457 static element_entry
* alloc_element_entry(const xmlChar
*local
, const xmlChar
*prefix
, int nb_ns
,
458 const xmlChar
**namespaces
)
463 ret
= heap_alloc(sizeof(*ret
));
464 if (!ret
) return ret
;
466 ret
->local
= bstr_from_xmlChar(local
);
467 ret
->prefix
= bstr_from_xmlChar(prefix
);
468 ret
->qname
= build_qname(ret
->prefix
, ret
->local
);
469 ret
->ns
= nb_ns
? heap_alloc(nb_ns
*sizeof(ns
)) : NULL
;
470 ret
->ns_count
= nb_ns
;
472 for (i
=0; i
< nb_ns
; i
++)
474 ret
->ns
[i
].prefix
= bstr_from_xmlChar(namespaces
[2*i
]);
475 ret
->ns
[i
].uri
= bstr_from_xmlChar(namespaces
[2*i
+1]);
481 static void free_element_entry(element_entry
*element
)
485 for (i
=0; i
<element
->ns_count
;i
++)
487 SysFreeString(element
->ns
[i
].prefix
);
488 SysFreeString(element
->ns
[i
].uri
);
491 SysFreeString(element
->prefix
);
492 SysFreeString(element
->local
);
493 SysFreeString(element
->qname
);
495 heap_free(element
->ns
);
499 static void push_element_ns(saxlocator
*locator
, element_entry
*element
)
501 list_add_head(&locator
->elements
, &element
->entry
);
504 static element_entry
* pop_element_ns(saxlocator
*locator
)
506 element_entry
*element
= LIST_ENTRY(list_head(&locator
->elements
), element_entry
, entry
);
509 list_remove(&element
->entry
);
514 static BSTR
find_element_uri(saxlocator
*locator
, const xmlChar
*uri
)
516 element_entry
*element
;
520 if (!uri
) return NULL
;
522 uriW
= bstr_from_xmlChar(uri
);
524 LIST_FOR_EACH_ENTRY(element
, &locator
->elements
, element_entry
, entry
)
526 for (i
=0; i
< element
->ns_count
; i
++)
527 if (!strcmpW(uriW
, element
->ns
[i
].uri
))
530 return element
->ns
[i
].uri
;
535 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri
));
539 /* used to localize version dependent error check behaviour */
540 static inline BOOL
sax_callback_failed(saxlocator
*This
, HRESULT hr
)
542 return This
->saxreader
->version
>= MSXML4
? FAILED(hr
) : hr
!= S_OK
;
545 /* index value -1 means it tries to loop for a first time */
546 static inline BOOL
iterate_endprefix_index(saxlocator
*This
, const element_entry
*element
, int *i
)
548 if (This
->saxreader
->version
>= MSXML4
)
550 if (*i
== -1) *i
= 0; else ++*i
;
551 return *i
< element
->ns_count
;
555 if (*i
== -1) *i
= element
->ns_count
-1; else --*i
;
560 static BOOL
bstr_pool_insert(struct bstrpool
*pool
, BSTR pool_entry
)
564 pool
->pool
= HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(*pool
->pool
));
571 else if (pool
->index
== pool
->len
)
573 BSTR
*realloc
= HeapReAlloc(GetProcessHeap(), 0, pool
->pool
, pool
->len
* 2 * sizeof(*realloc
));
578 pool
->pool
= realloc
;
582 pool
->pool
[pool
->index
++] = pool_entry
;
586 static void free_bstr_pool(struct bstrpool
*pool
)
590 for (i
= 0; i
< pool
->index
; i
++)
591 SysFreeString(pool
->pool
[i
]);
593 HeapFree(GetProcessHeap(), 0, pool
->pool
);
596 pool
->index
= pool
->len
= 0;
599 static BSTR
bstr_from_xmlCharN(const xmlChar
*buf
, int len
)
607 dLen
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
608 if(len
!= -1) dLen
++;
609 bstr
= SysAllocStringLen(NULL
, dLen
-1);
612 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, bstr
, dLen
);
613 if(len
!= -1) bstr
[dLen
-1] = '\0';
618 static BSTR
QName_from_xmlChar(const xmlChar
*prefix
, const xmlChar
*name
)
623 if(!name
) return NULL
;
625 if(!prefix
|| !*prefix
)
626 return bstr_from_xmlChar(name
);
628 qname
= xmlBuildQName(name
, prefix
, NULL
, 0);
629 bstr
= bstr_from_xmlChar(qname
);
635 static BSTR
pooled_bstr_from_xmlChar(struct bstrpool
*pool
, const xmlChar
*buf
)
637 BSTR pool_entry
= bstr_from_xmlChar(buf
);
639 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
641 SysFreeString(pool_entry
);
648 static BSTR
pooled_bstr_from_xmlCharN(struct bstrpool
*pool
, const xmlChar
*buf
, int len
)
650 BSTR pool_entry
= bstr_from_xmlCharN(buf
, len
);
652 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
654 SysFreeString(pool_entry
);
661 static void format_error_message_from_id(saxlocator
*This
, HRESULT hr
)
663 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
664 xmlStopParser(This
->pParserCtxt
);
667 if (saxreader_has_handler(This
, SAXErrorHandler
))
670 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
,
671 NULL
, hr
, 0, msg
, sizeof(msg
)/sizeof(msg
[0]), NULL
))
673 FIXME("MSXML errors not yet supported.\n");
677 if(This
->vbInterface
)
679 BSTR bstrMsg
= SysAllocString(msg
);
680 IVBSAXErrorHandler_fatalError(handler
->vbhandler
,
681 &This
->IVBSAXLocator_iface
, &bstrMsg
, hr
);
682 SysFreeString(bstrMsg
);
685 ISAXErrorHandler_fatalError(handler
->handler
,
686 &This
->ISAXLocator_iface
, msg
, hr
);
690 static void update_position(saxlocator
*This
, BOOL fix_column
)
692 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
693 const xmlChar
*baseP
= This
->pParserCtxt
->input
->base
;
695 This
->line
= xmlSAX2GetLineNumber(This
->pParserCtxt
);
699 for(;p
>=baseP
&& *p
!='\n' && *p
!='\r'; p
--)
704 This
->column
= xmlSAX2GetColumnNumber(This
->pParserCtxt
);
708 /*** IVBSAXAttributes interface ***/
709 static HRESULT WINAPI
ivbsaxattributes_QueryInterface(
710 IVBSAXAttributes
* iface
,
714 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
715 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
716 return IVBSAXLocator_QueryInterface(&This
->IVBSAXLocator_iface
, riid
, ppvObject
);
719 static ULONG WINAPI
ivbsaxattributes_AddRef(IVBSAXAttributes
* iface
)
721 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
722 return IVBSAXLocator_AddRef(&This
->IVBSAXLocator_iface
);
725 static ULONG WINAPI
ivbsaxattributes_Release(IVBSAXAttributes
* iface
)
727 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
728 return IVBSAXLocator_Release(&This
->IVBSAXLocator_iface
);
731 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes
*iface
, UINT
* pctinfo
)
733 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
735 TRACE("(%p)->(%p)\n", This
, pctinfo
);
742 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfo(
743 IVBSAXAttributes
*iface
,
744 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
746 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
748 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
750 return get_typeinfo(IVBSAXAttributes_tid
, ppTInfo
);
753 static HRESULT WINAPI
ivbsaxattributes_GetIDsOfNames(
754 IVBSAXAttributes
*iface
,
761 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
765 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
768 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
771 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
774 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
775 ITypeInfo_Release(typeinfo
);
781 static HRESULT WINAPI
ivbsaxattributes_Invoke(
782 IVBSAXAttributes
*iface
,
787 DISPPARAMS
* pDispParams
,
789 EXCEPINFO
* pExcepInfo
,
792 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
796 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
797 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
799 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
802 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXAttributes_iface
, dispIdMember
, wFlags
,
803 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
804 ITypeInfo_Release(typeinfo
);
810 /*** IVBSAXAttributes methods ***/
811 static HRESULT WINAPI
ivbsaxattributes_get_length(
812 IVBSAXAttributes
* iface
,
815 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
816 return ISAXAttributes_getLength(&This
->ISAXAttributes_iface
, nLength
);
819 static HRESULT WINAPI
ivbsaxattributes_getURI(
820 IVBSAXAttributes
* iface
,
824 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
829 TRACE("(%p)->(%d %p)\n", This
, nIndex
, uri
);
835 hr
= ISAXAttributes_getURI(&This
->ISAXAttributes_iface
, nIndex
, &uriW
, &len
);
839 return return_bstrn(uriW
, len
, uri
);
842 static HRESULT WINAPI
ivbsaxattributes_getLocalName(
843 IVBSAXAttributes
* iface
,
847 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
852 TRACE("(%p)->(%d %p)\n", This
, nIndex
, name
);
858 hr
= ISAXAttributes_getLocalName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
862 return return_bstrn(nameW
, len
, name
);
865 static HRESULT WINAPI
ivbsaxattributes_getQName(
866 IVBSAXAttributes
* iface
,
870 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
875 TRACE("(%p)->(%d %p)\n", This
, nIndex
, QName
);
881 hr
= ISAXAttributes_getQName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
885 return return_bstrn(nameW
, len
, QName
);
888 static HRESULT WINAPI
ivbsaxattributes_getIndexFromName(
889 IVBSAXAttributes
* iface
,
894 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
895 return ISAXAttributes_getIndexFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
896 localName
, SysStringLen(localName
), index
);
899 static HRESULT WINAPI
ivbsaxattributes_getIndexFromQName(
900 IVBSAXAttributes
* iface
,
904 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
905 return ISAXAttributes_getIndexFromQName(&This
->ISAXAttributes_iface
, QName
,
906 SysStringLen(QName
), index
);
909 static HRESULT WINAPI
ivbsaxattributes_getType(
910 IVBSAXAttributes
* iface
,
914 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
919 TRACE("(%p)->(%d %p)\n", This
, nIndex
, type
);
925 hr
= ISAXAttributes_getType(&This
->ISAXAttributes_iface
, nIndex
, &typeW
, &len
);
929 return return_bstrn(typeW
, len
, type
);
932 static HRESULT WINAPI
ivbsaxattributes_getTypeFromName(
933 IVBSAXAttributes
* iface
,
938 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
943 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), type
);
949 hr
= ISAXAttributes_getTypeFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
950 localName
, SysStringLen(localName
), &typeW
, &len
);
954 return return_bstrn(typeW
, len
, type
);
957 static HRESULT WINAPI
ivbsaxattributes_getTypeFromQName(
958 IVBSAXAttributes
* iface
,
962 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
967 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), type
);
973 hr
= ISAXAttributes_getTypeFromQName(&This
->ISAXAttributes_iface
, QName
, SysStringLen(QName
),
978 return return_bstrn(typeW
, len
, type
);
981 static HRESULT WINAPI
ivbsaxattributes_getValue(
982 IVBSAXAttributes
* iface
,
986 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
991 TRACE("(%p)->(%d %p)\n", This
, nIndex
, value
);
997 hr
= ISAXAttributes_getValue(&This
->ISAXAttributes_iface
, nIndex
, &valueW
, &len
);
1001 return return_bstrn(valueW
, len
, value
);
1004 static HRESULT WINAPI
ivbsaxattributes_getValueFromName(
1005 IVBSAXAttributes
* iface
,
1010 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1011 const WCHAR
*valueW
;
1015 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), value
);
1021 hr
= ISAXAttributes_getValueFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
1022 localName
, SysStringLen(localName
), &valueW
, &len
);
1026 return return_bstrn(valueW
, len
, value
);
1029 static HRESULT WINAPI
ivbsaxattributes_getValueFromQName(
1030 IVBSAXAttributes
* iface
,
1034 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1035 const WCHAR
*valueW
;
1039 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), value
);
1045 hr
= ISAXAttributes_getValueFromQName(&This
->ISAXAttributes_iface
, QName
,
1046 SysStringLen(QName
), &valueW
, &len
);
1050 return return_bstrn(valueW
, len
, value
);
1053 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl
=
1055 ivbsaxattributes_QueryInterface
,
1056 ivbsaxattributes_AddRef
,
1057 ivbsaxattributes_Release
,
1058 ivbsaxattributes_GetTypeInfoCount
,
1059 ivbsaxattributes_GetTypeInfo
,
1060 ivbsaxattributes_GetIDsOfNames
,
1061 ivbsaxattributes_Invoke
,
1062 ivbsaxattributes_get_length
,
1063 ivbsaxattributes_getURI
,
1064 ivbsaxattributes_getLocalName
,
1065 ivbsaxattributes_getQName
,
1066 ivbsaxattributes_getIndexFromName
,
1067 ivbsaxattributes_getIndexFromQName
,
1068 ivbsaxattributes_getType
,
1069 ivbsaxattributes_getTypeFromName
,
1070 ivbsaxattributes_getTypeFromQName
,
1071 ivbsaxattributes_getValue
,
1072 ivbsaxattributes_getValueFromName
,
1073 ivbsaxattributes_getValueFromQName
1076 /*** ISAXAttributes interface ***/
1077 /*** IUnknown methods ***/
1078 static HRESULT WINAPI
isaxattributes_QueryInterface(
1079 ISAXAttributes
* iface
,
1083 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1084 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
1085 return ISAXLocator_QueryInterface(&This
->ISAXLocator_iface
, riid
, ppvObject
);
1088 static ULONG WINAPI
isaxattributes_AddRef(ISAXAttributes
* iface
)
1090 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1091 TRACE("%p\n", This
);
1092 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
1095 static ULONG WINAPI
isaxattributes_Release(ISAXAttributes
* iface
)
1097 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1099 TRACE("%p\n", This
);
1100 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
1103 /*** ISAXAttributes methods ***/
1104 static HRESULT WINAPI
isaxattributes_getLength(
1105 ISAXAttributes
* iface
,
1108 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1110 *length
= This
->attr_count
;
1111 TRACE("Length set to %d\n", *length
);
1115 static inline BOOL
is_valid_attr_index(const saxlocator
*locator
, int index
)
1117 return index
< locator
->attr_count
&& index
>= 0;
1120 static HRESULT WINAPI
isaxattributes_getURI(
1121 ISAXAttributes
* iface
,
1126 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1127 TRACE("(%p)->(%d)\n", This
, index
);
1129 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1130 if(!url
|| !size
) return E_POINTER
;
1132 *size
= SysStringLen(This
->attributes
[index
].szURI
);
1133 *url
= This
->attributes
[index
].szURI
;
1135 TRACE("(%s:%d)\n", debugstr_w(This
->attributes
[index
].szURI
), *size
);
1140 static HRESULT WINAPI
isaxattributes_getLocalName(
1141 ISAXAttributes
* iface
,
1143 const WCHAR
**pLocalName
,
1144 int *pLocalNameLength
)
1146 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1147 TRACE("(%p)->(%d)\n", This
, index
);
1149 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1150 if(!pLocalName
|| !pLocalNameLength
) return E_POINTER
;
1152 *pLocalNameLength
= SysStringLen(This
->attributes
[index
].szLocalname
);
1153 *pLocalName
= This
->attributes
[index
].szLocalname
;
1158 static HRESULT WINAPI
isaxattributes_getQName(
1159 ISAXAttributes
* iface
,
1161 const WCHAR
**pQName
,
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(!pQName
|| !pQNameLength
) return E_POINTER
;
1170 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1171 *pQName
= This
->attributes
[index
].szQName
;
1176 static HRESULT WINAPI
isaxattributes_getName(
1177 ISAXAttributes
* iface
,
1181 const WCHAR
**localName
,
1182 int *pLocalNameSize
,
1183 const WCHAR
**QName
,
1186 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1187 TRACE("(%p)->(%d)\n", This
, index
);
1189 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1190 if(!uri
|| !pUriLength
|| !localName
|| !pLocalNameSize
1191 || !QName
|| !pQNameLength
) return E_POINTER
;
1193 *pUriLength
= SysStringLen(This
->attributes
[index
].szURI
);
1194 *uri
= This
->attributes
[index
].szURI
;
1195 *pLocalNameSize
= SysStringLen(This
->attributes
[index
].szLocalname
);
1196 *localName
= This
->attributes
[index
].szLocalname
;
1197 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1198 *QName
= This
->attributes
[index
].szQName
;
1200 TRACE("(%s, %s, %s)\n", debugstr_w(*uri
), debugstr_w(*localName
), debugstr_w(*QName
));
1205 static HRESULT WINAPI
isaxattributes_getIndexFromName(
1206 ISAXAttributes
* iface
,
1209 const WCHAR
*pLocalName
,
1210 int cocalNameLength
,
1213 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1215 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), cUriLength
,
1216 debugstr_w(pLocalName
), cocalNameLength
);
1218 if(!pUri
|| !pLocalName
|| !index
) return E_POINTER
;
1220 for(i
=0; i
<This
->attr_count
; i
++)
1222 if(cUriLength
!=SysStringLen(This
->attributes
[i
].szURI
)
1223 || cocalNameLength
!=SysStringLen(This
->attributes
[i
].szLocalname
))
1225 if(cUriLength
&& memcmp(pUri
, This
->attributes
[i
].szURI
,
1226 sizeof(WCHAR
)*cUriLength
))
1228 if(cocalNameLength
&& memcmp(pLocalName
, This
->attributes
[i
].szLocalname
,
1229 sizeof(WCHAR
)*cocalNameLength
))
1236 return E_INVALIDARG
;
1239 static HRESULT WINAPI
isaxattributes_getIndexFromQName(
1240 ISAXAttributes
* iface
,
1241 const WCHAR
*pQName
,
1245 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1247 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQNameLength
);
1249 if(!pQName
|| !index
) return E_POINTER
;
1250 if(!nQNameLength
) return E_INVALIDARG
;
1252 for(i
=0; i
<This
->attr_count
; i
++)
1254 if(nQNameLength
!=SysStringLen(This
->attributes
[i
].szQName
)) continue;
1255 if(memcmp(pQName
, This
->attributes
[i
].szQName
, sizeof(WCHAR
)*nQNameLength
)) continue;
1261 return E_INVALIDARG
;
1264 static HRESULT WINAPI
isaxattributes_getType(
1265 ISAXAttributes
* iface
,
1267 const WCHAR
**pType
,
1270 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1272 FIXME("(%p)->(%d) stub\n", This
, nIndex
);
1276 static HRESULT WINAPI
isaxattributes_getTypeFromName(
1277 ISAXAttributes
* iface
,
1280 const WCHAR
*pLocalName
,
1282 const WCHAR
**pType
,
1285 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1287 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This
, debugstr_w(pUri
), nUri
,
1288 debugstr_w(pLocalName
), nLocalName
);
1292 static HRESULT WINAPI
isaxattributes_getTypeFromQName(
1293 ISAXAttributes
* iface
,
1294 const WCHAR
*pQName
,
1296 const WCHAR
**pType
,
1299 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1301 FIXME("(%p)->(%s, %d) stub\n", This
, debugstr_w(pQName
), nQName
);
1305 static HRESULT WINAPI
isaxattributes_getValue(
1306 ISAXAttributes
* iface
,
1308 const WCHAR
**value
,
1311 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1312 TRACE("(%p)->(%d)\n", This
, index
);
1314 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1315 if(!value
|| !nValue
) return E_POINTER
;
1317 *nValue
= SysStringLen(This
->attributes
[index
].szValue
);
1318 *value
= This
->attributes
[index
].szValue
;
1320 TRACE("(%s:%d)\n", debugstr_w(*value
), *nValue
);
1325 static HRESULT WINAPI
isaxattributes_getValueFromName(
1326 ISAXAttributes
* iface
,
1329 const WCHAR
*pLocalName
,
1331 const WCHAR
**pValue
,
1336 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1337 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), nUri
,
1338 debugstr_w(pLocalName
), nLocalName
);
1340 hr
= ISAXAttributes_getIndexFromName(iface
,
1341 pUri
, nUri
, pLocalName
, nLocalName
, &index
);
1342 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1347 static HRESULT WINAPI
isaxattributes_getValueFromQName(
1348 ISAXAttributes
* iface
,
1349 const WCHAR
*pQName
,
1351 const WCHAR
**pValue
,
1356 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1357 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQName
);
1359 hr
= ISAXAttributes_getIndexFromQName(iface
, pQName
, nQName
, &index
);
1360 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1365 static const struct ISAXAttributesVtbl isaxattributes_vtbl
=
1367 isaxattributes_QueryInterface
,
1368 isaxattributes_AddRef
,
1369 isaxattributes_Release
,
1370 isaxattributes_getLength
,
1371 isaxattributes_getURI
,
1372 isaxattributes_getLocalName
,
1373 isaxattributes_getQName
,
1374 isaxattributes_getName
,
1375 isaxattributes_getIndexFromName
,
1376 isaxattributes_getIndexFromQName
,
1377 isaxattributes_getType
,
1378 isaxattributes_getTypeFromName
,
1379 isaxattributes_getTypeFromQName
,
1380 isaxattributes_getValue
,
1381 isaxattributes_getValueFromName
,
1382 isaxattributes_getValueFromQName
1385 /* Libxml2 escapes '&' back to char reference '&' in attribute value,
1386 so when document has escaped value with '&' it's parsed to '&' and then
1387 escaped to '&'. This function takes care of ampersands only. */
1388 static BSTR
saxreader_get_unescaped_value(const xmlChar
*buf
, int len
)
1390 static const WCHAR ampescW
[] = {'&','#','3','8',';',0};
1391 WCHAR
*dest
, *ptrW
, *str
;
1398 str_len
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
1399 if (len
!= -1) str_len
++;
1401 str
= heap_alloc(str_len
*sizeof(WCHAR
));
1402 if (!str
) return NULL
;
1404 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, str
, str_len
);
1405 if (len
!= -1) str
[str_len
-1] = 0;
1408 while ((dest
= strstrW(ptrW
, ampescW
)))
1412 /* leave first '&' from a reference as a value */
1413 src
= dest
+ (sizeof(ampescW
)/sizeof(WCHAR
) - 1);
1416 /* move together with null terminator */
1417 memmove(dest
, src
, (strlenW(src
) + 1)*sizeof(WCHAR
));
1422 bstr
= SysAllocString(str
);
1428 static void free_attribute_values(saxlocator
*locator
)
1432 for (i
= 0; i
< locator
->attr_count
; i
++)
1434 SysFreeString(locator
->attributes
[i
].szLocalname
);
1435 locator
->attributes
[i
].szLocalname
= NULL
;
1437 SysFreeString(locator
->attributes
[i
].szValue
);
1438 locator
->attributes
[i
].szValue
= NULL
;
1440 SysFreeString(locator
->attributes
[i
].szQName
);
1441 locator
->attributes
[i
].szQName
= NULL
;
1445 static HRESULT
SAXAttributes_populate(saxlocator
*locator
,
1446 int nb_namespaces
, const xmlChar
**xmlNamespaces
,
1447 int nb_attributes
, const xmlChar
**xmlAttributes
)
1449 static const xmlChar xmlns
[] = "xmlns";
1450 static const WCHAR xmlnsW
[] = { 'x','m','l','n','s',0 };
1452 struct _attributes
*attrs
;
1455 /* skip namespace definitions */
1456 if ((locator
->saxreader
->features
& NamespacePrefixes
) == 0)
1459 locator
->attr_count
= nb_namespaces
+ nb_attributes
;
1460 if(locator
->attr_count
> locator
->attr_alloc_count
)
1462 int new_size
= locator
->attr_count
* 2;
1463 attrs
= heap_realloc_zero(locator
->attributes
, new_size
* sizeof(struct _attributes
));
1466 free_attribute_values(locator
);
1467 locator
->attr_count
= 0;
1468 return E_OUTOFMEMORY
;
1470 locator
->attributes
= attrs
;
1471 locator
->attr_alloc_count
= new_size
;
1475 attrs
= locator
->attributes
;
1478 for (i
= 0; i
< nb_namespaces
; i
++)
1480 SysFreeString(attrs
[nb_attributes
+i
].szLocalname
);
1481 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1483 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1485 SysFreeString(attrs
[nb_attributes
+i
].szValue
);
1486 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1488 SysFreeString(attrs
[nb_attributes
+i
].szQName
);
1489 if(!xmlNamespaces
[2*i
])
1490 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1492 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1495 for (i
= 0; i
< nb_attributes
; i
++)
1497 static const xmlChar xmlA
[] = "xml";
1499 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1500 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1502 /* that's an important feature to keep same uri pointer for every reported attribute */
1503 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1505 SysFreeString(attrs
[i
].szLocalname
);
1506 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1508 SysFreeString(attrs
[i
].szValue
);
1509 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1511 SysFreeString(attrs
[i
].szQName
);
1512 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1], xmlAttributes
[i
*5]);
1518 /*** LibXML callbacks ***/
1519 static void libxmlStartDocument(void *ctx
)
1521 saxlocator
*This
= ctx
;
1522 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1525 if (This
->saxreader
->version
>= MSXML4
)
1527 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1528 update_position(This
, FALSE
);
1529 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1531 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1536 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1540 /* store version value, declaration has to contain version attribute */
1541 if (This
->pParserCtxt
->standalone
!= -1)
1543 SysFreeString(This
->saxreader
->xmldecl_version
);
1544 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1547 if (saxreader_has_handler(This
, SAXContentHandler
))
1549 if(This
->vbInterface
)
1550 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1552 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1554 if (sax_callback_failed(This
, hr
))
1555 format_error_message_from_id(This
, hr
);
1559 static void libxmlEndDocument(void *ctx
)
1561 saxlocator
*This
= ctx
;
1562 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1565 if (This
->saxreader
->version
>= MSXML4
) {
1566 update_position(This
, FALSE
);
1567 if(This
->column
> 1)
1575 if(This
->ret
!= S_OK
) return;
1577 if (saxreader_has_handler(This
, SAXContentHandler
))
1579 if(This
->vbInterface
)
1580 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1582 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1584 if (sax_callback_failed(This
, hr
))
1585 format_error_message_from_id(This
, hr
);
1589 static void libxmlStartElementNS(
1591 const xmlChar
*localname
,
1592 const xmlChar
*prefix
,
1595 const xmlChar
**namespaces
,
1598 const xmlChar
**attributes
)
1600 saxlocator
*This
= ctx
;
1601 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1602 element_entry
*element
;
1606 update_position(This
, TRUE
);
1607 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1609 if(This
->saxreader
->version
< MSXML4
)
1612 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1613 push_element_ns(This
, element
);
1615 if (is_namespaces_enabled(This
->saxreader
))
1619 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1621 if (This
->vbInterface
)
1622 hr
= IVBSAXContentHandler_startPrefixMapping(
1624 &element
->ns
[i
].prefix
,
1625 &element
->ns
[i
].uri
);
1627 hr
= ISAXContentHandler_startPrefixMapping(
1629 element
->ns
[i
].prefix
,
1630 SysStringLen(element
->ns
[i
].prefix
),
1632 SysStringLen(element
->ns
[i
].uri
));
1634 if (sax_callback_failed(This
, hr
))
1636 format_error_message_from_id(This
, hr
);
1642 uri
= find_element_uri(This
, URI
);
1643 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1644 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1648 if (is_namespaces_enabled(This
->saxreader
))
1649 local
= element
->local
;
1653 if (This
->vbInterface
)
1654 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1655 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1657 hr
= ISAXContentHandler_startElement(handler
->handler
,
1658 uri
, SysStringLen(uri
),
1659 local
, SysStringLen(local
),
1660 element
->qname
, SysStringLen(element
->qname
),
1661 &This
->ISAXAttributes_iface
);
1663 if (sax_callback_failed(This
, hr
))
1664 format_error_message_from_id(This
, hr
);
1668 static void libxmlEndElementNS(
1670 const xmlChar
*localname
,
1671 const xmlChar
*prefix
,
1674 saxlocator
*This
= ctx
;
1675 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1676 element_entry
*element
;
1681 update_position(This
, FALSE
);
1682 p
= This
->pParserCtxt
->input
->cur
;
1684 if (This
->saxreader
->version
>= MSXML4
)
1687 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1689 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1694 else if(*(p
-1)!='>' || *(p
-2)!='/')
1697 while(p
-2>=This
->pParserCtxt
->input
->base
1698 && *(p
-2)!='<' && *(p
-1)!='/')
1700 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1706 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1709 uri
= find_element_uri(This
, URI
);
1710 element
= pop_element_ns(This
);
1712 if (!saxreader_has_handler(This
, SAXContentHandler
))
1714 free_attribute_values(This
);
1715 This
->attr_count
= 0;
1716 free_element_entry(element
);
1720 if (is_namespaces_enabled(This
->saxreader
))
1721 local
= element
->local
;
1725 if (This
->vbInterface
)
1726 hr
= IVBSAXContentHandler_endElement(
1728 &uri
, &local
, &element
->qname
);
1730 hr
= ISAXContentHandler_endElement(
1732 uri
, SysStringLen(uri
),
1733 local
, SysStringLen(local
),
1734 element
->qname
, SysStringLen(element
->qname
));
1736 free_attribute_values(This
);
1737 This
->attr_count
= 0;
1739 if (sax_callback_failed(This
, hr
))
1741 format_error_message_from_id(This
, hr
);
1742 free_element_entry(element
);
1746 if (is_namespaces_enabled(This
->saxreader
))
1749 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1751 if (This
->vbInterface
)
1752 hr
= IVBSAXContentHandler_endPrefixMapping(
1753 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1755 hr
= ISAXContentHandler_endPrefixMapping(
1756 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1758 if (sax_callback_failed(This
, hr
)) break;
1761 if (sax_callback_failed(This
, hr
))
1762 format_error_message_from_id(This
, hr
);
1765 free_element_entry(element
);
1768 static void libxmlCharacters(
1773 saxlocator
*This
= ctx
;
1777 BOOL lastEvent
= FALSE
;
1779 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1781 update_position(This
, FALSE
);
1782 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1783 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1785 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1790 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1794 if(*(ch
-1)=='\r') cur
--;
1799 while(end
-ch
<len
&& *end
!='\r') end
++;
1810 if (This
->saxreader
->version
>= MSXML4
)
1814 for(p
=cur
; p
!=end
; p
++)
1831 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1832 hr
= saxreader_saxcharacters(This
, Chars
);
1834 if (sax_callback_failed(This
, hr
))
1836 format_error_message_from_id(This
, hr
);
1840 if (This
->saxreader
->version
< MSXML4
)
1841 This
->column
+= end
-cur
;
1854 if(end
-ch
== len
) break;
1858 static void libxmlSetDocumentLocator(
1860 xmlSAXLocatorPtr loc
)
1862 saxlocator
*This
= ctx
;
1863 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1866 if (saxreader_has_handler(This
, SAXContentHandler
))
1868 if(This
->vbInterface
)
1869 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1870 &This
->IVBSAXLocator_iface
);
1872 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1876 format_error_message_from_id(This
, hr
);
1879 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1881 saxlocator
*This
= ctx
;
1882 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1885 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1887 update_position(This
, FALSE
);
1888 while(p
-4>=This
->pParserCtxt
->input
->base
1889 && memcmp(p
-4, "<!--", sizeof(char[4])))
1891 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1897 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1900 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1902 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1904 if (This
->vbInterface
)
1905 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1907 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1910 format_error_message_from_id(This
, hr
);
1913 static void libxmlFatalError(void *ctx
, const char *msg
, ...)
1915 saxlocator
*This
= ctx
;
1916 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1922 if(This
->ret
!= S_OK
) {
1923 xmlStopParser(This
->pParserCtxt
);
1927 va_start(args
, msg
);
1928 vsprintf(message
, msg
, args
);
1931 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1932 error
= heap_alloc(sizeof(WCHAR
)*len
);
1935 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1936 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1939 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1941 xmlStopParser(This
->pParserCtxt
);
1947 FIXME("Error handling is not compatible.\n");
1949 if(This
->vbInterface
)
1951 BSTR bstrError
= SysAllocString(error
);
1952 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1953 &bstrError
, E_FAIL
);
1954 SysFreeString(bstrError
);
1957 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1961 xmlStopParser(This
->pParserCtxt
);
1965 /* The only reason this helper exists is that CDATA section are reported by chunks,
1966 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1968 This helper should be called for substring with trailing newlines.
1970 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1972 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1975 ptr
= bstr
+ len
- 1;
1976 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1981 /* replace returns as:
1983 - "\r<char>" -> "\n<char>"
1989 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
1992 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
1999 ret
= SysAllocStringLen(bstr
, len
);
2000 SysFreeString(bstr
);
2004 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
2006 const xmlChar
*start
, *end
;
2007 saxlocator
*locator
= ctx
;
2008 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
2013 update_position(locator
, FALSE
);
2014 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2016 if (locator
->vbInterface
)
2017 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
2019 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
2024 format_error_message_from_id(locator
, hr
);
2034 /* scan for newlines */
2035 if (value
[i
] == '\r' || value
[i
] == '\n')
2037 /* skip newlines/linefeeds */
2040 if (value
[i
] != '\r' && value
[i
] != '\n') break;
2046 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
2047 TRACE("(chunk %s)\n", debugstr_w(chars
));
2048 hr
= saxreader_saxcharacters(locator
, chars
);
2049 SysFreeString(chars
);
2058 /* no newline chars (or last chunk) report as a whole */
2059 if (!end
&& start
== value
)
2062 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
2063 TRACE("(%s)\n", debugstr_w(chars
));
2064 hr
= saxreader_saxcharacters(locator
, chars
);
2065 SysFreeString(chars
);
2068 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2070 if (locator
->vbInterface
)
2071 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
2073 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
2077 format_error_message_from_id(locator
, hr
);
2080 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
2082 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
2083 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
2086 /*** IVBSAXLocator interface ***/
2087 /*** IUnknown methods ***/
2088 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2090 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2092 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2096 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2097 IsEqualGUID( riid
, &IID_IDispatch
) ||
2098 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
2102 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
2104 *ppvObject
= &This
->IVBSAXAttributes_iface
;
2108 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2109 return E_NOINTERFACE
;
2112 IVBSAXLocator_AddRef( iface
);
2117 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
2119 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2120 TRACE("%p\n", This
);
2121 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
2124 static ULONG WINAPI
ivbsaxlocator_Release(IVBSAXLocator
* iface
)
2126 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2127 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
2130 /*** IDispatch methods ***/
2131 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
2133 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2135 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2142 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
2143 IVBSAXLocator
*iface
,
2144 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2146 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2148 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2150 return get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2153 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2154 IVBSAXLocator
*iface
,
2156 LPOLESTR
* rgszNames
,
2161 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2162 ITypeInfo
*typeinfo
;
2165 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
2168 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2169 return E_INVALIDARG
;
2171 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2174 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2175 ITypeInfo_Release(typeinfo
);
2181 static HRESULT WINAPI
ivbsaxlocator_Invoke(
2182 IVBSAXLocator
*iface
,
2183 DISPID dispIdMember
,
2187 DISPPARAMS
* pDispParams
,
2188 VARIANT
* pVarResult
,
2189 EXCEPINFO
* pExcepInfo
,
2192 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2193 ITypeInfo
*typeinfo
;
2196 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2197 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2199 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2202 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXLocator_iface
, dispIdMember
, wFlags
,
2203 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2204 ITypeInfo_Release(typeinfo
);
2210 /*** IVBSAXLocator methods ***/
2211 static HRESULT WINAPI
ivbsaxlocator_get_columnNumber(
2212 IVBSAXLocator
* iface
,
2215 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2216 return ISAXLocator_getColumnNumber(&This
->ISAXLocator_iface
, pnColumn
);
2219 static HRESULT WINAPI
ivbsaxlocator_get_lineNumber(
2220 IVBSAXLocator
* iface
,
2223 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2224 return ISAXLocator_getLineNumber(&This
->ISAXLocator_iface
, pnLine
);
2227 static HRESULT WINAPI
ivbsaxlocator_get_publicId(IVBSAXLocator
* iface
, BSTR
*ret
)
2229 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2230 const WCHAR
*publicidW
;
2233 TRACE("(%p)->(%p)\n", This
, ret
);
2239 hr
= ISAXLocator_getPublicId(&This
->ISAXLocator_iface
, &publicidW
);
2243 return return_bstr(publicidW
, ret
);
2246 static HRESULT WINAPI
ivbsaxlocator_get_systemId(IVBSAXLocator
* iface
, BSTR
*ret
)
2248 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2249 const WCHAR
*systemidW
;
2252 TRACE("(%p)->(%p)\n", This
, ret
);
2258 hr
= ISAXLocator_getSystemId(&This
->ISAXLocator_iface
, &systemidW
);
2262 return return_bstr(systemidW
, ret
);
2265 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl
=
2267 ivbsaxlocator_QueryInterface
,
2268 ivbsaxlocator_AddRef
,
2269 ivbsaxlocator_Release
,
2270 ivbsaxlocator_GetTypeInfoCount
,
2271 ivbsaxlocator_GetTypeInfo
,
2272 ivbsaxlocator_GetIDsOfNames
,
2273 ivbsaxlocator_Invoke
,
2274 ivbsaxlocator_get_columnNumber
,
2275 ivbsaxlocator_get_lineNumber
,
2276 ivbsaxlocator_get_publicId
,
2277 ivbsaxlocator_get_systemId
2280 /*** ISAXLocator interface ***/
2281 /*** IUnknown methods ***/
2282 static HRESULT WINAPI
isaxlocator_QueryInterface(ISAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2284 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2286 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2290 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2291 IsEqualGUID( riid
, &IID_ISAXLocator
))
2295 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
2297 *ppvObject
= &This
->ISAXAttributes_iface
;
2301 WARN("interface %s not implemented\n", debugstr_guid(riid
));
2302 return E_NOINTERFACE
;
2305 ISAXLocator_AddRef( iface
);
2310 static ULONG WINAPI
isaxlocator_AddRef(ISAXLocator
* iface
)
2312 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2313 ULONG ref
= InterlockedIncrement( &This
->ref
);
2314 TRACE("(%p)->(%d)\n", This
, ref
);
2318 static ULONG WINAPI
isaxlocator_Release(
2321 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2322 LONG ref
= InterlockedDecrement( &This
->ref
);
2324 TRACE("(%p)->(%d)\n", This
, ref
);
2328 element_entry
*element
, *element2
;
2331 SysFreeString(This
->publicId
);
2332 SysFreeString(This
->systemId
);
2333 SysFreeString(This
->namespaceUri
);
2335 for(index
= 0; index
< This
->attr_alloc_count
; index
++)
2337 SysFreeString(This
->attributes
[index
].szLocalname
);
2338 SysFreeString(This
->attributes
[index
].szValue
);
2339 SysFreeString(This
->attributes
[index
].szQName
);
2341 heap_free(This
->attributes
);
2344 LIST_FOR_EACH_ENTRY_SAFE(element
, element2
, &This
->elements
, element_entry
, entry
)
2346 list_remove(&element
->entry
);
2347 free_element_entry(element
);
2350 ISAXXMLReader_Release(&This
->saxreader
->ISAXXMLReader_iface
);
2357 /*** ISAXLocator methods ***/
2358 static HRESULT WINAPI
isaxlocator_getColumnNumber(
2362 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2364 *pnColumn
= This
->column
;
2368 static HRESULT WINAPI
isaxlocator_getLineNumber(
2372 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2374 *pnLine
= This
->line
;
2378 static HRESULT WINAPI
isaxlocator_getPublicId(
2380 const WCHAR
** ppwchPublicId
)
2383 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2385 SysFreeString(This
->publicId
);
2387 publicId
= bstr_from_xmlChar(xmlSAX2GetPublicId(This
->pParserCtxt
));
2388 if(SysStringLen(publicId
))
2389 This
->publicId
= publicId
;
2392 SysFreeString(publicId
);
2393 This
->publicId
= NULL
;
2396 *ppwchPublicId
= This
->publicId
;
2400 static HRESULT WINAPI
isaxlocator_getSystemId(
2402 const WCHAR
** ppwchSystemId
)
2405 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2407 SysFreeString(This
->systemId
);
2409 systemId
= bstr_from_xmlChar(xmlSAX2GetSystemId(This
->pParserCtxt
));
2410 if(SysStringLen(systemId
))
2411 This
->systemId
= systemId
;
2414 SysFreeString(systemId
);
2415 This
->systemId
= NULL
;
2418 *ppwchSystemId
= This
->systemId
;
2422 static const struct ISAXLocatorVtbl SAXLocatorVtbl
=
2424 isaxlocator_QueryInterface
,
2426 isaxlocator_Release
,
2427 isaxlocator_getColumnNumber
,
2428 isaxlocator_getLineNumber
,
2429 isaxlocator_getPublicId
,
2430 isaxlocator_getSystemId
2433 static HRESULT
SAXLocator_create(saxreader
*reader
, saxlocator
**ppsaxlocator
, BOOL vbInterface
)
2435 static const WCHAR w3xmlns
[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2436 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2438 saxlocator
*locator
;
2440 locator
= heap_alloc( sizeof (*locator
) );
2442 return E_OUTOFMEMORY
;
2444 locator
->IVBSAXLocator_iface
.lpVtbl
= &VBSAXLocatorVtbl
;
2445 locator
->ISAXLocator_iface
.lpVtbl
= &SAXLocatorVtbl
;
2446 locator
->IVBSAXAttributes_iface
.lpVtbl
= &ivbsaxattributes_vtbl
;
2447 locator
->ISAXAttributes_iface
.lpVtbl
= &isaxattributes_vtbl
;
2449 locator
->vbInterface
= vbInterface
;
2451 locator
->saxreader
= reader
;
2452 ISAXXMLReader_AddRef(&reader
->ISAXXMLReader_iface
);
2454 locator
->pParserCtxt
= NULL
;
2455 locator
->publicId
= NULL
;
2456 locator
->systemId
= NULL
;
2457 locator
->line
= reader
->version
< MSXML4
? 0 : 1;
2458 locator
->column
= 0;
2459 locator
->ret
= S_OK
;
2460 if (locator
->saxreader
->version
>= MSXML6
)
2461 locator
->namespaceUri
= SysAllocString(w3xmlns
);
2463 locator
->namespaceUri
= SysAllocStringLen(NULL
, 0);
2464 if(!locator
->namespaceUri
)
2466 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2468 return E_OUTOFMEMORY
;
2471 locator
->attr_alloc_count
= 8;
2472 locator
->attr_count
= 0;
2473 locator
->attributes
= heap_alloc_zero(sizeof(struct _attributes
)*locator
->attr_alloc_count
);
2474 if(!locator
->attributes
)
2476 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2477 SysFreeString(locator
->namespaceUri
);
2479 return E_OUTOFMEMORY
;
2482 list_init(&locator
->elements
);
2484 *ppsaxlocator
= locator
;
2486 TRACE("returning %p\n", *ppsaxlocator
);
2491 /*** SAXXMLReader internal functions ***/
2492 static HRESULT
internal_parseBuffer(saxreader
*This
, const char *buffer
, int size
, BOOL vbInterface
)
2494 xmlCharEncoding encoding
= XML_CHAR_ENCODING_NONE
;
2495 xmlChar
*enc_name
= NULL
;
2496 saxlocator
*locator
;
2499 TRACE("(%p)->(%p %d)\n", This
, buffer
, size
);
2501 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2507 const unsigned char *buff
= (unsigned char*)buffer
;
2509 encoding
= xmlDetectCharEncoding((xmlChar
*)buffer
, 4);
2510 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2511 TRACE("detected encoding: %s\n", enc_name
);
2512 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2513 if ((encoding
== XML_CHAR_ENCODING_UTF8
) &&
2514 buff
[0] == 0xEF && buff
[1] == 0xBB && buff
[2] == 0xBF)
2521 /* if libxml2 detection failed try to guess */
2522 if (encoding
== XML_CHAR_ENCODING_NONE
)
2524 const WCHAR
*ptr
= (WCHAR
*)buffer
;
2525 /* xml declaration with possibly specfied encoding will be still handled by parser */
2526 if ((size
>= 2) && *ptr
== '<' && ptr
[1] != '?')
2528 enc_name
= (xmlChar
*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE
);
2529 encoding
= XML_CHAR_ENCODING_UTF16LE
;
2532 else if (encoding
== XML_CHAR_ENCODING_UTF8
)
2533 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2537 locator
->pParserCtxt
= xmlCreateMemoryParserCtxt(buffer
, size
);
2538 if (!locator
->pParserCtxt
)
2540 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2546 locator
->pParserCtxt
->encoding
= xmlStrdup(enc_name
);
2547 if (encoding
== XML_CHAR_ENCODING_UTF16LE
) {
2548 TRACE("switching to %s\n", enc_name
);
2549 xmlSwitchEncoding(locator
->pParserCtxt
, encoding
);
2553 xmlFree(locator
->pParserCtxt
->sax
);
2554 locator
->pParserCtxt
->sax
= &locator
->saxreader
->sax
;
2555 locator
->pParserCtxt
->userData
= locator
;
2557 This
->isParsing
= TRUE
;
2558 if(xmlParseDocument(locator
->pParserCtxt
) == -1 && locator
->ret
== S_OK
)
2562 This
->isParsing
= FALSE
;
2564 if(locator
->pParserCtxt
)
2566 locator
->pParserCtxt
->sax
= NULL
;
2567 xmlFreeParserCtxt(locator
->pParserCtxt
);
2568 locator
->pParserCtxt
= NULL
;
2571 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2575 static HRESULT
internal_parseStream(saxreader
*This
, ISequentialStream
*stream
, BOOL vbInterface
)
2577 saxlocator
*locator
;
2584 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2585 if(FAILED(hr
)) return hr
;
2587 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2588 if(FAILED(hr
)) return hr
;
2590 locator
->pParserCtxt
= xmlCreatePushParserCtxt(
2591 &locator
->saxreader
->sax
, locator
,
2592 data
, dataRead
, NULL
);
2593 if(!locator
->pParserCtxt
)
2595 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2599 This
->isParsing
= TRUE
;
2603 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2604 if (FAILED(hr
) || !dataRead
) break;
2606 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, dataRead
, 0);
2607 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2612 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2613 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2617 This
->isParsing
= FALSE
;
2619 xmlFreeParserCtxt(locator
->pParserCtxt
);
2620 locator
->pParserCtxt
= NULL
;
2621 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2625 static HRESULT
internal_parse(
2632 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varInput
));
2634 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2635 free_bstr_pool(&This
->pool
);
2637 switch(V_VT(&varInput
))
2640 case VT_BSTR
|VT_BYREF
:
2642 BSTR str
= V_ISBYREF(&varInput
) ? *V_BSTRREF(&varInput
) : V_BSTR(&varInput
);
2643 hr
= internal_parseBuffer(This
, (const char*)str
, strlenW(str
)*sizeof(WCHAR
), vbInterface
);
2646 case VT_ARRAY
|VT_UI1
: {
2648 LONG lBound
, uBound
;
2651 hr
= SafeArrayGetLBound(V_ARRAY(&varInput
), 1, &lBound
);
2652 if(hr
!= S_OK
) break;
2653 hr
= SafeArrayGetUBound(V_ARRAY(&varInput
), 1, &uBound
);
2654 if(hr
!= S_OK
) break;
2655 dataRead
= (uBound
-lBound
)*SafeArrayGetElemsize(V_ARRAY(&varInput
));
2656 hr
= SafeArrayAccessData(V_ARRAY(&varInput
), &pSAData
);
2657 if(hr
!= S_OK
) break;
2658 hr
= internal_parseBuffer(This
, pSAData
, dataRead
, vbInterface
);
2659 SafeArrayUnaccessData(V_ARRAY(&varInput
));
2664 IPersistStream
*persistStream
;
2665 ISequentialStream
*stream
= NULL
;
2666 IXMLDOMDocument
*xmlDoc
;
2668 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2669 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2673 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2674 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2675 SysStringByteLen(bstrData
), vbInterface
);
2676 IXMLDOMDocument_Release(xmlDoc
);
2677 SysFreeString(bstrData
);
2681 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2682 &IID_IPersistStream
, (void**)&persistStream
) == S_OK
)
2684 IStream
*stream_copy
;
2686 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream_copy
);
2689 IPersistStream_Release(persistStream
);
2693 hr
= IPersistStream_Save(persistStream
, stream_copy
, TRUE
);
2694 IPersistStream_Release(persistStream
);
2696 IStream_QueryInterface(stream_copy
, &IID_ISequentialStream
, (void**)&stream
);
2698 IStream_Release(stream_copy
);
2701 /* try base interface first */
2704 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2706 /* this should never happen if IStream is implemented properly, but just in case */
2707 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2712 hr
= internal_parseStream(This
, stream
, vbInterface
);
2713 ISequentialStream_Release(stream
);
2717 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2724 WARN("vt %d not implemented\n", V_VT(&varInput
));
2731 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2733 saxreader
*This
= obj
;
2735 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2738 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2740 saxreader
*This
= obj
;
2742 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2745 static HRESULT
internal_parseURL(
2754 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
2756 hr
= create_moniker_from_url(url
, &mon
);
2760 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, This
, &bsc
);
2761 else hr
= bind_url(mon
, internal_onDataAvailable
, This
, &bsc
);
2762 IMoniker_Release(mon
);
2767 return detach_bsc(bsc
);
2770 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2774 if (V_VT(v
) == VT_EMPTY
)
2775 return saxreader_put_handler(This
, type
, NULL
, vb
);
2779 case SAXDeclHandler
:
2780 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2782 case SAXLexicalHandler
:
2783 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2786 ERR("wrong handler type %d\n", type
);
2795 IUnknown
*handler
= NULL
;
2799 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2800 if (FAILED(hr
)) return hr
;
2803 saxreader_put_handler(This
, type
, handler
, vb
);
2804 if (handler
) IUnknown_Release(handler
);
2808 ERR("value type %d not supported\n", V_VT(v
));
2809 return E_INVALIDARG
;
2815 static HRESULT
internal_putProperty(
2823 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2825 if (This
->isParsing
) return E_FAIL
;
2827 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2828 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2829 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2831 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2832 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2834 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2836 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2837 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2841 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2843 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2844 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2848 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2850 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2853 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2856 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2859 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2862 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2865 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2868 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2871 return E_INVALIDARG
;
2874 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2876 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2878 if (!value
) return E_POINTER
;
2880 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2882 V_VT(value
) = VT_UNKNOWN
;
2883 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2887 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2889 V_VT(value
) = VT_UNKNOWN
;
2890 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2894 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2896 V_VT(value
) = VT_BSTR
;
2897 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2901 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2906 /*** IVBSAXXMLReader interface ***/
2907 /*** IUnknown methods ***/
2908 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2910 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2912 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2916 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2917 IsEqualGUID( riid
, &IID_IDispatch
) ||
2918 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2922 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2924 *ppvObject
= &This
->ISAXXMLReader_iface
;
2926 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2928 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2932 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2933 return E_NOINTERFACE
;
2936 IVBSAXXMLReader_AddRef( iface
);
2941 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2943 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2944 TRACE("%p\n", This
);
2945 return InterlockedIncrement( &This
->ref
);
2948 static ULONG WINAPI
saxxmlreader_Release(
2949 IVBSAXXMLReader
* iface
)
2951 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2954 TRACE("%p\n", This
);
2956 ref
= InterlockedDecrement( &This
->ref
);
2961 for (i
= 0; i
< SAXHandler_Last
; i
++)
2963 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2965 if (saxiface
->handler
)
2966 IUnknown_Release(saxiface
->handler
);
2968 if (saxiface
->vbhandler
)
2969 IUnknown_Release(saxiface
->vbhandler
);
2972 SysFreeString(This
->xmldecl_version
);
2973 free_bstr_pool(&This
->pool
);
2981 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2983 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2984 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2987 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2988 IVBSAXXMLReader
*iface
,
2989 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2991 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2992 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2993 iTInfo
, lcid
, ppTInfo
);
2996 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2997 IVBSAXXMLReader
*iface
,
2999 LPOLESTR
* rgszNames
,
3004 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3005 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
3006 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
3009 static HRESULT WINAPI
saxxmlreader_Invoke(
3010 IVBSAXXMLReader
*iface
,
3011 DISPID dispIdMember
,
3015 DISPPARAMS
* pDispParams
,
3016 VARIANT
* pVarResult
,
3017 EXCEPINFO
* pExcepInfo
,
3020 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3021 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
3022 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3025 /*** IVBSAXXMLReader methods ***/
3026 static HRESULT WINAPI
saxxmlreader_getFeature(
3027 IVBSAXXMLReader
* iface
,
3029 VARIANT_BOOL
*value
)
3031 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3032 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3035 static HRESULT WINAPI
saxxmlreader_putFeature(
3036 IVBSAXXMLReader
* iface
,
3040 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3041 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3044 static HRESULT WINAPI
saxxmlreader_getProperty(
3045 IVBSAXXMLReader
* iface
,
3049 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3050 return internal_getProperty(This
, prop
, value
, TRUE
);
3053 static HRESULT WINAPI
saxxmlreader_putProperty(
3054 IVBSAXXMLReader
* iface
,
3058 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3059 return internal_putProperty(This
, pProp
, value
, TRUE
);
3062 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3063 IVBSAXXMLReader
* iface
,
3064 IVBSAXEntityResolver
**resolver
)
3066 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3067 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3070 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3071 IVBSAXXMLReader
* iface
,
3072 IVBSAXEntityResolver
*resolver
)
3074 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3075 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3078 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3079 IVBSAXXMLReader
* iface
,
3080 IVBSAXContentHandler
**handler
)
3082 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3083 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3086 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3087 IVBSAXXMLReader
* iface
,
3088 IVBSAXContentHandler
*handler
)
3090 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3091 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3094 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3095 IVBSAXXMLReader
* iface
,
3096 IVBSAXDTDHandler
**handler
)
3098 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3099 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3102 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3103 IVBSAXXMLReader
* iface
,
3104 IVBSAXDTDHandler
*handler
)
3106 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3107 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3110 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3111 IVBSAXXMLReader
* iface
,
3112 IVBSAXErrorHandler
**handler
)
3114 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3115 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3118 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3119 IVBSAXXMLReader
* iface
,
3120 IVBSAXErrorHandler
*handler
)
3122 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3123 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3126 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3127 IVBSAXXMLReader
* iface
,
3130 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3132 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3136 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3137 IVBSAXXMLReader
* iface
,
3140 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3141 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3144 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3145 IVBSAXXMLReader
* iface
,
3146 BSTR
*pSecureBaseUrl
)
3148 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3150 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3154 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3155 IVBSAXXMLReader
* iface
,
3158 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3159 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3162 static HRESULT WINAPI
saxxmlreader_parse(
3163 IVBSAXXMLReader
* iface
,
3166 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3167 return internal_parse(This
, varInput
, TRUE
);
3170 static HRESULT WINAPI
saxxmlreader_parseURL(
3171 IVBSAXXMLReader
* iface
,
3174 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3175 return internal_parseURL(This
, url
, TRUE
);
3178 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3180 saxxmlreader_QueryInterface
,
3181 saxxmlreader_AddRef
,
3182 saxxmlreader_Release
,
3183 saxxmlreader_GetTypeInfoCount
,
3184 saxxmlreader_GetTypeInfo
,
3185 saxxmlreader_GetIDsOfNames
,
3186 saxxmlreader_Invoke
,
3187 saxxmlreader_getFeature
,
3188 saxxmlreader_putFeature
,
3189 saxxmlreader_getProperty
,
3190 saxxmlreader_putProperty
,
3191 saxxmlreader_get_entityResolver
,
3192 saxxmlreader_put_entityResolver
,
3193 saxxmlreader_get_contentHandler
,
3194 saxxmlreader_put_contentHandler
,
3195 saxxmlreader_get_dtdHandler
,
3196 saxxmlreader_put_dtdHandler
,
3197 saxxmlreader_get_errorHandler
,
3198 saxxmlreader_put_errorHandler
,
3199 saxxmlreader_get_baseURL
,
3200 saxxmlreader_put_baseURL
,
3201 saxxmlreader_get_secureBaseURL
,
3202 saxxmlreader_put_secureBaseURL
,
3204 saxxmlreader_parseURL
3207 /*** ISAXXMLReader interface ***/
3208 /*** IUnknown methods ***/
3209 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3211 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3212 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3215 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3217 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3218 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3221 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3223 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3224 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3227 /*** ISAXXMLReader methods ***/
3228 static HRESULT WINAPI
isaxxmlreader_getFeature(
3229 ISAXXMLReader
* iface
,
3230 const WCHAR
*feature_name
,
3231 VARIANT_BOOL
*value
)
3233 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3234 saxreader_feature feature
;
3236 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3238 feature
= get_saxreader_feature(feature_name
);
3239 if (feature
== Namespaces
|| feature
== NamespacePrefixes
)
3240 return get_feature_value(This
, feature
, value
);
3242 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3246 static HRESULT WINAPI
isaxxmlreader_putFeature(
3247 ISAXXMLReader
* iface
,
3248 const WCHAR
*feature_name
,
3251 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3252 saxreader_feature feature
;
3254 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3256 feature
= get_saxreader_feature(feature_name
);
3258 /* accepted cases */
3259 if ((feature
== ExternalGeneralEntities
&& value
== VARIANT_FALSE
) ||
3260 (feature
== ExternalParameterEntities
&& value
== VARIANT_FALSE
) ||
3261 feature
== Namespaces
||
3262 feature
== NamespacePrefixes
)
3264 return set_feature_value(This
, feature
, value
);
3267 if (feature
== LexicalHandlerParEntities
|| feature
== ProhibitDTD
)
3269 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3270 return set_feature_value(This
, feature
, value
);
3273 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3277 static HRESULT WINAPI
isaxxmlreader_getProperty(
3278 ISAXXMLReader
* iface
,
3282 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3283 return internal_getProperty(This
, prop
, value
, FALSE
);
3286 static HRESULT WINAPI
isaxxmlreader_putProperty(
3287 ISAXXMLReader
* iface
,
3291 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3292 return internal_putProperty(This
, pProp
, value
, FALSE
);
3295 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3296 ISAXXMLReader
* iface
,
3297 ISAXEntityResolver
**resolver
)
3299 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3300 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3303 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3304 ISAXXMLReader
* iface
,
3305 ISAXEntityResolver
*resolver
)
3307 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3308 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3311 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3312 ISAXXMLReader
* iface
,
3313 ISAXContentHandler
**handler
)
3315 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3316 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3319 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3320 ISAXXMLReader
* iface
,
3321 ISAXContentHandler
*handler
)
3323 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3324 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3327 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3328 ISAXXMLReader
* iface
,
3329 ISAXDTDHandler
**handler
)
3331 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3332 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3335 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3336 ISAXXMLReader
* iface
,
3337 ISAXDTDHandler
*handler
)
3339 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3340 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3343 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3344 ISAXXMLReader
* iface
,
3345 ISAXErrorHandler
**handler
)
3347 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3348 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3351 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3353 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3354 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3357 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3358 ISAXXMLReader
* iface
,
3359 const WCHAR
**base_url
)
3361 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3363 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3367 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3368 ISAXXMLReader
* iface
,
3369 const WCHAR
*pBaseUrl
)
3371 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3373 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3377 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3378 ISAXXMLReader
* iface
,
3379 const WCHAR
**pSecureBaseUrl
)
3381 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3382 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3386 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3387 ISAXXMLReader
* iface
,
3388 const WCHAR
*secureBaseUrl
)
3390 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3392 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3396 static HRESULT WINAPI
isaxxmlreader_parse(
3397 ISAXXMLReader
* iface
,
3400 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3401 return internal_parse(This
, varInput
, FALSE
);
3404 static HRESULT WINAPI
isaxxmlreader_parseURL(
3405 ISAXXMLReader
* iface
,
3408 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3409 return internal_parseURL(This
, url
, FALSE
);
3412 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3414 isaxxmlreader_QueryInterface
,
3415 isaxxmlreader_AddRef
,
3416 isaxxmlreader_Release
,
3417 isaxxmlreader_getFeature
,
3418 isaxxmlreader_putFeature
,
3419 isaxxmlreader_getProperty
,
3420 isaxxmlreader_putProperty
,
3421 isaxxmlreader_getEntityResolver
,
3422 isaxxmlreader_putEntityResolver
,
3423 isaxxmlreader_getContentHandler
,
3424 isaxxmlreader_putContentHandler
,
3425 isaxxmlreader_getDTDHandler
,
3426 isaxxmlreader_putDTDHandler
,
3427 isaxxmlreader_getErrorHandler
,
3428 isaxxmlreader_putErrorHandler
,
3429 isaxxmlreader_getBaseURL
,
3430 isaxxmlreader_putBaseURL
,
3431 isaxxmlreader_getSecureBaseURL
,
3432 isaxxmlreader_putSecureBaseURL
,
3433 isaxxmlreader_parse
,
3434 isaxxmlreader_parseURL
3437 static const tid_t saxreader_iface_tids
[] = {
3438 IVBSAXXMLReader_tid
,
3441 static dispex_static_data_t saxreader_dispex
= {
3443 IVBSAXXMLReader_tid
,
3445 saxreader_iface_tids
3448 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3452 TRACE("(%p)\n", ppObj
);
3454 reader
= heap_alloc( sizeof (*reader
) );
3456 return E_OUTOFMEMORY
;
3458 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3459 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3461 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3462 reader
->isParsing
= FALSE
;
3463 reader
->xmldecl_version
= NULL
;
3464 reader
->pool
.pool
= NULL
;
3465 reader
->pool
.index
= 0;
3466 reader
->pool
.len
= 0;
3467 reader
->features
= Namespaces
| NamespacePrefixes
;
3468 reader
->version
= version
;
3470 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3472 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3473 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3474 reader
->sax
.startDocument
= libxmlStartDocument
;
3475 reader
->sax
.endDocument
= libxmlEndDocument
;
3476 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3477 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3478 reader
->sax
.characters
= libxmlCharacters
;
3479 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3480 reader
->sax
.comment
= libxmlComment
;
3481 reader
->sax
.error
= libxmlFatalError
;
3482 reader
->sax
.fatalError
= libxmlFatalError
;
3483 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3484 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3486 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3488 TRACE("returning iface %p\n", *ppObj
);
3495 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3497 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3498 "libxml2 support was not present at compile time.\n");