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 void free_attribute_values(saxlocator
*locator
)
1426 for (i
= 0; i
< locator
->nb_attributes
; i
++)
1428 SysFreeString(locator
->attributes
[i
].szLocalname
);
1429 locator
->attributes
[i
].szLocalname
= NULL
;
1431 SysFreeString(locator
->attributes
[i
].szValue
);
1432 locator
->attributes
[i
].szValue
= NULL
;
1434 SysFreeString(locator
->attributes
[i
].szQName
);
1435 locator
->attributes
[i
].szQName
= NULL
;
1439 static HRESULT
SAXAttributes_populate(saxlocator
*locator
,
1440 int nb_namespaces
, const xmlChar
**xmlNamespaces
,
1441 int nb_attributes
, const xmlChar
**xmlAttributes
)
1443 static const xmlChar xmlns
[] = "xmlns";
1444 static const WCHAR xmlnsW
[] = { 'x','m','l','n','s',0 };
1446 struct _attributes
*attrs
;
1449 /* skip namespace definitions */
1450 if ((locator
->saxreader
->features
& NamespacePrefixes
) == 0)
1453 locator
->nb_attributes
= nb_namespaces
+ nb_attributes
;
1454 if(locator
->nb_attributes
> locator
->attributesSize
)
1456 int new_size
= locator
->attributesSize
* 2;
1457 attrs
= heap_realloc_zero(locator
->attributes
, new_size
* sizeof(struct _attributes
));
1460 free_attribute_values(locator
);
1461 locator
->nb_attributes
= 0;
1462 return E_OUTOFMEMORY
;
1464 locator
->attributes
= attrs
;
1465 locator
->attributesSize
= new_size
;
1469 attrs
= locator
->attributes
;
1472 for (i
= 0; i
< nb_namespaces
; i
++)
1474 SysFreeString(attrs
[nb_attributes
+i
].szLocalname
);
1475 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1477 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1479 SysFreeString(attrs
[nb_attributes
+i
].szValue
);
1480 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1482 SysFreeString(attrs
[nb_attributes
+i
].szQName
);
1483 if(!xmlNamespaces
[2*i
])
1484 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1486 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1489 for (i
= 0; i
< nb_attributes
; i
++)
1491 static const xmlChar xmlA
[] = "xml";
1493 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1494 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1496 /* that's an important feature to keep same uri pointer for every reported attribute */
1497 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1499 SysFreeString(attrs
[i
].szLocalname
);
1500 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1502 SysFreeString(attrs
[i
].szValue
);
1503 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1505 SysFreeString(attrs
[i
].szQName
);
1506 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1], xmlAttributes
[i
*5]);
1512 /*** LibXML callbacks ***/
1513 static void libxmlStartDocument(void *ctx
)
1515 saxlocator
*This
= ctx
;
1516 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1519 if (This
->saxreader
->version
>= MSXML4
)
1521 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1522 update_position(This
, FALSE
);
1523 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1525 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1530 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1534 /* store version value, declaration has to contain version attribute */
1535 if (This
->pParserCtxt
->standalone
!= -1)
1537 SysFreeString(This
->saxreader
->xmldecl_version
);
1538 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1541 if (saxreader_has_handler(This
, SAXContentHandler
))
1543 if(This
->vbInterface
)
1544 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1546 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1548 if (sax_callback_failed(This
, hr
))
1549 format_error_message_from_id(This
, hr
);
1553 static void libxmlEndDocument(void *ctx
)
1555 saxlocator
*This
= ctx
;
1556 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1559 if (This
->saxreader
->version
>= MSXML4
) {
1560 update_position(This
, FALSE
);
1561 if(This
->column
> 1)
1569 if(This
->ret
!= S_OK
) return;
1571 if (saxreader_has_handler(This
, SAXContentHandler
))
1573 if(This
->vbInterface
)
1574 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1576 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1578 if (sax_callback_failed(This
, hr
))
1579 format_error_message_from_id(This
, hr
);
1583 static void libxmlStartElementNS(
1585 const xmlChar
*localname
,
1586 const xmlChar
*prefix
,
1589 const xmlChar
**namespaces
,
1592 const xmlChar
**attributes
)
1594 saxlocator
*This
= ctx
;
1595 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1596 element_entry
*element
;
1600 update_position(This
, TRUE
);
1601 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1603 if(This
->saxreader
->version
< MSXML4
)
1606 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1607 push_element_ns(This
, element
);
1609 if (is_namespaces_enabled(This
->saxreader
))
1613 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1615 if (This
->vbInterface
)
1616 hr
= IVBSAXContentHandler_startPrefixMapping(
1618 &element
->ns
[i
].prefix
,
1619 &element
->ns
[i
].uri
);
1621 hr
= ISAXContentHandler_startPrefixMapping(
1623 element
->ns
[i
].prefix
,
1624 SysStringLen(element
->ns
[i
].prefix
),
1626 SysStringLen(element
->ns
[i
].uri
));
1628 if (sax_callback_failed(This
, hr
))
1630 format_error_message_from_id(This
, hr
);
1636 uri
= find_element_uri(This
, URI
);
1637 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1638 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1642 if (is_namespaces_enabled(This
->saxreader
))
1643 local
= element
->local
;
1647 if (This
->vbInterface
)
1648 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1649 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1651 hr
= ISAXContentHandler_startElement(handler
->handler
,
1652 uri
, SysStringLen(uri
),
1653 local
, SysStringLen(local
),
1654 element
->qname
, SysStringLen(element
->qname
),
1655 &This
->ISAXAttributes_iface
);
1657 if (sax_callback_failed(This
, hr
))
1658 format_error_message_from_id(This
, hr
);
1662 static void libxmlEndElementNS(
1664 const xmlChar
*localname
,
1665 const xmlChar
*prefix
,
1668 saxlocator
*This
= ctx
;
1669 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1670 element_entry
*element
;
1675 update_position(This
, FALSE
);
1676 p
= This
->pParserCtxt
->input
->cur
;
1678 if (This
->saxreader
->version
>= MSXML4
)
1681 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1683 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1688 else if(*(p
-1)!='>' || *(p
-2)!='/')
1691 while(p
-2>=This
->pParserCtxt
->input
->base
1692 && *(p
-2)!='<' && *(p
-1)!='/')
1694 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1700 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1703 uri
= find_element_uri(This
, URI
);
1704 element
= pop_element_ns(This
);
1706 if (!saxreader_has_handler(This
, SAXContentHandler
))
1708 free_attribute_values(This
);
1709 This
->nb_attributes
= 0;
1710 free_element_entry(element
);
1714 if (is_namespaces_enabled(This
->saxreader
))
1715 local
= element
->local
;
1719 if (This
->vbInterface
)
1720 hr
= IVBSAXContentHandler_endElement(
1722 &uri
, &local
, &element
->qname
);
1724 hr
= ISAXContentHandler_endElement(
1726 uri
, SysStringLen(uri
),
1727 local
, SysStringLen(local
),
1728 element
->qname
, SysStringLen(element
->qname
));
1730 free_attribute_values(This
);
1731 This
->nb_attributes
= 0;
1733 if (sax_callback_failed(This
, hr
))
1735 format_error_message_from_id(This
, hr
);
1736 free_element_entry(element
);
1740 if (is_namespaces_enabled(This
->saxreader
))
1743 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1745 if (This
->vbInterface
)
1746 hr
= IVBSAXContentHandler_endPrefixMapping(
1747 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1749 hr
= ISAXContentHandler_endPrefixMapping(
1750 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1752 if (sax_callback_failed(This
, hr
)) break;
1755 if (sax_callback_failed(This
, hr
))
1756 format_error_message_from_id(This
, hr
);
1759 free_element_entry(element
);
1762 static void libxmlCharacters(
1767 saxlocator
*This
= ctx
;
1771 BOOL lastEvent
= FALSE
;
1773 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1775 update_position(This
, FALSE
);
1776 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1777 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1779 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1784 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1788 if(*(ch
-1)=='\r') cur
--;
1793 while(end
-ch
<len
&& *end
!='\r') end
++;
1804 if (This
->saxreader
->version
>= MSXML4
)
1808 for(p
=cur
; p
!=end
; p
++)
1825 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1826 hr
= saxreader_saxcharacters(This
, Chars
);
1828 if (sax_callback_failed(This
, hr
))
1830 format_error_message_from_id(This
, hr
);
1834 if (This
->saxreader
->version
< MSXML4
)
1835 This
->column
+= end
-cur
;
1848 if(end
-ch
== len
) break;
1852 static void libxmlSetDocumentLocator(
1854 xmlSAXLocatorPtr loc
)
1856 saxlocator
*This
= ctx
;
1857 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1860 if (saxreader_has_handler(This
, SAXContentHandler
))
1862 if(This
->vbInterface
)
1863 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1864 &This
->IVBSAXLocator_iface
);
1866 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1870 format_error_message_from_id(This
, hr
);
1873 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1875 saxlocator
*This
= ctx
;
1876 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1879 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1881 update_position(This
, FALSE
);
1882 while(p
-4>=This
->pParserCtxt
->input
->base
1883 && memcmp(p
-4, "<!--", sizeof(char[4])))
1885 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1891 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1894 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1896 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1898 if (This
->vbInterface
)
1899 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1901 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1904 format_error_message_from_id(This
, hr
);
1907 static void libxmlFatalError(void *ctx
, const char *msg
, ...)
1909 saxlocator
*This
= ctx
;
1910 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1916 if(This
->ret
!= S_OK
) {
1917 xmlStopParser(This
->pParserCtxt
);
1921 va_start(args
, msg
);
1922 vsprintf(message
, msg
, args
);
1925 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1926 error
= heap_alloc(sizeof(WCHAR
)*len
);
1929 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1930 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1933 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1935 xmlStopParser(This
->pParserCtxt
);
1941 FIXME("Error handling is not compatible.\n");
1943 if(This
->vbInterface
)
1945 BSTR bstrError
= SysAllocString(error
);
1946 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1947 &bstrError
, E_FAIL
);
1948 SysFreeString(bstrError
);
1951 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1955 xmlStopParser(This
->pParserCtxt
);
1959 /* The only reason this helper exists is that CDATA section are reported by chunks,
1960 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1962 This helper should be called for substring with trailing newlines.
1964 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1966 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1969 ptr
= bstr
+ len
- 1;
1970 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1975 /* replace returns as:
1977 - "\r<char>" -> "\n<char>"
1983 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
1986 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
1993 ret
= SysAllocStringLen(bstr
, len
);
1994 SysFreeString(bstr
);
1998 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
2000 const xmlChar
*start
, *end
;
2001 saxlocator
*locator
= ctx
;
2002 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
2007 update_position(locator
, FALSE
);
2008 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2010 if (locator
->vbInterface
)
2011 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
2013 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
2018 format_error_message_from_id(locator
, hr
);
2028 /* scan for newlines */
2029 if (value
[i
] == '\r' || value
[i
] == '\n')
2031 /* skip newlines/linefeeds */
2034 if (value
[i
] != '\r' && value
[i
] != '\n') break;
2040 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
2041 TRACE("(chunk %s)\n", debugstr_w(chars
));
2042 hr
= saxreader_saxcharacters(locator
, chars
);
2043 SysFreeString(chars
);
2052 /* no newline chars (or last chunk) report as a whole */
2053 if (!end
&& start
== value
)
2056 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
2057 TRACE("(%s)\n", debugstr_w(chars
));
2058 hr
= saxreader_saxcharacters(locator
, chars
);
2059 SysFreeString(chars
);
2062 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2064 if (locator
->vbInterface
)
2065 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
2067 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
2071 format_error_message_from_id(locator
, hr
);
2074 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
2076 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
2077 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
2080 /*** IVBSAXLocator interface ***/
2081 /*** IUnknown methods ***/
2082 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2084 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2086 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2090 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2091 IsEqualGUID( riid
, &IID_IDispatch
) ||
2092 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
2096 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
2098 *ppvObject
= &This
->IVBSAXAttributes_iface
;
2102 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2103 return E_NOINTERFACE
;
2106 IVBSAXLocator_AddRef( iface
);
2111 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
2113 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2114 TRACE("%p\n", This
);
2115 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
2118 static ULONG WINAPI
ivbsaxlocator_Release(IVBSAXLocator
* iface
)
2120 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2121 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
2124 /*** IDispatch methods ***/
2125 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
2127 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2129 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2136 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
2137 IVBSAXLocator
*iface
,
2138 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2140 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2142 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2144 return get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2147 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2148 IVBSAXLocator
*iface
,
2150 LPOLESTR
* rgszNames
,
2155 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2156 ITypeInfo
*typeinfo
;
2159 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
2162 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2163 return E_INVALIDARG
;
2165 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2168 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2169 ITypeInfo_Release(typeinfo
);
2175 static HRESULT WINAPI
ivbsaxlocator_Invoke(
2176 IVBSAXLocator
*iface
,
2177 DISPID dispIdMember
,
2181 DISPPARAMS
* pDispParams
,
2182 VARIANT
* pVarResult
,
2183 EXCEPINFO
* pExcepInfo
,
2186 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2187 ITypeInfo
*typeinfo
;
2190 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2191 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2193 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2196 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXLocator_iface
, dispIdMember
, wFlags
,
2197 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2198 ITypeInfo_Release(typeinfo
);
2204 /*** IVBSAXLocator methods ***/
2205 static HRESULT WINAPI
ivbsaxlocator_get_columnNumber(
2206 IVBSAXLocator
* iface
,
2209 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2210 return ISAXLocator_getColumnNumber(&This
->ISAXLocator_iface
, pnColumn
);
2213 static HRESULT WINAPI
ivbsaxlocator_get_lineNumber(
2214 IVBSAXLocator
* iface
,
2217 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2218 return ISAXLocator_getLineNumber(&This
->ISAXLocator_iface
, pnLine
);
2221 static HRESULT WINAPI
ivbsaxlocator_get_publicId(IVBSAXLocator
* iface
, BSTR
*ret
)
2223 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2224 const WCHAR
*publicidW
;
2227 TRACE("(%p)->(%p)\n", This
, ret
);
2233 hr
= ISAXLocator_getPublicId(&This
->ISAXLocator_iface
, &publicidW
);
2237 return return_bstr(publicidW
, ret
);
2240 static HRESULT WINAPI
ivbsaxlocator_get_systemId(IVBSAXLocator
* iface
, BSTR
*ret
)
2242 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2243 const WCHAR
*systemidW
;
2246 TRACE("(%p)->(%p)\n", This
, ret
);
2252 hr
= ISAXLocator_getSystemId(&This
->ISAXLocator_iface
, &systemidW
);
2256 return return_bstr(systemidW
, ret
);
2259 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl
=
2261 ivbsaxlocator_QueryInterface
,
2262 ivbsaxlocator_AddRef
,
2263 ivbsaxlocator_Release
,
2264 ivbsaxlocator_GetTypeInfoCount
,
2265 ivbsaxlocator_GetTypeInfo
,
2266 ivbsaxlocator_GetIDsOfNames
,
2267 ivbsaxlocator_Invoke
,
2268 ivbsaxlocator_get_columnNumber
,
2269 ivbsaxlocator_get_lineNumber
,
2270 ivbsaxlocator_get_publicId
,
2271 ivbsaxlocator_get_systemId
2274 /*** ISAXLocator interface ***/
2275 /*** IUnknown methods ***/
2276 static HRESULT WINAPI
isaxlocator_QueryInterface(ISAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2278 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2280 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2284 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2285 IsEqualGUID( riid
, &IID_ISAXLocator
))
2289 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
2291 *ppvObject
= &This
->ISAXAttributes_iface
;
2295 WARN("interface %s not implemented\n", debugstr_guid(riid
));
2296 return E_NOINTERFACE
;
2299 ISAXLocator_AddRef( iface
);
2304 static ULONG WINAPI
isaxlocator_AddRef(ISAXLocator
* iface
)
2306 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2307 ULONG ref
= InterlockedIncrement( &This
->ref
);
2308 TRACE("(%p)->(%d)\n", This
, ref
);
2312 static ULONG WINAPI
isaxlocator_Release(
2315 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2316 LONG ref
= InterlockedDecrement( &This
->ref
);
2318 TRACE("(%p)->(%d)\n", This
, ref
);
2322 element_entry
*element
, *element2
;
2325 SysFreeString(This
->publicId
);
2326 SysFreeString(This
->systemId
);
2327 SysFreeString(This
->namespaceUri
);
2329 for(index
=0; index
<This
->attributesSize
; index
++)
2331 SysFreeString(This
->attributes
[index
].szLocalname
);
2332 SysFreeString(This
->attributes
[index
].szValue
);
2333 SysFreeString(This
->attributes
[index
].szQName
);
2335 heap_free(This
->attributes
);
2338 LIST_FOR_EACH_ENTRY_SAFE(element
, element2
, &This
->elements
, element_entry
, entry
)
2340 list_remove(&element
->entry
);
2341 free_element_entry(element
);
2344 ISAXXMLReader_Release(&This
->saxreader
->ISAXXMLReader_iface
);
2351 /*** ISAXLocator methods ***/
2352 static HRESULT WINAPI
isaxlocator_getColumnNumber(
2356 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2358 *pnColumn
= This
->column
;
2362 static HRESULT WINAPI
isaxlocator_getLineNumber(
2366 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2368 *pnLine
= This
->line
;
2372 static HRESULT WINAPI
isaxlocator_getPublicId(
2374 const WCHAR
** ppwchPublicId
)
2377 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2379 SysFreeString(This
->publicId
);
2381 publicId
= bstr_from_xmlChar(xmlSAX2GetPublicId(This
->pParserCtxt
));
2382 if(SysStringLen(publicId
))
2383 This
->publicId
= publicId
;
2386 SysFreeString(publicId
);
2387 This
->publicId
= NULL
;
2390 *ppwchPublicId
= This
->publicId
;
2394 static HRESULT WINAPI
isaxlocator_getSystemId(
2396 const WCHAR
** ppwchSystemId
)
2399 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2401 SysFreeString(This
->systemId
);
2403 systemId
= bstr_from_xmlChar(xmlSAX2GetSystemId(This
->pParserCtxt
));
2404 if(SysStringLen(systemId
))
2405 This
->systemId
= systemId
;
2408 SysFreeString(systemId
);
2409 This
->systemId
= NULL
;
2412 *ppwchSystemId
= This
->systemId
;
2416 static const struct ISAXLocatorVtbl SAXLocatorVtbl
=
2418 isaxlocator_QueryInterface
,
2420 isaxlocator_Release
,
2421 isaxlocator_getColumnNumber
,
2422 isaxlocator_getLineNumber
,
2423 isaxlocator_getPublicId
,
2424 isaxlocator_getSystemId
2427 static HRESULT
SAXLocator_create(saxreader
*reader
, saxlocator
**ppsaxlocator
, BOOL vbInterface
)
2429 static const WCHAR w3xmlns
[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2430 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2432 saxlocator
*locator
;
2434 locator
= heap_alloc( sizeof (*locator
) );
2436 return E_OUTOFMEMORY
;
2438 locator
->IVBSAXLocator_iface
.lpVtbl
= &VBSAXLocatorVtbl
;
2439 locator
->ISAXLocator_iface
.lpVtbl
= &SAXLocatorVtbl
;
2440 locator
->IVBSAXAttributes_iface
.lpVtbl
= &ivbsaxattributes_vtbl
;
2441 locator
->ISAXAttributes_iface
.lpVtbl
= &isaxattributes_vtbl
;
2443 locator
->vbInterface
= vbInterface
;
2445 locator
->saxreader
= reader
;
2446 ISAXXMLReader_AddRef(&reader
->ISAXXMLReader_iface
);
2448 locator
->pParserCtxt
= NULL
;
2449 locator
->publicId
= NULL
;
2450 locator
->systemId
= NULL
;
2451 locator
->line
= reader
->version
< MSXML4
? 0 : 1;
2452 locator
->column
= 0;
2453 locator
->ret
= S_OK
;
2454 if (locator
->saxreader
->version
>= MSXML6
)
2455 locator
->namespaceUri
= SysAllocString(w3xmlns
);
2457 locator
->namespaceUri
= SysAllocStringLen(NULL
, 0);
2458 if(!locator
->namespaceUri
)
2460 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2462 return E_OUTOFMEMORY
;
2465 locator
->attributesSize
= 8;
2466 locator
->nb_attributes
= 0;
2467 locator
->attributes
= heap_alloc_zero(sizeof(struct _attributes
)*locator
->attributesSize
);
2468 if(!locator
->attributes
)
2470 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2471 SysFreeString(locator
->namespaceUri
);
2473 return E_OUTOFMEMORY
;
2476 list_init(&locator
->elements
);
2478 *ppsaxlocator
= locator
;
2480 TRACE("returning %p\n", *ppsaxlocator
);
2485 /*** SAXXMLReader internal functions ***/
2486 static HRESULT
internal_parseBuffer(saxreader
*This
, const char *buffer
, int size
, BOOL vbInterface
)
2488 xmlCharEncoding encoding
= XML_CHAR_ENCODING_NONE
;
2489 xmlChar
*enc_name
= NULL
;
2490 saxlocator
*locator
;
2493 TRACE("(%p)->(%p %d)\n", This
, buffer
, size
);
2495 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2501 const unsigned char *buff
= (unsigned char*)buffer
;
2503 encoding
= xmlDetectCharEncoding((xmlChar
*)buffer
, 4);
2504 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2505 TRACE("detected encoding: %s\n", enc_name
);
2506 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2507 if ((encoding
== XML_CHAR_ENCODING_UTF8
) &&
2508 buff
[0] == 0xEF && buff
[1] == 0xBB && buff
[2] == 0xBF)
2515 /* if libxml2 detection failed try to guess */
2516 if (encoding
== XML_CHAR_ENCODING_NONE
)
2518 const WCHAR
*ptr
= (WCHAR
*)buffer
;
2519 /* xml declaration with possibly specfied encoding will be still handled by parser */
2520 if ((size
>= 2) && *ptr
== '<' && ptr
[1] != '?')
2522 enc_name
= (xmlChar
*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE
);
2523 encoding
= XML_CHAR_ENCODING_UTF16LE
;
2526 else if (encoding
== XML_CHAR_ENCODING_UTF8
)
2527 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2531 locator
->pParserCtxt
= xmlCreateMemoryParserCtxt(buffer
, size
);
2532 if (!locator
->pParserCtxt
)
2534 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2540 locator
->pParserCtxt
->encoding
= xmlStrdup(enc_name
);
2541 if (encoding
== XML_CHAR_ENCODING_UTF16LE
) {
2542 TRACE("switching to %s\n", enc_name
);
2543 xmlSwitchEncoding(locator
->pParserCtxt
, encoding
);
2547 xmlFree(locator
->pParserCtxt
->sax
);
2548 locator
->pParserCtxt
->sax
= &locator
->saxreader
->sax
;
2549 locator
->pParserCtxt
->userData
= locator
;
2551 This
->isParsing
= TRUE
;
2552 if(xmlParseDocument(locator
->pParserCtxt
) == -1 && locator
->ret
== S_OK
)
2556 This
->isParsing
= FALSE
;
2558 if(locator
->pParserCtxt
)
2560 locator
->pParserCtxt
->sax
= NULL
;
2561 xmlFreeParserCtxt(locator
->pParserCtxt
);
2562 locator
->pParserCtxt
= NULL
;
2565 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2569 static HRESULT
internal_parseStream(saxreader
*This
, ISequentialStream
*stream
, BOOL vbInterface
)
2571 saxlocator
*locator
;
2578 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2579 if(FAILED(hr
)) return hr
;
2581 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2582 if(FAILED(hr
)) return hr
;
2584 locator
->pParserCtxt
= xmlCreatePushParserCtxt(
2585 &locator
->saxreader
->sax
, locator
,
2586 data
, dataRead
, NULL
);
2587 if(!locator
->pParserCtxt
)
2589 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2593 This
->isParsing
= TRUE
;
2597 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2598 if (FAILED(hr
) || !dataRead
) break;
2600 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, dataRead
, 0);
2601 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2606 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2607 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2611 This
->isParsing
= FALSE
;
2613 xmlFreeParserCtxt(locator
->pParserCtxt
);
2614 locator
->pParserCtxt
= NULL
;
2615 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2619 static HRESULT
internal_parse(
2626 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varInput
));
2628 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2629 free_bstr_pool(&This
->pool
);
2631 switch(V_VT(&varInput
))
2634 case VT_BSTR
|VT_BYREF
:
2636 BSTR str
= V_ISBYREF(&varInput
) ? *V_BSTRREF(&varInput
) : V_BSTR(&varInput
);
2637 hr
= internal_parseBuffer(This
, (const char*)str
, strlenW(str
)*sizeof(WCHAR
), vbInterface
);
2640 case VT_ARRAY
|VT_UI1
: {
2642 LONG lBound
, uBound
;
2645 hr
= SafeArrayGetLBound(V_ARRAY(&varInput
), 1, &lBound
);
2646 if(hr
!= S_OK
) break;
2647 hr
= SafeArrayGetUBound(V_ARRAY(&varInput
), 1, &uBound
);
2648 if(hr
!= S_OK
) break;
2649 dataRead
= (uBound
-lBound
)*SafeArrayGetElemsize(V_ARRAY(&varInput
));
2650 hr
= SafeArrayAccessData(V_ARRAY(&varInput
), &pSAData
);
2651 if(hr
!= S_OK
) break;
2652 hr
= internal_parseBuffer(This
, pSAData
, dataRead
, vbInterface
);
2653 SafeArrayUnaccessData(V_ARRAY(&varInput
));
2658 IPersistStream
*persistStream
;
2659 ISequentialStream
*stream
= NULL
;
2660 IXMLDOMDocument
*xmlDoc
;
2662 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2663 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2667 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2668 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2669 SysStringByteLen(bstrData
), vbInterface
);
2670 IXMLDOMDocument_Release(xmlDoc
);
2671 SysFreeString(bstrData
);
2675 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2676 &IID_IPersistStream
, (void**)&persistStream
) == S_OK
)
2678 IStream
*stream_copy
;
2680 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream_copy
);
2683 IPersistStream_Release(persistStream
);
2687 hr
= IPersistStream_Save(persistStream
, stream_copy
, TRUE
);
2688 IPersistStream_Release(persistStream
);
2690 IStream_QueryInterface(stream_copy
, &IID_ISequentialStream
, (void**)&stream
);
2692 IStream_Release(stream_copy
);
2695 /* try base interface first */
2698 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2700 /* this should never happen if IStream is implemented properly, but just in case */
2701 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2706 hr
= internal_parseStream(This
, stream
, vbInterface
);
2707 ISequentialStream_Release(stream
);
2711 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2718 WARN("vt %d not implemented\n", V_VT(&varInput
));
2725 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2727 saxreader
*This
= obj
;
2729 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2732 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2734 saxreader
*This
= obj
;
2736 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2739 static HRESULT
internal_parseURL(
2748 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
2750 hr
= create_moniker_from_url(url
, &mon
);
2754 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, This
, &bsc
);
2755 else hr
= bind_url(mon
, internal_onDataAvailable
, This
, &bsc
);
2756 IMoniker_Release(mon
);
2761 return detach_bsc(bsc
);
2764 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2768 if (V_VT(v
) == VT_EMPTY
)
2769 return saxreader_put_handler(This
, type
, NULL
, vb
);
2773 case SAXDeclHandler
:
2774 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2776 case SAXLexicalHandler
:
2777 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2780 ERR("wrong handler type %d\n", type
);
2789 IUnknown
*handler
= NULL
;
2793 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2794 if (FAILED(hr
)) return hr
;
2797 saxreader_put_handler(This
, type
, handler
, vb
);
2798 if (handler
) IUnknown_Release(handler
);
2802 ERR("value type %d not supported\n", V_VT(v
));
2803 return E_INVALIDARG
;
2809 static HRESULT
internal_putProperty(
2817 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2819 if (This
->isParsing
) return E_FAIL
;
2821 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2822 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2823 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2825 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2826 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2828 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2830 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2831 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2835 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2837 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2838 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2842 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2844 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2847 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2850 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2853 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2856 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2859 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2862 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2865 return E_INVALIDARG
;
2868 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2870 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2872 if (!value
) return E_POINTER
;
2874 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2876 V_VT(value
) = VT_UNKNOWN
;
2877 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2881 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2883 V_VT(value
) = VT_UNKNOWN
;
2884 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2888 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2890 V_VT(value
) = VT_BSTR
;
2891 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2895 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2900 /*** IVBSAXXMLReader interface ***/
2901 /*** IUnknown methods ***/
2902 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2904 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2906 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2910 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2911 IsEqualGUID( riid
, &IID_IDispatch
) ||
2912 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2916 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2918 *ppvObject
= &This
->ISAXXMLReader_iface
;
2920 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2922 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2926 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2927 return E_NOINTERFACE
;
2930 IVBSAXXMLReader_AddRef( iface
);
2935 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2937 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2938 TRACE("%p\n", This
);
2939 return InterlockedIncrement( &This
->ref
);
2942 static ULONG WINAPI
saxxmlreader_Release(
2943 IVBSAXXMLReader
* iface
)
2945 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2948 TRACE("%p\n", This
);
2950 ref
= InterlockedDecrement( &This
->ref
);
2955 for (i
= 0; i
< SAXHandler_Last
; i
++)
2957 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2959 if (saxiface
->handler
)
2960 IUnknown_Release(saxiface
->handler
);
2962 if (saxiface
->vbhandler
)
2963 IUnknown_Release(saxiface
->vbhandler
);
2966 SysFreeString(This
->xmldecl_version
);
2967 free_bstr_pool(&This
->pool
);
2975 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2977 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2978 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2981 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2982 IVBSAXXMLReader
*iface
,
2983 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2985 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2986 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2987 iTInfo
, lcid
, ppTInfo
);
2990 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2991 IVBSAXXMLReader
*iface
,
2993 LPOLESTR
* rgszNames
,
2998 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2999 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
3000 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
3003 static HRESULT WINAPI
saxxmlreader_Invoke(
3004 IVBSAXXMLReader
*iface
,
3005 DISPID dispIdMember
,
3009 DISPPARAMS
* pDispParams
,
3010 VARIANT
* pVarResult
,
3011 EXCEPINFO
* pExcepInfo
,
3014 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3015 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
3016 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3019 /*** IVBSAXXMLReader methods ***/
3020 static HRESULT WINAPI
saxxmlreader_getFeature(
3021 IVBSAXXMLReader
* iface
,
3023 VARIANT_BOOL
*value
)
3025 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3026 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3029 static HRESULT WINAPI
saxxmlreader_putFeature(
3030 IVBSAXXMLReader
* iface
,
3034 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3035 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3038 static HRESULT WINAPI
saxxmlreader_getProperty(
3039 IVBSAXXMLReader
* iface
,
3043 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3044 return internal_getProperty(This
, prop
, value
, TRUE
);
3047 static HRESULT WINAPI
saxxmlreader_putProperty(
3048 IVBSAXXMLReader
* iface
,
3052 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3053 return internal_putProperty(This
, pProp
, value
, TRUE
);
3056 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3057 IVBSAXXMLReader
* iface
,
3058 IVBSAXEntityResolver
**resolver
)
3060 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3061 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3064 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3065 IVBSAXXMLReader
* iface
,
3066 IVBSAXEntityResolver
*resolver
)
3068 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3069 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3072 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3073 IVBSAXXMLReader
* iface
,
3074 IVBSAXContentHandler
**handler
)
3076 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3077 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3080 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3081 IVBSAXXMLReader
* iface
,
3082 IVBSAXContentHandler
*handler
)
3084 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3085 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3088 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3089 IVBSAXXMLReader
* iface
,
3090 IVBSAXDTDHandler
**handler
)
3092 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3093 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3096 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3097 IVBSAXXMLReader
* iface
,
3098 IVBSAXDTDHandler
*handler
)
3100 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3101 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3104 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3105 IVBSAXXMLReader
* iface
,
3106 IVBSAXErrorHandler
**handler
)
3108 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3109 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3112 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3113 IVBSAXXMLReader
* iface
,
3114 IVBSAXErrorHandler
*handler
)
3116 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3117 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3120 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3121 IVBSAXXMLReader
* iface
,
3124 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3126 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3130 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3131 IVBSAXXMLReader
* iface
,
3134 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3135 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3138 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3139 IVBSAXXMLReader
* iface
,
3140 BSTR
*pSecureBaseUrl
)
3142 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3144 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3148 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3149 IVBSAXXMLReader
* iface
,
3152 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3153 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3156 static HRESULT WINAPI
saxxmlreader_parse(
3157 IVBSAXXMLReader
* iface
,
3160 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3161 return internal_parse(This
, varInput
, TRUE
);
3164 static HRESULT WINAPI
saxxmlreader_parseURL(
3165 IVBSAXXMLReader
* iface
,
3168 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3169 return internal_parseURL(This
, url
, TRUE
);
3172 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3174 saxxmlreader_QueryInterface
,
3175 saxxmlreader_AddRef
,
3176 saxxmlreader_Release
,
3177 saxxmlreader_GetTypeInfoCount
,
3178 saxxmlreader_GetTypeInfo
,
3179 saxxmlreader_GetIDsOfNames
,
3180 saxxmlreader_Invoke
,
3181 saxxmlreader_getFeature
,
3182 saxxmlreader_putFeature
,
3183 saxxmlreader_getProperty
,
3184 saxxmlreader_putProperty
,
3185 saxxmlreader_get_entityResolver
,
3186 saxxmlreader_put_entityResolver
,
3187 saxxmlreader_get_contentHandler
,
3188 saxxmlreader_put_contentHandler
,
3189 saxxmlreader_get_dtdHandler
,
3190 saxxmlreader_put_dtdHandler
,
3191 saxxmlreader_get_errorHandler
,
3192 saxxmlreader_put_errorHandler
,
3193 saxxmlreader_get_baseURL
,
3194 saxxmlreader_put_baseURL
,
3195 saxxmlreader_get_secureBaseURL
,
3196 saxxmlreader_put_secureBaseURL
,
3198 saxxmlreader_parseURL
3201 /*** ISAXXMLReader interface ***/
3202 /*** IUnknown methods ***/
3203 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3205 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3206 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3209 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3211 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3212 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3215 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3217 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3218 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3221 /*** ISAXXMLReader methods ***/
3222 static HRESULT WINAPI
isaxxmlreader_getFeature(
3223 ISAXXMLReader
* iface
,
3224 const WCHAR
*feature_name
,
3225 VARIANT_BOOL
*value
)
3227 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3228 saxreader_feature feature
;
3230 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3232 feature
= get_saxreader_feature(feature_name
);
3233 if (feature
== Namespaces
|| feature
== NamespacePrefixes
)
3234 return get_feature_value(This
, feature
, value
);
3236 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3240 static HRESULT WINAPI
isaxxmlreader_putFeature(
3241 ISAXXMLReader
* iface
,
3242 const WCHAR
*feature_name
,
3245 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3246 saxreader_feature feature
;
3248 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3250 feature
= get_saxreader_feature(feature_name
);
3252 /* accepted cases */
3253 if ((feature
== ExternalGeneralEntities
&& value
== VARIANT_FALSE
) ||
3254 (feature
== ExternalParameterEntities
&& value
== VARIANT_FALSE
) ||
3255 feature
== Namespaces
||
3256 feature
== NamespacePrefixes
)
3258 return set_feature_value(This
, feature
, value
);
3261 if (feature
== LexicalHandlerParEntities
|| feature
== ProhibitDTD
)
3263 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3264 return set_feature_value(This
, feature
, value
);
3267 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3271 static HRESULT WINAPI
isaxxmlreader_getProperty(
3272 ISAXXMLReader
* iface
,
3276 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3277 return internal_getProperty(This
, prop
, value
, FALSE
);
3280 static HRESULT WINAPI
isaxxmlreader_putProperty(
3281 ISAXXMLReader
* iface
,
3285 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3286 return internal_putProperty(This
, pProp
, value
, FALSE
);
3289 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3290 ISAXXMLReader
* iface
,
3291 ISAXEntityResolver
**resolver
)
3293 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3294 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3297 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3298 ISAXXMLReader
* iface
,
3299 ISAXEntityResolver
*resolver
)
3301 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3302 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3305 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3306 ISAXXMLReader
* iface
,
3307 ISAXContentHandler
**handler
)
3309 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3310 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3313 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3314 ISAXXMLReader
* iface
,
3315 ISAXContentHandler
*handler
)
3317 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3318 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3321 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3322 ISAXXMLReader
* iface
,
3323 ISAXDTDHandler
**handler
)
3325 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3326 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3329 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3330 ISAXXMLReader
* iface
,
3331 ISAXDTDHandler
*handler
)
3333 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3334 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3337 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3338 ISAXXMLReader
* iface
,
3339 ISAXErrorHandler
**handler
)
3341 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3342 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3345 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3347 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3348 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3351 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3352 ISAXXMLReader
* iface
,
3353 const WCHAR
**base_url
)
3355 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3357 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3361 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3362 ISAXXMLReader
* iface
,
3363 const WCHAR
*pBaseUrl
)
3365 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3367 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3371 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3372 ISAXXMLReader
* iface
,
3373 const WCHAR
**pSecureBaseUrl
)
3375 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3376 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3380 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3381 ISAXXMLReader
* iface
,
3382 const WCHAR
*secureBaseUrl
)
3384 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3386 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3390 static HRESULT WINAPI
isaxxmlreader_parse(
3391 ISAXXMLReader
* iface
,
3394 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3395 return internal_parse(This
, varInput
, FALSE
);
3398 static HRESULT WINAPI
isaxxmlreader_parseURL(
3399 ISAXXMLReader
* iface
,
3402 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3403 return internal_parseURL(This
, url
, FALSE
);
3406 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3408 isaxxmlreader_QueryInterface
,
3409 isaxxmlreader_AddRef
,
3410 isaxxmlreader_Release
,
3411 isaxxmlreader_getFeature
,
3412 isaxxmlreader_putFeature
,
3413 isaxxmlreader_getProperty
,
3414 isaxxmlreader_putProperty
,
3415 isaxxmlreader_getEntityResolver
,
3416 isaxxmlreader_putEntityResolver
,
3417 isaxxmlreader_getContentHandler
,
3418 isaxxmlreader_putContentHandler
,
3419 isaxxmlreader_getDTDHandler
,
3420 isaxxmlreader_putDTDHandler
,
3421 isaxxmlreader_getErrorHandler
,
3422 isaxxmlreader_putErrorHandler
,
3423 isaxxmlreader_getBaseURL
,
3424 isaxxmlreader_putBaseURL
,
3425 isaxxmlreader_getSecureBaseURL
,
3426 isaxxmlreader_putSecureBaseURL
,
3427 isaxxmlreader_parse
,
3428 isaxxmlreader_parseURL
3431 static const tid_t saxreader_iface_tids
[] = {
3432 IVBSAXXMLReader_tid
,
3435 static dispex_static_data_t saxreader_dispex
= {
3437 IVBSAXXMLReader_tid
,
3439 saxreader_iface_tids
3442 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3446 TRACE("(%p)\n", ppObj
);
3448 reader
= heap_alloc( sizeof (*reader
) );
3450 return E_OUTOFMEMORY
;
3452 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3453 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3455 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3456 reader
->isParsing
= FALSE
;
3457 reader
->xmldecl_version
= NULL
;
3458 reader
->pool
.pool
= NULL
;
3459 reader
->pool
.index
= 0;
3460 reader
->pool
.len
= 0;
3461 reader
->features
= Namespaces
| NamespacePrefixes
;
3462 reader
->version
= version
;
3464 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3466 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3467 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3468 reader
->sax
.startDocument
= libxmlStartDocument
;
3469 reader
->sax
.endDocument
= libxmlEndDocument
;
3470 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3471 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3472 reader
->sax
.characters
= libxmlCharacters
;
3473 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3474 reader
->sax
.comment
= libxmlComment
;
3475 reader
->sax
.error
= libxmlFatalError
;
3476 reader
->sax
.fatalError
= libxmlFatalError
;
3477 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3478 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3480 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3482 TRACE("returning iface %p\n", *ppObj
);
3489 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3491 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3492 "libxml2 support was not present at compile time.\n");