2 * SAX Reader implementation
4 * Copyright 2008 Alistair Leslie-Hughes
5 * Copyright 2008 Piotr Caban
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
29 # include <libxml/SAX2.h>
30 # include <libxml/parserInternals.h>
44 #include "wine/debug.h"
46 #include "msxml_private.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
55 ExhaustiveErrors
= 1 << 1,
56 ExternalGeneralEntities
= 1 << 2,
57 ExternalParameterEntities
= 1 << 3,
58 ForcedResync
= 1 << 4,
59 NamespacePrefixes
= 1 << 5,
61 ParameterEntities
= 1 << 7,
62 PreserveSystemIndentifiers
= 1 << 8,
64 SchemaValidation
= 1 << 10,
65 ServerHttpRequest
= 1 << 11,
66 SuppressValidationfatalError
= 1 << 12,
67 UseInlineSchema
= 1 << 13,
68 UseSchemaLocation
= 1 << 14,
69 LexicalHandlerParEntities
= 1 << 15
73 static const WCHAR FeatureExternalGeneralEntitiesW
[] = {
74 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/',
75 'f','e','a','t','u','r','e','s','/','e','x','t','e','r','n','a','l','-','g','e','n','e','r','a','l',
76 '-','e','n','t','i','t','i','e','s',0
79 static const WCHAR FeatureExternalParameterEntitiesW
[] = {
80 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
81 '/','e','x','t','e','r','n','a','l','-','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0
84 static const WCHAR FeatureLexicalHandlerParEntitiesW
[] = {
85 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
86 '/','l','e','x','i','c','a','l','-','h','a','n','d','l','e','r','/','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0
89 static const WCHAR FeatureProhibitDTDW
[] = {
90 'p','r','o','h','i','b','i','t','-','d','t','d',0
93 static const WCHAR FeatureNamespacesW
[] = {
94 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
95 '/','n','a','m','e','s','p','a','c','e','s',0
98 static const WCHAR FeatureNamespacePrefixesW
[] = {
99 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
100 '/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0
103 struct saxreader_feature_pair
105 saxreader_feature feature
;
109 static const struct saxreader_feature_pair saxreader_feature_map
[] = {
110 { ExternalGeneralEntities
, FeatureExternalGeneralEntitiesW
},
111 { ExternalParameterEntities
, FeatureExternalParameterEntitiesW
},
112 { LexicalHandlerParEntities
, FeatureLexicalHandlerParEntitiesW
},
113 { NamespacePrefixes
, FeatureNamespacePrefixesW
},
114 { Namespaces
, FeatureNamespacesW
},
115 { ProhibitDTD
, FeatureProhibitDTDW
}
118 static saxreader_feature
get_saxreader_feature(const WCHAR
*name
)
123 max
= sizeof(saxreader_feature_map
)/sizeof(struct saxreader_feature_pair
) - 1;
129 c
= strcmpW(saxreader_feature_map
[n
].name
, name
);
131 return saxreader_feature_map
[n
].feature
;
139 return FeatureUnknown
;
161 ns
*ns
; /* namespaces defined in this particular element */
167 SAXContentHandler
= 0,
176 struct saxanyhandler_iface
182 struct saxcontenthandler_iface
184 ISAXContentHandler
*handler
;
185 IVBSAXContentHandler
*vbhandler
;
188 struct saxerrorhandler_iface
190 ISAXErrorHandler
*handler
;
191 IVBSAXErrorHandler
*vbhandler
;
194 struct saxlexicalhandler_iface
196 ISAXLexicalHandler
*handler
;
197 IVBSAXLexicalHandler
*vbhandler
;
200 struct saxentityresolver_iface
202 ISAXEntityResolver
*handler
;
203 IVBSAXEntityResolver
*vbhandler
;
206 struct saxhandler_iface
209 struct saxcontenthandler_iface content
;
210 struct saxentityresolver_iface entityresolver
;
211 struct saxerrorhandler_iface error
;
212 struct saxlexicalhandler_iface lexical
;
213 struct saxanyhandler_iface anyhandler
;
220 IVBSAXXMLReader IVBSAXXMLReader_iface
;
221 ISAXXMLReader ISAXXMLReader_iface
;
224 struct saxhandler_iface saxhandlers
[SAXHandler_Last
];
227 struct bstrpool pool
;
228 saxreader_feature features
;
229 BSTR xmldecl_version
;
230 MSXML_VERSION version
;
233 static HRESULT
saxreader_put_handler(saxreader
*reader
, enum saxhandler_type type
, void *ptr
, BOOL vb
)
235 struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
236 IUnknown
*unk
= (IUnknown
*)ptr
;
239 IUnknown_AddRef(unk
);
241 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
242 IUnknown_Release(vb
? iface
->vbhandler
: iface
->handler
);
245 iface
->vbhandler
= unk
;
247 iface
->handler
= unk
;
252 static HRESULT
saxreader_get_handler(const saxreader
*reader
, enum saxhandler_type type
, BOOL vb
, void **ret
)
254 const struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
256 if (!ret
) return E_POINTER
;
258 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
261 IUnknown_AddRef(iface
->vbhandler
);
263 IUnknown_AddRef(iface
->handler
);
266 *ret
= vb
? iface
->vbhandler
: iface
->handler
;
271 static struct saxcontenthandler_iface
*saxreader_get_contenthandler(saxreader
*reader
)
273 return &reader
->saxhandlers
[SAXContentHandler
].u
.content
;
276 static struct saxerrorhandler_iface
*saxreader_get_errorhandler(saxreader
*reader
)
278 return &reader
->saxhandlers
[SAXErrorHandler
].u
.error
;
281 static struct saxlexicalhandler_iface
*saxreader_get_lexicalhandler(saxreader
*reader
)
283 return &reader
->saxhandlers
[SAXLexicalHandler
].u
.lexical
;
288 IVBSAXLocator IVBSAXLocator_iface
;
289 ISAXLocator ISAXLocator_iface
;
290 IVBSAXAttributes IVBSAXAttributes_iface
;
291 ISAXAttributes ISAXAttributes_iface
;
293 saxreader
*saxreader
;
295 xmlParserCtxtPtr pParserCtxt
;
301 struct list elements
;
304 int attr_alloc_count
;
315 static inline saxreader
*impl_from_IVBSAXXMLReader( IVBSAXXMLReader
*iface
)
317 return CONTAINING_RECORD(iface
, saxreader
, IVBSAXXMLReader_iface
);
320 static inline saxreader
*impl_from_ISAXXMLReader( ISAXXMLReader
*iface
)
322 return CONTAINING_RECORD(iface
, saxreader
, ISAXXMLReader_iface
);
325 static inline saxlocator
*impl_from_IVBSAXLocator( IVBSAXLocator
*iface
)
327 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXLocator_iface
);
330 static inline saxlocator
*impl_from_ISAXLocator( ISAXLocator
*iface
)
332 return CONTAINING_RECORD(iface
, saxlocator
, ISAXLocator_iface
);
335 static inline saxlocator
*impl_from_IVBSAXAttributes( IVBSAXAttributes
*iface
)
337 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXAttributes_iface
);
340 static inline saxlocator
*impl_from_ISAXAttributes( ISAXAttributes
*iface
)
342 return CONTAINING_RECORD(iface
, saxlocator
, ISAXAttributes_iface
);
345 static inline BOOL
saxreader_has_handler(const saxlocator
*locator
, enum saxhandler_type type
)
347 struct saxanyhandler_iface
*iface
= &locator
->saxreader
->saxhandlers
[type
].u
.anyhandler
;
348 return (locator
->vbInterface
&& iface
->vbhandler
) || (!locator
->vbInterface
&& iface
->handler
);
351 static HRESULT
saxreader_saxcharacters(saxlocator
*locator
, BSTR chars
)
353 struct saxcontenthandler_iface
*content
= saxreader_get_contenthandler(locator
->saxreader
);
356 if (!saxreader_has_handler(locator
, SAXContentHandler
)) return S_OK
;
358 if (locator
->vbInterface
)
359 hr
= IVBSAXContentHandler_characters(content
->vbhandler
, &chars
);
361 hr
= ISAXContentHandler_characters(content
->handler
, chars
, SysStringLen(chars
));
367 static const WCHAR PropertyCharsetW
[] = {
368 'c','h','a','r','s','e','t',0
370 static const WCHAR PropertyXmlDeclVersionW
[] = {
371 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
373 static const WCHAR PropertyDeclHandlerW
[] = {
374 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
375 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
376 'd','e','c','l','a','r','a','t','i','o','n',
377 '-','h','a','n','d','l','e','r',0
379 static const WCHAR PropertyDomNodeW
[] = {
380 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
381 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
382 'd','o','m','-','n','o','d','e',0
384 static const WCHAR PropertyInputSourceW
[] = {
385 'i','n','p','u','t','-','s','o','u','r','c','e',0
387 static const WCHAR PropertyLexicalHandlerW
[] = {
388 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
389 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
390 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
392 static const WCHAR PropertyMaxElementDepthW
[] = {
393 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
395 static const WCHAR PropertyMaxXMLSizeW
[] = {
396 'm','a','x','-','x','m','l','-','s','i','z','e',0
398 static const WCHAR PropertySchemaDeclHandlerW
[] = {
399 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
400 'h','a','n','d','l','e','r',0
402 static const WCHAR PropertyXMLDeclEncodingW
[] = {
403 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
405 static const WCHAR PropertyXMLDeclStandaloneW
[] = {
406 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
408 static const WCHAR PropertyXMLDeclVersionW
[] = {
409 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
412 static inline HRESULT
set_feature_value(saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL value
)
414 /* handling of non-VARIANT_* values is version dependent */
415 if ((reader
->version
< MSXML4
) && (value
!= VARIANT_TRUE
))
416 value
= VARIANT_FALSE
;
417 if ((reader
->version
>= MSXML4
) && (value
!= VARIANT_FALSE
))
418 value
= VARIANT_TRUE
;
420 if (value
== VARIANT_TRUE
)
421 reader
->features
|= feature
;
423 reader
->features
&= ~feature
;
428 static inline HRESULT
get_feature_value(const saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL
*value
)
430 *value
= reader
->features
& feature
? VARIANT_TRUE
: VARIANT_FALSE
;
434 static BOOL
is_namespaces_enabled(const saxreader
*reader
)
436 return (reader
->version
< MSXML4
) || (reader
->features
& Namespaces
);
439 static BSTR
build_qname(BSTR prefix
, BSTR local
)
441 if (prefix
&& *prefix
)
443 BSTR qname
= SysAllocStringLen(NULL
, SysStringLen(prefix
) + SysStringLen(local
) + 1);
447 strcpyW(ptr
, prefix
);
448 ptr
+= SysStringLen(prefix
);
454 return SysAllocString(local
);
457 static element_entry
* alloc_element_entry(const xmlChar
*local
, const xmlChar
*prefix
, int nb_ns
,
458 const xmlChar
**namespaces
)
463 ret
= heap_alloc(sizeof(*ret
));
464 if (!ret
) return ret
;
466 ret
->local
= bstr_from_xmlChar(local
);
467 ret
->prefix
= bstr_from_xmlChar(prefix
);
468 ret
->qname
= build_qname(ret
->prefix
, ret
->local
);
469 ret
->ns
= nb_ns
? heap_alloc(nb_ns
*sizeof(ns
)) : NULL
;
470 ret
->ns_count
= nb_ns
;
472 for (i
=0; i
< nb_ns
; i
++)
474 ret
->ns
[i
].prefix
= bstr_from_xmlChar(namespaces
[2*i
]);
475 ret
->ns
[i
].uri
= bstr_from_xmlChar(namespaces
[2*i
+1]);
481 static void free_element_entry(element_entry
*element
)
485 for (i
=0; i
<element
->ns_count
;i
++)
487 SysFreeString(element
->ns
[i
].prefix
);
488 SysFreeString(element
->ns
[i
].uri
);
491 SysFreeString(element
->prefix
);
492 SysFreeString(element
->local
);
493 SysFreeString(element
->qname
);
495 heap_free(element
->ns
);
499 static void push_element_ns(saxlocator
*locator
, element_entry
*element
)
501 list_add_head(&locator
->elements
, &element
->entry
);
504 static element_entry
* pop_element_ns(saxlocator
*locator
)
506 element_entry
*element
= LIST_ENTRY(list_head(&locator
->elements
), element_entry
, entry
);
509 list_remove(&element
->entry
);
514 static BSTR
find_element_uri(saxlocator
*locator
, const xmlChar
*uri
)
516 element_entry
*element
;
520 if (!uri
) return NULL
;
522 uriW
= bstr_from_xmlChar(uri
);
524 LIST_FOR_EACH_ENTRY(element
, &locator
->elements
, element_entry
, entry
)
526 for (i
=0; i
< element
->ns_count
; i
++)
527 if (!strcmpW(uriW
, element
->ns
[i
].uri
))
530 return element
->ns
[i
].uri
;
535 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri
));
539 /* used to localize version dependent error check behaviour */
540 static inline BOOL
sax_callback_failed(saxlocator
*This
, HRESULT hr
)
542 return This
->saxreader
->version
>= MSXML4
? FAILED(hr
) : hr
!= S_OK
;
545 /* index value -1 means it tries to loop for a first time */
546 static inline BOOL
iterate_endprefix_index(saxlocator
*This
, const element_entry
*element
, int *i
)
548 if (This
->saxreader
->version
>= MSXML4
)
550 if (*i
== -1) *i
= 0; else ++*i
;
551 return *i
< element
->ns_count
;
555 if (*i
== -1) *i
= element
->ns_count
-1; else --*i
;
560 static BOOL
bstr_pool_insert(struct bstrpool
*pool
, BSTR pool_entry
)
564 pool
->pool
= HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(*pool
->pool
));
571 else if (pool
->index
== pool
->len
)
573 BSTR
*realloc
= HeapReAlloc(GetProcessHeap(), 0, pool
->pool
, pool
->len
* 2 * sizeof(*realloc
));
578 pool
->pool
= realloc
;
582 pool
->pool
[pool
->index
++] = pool_entry
;
586 static void free_bstr_pool(struct bstrpool
*pool
)
590 for (i
= 0; i
< pool
->index
; i
++)
591 SysFreeString(pool
->pool
[i
]);
593 HeapFree(GetProcessHeap(), 0, pool
->pool
);
596 pool
->index
= pool
->len
= 0;
599 static BSTR
bstr_from_xmlCharN(const xmlChar
*buf
, int len
)
607 dLen
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
608 if(len
!= -1) dLen
++;
609 bstr
= SysAllocStringLen(NULL
, dLen
-1);
612 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, bstr
, dLen
);
613 if(len
!= -1) bstr
[dLen
-1] = '\0';
618 static BSTR
QName_from_xmlChar(const xmlChar
*prefix
, const xmlChar
*name
)
623 if(!name
) return NULL
;
625 if(!prefix
|| !*prefix
)
626 return bstr_from_xmlChar(name
);
628 qname
= xmlBuildQName(name
, prefix
, NULL
, 0);
629 bstr
= bstr_from_xmlChar(qname
);
635 static BSTR
pooled_bstr_from_xmlChar(struct bstrpool
*pool
, const xmlChar
*buf
)
637 BSTR pool_entry
= bstr_from_xmlChar(buf
);
639 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
641 SysFreeString(pool_entry
);
648 static BSTR
pooled_bstr_from_xmlCharN(struct bstrpool
*pool
, const xmlChar
*buf
, int len
)
650 BSTR pool_entry
= bstr_from_xmlCharN(buf
, len
);
652 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
654 SysFreeString(pool_entry
);
661 static void format_error_message_from_id(saxlocator
*This
, HRESULT hr
)
663 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
664 xmlStopParser(This
->pParserCtxt
);
667 if (saxreader_has_handler(This
, SAXErrorHandler
))
670 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
,
671 NULL
, hr
, 0, msg
, sizeof(msg
)/sizeof(msg
[0]), NULL
))
673 FIXME("MSXML errors not yet supported.\n");
677 if(This
->vbInterface
)
679 BSTR bstrMsg
= SysAllocString(msg
);
680 IVBSAXErrorHandler_fatalError(handler
->vbhandler
,
681 &This
->IVBSAXLocator_iface
, &bstrMsg
, hr
);
682 SysFreeString(bstrMsg
);
685 ISAXErrorHandler_fatalError(handler
->handler
,
686 &This
->ISAXLocator_iface
, msg
, hr
);
690 static void update_position(saxlocator
*This
, BOOL fix_column
)
692 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
694 This
->line
= xmlSAX2GetLineNumber(This
->pParserCtxt
);
698 for(; *p
!='\n' && *p
!='\r' && p
>=This
->pParserCtxt
->input
->base
; p
--)
703 This
->column
= xmlSAX2GetColumnNumber(This
->pParserCtxt
);
707 /*** IVBSAXAttributes interface ***/
708 static HRESULT WINAPI
ivbsaxattributes_QueryInterface(
709 IVBSAXAttributes
* iface
,
713 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
714 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
715 return IVBSAXLocator_QueryInterface(&This
->IVBSAXLocator_iface
, riid
, ppvObject
);
718 static ULONG WINAPI
ivbsaxattributes_AddRef(IVBSAXAttributes
* iface
)
720 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
721 return IVBSAXLocator_AddRef(&This
->IVBSAXLocator_iface
);
724 static ULONG WINAPI
ivbsaxattributes_Release(IVBSAXAttributes
* iface
)
726 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
727 return IVBSAXLocator_Release(&This
->IVBSAXLocator_iface
);
730 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes
*iface
, UINT
* pctinfo
)
732 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
734 TRACE("(%p)->(%p)\n", This
, pctinfo
);
741 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfo(
742 IVBSAXAttributes
*iface
,
743 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
745 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
747 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
749 return get_typeinfo(IVBSAXAttributes_tid
, ppTInfo
);
752 static HRESULT WINAPI
ivbsaxattributes_GetIDsOfNames(
753 IVBSAXAttributes
*iface
,
760 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
764 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
767 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
770 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
773 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
774 ITypeInfo_Release(typeinfo
);
780 static HRESULT WINAPI
ivbsaxattributes_Invoke(
781 IVBSAXAttributes
*iface
,
786 DISPPARAMS
* pDispParams
,
788 EXCEPINFO
* pExcepInfo
,
791 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
795 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
796 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
798 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
801 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXAttributes_iface
, dispIdMember
, wFlags
,
802 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
803 ITypeInfo_Release(typeinfo
);
809 /*** IVBSAXAttributes methods ***/
810 static HRESULT WINAPI
ivbsaxattributes_get_length(
811 IVBSAXAttributes
* iface
,
814 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
815 return ISAXAttributes_getLength(&This
->ISAXAttributes_iface
, nLength
);
818 static HRESULT WINAPI
ivbsaxattributes_getURI(
819 IVBSAXAttributes
* iface
,
823 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
828 TRACE("(%p)->(%d %p)\n", This
, nIndex
, uri
);
834 hr
= ISAXAttributes_getURI(&This
->ISAXAttributes_iface
, nIndex
, &uriW
, &len
);
838 return return_bstrn(uriW
, len
, uri
);
841 static HRESULT WINAPI
ivbsaxattributes_getLocalName(
842 IVBSAXAttributes
* iface
,
846 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
851 TRACE("(%p)->(%d %p)\n", This
, nIndex
, name
);
857 hr
= ISAXAttributes_getLocalName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
861 return return_bstrn(nameW
, len
, name
);
864 static HRESULT WINAPI
ivbsaxattributes_getQName(
865 IVBSAXAttributes
* iface
,
869 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
874 TRACE("(%p)->(%d %p)\n", This
, nIndex
, QName
);
880 hr
= ISAXAttributes_getQName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
884 return return_bstrn(nameW
, len
, QName
);
887 static HRESULT WINAPI
ivbsaxattributes_getIndexFromName(
888 IVBSAXAttributes
* iface
,
893 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
894 return ISAXAttributes_getIndexFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
895 localName
, SysStringLen(localName
), index
);
898 static HRESULT WINAPI
ivbsaxattributes_getIndexFromQName(
899 IVBSAXAttributes
* iface
,
903 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
904 return ISAXAttributes_getIndexFromQName(&This
->ISAXAttributes_iface
, QName
,
905 SysStringLen(QName
), index
);
908 static HRESULT WINAPI
ivbsaxattributes_getType(
909 IVBSAXAttributes
* iface
,
913 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
918 TRACE("(%p)->(%d %p)\n", This
, nIndex
, type
);
924 hr
= ISAXAttributes_getType(&This
->ISAXAttributes_iface
, nIndex
, &typeW
, &len
);
928 return return_bstrn(typeW
, len
, type
);
931 static HRESULT WINAPI
ivbsaxattributes_getTypeFromName(
932 IVBSAXAttributes
* iface
,
937 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
942 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), type
);
948 hr
= ISAXAttributes_getTypeFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
949 localName
, SysStringLen(localName
), &typeW
, &len
);
953 return return_bstrn(typeW
, len
, type
);
956 static HRESULT WINAPI
ivbsaxattributes_getTypeFromQName(
957 IVBSAXAttributes
* iface
,
961 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
966 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), type
);
972 hr
= ISAXAttributes_getTypeFromQName(&This
->ISAXAttributes_iface
, QName
, SysStringLen(QName
),
977 return return_bstrn(typeW
, len
, type
);
980 static HRESULT WINAPI
ivbsaxattributes_getValue(
981 IVBSAXAttributes
* iface
,
985 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
990 TRACE("(%p)->(%d %p)\n", This
, nIndex
, value
);
996 hr
= ISAXAttributes_getValue(&This
->ISAXAttributes_iface
, nIndex
, &valueW
, &len
);
1000 return return_bstrn(valueW
, len
, value
);
1003 static HRESULT WINAPI
ivbsaxattributes_getValueFromName(
1004 IVBSAXAttributes
* iface
,
1009 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1010 const WCHAR
*valueW
;
1014 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), value
);
1020 hr
= ISAXAttributes_getValueFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
1021 localName
, SysStringLen(localName
), &valueW
, &len
);
1025 return return_bstrn(valueW
, len
, value
);
1028 static HRESULT WINAPI
ivbsaxattributes_getValueFromQName(
1029 IVBSAXAttributes
* iface
,
1033 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1034 const WCHAR
*valueW
;
1038 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), value
);
1044 hr
= ISAXAttributes_getValueFromQName(&This
->ISAXAttributes_iface
, QName
,
1045 SysStringLen(QName
), &valueW
, &len
);
1049 return return_bstrn(valueW
, len
, value
);
1052 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl
=
1054 ivbsaxattributes_QueryInterface
,
1055 ivbsaxattributes_AddRef
,
1056 ivbsaxattributes_Release
,
1057 ivbsaxattributes_GetTypeInfoCount
,
1058 ivbsaxattributes_GetTypeInfo
,
1059 ivbsaxattributes_GetIDsOfNames
,
1060 ivbsaxattributes_Invoke
,
1061 ivbsaxattributes_get_length
,
1062 ivbsaxattributes_getURI
,
1063 ivbsaxattributes_getLocalName
,
1064 ivbsaxattributes_getQName
,
1065 ivbsaxattributes_getIndexFromName
,
1066 ivbsaxattributes_getIndexFromQName
,
1067 ivbsaxattributes_getType
,
1068 ivbsaxattributes_getTypeFromName
,
1069 ivbsaxattributes_getTypeFromQName
,
1070 ivbsaxattributes_getValue
,
1071 ivbsaxattributes_getValueFromName
,
1072 ivbsaxattributes_getValueFromQName
1075 /*** ISAXAttributes interface ***/
1076 /*** IUnknown methods ***/
1077 static HRESULT WINAPI
isaxattributes_QueryInterface(
1078 ISAXAttributes
* iface
,
1082 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1083 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
1084 return ISAXLocator_QueryInterface(&This
->ISAXLocator_iface
, riid
, ppvObject
);
1087 static ULONG WINAPI
isaxattributes_AddRef(ISAXAttributes
* iface
)
1089 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1090 TRACE("%p\n", This
);
1091 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
1094 static ULONG WINAPI
isaxattributes_Release(ISAXAttributes
* iface
)
1096 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1098 TRACE("%p\n", This
);
1099 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
1102 /*** ISAXAttributes methods ***/
1103 static HRESULT WINAPI
isaxattributes_getLength(
1104 ISAXAttributes
* iface
,
1107 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1109 *length
= This
->attr_count
;
1110 TRACE("Length set to %d\n", *length
);
1114 static inline BOOL
is_valid_attr_index(const saxlocator
*locator
, int index
)
1116 return index
< locator
->attr_count
&& index
>= 0;
1119 static HRESULT WINAPI
isaxattributes_getURI(
1120 ISAXAttributes
* iface
,
1125 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1126 TRACE("(%p)->(%d)\n", This
, index
);
1128 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1129 if(!url
|| !size
) return E_POINTER
;
1131 *size
= SysStringLen(This
->attributes
[index
].szURI
);
1132 *url
= This
->attributes
[index
].szURI
;
1134 TRACE("(%s:%d)\n", debugstr_w(This
->attributes
[index
].szURI
), *size
);
1139 static HRESULT WINAPI
isaxattributes_getLocalName(
1140 ISAXAttributes
* iface
,
1142 const WCHAR
**pLocalName
,
1143 int *pLocalNameLength
)
1145 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1146 TRACE("(%p)->(%d)\n", This
, index
);
1148 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1149 if(!pLocalName
|| !pLocalNameLength
) return E_POINTER
;
1151 *pLocalNameLength
= SysStringLen(This
->attributes
[index
].szLocalname
);
1152 *pLocalName
= This
->attributes
[index
].szLocalname
;
1157 static HRESULT WINAPI
isaxattributes_getQName(
1158 ISAXAttributes
* iface
,
1160 const WCHAR
**pQName
,
1163 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1164 TRACE("(%p)->(%d)\n", This
, index
);
1166 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1167 if(!pQName
|| !pQNameLength
) return E_POINTER
;
1169 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1170 *pQName
= This
->attributes
[index
].szQName
;
1175 static HRESULT WINAPI
isaxattributes_getName(
1176 ISAXAttributes
* iface
,
1180 const WCHAR
**localName
,
1181 int *pLocalNameSize
,
1182 const WCHAR
**QName
,
1185 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1186 TRACE("(%p)->(%d)\n", This
, index
);
1188 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1189 if(!uri
|| !pUriLength
|| !localName
|| !pLocalNameSize
1190 || !QName
|| !pQNameLength
) return E_POINTER
;
1192 *pUriLength
= SysStringLen(This
->attributes
[index
].szURI
);
1193 *uri
= This
->attributes
[index
].szURI
;
1194 *pLocalNameSize
= SysStringLen(This
->attributes
[index
].szLocalname
);
1195 *localName
= This
->attributes
[index
].szLocalname
;
1196 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1197 *QName
= This
->attributes
[index
].szQName
;
1199 TRACE("(%s, %s, %s)\n", debugstr_w(*uri
), debugstr_w(*localName
), debugstr_w(*QName
));
1204 static HRESULT WINAPI
isaxattributes_getIndexFromName(
1205 ISAXAttributes
* iface
,
1208 const WCHAR
*pLocalName
,
1209 int cocalNameLength
,
1212 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1214 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), cUriLength
,
1215 debugstr_w(pLocalName
), cocalNameLength
);
1217 if(!pUri
|| !pLocalName
|| !index
) return E_POINTER
;
1219 for(i
=0; i
<This
->attr_count
; i
++)
1221 if(cUriLength
!=SysStringLen(This
->attributes
[i
].szURI
)
1222 || cocalNameLength
!=SysStringLen(This
->attributes
[i
].szLocalname
))
1224 if(cUriLength
&& memcmp(pUri
, This
->attributes
[i
].szURI
,
1225 sizeof(WCHAR
)*cUriLength
))
1227 if(cocalNameLength
&& memcmp(pLocalName
, This
->attributes
[i
].szLocalname
,
1228 sizeof(WCHAR
)*cocalNameLength
))
1235 return E_INVALIDARG
;
1238 static HRESULT WINAPI
isaxattributes_getIndexFromQName(
1239 ISAXAttributes
* iface
,
1240 const WCHAR
*pQName
,
1244 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1246 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQNameLength
);
1248 if(!pQName
|| !index
) return E_POINTER
;
1249 if(!nQNameLength
) return E_INVALIDARG
;
1251 for(i
=0; i
<This
->attr_count
; i
++)
1253 if(nQNameLength
!=SysStringLen(This
->attributes
[i
].szQName
)) continue;
1254 if(memcmp(pQName
, This
->attributes
[i
].szQName
, sizeof(WCHAR
)*nQNameLength
)) continue;
1260 return E_INVALIDARG
;
1263 static HRESULT WINAPI
isaxattributes_getType(
1264 ISAXAttributes
* iface
,
1266 const WCHAR
**pType
,
1269 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1271 FIXME("(%p)->(%d) stub\n", This
, nIndex
);
1275 static HRESULT WINAPI
isaxattributes_getTypeFromName(
1276 ISAXAttributes
* iface
,
1279 const WCHAR
*pLocalName
,
1281 const WCHAR
**pType
,
1284 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1286 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This
, debugstr_w(pUri
), nUri
,
1287 debugstr_w(pLocalName
), nLocalName
);
1291 static HRESULT WINAPI
isaxattributes_getTypeFromQName(
1292 ISAXAttributes
* iface
,
1293 const WCHAR
*pQName
,
1295 const WCHAR
**pType
,
1298 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1300 FIXME("(%p)->(%s, %d) stub\n", This
, debugstr_w(pQName
), nQName
);
1304 static HRESULT WINAPI
isaxattributes_getValue(
1305 ISAXAttributes
* iface
,
1307 const WCHAR
**value
,
1310 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1311 TRACE("(%p)->(%d)\n", This
, index
);
1313 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1314 if(!value
|| !nValue
) return E_POINTER
;
1316 *nValue
= SysStringLen(This
->attributes
[index
].szValue
);
1317 *value
= This
->attributes
[index
].szValue
;
1319 TRACE("(%s:%d)\n", debugstr_w(*value
), *nValue
);
1324 static HRESULT WINAPI
isaxattributes_getValueFromName(
1325 ISAXAttributes
* iface
,
1328 const WCHAR
*pLocalName
,
1330 const WCHAR
**pValue
,
1335 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1336 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), nUri
,
1337 debugstr_w(pLocalName
), nLocalName
);
1339 hr
= ISAXAttributes_getIndexFromName(iface
,
1340 pUri
, nUri
, pLocalName
, nLocalName
, &index
);
1341 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1346 static HRESULT WINAPI
isaxattributes_getValueFromQName(
1347 ISAXAttributes
* iface
,
1348 const WCHAR
*pQName
,
1350 const WCHAR
**pValue
,
1355 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1356 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQName
);
1358 hr
= ISAXAttributes_getIndexFromQName(iface
, pQName
, nQName
, &index
);
1359 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1364 static const struct ISAXAttributesVtbl isaxattributes_vtbl
=
1366 isaxattributes_QueryInterface
,
1367 isaxattributes_AddRef
,
1368 isaxattributes_Release
,
1369 isaxattributes_getLength
,
1370 isaxattributes_getURI
,
1371 isaxattributes_getLocalName
,
1372 isaxattributes_getQName
,
1373 isaxattributes_getName
,
1374 isaxattributes_getIndexFromName
,
1375 isaxattributes_getIndexFromQName
,
1376 isaxattributes_getType
,
1377 isaxattributes_getTypeFromName
,
1378 isaxattributes_getTypeFromQName
,
1379 isaxattributes_getValue
,
1380 isaxattributes_getValueFromName
,
1381 isaxattributes_getValueFromQName
1384 /* Libxml2 escapes '&' back to char reference '&' in attribute value,
1385 so when document has escaped value with '&' it's parsed to '&' and then
1386 escaped to '&'. This function takes care of ampersands only. */
1387 static BSTR
saxreader_get_unescaped_value(const xmlChar
*buf
, int len
)
1389 static const WCHAR ampescW
[] = {'&','#','3','8',';',0};
1390 WCHAR
*dest
, *ptrW
, *str
;
1397 str_len
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
1398 if (len
!= -1) str_len
++;
1400 str
= heap_alloc(str_len
*sizeof(WCHAR
));
1401 if (!str
) return NULL
;
1403 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, str
, str_len
);
1404 if (len
!= -1) str
[str_len
-1] = 0;
1407 while ((dest
= strstrW(ptrW
, ampescW
)))
1411 /* leave first '&' from a reference as a value */
1412 src
= dest
+ (sizeof(ampescW
)/sizeof(WCHAR
) - 1);
1415 /* move together with null terminator */
1416 memmove(dest
, src
, (strlenW(src
) + 1)*sizeof(WCHAR
));
1421 bstr
= SysAllocString(str
);
1427 static void free_attribute_values(saxlocator
*locator
)
1431 for (i
= 0; i
< locator
->attr_count
; i
++)
1433 SysFreeString(locator
->attributes
[i
].szLocalname
);
1434 locator
->attributes
[i
].szLocalname
= NULL
;
1436 SysFreeString(locator
->attributes
[i
].szValue
);
1437 locator
->attributes
[i
].szValue
= NULL
;
1439 SysFreeString(locator
->attributes
[i
].szQName
);
1440 locator
->attributes
[i
].szQName
= NULL
;
1444 static HRESULT
SAXAttributes_populate(saxlocator
*locator
,
1445 int nb_namespaces
, const xmlChar
**xmlNamespaces
,
1446 int nb_attributes
, const xmlChar
**xmlAttributes
)
1448 static const xmlChar xmlns
[] = "xmlns";
1449 static const WCHAR xmlnsW
[] = { 'x','m','l','n','s',0 };
1451 struct _attributes
*attrs
;
1454 /* skip namespace definitions */
1455 if ((locator
->saxreader
->features
& NamespacePrefixes
) == 0)
1458 locator
->attr_count
= nb_namespaces
+ nb_attributes
;
1459 if(locator
->attr_count
> locator
->attr_alloc_count
)
1461 int new_size
= locator
->attr_count
* 2;
1462 attrs
= heap_realloc_zero(locator
->attributes
, new_size
* sizeof(struct _attributes
));
1465 free_attribute_values(locator
);
1466 locator
->attr_count
= 0;
1467 return E_OUTOFMEMORY
;
1469 locator
->attributes
= attrs
;
1470 locator
->attr_alloc_count
= new_size
;
1474 attrs
= locator
->attributes
;
1477 for (i
= 0; i
< nb_namespaces
; i
++)
1479 SysFreeString(attrs
[nb_attributes
+i
].szLocalname
);
1480 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1482 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1484 SysFreeString(attrs
[nb_attributes
+i
].szValue
);
1485 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1487 SysFreeString(attrs
[nb_attributes
+i
].szQName
);
1488 if(!xmlNamespaces
[2*i
])
1489 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1491 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1494 for (i
= 0; i
< nb_attributes
; i
++)
1496 static const xmlChar xmlA
[] = "xml";
1498 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1499 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1501 /* that's an important feature to keep same uri pointer for every reported attribute */
1502 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1504 SysFreeString(attrs
[i
].szLocalname
);
1505 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1507 SysFreeString(attrs
[i
].szValue
);
1508 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1510 SysFreeString(attrs
[i
].szQName
);
1511 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1], xmlAttributes
[i
*5]);
1517 /*** LibXML callbacks ***/
1518 static void libxmlStartDocument(void *ctx
)
1520 saxlocator
*This
= ctx
;
1521 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1524 if (This
->saxreader
->version
>= MSXML4
)
1526 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1527 update_position(This
, FALSE
);
1528 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1530 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1535 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1539 /* store version value, declaration has to contain version attribute */
1540 if (This
->pParserCtxt
->standalone
!= -1)
1542 SysFreeString(This
->saxreader
->xmldecl_version
);
1543 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1546 if (saxreader_has_handler(This
, SAXContentHandler
))
1548 if(This
->vbInterface
)
1549 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1551 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1553 if (sax_callback_failed(This
, hr
))
1554 format_error_message_from_id(This
, hr
);
1558 static void libxmlEndDocument(void *ctx
)
1560 saxlocator
*This
= ctx
;
1561 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1564 if (This
->saxreader
->version
>= MSXML4
) {
1565 update_position(This
, FALSE
);
1566 if(This
->column
> 1)
1574 if(This
->ret
!= S_OK
) return;
1576 if (saxreader_has_handler(This
, SAXContentHandler
))
1578 if(This
->vbInterface
)
1579 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1581 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1583 if (sax_callback_failed(This
, hr
))
1584 format_error_message_from_id(This
, hr
);
1588 static void libxmlStartElementNS(
1590 const xmlChar
*localname
,
1591 const xmlChar
*prefix
,
1594 const xmlChar
**namespaces
,
1597 const xmlChar
**attributes
)
1599 saxlocator
*This
= ctx
;
1600 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1601 element_entry
*element
;
1605 update_position(This
, TRUE
);
1606 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1608 if(This
->saxreader
->version
< MSXML4
)
1611 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1612 push_element_ns(This
, element
);
1614 if (is_namespaces_enabled(This
->saxreader
))
1618 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1620 if (This
->vbInterface
)
1621 hr
= IVBSAXContentHandler_startPrefixMapping(
1623 &element
->ns
[i
].prefix
,
1624 &element
->ns
[i
].uri
);
1626 hr
= ISAXContentHandler_startPrefixMapping(
1628 element
->ns
[i
].prefix
,
1629 SysStringLen(element
->ns
[i
].prefix
),
1631 SysStringLen(element
->ns
[i
].uri
));
1633 if (sax_callback_failed(This
, hr
))
1635 format_error_message_from_id(This
, hr
);
1641 uri
= find_element_uri(This
, URI
);
1642 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1643 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1647 if (is_namespaces_enabled(This
->saxreader
))
1648 local
= element
->local
;
1652 if (This
->vbInterface
)
1653 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1654 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1656 hr
= ISAXContentHandler_startElement(handler
->handler
,
1657 uri
, SysStringLen(uri
),
1658 local
, SysStringLen(local
),
1659 element
->qname
, SysStringLen(element
->qname
),
1660 &This
->ISAXAttributes_iface
);
1662 if (sax_callback_failed(This
, hr
))
1663 format_error_message_from_id(This
, hr
);
1667 static void libxmlEndElementNS(
1669 const xmlChar
*localname
,
1670 const xmlChar
*prefix
,
1673 saxlocator
*This
= ctx
;
1674 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1675 element_entry
*element
;
1680 update_position(This
, FALSE
);
1681 p
= This
->pParserCtxt
->input
->cur
;
1683 if (This
->saxreader
->version
>= MSXML4
)
1686 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1688 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1693 else if(*(p
-1)!='>' || *(p
-2)!='/')
1696 while(p
-2>=This
->pParserCtxt
->input
->base
1697 && *(p
-2)!='<' && *(p
-1)!='/')
1699 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1705 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1708 uri
= find_element_uri(This
, URI
);
1709 element
= pop_element_ns(This
);
1711 if (!saxreader_has_handler(This
, SAXContentHandler
))
1713 free_attribute_values(This
);
1714 This
->attr_count
= 0;
1715 free_element_entry(element
);
1719 if (is_namespaces_enabled(This
->saxreader
))
1720 local
= element
->local
;
1724 if (This
->vbInterface
)
1725 hr
= IVBSAXContentHandler_endElement(
1727 &uri
, &local
, &element
->qname
);
1729 hr
= ISAXContentHandler_endElement(
1731 uri
, SysStringLen(uri
),
1732 local
, SysStringLen(local
),
1733 element
->qname
, SysStringLen(element
->qname
));
1735 free_attribute_values(This
);
1736 This
->attr_count
= 0;
1738 if (sax_callback_failed(This
, hr
))
1740 format_error_message_from_id(This
, hr
);
1741 free_element_entry(element
);
1745 if (is_namespaces_enabled(This
->saxreader
))
1748 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1750 if (This
->vbInterface
)
1751 hr
= IVBSAXContentHandler_endPrefixMapping(
1752 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1754 hr
= ISAXContentHandler_endPrefixMapping(
1755 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1757 if (sax_callback_failed(This
, hr
)) break;
1760 if (sax_callback_failed(This
, hr
))
1761 format_error_message_from_id(This
, hr
);
1764 free_element_entry(element
);
1767 static void libxmlCharacters(
1772 saxlocator
*This
= ctx
;
1776 BOOL lastEvent
= FALSE
;
1778 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1780 update_position(This
, FALSE
);
1781 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1782 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1784 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1789 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1793 if(*(ch
-1)=='\r') cur
--;
1798 while(end
-ch
<len
&& *end
!='\r') end
++;
1809 if (This
->saxreader
->version
>= MSXML4
)
1813 for(p
=cur
; p
!=end
; p
++)
1830 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1831 hr
= saxreader_saxcharacters(This
, Chars
);
1833 if (sax_callback_failed(This
, hr
))
1835 format_error_message_from_id(This
, hr
);
1839 if (This
->saxreader
->version
< MSXML4
)
1840 This
->column
+= end
-cur
;
1853 if(end
-ch
== len
) break;
1857 static void libxmlSetDocumentLocator(
1859 xmlSAXLocatorPtr loc
)
1861 saxlocator
*This
= ctx
;
1862 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1865 if (saxreader_has_handler(This
, SAXContentHandler
))
1867 if(This
->vbInterface
)
1868 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1869 &This
->IVBSAXLocator_iface
);
1871 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1875 format_error_message_from_id(This
, hr
);
1878 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1880 saxlocator
*This
= ctx
;
1881 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1884 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1886 update_position(This
, FALSE
);
1887 while(p
-4>=This
->pParserCtxt
->input
->base
1888 && memcmp(p
-4, "<!--", sizeof(char[4])))
1890 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1896 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1899 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1901 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1903 if (This
->vbInterface
)
1904 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1906 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1909 format_error_message_from_id(This
, hr
);
1912 static void libxmlFatalError(void *ctx
, const char *msg
, ...)
1914 saxlocator
*This
= ctx
;
1915 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1921 if(This
->ret
!= S_OK
) {
1922 xmlStopParser(This
->pParserCtxt
);
1926 va_start(args
, msg
);
1927 vsprintf(message
, msg
, args
);
1930 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1931 error
= heap_alloc(sizeof(WCHAR
)*len
);
1934 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1935 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1938 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1940 xmlStopParser(This
->pParserCtxt
);
1946 FIXME("Error handling is not compatible.\n");
1948 if(This
->vbInterface
)
1950 BSTR bstrError
= SysAllocString(error
);
1951 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1952 &bstrError
, E_FAIL
);
1953 SysFreeString(bstrError
);
1956 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1960 xmlStopParser(This
->pParserCtxt
);
1964 /* The only reason this helper exists is that CDATA section are reported by chunks,
1965 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1967 This helper should be called for substring with trailing newlines.
1969 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1971 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1974 ptr
= bstr
+ len
- 1;
1975 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1980 /* replace returns as:
1982 - "\r<char>" -> "\n<char>"
1988 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
1991 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
1998 ret
= SysAllocStringLen(bstr
, len
);
1999 SysFreeString(bstr
);
2003 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
2005 const xmlChar
*start
, *end
;
2006 saxlocator
*locator
= ctx
;
2007 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
2012 update_position(locator
, FALSE
);
2013 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2015 if (locator
->vbInterface
)
2016 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
2018 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
2023 format_error_message_from_id(locator
, hr
);
2033 /* scan for newlines */
2034 if (value
[i
] == '\r' || value
[i
] == '\n')
2036 /* skip newlines/linefeeds */
2039 if (value
[i
] != '\r' && value
[i
] != '\n') break;
2045 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
2046 TRACE("(chunk %s)\n", debugstr_w(chars
));
2047 hr
= saxreader_saxcharacters(locator
, chars
);
2048 SysFreeString(chars
);
2057 /* no newline chars (or last chunk) report as a whole */
2058 if (!end
&& start
== value
)
2061 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
2062 TRACE("(%s)\n", debugstr_w(chars
));
2063 hr
= saxreader_saxcharacters(locator
, chars
);
2064 SysFreeString(chars
);
2067 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2069 if (locator
->vbInterface
)
2070 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
2072 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
2076 format_error_message_from_id(locator
, hr
);
2079 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
2081 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
2082 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
2085 /*** IVBSAXLocator interface ***/
2086 /*** IUnknown methods ***/
2087 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2089 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2091 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2095 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2096 IsEqualGUID( riid
, &IID_IDispatch
) ||
2097 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
2101 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
2103 *ppvObject
= &This
->IVBSAXAttributes_iface
;
2107 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2108 return E_NOINTERFACE
;
2111 IVBSAXLocator_AddRef( iface
);
2116 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
2118 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2119 TRACE("%p\n", This
);
2120 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
2123 static ULONG WINAPI
ivbsaxlocator_Release(IVBSAXLocator
* iface
)
2125 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2126 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
2129 /*** IDispatch methods ***/
2130 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
2132 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2134 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2141 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
2142 IVBSAXLocator
*iface
,
2143 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2145 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2147 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2149 return get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2152 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2153 IVBSAXLocator
*iface
,
2155 LPOLESTR
* rgszNames
,
2160 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2161 ITypeInfo
*typeinfo
;
2164 TRACE("(%p)->(%s %p %u %u %p)\n", This
, 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 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2192 ITypeInfo
*typeinfo
;
2195 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2196 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2198 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2201 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXLocator_iface
, dispIdMember
, wFlags
,
2202 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)->(%d)\n", This
, ref
);
2317 static ULONG WINAPI
isaxlocator_Release(
2320 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2321 LONG ref
= InterlockedDecrement( &This
->ref
);
2323 TRACE("(%p)->(%d)\n", This
, 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 heap_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
= heap_alloc( 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
= heap_alloc_zero(sizeof(struct _attributes
)*locator
->attr_alloc_count
);
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 /* xml declaration with possibly specfied encoding will be still handled by 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
, strlenW(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 IPersistStream
*persistStream
;
2664 ISequentialStream
*stream
= NULL
;
2665 IXMLDOMDocument
*xmlDoc
;
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 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2681 &IID_IPersistStream
, (void**)&persistStream
) == S_OK
)
2683 IStream
*stream_copy
;
2685 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream_copy
);
2688 IPersistStream_Release(persistStream
);
2692 hr
= IPersistStream_Save(persistStream
, stream_copy
, TRUE
);
2693 IPersistStream_Release(persistStream
);
2695 IStream_QueryInterface(stream_copy
, &IID_ISequentialStream
, (void**)&stream
);
2697 IStream_Release(stream_copy
);
2700 /* try base interface first */
2703 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2705 /* this should never happen if IStream is implemented properly, but just in case */
2706 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2711 hr
= internal_parseStream(This
, stream
, vbInterface
);
2712 ISequentialStream_Release(stream
);
2716 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2723 WARN("vt %d not implemented\n", V_VT(&varInput
));
2730 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2732 saxreader
*This
= obj
;
2734 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2737 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2739 saxreader
*This
= obj
;
2741 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2744 static HRESULT
internal_parseURL(
2753 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
2755 hr
= create_moniker_from_url(url
, &mon
);
2759 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, This
, &bsc
);
2760 else hr
= bind_url(mon
, internal_onDataAvailable
, This
, &bsc
);
2761 IMoniker_Release(mon
);
2766 return detach_bsc(bsc
);
2769 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2773 if (V_VT(v
) == VT_EMPTY
)
2774 return saxreader_put_handler(This
, type
, NULL
, vb
);
2778 case SAXDeclHandler
:
2779 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2781 case SAXLexicalHandler
:
2782 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2785 ERR("wrong handler type %d\n", type
);
2794 IUnknown
*handler
= NULL
;
2798 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2799 if (FAILED(hr
)) return hr
;
2802 saxreader_put_handler(This
, type
, handler
, vb
);
2803 if (handler
) IUnknown_Release(handler
);
2807 ERR("value type %d not supported\n", V_VT(v
));
2808 return E_INVALIDARG
;
2814 static HRESULT
internal_putProperty(
2822 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2824 if (This
->isParsing
) return E_FAIL
;
2826 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2827 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2828 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2830 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2831 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2833 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2835 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2836 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2840 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2842 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2843 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2847 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2849 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2852 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2855 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2858 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2861 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2864 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2867 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2870 return E_INVALIDARG
;
2873 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2875 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2877 if (!value
) return E_POINTER
;
2879 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2881 V_VT(value
) = VT_UNKNOWN
;
2882 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2886 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2888 V_VT(value
) = VT_UNKNOWN
;
2889 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2893 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2895 V_VT(value
) = VT_BSTR
;
2896 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2900 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2905 /*** IVBSAXXMLReader interface ***/
2906 /*** IUnknown methods ***/
2907 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2909 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2911 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2915 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2916 IsEqualGUID( riid
, &IID_IDispatch
) ||
2917 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2921 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2923 *ppvObject
= &This
->ISAXXMLReader_iface
;
2925 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2927 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2931 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2932 return E_NOINTERFACE
;
2935 IVBSAXXMLReader_AddRef( iface
);
2940 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2942 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2943 TRACE("%p\n", This
);
2944 return InterlockedIncrement( &This
->ref
);
2947 static ULONG WINAPI
saxxmlreader_Release(
2948 IVBSAXXMLReader
* iface
)
2950 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2953 TRACE("%p\n", This
);
2955 ref
= InterlockedDecrement( &This
->ref
);
2960 for (i
= 0; i
< SAXHandler_Last
; i
++)
2962 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2964 if (saxiface
->handler
)
2965 IUnknown_Release(saxiface
->handler
);
2967 if (saxiface
->vbhandler
)
2968 IUnknown_Release(saxiface
->vbhandler
);
2971 SysFreeString(This
->xmldecl_version
);
2972 free_bstr_pool(&This
->pool
);
2980 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2982 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2983 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2986 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2987 IVBSAXXMLReader
*iface
,
2988 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2990 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2991 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2992 iTInfo
, lcid
, ppTInfo
);
2995 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2996 IVBSAXXMLReader
*iface
,
2998 LPOLESTR
* rgszNames
,
3003 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3004 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
3005 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
3008 static HRESULT WINAPI
saxxmlreader_Invoke(
3009 IVBSAXXMLReader
*iface
,
3010 DISPID dispIdMember
,
3014 DISPPARAMS
* pDispParams
,
3015 VARIANT
* pVarResult
,
3016 EXCEPINFO
* pExcepInfo
,
3019 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3020 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
3021 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3024 /*** IVBSAXXMLReader methods ***/
3025 static HRESULT WINAPI
saxxmlreader_getFeature(
3026 IVBSAXXMLReader
* iface
,
3028 VARIANT_BOOL
*value
)
3030 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3031 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3034 static HRESULT WINAPI
saxxmlreader_putFeature(
3035 IVBSAXXMLReader
* iface
,
3039 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3040 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3043 static HRESULT WINAPI
saxxmlreader_getProperty(
3044 IVBSAXXMLReader
* iface
,
3048 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3049 return internal_getProperty(This
, prop
, value
, TRUE
);
3052 static HRESULT WINAPI
saxxmlreader_putProperty(
3053 IVBSAXXMLReader
* iface
,
3057 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3058 return internal_putProperty(This
, pProp
, value
, TRUE
);
3061 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3062 IVBSAXXMLReader
* iface
,
3063 IVBSAXEntityResolver
**resolver
)
3065 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3066 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3069 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3070 IVBSAXXMLReader
* iface
,
3071 IVBSAXEntityResolver
*resolver
)
3073 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3074 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3077 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3078 IVBSAXXMLReader
* iface
,
3079 IVBSAXContentHandler
**handler
)
3081 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3082 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3085 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3086 IVBSAXXMLReader
* iface
,
3087 IVBSAXContentHandler
*handler
)
3089 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3090 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3093 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3094 IVBSAXXMLReader
* iface
,
3095 IVBSAXDTDHandler
**handler
)
3097 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3098 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3101 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3102 IVBSAXXMLReader
* iface
,
3103 IVBSAXDTDHandler
*handler
)
3105 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3106 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3109 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3110 IVBSAXXMLReader
* iface
,
3111 IVBSAXErrorHandler
**handler
)
3113 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3114 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3117 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3118 IVBSAXXMLReader
* iface
,
3119 IVBSAXErrorHandler
*handler
)
3121 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3122 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3125 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3126 IVBSAXXMLReader
* iface
,
3129 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3131 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3135 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3136 IVBSAXXMLReader
* iface
,
3139 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3140 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3143 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3144 IVBSAXXMLReader
* iface
,
3145 BSTR
*pSecureBaseUrl
)
3147 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3149 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3153 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3154 IVBSAXXMLReader
* iface
,
3157 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3158 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3161 static HRESULT WINAPI
saxxmlreader_parse(
3162 IVBSAXXMLReader
* iface
,
3165 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3166 return internal_parse(This
, varInput
, TRUE
);
3169 static HRESULT WINAPI
saxxmlreader_parseURL(
3170 IVBSAXXMLReader
* iface
,
3173 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3174 return internal_parseURL(This
, url
, TRUE
);
3177 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3179 saxxmlreader_QueryInterface
,
3180 saxxmlreader_AddRef
,
3181 saxxmlreader_Release
,
3182 saxxmlreader_GetTypeInfoCount
,
3183 saxxmlreader_GetTypeInfo
,
3184 saxxmlreader_GetIDsOfNames
,
3185 saxxmlreader_Invoke
,
3186 saxxmlreader_getFeature
,
3187 saxxmlreader_putFeature
,
3188 saxxmlreader_getProperty
,
3189 saxxmlreader_putProperty
,
3190 saxxmlreader_get_entityResolver
,
3191 saxxmlreader_put_entityResolver
,
3192 saxxmlreader_get_contentHandler
,
3193 saxxmlreader_put_contentHandler
,
3194 saxxmlreader_get_dtdHandler
,
3195 saxxmlreader_put_dtdHandler
,
3196 saxxmlreader_get_errorHandler
,
3197 saxxmlreader_put_errorHandler
,
3198 saxxmlreader_get_baseURL
,
3199 saxxmlreader_put_baseURL
,
3200 saxxmlreader_get_secureBaseURL
,
3201 saxxmlreader_put_secureBaseURL
,
3203 saxxmlreader_parseURL
3206 /*** ISAXXMLReader interface ***/
3207 /*** IUnknown methods ***/
3208 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3210 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3211 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3214 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3216 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3217 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3220 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3222 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3223 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3226 /*** ISAXXMLReader methods ***/
3227 static HRESULT WINAPI
isaxxmlreader_getFeature(
3228 ISAXXMLReader
* iface
,
3229 const WCHAR
*feature_name
,
3230 VARIANT_BOOL
*value
)
3232 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3233 saxreader_feature feature
;
3235 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3237 feature
= get_saxreader_feature(feature_name
);
3238 if (feature
== Namespaces
|| feature
== NamespacePrefixes
)
3239 return get_feature_value(This
, feature
, value
);
3241 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3245 static HRESULT WINAPI
isaxxmlreader_putFeature(
3246 ISAXXMLReader
* iface
,
3247 const WCHAR
*feature_name
,
3250 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3251 saxreader_feature feature
;
3253 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3255 feature
= get_saxreader_feature(feature_name
);
3257 /* accepted cases */
3258 if ((feature
== ExternalGeneralEntities
&& value
== VARIANT_FALSE
) ||
3259 (feature
== ExternalParameterEntities
&& value
== VARIANT_FALSE
) ||
3260 feature
== Namespaces
||
3261 feature
== NamespacePrefixes
)
3263 return set_feature_value(This
, feature
, value
);
3266 if (feature
== LexicalHandlerParEntities
|| feature
== ProhibitDTD
)
3268 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3269 return set_feature_value(This
, feature
, value
);
3272 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3276 static HRESULT WINAPI
isaxxmlreader_getProperty(
3277 ISAXXMLReader
* iface
,
3281 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3282 return internal_getProperty(This
, prop
, value
, FALSE
);
3285 static HRESULT WINAPI
isaxxmlreader_putProperty(
3286 ISAXXMLReader
* iface
,
3290 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3291 return internal_putProperty(This
, pProp
, value
, FALSE
);
3294 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3295 ISAXXMLReader
* iface
,
3296 ISAXEntityResolver
**resolver
)
3298 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3299 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3302 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3303 ISAXXMLReader
* iface
,
3304 ISAXEntityResolver
*resolver
)
3306 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3307 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3310 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3311 ISAXXMLReader
* iface
,
3312 ISAXContentHandler
**handler
)
3314 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3315 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3318 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3319 ISAXXMLReader
* iface
,
3320 ISAXContentHandler
*handler
)
3322 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3323 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3326 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3327 ISAXXMLReader
* iface
,
3328 ISAXDTDHandler
**handler
)
3330 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3331 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3334 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3335 ISAXXMLReader
* iface
,
3336 ISAXDTDHandler
*handler
)
3338 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3339 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3342 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3343 ISAXXMLReader
* iface
,
3344 ISAXErrorHandler
**handler
)
3346 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3347 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3350 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3352 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3353 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3356 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3357 ISAXXMLReader
* iface
,
3358 const WCHAR
**base_url
)
3360 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3362 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3366 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3367 ISAXXMLReader
* iface
,
3368 const WCHAR
*pBaseUrl
)
3370 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3372 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3376 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3377 ISAXXMLReader
* iface
,
3378 const WCHAR
**pSecureBaseUrl
)
3380 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3381 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3385 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3386 ISAXXMLReader
* iface
,
3387 const WCHAR
*secureBaseUrl
)
3389 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3391 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3395 static HRESULT WINAPI
isaxxmlreader_parse(
3396 ISAXXMLReader
* iface
,
3399 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3400 return internal_parse(This
, varInput
, FALSE
);
3403 static HRESULT WINAPI
isaxxmlreader_parseURL(
3404 ISAXXMLReader
* iface
,
3407 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3408 return internal_parseURL(This
, url
, FALSE
);
3411 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3413 isaxxmlreader_QueryInterface
,
3414 isaxxmlreader_AddRef
,
3415 isaxxmlreader_Release
,
3416 isaxxmlreader_getFeature
,
3417 isaxxmlreader_putFeature
,
3418 isaxxmlreader_getProperty
,
3419 isaxxmlreader_putProperty
,
3420 isaxxmlreader_getEntityResolver
,
3421 isaxxmlreader_putEntityResolver
,
3422 isaxxmlreader_getContentHandler
,
3423 isaxxmlreader_putContentHandler
,
3424 isaxxmlreader_getDTDHandler
,
3425 isaxxmlreader_putDTDHandler
,
3426 isaxxmlreader_getErrorHandler
,
3427 isaxxmlreader_putErrorHandler
,
3428 isaxxmlreader_getBaseURL
,
3429 isaxxmlreader_putBaseURL
,
3430 isaxxmlreader_getSecureBaseURL
,
3431 isaxxmlreader_putSecureBaseURL
,
3432 isaxxmlreader_parse
,
3433 isaxxmlreader_parseURL
3436 static const tid_t saxreader_iface_tids
[] = {
3437 IVBSAXXMLReader_tid
,
3440 static dispex_static_data_t saxreader_dispex
= {
3442 IVBSAXXMLReader_tid
,
3444 saxreader_iface_tids
3447 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3451 TRACE("(%p)\n", ppObj
);
3453 reader
= heap_alloc( sizeof (*reader
) );
3455 return E_OUTOFMEMORY
;
3457 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3458 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3460 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3461 reader
->isParsing
= FALSE
;
3462 reader
->xmldecl_version
= NULL
;
3463 reader
->pool
.pool
= NULL
;
3464 reader
->pool
.index
= 0;
3465 reader
->pool
.len
= 0;
3466 reader
->features
= Namespaces
| NamespacePrefixes
;
3467 reader
->version
= version
;
3469 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3471 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3472 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3473 reader
->sax
.startDocument
= libxmlStartDocument
;
3474 reader
->sax
.endDocument
= libxmlEndDocument
;
3475 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3476 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3477 reader
->sax
.characters
= libxmlCharacters
;
3478 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3479 reader
->sax
.comment
= libxmlComment
;
3480 reader
->sax
.error
= libxmlFatalError
;
3481 reader
->sax
.fatalError
= libxmlFatalError
;
3482 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3483 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3485 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3487 TRACE("returning iface %p\n", *ppObj
);
3494 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3496 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3497 "libxml2 support was not present at compile time.\n");