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
24 #include <libxml/parser.h>
25 #include <libxml/xmlerror.h>
26 #include <libxml/SAX2.h>
27 #include <libxml/parserInternals.h>
40 #include "wine/debug.h"
42 #include "msxml_private.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
49 ExhaustiveErrors
= 1 << 1,
50 ExternalGeneralEntities
= 1 << 2,
51 ExternalParameterEntities
= 1 << 3,
52 ForcedResync
= 1 << 4,
53 NamespacePrefixes
= 1 << 5,
55 ParameterEntities
= 1 << 7,
56 PreserveSystemIndentifiers
= 1 << 8,
58 SchemaValidation
= 1 << 10,
59 ServerHttpRequest
= 1 << 11,
60 SuppressValidationfatalError
= 1 << 12,
61 UseInlineSchema
= 1 << 13,
62 UseSchemaLocation
= 1 << 14,
63 LexicalHandlerParEntities
= 1 << 15
67 static const WCHAR FeatureExternalGeneralEntitiesW
[] = {
68 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/',
69 'f','e','a','t','u','r','e','s','/','e','x','t','e','r','n','a','l','-','g','e','n','e','r','a','l',
70 '-','e','n','t','i','t','i','e','s',0
73 static const WCHAR FeatureExternalParameterEntitiesW
[] = {
74 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
75 '/','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
78 static const WCHAR FeatureLexicalHandlerParEntitiesW
[] = {
79 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
80 '/','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
83 static const WCHAR FeatureProhibitDTDW
[] = {
84 'p','r','o','h','i','b','i','t','-','d','t','d',0
87 static const WCHAR FeatureNamespacesW
[] = {
88 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
89 '/','n','a','m','e','s','p','a','c','e','s',0
92 static const WCHAR FeatureNamespacePrefixesW
[] = {
93 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
94 '/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0
97 static const WCHAR ExhaustiveErrorsW
[] = {
98 'e','x','h','a','u','s','t','i','v','e','-','e','r','r','o','r','s',0
101 static const WCHAR SchemaValidationW
[] = {
102 's','c','h','e','m','a','-','v','a','l','i','d','a','t','i','o','n',0
105 struct saxreader_feature_pair
107 saxreader_feature feature
;
111 static const struct saxreader_feature_pair saxreader_feature_map
[] = {
112 { ExhaustiveErrors
, ExhaustiveErrorsW
},
113 { ExternalGeneralEntities
, FeatureExternalGeneralEntitiesW
},
114 { ExternalParameterEntities
, FeatureExternalParameterEntitiesW
},
115 { LexicalHandlerParEntities
, FeatureLexicalHandlerParEntitiesW
},
116 { NamespacePrefixes
, FeatureNamespacePrefixesW
},
117 { Namespaces
, FeatureNamespacesW
},
118 { ProhibitDTD
, FeatureProhibitDTDW
},
119 { SchemaValidation
, SchemaValidationW
},
122 static saxreader_feature
get_saxreader_feature(const WCHAR
*name
)
127 max
= ARRAY_SIZE(saxreader_feature_map
) - 1;
133 c
= wcscmp(saxreader_feature_map
[n
].name
, name
);
135 return saxreader_feature_map
[n
].feature
;
143 return FeatureUnknown
;
146 static const WCHAR empty_str
;
167 ns
*ns
; /* namespaces defined in this particular element */
173 SAXContentHandler
= 0,
182 struct saxanyhandler_iface
188 struct saxcontenthandler_iface
190 ISAXContentHandler
*handler
;
191 IVBSAXContentHandler
*vbhandler
;
194 struct saxerrorhandler_iface
196 ISAXErrorHandler
*handler
;
197 IVBSAXErrorHandler
*vbhandler
;
200 struct saxlexicalhandler_iface
202 ISAXLexicalHandler
*handler
;
203 IVBSAXLexicalHandler
*vbhandler
;
206 struct saxentityresolver_iface
208 ISAXEntityResolver
*handler
;
209 IVBSAXEntityResolver
*vbhandler
;
212 struct saxhandler_iface
215 struct saxcontenthandler_iface content
;
216 struct saxentityresolver_iface entityresolver
;
217 struct saxerrorhandler_iface error
;
218 struct saxlexicalhandler_iface lexical
;
219 struct saxanyhandler_iface anyhandler
;
226 IVBSAXXMLReader IVBSAXXMLReader_iface
;
227 ISAXXMLReader ISAXXMLReader_iface
;
230 struct saxhandler_iface saxhandlers
[SAXHandler_Last
];
233 struct bstrpool pool
;
234 saxreader_feature features
;
235 BSTR xmldecl_version
;
236 MSXML_VERSION version
;
239 static HRESULT
saxreader_put_handler(saxreader
*reader
, enum saxhandler_type type
, void *ptr
, BOOL vb
)
241 struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
242 IUnknown
*unk
= (IUnknown
*)ptr
;
245 IUnknown_AddRef(unk
);
247 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
248 IUnknown_Release(vb
? iface
->vbhandler
: iface
->handler
);
251 iface
->vbhandler
= unk
;
253 iface
->handler
= unk
;
258 static HRESULT
saxreader_get_handler(const saxreader
*reader
, enum saxhandler_type type
, BOOL vb
, void **ret
)
260 const struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
262 if (!ret
) return E_POINTER
;
264 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
267 IUnknown_AddRef(iface
->vbhandler
);
269 IUnknown_AddRef(iface
->handler
);
272 *ret
= vb
? iface
->vbhandler
: iface
->handler
;
277 static struct saxcontenthandler_iface
*saxreader_get_contenthandler(saxreader
*reader
)
279 return &reader
->saxhandlers
[SAXContentHandler
].u
.content
;
282 static struct saxerrorhandler_iface
*saxreader_get_errorhandler(saxreader
*reader
)
284 return &reader
->saxhandlers
[SAXErrorHandler
].u
.error
;
287 static struct saxlexicalhandler_iface
*saxreader_get_lexicalhandler(saxreader
*reader
)
289 return &reader
->saxhandlers
[SAXLexicalHandler
].u
.lexical
;
294 IVBSAXLocator IVBSAXLocator_iface
;
295 ISAXLocator ISAXLocator_iface
;
296 IVBSAXAttributes IVBSAXAttributes_iface
;
297 ISAXAttributes ISAXAttributes_iface
;
299 saxreader
*saxreader
;
301 xmlParserCtxtPtr pParserCtxt
;
307 struct list elements
;
310 int attr_alloc_count
;
321 static inline saxreader
*impl_from_IVBSAXXMLReader( IVBSAXXMLReader
*iface
)
323 return CONTAINING_RECORD(iface
, saxreader
, IVBSAXXMLReader_iface
);
326 static inline saxreader
*impl_from_ISAXXMLReader( ISAXXMLReader
*iface
)
328 return CONTAINING_RECORD(iface
, saxreader
, ISAXXMLReader_iface
);
331 static inline saxlocator
*impl_from_IVBSAXLocator( IVBSAXLocator
*iface
)
333 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXLocator_iface
);
336 static inline saxlocator
*impl_from_ISAXLocator( ISAXLocator
*iface
)
338 return CONTAINING_RECORD(iface
, saxlocator
, ISAXLocator_iface
);
341 static inline saxlocator
*impl_from_IVBSAXAttributes( IVBSAXAttributes
*iface
)
343 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXAttributes_iface
);
346 static inline saxlocator
*impl_from_ISAXAttributes( ISAXAttributes
*iface
)
348 return CONTAINING_RECORD(iface
, saxlocator
, ISAXAttributes_iface
);
351 static inline BOOL
saxreader_has_handler(const saxlocator
*locator
, enum saxhandler_type type
)
353 struct saxanyhandler_iface
*iface
= &locator
->saxreader
->saxhandlers
[type
].u
.anyhandler
;
354 return (locator
->vbInterface
&& iface
->vbhandler
) || (!locator
->vbInterface
&& iface
->handler
);
357 static HRESULT
saxreader_saxcharacters(saxlocator
*locator
, BSTR chars
)
359 struct saxcontenthandler_iface
*content
= saxreader_get_contenthandler(locator
->saxreader
);
362 if (!saxreader_has_handler(locator
, SAXContentHandler
)) return S_OK
;
364 if (locator
->vbInterface
)
365 hr
= IVBSAXContentHandler_characters(content
->vbhandler
, &chars
);
367 hr
= ISAXContentHandler_characters(content
->handler
, chars
, SysStringLen(chars
));
373 static const WCHAR PropertyCharsetW
[] = {
374 'c','h','a','r','s','e','t',0
376 static const WCHAR PropertyXmlDeclVersionW
[] = {
377 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
379 static const WCHAR PropertyDeclHandlerW
[] = {
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','e','c','l','a','r','a','t','i','o','n',
383 '-','h','a','n','d','l','e','r',0
385 static const WCHAR PropertyDomNodeW
[] = {
386 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
387 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
388 'd','o','m','-','n','o','d','e',0
390 static const WCHAR PropertyInputSourceW
[] = {
391 'i','n','p','u','t','-','s','o','u','r','c','e',0
393 static const WCHAR PropertyLexicalHandlerW
[] = {
394 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
395 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
396 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
398 static const WCHAR PropertyMaxElementDepthW
[] = {
399 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
401 static const WCHAR PropertyMaxXMLSizeW
[] = {
402 'm','a','x','-','x','m','l','-','s','i','z','e',0
404 static const WCHAR PropertySchemaDeclHandlerW
[] = {
405 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
406 'h','a','n','d','l','e','r',0
408 static const WCHAR PropertyXMLDeclEncodingW
[] = {
409 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
411 static const WCHAR PropertyXMLDeclStandaloneW
[] = {
412 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
414 static const WCHAR PropertyXMLDeclVersionW
[] = {
415 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
418 static inline HRESULT
set_feature_value(saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL value
)
420 /* handling of non-VARIANT_* values is version dependent */
421 if ((reader
->version
< MSXML4
) && (value
!= VARIANT_TRUE
))
422 value
= VARIANT_FALSE
;
423 if ((reader
->version
>= MSXML4
) && (value
!= VARIANT_FALSE
))
424 value
= VARIANT_TRUE
;
426 if (value
== VARIANT_TRUE
)
427 reader
->features
|= feature
;
429 reader
->features
&= ~feature
;
434 static inline HRESULT
get_feature_value(const saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL
*value
)
436 *value
= reader
->features
& feature
? VARIANT_TRUE
: VARIANT_FALSE
;
440 static BOOL
is_namespaces_enabled(const saxreader
*reader
)
442 return (reader
->version
< MSXML4
) || (reader
->features
& Namespaces
);
445 static BSTR
build_qname(BSTR prefix
, BSTR local
)
447 if (prefix
&& *prefix
)
449 BSTR qname
= SysAllocStringLen(NULL
, SysStringLen(prefix
) + SysStringLen(local
) + 1);
453 lstrcpyW(ptr
, prefix
);
454 ptr
+= SysStringLen(prefix
);
456 lstrcpyW(ptr
, local
);
460 return SysAllocString(local
);
463 static element_entry
* alloc_element_entry(const xmlChar
*local
, const xmlChar
*prefix
, int nb_ns
,
464 const xmlChar
**namespaces
)
469 ret
= heap_alloc(sizeof(*ret
));
470 if (!ret
) return ret
;
472 ret
->local
= bstr_from_xmlChar(local
);
473 ret
->prefix
= bstr_from_xmlChar(prefix
);
474 ret
->qname
= build_qname(ret
->prefix
, ret
->local
);
475 ret
->ns
= nb_ns
? heap_alloc(nb_ns
*sizeof(ns
)) : NULL
;
476 ret
->ns_count
= nb_ns
;
478 for (i
=0; i
< nb_ns
; i
++)
480 ret
->ns
[i
].prefix
= bstr_from_xmlChar(namespaces
[2*i
]);
481 ret
->ns
[i
].uri
= bstr_from_xmlChar(namespaces
[2*i
+1]);
487 static void free_element_entry(element_entry
*element
)
491 for (i
=0; i
<element
->ns_count
;i
++)
493 SysFreeString(element
->ns
[i
].prefix
);
494 SysFreeString(element
->ns
[i
].uri
);
497 SysFreeString(element
->prefix
);
498 SysFreeString(element
->local
);
499 SysFreeString(element
->qname
);
501 heap_free(element
->ns
);
505 static void push_element_ns(saxlocator
*locator
, element_entry
*element
)
507 list_add_head(&locator
->elements
, &element
->entry
);
510 static element_entry
* pop_element_ns(saxlocator
*locator
)
512 element_entry
*element
= LIST_ENTRY(list_head(&locator
->elements
), element_entry
, entry
);
515 list_remove(&element
->entry
);
520 static BSTR
find_element_uri(saxlocator
*locator
, const xmlChar
*uri
)
522 element_entry
*element
;
526 if (!uri
) return NULL
;
528 uriW
= bstr_from_xmlChar(uri
);
530 LIST_FOR_EACH_ENTRY(element
, &locator
->elements
, element_entry
, entry
)
532 for (i
=0; i
< element
->ns_count
; i
++)
533 if (!wcscmp(uriW
, element
->ns
[i
].uri
))
536 return element
->ns
[i
].uri
;
541 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri
));
545 /* used to localize version dependent error check behaviour */
546 static inline BOOL
sax_callback_failed(saxlocator
*This
, HRESULT hr
)
548 return This
->saxreader
->version
>= MSXML4
? FAILED(hr
) : hr
!= S_OK
;
551 /* index value -1 means it tries to loop for a first time */
552 static inline BOOL
iterate_endprefix_index(saxlocator
*This
, const element_entry
*element
, int *i
)
554 if (This
->saxreader
->version
>= MSXML4
)
556 if (*i
== -1) *i
= 0; else ++*i
;
557 return *i
< element
->ns_count
;
561 if (*i
== -1) *i
= element
->ns_count
-1; else --*i
;
566 static BOOL
bstr_pool_insert(struct bstrpool
*pool
, BSTR pool_entry
)
570 pool
->pool
= heap_alloc(16 * sizeof(*pool
->pool
));
577 else if (pool
->index
== pool
->len
)
579 BSTR
*realloc
= heap_realloc(pool
->pool
, pool
->len
* 2 * sizeof(*realloc
));
584 pool
->pool
= realloc
;
588 pool
->pool
[pool
->index
++] = pool_entry
;
592 static void free_bstr_pool(struct bstrpool
*pool
)
596 for (i
= 0; i
< pool
->index
; i
++)
597 SysFreeString(pool
->pool
[i
]);
599 heap_free(pool
->pool
);
602 pool
->index
= pool
->len
= 0;
605 static BSTR
bstr_from_xmlCharN(const xmlChar
*buf
, int len
)
613 dLen
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
614 if(len
!= -1) dLen
++;
615 bstr
= SysAllocStringLen(NULL
, dLen
-1);
618 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, bstr
, dLen
);
619 if(len
!= -1) bstr
[dLen
-1] = '\0';
624 static BSTR
QName_from_xmlChar(const xmlChar
*prefix
, const xmlChar
*name
)
629 if(!name
) return NULL
;
631 if(!prefix
|| !*prefix
)
632 return bstr_from_xmlChar(name
);
634 qname
= xmlBuildQName(name
, prefix
, NULL
, 0);
635 bstr
= bstr_from_xmlChar(qname
);
641 static BSTR
pooled_bstr_from_xmlChar(struct bstrpool
*pool
, const xmlChar
*buf
)
643 BSTR pool_entry
= bstr_from_xmlChar(buf
);
645 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
647 SysFreeString(pool_entry
);
654 static BSTR
pooled_bstr_from_xmlCharN(struct bstrpool
*pool
, const xmlChar
*buf
, int len
)
656 BSTR pool_entry
= bstr_from_xmlCharN(buf
, len
);
658 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
660 SysFreeString(pool_entry
);
667 static void format_error_message_from_id(saxlocator
*This
, HRESULT hr
)
669 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
670 xmlStopParser(This
->pParserCtxt
);
673 if (saxreader_has_handler(This
, SAXErrorHandler
))
676 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
,
677 NULL
, hr
, 0, msg
, ARRAY_SIZE(msg
), NULL
))
679 FIXME("MSXML errors not yet supported.\n");
683 if(This
->vbInterface
)
685 BSTR bstrMsg
= SysAllocString(msg
);
686 IVBSAXErrorHandler_fatalError(handler
->vbhandler
,
687 &This
->IVBSAXLocator_iface
, &bstrMsg
, hr
);
688 SysFreeString(bstrMsg
);
691 ISAXErrorHandler_fatalError(handler
->handler
,
692 &This
->ISAXLocator_iface
, msg
, hr
);
696 static void update_position(saxlocator
*This
, BOOL fix_column
)
698 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
699 const xmlChar
*baseP
= This
->pParserCtxt
->input
->base
;
701 This
->line
= xmlSAX2GetLineNumber(This
->pParserCtxt
);
705 for(;p
>=baseP
&& *p
!='\n' && *p
!='\r'; p
--)
710 This
->column
= xmlSAX2GetColumnNumber(This
->pParserCtxt
);
714 /*** IVBSAXAttributes interface ***/
715 static HRESULT WINAPI
ivbsaxattributes_QueryInterface(
716 IVBSAXAttributes
* iface
,
720 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
721 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
722 return IVBSAXLocator_QueryInterface(&This
->IVBSAXLocator_iface
, riid
, ppvObject
);
725 static ULONG WINAPI
ivbsaxattributes_AddRef(IVBSAXAttributes
* iface
)
727 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
728 return IVBSAXLocator_AddRef(&This
->IVBSAXLocator_iface
);
731 static ULONG WINAPI
ivbsaxattributes_Release(IVBSAXAttributes
* iface
)
733 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
734 return IVBSAXLocator_Release(&This
->IVBSAXLocator_iface
);
737 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes
*iface
, UINT
* pctinfo
)
739 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
741 TRACE("(%p)->(%p)\n", This
, pctinfo
);
748 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfo(
749 IVBSAXAttributes
*iface
,
750 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
752 TRACE("%p, %u, %lx, %p.\n", iface
, iTInfo
, lcid
, ppTInfo
);
754 return get_typeinfo(IVBSAXAttributes_tid
, ppTInfo
);
757 static HRESULT WINAPI
ivbsaxattributes_GetIDsOfNames(
758 IVBSAXAttributes
*iface
,
768 TRACE("%p, %s, %p, %u, %lx %p.\n", iface
, debugstr_guid(riid
), rgszNames
, cNames
,
771 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
774 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
777 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
778 ITypeInfo_Release(typeinfo
);
784 static HRESULT WINAPI
ivbsaxattributes_Invoke(
785 IVBSAXAttributes
*iface
,
790 DISPPARAMS
* pDispParams
,
792 EXCEPINFO
* pExcepInfo
,
798 TRACE("%p, %ld, %s, %lx, %d, %p, %p, %p, %p.\n", iface
, dispIdMember
, debugstr_guid(riid
),
799 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
801 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
804 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
805 ITypeInfo_Release(typeinfo
);
811 /*** IVBSAXAttributes methods ***/
812 static HRESULT WINAPI
ivbsaxattributes_get_length(
813 IVBSAXAttributes
* iface
,
816 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
817 return ISAXAttributes_getLength(&This
->ISAXAttributes_iface
, nLength
);
820 static HRESULT WINAPI
ivbsaxattributes_getURI(
821 IVBSAXAttributes
* iface
,
825 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
830 TRACE("(%p)->(%d %p)\n", This
, nIndex
, uri
);
836 hr
= ISAXAttributes_getURI(&This
->ISAXAttributes_iface
, nIndex
, &uriW
, &len
);
840 return return_bstrn(uriW
, len
, uri
);
843 static HRESULT WINAPI
ivbsaxattributes_getLocalName(
844 IVBSAXAttributes
* iface
,
848 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
853 TRACE("(%p)->(%d %p)\n", This
, nIndex
, name
);
859 hr
= ISAXAttributes_getLocalName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
863 return return_bstrn(nameW
, len
, name
);
866 static HRESULT WINAPI
ivbsaxattributes_getQName(
867 IVBSAXAttributes
* iface
,
871 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
876 TRACE("(%p)->(%d %p)\n", This
, nIndex
, QName
);
882 hr
= ISAXAttributes_getQName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
886 return return_bstrn(nameW
, len
, QName
);
889 static HRESULT WINAPI
ivbsaxattributes_getIndexFromName(
890 IVBSAXAttributes
* iface
,
895 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
896 return ISAXAttributes_getIndexFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
897 localName
, SysStringLen(localName
), index
);
900 static HRESULT WINAPI
ivbsaxattributes_getIndexFromQName(
901 IVBSAXAttributes
* iface
,
905 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
906 return ISAXAttributes_getIndexFromQName(&This
->ISAXAttributes_iface
, QName
,
907 SysStringLen(QName
), index
);
910 static HRESULT WINAPI
ivbsaxattributes_getType(
911 IVBSAXAttributes
* iface
,
915 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
920 TRACE("(%p)->(%d %p)\n", This
, nIndex
, type
);
926 hr
= ISAXAttributes_getType(&This
->ISAXAttributes_iface
, nIndex
, &typeW
, &len
);
930 return return_bstrn(typeW
, len
, type
);
933 static HRESULT WINAPI
ivbsaxattributes_getTypeFromName(
934 IVBSAXAttributes
* iface
,
939 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
944 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), type
);
950 hr
= ISAXAttributes_getTypeFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
951 localName
, SysStringLen(localName
), &typeW
, &len
);
955 return return_bstrn(typeW
, len
, type
);
958 static HRESULT WINAPI
ivbsaxattributes_getTypeFromQName(
959 IVBSAXAttributes
* iface
,
963 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
968 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), type
);
974 hr
= ISAXAttributes_getTypeFromQName(&This
->ISAXAttributes_iface
, QName
, SysStringLen(QName
),
979 return return_bstrn(typeW
, len
, type
);
982 static HRESULT WINAPI
ivbsaxattributes_getValue(
983 IVBSAXAttributes
* iface
,
987 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
992 TRACE("(%p)->(%d %p)\n", This
, nIndex
, value
);
998 hr
= ISAXAttributes_getValue(&This
->ISAXAttributes_iface
, nIndex
, &valueW
, &len
);
1002 return return_bstrn(valueW
, len
, value
);
1005 static HRESULT WINAPI
ivbsaxattributes_getValueFromName(
1006 IVBSAXAttributes
* iface
,
1011 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1012 const WCHAR
*valueW
;
1016 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), value
);
1022 hr
= ISAXAttributes_getValueFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
1023 localName
, SysStringLen(localName
), &valueW
, &len
);
1027 return return_bstrn(valueW
, len
, value
);
1030 static HRESULT WINAPI
ivbsaxattributes_getValueFromQName(
1031 IVBSAXAttributes
* iface
,
1035 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1036 const WCHAR
*valueW
;
1040 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), value
);
1046 hr
= ISAXAttributes_getValueFromQName(&This
->ISAXAttributes_iface
, QName
,
1047 SysStringLen(QName
), &valueW
, &len
);
1051 return return_bstrn(valueW
, len
, value
);
1054 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl
=
1056 ivbsaxattributes_QueryInterface
,
1057 ivbsaxattributes_AddRef
,
1058 ivbsaxattributes_Release
,
1059 ivbsaxattributes_GetTypeInfoCount
,
1060 ivbsaxattributes_GetTypeInfo
,
1061 ivbsaxattributes_GetIDsOfNames
,
1062 ivbsaxattributes_Invoke
,
1063 ivbsaxattributes_get_length
,
1064 ivbsaxattributes_getURI
,
1065 ivbsaxattributes_getLocalName
,
1066 ivbsaxattributes_getQName
,
1067 ivbsaxattributes_getIndexFromName
,
1068 ivbsaxattributes_getIndexFromQName
,
1069 ivbsaxattributes_getType
,
1070 ivbsaxattributes_getTypeFromName
,
1071 ivbsaxattributes_getTypeFromQName
,
1072 ivbsaxattributes_getValue
,
1073 ivbsaxattributes_getValueFromName
,
1074 ivbsaxattributes_getValueFromQName
1077 /*** ISAXAttributes interface ***/
1078 /*** IUnknown methods ***/
1079 static HRESULT WINAPI
isaxattributes_QueryInterface(
1080 ISAXAttributes
* iface
,
1084 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1085 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
1086 return ISAXLocator_QueryInterface(&This
->ISAXLocator_iface
, riid
, ppvObject
);
1089 static ULONG WINAPI
isaxattributes_AddRef(ISAXAttributes
* iface
)
1091 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1092 TRACE("%p\n", This
);
1093 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
1096 static ULONG WINAPI
isaxattributes_Release(ISAXAttributes
* iface
)
1098 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1100 TRACE("%p\n", This
);
1101 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
1104 /*** ISAXAttributes methods ***/
1105 static HRESULT WINAPI
isaxattributes_getLength(
1106 ISAXAttributes
* iface
,
1109 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1111 *length
= This
->attr_count
;
1112 TRACE("Length set to %d\n", *length
);
1116 static inline BOOL
is_valid_attr_index(const saxlocator
*locator
, int index
)
1118 return index
< locator
->attr_count
&& index
>= 0;
1121 static HRESULT WINAPI
isaxattributes_getURI(
1122 ISAXAttributes
* iface
,
1127 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1128 TRACE("(%p)->(%d)\n", This
, index
);
1130 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1131 if(!url
|| !size
) return E_POINTER
;
1133 *size
= SysStringLen(This
->attributes
[index
].szURI
);
1134 *url
= This
->attributes
[index
].szURI
;
1136 TRACE("(%s:%d)\n", debugstr_w(This
->attributes
[index
].szURI
), *size
);
1141 static HRESULT WINAPI
isaxattributes_getLocalName(
1142 ISAXAttributes
* iface
,
1144 const WCHAR
**pLocalName
,
1145 int *pLocalNameLength
)
1147 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1148 TRACE("(%p)->(%d)\n", This
, index
);
1150 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1151 if(!pLocalName
|| !pLocalNameLength
) return E_POINTER
;
1153 *pLocalNameLength
= SysStringLen(This
->attributes
[index
].szLocalname
);
1154 *pLocalName
= This
->attributes
[index
].szLocalname
;
1159 static HRESULT WINAPI
isaxattributes_getQName(
1160 ISAXAttributes
* iface
,
1162 const WCHAR
**pQName
,
1165 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1166 TRACE("(%p)->(%d)\n", This
, index
);
1168 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1169 if(!pQName
|| !pQNameLength
) return E_POINTER
;
1171 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1172 *pQName
= This
->attributes
[index
].szQName
;
1177 static HRESULT WINAPI
isaxattributes_getName(
1178 ISAXAttributes
* iface
,
1182 const WCHAR
**localName
,
1183 int *pLocalNameSize
,
1184 const WCHAR
**QName
,
1187 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1188 TRACE("(%p)->(%d)\n", This
, index
);
1190 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1191 if(!uri
|| !pUriLength
|| !localName
|| !pLocalNameSize
1192 || !QName
|| !pQNameLength
) return E_POINTER
;
1194 *pUriLength
= SysStringLen(This
->attributes
[index
].szURI
);
1195 *uri
= This
->attributes
[index
].szURI
;
1196 *pLocalNameSize
= SysStringLen(This
->attributes
[index
].szLocalname
);
1197 *localName
= This
->attributes
[index
].szLocalname
;
1198 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1199 *QName
= This
->attributes
[index
].szQName
;
1201 TRACE("(%s, %s, %s)\n", debugstr_w(*uri
), debugstr_w(*localName
), debugstr_w(*QName
));
1206 static HRESULT WINAPI
isaxattributes_getIndexFromName(
1207 ISAXAttributes
* iface
,
1210 const WCHAR
*pLocalName
,
1211 int cocalNameLength
,
1214 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1216 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), cUriLength
,
1217 debugstr_w(pLocalName
), cocalNameLength
);
1219 if(!pUri
|| !pLocalName
|| !index
) return E_POINTER
;
1221 for(i
=0; i
<This
->attr_count
; i
++)
1223 if(cUriLength
!=SysStringLen(This
->attributes
[i
].szURI
)
1224 || cocalNameLength
!=SysStringLen(This
->attributes
[i
].szLocalname
))
1226 if(cUriLength
&& memcmp(pUri
, This
->attributes
[i
].szURI
,
1227 sizeof(WCHAR
)*cUriLength
))
1229 if(cocalNameLength
&& memcmp(pLocalName
, This
->attributes
[i
].szLocalname
,
1230 sizeof(WCHAR
)*cocalNameLength
))
1237 return E_INVALIDARG
;
1240 static HRESULT WINAPI
isaxattributes_getIndexFromQName(
1241 ISAXAttributes
* iface
,
1242 const WCHAR
*pQName
,
1246 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1248 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQNameLength
);
1250 if(!pQName
|| !index
) return E_POINTER
;
1251 if(!nQNameLength
) return E_INVALIDARG
;
1253 for(i
=0; i
<This
->attr_count
; i
++)
1255 if(nQNameLength
!=SysStringLen(This
->attributes
[i
].szQName
)) continue;
1256 if(memcmp(pQName
, This
->attributes
[i
].szQName
, sizeof(WCHAR
)*nQNameLength
)) continue;
1262 return E_INVALIDARG
;
1265 static HRESULT WINAPI
isaxattributes_getType(
1266 ISAXAttributes
* iface
,
1268 const WCHAR
**pType
,
1271 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1273 FIXME("(%p)->(%d) stub\n", This
, nIndex
);
1277 static HRESULT WINAPI
isaxattributes_getTypeFromName(
1278 ISAXAttributes
* iface
,
1281 const WCHAR
*pLocalName
,
1283 const WCHAR
**pType
,
1286 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1288 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This
, debugstr_w(pUri
), nUri
,
1289 debugstr_w(pLocalName
), nLocalName
);
1293 static HRESULT WINAPI
isaxattributes_getTypeFromQName(
1294 ISAXAttributes
* iface
,
1295 const WCHAR
*pQName
,
1297 const WCHAR
**pType
,
1300 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1302 FIXME("(%p)->(%s, %d) stub\n", This
, debugstr_w(pQName
), nQName
);
1306 static HRESULT WINAPI
isaxattributes_getValue(
1307 ISAXAttributes
* iface
,
1309 const WCHAR
**value
,
1312 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1313 TRACE("(%p)->(%d)\n", This
, index
);
1315 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1316 if(!value
|| !nValue
) return E_POINTER
;
1318 *nValue
= SysStringLen(This
->attributes
[index
].szValue
);
1319 *value
= This
->attributes
[index
].szValue
;
1321 TRACE("(%s:%d)\n", debugstr_w(*value
), *nValue
);
1326 static HRESULT WINAPI
isaxattributes_getValueFromName(
1327 ISAXAttributes
* iface
,
1330 const WCHAR
*pLocalName
,
1332 const WCHAR
**pValue
,
1337 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1338 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), nUri
,
1339 debugstr_w(pLocalName
), nLocalName
);
1341 hr
= ISAXAttributes_getIndexFromName(iface
,
1342 pUri
, nUri
, pLocalName
, nLocalName
, &index
);
1343 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1348 static HRESULT WINAPI
isaxattributes_getValueFromQName(
1349 ISAXAttributes
* iface
,
1350 const WCHAR
*pQName
,
1352 const WCHAR
**pValue
,
1357 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1358 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQName
);
1360 hr
= ISAXAttributes_getIndexFromQName(iface
, pQName
, nQName
, &index
);
1361 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1366 static const struct ISAXAttributesVtbl isaxattributes_vtbl
=
1368 isaxattributes_QueryInterface
,
1369 isaxattributes_AddRef
,
1370 isaxattributes_Release
,
1371 isaxattributes_getLength
,
1372 isaxattributes_getURI
,
1373 isaxattributes_getLocalName
,
1374 isaxattributes_getQName
,
1375 isaxattributes_getName
,
1376 isaxattributes_getIndexFromName
,
1377 isaxattributes_getIndexFromQName
,
1378 isaxattributes_getType
,
1379 isaxattributes_getTypeFromName
,
1380 isaxattributes_getTypeFromQName
,
1381 isaxattributes_getValue
,
1382 isaxattributes_getValueFromName
,
1383 isaxattributes_getValueFromQName
1386 /* Libxml2 escapes '&' back to char reference '&' in attribute value,
1387 so when document has escaped value with '&' it's parsed to '&' and then
1388 escaped to '&'. This function takes care of ampersands only. */
1389 static BSTR
saxreader_get_unescaped_value(const xmlChar
*buf
, int len
)
1391 static const WCHAR ampescW
[] = {'&','#','3','8',';',0};
1392 WCHAR
*dest
, *ptrW
, *str
;
1399 str_len
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
1400 if (len
!= -1) str_len
++;
1402 str
= heap_alloc(str_len
*sizeof(WCHAR
));
1403 if (!str
) return NULL
;
1405 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, str
, str_len
);
1406 if (len
!= -1) str
[str_len
-1] = 0;
1409 while ((dest
= wcsstr(ptrW
, ampescW
)))
1413 /* leave first '&' from a reference as a value */
1414 src
= dest
+ ARRAY_SIZE(ampescW
) - 1;
1417 /* move together with null terminator */
1418 memmove(dest
, src
, (lstrlenW(src
) + 1)*sizeof(WCHAR
));
1423 bstr
= SysAllocString(str
);
1429 static void free_attribute_values(saxlocator
*locator
)
1433 for (i
= 0; i
< locator
->attr_count
; i
++)
1435 SysFreeString(locator
->attributes
[i
].szLocalname
);
1436 locator
->attributes
[i
].szLocalname
= NULL
;
1438 SysFreeString(locator
->attributes
[i
].szValue
);
1439 locator
->attributes
[i
].szValue
= NULL
;
1441 SysFreeString(locator
->attributes
[i
].szQName
);
1442 locator
->attributes
[i
].szQName
= NULL
;
1446 static HRESULT
SAXAttributes_populate(saxlocator
*locator
,
1447 int nb_namespaces
, const xmlChar
**xmlNamespaces
,
1448 int nb_attributes
, const xmlChar
**xmlAttributes
)
1450 static const xmlChar xmlns
[] = "xmlns";
1451 static const WCHAR xmlnsW
[] = { 'x','m','l','n','s',0 };
1453 struct _attributes
*attrs
;
1456 /* skip namespace definitions */
1457 if ((locator
->saxreader
->features
& NamespacePrefixes
) == 0)
1460 locator
->attr_count
= nb_namespaces
+ nb_attributes
;
1461 if(locator
->attr_count
> locator
->attr_alloc_count
)
1463 int new_size
= locator
->attr_count
* 2;
1464 attrs
= heap_realloc_zero(locator
->attributes
, new_size
* sizeof(struct _attributes
));
1467 free_attribute_values(locator
);
1468 locator
->attr_count
= 0;
1469 return E_OUTOFMEMORY
;
1471 locator
->attributes
= attrs
;
1472 locator
->attr_alloc_count
= new_size
;
1476 attrs
= locator
->attributes
;
1479 for (i
= 0; i
< nb_namespaces
; i
++)
1481 SysFreeString(attrs
[nb_attributes
+i
].szLocalname
);
1482 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1484 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1486 SysFreeString(attrs
[nb_attributes
+i
].szValue
);
1487 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1489 SysFreeString(attrs
[nb_attributes
+i
].szQName
);
1490 if(!xmlNamespaces
[2*i
])
1491 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1493 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1496 for (i
= 0; i
< nb_attributes
; i
++)
1498 static const xmlChar xmlA
[] = "xml";
1500 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1501 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1503 /* that's an important feature to keep same uri pointer for every reported attribute */
1504 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1506 SysFreeString(attrs
[i
].szLocalname
);
1507 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1509 SysFreeString(attrs
[i
].szValue
);
1510 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1512 SysFreeString(attrs
[i
].szQName
);
1513 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1], xmlAttributes
[i
*5]);
1519 /*** LibXML callbacks ***/
1520 static void libxmlStartDocument(void *ctx
)
1522 saxlocator
*This
= ctx
;
1523 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1526 if (This
->saxreader
->version
>= MSXML4
)
1528 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1529 update_position(This
, FALSE
);
1530 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1532 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1537 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1541 /* store version value, declaration has to contain version attribute */
1542 if (This
->pParserCtxt
->standalone
!= -1)
1544 SysFreeString(This
->saxreader
->xmldecl_version
);
1545 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1548 if (saxreader_has_handler(This
, SAXContentHandler
))
1550 if(This
->vbInterface
)
1551 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1553 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1555 if (sax_callback_failed(This
, hr
))
1556 format_error_message_from_id(This
, hr
);
1560 static void libxmlEndDocument(void *ctx
)
1562 saxlocator
*This
= ctx
;
1563 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1566 if (This
->saxreader
->version
>= MSXML4
) {
1567 update_position(This
, FALSE
);
1568 if(This
->column
> 1)
1576 if(This
->ret
!= S_OK
) return;
1578 if (saxreader_has_handler(This
, SAXContentHandler
))
1580 if(This
->vbInterface
)
1581 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1583 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1585 if (sax_callback_failed(This
, hr
))
1586 format_error_message_from_id(This
, hr
);
1590 static void libxmlStartElementNS(
1592 const xmlChar
*localname
,
1593 const xmlChar
*prefix
,
1596 const xmlChar
**namespaces
,
1599 const xmlChar
**attributes
)
1601 saxlocator
*This
= ctx
;
1602 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1603 element_entry
*element
;
1607 update_position(This
, TRUE
);
1608 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1610 if(This
->saxreader
->version
< MSXML4
)
1613 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1614 push_element_ns(This
, element
);
1616 if (is_namespaces_enabled(This
->saxreader
))
1620 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1622 if (This
->vbInterface
)
1623 hr
= IVBSAXContentHandler_startPrefixMapping(
1625 &element
->ns
[i
].prefix
,
1626 &element
->ns
[i
].uri
);
1628 hr
= ISAXContentHandler_startPrefixMapping(
1630 element
->ns
[i
].prefix
,
1631 SysStringLen(element
->ns
[i
].prefix
),
1633 SysStringLen(element
->ns
[i
].uri
));
1635 if (sax_callback_failed(This
, hr
))
1637 format_error_message_from_id(This
, hr
);
1643 uri
= find_element_uri(This
, URI
);
1644 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1645 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1649 if (is_namespaces_enabled(This
->saxreader
))
1650 local
= element
->local
;
1654 if (This
->vbInterface
)
1655 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1656 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1658 hr
= ISAXContentHandler_startElement(handler
->handler
,
1659 uri
? uri
: &empty_str
, SysStringLen(uri
),
1660 local
? local
: &empty_str
, SysStringLen(local
),
1661 element
->qname
, SysStringLen(element
->qname
),
1662 &This
->ISAXAttributes_iface
);
1664 if (sax_callback_failed(This
, hr
))
1665 format_error_message_from_id(This
, hr
);
1669 static void libxmlEndElementNS(
1671 const xmlChar
*localname
,
1672 const xmlChar
*prefix
,
1675 saxlocator
*This
= ctx
;
1676 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1677 element_entry
*element
;
1682 update_position(This
, FALSE
);
1683 p
= This
->pParserCtxt
->input
->cur
;
1685 if (This
->saxreader
->version
>= MSXML4
)
1688 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1690 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1695 else if(*(p
-1)!='>' || *(p
-2)!='/')
1698 while(p
-2>=This
->pParserCtxt
->input
->base
1699 && *(p
-2)!='<' && *(p
-1)!='/')
1701 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1707 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1710 uri
= find_element_uri(This
, URI
);
1711 element
= pop_element_ns(This
);
1713 if (!saxreader_has_handler(This
, SAXContentHandler
))
1715 free_attribute_values(This
);
1716 This
->attr_count
= 0;
1717 free_element_entry(element
);
1721 if (is_namespaces_enabled(This
->saxreader
))
1722 local
= element
->local
;
1726 if (This
->vbInterface
)
1727 hr
= IVBSAXContentHandler_endElement(
1729 &uri
, &local
, &element
->qname
);
1731 hr
= ISAXContentHandler_endElement(
1733 uri
? uri
: &empty_str
, SysStringLen(uri
),
1734 local
? local
: &empty_str
, SysStringLen(local
),
1735 element
->qname
, SysStringLen(element
->qname
));
1737 free_attribute_values(This
);
1738 This
->attr_count
= 0;
1740 if (sax_callback_failed(This
, hr
))
1742 format_error_message_from_id(This
, hr
);
1743 free_element_entry(element
);
1747 if (is_namespaces_enabled(This
->saxreader
))
1750 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1752 if (This
->vbInterface
)
1753 hr
= IVBSAXContentHandler_endPrefixMapping(
1754 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1756 hr
= ISAXContentHandler_endPrefixMapping(
1757 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1759 if (sax_callback_failed(This
, hr
)) break;
1762 if (sax_callback_failed(This
, hr
))
1763 format_error_message_from_id(This
, hr
);
1766 free_element_entry(element
);
1769 static void libxmlCharacters(
1774 saxlocator
*This
= ctx
;
1778 BOOL lastEvent
= FALSE
;
1780 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1782 update_position(This
, FALSE
);
1783 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1784 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1786 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1791 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1795 if(*(ch
-1)=='\r') cur
--;
1800 while(end
-ch
<len
&& *end
!='\r') end
++;
1811 if (This
->saxreader
->version
>= MSXML4
)
1815 for(p
=cur
; p
!=end
; p
++)
1832 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1833 hr
= saxreader_saxcharacters(This
, Chars
);
1835 if (sax_callback_failed(This
, hr
))
1837 format_error_message_from_id(This
, hr
);
1841 if (This
->saxreader
->version
< MSXML4
)
1842 This
->column
+= end
-cur
;
1855 if(end
-ch
== len
) break;
1859 static void libxmlSetDocumentLocator(
1861 xmlSAXLocatorPtr loc
)
1863 saxlocator
*This
= ctx
;
1864 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1867 if (saxreader_has_handler(This
, SAXContentHandler
))
1869 if(This
->vbInterface
)
1870 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1871 &This
->IVBSAXLocator_iface
);
1873 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1877 format_error_message_from_id(This
, hr
);
1880 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1882 saxlocator
*This
= ctx
;
1883 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1886 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1888 update_position(This
, FALSE
);
1889 while(p
-4>=This
->pParserCtxt
->input
->base
1890 && memcmp(p
-4, "<!--", sizeof(char[4])))
1892 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1898 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1901 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1903 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1905 if (This
->vbInterface
)
1906 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1908 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1911 format_error_message_from_id(This
, hr
);
1914 static void WINAPIV
libxmlFatalError(void *ctx
, const char *msg
, ...)
1916 saxlocator
*This
= ctx
;
1917 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1923 if(This
->ret
!= S_OK
) {
1924 xmlStopParser(This
->pParserCtxt
);
1928 va_start(args
, msg
);
1929 vsprintf(message
, msg
, args
);
1932 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1933 error
= heap_alloc(sizeof(WCHAR
)*len
);
1936 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1937 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1940 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1942 xmlStopParser(This
->pParserCtxt
);
1948 FIXME("Error handling is not compatible.\n");
1950 if(This
->vbInterface
)
1952 BSTR bstrError
= SysAllocString(error
);
1953 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1954 &bstrError
, E_FAIL
);
1955 SysFreeString(bstrError
);
1958 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1962 xmlStopParser(This
->pParserCtxt
);
1966 /* The only reason this helper exists is that CDATA section are reported by chunks,
1967 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1969 This helper should be called for substring with trailing newlines.
1971 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1973 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1976 len
= SysStringLen(bstr
);
1977 ptr
= bstr
+ len
- 1;
1978 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1983 /* replace returns as:
1985 - "\r<char>" -> "\n<char>"
1991 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
1994 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
2001 ret
= SysAllocStringLen(bstr
, len
);
2002 SysFreeString(bstr
);
2006 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
2008 const xmlChar
*start
, *end
;
2009 saxlocator
*locator
= ctx
;
2010 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
2015 update_position(locator
, FALSE
);
2016 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2018 if (locator
->vbInterface
)
2019 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
2021 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
2026 format_error_message_from_id(locator
, hr
);
2036 /* scan for newlines */
2037 if (value
[i
] == '\r' || value
[i
] == '\n')
2039 /* skip newlines/linefeeds */
2042 if (value
[i
] != '\r' && value
[i
] != '\n') break;
2048 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
2049 TRACE("(chunk %s)\n", debugstr_w(chars
));
2050 hr
= saxreader_saxcharacters(locator
, chars
);
2051 SysFreeString(chars
);
2060 /* no newline chars (or last chunk) report as a whole */
2061 if (!end
&& start
== value
)
2064 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
2065 TRACE("(%s)\n", debugstr_w(chars
));
2066 hr
= saxreader_saxcharacters(locator
, chars
);
2067 SysFreeString(chars
);
2070 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2072 if (locator
->vbInterface
)
2073 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
2075 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
2079 format_error_message_from_id(locator
, hr
);
2082 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
2084 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
2085 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
2088 /*** IVBSAXLocator interface ***/
2089 /*** IUnknown methods ***/
2090 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2092 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2094 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2098 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2099 IsEqualGUID( riid
, &IID_IDispatch
) ||
2100 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
2104 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
2106 *ppvObject
= &This
->IVBSAXAttributes_iface
;
2110 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2111 return E_NOINTERFACE
;
2114 IVBSAXLocator_AddRef( iface
);
2119 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
2121 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2122 TRACE("%p\n", This
);
2123 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
2126 static ULONG WINAPI
ivbsaxlocator_Release(IVBSAXLocator
* iface
)
2128 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2129 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
2132 /*** IDispatch methods ***/
2133 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
2135 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2137 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2144 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
2145 IVBSAXLocator
*iface
,
2146 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2148 TRACE("%p, %u, %lx, %p.\n", iface
, iTInfo
, lcid
, ppTInfo
);
2150 return get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2153 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2154 IVBSAXLocator
*iface
,
2156 LPOLESTR
* rgszNames
,
2161 ITypeInfo
*typeinfo
;
2164 TRACE("%p, %s, %p, %u, %lx, %p.\n", iface
, debugstr_guid(riid
), rgszNames
, cNames
,
2167 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2168 return E_INVALIDARG
;
2170 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2173 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2174 ITypeInfo_Release(typeinfo
);
2180 static HRESULT WINAPI
ivbsaxlocator_Invoke(
2181 IVBSAXLocator
*iface
,
2182 DISPID dispIdMember
,
2186 DISPPARAMS
* pDispParams
,
2187 VARIANT
* pVarResult
,
2188 EXCEPINFO
* pExcepInfo
,
2191 ITypeInfo
*typeinfo
;
2194 TRACE("%p, %ld, %s, %lx, %d, %p, %p, %p, %p.\n", iface
, dispIdMember
, debugstr_guid(riid
),
2195 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2197 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2200 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2201 ITypeInfo_Release(typeinfo
);
2207 /*** IVBSAXLocator methods ***/
2208 static HRESULT WINAPI
ivbsaxlocator_get_columnNumber(
2209 IVBSAXLocator
* iface
,
2212 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2213 return ISAXLocator_getColumnNumber(&This
->ISAXLocator_iface
, pnColumn
);
2216 static HRESULT WINAPI
ivbsaxlocator_get_lineNumber(
2217 IVBSAXLocator
* iface
,
2220 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2221 return ISAXLocator_getLineNumber(&This
->ISAXLocator_iface
, pnLine
);
2224 static HRESULT WINAPI
ivbsaxlocator_get_publicId(IVBSAXLocator
* iface
, BSTR
*ret
)
2226 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2227 const WCHAR
*publicidW
;
2230 TRACE("(%p)->(%p)\n", This
, ret
);
2236 hr
= ISAXLocator_getPublicId(&This
->ISAXLocator_iface
, &publicidW
);
2240 return return_bstr(publicidW
, ret
);
2243 static HRESULT WINAPI
ivbsaxlocator_get_systemId(IVBSAXLocator
* iface
, BSTR
*ret
)
2245 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2246 const WCHAR
*systemidW
;
2249 TRACE("(%p)->(%p)\n", This
, ret
);
2255 hr
= ISAXLocator_getSystemId(&This
->ISAXLocator_iface
, &systemidW
);
2259 return return_bstr(systemidW
, ret
);
2262 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl
=
2264 ivbsaxlocator_QueryInterface
,
2265 ivbsaxlocator_AddRef
,
2266 ivbsaxlocator_Release
,
2267 ivbsaxlocator_GetTypeInfoCount
,
2268 ivbsaxlocator_GetTypeInfo
,
2269 ivbsaxlocator_GetIDsOfNames
,
2270 ivbsaxlocator_Invoke
,
2271 ivbsaxlocator_get_columnNumber
,
2272 ivbsaxlocator_get_lineNumber
,
2273 ivbsaxlocator_get_publicId
,
2274 ivbsaxlocator_get_systemId
2277 /*** ISAXLocator interface ***/
2278 /*** IUnknown methods ***/
2279 static HRESULT WINAPI
isaxlocator_QueryInterface(ISAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2281 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2283 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2287 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2288 IsEqualGUID( riid
, &IID_ISAXLocator
))
2292 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
2294 *ppvObject
= &This
->ISAXAttributes_iface
;
2298 WARN("interface %s not implemented\n", debugstr_guid(riid
));
2299 return E_NOINTERFACE
;
2302 ISAXLocator_AddRef( iface
);
2307 static ULONG WINAPI
isaxlocator_AddRef(ISAXLocator
* iface
)
2309 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2310 ULONG ref
= InterlockedIncrement( &This
->ref
);
2311 TRACE("%p, refcount %lu.\n", iface
, ref
);
2315 static ULONG WINAPI
isaxlocator_Release(
2318 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2319 ULONG ref
= InterlockedDecrement( &This
->ref
);
2321 TRACE("%p, refcount %ld.\n", iface
, ref
);
2325 element_entry
*element
, *element2
;
2328 SysFreeString(This
->publicId
);
2329 SysFreeString(This
->systemId
);
2330 SysFreeString(This
->namespaceUri
);
2332 for(index
= 0; index
< This
->attr_alloc_count
; index
++)
2334 SysFreeString(This
->attributes
[index
].szLocalname
);
2335 SysFreeString(This
->attributes
[index
].szValue
);
2336 SysFreeString(This
->attributes
[index
].szQName
);
2338 heap_free(This
->attributes
);
2341 LIST_FOR_EACH_ENTRY_SAFE(element
, element2
, &This
->elements
, element_entry
, entry
)
2343 list_remove(&element
->entry
);
2344 free_element_entry(element
);
2347 ISAXXMLReader_Release(&This
->saxreader
->ISAXXMLReader_iface
);
2354 /*** ISAXLocator methods ***/
2355 static HRESULT WINAPI
isaxlocator_getColumnNumber(
2359 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2361 *pnColumn
= This
->column
;
2365 static HRESULT WINAPI
isaxlocator_getLineNumber(
2369 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2371 *pnLine
= This
->line
;
2375 static HRESULT WINAPI
isaxlocator_getPublicId(
2377 const WCHAR
** ppwchPublicId
)
2380 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2382 SysFreeString(This
->publicId
);
2384 publicId
= bstr_from_xmlChar(xmlSAX2GetPublicId(This
->pParserCtxt
));
2385 if(SysStringLen(publicId
))
2386 This
->publicId
= publicId
;
2389 SysFreeString(publicId
);
2390 This
->publicId
= NULL
;
2393 *ppwchPublicId
= This
->publicId
;
2397 static HRESULT WINAPI
isaxlocator_getSystemId(
2399 const WCHAR
** ppwchSystemId
)
2402 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2404 SysFreeString(This
->systemId
);
2406 systemId
= bstr_from_xmlChar(xmlSAX2GetSystemId(This
->pParserCtxt
));
2407 if(SysStringLen(systemId
))
2408 This
->systemId
= systemId
;
2411 SysFreeString(systemId
);
2412 This
->systemId
= NULL
;
2415 *ppwchSystemId
= This
->systemId
;
2419 static const struct ISAXLocatorVtbl SAXLocatorVtbl
=
2421 isaxlocator_QueryInterface
,
2423 isaxlocator_Release
,
2424 isaxlocator_getColumnNumber
,
2425 isaxlocator_getLineNumber
,
2426 isaxlocator_getPublicId
,
2427 isaxlocator_getSystemId
2430 static HRESULT
SAXLocator_create(saxreader
*reader
, saxlocator
**ppsaxlocator
, BOOL vbInterface
)
2432 static const WCHAR w3xmlns
[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2433 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2435 saxlocator
*locator
;
2437 locator
= heap_alloc( sizeof (*locator
) );
2439 return E_OUTOFMEMORY
;
2441 locator
->IVBSAXLocator_iface
.lpVtbl
= &VBSAXLocatorVtbl
;
2442 locator
->ISAXLocator_iface
.lpVtbl
= &SAXLocatorVtbl
;
2443 locator
->IVBSAXAttributes_iface
.lpVtbl
= &ivbsaxattributes_vtbl
;
2444 locator
->ISAXAttributes_iface
.lpVtbl
= &isaxattributes_vtbl
;
2446 locator
->vbInterface
= vbInterface
;
2448 locator
->saxreader
= reader
;
2449 ISAXXMLReader_AddRef(&reader
->ISAXXMLReader_iface
);
2451 locator
->pParserCtxt
= NULL
;
2452 locator
->publicId
= NULL
;
2453 locator
->systemId
= NULL
;
2454 locator
->line
= reader
->version
< MSXML4
? 0 : 1;
2455 locator
->column
= 0;
2456 locator
->ret
= S_OK
;
2457 if (locator
->saxreader
->version
>= MSXML6
)
2458 locator
->namespaceUri
= SysAllocString(w3xmlns
);
2460 locator
->namespaceUri
= SysAllocStringLen(NULL
, 0);
2461 if(!locator
->namespaceUri
)
2463 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2465 return E_OUTOFMEMORY
;
2468 locator
->attr_alloc_count
= 8;
2469 locator
->attr_count
= 0;
2470 locator
->attributes
= heap_alloc_zero(sizeof(struct _attributes
)*locator
->attr_alloc_count
);
2471 if(!locator
->attributes
)
2473 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2474 SysFreeString(locator
->namespaceUri
);
2476 return E_OUTOFMEMORY
;
2479 list_init(&locator
->elements
);
2481 *ppsaxlocator
= locator
;
2483 TRACE("returning %p\n", *ppsaxlocator
);
2488 /*** SAXXMLReader internal functions ***/
2489 static HRESULT
internal_parseBuffer(saxreader
*This
, const char *buffer
, int size
, BOOL vbInterface
)
2491 xmlCharEncoding encoding
= XML_CHAR_ENCODING_NONE
;
2492 xmlChar
*enc_name
= NULL
;
2493 saxlocator
*locator
;
2496 TRACE("(%p)->(%p %d)\n", This
, buffer
, size
);
2498 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2504 const unsigned char *buff
= (unsigned char*)buffer
;
2506 encoding
= xmlDetectCharEncoding((xmlChar
*)buffer
, 4);
2507 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2508 TRACE("detected encoding: %s\n", enc_name
);
2509 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2510 if ((encoding
== XML_CHAR_ENCODING_UTF8
) &&
2511 buff
[0] == 0xEF && buff
[1] == 0xBB && buff
[2] == 0xBF)
2518 /* if libxml2 detection failed try to guess */
2519 if (encoding
== XML_CHAR_ENCODING_NONE
)
2521 const WCHAR
*ptr
= (WCHAR
*)buffer
;
2522 /* an xml declaration with optional encoding will still be handled by the parser */
2523 if ((size
>= 2) && *ptr
== '<' && ptr
[1] != '?')
2525 enc_name
= (xmlChar
*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE
);
2526 encoding
= XML_CHAR_ENCODING_UTF16LE
;
2529 else if (encoding
== XML_CHAR_ENCODING_UTF8
)
2530 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2534 locator
->pParserCtxt
= xmlCreateMemoryParserCtxt(buffer
, size
);
2535 if (!locator
->pParserCtxt
)
2537 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2543 locator
->pParserCtxt
->encoding
= xmlStrdup(enc_name
);
2544 if (encoding
== XML_CHAR_ENCODING_UTF16LE
) {
2545 TRACE("switching to %s\n", enc_name
);
2546 xmlSwitchEncoding(locator
->pParserCtxt
, encoding
);
2550 xmlFree(locator
->pParserCtxt
->sax
);
2551 locator
->pParserCtxt
->sax
= &locator
->saxreader
->sax
;
2552 locator
->pParserCtxt
->userData
= locator
;
2554 This
->isParsing
= TRUE
;
2555 if(xmlParseDocument(locator
->pParserCtxt
) == -1 && locator
->ret
== S_OK
)
2559 This
->isParsing
= FALSE
;
2561 if(locator
->pParserCtxt
)
2563 locator
->pParserCtxt
->sax
= NULL
;
2564 xmlFreeParserCtxt(locator
->pParserCtxt
);
2565 locator
->pParserCtxt
= NULL
;
2568 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2572 static HRESULT
internal_parseStream(saxreader
*This
, ISequentialStream
*stream
, BOOL vbInterface
)
2574 saxlocator
*locator
;
2581 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2582 if(FAILED(hr
)) return hr
;
2584 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2585 if(FAILED(hr
)) return hr
;
2587 locator
->pParserCtxt
= xmlCreatePushParserCtxt(
2588 &locator
->saxreader
->sax
, locator
,
2589 data
, dataRead
, NULL
);
2590 if(!locator
->pParserCtxt
)
2592 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2596 This
->isParsing
= TRUE
;
2600 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2601 if (FAILED(hr
) || !dataRead
) break;
2603 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, dataRead
, 0);
2604 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2609 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2610 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2614 This
->isParsing
= FALSE
;
2616 xmlFreeParserCtxt(locator
->pParserCtxt
);
2617 locator
->pParserCtxt
= NULL
;
2618 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2622 static HRESULT
internal_parse(
2629 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varInput
));
2631 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2632 free_bstr_pool(&This
->pool
);
2634 switch(V_VT(&varInput
))
2637 case VT_BSTR
|VT_BYREF
:
2639 BSTR str
= V_ISBYREF(&varInput
) ? *V_BSTRREF(&varInput
) : V_BSTR(&varInput
);
2640 hr
= internal_parseBuffer(This
, (const char*)str
, lstrlenW(str
)*sizeof(WCHAR
), vbInterface
);
2643 case VT_ARRAY
|VT_UI1
: {
2645 LONG lBound
, uBound
;
2648 hr
= SafeArrayGetLBound(V_ARRAY(&varInput
), 1, &lBound
);
2649 if(hr
!= S_OK
) break;
2650 hr
= SafeArrayGetUBound(V_ARRAY(&varInput
), 1, &uBound
);
2651 if(hr
!= S_OK
) break;
2652 dataRead
= (uBound
-lBound
)*SafeArrayGetElemsize(V_ARRAY(&varInput
));
2653 hr
= SafeArrayAccessData(V_ARRAY(&varInput
), &pSAData
);
2654 if(hr
!= S_OK
) break;
2655 hr
= internal_parseBuffer(This
, pSAData
, dataRead
, vbInterface
);
2656 SafeArrayUnaccessData(V_ARRAY(&varInput
));
2661 ISequentialStream
*stream
= NULL
;
2662 IXMLDOMDocument
*xmlDoc
;
2664 if (!V_UNKNOWN(&varInput
))
2665 return E_INVALIDARG
;
2667 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2668 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2672 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2673 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2674 SysStringByteLen(bstrData
), vbInterface
);
2675 IXMLDOMDocument_Release(xmlDoc
);
2676 SysFreeString(bstrData
);
2680 /* try base interface first */
2681 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2683 /* this should never happen if IStream is implemented properly, but just in case */
2684 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2688 hr
= internal_parseStream(This
, stream
, vbInterface
);
2689 ISequentialStream_Release(stream
);
2693 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2700 WARN("vt %d not implemented\n", V_VT(&varInput
));
2707 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2709 saxreader
*This
= obj
;
2711 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2714 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2716 saxreader
*This
= obj
;
2718 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2721 static HRESULT
internal_parseURL(saxreader
*reader
, const WCHAR
*url
, BOOL vbInterface
)
2727 TRACE("%p, %s.\n", reader
, debugstr_w(url
));
2729 if (!url
&& reader
->version
< MSXML4
)
2730 return E_INVALIDARG
;
2732 hr
= create_moniker_from_url(url
, &mon
);
2736 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, reader
, &bsc
);
2737 else hr
= bind_url(mon
, internal_onDataAvailable
, reader
, &bsc
);
2738 IMoniker_Release(mon
);
2743 return detach_bsc(bsc
);
2746 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2750 if (V_VT(v
) == VT_EMPTY
)
2751 return saxreader_put_handler(This
, type
, NULL
, vb
);
2755 case SAXDeclHandler
:
2756 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2758 case SAXLexicalHandler
:
2759 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2762 ERR("wrong handler type %d\n", type
);
2771 IUnknown
*handler
= NULL
;
2775 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2776 if (FAILED(hr
)) return hr
;
2779 saxreader_put_handler(This
, type
, handler
, vb
);
2780 if (handler
) IUnknown_Release(handler
);
2784 ERR("value type %d not supported\n", V_VT(v
));
2785 return E_INVALIDARG
;
2791 static HRESULT
internal_putProperty(
2799 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2801 if (This
->isParsing
) return E_FAIL
;
2803 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2804 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2805 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2807 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2808 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2810 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2812 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2813 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2817 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2819 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2820 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2824 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2826 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2829 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2832 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2835 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2838 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2841 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2844 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2847 return E_INVALIDARG
;
2850 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2852 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2854 if (!value
) return E_POINTER
;
2856 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2858 V_VT(value
) = VT_UNKNOWN
;
2859 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2863 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2865 V_VT(value
) = VT_UNKNOWN
;
2866 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2870 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2872 V_VT(value
) = VT_BSTR
;
2873 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2877 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2882 /*** IVBSAXXMLReader interface ***/
2883 /*** IUnknown methods ***/
2884 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2886 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2888 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2892 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2893 IsEqualGUID( riid
, &IID_IDispatch
) ||
2894 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2898 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2900 *ppvObject
= &This
->ISAXXMLReader_iface
;
2902 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2904 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2908 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2909 return E_NOINTERFACE
;
2912 IVBSAXXMLReader_AddRef( iface
);
2917 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2919 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2920 TRACE("%p\n", This
);
2921 return InterlockedIncrement( &This
->ref
);
2924 static ULONG WINAPI
saxxmlreader_Release(
2925 IVBSAXXMLReader
* iface
)
2927 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2930 TRACE("%p\n", This
);
2932 ref
= InterlockedDecrement( &This
->ref
);
2937 for (i
= 0; i
< SAXHandler_Last
; i
++)
2939 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2941 if (saxiface
->handler
)
2942 IUnknown_Release(saxiface
->handler
);
2944 if (saxiface
->vbhandler
)
2945 IUnknown_Release(saxiface
->vbhandler
);
2948 SysFreeString(This
->xmldecl_version
);
2949 free_bstr_pool(&This
->pool
);
2957 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2959 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2960 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2963 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2964 IVBSAXXMLReader
*iface
,
2965 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2967 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2968 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2969 iTInfo
, lcid
, ppTInfo
);
2972 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2973 IVBSAXXMLReader
*iface
,
2975 LPOLESTR
* rgszNames
,
2980 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2981 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
2982 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
2985 static HRESULT WINAPI
saxxmlreader_Invoke(
2986 IVBSAXXMLReader
*iface
,
2987 DISPID dispIdMember
,
2991 DISPPARAMS
* pDispParams
,
2992 VARIANT
* pVarResult
,
2993 EXCEPINFO
* pExcepInfo
,
2996 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2997 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
2998 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3001 /*** IVBSAXXMLReader methods ***/
3002 static HRESULT WINAPI
saxxmlreader_getFeature(
3003 IVBSAXXMLReader
* iface
,
3005 VARIANT_BOOL
*value
)
3007 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3008 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3011 static HRESULT WINAPI
saxxmlreader_putFeature(
3012 IVBSAXXMLReader
* iface
,
3016 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3017 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3020 static HRESULT WINAPI
saxxmlreader_getProperty(
3021 IVBSAXXMLReader
* iface
,
3025 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3026 return internal_getProperty(This
, prop
, value
, TRUE
);
3029 static HRESULT WINAPI
saxxmlreader_putProperty(
3030 IVBSAXXMLReader
* iface
,
3034 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3035 return internal_putProperty(This
, pProp
, value
, TRUE
);
3038 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3039 IVBSAXXMLReader
* iface
,
3040 IVBSAXEntityResolver
**resolver
)
3042 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3043 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3046 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3047 IVBSAXXMLReader
* iface
,
3048 IVBSAXEntityResolver
*resolver
)
3050 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3051 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3054 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3055 IVBSAXXMLReader
* iface
,
3056 IVBSAXContentHandler
**handler
)
3058 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3059 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3062 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3063 IVBSAXXMLReader
* iface
,
3064 IVBSAXContentHandler
*handler
)
3066 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3067 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3070 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3071 IVBSAXXMLReader
* iface
,
3072 IVBSAXDTDHandler
**handler
)
3074 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3075 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3078 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3079 IVBSAXXMLReader
* iface
,
3080 IVBSAXDTDHandler
*handler
)
3082 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3083 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3086 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3087 IVBSAXXMLReader
* iface
,
3088 IVBSAXErrorHandler
**handler
)
3090 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3091 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3094 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3095 IVBSAXXMLReader
* iface
,
3096 IVBSAXErrorHandler
*handler
)
3098 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3099 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3102 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3103 IVBSAXXMLReader
* iface
,
3106 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3108 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3112 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3113 IVBSAXXMLReader
* iface
,
3116 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3117 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3120 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3121 IVBSAXXMLReader
* iface
,
3122 BSTR
*pSecureBaseUrl
)
3124 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3126 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3130 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3131 IVBSAXXMLReader
* iface
,
3134 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3135 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3138 static HRESULT WINAPI
saxxmlreader_parse(
3139 IVBSAXXMLReader
* iface
,
3142 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3143 return internal_parse(This
, varInput
, TRUE
);
3146 static HRESULT WINAPI
saxxmlreader_parseURL(
3147 IVBSAXXMLReader
* iface
,
3150 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3151 return internal_parseURL(This
, url
, TRUE
);
3154 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3156 saxxmlreader_QueryInterface
,
3157 saxxmlreader_AddRef
,
3158 saxxmlreader_Release
,
3159 saxxmlreader_GetTypeInfoCount
,
3160 saxxmlreader_GetTypeInfo
,
3161 saxxmlreader_GetIDsOfNames
,
3162 saxxmlreader_Invoke
,
3163 saxxmlreader_getFeature
,
3164 saxxmlreader_putFeature
,
3165 saxxmlreader_getProperty
,
3166 saxxmlreader_putProperty
,
3167 saxxmlreader_get_entityResolver
,
3168 saxxmlreader_put_entityResolver
,
3169 saxxmlreader_get_contentHandler
,
3170 saxxmlreader_put_contentHandler
,
3171 saxxmlreader_get_dtdHandler
,
3172 saxxmlreader_put_dtdHandler
,
3173 saxxmlreader_get_errorHandler
,
3174 saxxmlreader_put_errorHandler
,
3175 saxxmlreader_get_baseURL
,
3176 saxxmlreader_put_baseURL
,
3177 saxxmlreader_get_secureBaseURL
,
3178 saxxmlreader_put_secureBaseURL
,
3180 saxxmlreader_parseURL
3183 /*** ISAXXMLReader interface ***/
3184 /*** IUnknown methods ***/
3185 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3187 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3188 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3191 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3193 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3194 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3197 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3199 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3200 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3203 /*** ISAXXMLReader methods ***/
3204 static HRESULT WINAPI
isaxxmlreader_getFeature(
3205 ISAXXMLReader
* iface
,
3206 const WCHAR
*feature_name
,
3207 VARIANT_BOOL
*value
)
3209 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3210 saxreader_feature feature
;
3212 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3214 feature
= get_saxreader_feature(feature_name
);
3216 if (This
->version
< MSXML4
&& (feature
== ExhaustiveErrors
|| feature
== SchemaValidation
))
3217 return E_INVALIDARG
;
3219 if (feature
== Namespaces
||
3220 feature
== NamespacePrefixes
||
3221 feature
== ExhaustiveErrors
||
3222 feature
== SchemaValidation
)
3223 return get_feature_value(This
, feature
, value
);
3225 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3229 static HRESULT WINAPI
isaxxmlreader_putFeature(
3230 ISAXXMLReader
* iface
,
3231 const WCHAR
*feature_name
,
3234 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3235 saxreader_feature feature
;
3237 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3239 feature
= get_saxreader_feature(feature_name
);
3241 /* accepted cases */
3242 if ((feature
== ExhaustiveErrors
&& value
== VARIANT_FALSE
) ||
3243 (feature
== SchemaValidation
&& value
== VARIANT_FALSE
) ||
3244 feature
== Namespaces
||
3245 feature
== NamespacePrefixes
)
3247 return set_feature_value(This
, feature
, value
);
3250 if (feature
== LexicalHandlerParEntities
||
3251 feature
== ProhibitDTD
||
3252 feature
== ExternalGeneralEntities
||
3253 feature
== ExternalParameterEntities
)
3255 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3256 return set_feature_value(This
, feature
, value
);
3259 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3263 static HRESULT WINAPI
isaxxmlreader_getProperty(
3264 ISAXXMLReader
* iface
,
3268 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3269 return internal_getProperty(This
, prop
, value
, FALSE
);
3272 static HRESULT WINAPI
isaxxmlreader_putProperty(
3273 ISAXXMLReader
* iface
,
3277 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3278 return internal_putProperty(This
, pProp
, value
, FALSE
);
3281 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3282 ISAXXMLReader
* iface
,
3283 ISAXEntityResolver
**resolver
)
3285 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3286 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3289 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3290 ISAXXMLReader
* iface
,
3291 ISAXEntityResolver
*resolver
)
3293 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3294 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3297 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3298 ISAXXMLReader
* iface
,
3299 ISAXContentHandler
**handler
)
3301 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3302 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3305 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3306 ISAXXMLReader
* iface
,
3307 ISAXContentHandler
*handler
)
3309 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3310 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3313 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3314 ISAXXMLReader
* iface
,
3315 ISAXDTDHandler
**handler
)
3317 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3318 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3321 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3322 ISAXXMLReader
* iface
,
3323 ISAXDTDHandler
*handler
)
3325 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3326 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3329 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3330 ISAXXMLReader
* iface
,
3331 ISAXErrorHandler
**handler
)
3333 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3334 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3337 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3339 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3340 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3343 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3344 ISAXXMLReader
* iface
,
3345 const WCHAR
**base_url
)
3347 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3349 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3353 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3354 ISAXXMLReader
* iface
,
3355 const WCHAR
*pBaseUrl
)
3357 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3359 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3363 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3364 ISAXXMLReader
* iface
,
3365 const WCHAR
**pSecureBaseUrl
)
3367 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3368 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3372 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3373 ISAXXMLReader
* iface
,
3374 const WCHAR
*secureBaseUrl
)
3376 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3378 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3382 static HRESULT WINAPI
isaxxmlreader_parse(
3383 ISAXXMLReader
* iface
,
3386 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3387 return internal_parse(This
, varInput
, FALSE
);
3390 static HRESULT WINAPI
isaxxmlreader_parseURL(
3391 ISAXXMLReader
* iface
,
3394 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3395 return internal_parseURL(This
, url
, FALSE
);
3398 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3400 isaxxmlreader_QueryInterface
,
3401 isaxxmlreader_AddRef
,
3402 isaxxmlreader_Release
,
3403 isaxxmlreader_getFeature
,
3404 isaxxmlreader_putFeature
,
3405 isaxxmlreader_getProperty
,
3406 isaxxmlreader_putProperty
,
3407 isaxxmlreader_getEntityResolver
,
3408 isaxxmlreader_putEntityResolver
,
3409 isaxxmlreader_getContentHandler
,
3410 isaxxmlreader_putContentHandler
,
3411 isaxxmlreader_getDTDHandler
,
3412 isaxxmlreader_putDTDHandler
,
3413 isaxxmlreader_getErrorHandler
,
3414 isaxxmlreader_putErrorHandler
,
3415 isaxxmlreader_getBaseURL
,
3416 isaxxmlreader_putBaseURL
,
3417 isaxxmlreader_getSecureBaseURL
,
3418 isaxxmlreader_putSecureBaseURL
,
3419 isaxxmlreader_parse
,
3420 isaxxmlreader_parseURL
3423 static const tid_t saxreader_iface_tids
[] = {
3424 IVBSAXXMLReader_tid
,
3427 static dispex_static_data_t saxreader_dispex
= {
3429 IVBSAXXMLReader_tid
,
3431 saxreader_iface_tids
3434 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3438 TRACE("(%p)\n", ppObj
);
3440 reader
= heap_alloc( sizeof (*reader
) );
3442 return E_OUTOFMEMORY
;
3444 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3445 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3447 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3448 reader
->isParsing
= FALSE
;
3449 reader
->xmldecl_version
= NULL
;
3450 reader
->pool
.pool
= NULL
;
3451 reader
->pool
.index
= 0;
3452 reader
->pool
.len
= 0;
3453 reader
->features
= Namespaces
| NamespacePrefixes
;
3454 reader
->version
= version
;
3456 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3458 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3459 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3460 reader
->sax
.startDocument
= libxmlStartDocument
;
3461 reader
->sax
.endDocument
= libxmlEndDocument
;
3462 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3463 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3464 reader
->sax
.characters
= libxmlCharacters
;
3465 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3466 reader
->sax
.comment
= libxmlComment
;
3467 reader
->sax
.error
= libxmlFatalError
;
3468 reader
->sax
.fatalError
= libxmlFatalError
;
3469 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3470 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3472 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3474 TRACE("returning iface %p\n", *ppObj
);