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"
48 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
;
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
), 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;
694 This
->line
= xmlSAX2GetLineNumber(This
->pParserCtxt
);
698 for(; *p
!='\n' && *p
!='\r' && p
>=This
->pParserCtxt
->input
->base
; p
--)
703 This
->column
= xmlSAX2GetColumnNumber(This
->pParserCtxt
);
707 /*** IVBSAXAttributes interface ***/
708 static HRESULT WINAPI
ivbsaxattributes_QueryInterface(
709 IVBSAXAttributes
* iface
,
713 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
714 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
715 return IVBSAXLocator_QueryInterface(&This
->IVBSAXLocator_iface
, riid
, ppvObject
);
718 static ULONG WINAPI
ivbsaxattributes_AddRef(IVBSAXAttributes
* iface
)
720 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
721 return IVBSAXLocator_AddRef(&This
->IVBSAXLocator_iface
);
724 static ULONG WINAPI
ivbsaxattributes_Release(IVBSAXAttributes
* iface
)
726 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
727 return IVBSAXLocator_Release(&This
->IVBSAXLocator_iface
);
730 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes
*iface
, UINT
* pctinfo
)
732 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
734 TRACE("(%p)->(%p)\n", This
, pctinfo
);
741 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfo(
742 IVBSAXAttributes
*iface
,
743 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
745 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
747 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
749 return get_typeinfo(IVBSAXAttributes_tid
, ppTInfo
);
752 static HRESULT WINAPI
ivbsaxattributes_GetIDsOfNames(
753 IVBSAXAttributes
*iface
,
760 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
764 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
767 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
770 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
773 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
774 ITypeInfo_Release(typeinfo
);
780 static HRESULT WINAPI
ivbsaxattributes_Invoke(
781 IVBSAXAttributes
*iface
,
786 DISPPARAMS
* pDispParams
,
788 EXCEPINFO
* pExcepInfo
,
791 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
795 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
796 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
798 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
801 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXAttributes_iface
, dispIdMember
, wFlags
,
802 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
803 ITypeInfo_Release(typeinfo
);
809 /*** IVBSAXAttributes methods ***/
810 static HRESULT WINAPI
ivbsaxattributes_get_length(
811 IVBSAXAttributes
* iface
,
814 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
815 return ISAXAttributes_getLength(&This
->ISAXAttributes_iface
, nLength
);
818 static HRESULT WINAPI
ivbsaxattributes_getURI(
819 IVBSAXAttributes
* iface
,
823 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
828 TRACE("(%p)->(%d %p)\n", This
, nIndex
, uri
);
834 hr
= ISAXAttributes_getURI(&This
->ISAXAttributes_iface
, nIndex
, &uriW
, &len
);
838 return return_bstrn(uriW
, len
, uri
);
841 static HRESULT WINAPI
ivbsaxattributes_getLocalName(
842 IVBSAXAttributes
* iface
,
846 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
851 TRACE("(%p)->(%d %p)\n", This
, nIndex
, name
);
857 hr
= ISAXAttributes_getLocalName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
861 return return_bstrn(nameW
, len
, name
);
864 static HRESULT WINAPI
ivbsaxattributes_getQName(
865 IVBSAXAttributes
* iface
,
869 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
874 TRACE("(%p)->(%d %p)\n", This
, nIndex
, QName
);
880 hr
= ISAXAttributes_getQName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
884 return return_bstrn(nameW
, len
, QName
);
887 static HRESULT WINAPI
ivbsaxattributes_getIndexFromName(
888 IVBSAXAttributes
* iface
,
893 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
894 return ISAXAttributes_getIndexFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
895 localName
, SysStringLen(localName
), index
);
898 static HRESULT WINAPI
ivbsaxattributes_getIndexFromQName(
899 IVBSAXAttributes
* iface
,
903 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
904 return ISAXAttributes_getIndexFromQName(&This
->ISAXAttributes_iface
, QName
,
905 SysStringLen(QName
), index
);
908 static HRESULT WINAPI
ivbsaxattributes_getType(
909 IVBSAXAttributes
* iface
,
913 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
918 TRACE("(%p)->(%d %p)\n", This
, nIndex
, type
);
924 hr
= ISAXAttributes_getType(&This
->ISAXAttributes_iface
, nIndex
, &typeW
, &len
);
928 return return_bstrn(typeW
, len
, type
);
931 static HRESULT WINAPI
ivbsaxattributes_getTypeFromName(
932 IVBSAXAttributes
* iface
,
937 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
942 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), type
);
948 hr
= ISAXAttributes_getTypeFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
949 localName
, SysStringLen(localName
), &typeW
, &len
);
953 return return_bstrn(typeW
, len
, type
);
956 static HRESULT WINAPI
ivbsaxattributes_getTypeFromQName(
957 IVBSAXAttributes
* iface
,
961 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
966 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), type
);
972 hr
= ISAXAttributes_getTypeFromQName(&This
->ISAXAttributes_iface
, QName
, SysStringLen(QName
),
977 return return_bstrn(typeW
, len
, type
);
980 static HRESULT WINAPI
ivbsaxattributes_getValue(
981 IVBSAXAttributes
* iface
,
985 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
990 TRACE("(%p)->(%d %p)\n", This
, nIndex
, value
);
996 hr
= ISAXAttributes_getValue(&This
->ISAXAttributes_iface
, nIndex
, &valueW
, &len
);
1000 return return_bstrn(valueW
, len
, value
);
1003 static HRESULT WINAPI
ivbsaxattributes_getValueFromName(
1004 IVBSAXAttributes
* iface
,
1009 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1010 const WCHAR
*valueW
;
1014 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), value
);
1020 hr
= ISAXAttributes_getValueFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
1021 localName
, SysStringLen(localName
), &valueW
, &len
);
1025 return return_bstrn(valueW
, len
, value
);
1028 static HRESULT WINAPI
ivbsaxattributes_getValueFromQName(
1029 IVBSAXAttributes
* iface
,
1033 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1034 const WCHAR
*valueW
;
1038 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), value
);
1044 hr
= ISAXAttributes_getValueFromQName(&This
->ISAXAttributes_iface
, QName
,
1045 SysStringLen(QName
), &valueW
, &len
);
1049 return return_bstrn(valueW
, len
, value
);
1052 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl
=
1054 ivbsaxattributes_QueryInterface
,
1055 ivbsaxattributes_AddRef
,
1056 ivbsaxattributes_Release
,
1057 ivbsaxattributes_GetTypeInfoCount
,
1058 ivbsaxattributes_GetTypeInfo
,
1059 ivbsaxattributes_GetIDsOfNames
,
1060 ivbsaxattributes_Invoke
,
1061 ivbsaxattributes_get_length
,
1062 ivbsaxattributes_getURI
,
1063 ivbsaxattributes_getLocalName
,
1064 ivbsaxattributes_getQName
,
1065 ivbsaxattributes_getIndexFromName
,
1066 ivbsaxattributes_getIndexFromQName
,
1067 ivbsaxattributes_getType
,
1068 ivbsaxattributes_getTypeFromName
,
1069 ivbsaxattributes_getTypeFromQName
,
1070 ivbsaxattributes_getValue
,
1071 ivbsaxattributes_getValueFromName
,
1072 ivbsaxattributes_getValueFromQName
1075 /*** ISAXAttributes interface ***/
1076 /*** IUnknown methods ***/
1077 static HRESULT WINAPI
isaxattributes_QueryInterface(
1078 ISAXAttributes
* iface
,
1082 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1083 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
1084 return ISAXLocator_QueryInterface(&This
->ISAXLocator_iface
, riid
, ppvObject
);
1087 static ULONG WINAPI
isaxattributes_AddRef(ISAXAttributes
* iface
)
1089 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1090 TRACE("%p\n", This
);
1091 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
1094 static ULONG WINAPI
isaxattributes_Release(ISAXAttributes
* iface
)
1096 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1098 TRACE("%p\n", This
);
1099 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
1102 /*** ISAXAttributes methods ***/
1103 static HRESULT WINAPI
isaxattributes_getLength(
1104 ISAXAttributes
* iface
,
1107 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1109 *length
= This
->nb_attributes
;
1110 TRACE("Length set to %d\n", *length
);
1114 static HRESULT WINAPI
isaxattributes_getURI(
1115 ISAXAttributes
* iface
,
1120 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1121 TRACE("(%p)->(%d)\n", This
, index
);
1123 if(index
>= This
->nb_attributes
|| index
< 0) return E_INVALIDARG
;
1124 if(!url
|| !size
) return E_POINTER
;
1126 *size
= SysStringLen(This
->attributes
[index
].szURI
);
1127 *url
= This
->attributes
[index
].szURI
;
1129 TRACE("(%s:%d)\n", debugstr_w(This
->attributes
[index
].szURI
), *size
);
1134 static HRESULT WINAPI
isaxattributes_getLocalName(
1135 ISAXAttributes
* iface
,
1137 const WCHAR
**pLocalName
,
1138 int *pLocalNameLength
)
1140 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1141 TRACE("(%p)->(%d)\n", This
, nIndex
);
1143 if(nIndex
>=This
->nb_attributes
|| nIndex
<0) return E_INVALIDARG
;
1144 if(!pLocalName
|| !pLocalNameLength
) return E_POINTER
;
1146 *pLocalNameLength
= SysStringLen(This
->attributes
[nIndex
].szLocalname
);
1147 *pLocalName
= This
->attributes
[nIndex
].szLocalname
;
1152 static HRESULT WINAPI
isaxattributes_getQName(
1153 ISAXAttributes
* iface
,
1155 const WCHAR
**pQName
,
1158 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1159 TRACE("(%p)->(%d)\n", This
, nIndex
);
1161 if(nIndex
>=This
->nb_attributes
|| nIndex
<0) return E_INVALIDARG
;
1162 if(!pQName
|| !pQNameLength
) return E_POINTER
;
1164 *pQNameLength
= SysStringLen(This
->attributes
[nIndex
].szQName
);
1165 *pQName
= This
->attributes
[nIndex
].szQName
;
1170 static HRESULT WINAPI
isaxattributes_getName(
1171 ISAXAttributes
* iface
,
1175 const WCHAR
**localName
,
1176 int *pLocalNameSize
,
1177 const WCHAR
**QName
,
1180 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1181 TRACE("(%p)->(%d)\n", This
, index
);
1183 if(index
>=This
->nb_attributes
|| index
<0) return E_INVALIDARG
;
1184 if(!uri
|| !pUriLength
|| !localName
|| !pLocalNameSize
1185 || !QName
|| !pQNameLength
) return E_POINTER
;
1187 *pUriLength
= SysStringLen(This
->attributes
[index
].szURI
);
1188 *uri
= This
->attributes
[index
].szURI
;
1189 *pLocalNameSize
= SysStringLen(This
->attributes
[index
].szLocalname
);
1190 *localName
= This
->attributes
[index
].szLocalname
;
1191 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1192 *QName
= This
->attributes
[index
].szQName
;
1194 TRACE("(%s, %s, %s)\n", debugstr_w(*uri
), debugstr_w(*localName
), debugstr_w(*QName
));
1199 static HRESULT WINAPI
isaxattributes_getIndexFromName(
1200 ISAXAttributes
* iface
,
1203 const WCHAR
*pLocalName
,
1204 int cocalNameLength
,
1207 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1209 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), cUriLength
,
1210 debugstr_w(pLocalName
), cocalNameLength
);
1212 if(!pUri
|| !pLocalName
|| !index
) return E_POINTER
;
1214 for(i
=0; i
<This
->nb_attributes
; i
++)
1216 if(cUriLength
!=SysStringLen(This
->attributes
[i
].szURI
)
1217 || cocalNameLength
!=SysStringLen(This
->attributes
[i
].szLocalname
))
1219 if(cUriLength
&& memcmp(pUri
, This
->attributes
[i
].szURI
,
1220 sizeof(WCHAR
)*cUriLength
))
1222 if(cocalNameLength
&& memcmp(pLocalName
, This
->attributes
[i
].szLocalname
,
1223 sizeof(WCHAR
)*cocalNameLength
))
1230 return E_INVALIDARG
;
1233 static HRESULT WINAPI
isaxattributes_getIndexFromQName(
1234 ISAXAttributes
* iface
,
1235 const WCHAR
*pQName
,
1239 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1241 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQNameLength
);
1243 if(!pQName
|| !index
) return E_POINTER
;
1244 if(!nQNameLength
) return E_INVALIDARG
;
1246 for(i
=0; i
<This
->nb_attributes
; i
++)
1248 if(nQNameLength
!=SysStringLen(This
->attributes
[i
].szQName
)) continue;
1249 if(memcmp(pQName
, This
->attributes
[i
].szQName
, sizeof(WCHAR
)*nQNameLength
)) continue;
1255 return E_INVALIDARG
;
1258 static HRESULT WINAPI
isaxattributes_getType(
1259 ISAXAttributes
* iface
,
1261 const WCHAR
**pType
,
1264 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1266 FIXME("(%p)->(%d) stub\n", This
, nIndex
);
1270 static HRESULT WINAPI
isaxattributes_getTypeFromName(
1271 ISAXAttributes
* iface
,
1274 const WCHAR
*pLocalName
,
1276 const WCHAR
**pType
,
1279 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1281 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This
, debugstr_w(pUri
), nUri
,
1282 debugstr_w(pLocalName
), nLocalName
);
1286 static HRESULT WINAPI
isaxattributes_getTypeFromQName(
1287 ISAXAttributes
* iface
,
1288 const WCHAR
*pQName
,
1290 const WCHAR
**pType
,
1293 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1295 FIXME("(%p)->(%s, %d) stub\n", This
, debugstr_w(pQName
), nQName
);
1299 static HRESULT WINAPI
isaxattributes_getValue(
1300 ISAXAttributes
* iface
,
1302 const WCHAR
**value
,
1305 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1306 TRACE("(%p)->(%d)\n", This
, index
);
1308 if(index
>=This
->nb_attributes
|| index
<0) return E_INVALIDARG
;
1309 if(!value
|| !nValue
) return E_POINTER
;
1311 *nValue
= SysStringLen(This
->attributes
[index
].szValue
);
1312 *value
= This
->attributes
[index
].szValue
;
1314 TRACE("(%s:%d)\n", debugstr_w(*value
), *nValue
);
1319 static HRESULT WINAPI
isaxattributes_getValueFromName(
1320 ISAXAttributes
* iface
,
1323 const WCHAR
*pLocalName
,
1325 const WCHAR
**pValue
,
1330 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1331 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), nUri
,
1332 debugstr_w(pLocalName
), nLocalName
);
1334 hr
= ISAXAttributes_getIndexFromName(iface
,
1335 pUri
, nUri
, pLocalName
, nLocalName
, &index
);
1336 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1341 static HRESULT WINAPI
isaxattributes_getValueFromQName(
1342 ISAXAttributes
* iface
,
1343 const WCHAR
*pQName
,
1345 const WCHAR
**pValue
,
1350 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1351 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQName
);
1353 hr
= ISAXAttributes_getIndexFromQName(iface
, pQName
, nQName
, &index
);
1354 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1359 static const struct ISAXAttributesVtbl isaxattributes_vtbl
=
1361 isaxattributes_QueryInterface
,
1362 isaxattributes_AddRef
,
1363 isaxattributes_Release
,
1364 isaxattributes_getLength
,
1365 isaxattributes_getURI
,
1366 isaxattributes_getLocalName
,
1367 isaxattributes_getQName
,
1368 isaxattributes_getName
,
1369 isaxattributes_getIndexFromName
,
1370 isaxattributes_getIndexFromQName
,
1371 isaxattributes_getType
,
1372 isaxattributes_getTypeFromName
,
1373 isaxattributes_getTypeFromQName
,
1374 isaxattributes_getValue
,
1375 isaxattributes_getValueFromName
,
1376 isaxattributes_getValueFromQName
1379 /* Libxml2 escapes '&' back to char reference '&' in attribute value,
1380 so when document has escaped value with '&' it's parsed to '&' and then
1381 escaped to '&'. This function takes care of ampersands only. */
1382 static BSTR
saxreader_get_unescaped_value(const xmlChar
*buf
, int len
)
1384 static const WCHAR ampescW
[] = {'&','#','3','8',';',0};
1385 WCHAR
*dest
, *ptrW
, *str
;
1392 str_len
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
1393 if (len
!= -1) str_len
++;
1395 str
= heap_alloc(str_len
*sizeof(WCHAR
));
1396 if (!str
) return NULL
;
1398 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, str
, str_len
);
1399 if (len
!= -1) str
[str_len
-1] = 0;
1402 while ((dest
= strstrW(ptrW
, ampescW
)))
1406 /* leave first '&' from a reference as a value */
1407 src
= dest
+ (sizeof(ampescW
)/sizeof(WCHAR
) - 1);
1410 /* move together with null terminator */
1411 memmove(dest
, src
, (strlenW(src
) + 1)*sizeof(WCHAR
));
1416 bstr
= SysAllocString(str
);
1422 static HRESULT
SAXAttributes_populate(saxlocator
*locator
,
1423 int nb_namespaces
, const xmlChar
**xmlNamespaces
,
1424 int nb_attributes
, const xmlChar
**xmlAttributes
)
1426 static const xmlChar xmlns
[] = "xmlns";
1427 static const WCHAR xmlnsW
[] = { 'x','m','l','n','s',0 };
1429 struct _attributes
*attrs
;
1432 /* skip namespace definitions */
1433 if ((locator
->saxreader
->features
& NamespacePrefixes
) == 0)
1436 locator
->nb_attributes
= nb_namespaces
+ nb_attributes
;
1437 if(locator
->nb_attributes
> locator
->attributesSize
)
1439 attrs
= heap_realloc(locator
->attributes
, sizeof(struct _attributes
)*locator
->nb_attributes
*2);
1442 locator
->nb_attributes
= 0;
1443 return E_OUTOFMEMORY
;
1445 locator
->attributes
= attrs
;
1449 attrs
= locator
->attributes
;
1452 for (i
= 0; i
< nb_namespaces
; i
++)
1454 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1455 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1456 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1457 if(!xmlNamespaces
[2*i
])
1458 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1460 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1463 for (i
= 0; i
< nb_attributes
; i
++)
1465 static const xmlChar xmlA
[] = "xml";
1467 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1468 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1470 /* that's an important feature to keep same uri pointer for every reported attribute */
1471 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1473 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1474 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1475 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1],
1476 xmlAttributes
[i
*5]);
1482 /*** LibXML callbacks ***/
1483 static void libxmlStartDocument(void *ctx
)
1485 saxlocator
*This
= ctx
;
1486 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1489 if (This
->saxreader
->version
>= MSXML4
)
1491 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1492 update_position(This
, FALSE
);
1493 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1495 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1500 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1504 /* store version value, declaration has to contain version attribute */
1505 if (This
->pParserCtxt
->standalone
!= -1)
1507 SysFreeString(This
->saxreader
->xmldecl_version
);
1508 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1511 if (saxreader_has_handler(This
, SAXContentHandler
))
1513 if(This
->vbInterface
)
1514 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1516 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1518 if (sax_callback_failed(This
, hr
))
1519 format_error_message_from_id(This
, hr
);
1523 static void libxmlEndDocument(void *ctx
)
1525 saxlocator
*This
= ctx
;
1526 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1529 if (This
->saxreader
->version
>= MSXML4
) {
1530 update_position(This
, FALSE
);
1531 if(This
->column
> 1)
1539 if(This
->ret
!= S_OK
) return;
1541 if (saxreader_has_handler(This
, SAXContentHandler
))
1543 if(This
->vbInterface
)
1544 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1546 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1548 if (sax_callback_failed(This
, hr
))
1549 format_error_message_from_id(This
, hr
);
1553 static void libxmlStartElementNS(
1555 const xmlChar
*localname
,
1556 const xmlChar
*prefix
,
1559 const xmlChar
**namespaces
,
1562 const xmlChar
**attributes
)
1564 saxlocator
*This
= ctx
;
1565 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1566 element_entry
*element
;
1570 update_position(This
, TRUE
);
1571 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1573 if(This
->saxreader
->version
< MSXML4
)
1576 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1577 push_element_ns(This
, element
);
1579 if (is_namespaces_enabled(This
->saxreader
))
1583 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1585 if (This
->vbInterface
)
1586 hr
= IVBSAXContentHandler_startPrefixMapping(
1588 &element
->ns
[i
].prefix
,
1589 &element
->ns
[i
].uri
);
1591 hr
= ISAXContentHandler_startPrefixMapping(
1593 element
->ns
[i
].prefix
,
1594 SysStringLen(element
->ns
[i
].prefix
),
1596 SysStringLen(element
->ns
[i
].uri
));
1598 if (sax_callback_failed(This
, hr
))
1600 format_error_message_from_id(This
, hr
);
1606 uri
= find_element_uri(This
, URI
);
1607 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1608 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1612 if (is_namespaces_enabled(This
->saxreader
))
1613 local
= element
->local
;
1617 if (This
->vbInterface
)
1618 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1619 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1621 hr
= ISAXContentHandler_startElement(handler
->handler
,
1622 uri
, SysStringLen(uri
),
1623 local
, SysStringLen(local
),
1624 element
->qname
, SysStringLen(element
->qname
),
1625 &This
->ISAXAttributes_iface
);
1627 if (sax_callback_failed(This
, hr
))
1628 format_error_message_from_id(This
, hr
);
1632 static void libxmlEndElementNS(
1634 const xmlChar
*localname
,
1635 const xmlChar
*prefix
,
1638 saxlocator
*This
= ctx
;
1639 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1640 element_entry
*element
;
1645 update_position(This
, FALSE
);
1646 p
= This
->pParserCtxt
->input
->cur
;
1648 if (This
->saxreader
->version
>= MSXML4
)
1651 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1653 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1658 else if(*(p
-1)!='>' || *(p
-2)!='/')
1661 while(p
-2>=This
->pParserCtxt
->input
->base
1662 && *(p
-2)!='<' && *(p
-1)!='/')
1664 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1670 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1673 uri
= find_element_uri(This
, URI
);
1674 element
= pop_element_ns(This
);
1676 if (!saxreader_has_handler(This
, SAXContentHandler
))
1678 This
->nb_attributes
= 0;
1679 free_element_entry(element
);
1683 if (is_namespaces_enabled(This
->saxreader
))
1684 local
= element
->local
;
1688 if (This
->vbInterface
)
1689 hr
= IVBSAXContentHandler_endElement(
1691 &uri
, &local
, &element
->qname
);
1693 hr
= ISAXContentHandler_endElement(
1695 uri
, SysStringLen(uri
),
1696 local
, SysStringLen(local
),
1697 element
->qname
, SysStringLen(element
->qname
));
1699 This
->nb_attributes
= 0;
1701 if (sax_callback_failed(This
, hr
))
1703 format_error_message_from_id(This
, hr
);
1704 free_element_entry(element
);
1708 if (is_namespaces_enabled(This
->saxreader
))
1711 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1713 if (This
->vbInterface
)
1714 hr
= IVBSAXContentHandler_endPrefixMapping(
1715 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1717 hr
= ISAXContentHandler_endPrefixMapping(
1718 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1720 if (sax_callback_failed(This
, hr
)) break;
1723 if (sax_callback_failed(This
, hr
))
1724 format_error_message_from_id(This
, hr
);
1727 free_element_entry(element
);
1730 static void libxmlCharacters(
1735 saxlocator
*This
= ctx
;
1739 BOOL lastEvent
= FALSE
;
1741 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1743 update_position(This
, FALSE
);
1744 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1745 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1747 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1752 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1756 if(*(ch
-1)=='\r') cur
--;
1761 while(end
-ch
<len
&& *end
!='\r') end
++;
1772 if (This
->saxreader
->version
>= MSXML4
)
1776 for(p
=cur
; p
!=end
; p
++)
1793 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1794 hr
= saxreader_saxcharacters(This
, Chars
);
1796 if (sax_callback_failed(This
, hr
))
1798 format_error_message_from_id(This
, hr
);
1802 if (This
->saxreader
->version
< MSXML4
)
1803 This
->column
+= end
-cur
;
1816 if(end
-ch
== len
) break;
1820 static void libxmlSetDocumentLocator(
1822 xmlSAXLocatorPtr loc
)
1824 saxlocator
*This
= ctx
;
1825 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1828 if (saxreader_has_handler(This
, SAXContentHandler
))
1830 if(This
->vbInterface
)
1831 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1832 &This
->IVBSAXLocator_iface
);
1834 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1838 format_error_message_from_id(This
, hr
);
1841 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1843 saxlocator
*This
= ctx
;
1844 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1847 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1849 update_position(This
, FALSE
);
1850 while(p
-4>=This
->pParserCtxt
->input
->base
1851 && memcmp(p
-4, "<!--", sizeof(char[4])))
1853 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1859 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1862 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1864 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1866 if (This
->vbInterface
)
1867 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1869 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1872 format_error_message_from_id(This
, hr
);
1875 static void libxmlFatalError(void *ctx
, const char *msg
, ...)
1877 saxlocator
*This
= ctx
;
1878 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1884 if(This
->ret
!= S_OK
) {
1885 xmlStopParser(This
->pParserCtxt
);
1889 va_start(args
, msg
);
1890 vsprintf(message
, msg
, args
);
1893 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1894 error
= heap_alloc(sizeof(WCHAR
)*len
);
1897 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1898 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1901 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1903 xmlStopParser(This
->pParserCtxt
);
1909 FIXME("Error handling is not compatible.\n");
1911 if(This
->vbInterface
)
1913 BSTR bstrError
= SysAllocString(error
);
1914 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1915 &bstrError
, E_FAIL
);
1916 SysFreeString(bstrError
);
1919 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1923 xmlStopParser(This
->pParserCtxt
);
1927 /* The only reason this helper exists is that CDATA section are reported by chunks,
1928 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1930 This helper should be called for substring with trailing newlines.
1932 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1934 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1937 ptr
= bstr
+ len
- 1;
1938 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1943 /* replace returns as:
1945 - "\r<char>" -> "\n<char>"
1951 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
1954 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
1961 ret
= SysAllocStringLen(bstr
, len
);
1962 SysFreeString(bstr
);
1966 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
1968 const xmlChar
*start
, *end
;
1969 saxlocator
*locator
= ctx
;
1970 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
1975 update_position(locator
, FALSE
);
1976 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
1978 if (locator
->vbInterface
)
1979 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
1981 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
1986 format_error_message_from_id(locator
, hr
);
1996 /* scan for newlines */
1997 if (value
[i
] == '\r' || value
[i
] == '\n')
1999 /* skip newlines/linefeeds */
2002 if (value
[i
] != '\r' && value
[i
] != '\n') break;
2008 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
2009 TRACE("(chunk %s)\n", debugstr_w(chars
));
2010 hr
= saxreader_saxcharacters(locator
, chars
);
2011 SysFreeString(chars
);
2020 /* no newline chars (or last chunk) report as a whole */
2021 if (!end
&& start
== value
)
2024 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
2025 TRACE("(%s)\n", debugstr_w(chars
));
2026 hr
= saxreader_saxcharacters(locator
, chars
);
2027 SysFreeString(chars
);
2030 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2032 if (locator
->vbInterface
)
2033 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
2035 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
2039 format_error_message_from_id(locator
, hr
);
2042 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
2044 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
2045 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
2048 /*** IVBSAXLocator interface ***/
2049 /*** IUnknown methods ***/
2050 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2052 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2054 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2058 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2059 IsEqualGUID( riid
, &IID_IDispatch
) ||
2060 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
2064 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
2066 *ppvObject
= &This
->IVBSAXAttributes_iface
;
2070 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2071 return E_NOINTERFACE
;
2074 IVBSAXLocator_AddRef( iface
);
2079 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
2081 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2082 TRACE("%p\n", This
);
2083 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
2086 static ULONG WINAPI
ivbsaxlocator_Release(IVBSAXLocator
* iface
)
2088 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2089 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
2092 /*** IDispatch methods ***/
2093 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
2095 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2097 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2104 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
2105 IVBSAXLocator
*iface
,
2106 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2108 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2110 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2112 return get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2115 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2116 IVBSAXLocator
*iface
,
2118 LPOLESTR
* rgszNames
,
2123 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2124 ITypeInfo
*typeinfo
;
2127 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
2130 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2131 return E_INVALIDARG
;
2133 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2136 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2137 ITypeInfo_Release(typeinfo
);
2143 static HRESULT WINAPI
ivbsaxlocator_Invoke(
2144 IVBSAXLocator
*iface
,
2145 DISPID dispIdMember
,
2149 DISPPARAMS
* pDispParams
,
2150 VARIANT
* pVarResult
,
2151 EXCEPINFO
* pExcepInfo
,
2154 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2155 ITypeInfo
*typeinfo
;
2158 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2159 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2161 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2164 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXLocator_iface
, dispIdMember
, wFlags
,
2165 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2166 ITypeInfo_Release(typeinfo
);
2172 /*** IVBSAXLocator methods ***/
2173 static HRESULT WINAPI
ivbsaxlocator_get_columnNumber(
2174 IVBSAXLocator
* iface
,
2177 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2178 return ISAXLocator_getColumnNumber(&This
->ISAXLocator_iface
, pnColumn
);
2181 static HRESULT WINAPI
ivbsaxlocator_get_lineNumber(
2182 IVBSAXLocator
* iface
,
2185 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2186 return ISAXLocator_getLineNumber(&This
->ISAXLocator_iface
, pnLine
);
2189 static HRESULT WINAPI
ivbsaxlocator_get_publicId(IVBSAXLocator
* iface
, BSTR
*ret
)
2191 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2192 const WCHAR
*publicidW
;
2195 TRACE("(%p)->(%p)\n", This
, ret
);
2201 hr
= ISAXLocator_getPublicId(&This
->ISAXLocator_iface
, &publicidW
);
2205 return return_bstr(publicidW
, ret
);
2208 static HRESULT WINAPI
ivbsaxlocator_get_systemId(IVBSAXLocator
* iface
, BSTR
*ret
)
2210 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2211 const WCHAR
*systemidW
;
2214 TRACE("(%p)->(%p)\n", This
, ret
);
2220 hr
= ISAXLocator_getSystemId(&This
->ISAXLocator_iface
, &systemidW
);
2224 return return_bstr(systemidW
, ret
);
2227 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl
=
2229 ivbsaxlocator_QueryInterface
,
2230 ivbsaxlocator_AddRef
,
2231 ivbsaxlocator_Release
,
2232 ivbsaxlocator_GetTypeInfoCount
,
2233 ivbsaxlocator_GetTypeInfo
,
2234 ivbsaxlocator_GetIDsOfNames
,
2235 ivbsaxlocator_Invoke
,
2236 ivbsaxlocator_get_columnNumber
,
2237 ivbsaxlocator_get_lineNumber
,
2238 ivbsaxlocator_get_publicId
,
2239 ivbsaxlocator_get_systemId
2242 /*** ISAXLocator interface ***/
2243 /*** IUnknown methods ***/
2244 static HRESULT WINAPI
isaxlocator_QueryInterface(ISAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2246 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2248 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2252 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2253 IsEqualGUID( riid
, &IID_ISAXLocator
))
2257 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
2259 *ppvObject
= &This
->ISAXAttributes_iface
;
2263 WARN("interface %s not implemented\n", debugstr_guid(riid
));
2264 return E_NOINTERFACE
;
2267 ISAXLocator_AddRef( iface
);
2272 static ULONG WINAPI
isaxlocator_AddRef(ISAXLocator
* iface
)
2274 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2275 ULONG ref
= InterlockedIncrement( &This
->ref
);
2276 TRACE("(%p)->(%d)\n", This
, ref
);
2280 static ULONG WINAPI
isaxlocator_Release(
2283 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2284 LONG ref
= InterlockedDecrement( &This
->ref
);
2286 TRACE("(%p)->(%d)\n", This
, ref
);
2290 element_entry
*element
, *element2
;
2293 SysFreeString(This
->publicId
);
2294 SysFreeString(This
->systemId
);
2295 SysFreeString(This
->namespaceUri
);
2297 for(index
=0; index
<This
->nb_attributes
; index
++)
2299 SysFreeString(This
->attributes
[index
].szLocalname
);
2300 SysFreeString(This
->attributes
[index
].szValue
);
2301 SysFreeString(This
->attributes
[index
].szQName
);
2303 heap_free(This
->attributes
);
2306 LIST_FOR_EACH_ENTRY_SAFE(element
, element2
, &This
->elements
, element_entry
, entry
)
2308 list_remove(&element
->entry
);
2309 free_element_entry(element
);
2312 ISAXXMLReader_Release(&This
->saxreader
->ISAXXMLReader_iface
);
2319 /*** ISAXLocator methods ***/
2320 static HRESULT WINAPI
isaxlocator_getColumnNumber(
2324 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2326 *pnColumn
= This
->column
;
2330 static HRESULT WINAPI
isaxlocator_getLineNumber(
2334 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2336 *pnLine
= This
->line
;
2340 static HRESULT WINAPI
isaxlocator_getPublicId(
2342 const WCHAR
** ppwchPublicId
)
2345 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2347 SysFreeString(This
->publicId
);
2349 publicId
= bstr_from_xmlChar(xmlSAX2GetPublicId(This
->pParserCtxt
));
2350 if(SysStringLen(publicId
))
2351 This
->publicId
= publicId
;
2354 SysFreeString(publicId
);
2355 This
->publicId
= NULL
;
2358 *ppwchPublicId
= This
->publicId
;
2362 static HRESULT WINAPI
isaxlocator_getSystemId(
2364 const WCHAR
** ppwchSystemId
)
2367 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2369 SysFreeString(This
->systemId
);
2371 systemId
= bstr_from_xmlChar(xmlSAX2GetSystemId(This
->pParserCtxt
));
2372 if(SysStringLen(systemId
))
2373 This
->systemId
= systemId
;
2376 SysFreeString(systemId
);
2377 This
->systemId
= NULL
;
2380 *ppwchSystemId
= This
->systemId
;
2384 static const struct ISAXLocatorVtbl SAXLocatorVtbl
=
2386 isaxlocator_QueryInterface
,
2388 isaxlocator_Release
,
2389 isaxlocator_getColumnNumber
,
2390 isaxlocator_getLineNumber
,
2391 isaxlocator_getPublicId
,
2392 isaxlocator_getSystemId
2395 static HRESULT
SAXLocator_create(saxreader
*reader
, saxlocator
**ppsaxlocator
, BOOL vbInterface
)
2397 static const WCHAR w3xmlns
[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2398 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2400 saxlocator
*locator
;
2402 locator
= heap_alloc( sizeof (*locator
) );
2404 return E_OUTOFMEMORY
;
2406 locator
->IVBSAXLocator_iface
.lpVtbl
= &VBSAXLocatorVtbl
;
2407 locator
->ISAXLocator_iface
.lpVtbl
= &SAXLocatorVtbl
;
2408 locator
->IVBSAXAttributes_iface
.lpVtbl
= &ivbsaxattributes_vtbl
;
2409 locator
->ISAXAttributes_iface
.lpVtbl
= &isaxattributes_vtbl
;
2411 locator
->vbInterface
= vbInterface
;
2413 locator
->saxreader
= reader
;
2414 ISAXXMLReader_AddRef(&reader
->ISAXXMLReader_iface
);
2416 locator
->pParserCtxt
= NULL
;
2417 locator
->publicId
= NULL
;
2418 locator
->systemId
= NULL
;
2419 locator
->line
= reader
->version
< MSXML4
? 0 : 1;
2420 locator
->column
= 0;
2421 locator
->ret
= S_OK
;
2422 if (locator
->saxreader
->version
>= MSXML6
)
2423 locator
->namespaceUri
= SysAllocString(w3xmlns
);
2425 locator
->namespaceUri
= SysAllocStringLen(NULL
, 0);
2426 if(!locator
->namespaceUri
)
2428 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2430 return E_OUTOFMEMORY
;
2433 locator
->attributesSize
= 8;
2434 locator
->nb_attributes
= 0;
2435 locator
->attributes
= heap_alloc(sizeof(struct _attributes
)*locator
->attributesSize
);
2436 if(!locator
->attributes
)
2438 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2439 SysFreeString(locator
->namespaceUri
);
2441 return E_OUTOFMEMORY
;
2444 list_init(&locator
->elements
);
2446 *ppsaxlocator
= locator
;
2448 TRACE("returning %p\n", *ppsaxlocator
);
2453 /*** SAXXMLReader internal functions ***/
2454 static HRESULT
internal_parseBuffer(saxreader
*This
, const char *buffer
, int size
, BOOL vbInterface
)
2456 xmlCharEncoding encoding
= XML_CHAR_ENCODING_NONE
;
2457 xmlChar
*enc_name
= NULL
;
2458 saxlocator
*locator
;
2461 TRACE("(%p)->(%p %d)\n", This
, buffer
, size
);
2463 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2469 const unsigned char *buff
= (unsigned char*)buffer
;
2471 encoding
= xmlDetectCharEncoding((xmlChar
*)buffer
, 4);
2472 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2473 TRACE("detected encoding: %s\n", enc_name
);
2474 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2475 if ((encoding
== XML_CHAR_ENCODING_UTF8
) &&
2476 buff
[0] == 0xEF && buff
[1] == 0xBB && buff
[2] == 0xBF)
2483 /* if libxml2 detection failed try to guess */
2484 if (encoding
== XML_CHAR_ENCODING_NONE
)
2486 const WCHAR
*ptr
= (WCHAR
*)buffer
;
2487 /* xml declaration with possibly specfied encoding will be still handled by parser */
2488 if ((size
>= 2) && *ptr
== '<' && ptr
[1] != '?')
2490 enc_name
= (xmlChar
*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE
);
2491 encoding
= XML_CHAR_ENCODING_UTF16LE
;
2494 else if (encoding
== XML_CHAR_ENCODING_UTF8
)
2495 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2499 locator
->pParserCtxt
= xmlCreateMemoryParserCtxt(buffer
, size
);
2500 if (!locator
->pParserCtxt
)
2502 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2508 locator
->pParserCtxt
->encoding
= xmlStrdup(enc_name
);
2509 if (encoding
== XML_CHAR_ENCODING_UTF16LE
) {
2510 TRACE("switching to %s\n", enc_name
);
2511 xmlSwitchEncoding(locator
->pParserCtxt
, encoding
);
2515 xmlFree(locator
->pParserCtxt
->sax
);
2516 locator
->pParserCtxt
->sax
= &locator
->saxreader
->sax
;
2517 locator
->pParserCtxt
->userData
= locator
;
2519 This
->isParsing
= TRUE
;
2520 if(xmlParseDocument(locator
->pParserCtxt
) == -1 && locator
->ret
== S_OK
)
2524 This
->isParsing
= FALSE
;
2526 if(locator
->pParserCtxt
)
2528 locator
->pParserCtxt
->sax
= NULL
;
2529 xmlFreeParserCtxt(locator
->pParserCtxt
);
2530 locator
->pParserCtxt
= NULL
;
2533 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2537 static HRESULT
internal_parseStream(saxreader
*This
, ISequentialStream
*stream
, BOOL vbInterface
)
2539 saxlocator
*locator
;
2546 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2547 if(FAILED(hr
)) return hr
;
2549 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2550 if(FAILED(hr
)) return hr
;
2552 locator
->pParserCtxt
= xmlCreatePushParserCtxt(
2553 &locator
->saxreader
->sax
, locator
,
2554 data
, dataRead
, NULL
);
2555 if(!locator
->pParserCtxt
)
2557 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2561 This
->isParsing
= TRUE
;
2565 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2566 if (FAILED(hr
) || !dataRead
) break;
2568 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, dataRead
, 0);
2569 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2574 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2575 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2579 This
->isParsing
= FALSE
;
2581 xmlFreeParserCtxt(locator
->pParserCtxt
);
2582 locator
->pParserCtxt
= NULL
;
2583 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2587 static HRESULT
internal_parse(
2594 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varInput
));
2596 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2597 free_bstr_pool(&This
->pool
);
2599 switch(V_VT(&varInput
))
2602 case VT_BSTR
|VT_BYREF
:
2604 BSTR str
= V_ISBYREF(&varInput
) ? *V_BSTRREF(&varInput
) : V_BSTR(&varInput
);
2605 hr
= internal_parseBuffer(This
, (const char*)str
, strlenW(str
)*sizeof(WCHAR
), vbInterface
);
2608 case VT_ARRAY
|VT_UI1
: {
2610 LONG lBound
, uBound
;
2613 hr
= SafeArrayGetLBound(V_ARRAY(&varInput
), 1, &lBound
);
2614 if(hr
!= S_OK
) break;
2615 hr
= SafeArrayGetUBound(V_ARRAY(&varInput
), 1, &uBound
);
2616 if(hr
!= S_OK
) break;
2617 dataRead
= (uBound
-lBound
)*SafeArrayGetElemsize(V_ARRAY(&varInput
));
2618 hr
= SafeArrayAccessData(V_ARRAY(&varInput
), &pSAData
);
2619 if(hr
!= S_OK
) break;
2620 hr
= internal_parseBuffer(This
, pSAData
, dataRead
, vbInterface
);
2621 SafeArrayUnaccessData(V_ARRAY(&varInput
));
2626 IPersistStream
*persistStream
;
2627 ISequentialStream
*stream
= NULL
;
2628 IXMLDOMDocument
*xmlDoc
;
2630 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2631 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2635 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2636 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2637 SysStringByteLen(bstrData
), vbInterface
);
2638 IXMLDOMDocument_Release(xmlDoc
);
2639 SysFreeString(bstrData
);
2643 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2644 &IID_IPersistStream
, (void**)&persistStream
) == S_OK
)
2646 IStream
*stream_copy
;
2648 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream_copy
);
2651 IPersistStream_Release(persistStream
);
2655 hr
= IPersistStream_Save(persistStream
, stream_copy
, TRUE
);
2656 IPersistStream_Release(persistStream
);
2658 IStream_QueryInterface(stream_copy
, &IID_ISequentialStream
, (void**)&stream
);
2660 IStream_Release(stream_copy
);
2663 /* try base interface first */
2666 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2668 /* this should never happen if IStream is implemented properly, but just in case */
2669 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2674 hr
= internal_parseStream(This
, stream
, vbInterface
);
2675 ISequentialStream_Release(stream
);
2679 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2686 WARN("vt %d not implemented\n", V_VT(&varInput
));
2693 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2695 saxreader
*This
= obj
;
2697 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2700 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2702 saxreader
*This
= obj
;
2704 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2707 static HRESULT
internal_parseURL(
2716 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
2718 hr
= create_moniker_from_url(url
, &mon
);
2722 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, This
, &bsc
);
2723 else hr
= bind_url(mon
, internal_onDataAvailable
, This
, &bsc
);
2724 IMoniker_Release(mon
);
2729 return detach_bsc(bsc
);
2732 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2736 if (V_VT(v
) == VT_EMPTY
)
2737 return saxreader_put_handler(This
, type
, NULL
, vb
);
2741 case SAXDeclHandler
:
2742 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2744 case SAXLexicalHandler
:
2745 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2748 ERR("wrong handler type %d\n", type
);
2757 IUnknown
*handler
= NULL
;
2761 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2762 if (FAILED(hr
)) return hr
;
2765 saxreader_put_handler(This
, type
, handler
, vb
);
2766 if (handler
) IUnknown_Release(handler
);
2770 ERR("value type %d not supported\n", V_VT(v
));
2771 return E_INVALIDARG
;
2777 static HRESULT
internal_putProperty(
2785 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2787 if (This
->isParsing
) return E_FAIL
;
2789 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2790 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2791 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2793 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2794 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2796 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2798 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2799 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2803 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2805 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2806 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2810 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2812 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2815 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2818 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2821 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2824 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2827 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2830 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2833 return E_INVALIDARG
;
2836 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2838 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2840 if (!value
) return E_POINTER
;
2842 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2844 V_VT(value
) = VT_UNKNOWN
;
2845 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2849 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2851 V_VT(value
) = VT_UNKNOWN
;
2852 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2856 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2858 V_VT(value
) = VT_BSTR
;
2859 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2863 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2868 /*** IVBSAXXMLReader interface ***/
2869 /*** IUnknown methods ***/
2870 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2872 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2874 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2878 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2879 IsEqualGUID( riid
, &IID_IDispatch
) ||
2880 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2884 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2886 *ppvObject
= &This
->ISAXXMLReader_iface
;
2888 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2890 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2894 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2895 return E_NOINTERFACE
;
2898 IVBSAXXMLReader_AddRef( iface
);
2903 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2905 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2906 TRACE("%p\n", This
);
2907 return InterlockedIncrement( &This
->ref
);
2910 static ULONG WINAPI
saxxmlreader_Release(
2911 IVBSAXXMLReader
* iface
)
2913 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2916 TRACE("%p\n", This
);
2918 ref
= InterlockedDecrement( &This
->ref
);
2923 for (i
= 0; i
< SAXHandler_Last
; i
++)
2925 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2927 if (saxiface
->handler
)
2928 IUnknown_Release(saxiface
->handler
);
2930 if (saxiface
->vbhandler
)
2931 IUnknown_Release(saxiface
->vbhandler
);
2934 SysFreeString(This
->xmldecl_version
);
2935 free_bstr_pool(&This
->pool
);
2943 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2945 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2946 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2949 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2950 IVBSAXXMLReader
*iface
,
2951 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2953 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2954 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2955 iTInfo
, lcid
, ppTInfo
);
2958 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2959 IVBSAXXMLReader
*iface
,
2961 LPOLESTR
* rgszNames
,
2966 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2967 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
2968 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
2971 static HRESULT WINAPI
saxxmlreader_Invoke(
2972 IVBSAXXMLReader
*iface
,
2973 DISPID dispIdMember
,
2977 DISPPARAMS
* pDispParams
,
2978 VARIANT
* pVarResult
,
2979 EXCEPINFO
* pExcepInfo
,
2982 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2983 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
2984 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2987 /*** IVBSAXXMLReader methods ***/
2988 static HRESULT WINAPI
saxxmlreader_getFeature(
2989 IVBSAXXMLReader
* iface
,
2991 VARIANT_BOOL
*value
)
2993 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2994 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
2997 static HRESULT WINAPI
saxxmlreader_putFeature(
2998 IVBSAXXMLReader
* iface
,
3002 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3003 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3006 static HRESULT WINAPI
saxxmlreader_getProperty(
3007 IVBSAXXMLReader
* iface
,
3011 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3012 return internal_getProperty(This
, prop
, value
, TRUE
);
3015 static HRESULT WINAPI
saxxmlreader_putProperty(
3016 IVBSAXXMLReader
* iface
,
3020 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3021 return internal_putProperty(This
, pProp
, value
, TRUE
);
3024 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3025 IVBSAXXMLReader
* iface
,
3026 IVBSAXEntityResolver
**resolver
)
3028 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3029 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3032 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3033 IVBSAXXMLReader
* iface
,
3034 IVBSAXEntityResolver
*resolver
)
3036 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3037 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3040 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3041 IVBSAXXMLReader
* iface
,
3042 IVBSAXContentHandler
**handler
)
3044 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3045 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3048 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3049 IVBSAXXMLReader
* iface
,
3050 IVBSAXContentHandler
*handler
)
3052 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3053 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3056 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3057 IVBSAXXMLReader
* iface
,
3058 IVBSAXDTDHandler
**handler
)
3060 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3061 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3064 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3065 IVBSAXXMLReader
* iface
,
3066 IVBSAXDTDHandler
*handler
)
3068 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3069 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3072 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3073 IVBSAXXMLReader
* iface
,
3074 IVBSAXErrorHandler
**handler
)
3076 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3077 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3080 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3081 IVBSAXXMLReader
* iface
,
3082 IVBSAXErrorHandler
*handler
)
3084 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3085 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3088 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3089 IVBSAXXMLReader
* iface
,
3092 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3094 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3098 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3099 IVBSAXXMLReader
* iface
,
3102 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3103 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3106 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3107 IVBSAXXMLReader
* iface
,
3108 BSTR
*pSecureBaseUrl
)
3110 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3112 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3116 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3117 IVBSAXXMLReader
* iface
,
3120 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3121 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3124 static HRESULT WINAPI
saxxmlreader_parse(
3125 IVBSAXXMLReader
* iface
,
3128 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3129 return internal_parse(This
, varInput
, TRUE
);
3132 static HRESULT WINAPI
saxxmlreader_parseURL(
3133 IVBSAXXMLReader
* iface
,
3136 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3137 return internal_parseURL(This
, url
, TRUE
);
3140 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3142 saxxmlreader_QueryInterface
,
3143 saxxmlreader_AddRef
,
3144 saxxmlreader_Release
,
3145 saxxmlreader_GetTypeInfoCount
,
3146 saxxmlreader_GetTypeInfo
,
3147 saxxmlreader_GetIDsOfNames
,
3148 saxxmlreader_Invoke
,
3149 saxxmlreader_getFeature
,
3150 saxxmlreader_putFeature
,
3151 saxxmlreader_getProperty
,
3152 saxxmlreader_putProperty
,
3153 saxxmlreader_get_entityResolver
,
3154 saxxmlreader_put_entityResolver
,
3155 saxxmlreader_get_contentHandler
,
3156 saxxmlreader_put_contentHandler
,
3157 saxxmlreader_get_dtdHandler
,
3158 saxxmlreader_put_dtdHandler
,
3159 saxxmlreader_get_errorHandler
,
3160 saxxmlreader_put_errorHandler
,
3161 saxxmlreader_get_baseURL
,
3162 saxxmlreader_put_baseURL
,
3163 saxxmlreader_get_secureBaseURL
,
3164 saxxmlreader_put_secureBaseURL
,
3166 saxxmlreader_parseURL
3169 /*** ISAXXMLReader interface ***/
3170 /*** IUnknown methods ***/
3171 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3173 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3174 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3177 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3179 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3180 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3183 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3185 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3186 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3189 /*** ISAXXMLReader methods ***/
3190 static HRESULT WINAPI
isaxxmlreader_getFeature(
3191 ISAXXMLReader
* iface
,
3192 const WCHAR
*feature_name
,
3193 VARIANT_BOOL
*value
)
3195 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3196 saxreader_feature feature
;
3198 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3200 feature
= get_saxreader_feature(feature_name
);
3201 if (feature
== Namespaces
|| feature
== NamespacePrefixes
)
3202 return get_feature_value(This
, feature
, value
);
3204 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3208 static HRESULT WINAPI
isaxxmlreader_putFeature(
3209 ISAXXMLReader
* iface
,
3210 const WCHAR
*feature_name
,
3213 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3214 saxreader_feature feature
;
3216 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3218 feature
= get_saxreader_feature(feature_name
);
3220 /* accepted cases */
3221 if ((feature
== ExternalGeneralEntities
&& value
== VARIANT_FALSE
) ||
3222 (feature
== ExternalParameterEntities
&& value
== VARIANT_FALSE
) ||
3223 feature
== Namespaces
||
3224 feature
== NamespacePrefixes
)
3226 return set_feature_value(This
, feature
, value
);
3229 if (feature
== LexicalHandlerParEntities
|| feature
== ProhibitDTD
)
3231 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3232 return set_feature_value(This
, feature
, value
);
3235 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3239 static HRESULT WINAPI
isaxxmlreader_getProperty(
3240 ISAXXMLReader
* iface
,
3244 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3245 return internal_getProperty(This
, prop
, value
, FALSE
);
3248 static HRESULT WINAPI
isaxxmlreader_putProperty(
3249 ISAXXMLReader
* iface
,
3253 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3254 return internal_putProperty(This
, pProp
, value
, FALSE
);
3257 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3258 ISAXXMLReader
* iface
,
3259 ISAXEntityResolver
**resolver
)
3261 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3262 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3265 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3266 ISAXXMLReader
* iface
,
3267 ISAXEntityResolver
*resolver
)
3269 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3270 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3273 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3274 ISAXXMLReader
* iface
,
3275 ISAXContentHandler
**handler
)
3277 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3278 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3281 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3282 ISAXXMLReader
* iface
,
3283 ISAXContentHandler
*handler
)
3285 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3286 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3289 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3290 ISAXXMLReader
* iface
,
3291 ISAXDTDHandler
**handler
)
3293 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3294 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3297 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3298 ISAXXMLReader
* iface
,
3299 ISAXDTDHandler
*handler
)
3301 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3302 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3305 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3306 ISAXXMLReader
* iface
,
3307 ISAXErrorHandler
**handler
)
3309 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3310 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3313 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3315 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3316 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3319 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3320 ISAXXMLReader
* iface
,
3321 const WCHAR
**base_url
)
3323 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3325 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3329 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3330 ISAXXMLReader
* iface
,
3331 const WCHAR
*pBaseUrl
)
3333 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3335 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3339 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3340 ISAXXMLReader
* iface
,
3341 const WCHAR
**pSecureBaseUrl
)
3343 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3344 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3348 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3349 ISAXXMLReader
* iface
,
3350 const WCHAR
*secureBaseUrl
)
3352 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3354 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3358 static HRESULT WINAPI
isaxxmlreader_parse(
3359 ISAXXMLReader
* iface
,
3362 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3363 return internal_parse(This
, varInput
, FALSE
);
3366 static HRESULT WINAPI
isaxxmlreader_parseURL(
3367 ISAXXMLReader
* iface
,
3370 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3371 return internal_parseURL(This
, url
, FALSE
);
3374 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3376 isaxxmlreader_QueryInterface
,
3377 isaxxmlreader_AddRef
,
3378 isaxxmlreader_Release
,
3379 isaxxmlreader_getFeature
,
3380 isaxxmlreader_putFeature
,
3381 isaxxmlreader_getProperty
,
3382 isaxxmlreader_putProperty
,
3383 isaxxmlreader_getEntityResolver
,
3384 isaxxmlreader_putEntityResolver
,
3385 isaxxmlreader_getContentHandler
,
3386 isaxxmlreader_putContentHandler
,
3387 isaxxmlreader_getDTDHandler
,
3388 isaxxmlreader_putDTDHandler
,
3389 isaxxmlreader_getErrorHandler
,
3390 isaxxmlreader_putErrorHandler
,
3391 isaxxmlreader_getBaseURL
,
3392 isaxxmlreader_putBaseURL
,
3393 isaxxmlreader_getSecureBaseURL
,
3394 isaxxmlreader_putSecureBaseURL
,
3395 isaxxmlreader_parse
,
3396 isaxxmlreader_parseURL
3399 static const tid_t saxreader_iface_tids
[] = {
3400 IVBSAXXMLReader_tid
,
3403 static dispex_static_data_t saxreader_dispex
= {
3405 IVBSAXXMLReader_tid
,
3407 saxreader_iface_tids
3410 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3414 TRACE("(%p)\n", ppObj
);
3416 reader
= heap_alloc( sizeof (*reader
) );
3418 return E_OUTOFMEMORY
;
3420 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3421 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3423 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3424 reader
->isParsing
= FALSE
;
3425 reader
->xmldecl_version
= NULL
;
3426 reader
->pool
.pool
= NULL
;
3427 reader
->pool
.index
= 0;
3428 reader
->pool
.len
= 0;
3429 reader
->features
= Namespaces
| NamespacePrefixes
;
3430 reader
->version
= version
;
3432 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3434 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3435 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3436 reader
->sax
.startDocument
= libxmlStartDocument
;
3437 reader
->sax
.endDocument
= libxmlEndDocument
;
3438 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3439 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3440 reader
->sax
.characters
= libxmlCharacters
;
3441 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3442 reader
->sax
.comment
= libxmlComment
;
3443 reader
->sax
.error
= libxmlFatalError
;
3444 reader
->sax
.fatalError
= libxmlFatalError
;
3445 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3446 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3448 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3450 TRACE("returning iface %p\n", *ppObj
);
3457 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3459 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3460 "libxml2 support was not present at compile time.\n");