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
= malloc(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
? malloc(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
);
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
= malloc(16 * sizeof(*pool
->pool
));
577 else if (pool
->index
== pool
->len
)
579 BSTR
*new_pool
= realloc(pool
->pool
, pool
->len
* 2 * sizeof(*new_pool
));
584 pool
->pool
= new_pool
;
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
]);
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
= malloc(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
= realloc(locator
->attributes
, new_size
* sizeof(*locator
->attributes
));
1467 free_attribute_values(locator
);
1468 locator
->attr_count
= 0;
1469 return E_OUTOFMEMORY
;
1471 memset(attrs
+ locator
->attr_alloc_count
, 0,
1472 (new_size
- locator
->attr_alloc_count
) * sizeof(*locator
->attributes
));
1473 locator
->attributes
= attrs
;
1474 locator
->attr_alloc_count
= new_size
;
1478 attrs
= locator
->attributes
;
1481 for (i
= 0; i
< nb_namespaces
; i
++)
1483 SysFreeString(attrs
[nb_attributes
+i
].szLocalname
);
1484 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1486 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1488 SysFreeString(attrs
[nb_attributes
+i
].szValue
);
1489 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1491 SysFreeString(attrs
[nb_attributes
+i
].szQName
);
1492 if(!xmlNamespaces
[2*i
])
1493 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1495 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1498 for (i
= 0; i
< nb_attributes
; i
++)
1500 static const xmlChar xmlA
[] = "xml";
1502 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1503 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1505 /* that's an important feature to keep same uri pointer for every reported attribute */
1506 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1508 SysFreeString(attrs
[i
].szLocalname
);
1509 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1511 SysFreeString(attrs
[i
].szValue
);
1512 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1514 SysFreeString(attrs
[i
].szQName
);
1515 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1], xmlAttributes
[i
*5]);
1521 /*** LibXML callbacks ***/
1522 static void libxmlStartDocument(void *ctx
)
1524 saxlocator
*This
= ctx
;
1525 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1528 if (This
->saxreader
->version
>= MSXML4
)
1530 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1531 update_position(This
, FALSE
);
1532 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1534 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1539 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1543 /* store version value, declaration has to contain version attribute */
1544 if (This
->pParserCtxt
->standalone
!= -1)
1546 SysFreeString(This
->saxreader
->xmldecl_version
);
1547 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1550 if (saxreader_has_handler(This
, SAXContentHandler
))
1552 if(This
->vbInterface
)
1553 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1555 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1557 if (sax_callback_failed(This
, hr
))
1558 format_error_message_from_id(This
, hr
);
1562 static void libxmlEndDocument(void *ctx
)
1564 saxlocator
*This
= ctx
;
1565 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1568 if (This
->saxreader
->version
>= MSXML4
) {
1569 update_position(This
, FALSE
);
1570 if(This
->column
> 1)
1578 if(This
->ret
!= S_OK
) return;
1580 if (saxreader_has_handler(This
, SAXContentHandler
))
1582 if(This
->vbInterface
)
1583 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1585 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1587 if (sax_callback_failed(This
, hr
))
1588 format_error_message_from_id(This
, hr
);
1592 static void libxmlStartElementNS(
1594 const xmlChar
*localname
,
1595 const xmlChar
*prefix
,
1598 const xmlChar
**namespaces
,
1601 const xmlChar
**attributes
)
1603 saxlocator
*This
= ctx
;
1604 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1605 element_entry
*element
;
1609 update_position(This
, TRUE
);
1610 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1612 if(This
->saxreader
->version
< MSXML4
)
1615 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1616 push_element_ns(This
, element
);
1618 if (is_namespaces_enabled(This
->saxreader
))
1622 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1624 if (This
->vbInterface
)
1625 hr
= IVBSAXContentHandler_startPrefixMapping(
1627 &element
->ns
[i
].prefix
,
1628 &element
->ns
[i
].uri
);
1630 hr
= ISAXContentHandler_startPrefixMapping(
1632 element
->ns
[i
].prefix
,
1633 SysStringLen(element
->ns
[i
].prefix
),
1635 SysStringLen(element
->ns
[i
].uri
));
1637 if (sax_callback_failed(This
, hr
))
1639 format_error_message_from_id(This
, hr
);
1645 uri
= find_element_uri(This
, URI
);
1646 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1647 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1651 if (is_namespaces_enabled(This
->saxreader
))
1652 local
= element
->local
;
1656 if (This
->vbInterface
)
1657 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1658 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1660 hr
= ISAXContentHandler_startElement(handler
->handler
,
1661 uri
? uri
: &empty_str
, SysStringLen(uri
),
1662 local
? local
: &empty_str
, SysStringLen(local
),
1663 element
->qname
, SysStringLen(element
->qname
),
1664 &This
->ISAXAttributes_iface
);
1666 if (sax_callback_failed(This
, hr
))
1667 format_error_message_from_id(This
, hr
);
1671 static void libxmlEndElementNS(
1673 const xmlChar
*localname
,
1674 const xmlChar
*prefix
,
1677 saxlocator
*This
= ctx
;
1678 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1679 element_entry
*element
;
1684 update_position(This
, FALSE
);
1685 p
= This
->pParserCtxt
->input
->cur
;
1687 if (This
->saxreader
->version
>= MSXML4
)
1690 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1692 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1697 else if(*(p
-1)!='>' || *(p
-2)!='/')
1700 while(p
-2>=This
->pParserCtxt
->input
->base
1701 && *(p
-2)!='<' && *(p
-1)!='/')
1703 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1709 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1712 uri
= find_element_uri(This
, URI
);
1713 element
= pop_element_ns(This
);
1715 if (!saxreader_has_handler(This
, SAXContentHandler
))
1717 free_attribute_values(This
);
1718 This
->attr_count
= 0;
1719 free_element_entry(element
);
1723 if (is_namespaces_enabled(This
->saxreader
))
1724 local
= element
->local
;
1728 if (This
->vbInterface
)
1729 hr
= IVBSAXContentHandler_endElement(
1731 &uri
, &local
, &element
->qname
);
1733 hr
= ISAXContentHandler_endElement(
1735 uri
? uri
: &empty_str
, SysStringLen(uri
),
1736 local
? local
: &empty_str
, SysStringLen(local
),
1737 element
->qname
, SysStringLen(element
->qname
));
1739 free_attribute_values(This
);
1740 This
->attr_count
= 0;
1742 if (sax_callback_failed(This
, hr
))
1744 format_error_message_from_id(This
, hr
);
1745 free_element_entry(element
);
1749 if (is_namespaces_enabled(This
->saxreader
))
1752 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1754 if (This
->vbInterface
)
1755 hr
= IVBSAXContentHandler_endPrefixMapping(
1756 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1758 hr
= ISAXContentHandler_endPrefixMapping(
1759 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1761 if (sax_callback_failed(This
, hr
)) break;
1764 if (sax_callback_failed(This
, hr
))
1765 format_error_message_from_id(This
, hr
);
1768 free_element_entry(element
);
1771 static void libxmlCharacters(
1776 saxlocator
*This
= ctx
;
1780 BOOL lastEvent
= FALSE
;
1782 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1784 update_position(This
, FALSE
);
1785 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1786 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1788 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1793 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1797 if(*(ch
-1)=='\r') cur
--;
1802 while(end
-ch
<len
&& *end
!='\r') end
++;
1813 if (This
->saxreader
->version
>= MSXML4
)
1817 for(p
=cur
; p
!=end
; p
++)
1834 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1835 hr
= saxreader_saxcharacters(This
, Chars
);
1837 if (sax_callback_failed(This
, hr
))
1839 format_error_message_from_id(This
, hr
);
1843 if (This
->saxreader
->version
< MSXML4
)
1844 This
->column
+= end
-cur
;
1857 if(end
-ch
== len
) break;
1861 static void libxmlSetDocumentLocator(
1863 xmlSAXLocatorPtr loc
)
1865 saxlocator
*This
= ctx
;
1866 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1869 if (saxreader_has_handler(This
, SAXContentHandler
))
1871 if(This
->vbInterface
)
1872 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1873 &This
->IVBSAXLocator_iface
);
1875 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1879 format_error_message_from_id(This
, hr
);
1882 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1884 saxlocator
*This
= ctx
;
1885 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1888 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1890 update_position(This
, FALSE
);
1891 while(p
-4>=This
->pParserCtxt
->input
->base
1892 && memcmp(p
-4, "<!--", sizeof(char[4])))
1894 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1900 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1903 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1905 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1907 if (This
->vbInterface
)
1908 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1910 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1913 format_error_message_from_id(This
, hr
);
1916 static void WINAPIV
libxmlFatalError(void *ctx
, const char *msg
, ...)
1918 saxlocator
*This
= ctx
;
1919 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1925 if(This
->ret
!= S_OK
) {
1926 xmlStopParser(This
->pParserCtxt
);
1930 va_start(args
, msg
);
1931 vsprintf(message
, msg
, args
);
1934 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1935 error
= malloc(sizeof(WCHAR
) * len
);
1938 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1939 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1942 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1944 xmlStopParser(This
->pParserCtxt
);
1950 FIXME("Error handling is not compatible.\n");
1952 if(This
->vbInterface
)
1954 BSTR bstrError
= SysAllocString(error
);
1955 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1956 &bstrError
, E_FAIL
);
1957 SysFreeString(bstrError
);
1960 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1964 xmlStopParser(This
->pParserCtxt
);
1968 /* The only reason this helper exists is that CDATA section are reported by chunks,
1969 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1971 This helper should be called for substring with trailing newlines.
1973 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1975 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1978 len
= SysStringLen(bstr
);
1979 ptr
= bstr
+ len
- 1;
1980 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1985 /* replace returns as:
1987 - "\r<char>" -> "\n<char>"
1993 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
1996 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
2003 ret
= SysAllocStringLen(bstr
, len
);
2004 SysFreeString(bstr
);
2008 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
2010 const xmlChar
*start
, *end
;
2011 saxlocator
*locator
= ctx
;
2012 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
2017 update_position(locator
, FALSE
);
2018 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2020 if (locator
->vbInterface
)
2021 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
2023 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
2028 format_error_message_from_id(locator
, hr
);
2038 /* scan for newlines */
2039 if (value
[i
] == '\r' || value
[i
] == '\n')
2041 /* skip newlines/linefeeds */
2044 if (value
[i
] != '\r' && value
[i
] != '\n') break;
2050 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
2051 TRACE("(chunk %s)\n", debugstr_w(chars
));
2052 hr
= saxreader_saxcharacters(locator
, chars
);
2053 SysFreeString(chars
);
2062 /* no newline chars (or last chunk) report as a whole */
2063 if (!end
&& start
== value
)
2066 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
2067 TRACE("(%s)\n", debugstr_w(chars
));
2068 hr
= saxreader_saxcharacters(locator
, chars
);
2069 SysFreeString(chars
);
2072 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2074 if (locator
->vbInterface
)
2075 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
2077 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
2081 format_error_message_from_id(locator
, hr
);
2084 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
2086 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
2087 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
2090 /*** IVBSAXLocator interface ***/
2091 /*** IUnknown methods ***/
2092 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2094 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2096 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2100 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2101 IsEqualGUID( riid
, &IID_IDispatch
) ||
2102 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
2106 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
2108 *ppvObject
= &This
->IVBSAXAttributes_iface
;
2112 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2113 return E_NOINTERFACE
;
2116 IVBSAXLocator_AddRef( iface
);
2121 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
2123 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2124 TRACE("%p\n", This
);
2125 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
2128 static ULONG WINAPI
ivbsaxlocator_Release(IVBSAXLocator
* iface
)
2130 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2131 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
2134 /*** IDispatch methods ***/
2135 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
2137 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2139 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2146 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
2147 IVBSAXLocator
*iface
,
2148 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2150 TRACE("%p, %u, %lx, %p.\n", iface
, iTInfo
, lcid
, ppTInfo
);
2152 return get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2155 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2156 IVBSAXLocator
*iface
,
2158 LPOLESTR
* rgszNames
,
2163 ITypeInfo
*typeinfo
;
2166 TRACE("%p, %s, %p, %u, %lx, %p.\n", iface
, debugstr_guid(riid
), rgszNames
, cNames
,
2169 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2170 return E_INVALIDARG
;
2172 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2175 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2176 ITypeInfo_Release(typeinfo
);
2182 static HRESULT WINAPI
ivbsaxlocator_Invoke(
2183 IVBSAXLocator
*iface
,
2184 DISPID dispIdMember
,
2188 DISPPARAMS
* pDispParams
,
2189 VARIANT
* pVarResult
,
2190 EXCEPINFO
* pExcepInfo
,
2193 ITypeInfo
*typeinfo
;
2196 TRACE("%p, %ld, %s, %lx, %d, %p, %p, %p, %p.\n", iface
, dispIdMember
, debugstr_guid(riid
),
2197 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2199 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2202 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2203 ITypeInfo_Release(typeinfo
);
2209 /*** IVBSAXLocator methods ***/
2210 static HRESULT WINAPI
ivbsaxlocator_get_columnNumber(
2211 IVBSAXLocator
* iface
,
2214 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2215 return ISAXLocator_getColumnNumber(&This
->ISAXLocator_iface
, pnColumn
);
2218 static HRESULT WINAPI
ivbsaxlocator_get_lineNumber(
2219 IVBSAXLocator
* iface
,
2222 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2223 return ISAXLocator_getLineNumber(&This
->ISAXLocator_iface
, pnLine
);
2226 static HRESULT WINAPI
ivbsaxlocator_get_publicId(IVBSAXLocator
* iface
, BSTR
*ret
)
2228 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2229 const WCHAR
*publicidW
;
2232 TRACE("(%p)->(%p)\n", This
, ret
);
2238 hr
= ISAXLocator_getPublicId(&This
->ISAXLocator_iface
, &publicidW
);
2242 return return_bstr(publicidW
, ret
);
2245 static HRESULT WINAPI
ivbsaxlocator_get_systemId(IVBSAXLocator
* iface
, BSTR
*ret
)
2247 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2248 const WCHAR
*systemidW
;
2251 TRACE("(%p)->(%p)\n", This
, ret
);
2257 hr
= ISAXLocator_getSystemId(&This
->ISAXLocator_iface
, &systemidW
);
2261 return return_bstr(systemidW
, ret
);
2264 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl
=
2266 ivbsaxlocator_QueryInterface
,
2267 ivbsaxlocator_AddRef
,
2268 ivbsaxlocator_Release
,
2269 ivbsaxlocator_GetTypeInfoCount
,
2270 ivbsaxlocator_GetTypeInfo
,
2271 ivbsaxlocator_GetIDsOfNames
,
2272 ivbsaxlocator_Invoke
,
2273 ivbsaxlocator_get_columnNumber
,
2274 ivbsaxlocator_get_lineNumber
,
2275 ivbsaxlocator_get_publicId
,
2276 ivbsaxlocator_get_systemId
2279 /*** ISAXLocator interface ***/
2280 /*** IUnknown methods ***/
2281 static HRESULT WINAPI
isaxlocator_QueryInterface(ISAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2283 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2285 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2289 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2290 IsEqualGUID( riid
, &IID_ISAXLocator
))
2294 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
2296 *ppvObject
= &This
->ISAXAttributes_iface
;
2300 WARN("interface %s not implemented\n", debugstr_guid(riid
));
2301 return E_NOINTERFACE
;
2304 ISAXLocator_AddRef( iface
);
2309 static ULONG WINAPI
isaxlocator_AddRef(ISAXLocator
* iface
)
2311 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2312 ULONG ref
= InterlockedIncrement( &This
->ref
);
2313 TRACE("%p, refcount %lu.\n", iface
, ref
);
2317 static ULONG WINAPI
isaxlocator_Release(
2320 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2321 ULONG ref
= InterlockedDecrement( &This
->ref
);
2323 TRACE("%p, refcount %ld.\n", iface
, ref
);
2327 element_entry
*element
, *element2
;
2330 SysFreeString(This
->publicId
);
2331 SysFreeString(This
->systemId
);
2332 SysFreeString(This
->namespaceUri
);
2334 for(index
= 0; index
< This
->attr_alloc_count
; index
++)
2336 SysFreeString(This
->attributes
[index
].szLocalname
);
2337 SysFreeString(This
->attributes
[index
].szValue
);
2338 SysFreeString(This
->attributes
[index
].szQName
);
2340 free(This
->attributes
);
2343 LIST_FOR_EACH_ENTRY_SAFE(element
, element2
, &This
->elements
, element_entry
, entry
)
2345 list_remove(&element
->entry
);
2346 free_element_entry(element
);
2349 ISAXXMLReader_Release(&This
->saxreader
->ISAXXMLReader_iface
);
2356 /*** ISAXLocator methods ***/
2357 static HRESULT WINAPI
isaxlocator_getColumnNumber(
2361 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2363 *pnColumn
= This
->column
;
2367 static HRESULT WINAPI
isaxlocator_getLineNumber(
2371 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2373 *pnLine
= This
->line
;
2377 static HRESULT WINAPI
isaxlocator_getPublicId(
2379 const WCHAR
** ppwchPublicId
)
2382 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2384 SysFreeString(This
->publicId
);
2386 publicId
= bstr_from_xmlChar(xmlSAX2GetPublicId(This
->pParserCtxt
));
2387 if(SysStringLen(publicId
))
2388 This
->publicId
= publicId
;
2391 SysFreeString(publicId
);
2392 This
->publicId
= NULL
;
2395 *ppwchPublicId
= This
->publicId
;
2399 static HRESULT WINAPI
isaxlocator_getSystemId(
2401 const WCHAR
** ppwchSystemId
)
2404 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2406 SysFreeString(This
->systemId
);
2408 systemId
= bstr_from_xmlChar(xmlSAX2GetSystemId(This
->pParserCtxt
));
2409 if(SysStringLen(systemId
))
2410 This
->systemId
= systemId
;
2413 SysFreeString(systemId
);
2414 This
->systemId
= NULL
;
2417 *ppwchSystemId
= This
->systemId
;
2421 static const struct ISAXLocatorVtbl SAXLocatorVtbl
=
2423 isaxlocator_QueryInterface
,
2425 isaxlocator_Release
,
2426 isaxlocator_getColumnNumber
,
2427 isaxlocator_getLineNumber
,
2428 isaxlocator_getPublicId
,
2429 isaxlocator_getSystemId
2432 static HRESULT
SAXLocator_create(saxreader
*reader
, saxlocator
**ppsaxlocator
, BOOL vbInterface
)
2434 static const WCHAR w3xmlns
[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2435 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2437 saxlocator
*locator
;
2439 locator
= malloc(sizeof(*locator
));
2441 return E_OUTOFMEMORY
;
2443 locator
->IVBSAXLocator_iface
.lpVtbl
= &VBSAXLocatorVtbl
;
2444 locator
->ISAXLocator_iface
.lpVtbl
= &SAXLocatorVtbl
;
2445 locator
->IVBSAXAttributes_iface
.lpVtbl
= &ivbsaxattributes_vtbl
;
2446 locator
->ISAXAttributes_iface
.lpVtbl
= &isaxattributes_vtbl
;
2448 locator
->vbInterface
= vbInterface
;
2450 locator
->saxreader
= reader
;
2451 ISAXXMLReader_AddRef(&reader
->ISAXXMLReader_iface
);
2453 locator
->pParserCtxt
= NULL
;
2454 locator
->publicId
= NULL
;
2455 locator
->systemId
= NULL
;
2456 locator
->line
= reader
->version
< MSXML4
? 0 : 1;
2457 locator
->column
= 0;
2458 locator
->ret
= S_OK
;
2459 if (locator
->saxreader
->version
>= MSXML6
)
2460 locator
->namespaceUri
= SysAllocString(w3xmlns
);
2462 locator
->namespaceUri
= SysAllocStringLen(NULL
, 0);
2463 if(!locator
->namespaceUri
)
2465 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2467 return E_OUTOFMEMORY
;
2470 locator
->attr_alloc_count
= 8;
2471 locator
->attr_count
= 0;
2472 locator
->attributes
= calloc(locator
->attr_alloc_count
, sizeof(*locator
->attributes
));
2473 if(!locator
->attributes
)
2475 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2476 SysFreeString(locator
->namespaceUri
);
2478 return E_OUTOFMEMORY
;
2481 list_init(&locator
->elements
);
2483 *ppsaxlocator
= locator
;
2485 TRACE("returning %p\n", *ppsaxlocator
);
2490 /*** SAXXMLReader internal functions ***/
2491 static HRESULT
internal_parseBuffer(saxreader
*This
, const char *buffer
, int size
, BOOL vbInterface
)
2493 xmlCharEncoding encoding
= XML_CHAR_ENCODING_NONE
;
2494 xmlChar
*enc_name
= NULL
;
2495 saxlocator
*locator
;
2498 TRACE("(%p)->(%p %d)\n", This
, buffer
, size
);
2500 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2506 const unsigned char *buff
= (unsigned char*)buffer
;
2508 encoding
= xmlDetectCharEncoding((xmlChar
*)buffer
, 4);
2509 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2510 TRACE("detected encoding: %s\n", enc_name
);
2511 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2512 if ((encoding
== XML_CHAR_ENCODING_UTF8
) &&
2513 buff
[0] == 0xEF && buff
[1] == 0xBB && buff
[2] == 0xBF)
2520 /* if libxml2 detection failed try to guess */
2521 if (encoding
== XML_CHAR_ENCODING_NONE
)
2523 const WCHAR
*ptr
= (WCHAR
*)buffer
;
2524 /* an xml declaration with optional encoding will still be handled by the parser */
2525 if ((size
>= 2) && *ptr
== '<' && ptr
[1] != '?')
2527 enc_name
= (xmlChar
*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE
);
2528 encoding
= XML_CHAR_ENCODING_UTF16LE
;
2531 else if (encoding
== XML_CHAR_ENCODING_UTF8
)
2532 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2536 locator
->pParserCtxt
= xmlCreateMemoryParserCtxt(buffer
, size
);
2537 if (!locator
->pParserCtxt
)
2539 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2545 locator
->pParserCtxt
->encoding
= xmlStrdup(enc_name
);
2546 if (encoding
== XML_CHAR_ENCODING_UTF16LE
) {
2547 TRACE("switching to %s\n", enc_name
);
2548 xmlSwitchEncoding(locator
->pParserCtxt
, encoding
);
2552 xmlFree(locator
->pParserCtxt
->sax
);
2553 locator
->pParserCtxt
->sax
= &locator
->saxreader
->sax
;
2554 locator
->pParserCtxt
->userData
= locator
;
2556 This
->isParsing
= TRUE
;
2557 if(xmlParseDocument(locator
->pParserCtxt
) == -1 && locator
->ret
== S_OK
)
2561 This
->isParsing
= FALSE
;
2563 if(locator
->pParserCtxt
)
2565 locator
->pParserCtxt
->sax
= NULL
;
2566 xmlFreeParserCtxt(locator
->pParserCtxt
);
2567 locator
->pParserCtxt
= NULL
;
2570 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2574 static HRESULT
internal_parseStream(saxreader
*This
, ISequentialStream
*stream
, BOOL vbInterface
)
2576 saxlocator
*locator
;
2583 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2584 if(FAILED(hr
)) return hr
;
2586 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2587 if(FAILED(hr
)) return hr
;
2589 locator
->pParserCtxt
= xmlCreatePushParserCtxt(
2590 &locator
->saxreader
->sax
, locator
,
2591 data
, dataRead
, NULL
);
2592 if(!locator
->pParserCtxt
)
2594 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2598 This
->isParsing
= TRUE
;
2602 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2603 if (FAILED(hr
) || !dataRead
) break;
2605 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, dataRead
, 0);
2606 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2611 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2612 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2616 This
->isParsing
= FALSE
;
2618 xmlFreeParserCtxt(locator
->pParserCtxt
);
2619 locator
->pParserCtxt
= NULL
;
2620 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2624 static HRESULT
internal_parse(
2631 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varInput
));
2633 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2634 free_bstr_pool(&This
->pool
);
2636 switch(V_VT(&varInput
))
2639 case VT_BSTR
|VT_BYREF
:
2641 BSTR str
= V_ISBYREF(&varInput
) ? *V_BSTRREF(&varInput
) : V_BSTR(&varInput
);
2642 hr
= internal_parseBuffer(This
, (const char*)str
, lstrlenW(str
)*sizeof(WCHAR
), vbInterface
);
2645 case VT_ARRAY
|VT_UI1
: {
2647 LONG lBound
, uBound
;
2650 hr
= SafeArrayGetLBound(V_ARRAY(&varInput
), 1, &lBound
);
2651 if(hr
!= S_OK
) break;
2652 hr
= SafeArrayGetUBound(V_ARRAY(&varInput
), 1, &uBound
);
2653 if(hr
!= S_OK
) break;
2654 dataRead
= (uBound
-lBound
)*SafeArrayGetElemsize(V_ARRAY(&varInput
));
2655 hr
= SafeArrayAccessData(V_ARRAY(&varInput
), &pSAData
);
2656 if(hr
!= S_OK
) break;
2657 hr
= internal_parseBuffer(This
, pSAData
, dataRead
, vbInterface
);
2658 SafeArrayUnaccessData(V_ARRAY(&varInput
));
2663 ISequentialStream
*stream
= NULL
;
2664 IXMLDOMDocument
*xmlDoc
;
2666 if (!V_UNKNOWN(&varInput
))
2667 return E_INVALIDARG
;
2669 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2670 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2674 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2675 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2676 SysStringByteLen(bstrData
), vbInterface
);
2677 IXMLDOMDocument_Release(xmlDoc
);
2678 SysFreeString(bstrData
);
2682 /* try base interface first */
2683 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2685 /* this should never happen if IStream is implemented properly, but just in case */
2686 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2690 hr
= internal_parseStream(This
, stream
, vbInterface
);
2691 ISequentialStream_Release(stream
);
2695 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2702 WARN("vt %d not implemented\n", V_VT(&varInput
));
2709 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2711 saxreader
*This
= obj
;
2713 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2716 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2718 saxreader
*This
= obj
;
2720 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2723 static HRESULT
internal_parseURL(saxreader
*reader
, const WCHAR
*url
, BOOL vbInterface
)
2729 TRACE("%p, %s.\n", reader
, debugstr_w(url
));
2731 if (!url
&& reader
->version
< MSXML4
)
2732 return E_INVALIDARG
;
2734 hr
= create_moniker_from_url(url
, &mon
);
2738 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, reader
, &bsc
);
2739 else hr
= bind_url(mon
, internal_onDataAvailable
, reader
, &bsc
);
2740 IMoniker_Release(mon
);
2745 return detach_bsc(bsc
);
2748 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2752 if (V_VT(v
) == VT_EMPTY
)
2753 return saxreader_put_handler(This
, type
, NULL
, vb
);
2757 case SAXDeclHandler
:
2758 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2760 case SAXLexicalHandler
:
2761 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2764 ERR("wrong handler type %d\n", type
);
2773 IUnknown
*handler
= NULL
;
2777 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2778 if (FAILED(hr
)) return hr
;
2781 saxreader_put_handler(This
, type
, handler
, vb
);
2782 if (handler
) IUnknown_Release(handler
);
2786 ERR("value type %d not supported\n", V_VT(v
));
2787 return E_INVALIDARG
;
2793 static HRESULT
internal_putProperty(
2801 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2803 if (This
->isParsing
) return E_FAIL
;
2805 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2806 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2807 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2809 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2810 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2812 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2814 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2815 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2819 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2821 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2822 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2826 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2828 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2831 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2834 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2837 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2840 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2843 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2846 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2849 return E_INVALIDARG
;
2852 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2854 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2856 if (!value
) return E_POINTER
;
2858 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2860 V_VT(value
) = VT_UNKNOWN
;
2861 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2865 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2867 V_VT(value
) = VT_UNKNOWN
;
2868 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2872 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2874 V_VT(value
) = VT_BSTR
;
2875 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2879 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2884 /*** IVBSAXXMLReader interface ***/
2885 /*** IUnknown methods ***/
2886 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2888 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2890 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2894 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2895 IsEqualGUID( riid
, &IID_IDispatch
) ||
2896 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2900 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2902 *ppvObject
= &This
->ISAXXMLReader_iface
;
2904 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2906 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2910 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2911 return E_NOINTERFACE
;
2914 IVBSAXXMLReader_AddRef( iface
);
2919 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2921 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2922 TRACE("%p\n", This
);
2923 return InterlockedIncrement( &This
->ref
);
2926 static ULONG WINAPI
saxxmlreader_Release(
2927 IVBSAXXMLReader
* iface
)
2929 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2932 TRACE("%p\n", This
);
2934 ref
= InterlockedDecrement( &This
->ref
);
2939 for (i
= 0; i
< SAXHandler_Last
; i
++)
2941 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2943 if (saxiface
->handler
)
2944 IUnknown_Release(saxiface
->handler
);
2946 if (saxiface
->vbhandler
)
2947 IUnknown_Release(saxiface
->vbhandler
);
2950 SysFreeString(This
->xmldecl_version
);
2951 free_bstr_pool(&This
->pool
);
2959 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2961 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2962 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2965 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2966 IVBSAXXMLReader
*iface
,
2967 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2969 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2970 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2971 iTInfo
, lcid
, ppTInfo
);
2974 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2975 IVBSAXXMLReader
*iface
,
2977 LPOLESTR
* rgszNames
,
2982 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2983 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
2984 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
2987 static HRESULT WINAPI
saxxmlreader_Invoke(
2988 IVBSAXXMLReader
*iface
,
2989 DISPID dispIdMember
,
2993 DISPPARAMS
* pDispParams
,
2994 VARIANT
* pVarResult
,
2995 EXCEPINFO
* pExcepInfo
,
2998 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2999 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
3000 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3003 /*** IVBSAXXMLReader methods ***/
3004 static HRESULT WINAPI
saxxmlreader_getFeature(
3005 IVBSAXXMLReader
* iface
,
3007 VARIANT_BOOL
*value
)
3009 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3010 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3013 static HRESULT WINAPI
saxxmlreader_putFeature(
3014 IVBSAXXMLReader
* iface
,
3018 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3019 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3022 static HRESULT WINAPI
saxxmlreader_getProperty(
3023 IVBSAXXMLReader
* iface
,
3027 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3028 return internal_getProperty(This
, prop
, value
, TRUE
);
3031 static HRESULT WINAPI
saxxmlreader_putProperty(
3032 IVBSAXXMLReader
* iface
,
3036 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3037 return internal_putProperty(This
, pProp
, value
, TRUE
);
3040 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3041 IVBSAXXMLReader
* iface
,
3042 IVBSAXEntityResolver
**resolver
)
3044 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3045 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3048 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3049 IVBSAXXMLReader
* iface
,
3050 IVBSAXEntityResolver
*resolver
)
3052 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3053 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3056 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3057 IVBSAXXMLReader
* iface
,
3058 IVBSAXContentHandler
**handler
)
3060 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3061 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3064 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3065 IVBSAXXMLReader
* iface
,
3066 IVBSAXContentHandler
*handler
)
3068 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3069 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3072 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3073 IVBSAXXMLReader
* iface
,
3074 IVBSAXDTDHandler
**handler
)
3076 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3077 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3080 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3081 IVBSAXXMLReader
* iface
,
3082 IVBSAXDTDHandler
*handler
)
3084 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3085 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3088 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3089 IVBSAXXMLReader
* iface
,
3090 IVBSAXErrorHandler
**handler
)
3092 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3093 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3096 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3097 IVBSAXXMLReader
* iface
,
3098 IVBSAXErrorHandler
*handler
)
3100 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3101 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3104 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3105 IVBSAXXMLReader
* iface
,
3108 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3110 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3114 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3115 IVBSAXXMLReader
* iface
,
3118 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3119 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3122 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3123 IVBSAXXMLReader
* iface
,
3124 BSTR
*pSecureBaseUrl
)
3126 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3128 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3132 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3133 IVBSAXXMLReader
* iface
,
3136 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3137 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3140 static HRESULT WINAPI
saxxmlreader_parse(
3141 IVBSAXXMLReader
* iface
,
3144 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3145 return internal_parse(This
, varInput
, TRUE
);
3148 static HRESULT WINAPI
saxxmlreader_parseURL(
3149 IVBSAXXMLReader
* iface
,
3152 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3153 return internal_parseURL(This
, url
, TRUE
);
3156 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3158 saxxmlreader_QueryInterface
,
3159 saxxmlreader_AddRef
,
3160 saxxmlreader_Release
,
3161 saxxmlreader_GetTypeInfoCount
,
3162 saxxmlreader_GetTypeInfo
,
3163 saxxmlreader_GetIDsOfNames
,
3164 saxxmlreader_Invoke
,
3165 saxxmlreader_getFeature
,
3166 saxxmlreader_putFeature
,
3167 saxxmlreader_getProperty
,
3168 saxxmlreader_putProperty
,
3169 saxxmlreader_get_entityResolver
,
3170 saxxmlreader_put_entityResolver
,
3171 saxxmlreader_get_contentHandler
,
3172 saxxmlreader_put_contentHandler
,
3173 saxxmlreader_get_dtdHandler
,
3174 saxxmlreader_put_dtdHandler
,
3175 saxxmlreader_get_errorHandler
,
3176 saxxmlreader_put_errorHandler
,
3177 saxxmlreader_get_baseURL
,
3178 saxxmlreader_put_baseURL
,
3179 saxxmlreader_get_secureBaseURL
,
3180 saxxmlreader_put_secureBaseURL
,
3182 saxxmlreader_parseURL
3185 /*** ISAXXMLReader interface ***/
3186 /*** IUnknown methods ***/
3187 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3189 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3190 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3193 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3195 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3196 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3199 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3201 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3202 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3205 /*** ISAXXMLReader methods ***/
3206 static HRESULT WINAPI
isaxxmlreader_getFeature(
3207 ISAXXMLReader
* iface
,
3208 const WCHAR
*feature_name
,
3209 VARIANT_BOOL
*value
)
3211 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3212 saxreader_feature feature
;
3214 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3216 feature
= get_saxreader_feature(feature_name
);
3218 if (This
->version
< MSXML4
&& (feature
== ExhaustiveErrors
|| feature
== SchemaValidation
))
3219 return E_INVALIDARG
;
3221 if (feature
== Namespaces
||
3222 feature
== NamespacePrefixes
||
3223 feature
== ExhaustiveErrors
||
3224 feature
== SchemaValidation
)
3225 return get_feature_value(This
, feature
, value
);
3227 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3231 static HRESULT WINAPI
isaxxmlreader_putFeature(
3232 ISAXXMLReader
* iface
,
3233 const WCHAR
*feature_name
,
3236 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3237 saxreader_feature feature
;
3239 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3241 feature
= get_saxreader_feature(feature_name
);
3243 /* accepted cases */
3244 if ((feature
== ExhaustiveErrors
&& value
== VARIANT_FALSE
) ||
3245 (feature
== SchemaValidation
&& value
== VARIANT_FALSE
) ||
3246 feature
== Namespaces
||
3247 feature
== NamespacePrefixes
)
3249 return set_feature_value(This
, feature
, value
);
3252 if (feature
== LexicalHandlerParEntities
||
3253 feature
== ProhibitDTD
||
3254 feature
== ExternalGeneralEntities
||
3255 feature
== ExternalParameterEntities
)
3257 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3258 return set_feature_value(This
, feature
, value
);
3261 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3265 static HRESULT WINAPI
isaxxmlreader_getProperty(
3266 ISAXXMLReader
* iface
,
3270 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3271 return internal_getProperty(This
, prop
, value
, FALSE
);
3274 static HRESULT WINAPI
isaxxmlreader_putProperty(
3275 ISAXXMLReader
* iface
,
3279 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3280 return internal_putProperty(This
, pProp
, value
, FALSE
);
3283 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3284 ISAXXMLReader
* iface
,
3285 ISAXEntityResolver
**resolver
)
3287 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3288 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3291 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3292 ISAXXMLReader
* iface
,
3293 ISAXEntityResolver
*resolver
)
3295 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3296 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3299 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3300 ISAXXMLReader
* iface
,
3301 ISAXContentHandler
**handler
)
3303 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3304 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3307 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3308 ISAXXMLReader
* iface
,
3309 ISAXContentHandler
*handler
)
3311 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3312 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3315 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3316 ISAXXMLReader
* iface
,
3317 ISAXDTDHandler
**handler
)
3319 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3320 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3323 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3324 ISAXXMLReader
* iface
,
3325 ISAXDTDHandler
*handler
)
3327 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3328 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3331 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3332 ISAXXMLReader
* iface
,
3333 ISAXErrorHandler
**handler
)
3335 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3336 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3339 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3341 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3342 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3345 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3346 ISAXXMLReader
* iface
,
3347 const WCHAR
**base_url
)
3349 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3351 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3355 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3356 ISAXXMLReader
* iface
,
3357 const WCHAR
*pBaseUrl
)
3359 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3361 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3365 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3366 ISAXXMLReader
* iface
,
3367 const WCHAR
**pSecureBaseUrl
)
3369 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3370 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3374 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3375 ISAXXMLReader
* iface
,
3376 const WCHAR
*secureBaseUrl
)
3378 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3380 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3384 static HRESULT WINAPI
isaxxmlreader_parse(
3385 ISAXXMLReader
* iface
,
3388 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3389 return internal_parse(This
, varInput
, FALSE
);
3392 static HRESULT WINAPI
isaxxmlreader_parseURL(
3393 ISAXXMLReader
* iface
,
3396 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3397 return internal_parseURL(This
, url
, FALSE
);
3400 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3402 isaxxmlreader_QueryInterface
,
3403 isaxxmlreader_AddRef
,
3404 isaxxmlreader_Release
,
3405 isaxxmlreader_getFeature
,
3406 isaxxmlreader_putFeature
,
3407 isaxxmlreader_getProperty
,
3408 isaxxmlreader_putProperty
,
3409 isaxxmlreader_getEntityResolver
,
3410 isaxxmlreader_putEntityResolver
,
3411 isaxxmlreader_getContentHandler
,
3412 isaxxmlreader_putContentHandler
,
3413 isaxxmlreader_getDTDHandler
,
3414 isaxxmlreader_putDTDHandler
,
3415 isaxxmlreader_getErrorHandler
,
3416 isaxxmlreader_putErrorHandler
,
3417 isaxxmlreader_getBaseURL
,
3418 isaxxmlreader_putBaseURL
,
3419 isaxxmlreader_getSecureBaseURL
,
3420 isaxxmlreader_putSecureBaseURL
,
3421 isaxxmlreader_parse
,
3422 isaxxmlreader_parseURL
3425 static const tid_t saxreader_iface_tids
[] = {
3426 IVBSAXXMLReader_tid
,
3429 static dispex_static_data_t saxreader_dispex
= {
3431 IVBSAXXMLReader_tid
,
3433 saxreader_iface_tids
3436 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3440 TRACE("(%p)\n", ppObj
);
3442 reader
= malloc(sizeof(*reader
));
3444 return E_OUTOFMEMORY
;
3446 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3447 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3449 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3450 reader
->isParsing
= FALSE
;
3451 reader
->xmldecl_version
= NULL
;
3452 reader
->pool
.pool
= NULL
;
3453 reader
->pool
.index
= 0;
3454 reader
->pool
.len
= 0;
3455 reader
->features
= Namespaces
| NamespacePrefixes
;
3456 reader
->version
= version
;
3458 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3460 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3461 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3462 reader
->sax
.startDocument
= libxmlStartDocument
;
3463 reader
->sax
.endDocument
= libxmlEndDocument
;
3464 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3465 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3466 reader
->sax
.characters
= libxmlCharacters
;
3467 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3468 reader
->sax
.comment
= libxmlComment
;
3469 reader
->sax
.error
= libxmlFatalError
;
3470 reader
->sax
.fatalError
= libxmlFatalError
;
3471 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3472 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3474 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3476 TRACE("returning iface %p\n", *ppObj
);