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
21 #define WIN32_NO_STATUS
30 //# include <libxml/parser.h>
31 //# include <libxml/xmlerror.h>
32 //# include <libxml/SAX2.h>
33 # include <libxml/parserInternals.h>
38 //#include "winuser.h"
42 //#include "wininet.h"
45 //#include "shlwapi.h"
47 #include <wine/debug.h>
48 #include <wine/list.h>
50 #include "msxml_private.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
59 ExhaustiveErrors
= 1 << 1,
60 ExternalGeneralEntities
= 1 << 2,
61 ExternalParameterEntities
= 1 << 3,
62 ForcedResync
= 1 << 4,
63 NamespacePrefixes
= 1 << 5,
65 ParameterEntities
= 1 << 7,
66 PreserveSystemIndentifiers
= 1 << 8,
68 SchemaValidation
= 1 << 10,
69 ServerHttpRequest
= 1 << 11,
70 SuppressValidationfatalError
= 1 << 12,
71 UseInlineSchema
= 1 << 13,
72 UseSchemaLocation
= 1 << 14,
73 LexicalHandlerParEntities
= 1 << 15
77 static const WCHAR FeatureExternalGeneralEntitiesW
[] = {
78 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/',
79 'f','e','a','t','u','r','e','s','/','e','x','t','e','r','n','a','l','-','g','e','n','e','r','a','l',
80 '-','e','n','t','i','t','i','e','s',0
83 static const WCHAR FeatureExternalParameterEntitiesW
[] = {
84 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
85 '/','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
88 static const WCHAR FeatureLexicalHandlerParEntitiesW
[] = {
89 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
90 '/','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
93 static const WCHAR FeatureProhibitDTDW
[] = {
94 'p','r','o','h','i','b','i','t','-','d','t','d',0
97 static const WCHAR FeatureNamespacesW
[] = {
98 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
99 '/','n','a','m','e','s','p','a','c','e','s',0
102 static const WCHAR FeatureNamespacePrefixesW
[] = {
103 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
104 '/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0
107 struct saxreader_feature_pair
109 saxreader_feature feature
;
113 static const struct saxreader_feature_pair saxreader_feature_map
[] = {
114 { ExternalGeneralEntities
, FeatureExternalGeneralEntitiesW
},
115 { ExternalParameterEntities
, FeatureExternalParameterEntitiesW
},
116 { LexicalHandlerParEntities
, FeatureLexicalHandlerParEntitiesW
},
117 { NamespacePrefixes
, FeatureNamespacePrefixesW
},
118 { Namespaces
, FeatureNamespacesW
},
119 { ProhibitDTD
, FeatureProhibitDTDW
}
122 static saxreader_feature
get_saxreader_feature(const WCHAR
*name
)
127 max
= sizeof(saxreader_feature_map
)/sizeof(struct saxreader_feature_pair
) - 1;
133 c
= strcmpW(saxreader_feature_map
[n
].name
, name
);
135 return saxreader_feature_map
[n
].feature
;
143 return FeatureUnknown
;
165 ns
*ns
; /* namespaces defined in this particular element */
171 SAXContentHandler
= 0,
180 struct saxanyhandler_iface
186 struct saxcontenthandler_iface
188 ISAXContentHandler
*handler
;
189 IVBSAXContentHandler
*vbhandler
;
192 struct saxerrorhandler_iface
194 ISAXErrorHandler
*handler
;
195 IVBSAXErrorHandler
*vbhandler
;
198 struct saxlexicalhandler_iface
200 ISAXLexicalHandler
*handler
;
201 IVBSAXLexicalHandler
*vbhandler
;
204 struct saxentityresolver_iface
206 ISAXEntityResolver
*handler
;
207 IVBSAXEntityResolver
*vbhandler
;
210 struct saxhandler_iface
213 struct saxcontenthandler_iface content
;
214 struct saxentityresolver_iface entityresolver
;
215 struct saxerrorhandler_iface error
;
216 struct saxlexicalhandler_iface lexical
;
217 struct saxanyhandler_iface anyhandler
;
224 IVBSAXXMLReader IVBSAXXMLReader_iface
;
225 ISAXXMLReader ISAXXMLReader_iface
;
228 struct saxhandler_iface saxhandlers
[SAXHandler_Last
];
231 struct bstrpool pool
;
232 saxreader_feature features
;
233 BSTR xmldecl_version
;
234 MSXML_VERSION version
;
237 static HRESULT
saxreader_put_handler(saxreader
*reader
, enum saxhandler_type type
, void *ptr
, BOOL vb
)
239 struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
240 IUnknown
*unk
= (IUnknown
*)ptr
;
243 IUnknown_AddRef(unk
);
245 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
246 IUnknown_Release(vb
? iface
->vbhandler
: iface
->handler
);
249 iface
->vbhandler
= unk
;
251 iface
->handler
= unk
;
256 static HRESULT
saxreader_get_handler(const saxreader
*reader
, enum saxhandler_type type
, BOOL vb
, void **ret
)
258 const struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
260 if (!ret
) return E_POINTER
;
262 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
265 IUnknown_AddRef(iface
->vbhandler
);
267 IUnknown_AddRef(iface
->handler
);
270 *ret
= vb
? iface
->vbhandler
: iface
->handler
;
275 static struct saxcontenthandler_iface
*saxreader_get_contenthandler(saxreader
*reader
)
277 return &reader
->saxhandlers
[SAXContentHandler
].u
.content
;
280 static struct saxerrorhandler_iface
*saxreader_get_errorhandler(saxreader
*reader
)
282 return &reader
->saxhandlers
[SAXErrorHandler
].u
.error
;
285 static struct saxlexicalhandler_iface
*saxreader_get_lexicalhandler(saxreader
*reader
)
287 return &reader
->saxhandlers
[SAXLexicalHandler
].u
.lexical
;
292 IVBSAXLocator IVBSAXLocator_iface
;
293 ISAXLocator ISAXLocator_iface
;
294 IVBSAXAttributes IVBSAXAttributes_iface
;
295 ISAXAttributes ISAXAttributes_iface
;
297 saxreader
*saxreader
;
299 xmlParserCtxtPtr pParserCtxt
;
305 struct list elements
;
319 static inline saxreader
*impl_from_IVBSAXXMLReader( IVBSAXXMLReader
*iface
)
321 return CONTAINING_RECORD(iface
, saxreader
, IVBSAXXMLReader_iface
);
324 static inline saxreader
*impl_from_ISAXXMLReader( ISAXXMLReader
*iface
)
326 return CONTAINING_RECORD(iface
, saxreader
, ISAXXMLReader_iface
);
329 static inline saxlocator
*impl_from_IVBSAXLocator( IVBSAXLocator
*iface
)
331 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXLocator_iface
);
334 static inline saxlocator
*impl_from_ISAXLocator( ISAXLocator
*iface
)
336 return CONTAINING_RECORD(iface
, saxlocator
, ISAXLocator_iface
);
339 static inline saxlocator
*impl_from_IVBSAXAttributes( IVBSAXAttributes
*iface
)
341 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXAttributes_iface
);
344 static inline saxlocator
*impl_from_ISAXAttributes( ISAXAttributes
*iface
)
346 return CONTAINING_RECORD(iface
, saxlocator
, ISAXAttributes_iface
);
349 static inline int saxreader_has_handler(const saxlocator
*locator
, enum saxhandler_type type
)
351 struct saxanyhandler_iface
*iface
= &locator
->saxreader
->saxhandlers
[type
].u
.anyhandler
;
352 return (locator
->vbInterface
&& iface
->vbhandler
) || (!locator
->vbInterface
&& iface
->handler
);
355 static HRESULT
saxreader_saxcharacters(saxlocator
*locator
, BSTR chars
)
357 struct saxcontenthandler_iface
*content
= saxreader_get_contenthandler(locator
->saxreader
);
360 if (!saxreader_has_handler(locator
, SAXContentHandler
)) return S_OK
;
362 if (locator
->vbInterface
)
363 hr
= IVBSAXContentHandler_characters(content
->vbhandler
, &chars
);
365 hr
= ISAXContentHandler_characters(content
->handler
, chars
, SysStringLen(chars
));
371 static const WCHAR PropertyCharsetW
[] = {
372 'c','h','a','r','s','e','t',0
374 static const WCHAR PropertyXmlDeclVersionW
[] = {
375 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
377 static const WCHAR PropertyDeclHandlerW
[] = {
378 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
379 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
380 'd','e','c','l','a','r','a','t','i','o','n',
381 '-','h','a','n','d','l','e','r',0
383 static const WCHAR PropertyDomNodeW
[] = {
384 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
385 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
386 'd','o','m','-','n','o','d','e',0
388 static const WCHAR PropertyInputSourceW
[] = {
389 'i','n','p','u','t','-','s','o','u','r','c','e',0
391 static const WCHAR PropertyLexicalHandlerW
[] = {
392 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
393 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
394 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
396 static const WCHAR PropertyMaxElementDepthW
[] = {
397 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
399 static const WCHAR PropertyMaxXMLSizeW
[] = {
400 'm','a','x','-','x','m','l','-','s','i','z','e',0
402 static const WCHAR PropertySchemaDeclHandlerW
[] = {
403 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
404 'h','a','n','d','l','e','r',0
406 static const WCHAR PropertyXMLDeclEncodingW
[] = {
407 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
409 static const WCHAR PropertyXMLDeclStandaloneW
[] = {
410 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
412 static const WCHAR PropertyXMLDeclVersionW
[] = {
413 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
416 static inline HRESULT
set_feature_value(saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL value
)
418 /* handling of non-VARIANT_* values is version dependent */
419 if ((reader
->version
< MSXML4
) && (value
!= VARIANT_TRUE
))
420 value
= VARIANT_FALSE
;
421 if ((reader
->version
>= MSXML4
) && (value
!= VARIANT_FALSE
))
422 value
= VARIANT_TRUE
;
424 if (value
== VARIANT_TRUE
)
425 reader
->features
|= feature
;
427 reader
->features
&= ~feature
;
432 static inline HRESULT
get_feature_value(const saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL
*value
)
434 *value
= reader
->features
& feature
? VARIANT_TRUE
: VARIANT_FALSE
;
438 static BOOL
is_namespaces_enabled(const saxreader
*reader
)
440 return (reader
->version
< MSXML4
) || (reader
->features
& Namespaces
);
443 static BSTR
build_qname(BSTR prefix
, BSTR local
)
445 if (prefix
&& *prefix
)
447 BSTR qname
= SysAllocStringLen(NULL
, SysStringLen(prefix
) + SysStringLen(local
) + 1);
451 strcpyW(ptr
, prefix
);
452 ptr
+= SysStringLen(prefix
);
458 return SysAllocString(local
);
461 static element_entry
* alloc_element_entry(const xmlChar
*local
, const xmlChar
*prefix
, int nb_ns
,
462 const xmlChar
**namespaces
)
467 ret
= heap_alloc(sizeof(*ret
));
468 if (!ret
) return ret
;
470 ret
->local
= bstr_from_xmlChar(local
);
471 ret
->prefix
= bstr_from_xmlChar(prefix
);
472 ret
->qname
= build_qname(ret
->prefix
, ret
->local
);
473 ret
->ns
= nb_ns
? heap_alloc(nb_ns
*sizeof(ns
)) : NULL
;
474 ret
->ns_count
= nb_ns
;
476 for (i
=0; i
< nb_ns
; i
++)
478 ret
->ns
[i
].prefix
= bstr_from_xmlChar(namespaces
[2*i
]);
479 ret
->ns
[i
].uri
= bstr_from_xmlChar(namespaces
[2*i
+1]);
485 static void free_element_entry(element_entry
*element
)
489 for (i
=0; i
<element
->ns_count
;i
++)
491 SysFreeString(element
->ns
[i
].prefix
);
492 SysFreeString(element
->ns
[i
].uri
);
495 SysFreeString(element
->prefix
);
496 SysFreeString(element
->local
);
498 heap_free(element
->ns
);
502 static void push_element_ns(saxlocator
*locator
, element_entry
*element
)
504 list_add_head(&locator
->elements
, &element
->entry
);
507 static element_entry
* pop_element_ns(saxlocator
*locator
)
509 element_entry
*element
= LIST_ENTRY(list_head(&locator
->elements
), element_entry
, entry
);
512 list_remove(&element
->entry
);
517 static BSTR
find_element_uri(saxlocator
*locator
, const xmlChar
*uri
)
519 element_entry
*element
;
523 if (!uri
) return NULL
;
525 uriW
= bstr_from_xmlChar(uri
);
527 LIST_FOR_EACH_ENTRY(element
, &locator
->elements
, element_entry
, entry
)
529 for (i
=0; i
< element
->ns_count
; i
++)
530 if (!strcmpW(uriW
, element
->ns
[i
].uri
))
533 return element
->ns
[i
].uri
;
538 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri
));
542 /* used to localize version dependent error check behaviour */
543 static inline BOOL
sax_callback_failed(saxlocator
*This
, HRESULT hr
)
545 return This
->saxreader
->version
>= MSXML4
? FAILED(hr
) : hr
!= S_OK
;
548 /* index value -1 means it tries to loop for a first time */
549 static inline BOOL
iterate_endprefix_index(saxlocator
*This
, const element_entry
*element
, int *i
)
551 if (This
->saxreader
->version
>= MSXML4
)
553 if (*i
== -1) *i
= 0; else ++*i
;
554 return *i
< element
->ns_count
;
558 if (*i
== -1) *i
= element
->ns_count
-1; else --*i
;
563 static BOOL
bstr_pool_insert(struct bstrpool
*pool
, BSTR pool_entry
)
567 pool
->pool
= HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(*pool
->pool
));
574 else if (pool
->index
== pool
->len
)
576 BSTR
*realloc
= HeapReAlloc(GetProcessHeap(), 0, pool
->pool
, pool
->len
* 2 * sizeof(*realloc
));
581 pool
->pool
= realloc
;
585 pool
->pool
[pool
->index
++] = pool_entry
;
589 static void free_bstr_pool(struct bstrpool
*pool
)
593 for (i
= 0; i
< pool
->index
; i
++)
594 SysFreeString(pool
->pool
[i
]);
596 HeapFree(GetProcessHeap(), 0, pool
->pool
);
599 pool
->index
= pool
->len
= 0;
602 static BSTR
bstr_from_xmlCharN(const xmlChar
*buf
, int len
)
610 dLen
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
611 if(len
!= -1) dLen
++;
612 bstr
= SysAllocStringLen(NULL
, dLen
-1);
615 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, bstr
, dLen
);
616 if(len
!= -1) bstr
[dLen
-1] = '\0';
621 static BSTR
QName_from_xmlChar(const xmlChar
*prefix
, const xmlChar
*name
)
626 if(!name
) return NULL
;
628 if(!prefix
|| !*prefix
)
629 return bstr_from_xmlChar(name
);
631 qname
= xmlBuildQName(name
, prefix
, NULL
, 0);
632 bstr
= bstr_from_xmlChar(qname
);
638 static BSTR
pooled_bstr_from_xmlChar(struct bstrpool
*pool
, const xmlChar
*buf
)
640 BSTR pool_entry
= bstr_from_xmlChar(buf
);
642 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
644 SysFreeString(pool_entry
);
651 static BSTR
pooled_bstr_from_xmlCharN(struct bstrpool
*pool
, const xmlChar
*buf
, int len
)
653 BSTR pool_entry
= bstr_from_xmlCharN(buf
, len
);
655 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
657 SysFreeString(pool_entry
);
664 static void format_error_message_from_id(saxlocator
*This
, HRESULT hr
)
666 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
667 xmlStopParser(This
->pParserCtxt
);
670 if (saxreader_has_handler(This
, SAXErrorHandler
))
673 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
,
674 NULL
, hr
, 0, msg
, sizeof(msg
), NULL
))
676 FIXME("MSXML errors not yet supported.\n");
680 if(This
->vbInterface
)
682 BSTR bstrMsg
= SysAllocString(msg
);
683 IVBSAXErrorHandler_fatalError(handler
->vbhandler
,
684 &This
->IVBSAXLocator_iface
, &bstrMsg
, hr
);
685 SysFreeString(bstrMsg
);
688 ISAXErrorHandler_fatalError(handler
->handler
,
689 &This
->ISAXLocator_iface
, msg
, hr
);
693 static void update_position(saxlocator
*This
, BOOL fix_column
)
695 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
697 This
->line
= xmlSAX2GetLineNumber(This
->pParserCtxt
);
701 for(; *p
!='\n' && *p
!='\r' && p
>=This
->pParserCtxt
->input
->base
; p
--)
706 This
->column
= xmlSAX2GetColumnNumber(This
->pParserCtxt
);
710 /*** IVBSAXAttributes interface ***/
711 /*** IUnknown methods ***/
712 static HRESULT WINAPI
ivbsaxattributes_QueryInterface(
713 IVBSAXAttributes
* iface
,
717 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
718 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
719 return IVBSAXLocator_QueryInterface(&This
->IVBSAXLocator_iface
, riid
, ppvObject
);
722 static ULONG WINAPI
ivbsaxattributes_AddRef(IVBSAXAttributes
* iface
)
724 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
725 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
728 static ULONG WINAPI
ivbsaxattributes_Release(IVBSAXAttributes
* iface
)
730 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
731 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
734 /*** IDispatch methods ***/
735 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes
*iface
, UINT
* pctinfo
)
737 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
739 TRACE("(%p)->(%p)\n", This
, pctinfo
);
746 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfo(
747 IVBSAXAttributes
*iface
,
748 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
750 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
753 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
755 hr
= get_typeinfo(IVBSAXAttributes_tid
, ppTInfo
);
760 static HRESULT WINAPI
ivbsaxattributes_GetIDsOfNames(
761 IVBSAXAttributes
*iface
,
768 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
772 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
775 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
778 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
781 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
782 ITypeInfo_Release(typeinfo
);
788 static HRESULT WINAPI
ivbsaxattributes_Invoke(
789 IVBSAXAttributes
*iface
,
794 DISPPARAMS
* pDispParams
,
796 EXCEPINFO
* pExcepInfo
,
799 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
803 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
804 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
806 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
809 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXAttributes_iface
, dispIdMember
, wFlags
,
810 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
811 ITypeInfo_Release(typeinfo
);
817 /*** IVBSAXAttributes methods ***/
818 static HRESULT WINAPI
ivbsaxattributes_get_length(
819 IVBSAXAttributes
* iface
,
822 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
823 return ISAXAttributes_getLength(&This
->ISAXAttributes_iface
, nLength
);
826 static HRESULT WINAPI
ivbsaxattributes_getURI(
827 IVBSAXAttributes
* iface
,
832 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
833 return ISAXAttributes_getURI(&This
->ISAXAttributes_iface
, nIndex
, (const WCHAR
**)uri
, &len
);
836 static HRESULT WINAPI
ivbsaxattributes_getLocalName(
837 IVBSAXAttributes
* iface
,
842 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
843 return ISAXAttributes_getLocalName(&This
->ISAXAttributes_iface
, nIndex
,
844 (const WCHAR
**)localName
, &len
);
847 static HRESULT WINAPI
ivbsaxattributes_getQName(
848 IVBSAXAttributes
* iface
,
853 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
854 return ISAXAttributes_getQName(&This
->ISAXAttributes_iface
, nIndex
, (const WCHAR
**)QName
, &len
);
857 static HRESULT WINAPI
ivbsaxattributes_getIndexFromName(
858 IVBSAXAttributes
* iface
,
863 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
864 return ISAXAttributes_getIndexFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
865 localName
, SysStringLen(localName
), index
);
868 static HRESULT WINAPI
ivbsaxattributes_getIndexFromQName(
869 IVBSAXAttributes
* iface
,
873 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
874 return ISAXAttributes_getIndexFromQName(&This
->ISAXAttributes_iface
, QName
,
875 SysStringLen(QName
), index
);
878 static HRESULT WINAPI
ivbsaxattributes_getType(
879 IVBSAXAttributes
* iface
,
884 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
885 return ISAXAttributes_getType(&This
->ISAXAttributes_iface
, nIndex
, (const WCHAR
**)type
, &len
);
888 static HRESULT WINAPI
ivbsaxattributes_getTypeFromName(
889 IVBSAXAttributes
* iface
,
895 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
896 return ISAXAttributes_getTypeFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
897 localName
, SysStringLen(localName
), (const WCHAR
**)type
, &len
);
900 static HRESULT WINAPI
ivbsaxattributes_getTypeFromQName(
901 IVBSAXAttributes
* iface
,
906 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
907 return ISAXAttributes_getTypeFromQName(&This
->ISAXAttributes_iface
, QName
, SysStringLen(QName
),
908 (const WCHAR
**)type
, &len
);
911 static HRESULT WINAPI
ivbsaxattributes_getValue(
912 IVBSAXAttributes
* iface
,
917 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
918 return ISAXAttributes_getValue(&This
->ISAXAttributes_iface
, nIndex
, (const WCHAR
**)value
, &len
);
921 static HRESULT WINAPI
ivbsaxattributes_getValueFromName(
922 IVBSAXAttributes
* iface
,
928 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
929 return ISAXAttributes_getValueFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
930 localName
, SysStringLen(localName
), (const WCHAR
**)value
, &len
);
933 static HRESULT WINAPI
ivbsaxattributes_getValueFromQName(
934 IVBSAXAttributes
* iface
,
939 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
940 return ISAXAttributes_getValueFromQName(&This
->ISAXAttributes_iface
, QName
,
941 SysStringLen(QName
), (const WCHAR
**)value
, &len
);
944 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl
=
946 ivbsaxattributes_QueryInterface
,
947 ivbsaxattributes_AddRef
,
948 ivbsaxattributes_Release
,
949 ivbsaxattributes_GetTypeInfoCount
,
950 ivbsaxattributes_GetTypeInfo
,
951 ivbsaxattributes_GetIDsOfNames
,
952 ivbsaxattributes_Invoke
,
953 ivbsaxattributes_get_length
,
954 ivbsaxattributes_getURI
,
955 ivbsaxattributes_getLocalName
,
956 ivbsaxattributes_getQName
,
957 ivbsaxattributes_getIndexFromName
,
958 ivbsaxattributes_getIndexFromQName
,
959 ivbsaxattributes_getType
,
960 ivbsaxattributes_getTypeFromName
,
961 ivbsaxattributes_getTypeFromQName
,
962 ivbsaxattributes_getValue
,
963 ivbsaxattributes_getValueFromName
,
964 ivbsaxattributes_getValueFromQName
967 /*** ISAXAttributes interface ***/
968 /*** IUnknown methods ***/
969 static HRESULT WINAPI
isaxattributes_QueryInterface(
970 ISAXAttributes
* iface
,
974 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
975 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
976 return ISAXLocator_QueryInterface(&This
->ISAXLocator_iface
, riid
, ppvObject
);
979 static ULONG WINAPI
isaxattributes_AddRef(ISAXAttributes
* iface
)
981 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
983 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
986 static ULONG WINAPI
isaxattributes_Release(ISAXAttributes
* iface
)
988 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
991 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
994 /*** ISAXAttributes methods ***/
995 static HRESULT WINAPI
isaxattributes_getLength(
996 ISAXAttributes
* iface
,
999 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1001 *length
= This
->nb_attributes
;
1002 TRACE("Length set to %d\n", *length
);
1006 static HRESULT WINAPI
isaxattributes_getURI(
1007 ISAXAttributes
* iface
,
1012 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1013 TRACE("(%p)->(%d)\n", This
, index
);
1015 if(index
>= This
->nb_attributes
|| index
< 0) return E_INVALIDARG
;
1016 if(!url
|| !size
) return E_POINTER
;
1018 *size
= SysStringLen(This
->attributes
[index
].szURI
);
1019 *url
= This
->attributes
[index
].szURI
;
1021 TRACE("(%s:%d)\n", debugstr_w(This
->attributes
[index
].szURI
), *size
);
1026 static HRESULT WINAPI
isaxattributes_getLocalName(
1027 ISAXAttributes
* iface
,
1029 const WCHAR
**pLocalName
,
1030 int *pLocalNameLength
)
1032 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1033 TRACE("(%p)->(%d)\n", This
, nIndex
);
1035 if(nIndex
>=This
->nb_attributes
|| nIndex
<0) return E_INVALIDARG
;
1036 if(!pLocalName
|| !pLocalNameLength
) return E_POINTER
;
1038 *pLocalNameLength
= SysStringLen(This
->attributes
[nIndex
].szLocalname
);
1039 *pLocalName
= This
->attributes
[nIndex
].szLocalname
;
1044 static HRESULT WINAPI
isaxattributes_getQName(
1045 ISAXAttributes
* iface
,
1047 const WCHAR
**pQName
,
1050 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1051 TRACE("(%p)->(%d)\n", This
, nIndex
);
1053 if(nIndex
>=This
->nb_attributes
|| nIndex
<0) return E_INVALIDARG
;
1054 if(!pQName
|| !pQNameLength
) return E_POINTER
;
1056 *pQNameLength
= SysStringLen(This
->attributes
[nIndex
].szQName
);
1057 *pQName
= This
->attributes
[nIndex
].szQName
;
1062 static HRESULT WINAPI
isaxattributes_getName(
1063 ISAXAttributes
* iface
,
1067 const WCHAR
**localName
,
1068 int *pLocalNameSize
,
1069 const WCHAR
**QName
,
1072 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1073 TRACE("(%p)->(%d)\n", This
, index
);
1075 if(index
>=This
->nb_attributes
|| index
<0) return E_INVALIDARG
;
1076 if(!uri
|| !pUriLength
|| !localName
|| !pLocalNameSize
1077 || !QName
|| !pQNameLength
) return E_POINTER
;
1079 *pUriLength
= SysStringLen(This
->attributes
[index
].szURI
);
1080 *uri
= This
->attributes
[index
].szURI
;
1081 *pLocalNameSize
= SysStringLen(This
->attributes
[index
].szLocalname
);
1082 *localName
= This
->attributes
[index
].szLocalname
;
1083 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1084 *QName
= This
->attributes
[index
].szQName
;
1086 TRACE("(%s, %s, %s)\n", debugstr_w(*uri
), debugstr_w(*localName
), debugstr_w(*QName
));
1091 static HRESULT WINAPI
isaxattributes_getIndexFromName(
1092 ISAXAttributes
* iface
,
1095 const WCHAR
*pLocalName
,
1096 int cocalNameLength
,
1099 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1101 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), cUriLength
,
1102 debugstr_w(pLocalName
), cocalNameLength
);
1104 if(!pUri
|| !pLocalName
|| !index
) return E_POINTER
;
1106 for(i
=0; i
<This
->nb_attributes
; i
++)
1108 if(cUriLength
!=SysStringLen(This
->attributes
[i
].szURI
)
1109 || cocalNameLength
!=SysStringLen(This
->attributes
[i
].szLocalname
))
1111 if(cUriLength
&& memcmp(pUri
, This
->attributes
[i
].szURI
,
1112 sizeof(WCHAR
)*cUriLength
))
1114 if(cocalNameLength
&& memcmp(pLocalName
, This
->attributes
[i
].szLocalname
,
1115 sizeof(WCHAR
)*cocalNameLength
))
1122 return E_INVALIDARG
;
1125 static HRESULT WINAPI
isaxattributes_getIndexFromQName(
1126 ISAXAttributes
* iface
,
1127 const WCHAR
*pQName
,
1131 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1133 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQNameLength
);
1135 if(!pQName
|| !index
) return E_POINTER
;
1136 if(!nQNameLength
) return E_INVALIDARG
;
1138 for(i
=0; i
<This
->nb_attributes
; i
++)
1140 if(nQNameLength
!=SysStringLen(This
->attributes
[i
].szQName
)) continue;
1141 if(memcmp(pQName
, This
->attributes
[i
].szQName
, sizeof(WCHAR
)*nQNameLength
)) continue;
1147 return E_INVALIDARG
;
1150 static HRESULT WINAPI
isaxattributes_getType(
1151 ISAXAttributes
* iface
,
1153 const WCHAR
**pType
,
1156 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1158 FIXME("(%p)->(%d) stub\n", This
, nIndex
);
1162 static HRESULT WINAPI
isaxattributes_getTypeFromName(
1163 ISAXAttributes
* iface
,
1166 const WCHAR
*pLocalName
,
1168 const WCHAR
**pType
,
1171 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1173 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This
, debugstr_w(pUri
), nUri
,
1174 debugstr_w(pLocalName
), nLocalName
);
1178 static HRESULT WINAPI
isaxattributes_getTypeFromQName(
1179 ISAXAttributes
* iface
,
1180 const WCHAR
*pQName
,
1182 const WCHAR
**pType
,
1185 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1187 FIXME("(%p)->(%s, %d) stub\n", This
, debugstr_w(pQName
), nQName
);
1191 static HRESULT WINAPI
isaxattributes_getValue(
1192 ISAXAttributes
* iface
,
1194 const WCHAR
**value
,
1197 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1198 TRACE("(%p)->(%d)\n", This
, index
);
1200 if(index
>=This
->nb_attributes
|| index
<0) return E_INVALIDARG
;
1201 if(!value
|| !nValue
) return E_POINTER
;
1203 *nValue
= SysStringLen(This
->attributes
[index
].szValue
);
1204 *value
= This
->attributes
[index
].szValue
;
1206 TRACE("(%s:%d)\n", debugstr_w(*value
), *nValue
);
1211 static HRESULT WINAPI
isaxattributes_getValueFromName(
1212 ISAXAttributes
* iface
,
1215 const WCHAR
*pLocalName
,
1217 const WCHAR
**pValue
,
1222 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1223 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), nUri
,
1224 debugstr_w(pLocalName
), nLocalName
);
1226 hr
= ISAXAttributes_getIndexFromName(iface
,
1227 pUri
, nUri
, pLocalName
, nLocalName
, &index
);
1228 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1233 static HRESULT WINAPI
isaxattributes_getValueFromQName(
1234 ISAXAttributes
* iface
,
1235 const WCHAR
*pQName
,
1237 const WCHAR
**pValue
,
1242 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1243 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQName
);
1245 hr
= ISAXAttributes_getIndexFromQName(iface
, pQName
, nQName
, &index
);
1246 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1251 static const struct ISAXAttributesVtbl isaxattributes_vtbl
=
1253 isaxattributes_QueryInterface
,
1254 isaxattributes_AddRef
,
1255 isaxattributes_Release
,
1256 isaxattributes_getLength
,
1257 isaxattributes_getURI
,
1258 isaxattributes_getLocalName
,
1259 isaxattributes_getQName
,
1260 isaxattributes_getName
,
1261 isaxattributes_getIndexFromName
,
1262 isaxattributes_getIndexFromQName
,
1263 isaxattributes_getType
,
1264 isaxattributes_getTypeFromName
,
1265 isaxattributes_getTypeFromQName
,
1266 isaxattributes_getValue
,
1267 isaxattributes_getValueFromName
,
1268 isaxattributes_getValueFromQName
1271 /* Libxml2 escapes '&' back to char reference '&' in attribute value,
1272 so when document has escaped value with '&' it's parsed to '&' and then
1273 escaped to '&'. This function takes care of ampersands only. */
1274 static BSTR
saxreader_get_unescaped_value(const xmlChar
*buf
, int len
)
1276 static const WCHAR ampescW
[] = {'&','#','3','8',';',0};
1277 WCHAR
*dest
, *ptrW
, *str
;
1284 str_len
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
1285 if (len
!= -1) str_len
++;
1287 str
= heap_alloc(str_len
*sizeof(WCHAR
));
1288 if (!str
) return NULL
;
1290 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, str
, str_len
);
1291 if (len
!= -1) str
[str_len
-1] = 0;
1294 while ((dest
= strstrW(ptrW
, ampescW
)))
1298 /* leave first '&' from a reference as a value */
1299 src
= dest
+ (sizeof(ampescW
)/sizeof(WCHAR
) - 1);
1302 /* move together with null terminator */
1303 memmove(dest
, src
, (strlenW(src
) + 1)*sizeof(WCHAR
));
1308 bstr
= SysAllocString(str
);
1314 static HRESULT
SAXAttributes_populate(saxlocator
*locator
,
1315 int nb_namespaces
, const xmlChar
**xmlNamespaces
,
1316 int nb_attributes
, const xmlChar
**xmlAttributes
)
1318 static const xmlChar xmlns
[] = "xmlns";
1319 static const WCHAR xmlnsW
[] = { 'x','m','l','n','s',0 };
1321 struct _attributes
*attrs
;
1324 /* skip namespace definitions */
1325 if ((locator
->saxreader
->features
& NamespacePrefixes
) == 0)
1328 locator
->nb_attributes
= nb_namespaces
+ nb_attributes
;
1329 if(locator
->nb_attributes
> locator
->attributesSize
)
1331 attrs
= heap_realloc(locator
->attributes
, sizeof(struct _attributes
)*locator
->nb_attributes
*2);
1334 locator
->nb_attributes
= 0;
1335 return E_OUTOFMEMORY
;
1337 locator
->attributes
= attrs
;
1341 attrs
= locator
->attributes
;
1344 for (i
= 0; i
< nb_namespaces
; i
++)
1346 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1347 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1348 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1349 if(!xmlNamespaces
[2*i
])
1350 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1352 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1355 for (i
= 0; i
< nb_attributes
; i
++)
1357 static const xmlChar xmlA
[] = "xml";
1359 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1360 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1362 /* that's an important feature to keep same uri pointer for every reported attribute */
1363 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1365 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1366 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1367 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1],
1368 xmlAttributes
[i
*5]);
1374 /*** LibXML callbacks ***/
1375 static void libxmlStartDocument(void *ctx
)
1377 saxlocator
*This
= ctx
;
1378 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1381 if (This
->saxreader
->version
>= MSXML4
)
1383 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1384 update_position(This
, FALSE
);
1385 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1387 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1392 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1396 /* store version value, declaration has to contain version attribute */
1397 if (This
->pParserCtxt
->standalone
!= -1)
1399 SysFreeString(This
->saxreader
->xmldecl_version
);
1400 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1403 if (saxreader_has_handler(This
, SAXContentHandler
))
1405 if(This
->vbInterface
)
1406 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1408 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1410 if (sax_callback_failed(This
, hr
))
1411 format_error_message_from_id(This
, hr
);
1415 static void libxmlEndDocument(void *ctx
)
1417 saxlocator
*This
= ctx
;
1418 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1421 if (This
->saxreader
->version
>= MSXML4
) {
1422 update_position(This
, FALSE
);
1423 if(This
->column
> 1)
1431 if(This
->ret
!= S_OK
) return;
1433 if (saxreader_has_handler(This
, SAXContentHandler
))
1435 if(This
->vbInterface
)
1436 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1438 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1440 if (sax_callback_failed(This
, hr
))
1441 format_error_message_from_id(This
, hr
);
1445 static void libxmlStartElementNS(
1447 const xmlChar
*localname
,
1448 const xmlChar
*prefix
,
1451 const xmlChar
**namespaces
,
1454 const xmlChar
**attributes
)
1456 saxlocator
*This
= ctx
;
1457 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1458 element_entry
*element
;
1462 update_position(This
, TRUE
);
1463 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1465 if(This
->saxreader
->version
< MSXML4
)
1468 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1469 push_element_ns(This
, element
);
1471 if (is_namespaces_enabled(This
->saxreader
))
1475 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1477 if (This
->vbInterface
)
1478 hr
= IVBSAXContentHandler_startPrefixMapping(
1480 &element
->ns
[i
].prefix
,
1481 &element
->ns
[i
].uri
);
1483 hr
= ISAXContentHandler_startPrefixMapping(
1485 element
->ns
[i
].prefix
,
1486 SysStringLen(element
->ns
[i
].prefix
),
1488 SysStringLen(element
->ns
[i
].uri
));
1490 if (sax_callback_failed(This
, hr
))
1492 format_error_message_from_id(This
, hr
);
1498 uri
= find_element_uri(This
, URI
);
1499 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1500 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1504 if (is_namespaces_enabled(This
->saxreader
))
1505 local
= element
->local
;
1509 if (This
->vbInterface
)
1510 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1511 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1513 hr
= ISAXContentHandler_startElement(handler
->handler
,
1514 uri
, SysStringLen(uri
),
1515 local
, SysStringLen(local
),
1516 element
->qname
, SysStringLen(element
->qname
),
1517 &This
->ISAXAttributes_iface
);
1519 if (sax_callback_failed(This
, hr
))
1520 format_error_message_from_id(This
, hr
);
1524 static void libxmlEndElementNS(
1526 const xmlChar
*localname
,
1527 const xmlChar
*prefix
,
1530 saxlocator
*This
= ctx
;
1531 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1532 element_entry
*element
;
1537 update_position(This
, FALSE
);
1538 p
= This
->pParserCtxt
->input
->cur
;
1540 if (This
->saxreader
->version
>= MSXML4
)
1543 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1545 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1550 else if(*(p
-1)!='>' || *(p
-2)!='/')
1553 while(p
-2>=This
->pParserCtxt
->input
->base
1554 && *(p
-2)!='<' && *(p
-1)!='/')
1556 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1562 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1565 uri
= find_element_uri(This
, URI
);
1566 element
= pop_element_ns(This
);
1568 if (!saxreader_has_handler(This
, SAXContentHandler
))
1570 This
->nb_attributes
= 0;
1571 free_element_entry(element
);
1575 if (is_namespaces_enabled(This
->saxreader
))
1576 local
= element
->local
;
1580 if (This
->vbInterface
)
1581 hr
= IVBSAXContentHandler_endElement(
1583 &uri
, &local
, &element
->qname
);
1585 hr
= ISAXContentHandler_endElement(
1587 uri
, SysStringLen(uri
),
1588 local
, SysStringLen(local
),
1589 element
->qname
, SysStringLen(element
->qname
));
1591 This
->nb_attributes
= 0;
1593 if (sax_callback_failed(This
, hr
))
1595 format_error_message_from_id(This
, hr
);
1596 free_element_entry(element
);
1600 if (is_namespaces_enabled(This
->saxreader
))
1603 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1605 if (This
->vbInterface
)
1606 hr
= IVBSAXContentHandler_endPrefixMapping(
1607 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1609 hr
= ISAXContentHandler_endPrefixMapping(
1610 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1612 if (sax_callback_failed(This
, hr
)) break;
1615 if (sax_callback_failed(This
, hr
))
1616 format_error_message_from_id(This
, hr
);
1619 free_element_entry(element
);
1622 static void libxmlCharacters(
1627 saxlocator
*This
= ctx
;
1631 BOOL lastEvent
= FALSE
;
1633 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1635 update_position(This
, FALSE
);
1636 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1637 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1639 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1644 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1648 if(*(ch
-1)=='\r') cur
--;
1653 while(end
-ch
<len
&& *end
!='\r') end
++;
1664 if (This
->saxreader
->version
>= MSXML4
)
1668 for(p
=cur
; p
!=end
; p
++)
1685 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1686 hr
= saxreader_saxcharacters(This
, Chars
);
1688 if (sax_callback_failed(This
, hr
))
1690 format_error_message_from_id(This
, hr
);
1694 if (This
->saxreader
->version
< MSXML4
)
1695 This
->column
+= end
-cur
;
1708 if(end
-ch
== len
) break;
1712 static void libxmlSetDocumentLocator(
1714 xmlSAXLocatorPtr loc
)
1716 saxlocator
*This
= ctx
;
1717 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1720 if (saxreader_has_handler(This
, SAXContentHandler
))
1722 if(This
->vbInterface
)
1723 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1724 &This
->IVBSAXLocator_iface
);
1726 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1730 format_error_message_from_id(This
, hr
);
1733 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1735 saxlocator
*This
= ctx
;
1736 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1739 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1741 update_position(This
, FALSE
);
1742 while(p
-4>=This
->pParserCtxt
->input
->base
1743 && memcmp(p
-4, "<!--", sizeof(char[4])))
1745 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1751 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1754 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1756 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1758 if (This
->vbInterface
)
1759 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1761 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1764 format_error_message_from_id(This
, hr
);
1767 static void libxmlFatalError(void *ctx
, const char *msg
, ...)
1769 saxlocator
*This
= ctx
;
1770 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1776 if(This
->ret
!= S_OK
) {
1777 xmlStopParser(This
->pParserCtxt
);
1781 va_start(args
, msg
);
1782 vsprintf(message
, msg
, args
);
1785 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1786 error
= heap_alloc(sizeof(WCHAR
)*len
);
1789 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1790 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1793 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1795 xmlStopParser(This
->pParserCtxt
);
1801 FIXME("Error handling is not compatible.\n");
1803 if(This
->vbInterface
)
1805 BSTR bstrError
= SysAllocString(error
);
1806 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1807 &bstrError
, E_FAIL
);
1808 SysFreeString(bstrError
);
1811 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1815 xmlStopParser(This
->pParserCtxt
);
1819 /* The only reason this helper exists is that CDATA section are reported by chunks,
1820 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1822 This helper should be called for substring with trailing newlines.
1824 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1826 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1829 ptr
= bstr
+ len
- 1;
1830 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1835 /* replace returns as:
1837 - "\r<char>" -> "\n<char>"
1843 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
1846 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
1853 ret
= SysAllocStringLen(bstr
, len
);
1854 SysFreeString(bstr
);
1858 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
1860 const xmlChar
*start
, *end
;
1861 saxlocator
*locator
= ctx
;
1862 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
1867 update_position(locator
, FALSE
);
1868 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
1870 if (locator
->vbInterface
)
1871 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
1873 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
1878 format_error_message_from_id(locator
, hr
);
1888 /* scan for newlines */
1889 if (value
[i
] == '\r' || value
[i
] == '\n')
1891 /* skip newlines/linefeeds */
1894 if (value
[i
] != '\r' && value
[i
] != '\n') break;
1900 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
1901 TRACE("(chunk %s)\n", debugstr_w(chars
));
1902 hr
= saxreader_saxcharacters(locator
, chars
);
1903 SysFreeString(chars
);
1912 /* no newline chars (or last chunk) report as a whole */
1913 if (!end
&& start
== value
)
1916 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
1917 TRACE("(%s)\n", debugstr_w(chars
));
1918 hr
= saxreader_saxcharacters(locator
, chars
);
1919 SysFreeString(chars
);
1922 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
1924 if (locator
->vbInterface
)
1925 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
1927 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
1931 format_error_message_from_id(locator
, hr
);
1934 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
1936 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
1937 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
1940 /*** IVBSAXLocator interface ***/
1941 /*** IUnknown methods ***/
1942 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
1944 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
1946 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
1950 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
1951 IsEqualGUID( riid
, &IID_IDispatch
) ||
1952 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
1956 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
1958 *ppvObject
= &This
->IVBSAXAttributes_iface
;
1962 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
1963 return E_NOINTERFACE
;
1966 IVBSAXLocator_AddRef( iface
);
1971 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
1973 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
1974 TRACE("%p\n", This
);
1975 return InterlockedIncrement( &This
->ref
);
1978 static ULONG WINAPI
ivbsaxlocator_Release(
1979 IVBSAXLocator
* iface
)
1981 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
1982 return ISAXLocator_Release((ISAXLocator
*)&This
->IVBSAXLocator_iface
);
1985 /*** IDispatch methods ***/
1986 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
1988 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
1990 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1997 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
1998 IVBSAXLocator
*iface
,
1999 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2001 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2004 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2006 hr
= get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2011 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2012 IVBSAXLocator
*iface
,
2014 LPOLESTR
* rgszNames
,
2019 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2020 ITypeInfo
*typeinfo
;
2023 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
2026 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2027 return E_INVALIDARG
;
2029 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2032 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2033 ITypeInfo_Release(typeinfo
);
2039 static HRESULT WINAPI
ivbsaxlocator_Invoke(
2040 IVBSAXLocator
*iface
,
2041 DISPID dispIdMember
,
2045 DISPPARAMS
* pDispParams
,
2046 VARIANT
* pVarResult
,
2047 EXCEPINFO
* pExcepInfo
,
2050 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2051 ITypeInfo
*typeinfo
;
2054 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2055 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2057 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2060 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXLocator_iface
, dispIdMember
, wFlags
,
2061 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2062 ITypeInfo_Release(typeinfo
);
2068 /*** IVBSAXLocator methods ***/
2069 static HRESULT WINAPI
ivbsaxlocator_get_columnNumber(
2070 IVBSAXLocator
* iface
,
2073 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2074 return ISAXLocator_getColumnNumber((ISAXLocator
*)&This
->IVBSAXLocator_iface
, pnColumn
);
2077 static HRESULT WINAPI
ivbsaxlocator_get_lineNumber(
2078 IVBSAXLocator
* iface
,
2081 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2082 return ISAXLocator_getLineNumber((ISAXLocator
*)&This
->IVBSAXLocator_iface
, pnLine
);
2085 static HRESULT WINAPI
ivbsaxlocator_get_publicId(
2086 IVBSAXLocator
* iface
,
2089 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2090 return ISAXLocator_getPublicId((ISAXLocator
*)&This
->IVBSAXLocator_iface
,
2091 (const WCHAR
**)publicId
);
2094 static HRESULT WINAPI
ivbsaxlocator_get_systemId(
2095 IVBSAXLocator
* iface
,
2098 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2099 return ISAXLocator_getSystemId((ISAXLocator
*)&This
->IVBSAXLocator_iface
,
2100 (const WCHAR
**)systemId
);
2103 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl
=
2105 ivbsaxlocator_QueryInterface
,
2106 ivbsaxlocator_AddRef
,
2107 ivbsaxlocator_Release
,
2108 ivbsaxlocator_GetTypeInfoCount
,
2109 ivbsaxlocator_GetTypeInfo
,
2110 ivbsaxlocator_GetIDsOfNames
,
2111 ivbsaxlocator_Invoke
,
2112 ivbsaxlocator_get_columnNumber
,
2113 ivbsaxlocator_get_lineNumber
,
2114 ivbsaxlocator_get_publicId
,
2115 ivbsaxlocator_get_systemId
2118 /*** ISAXLocator interface ***/
2119 /*** IUnknown methods ***/
2120 static HRESULT WINAPI
isaxlocator_QueryInterface(ISAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2122 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2124 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2128 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2129 IsEqualGUID( riid
, &IID_ISAXLocator
))
2133 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
2135 *ppvObject
= &This
->ISAXAttributes_iface
;
2139 WARN("interface %s not implemented\n", debugstr_guid(riid
));
2140 return E_NOINTERFACE
;
2143 ISAXLocator_AddRef( iface
);
2148 static ULONG WINAPI
isaxlocator_AddRef(ISAXLocator
* iface
)
2150 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2151 ULONG ref
= InterlockedIncrement( &This
->ref
);
2152 TRACE("(%p)->(%d)\n", This
, ref
);
2156 static ULONG WINAPI
isaxlocator_Release(
2159 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2160 LONG ref
= InterlockedDecrement( &This
->ref
);
2162 TRACE("(%p)->(%d)\n", This
, ref
);
2166 element_entry
*element
, *element2
;
2169 SysFreeString(This
->publicId
);
2170 SysFreeString(This
->systemId
);
2171 SysFreeString(This
->namespaceUri
);
2173 for(index
=0; index
<This
->nb_attributes
; index
++)
2175 SysFreeString(This
->attributes
[index
].szLocalname
);
2176 SysFreeString(This
->attributes
[index
].szValue
);
2177 SysFreeString(This
->attributes
[index
].szQName
);
2179 heap_free(This
->attributes
);
2182 LIST_FOR_EACH_ENTRY_SAFE(element
, element2
, &This
->elements
, element_entry
, entry
)
2184 list_remove(&element
->entry
);
2185 free_element_entry(element
);
2188 ISAXXMLReader_Release(&This
->saxreader
->ISAXXMLReader_iface
);
2195 /*** ISAXLocator methods ***/
2196 static HRESULT WINAPI
isaxlocator_getColumnNumber(
2200 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2202 *pnColumn
= This
->column
;
2206 static HRESULT WINAPI
isaxlocator_getLineNumber(
2210 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2212 *pnLine
= This
->line
;
2216 static HRESULT WINAPI
isaxlocator_getPublicId(
2218 const WCHAR
** ppwchPublicId
)
2221 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2223 SysFreeString(This
->publicId
);
2225 publicId
= bstr_from_xmlChar(xmlSAX2GetPublicId(This
->pParserCtxt
));
2226 if(SysStringLen(publicId
))
2227 This
->publicId
= publicId
;
2230 SysFreeString(publicId
);
2231 This
->publicId
= NULL
;
2234 *ppwchPublicId
= This
->publicId
;
2238 static HRESULT WINAPI
isaxlocator_getSystemId(
2240 const WCHAR
** ppwchSystemId
)
2243 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2245 SysFreeString(This
->systemId
);
2247 systemId
= bstr_from_xmlChar(xmlSAX2GetSystemId(This
->pParserCtxt
));
2248 if(SysStringLen(systemId
))
2249 This
->systemId
= systemId
;
2252 SysFreeString(systemId
);
2253 This
->systemId
= NULL
;
2256 *ppwchSystemId
= This
->systemId
;
2260 static const struct ISAXLocatorVtbl SAXLocatorVtbl
=
2262 isaxlocator_QueryInterface
,
2264 isaxlocator_Release
,
2265 isaxlocator_getColumnNumber
,
2266 isaxlocator_getLineNumber
,
2267 isaxlocator_getPublicId
,
2268 isaxlocator_getSystemId
2271 static HRESULT
SAXLocator_create(saxreader
*reader
, saxlocator
**ppsaxlocator
, BOOL vbInterface
)
2273 static const WCHAR w3xmlns
[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2274 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2276 saxlocator
*locator
;
2278 locator
= heap_alloc( sizeof (*locator
) );
2280 return E_OUTOFMEMORY
;
2282 locator
->IVBSAXLocator_iface
.lpVtbl
= &VBSAXLocatorVtbl
;
2283 locator
->ISAXLocator_iface
.lpVtbl
= &SAXLocatorVtbl
;
2284 locator
->IVBSAXAttributes_iface
.lpVtbl
= &ivbsaxattributes_vtbl
;
2285 locator
->ISAXAttributes_iface
.lpVtbl
= &isaxattributes_vtbl
;
2287 locator
->vbInterface
= vbInterface
;
2289 locator
->saxreader
= reader
;
2290 ISAXXMLReader_AddRef(&reader
->ISAXXMLReader_iface
);
2292 locator
->pParserCtxt
= NULL
;
2293 locator
->publicId
= NULL
;
2294 locator
->systemId
= NULL
;
2295 locator
->line
= reader
->version
< MSXML4
? 0 : 1;
2296 locator
->column
= 0;
2297 locator
->ret
= S_OK
;
2298 if (locator
->saxreader
->version
>= MSXML6
)
2299 locator
->namespaceUri
= SysAllocString(w3xmlns
);
2301 locator
->namespaceUri
= SysAllocStringLen(NULL
, 0);
2302 if(!locator
->namespaceUri
)
2304 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2306 return E_OUTOFMEMORY
;
2309 locator
->attributesSize
= 8;
2310 locator
->nb_attributes
= 0;
2311 locator
->attributes
= heap_alloc(sizeof(struct _attributes
)*locator
->attributesSize
);
2312 if(!locator
->attributes
)
2314 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2315 SysFreeString(locator
->namespaceUri
);
2317 return E_OUTOFMEMORY
;
2320 list_init(&locator
->elements
);
2322 *ppsaxlocator
= locator
;
2324 TRACE("returning %p\n", *ppsaxlocator
);
2329 /*** SAXXMLReader internal functions ***/
2330 static HRESULT
internal_parseBuffer(saxreader
*This
, const char *buffer
, int size
, BOOL vbInterface
)
2332 xmlCharEncoding encoding
= XML_CHAR_ENCODING_NONE
;
2333 xmlChar
*enc_name
= NULL
;
2334 saxlocator
*locator
;
2337 TRACE("(%p)->(%p %d)\n", This
, buffer
, size
);
2339 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2345 const unsigned char *buff
= (unsigned char*)buffer
;
2347 encoding
= xmlDetectCharEncoding((xmlChar
*)buffer
, 4);
2348 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2349 TRACE("detected encoding: %s\n", enc_name
);
2350 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2351 if ((encoding
== XML_CHAR_ENCODING_UTF8
) &&
2352 buff
[0] == 0xEF && buff
[1] == 0xBB && buff
[2] == 0xBF)
2359 /* if libxml2 detection failed try to guess */
2360 if (encoding
== XML_CHAR_ENCODING_NONE
)
2362 const WCHAR
*ptr
= (WCHAR
*)buffer
;
2363 /* xml declaration with possibly specfied encoding will be still handled by parser */
2364 if ((size
>= 2) && *ptr
== '<' && ptr
[1] != '?')
2366 enc_name
= (xmlChar
*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE
);
2367 encoding
= XML_CHAR_ENCODING_UTF16LE
;
2370 else if (encoding
== XML_CHAR_ENCODING_UTF8
)
2371 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2375 locator
->pParserCtxt
= xmlCreateMemoryParserCtxt(buffer
, size
);
2376 if (!locator
->pParserCtxt
)
2378 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2384 locator
->pParserCtxt
->encoding
= xmlStrdup(enc_name
);
2385 if (encoding
== XML_CHAR_ENCODING_UTF16LE
) {
2386 TRACE("switching to %s\n", enc_name
);
2387 xmlSwitchEncoding(locator
->pParserCtxt
, encoding
);
2391 xmlFree(locator
->pParserCtxt
->sax
);
2392 locator
->pParserCtxt
->sax
= &locator
->saxreader
->sax
;
2393 locator
->pParserCtxt
->userData
= locator
;
2395 This
->isParsing
= TRUE
;
2396 if(xmlParseDocument(locator
->pParserCtxt
) == -1 && locator
->ret
== S_OK
)
2400 This
->isParsing
= FALSE
;
2402 if(locator
->pParserCtxt
)
2404 locator
->pParserCtxt
->sax
= NULL
;
2405 xmlFreeParserCtxt(locator
->pParserCtxt
);
2406 locator
->pParserCtxt
= NULL
;
2409 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2413 static HRESULT
internal_parseStream(saxreader
*This
, ISequentialStream
*stream
, BOOL vbInterface
)
2415 saxlocator
*locator
;
2422 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2423 if(FAILED(hr
)) return hr
;
2425 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2426 if(FAILED(hr
)) return hr
;
2428 locator
->pParserCtxt
= xmlCreatePushParserCtxt(
2429 &locator
->saxreader
->sax
, locator
,
2430 data
, dataRead
, NULL
);
2431 if(!locator
->pParserCtxt
)
2433 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2437 This
->isParsing
= TRUE
;
2439 if(dataRead
!= sizeof(data
))
2441 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2442 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2449 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2450 if (FAILED(hr
)) break;
2452 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, dataRead
, 0);
2453 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2455 if (hr
!= S_OK
) break;
2457 if (dataRead
!= sizeof(data
))
2459 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2460 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2466 This
->isParsing
= FALSE
;
2468 xmlFreeParserCtxt(locator
->pParserCtxt
);
2469 locator
->pParserCtxt
= NULL
;
2470 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2474 static HRESULT
internal_parse(
2481 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varInput
));
2483 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2484 free_bstr_pool(&This
->pool
);
2486 switch(V_VT(&varInput
))
2489 hr
= internal_parseBuffer(This
, (const char*)V_BSTR(&varInput
),
2490 strlenW(V_BSTR(&varInput
))*sizeof(WCHAR
), vbInterface
);
2492 case VT_ARRAY
|VT_UI1
: {
2494 LONG lBound
, uBound
;
2497 hr
= SafeArrayGetLBound(V_ARRAY(&varInput
), 1, &lBound
);
2498 if(hr
!= S_OK
) break;
2499 hr
= SafeArrayGetUBound(V_ARRAY(&varInput
), 1, &uBound
);
2500 if(hr
!= S_OK
) break;
2501 dataRead
= (uBound
-lBound
)*SafeArrayGetElemsize(V_ARRAY(&varInput
));
2502 hr
= SafeArrayAccessData(V_ARRAY(&varInput
), &pSAData
);
2503 if(hr
!= S_OK
) break;
2504 hr
= internal_parseBuffer(This
, pSAData
, dataRead
, vbInterface
);
2505 SafeArrayUnaccessData(V_ARRAY(&varInput
));
2510 IPersistStream
*persistStream
;
2511 ISequentialStream
*stream
= NULL
;
2512 IXMLDOMDocument
*xmlDoc
;
2514 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2515 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2519 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2520 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2521 SysStringByteLen(bstrData
), vbInterface
);
2522 IXMLDOMDocument_Release(xmlDoc
);
2523 SysFreeString(bstrData
);
2527 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2528 &IID_IPersistStream
, (void**)&persistStream
) == S_OK
)
2530 IStream
*stream_copy
;
2532 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream_copy
);
2535 IPersistStream_Release(persistStream
);
2539 hr
= IPersistStream_Save(persistStream
, stream_copy
, TRUE
);
2540 IPersistStream_Release(persistStream
);
2542 IStream_QueryInterface(stream_copy
, &IID_ISequentialStream
, (void**)&stream
);
2544 IStream_Release(stream_copy
);
2547 /* try base interface first */
2550 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2552 /* this should never happen if IStream is implemented properly, but just in case */
2553 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2558 hr
= internal_parseStream(This
, stream
, vbInterface
);
2559 ISequentialStream_Release(stream
);
2563 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2570 WARN("vt %d not implemented\n", V_VT(&varInput
));
2577 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2579 saxreader
*This
= obj
;
2581 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2584 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2586 saxreader
*This
= obj
;
2588 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2591 static HRESULT
internal_parseURL(
2600 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
2602 hr
= create_moniker_from_url(url
, &mon
);
2606 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, This
, &bsc
);
2607 else hr
= bind_url(mon
, internal_onDataAvailable
, This
, &bsc
);
2608 IMoniker_Release(mon
);
2613 return detach_bsc(bsc
);
2616 static HRESULT
internal_putProperty(
2622 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2624 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2626 if(This
->isParsing
) return E_FAIL
;
2628 switch (V_VT(&value
))
2631 saxreader_put_handler(This
, SAXDeclHandler
, NULL
, vbInterface
);
2635 IUnknown
*handler
= NULL
;
2637 if (V_UNKNOWN(&value
))
2642 hr
= IUnknown_QueryInterface(V_UNKNOWN(&value
), &IID_IVBSAXDeclHandler
, (void**)&handler
);
2644 hr
= IUnknown_QueryInterface(V_UNKNOWN(&value
), &IID_ISAXDeclHandler
, (void**)&handler
);
2645 if (FAILED(hr
)) return hr
;
2648 saxreader_put_handler(This
, SAXDeclHandler
, handler
, vbInterface
);
2649 if (handler
) IUnknown_Release(handler
);
2653 return E_INVALIDARG
;
2659 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2661 if(This
->isParsing
) return E_FAIL
;
2663 switch (V_VT(&value
))
2666 saxreader_put_handler(This
, SAXLexicalHandler
, NULL
, vbInterface
);
2670 IUnknown
*handler
= NULL
;
2672 if (V_UNKNOWN(&value
))
2677 hr
= IUnknown_QueryInterface(V_UNKNOWN(&value
), &IID_IVBSAXLexicalHandler
, (void**)&handler
);
2679 hr
= IUnknown_QueryInterface(V_UNKNOWN(&value
), &IID_ISAXLexicalHandler
, (void**)&handler
);
2680 if (FAILED(hr
)) return hr
;
2683 saxreader_put_handler(This
, SAXLexicalHandler
, handler
, vbInterface
);
2684 if (handler
) IUnknown_Release(handler
);
2688 return E_INVALIDARG
;
2694 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2696 if (V_VT(&value
) == VT_I4
&& V_I4(&value
) == 0) return S_OK
;
2697 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(&value
));
2701 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2703 if (V_VT(&value
) == VT_I4
&& V_I4(&value
) == 0) return S_OK
;
2704 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(&value
));
2708 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2710 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2713 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2716 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2719 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2722 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2725 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2728 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2731 return E_INVALIDARG
;
2734 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2736 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2738 if (!value
) return E_POINTER
;
2740 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2742 V_VT(value
) = VT_UNKNOWN
;
2743 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2747 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2749 V_VT(value
) = VT_UNKNOWN
;
2750 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2754 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2756 V_VT(value
) = VT_BSTR
;
2757 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2761 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2766 /*** IVBSAXXMLReader interface ***/
2767 /*** IUnknown methods ***/
2768 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2770 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2772 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2776 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2777 IsEqualGUID( riid
, &IID_IDispatch
) ||
2778 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2782 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2784 *ppvObject
= &This
->ISAXXMLReader_iface
;
2786 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2788 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2792 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2793 return E_NOINTERFACE
;
2796 IVBSAXXMLReader_AddRef( iface
);
2801 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2803 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2804 TRACE("%p\n", This
);
2805 return InterlockedIncrement( &This
->ref
);
2808 static ULONG WINAPI
saxxmlreader_Release(
2809 IVBSAXXMLReader
* iface
)
2811 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2814 TRACE("%p\n", This
);
2816 ref
= InterlockedDecrement( &This
->ref
);
2821 for (i
= 0; i
< SAXHandler_Last
; i
++)
2823 struct saxanyhandler_iface
*iface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2826 IUnknown_Release(iface
->handler
);
2828 if (iface
->vbhandler
)
2829 IUnknown_Release(iface
->vbhandler
);
2832 SysFreeString(This
->xmldecl_version
);
2833 free_bstr_pool(&This
->pool
);
2835 release_dispex(&This
->dispex
);
2842 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2844 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2845 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2848 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2849 IVBSAXXMLReader
*iface
,
2850 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2852 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2853 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2854 iTInfo
, lcid
, ppTInfo
);
2857 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2858 IVBSAXXMLReader
*iface
,
2860 LPOLESTR
* rgszNames
,
2865 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2866 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
2867 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
2870 static HRESULT WINAPI
saxxmlreader_Invoke(
2871 IVBSAXXMLReader
*iface
,
2872 DISPID dispIdMember
,
2876 DISPPARAMS
* pDispParams
,
2877 VARIANT
* pVarResult
,
2878 EXCEPINFO
* pExcepInfo
,
2881 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2882 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
2883 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2886 /*** IVBSAXXMLReader methods ***/
2887 static HRESULT WINAPI
saxxmlreader_getFeature(
2888 IVBSAXXMLReader
* iface
,
2889 const WCHAR
*feature_name
,
2890 VARIANT_BOOL
*value
)
2892 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2893 saxreader_feature feature
;
2895 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
2897 feature
= get_saxreader_feature(feature_name
);
2898 if (feature
== Namespaces
|| feature
== NamespacePrefixes
)
2899 return get_feature_value(This
, feature
, value
);
2901 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
2905 static HRESULT WINAPI
saxxmlreader_putFeature(
2906 IVBSAXXMLReader
* iface
,
2907 const WCHAR
*feature_name
,
2910 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2911 saxreader_feature feature
;
2913 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
2915 feature
= get_saxreader_feature(feature_name
);
2917 /* accepted cases */
2918 if ((feature
== ExternalGeneralEntities
&& value
== VARIANT_FALSE
) ||
2919 (feature
== ExternalParameterEntities
&& value
== VARIANT_FALSE
) ||
2920 feature
== Namespaces
||
2921 feature
== NamespacePrefixes
)
2923 return set_feature_value(This
, feature
, value
);
2926 if (feature
== LexicalHandlerParEntities
|| feature
== ProhibitDTD
)
2928 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
2929 return set_feature_value(This
, feature
, value
);
2932 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
2936 static HRESULT WINAPI
saxxmlreader_getProperty(
2937 IVBSAXXMLReader
* iface
,
2941 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2942 return internal_getProperty(This
, prop
, value
, TRUE
);
2945 static HRESULT WINAPI
saxxmlreader_putProperty(
2946 IVBSAXXMLReader
* iface
,
2950 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2951 return internal_putProperty(This
, pProp
, value
, TRUE
);
2954 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
2955 IVBSAXXMLReader
* iface
,
2956 IVBSAXEntityResolver
**resolver
)
2958 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2959 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
2962 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
2963 IVBSAXXMLReader
* iface
,
2964 IVBSAXEntityResolver
*resolver
)
2966 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2967 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
2970 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
2971 IVBSAXXMLReader
* iface
,
2972 IVBSAXContentHandler
**handler
)
2974 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2975 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
2978 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
2979 IVBSAXXMLReader
* iface
,
2980 IVBSAXContentHandler
*handler
)
2982 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2983 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
2986 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
2987 IVBSAXXMLReader
* iface
,
2988 IVBSAXDTDHandler
**handler
)
2990 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2991 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
2994 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
2995 IVBSAXXMLReader
* iface
,
2996 IVBSAXDTDHandler
*handler
)
2998 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2999 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3002 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3003 IVBSAXXMLReader
* iface
,
3004 IVBSAXErrorHandler
**handler
)
3006 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3007 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3010 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3011 IVBSAXXMLReader
* iface
,
3012 IVBSAXErrorHandler
*handler
)
3014 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3015 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3018 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3019 IVBSAXXMLReader
* iface
,
3020 const WCHAR
**pBaseUrl
)
3022 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3024 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3028 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3029 IVBSAXXMLReader
* iface
,
3030 const WCHAR
*pBaseUrl
)
3032 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3034 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3038 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3039 IVBSAXXMLReader
* iface
,
3040 const WCHAR
**pSecureBaseUrl
)
3042 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3044 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3049 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3050 IVBSAXXMLReader
* iface
,
3051 const WCHAR
*secureBaseUrl
)
3053 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3055 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3059 static HRESULT WINAPI
saxxmlreader_parse(
3060 IVBSAXXMLReader
* iface
,
3063 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3064 return internal_parse(This
, varInput
, TRUE
);
3067 static HRESULT WINAPI
saxxmlreader_parseURL(
3068 IVBSAXXMLReader
* iface
,
3071 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3072 return internal_parseURL(This
, url
, TRUE
);
3075 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3077 saxxmlreader_QueryInterface
,
3078 saxxmlreader_AddRef
,
3079 saxxmlreader_Release
,
3080 saxxmlreader_GetTypeInfoCount
,
3081 saxxmlreader_GetTypeInfo
,
3082 saxxmlreader_GetIDsOfNames
,
3083 saxxmlreader_Invoke
,
3084 saxxmlreader_getFeature
,
3085 saxxmlreader_putFeature
,
3086 saxxmlreader_getProperty
,
3087 saxxmlreader_putProperty
,
3088 saxxmlreader_get_entityResolver
,
3089 saxxmlreader_put_entityResolver
,
3090 saxxmlreader_get_contentHandler
,
3091 saxxmlreader_put_contentHandler
,
3092 saxxmlreader_get_dtdHandler
,
3093 saxxmlreader_put_dtdHandler
,
3094 saxxmlreader_get_errorHandler
,
3095 saxxmlreader_put_errorHandler
,
3096 saxxmlreader_get_baseURL
,
3097 saxxmlreader_put_baseURL
,
3098 saxxmlreader_get_secureBaseURL
,
3099 saxxmlreader_put_secureBaseURL
,
3101 saxxmlreader_parseURL
3104 /*** ISAXXMLReader interface ***/
3105 /*** IUnknown methods ***/
3106 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3108 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3109 return saxxmlreader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3112 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3114 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3115 return saxxmlreader_AddRef(&This
->IVBSAXXMLReader_iface
);
3118 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3120 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3121 return saxxmlreader_Release(&This
->IVBSAXXMLReader_iface
);
3124 /*** ISAXXMLReader methods ***/
3125 static HRESULT WINAPI
isaxxmlreader_getFeature(
3126 ISAXXMLReader
* iface
,
3127 const WCHAR
*pFeature
,
3128 VARIANT_BOOL
*pValue
)
3130 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3131 return IVBSAXXMLReader_getFeature(&This
->IVBSAXXMLReader_iface
, pFeature
, pValue
);
3134 static HRESULT WINAPI
isaxxmlreader_putFeature(
3135 ISAXXMLReader
* iface
,
3136 const WCHAR
*pFeature
,
3137 VARIANT_BOOL vfValue
)
3139 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3140 return IVBSAXXMLReader_putFeature(&This
->IVBSAXXMLReader_iface
, pFeature
, vfValue
);
3143 static HRESULT WINAPI
isaxxmlreader_getProperty(
3144 ISAXXMLReader
* iface
,
3148 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3149 return internal_getProperty(This
, prop
, value
, FALSE
);
3152 static HRESULT WINAPI
isaxxmlreader_putProperty(
3153 ISAXXMLReader
* iface
,
3157 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3158 return internal_putProperty(This
, pProp
, value
, FALSE
);
3161 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3162 ISAXXMLReader
* iface
,
3163 ISAXEntityResolver
**resolver
)
3165 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3166 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3169 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3170 ISAXXMLReader
* iface
,
3171 ISAXEntityResolver
*resolver
)
3173 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3174 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3177 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3178 ISAXXMLReader
* iface
,
3179 ISAXContentHandler
**handler
)
3181 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3182 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3185 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3186 ISAXXMLReader
* iface
,
3187 ISAXContentHandler
*handler
)
3189 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3190 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3193 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3194 ISAXXMLReader
* iface
,
3195 ISAXDTDHandler
**handler
)
3197 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3198 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3201 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3202 ISAXXMLReader
* iface
,
3203 ISAXDTDHandler
*handler
)
3205 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3206 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3209 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3210 ISAXXMLReader
* iface
,
3211 ISAXErrorHandler
**handler
)
3213 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3214 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3217 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3219 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3220 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3223 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3224 ISAXXMLReader
* iface
,
3225 const WCHAR
**pBaseUrl
)
3227 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3228 return IVBSAXXMLReader_get_baseURL(&This
->IVBSAXXMLReader_iface
, pBaseUrl
);
3231 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3232 ISAXXMLReader
* iface
,
3233 const WCHAR
*pBaseUrl
)
3235 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3236 return IVBSAXXMLReader_put_baseURL(&This
->IVBSAXXMLReader_iface
, pBaseUrl
);
3239 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3240 ISAXXMLReader
* iface
,
3241 const WCHAR
**pSecureBaseUrl
)
3243 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3244 return IVBSAXXMLReader_get_secureBaseURL(&This
->IVBSAXXMLReader_iface
, pSecureBaseUrl
);
3247 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3248 ISAXXMLReader
* iface
,
3249 const WCHAR
*secureBaseUrl
)
3251 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3252 return IVBSAXXMLReader_put_secureBaseURL(&This
->IVBSAXXMLReader_iface
, secureBaseUrl
);
3255 static HRESULT WINAPI
isaxxmlreader_parse(
3256 ISAXXMLReader
* iface
,
3259 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3260 return internal_parse(This
, varInput
, FALSE
);
3263 static HRESULT WINAPI
isaxxmlreader_parseURL(
3264 ISAXXMLReader
* iface
,
3267 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3268 return internal_parseURL(This
, url
, FALSE
);
3271 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3273 isaxxmlreader_QueryInterface
,
3274 isaxxmlreader_AddRef
,
3275 isaxxmlreader_Release
,
3276 isaxxmlreader_getFeature
,
3277 isaxxmlreader_putFeature
,
3278 isaxxmlreader_getProperty
,
3279 isaxxmlreader_putProperty
,
3280 isaxxmlreader_getEntityResolver
,
3281 isaxxmlreader_putEntityResolver
,
3282 isaxxmlreader_getContentHandler
,
3283 isaxxmlreader_putContentHandler
,
3284 isaxxmlreader_getDTDHandler
,
3285 isaxxmlreader_putDTDHandler
,
3286 isaxxmlreader_getErrorHandler
,
3287 isaxxmlreader_putErrorHandler
,
3288 isaxxmlreader_getBaseURL
,
3289 isaxxmlreader_putBaseURL
,
3290 isaxxmlreader_getSecureBaseURL
,
3291 isaxxmlreader_putSecureBaseURL
,
3292 isaxxmlreader_parse
,
3293 isaxxmlreader_parseURL
3296 static const tid_t saxreader_iface_tids
[] = {
3297 IVBSAXXMLReader_tid
,
3300 static dispex_static_data_t saxreader_dispex
= {
3302 IVBSAXXMLReader_tid
,
3304 saxreader_iface_tids
3307 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, IUnknown
*outer
, LPVOID
*ppObj
)
3311 TRACE("(%p, %p)\n", outer
, ppObj
);
3313 reader
= heap_alloc( sizeof (*reader
) );
3315 return E_OUTOFMEMORY
;
3317 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3318 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3320 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3321 reader
->isParsing
= FALSE
;
3322 reader
->xmldecl_version
= NULL
;
3323 reader
->pool
.pool
= NULL
;
3324 reader
->pool
.index
= 0;
3325 reader
->pool
.len
= 0;
3326 reader
->features
= Namespaces
| NamespacePrefixes
;
3327 reader
->version
= version
;
3329 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3331 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3332 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3333 reader
->sax
.startDocument
= libxmlStartDocument
;
3334 reader
->sax
.endDocument
= libxmlEndDocument
;
3335 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3336 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3337 reader
->sax
.characters
= libxmlCharacters
;
3338 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3339 reader
->sax
.comment
= libxmlComment
;
3340 reader
->sax
.error
= libxmlFatalError
;
3341 reader
->sax
.fatalError
= libxmlFatalError
;
3342 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3343 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3345 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3347 TRACE("returning iface %p\n", *ppObj
);
3354 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
3356 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3357 "libxml2 support was not present at compile time.\n");