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 static const WCHAR ExhaustiveErrorsW
[] = {
104 'e','x','h','a','u','s','t','i','v','e','-','e','r','r','o','r','s',0
107 struct saxreader_feature_pair
109 saxreader_feature feature
;
113 static const struct saxreader_feature_pair saxreader_feature_map
[] = {
114 { ExhaustiveErrors
, ExhaustiveErrorsW
},
115 { ExternalGeneralEntities
, FeatureExternalGeneralEntitiesW
},
116 { ExternalParameterEntities
, FeatureExternalParameterEntitiesW
},
117 { LexicalHandlerParEntities
, FeatureLexicalHandlerParEntitiesW
},
118 { NamespacePrefixes
, FeatureNamespacePrefixesW
},
119 { Namespaces
, FeatureNamespacesW
},
120 { ProhibitDTD
, FeatureProhibitDTDW
}
123 static saxreader_feature
get_saxreader_feature(const WCHAR
*name
)
128 max
= sizeof(saxreader_feature_map
)/sizeof(struct saxreader_feature_pair
) - 1;
134 c
= strcmpW(saxreader_feature_map
[n
].name
, name
);
136 return saxreader_feature_map
[n
].feature
;
144 return FeatureUnknown
;
166 ns
*ns
; /* namespaces defined in this particular element */
172 SAXContentHandler
= 0,
181 struct saxanyhandler_iface
187 struct saxcontenthandler_iface
189 ISAXContentHandler
*handler
;
190 IVBSAXContentHandler
*vbhandler
;
193 struct saxerrorhandler_iface
195 ISAXErrorHandler
*handler
;
196 IVBSAXErrorHandler
*vbhandler
;
199 struct saxlexicalhandler_iface
201 ISAXLexicalHandler
*handler
;
202 IVBSAXLexicalHandler
*vbhandler
;
205 struct saxentityresolver_iface
207 ISAXEntityResolver
*handler
;
208 IVBSAXEntityResolver
*vbhandler
;
211 struct saxhandler_iface
214 struct saxcontenthandler_iface content
;
215 struct saxentityresolver_iface entityresolver
;
216 struct saxerrorhandler_iface error
;
217 struct saxlexicalhandler_iface lexical
;
218 struct saxanyhandler_iface anyhandler
;
225 IVBSAXXMLReader IVBSAXXMLReader_iface
;
226 ISAXXMLReader ISAXXMLReader_iface
;
229 struct saxhandler_iface saxhandlers
[SAXHandler_Last
];
232 struct bstrpool pool
;
233 saxreader_feature features
;
234 BSTR xmldecl_version
;
235 MSXML_VERSION version
;
238 static HRESULT
saxreader_put_handler(saxreader
*reader
, enum saxhandler_type type
, void *ptr
, BOOL vb
)
240 struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
241 IUnknown
*unk
= (IUnknown
*)ptr
;
244 IUnknown_AddRef(unk
);
246 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
247 IUnknown_Release(vb
? iface
->vbhandler
: iface
->handler
);
250 iface
->vbhandler
= unk
;
252 iface
->handler
= unk
;
257 static HRESULT
saxreader_get_handler(const saxreader
*reader
, enum saxhandler_type type
, BOOL vb
, void **ret
)
259 const struct saxanyhandler_iface
*iface
= &reader
->saxhandlers
[type
].u
.anyhandler
;
261 if (!ret
) return E_POINTER
;
263 if ((vb
&& iface
->vbhandler
) || (!vb
&& iface
->handler
))
266 IUnknown_AddRef(iface
->vbhandler
);
268 IUnknown_AddRef(iface
->handler
);
271 *ret
= vb
? iface
->vbhandler
: iface
->handler
;
276 static struct saxcontenthandler_iface
*saxreader_get_contenthandler(saxreader
*reader
)
278 return &reader
->saxhandlers
[SAXContentHandler
].u
.content
;
281 static struct saxerrorhandler_iface
*saxreader_get_errorhandler(saxreader
*reader
)
283 return &reader
->saxhandlers
[SAXErrorHandler
].u
.error
;
286 static struct saxlexicalhandler_iface
*saxreader_get_lexicalhandler(saxreader
*reader
)
288 return &reader
->saxhandlers
[SAXLexicalHandler
].u
.lexical
;
293 IVBSAXLocator IVBSAXLocator_iface
;
294 ISAXLocator ISAXLocator_iface
;
295 IVBSAXAttributes IVBSAXAttributes_iface
;
296 ISAXAttributes ISAXAttributes_iface
;
298 saxreader
*saxreader
;
300 xmlParserCtxtPtr pParserCtxt
;
306 struct list elements
;
309 int attr_alloc_count
;
320 static inline saxreader
*impl_from_IVBSAXXMLReader( IVBSAXXMLReader
*iface
)
322 return CONTAINING_RECORD(iface
, saxreader
, IVBSAXXMLReader_iface
);
325 static inline saxreader
*impl_from_ISAXXMLReader( ISAXXMLReader
*iface
)
327 return CONTAINING_RECORD(iface
, saxreader
, ISAXXMLReader_iface
);
330 static inline saxlocator
*impl_from_IVBSAXLocator( IVBSAXLocator
*iface
)
332 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXLocator_iface
);
335 static inline saxlocator
*impl_from_ISAXLocator( ISAXLocator
*iface
)
337 return CONTAINING_RECORD(iface
, saxlocator
, ISAXLocator_iface
);
340 static inline saxlocator
*impl_from_IVBSAXAttributes( IVBSAXAttributes
*iface
)
342 return CONTAINING_RECORD(iface
, saxlocator
, IVBSAXAttributes_iface
);
345 static inline saxlocator
*impl_from_ISAXAttributes( ISAXAttributes
*iface
)
347 return CONTAINING_RECORD(iface
, saxlocator
, ISAXAttributes_iface
);
350 static inline BOOL
saxreader_has_handler(const saxlocator
*locator
, enum saxhandler_type type
)
352 struct saxanyhandler_iface
*iface
= &locator
->saxreader
->saxhandlers
[type
].u
.anyhandler
;
353 return (locator
->vbInterface
&& iface
->vbhandler
) || (!locator
->vbInterface
&& iface
->handler
);
356 static HRESULT
saxreader_saxcharacters(saxlocator
*locator
, BSTR chars
)
358 struct saxcontenthandler_iface
*content
= saxreader_get_contenthandler(locator
->saxreader
);
361 if (!saxreader_has_handler(locator
, SAXContentHandler
)) return S_OK
;
363 if (locator
->vbInterface
)
364 hr
= IVBSAXContentHandler_characters(content
->vbhandler
, &chars
);
366 hr
= ISAXContentHandler_characters(content
->handler
, chars
, SysStringLen(chars
));
372 static const WCHAR PropertyCharsetW
[] = {
373 'c','h','a','r','s','e','t',0
375 static const WCHAR PropertyXmlDeclVersionW
[] = {
376 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
378 static const WCHAR PropertyDeclHandlerW
[] = {
379 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
380 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
381 'd','e','c','l','a','r','a','t','i','o','n',
382 '-','h','a','n','d','l','e','r',0
384 static const WCHAR PropertyDomNodeW
[] = {
385 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
386 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
387 'd','o','m','-','n','o','d','e',0
389 static const WCHAR PropertyInputSourceW
[] = {
390 'i','n','p','u','t','-','s','o','u','r','c','e',0
392 static const WCHAR PropertyLexicalHandlerW
[] = {
393 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
394 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
395 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
397 static const WCHAR PropertyMaxElementDepthW
[] = {
398 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
400 static const WCHAR PropertyMaxXMLSizeW
[] = {
401 'm','a','x','-','x','m','l','-','s','i','z','e',0
403 static const WCHAR PropertySchemaDeclHandlerW
[] = {
404 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
405 'h','a','n','d','l','e','r',0
407 static const WCHAR PropertyXMLDeclEncodingW
[] = {
408 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
410 static const WCHAR PropertyXMLDeclStandaloneW
[] = {
411 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
413 static const WCHAR PropertyXMLDeclVersionW
[] = {
414 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
417 static inline HRESULT
set_feature_value(saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL value
)
419 /* handling of non-VARIANT_* values is version dependent */
420 if ((reader
->version
< MSXML4
) && (value
!= VARIANT_TRUE
))
421 value
= VARIANT_FALSE
;
422 if ((reader
->version
>= MSXML4
) && (value
!= VARIANT_FALSE
))
423 value
= VARIANT_TRUE
;
425 if (value
== VARIANT_TRUE
)
426 reader
->features
|= feature
;
428 reader
->features
&= ~feature
;
433 static inline HRESULT
get_feature_value(const saxreader
*reader
, saxreader_feature feature
, VARIANT_BOOL
*value
)
435 *value
= reader
->features
& feature
? VARIANT_TRUE
: VARIANT_FALSE
;
439 static BOOL
is_namespaces_enabled(const saxreader
*reader
)
441 return (reader
->version
< MSXML4
) || (reader
->features
& Namespaces
);
444 static BSTR
build_qname(BSTR prefix
, BSTR local
)
446 if (prefix
&& *prefix
)
448 BSTR qname
= SysAllocStringLen(NULL
, SysStringLen(prefix
) + SysStringLen(local
) + 1);
452 strcpyW(ptr
, prefix
);
453 ptr
+= SysStringLen(prefix
);
459 return SysAllocString(local
);
462 static element_entry
* alloc_element_entry(const xmlChar
*local
, const xmlChar
*prefix
, int nb_ns
,
463 const xmlChar
**namespaces
)
468 ret
= heap_alloc(sizeof(*ret
));
469 if (!ret
) return ret
;
471 ret
->local
= bstr_from_xmlChar(local
);
472 ret
->prefix
= bstr_from_xmlChar(prefix
);
473 ret
->qname
= build_qname(ret
->prefix
, ret
->local
);
474 ret
->ns
= nb_ns
? heap_alloc(nb_ns
*sizeof(ns
)) : NULL
;
475 ret
->ns_count
= nb_ns
;
477 for (i
=0; i
< nb_ns
; i
++)
479 ret
->ns
[i
].prefix
= bstr_from_xmlChar(namespaces
[2*i
]);
480 ret
->ns
[i
].uri
= bstr_from_xmlChar(namespaces
[2*i
+1]);
486 static void free_element_entry(element_entry
*element
)
490 for (i
=0; i
<element
->ns_count
;i
++)
492 SysFreeString(element
->ns
[i
].prefix
);
493 SysFreeString(element
->ns
[i
].uri
);
496 SysFreeString(element
->prefix
);
497 SysFreeString(element
->local
);
498 SysFreeString(element
->qname
);
500 heap_free(element
->ns
);
504 static void push_element_ns(saxlocator
*locator
, element_entry
*element
)
506 list_add_head(&locator
->elements
, &element
->entry
);
509 static element_entry
* pop_element_ns(saxlocator
*locator
)
511 element_entry
*element
= LIST_ENTRY(list_head(&locator
->elements
), element_entry
, entry
);
514 list_remove(&element
->entry
);
519 static BSTR
find_element_uri(saxlocator
*locator
, const xmlChar
*uri
)
521 element_entry
*element
;
525 if (!uri
) return NULL
;
527 uriW
= bstr_from_xmlChar(uri
);
529 LIST_FOR_EACH_ENTRY(element
, &locator
->elements
, element_entry
, entry
)
531 for (i
=0; i
< element
->ns_count
; i
++)
532 if (!strcmpW(uriW
, element
->ns
[i
].uri
))
535 return element
->ns
[i
].uri
;
540 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri
));
544 /* used to localize version dependent error check behaviour */
545 static inline BOOL
sax_callback_failed(saxlocator
*This
, HRESULT hr
)
547 return This
->saxreader
->version
>= MSXML4
? FAILED(hr
) : hr
!= S_OK
;
550 /* index value -1 means it tries to loop for a first time */
551 static inline BOOL
iterate_endprefix_index(saxlocator
*This
, const element_entry
*element
, int *i
)
553 if (This
->saxreader
->version
>= MSXML4
)
555 if (*i
== -1) *i
= 0; else ++*i
;
556 return *i
< element
->ns_count
;
560 if (*i
== -1) *i
= element
->ns_count
-1; else --*i
;
565 static BOOL
bstr_pool_insert(struct bstrpool
*pool
, BSTR pool_entry
)
569 pool
->pool
= heap_alloc(16 * sizeof(*pool
->pool
));
576 else if (pool
->index
== pool
->len
)
578 BSTR
*realloc
= heap_realloc(pool
->pool
, pool
->len
* 2 * sizeof(*realloc
));
583 pool
->pool
= realloc
;
587 pool
->pool
[pool
->index
++] = pool_entry
;
591 static void free_bstr_pool(struct bstrpool
*pool
)
595 for (i
= 0; i
< pool
->index
; i
++)
596 SysFreeString(pool
->pool
[i
]);
598 heap_free(pool
->pool
);
601 pool
->index
= pool
->len
= 0;
604 static BSTR
bstr_from_xmlCharN(const xmlChar
*buf
, int len
)
612 dLen
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
613 if(len
!= -1) dLen
++;
614 bstr
= SysAllocStringLen(NULL
, dLen
-1);
617 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, bstr
, dLen
);
618 if(len
!= -1) bstr
[dLen
-1] = '\0';
623 static BSTR
QName_from_xmlChar(const xmlChar
*prefix
, const xmlChar
*name
)
628 if(!name
) return NULL
;
630 if(!prefix
|| !*prefix
)
631 return bstr_from_xmlChar(name
);
633 qname
= xmlBuildQName(name
, prefix
, NULL
, 0);
634 bstr
= bstr_from_xmlChar(qname
);
640 static BSTR
pooled_bstr_from_xmlChar(struct bstrpool
*pool
, const xmlChar
*buf
)
642 BSTR pool_entry
= bstr_from_xmlChar(buf
);
644 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
646 SysFreeString(pool_entry
);
653 static BSTR
pooled_bstr_from_xmlCharN(struct bstrpool
*pool
, const xmlChar
*buf
, int len
)
655 BSTR pool_entry
= bstr_from_xmlCharN(buf
, len
);
657 if (pool_entry
&& !bstr_pool_insert(pool
, pool_entry
))
659 SysFreeString(pool_entry
);
666 static void format_error_message_from_id(saxlocator
*This
, HRESULT hr
)
668 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
669 xmlStopParser(This
->pParserCtxt
);
672 if (saxreader_has_handler(This
, SAXErrorHandler
))
675 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
,
676 NULL
, hr
, 0, msg
, sizeof(msg
)/sizeof(msg
[0]), NULL
))
678 FIXME("MSXML errors not yet supported.\n");
682 if(This
->vbInterface
)
684 BSTR bstrMsg
= SysAllocString(msg
);
685 IVBSAXErrorHandler_fatalError(handler
->vbhandler
,
686 &This
->IVBSAXLocator_iface
, &bstrMsg
, hr
);
687 SysFreeString(bstrMsg
);
690 ISAXErrorHandler_fatalError(handler
->handler
,
691 &This
->ISAXLocator_iface
, msg
, hr
);
695 static void update_position(saxlocator
*This
, BOOL fix_column
)
697 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
698 const xmlChar
*baseP
= This
->pParserCtxt
->input
->base
;
700 This
->line
= xmlSAX2GetLineNumber(This
->pParserCtxt
);
704 for(;p
>=baseP
&& *p
!='\n' && *p
!='\r'; p
--)
709 This
->column
= xmlSAX2GetColumnNumber(This
->pParserCtxt
);
713 /*** IVBSAXAttributes interface ***/
714 static HRESULT WINAPI
ivbsaxattributes_QueryInterface(
715 IVBSAXAttributes
* iface
,
719 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
720 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
721 return IVBSAXLocator_QueryInterface(&This
->IVBSAXLocator_iface
, riid
, ppvObject
);
724 static ULONG WINAPI
ivbsaxattributes_AddRef(IVBSAXAttributes
* iface
)
726 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
727 return IVBSAXLocator_AddRef(&This
->IVBSAXLocator_iface
);
730 static ULONG WINAPI
ivbsaxattributes_Release(IVBSAXAttributes
* iface
)
732 saxlocator
*This
= impl_from_IVBSAXAttributes(iface
);
733 return IVBSAXLocator_Release(&This
->IVBSAXLocator_iface
);
736 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes
*iface
, UINT
* pctinfo
)
738 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
740 TRACE("(%p)->(%p)\n", This
, pctinfo
);
747 static HRESULT WINAPI
ivbsaxattributes_GetTypeInfo(
748 IVBSAXAttributes
*iface
,
749 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
751 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
753 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
755 return get_typeinfo(IVBSAXAttributes_tid
, ppTInfo
);
758 static HRESULT WINAPI
ivbsaxattributes_GetIDsOfNames(
759 IVBSAXAttributes
*iface
,
766 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
770 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
773 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
776 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
779 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
780 ITypeInfo_Release(typeinfo
);
786 static HRESULT WINAPI
ivbsaxattributes_Invoke(
787 IVBSAXAttributes
*iface
,
792 DISPPARAMS
* pDispParams
,
794 EXCEPINFO
* pExcepInfo
,
797 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
801 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
802 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
804 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
807 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXAttributes_iface
, dispIdMember
, wFlags
,
808 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
809 ITypeInfo_Release(typeinfo
);
815 /*** IVBSAXAttributes methods ***/
816 static HRESULT WINAPI
ivbsaxattributes_get_length(
817 IVBSAXAttributes
* iface
,
820 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
821 return ISAXAttributes_getLength(&This
->ISAXAttributes_iface
, nLength
);
824 static HRESULT WINAPI
ivbsaxattributes_getURI(
825 IVBSAXAttributes
* iface
,
829 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
834 TRACE("(%p)->(%d %p)\n", This
, nIndex
, uri
);
840 hr
= ISAXAttributes_getURI(&This
->ISAXAttributes_iface
, nIndex
, &uriW
, &len
);
844 return return_bstrn(uriW
, len
, uri
);
847 static HRESULT WINAPI
ivbsaxattributes_getLocalName(
848 IVBSAXAttributes
* iface
,
852 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
857 TRACE("(%p)->(%d %p)\n", This
, nIndex
, name
);
863 hr
= ISAXAttributes_getLocalName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
867 return return_bstrn(nameW
, len
, name
);
870 static HRESULT WINAPI
ivbsaxattributes_getQName(
871 IVBSAXAttributes
* iface
,
875 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
880 TRACE("(%p)->(%d %p)\n", This
, nIndex
, QName
);
886 hr
= ISAXAttributes_getQName(&This
->ISAXAttributes_iface
, nIndex
, &nameW
, &len
);
890 return return_bstrn(nameW
, len
, QName
);
893 static HRESULT WINAPI
ivbsaxattributes_getIndexFromName(
894 IVBSAXAttributes
* iface
,
899 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
900 return ISAXAttributes_getIndexFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
901 localName
, SysStringLen(localName
), index
);
904 static HRESULT WINAPI
ivbsaxattributes_getIndexFromQName(
905 IVBSAXAttributes
* iface
,
909 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
910 return ISAXAttributes_getIndexFromQName(&This
->ISAXAttributes_iface
, QName
,
911 SysStringLen(QName
), index
);
914 static HRESULT WINAPI
ivbsaxattributes_getType(
915 IVBSAXAttributes
* iface
,
919 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
924 TRACE("(%p)->(%d %p)\n", This
, nIndex
, type
);
930 hr
= ISAXAttributes_getType(&This
->ISAXAttributes_iface
, nIndex
, &typeW
, &len
);
934 return return_bstrn(typeW
, len
, type
);
937 static HRESULT WINAPI
ivbsaxattributes_getTypeFromName(
938 IVBSAXAttributes
* iface
,
943 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
948 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), type
);
954 hr
= ISAXAttributes_getTypeFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
955 localName
, SysStringLen(localName
), &typeW
, &len
);
959 return return_bstrn(typeW
, len
, type
);
962 static HRESULT WINAPI
ivbsaxattributes_getTypeFromQName(
963 IVBSAXAttributes
* iface
,
967 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
972 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), type
);
978 hr
= ISAXAttributes_getTypeFromQName(&This
->ISAXAttributes_iface
, QName
, SysStringLen(QName
),
983 return return_bstrn(typeW
, len
, type
);
986 static HRESULT WINAPI
ivbsaxattributes_getValue(
987 IVBSAXAttributes
* iface
,
991 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
996 TRACE("(%p)->(%d %p)\n", This
, nIndex
, value
);
1002 hr
= ISAXAttributes_getValue(&This
->ISAXAttributes_iface
, nIndex
, &valueW
, &len
);
1006 return return_bstrn(valueW
, len
, value
);
1009 static HRESULT WINAPI
ivbsaxattributes_getValueFromName(
1010 IVBSAXAttributes
* iface
,
1015 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1016 const WCHAR
*valueW
;
1020 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(uri
), debugstr_w(localName
), value
);
1026 hr
= ISAXAttributes_getValueFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
1027 localName
, SysStringLen(localName
), &valueW
, &len
);
1031 return return_bstrn(valueW
, len
, value
);
1034 static HRESULT WINAPI
ivbsaxattributes_getValueFromQName(
1035 IVBSAXAttributes
* iface
,
1039 saxlocator
*This
= impl_from_IVBSAXAttributes( iface
);
1040 const WCHAR
*valueW
;
1044 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(QName
), value
);
1050 hr
= ISAXAttributes_getValueFromQName(&This
->ISAXAttributes_iface
, QName
,
1051 SysStringLen(QName
), &valueW
, &len
);
1055 return return_bstrn(valueW
, len
, value
);
1058 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl
=
1060 ivbsaxattributes_QueryInterface
,
1061 ivbsaxattributes_AddRef
,
1062 ivbsaxattributes_Release
,
1063 ivbsaxattributes_GetTypeInfoCount
,
1064 ivbsaxattributes_GetTypeInfo
,
1065 ivbsaxattributes_GetIDsOfNames
,
1066 ivbsaxattributes_Invoke
,
1067 ivbsaxattributes_get_length
,
1068 ivbsaxattributes_getURI
,
1069 ivbsaxattributes_getLocalName
,
1070 ivbsaxattributes_getQName
,
1071 ivbsaxattributes_getIndexFromName
,
1072 ivbsaxattributes_getIndexFromQName
,
1073 ivbsaxattributes_getType
,
1074 ivbsaxattributes_getTypeFromName
,
1075 ivbsaxattributes_getTypeFromQName
,
1076 ivbsaxattributes_getValue
,
1077 ivbsaxattributes_getValueFromName
,
1078 ivbsaxattributes_getValueFromQName
1081 /*** ISAXAttributes interface ***/
1082 /*** IUnknown methods ***/
1083 static HRESULT WINAPI
isaxattributes_QueryInterface(
1084 ISAXAttributes
* iface
,
1088 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1089 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
1090 return ISAXLocator_QueryInterface(&This
->ISAXLocator_iface
, riid
, ppvObject
);
1093 static ULONG WINAPI
isaxattributes_AddRef(ISAXAttributes
* iface
)
1095 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1096 TRACE("%p\n", This
);
1097 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
1100 static ULONG WINAPI
isaxattributes_Release(ISAXAttributes
* iface
)
1102 saxlocator
*This
= impl_from_ISAXAttributes(iface
);
1104 TRACE("%p\n", This
);
1105 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
1108 /*** ISAXAttributes methods ***/
1109 static HRESULT WINAPI
isaxattributes_getLength(
1110 ISAXAttributes
* iface
,
1113 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1115 *length
= This
->attr_count
;
1116 TRACE("Length set to %d\n", *length
);
1120 static inline BOOL
is_valid_attr_index(const saxlocator
*locator
, int index
)
1122 return index
< locator
->attr_count
&& index
>= 0;
1125 static HRESULT WINAPI
isaxattributes_getURI(
1126 ISAXAttributes
* iface
,
1131 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1132 TRACE("(%p)->(%d)\n", This
, index
);
1134 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1135 if(!url
|| !size
) return E_POINTER
;
1137 *size
= SysStringLen(This
->attributes
[index
].szURI
);
1138 *url
= This
->attributes
[index
].szURI
;
1140 TRACE("(%s:%d)\n", debugstr_w(This
->attributes
[index
].szURI
), *size
);
1145 static HRESULT WINAPI
isaxattributes_getLocalName(
1146 ISAXAttributes
* iface
,
1148 const WCHAR
**pLocalName
,
1149 int *pLocalNameLength
)
1151 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1152 TRACE("(%p)->(%d)\n", This
, index
);
1154 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1155 if(!pLocalName
|| !pLocalNameLength
) return E_POINTER
;
1157 *pLocalNameLength
= SysStringLen(This
->attributes
[index
].szLocalname
);
1158 *pLocalName
= This
->attributes
[index
].szLocalname
;
1163 static HRESULT WINAPI
isaxattributes_getQName(
1164 ISAXAttributes
* iface
,
1166 const WCHAR
**pQName
,
1169 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1170 TRACE("(%p)->(%d)\n", This
, index
);
1172 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1173 if(!pQName
|| !pQNameLength
) return E_POINTER
;
1175 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1176 *pQName
= This
->attributes
[index
].szQName
;
1181 static HRESULT WINAPI
isaxattributes_getName(
1182 ISAXAttributes
* iface
,
1186 const WCHAR
**localName
,
1187 int *pLocalNameSize
,
1188 const WCHAR
**QName
,
1191 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1192 TRACE("(%p)->(%d)\n", This
, index
);
1194 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1195 if(!uri
|| !pUriLength
|| !localName
|| !pLocalNameSize
1196 || !QName
|| !pQNameLength
) return E_POINTER
;
1198 *pUriLength
= SysStringLen(This
->attributes
[index
].szURI
);
1199 *uri
= This
->attributes
[index
].szURI
;
1200 *pLocalNameSize
= SysStringLen(This
->attributes
[index
].szLocalname
);
1201 *localName
= This
->attributes
[index
].szLocalname
;
1202 *pQNameLength
= SysStringLen(This
->attributes
[index
].szQName
);
1203 *QName
= This
->attributes
[index
].szQName
;
1205 TRACE("(%s, %s, %s)\n", debugstr_w(*uri
), debugstr_w(*localName
), debugstr_w(*QName
));
1210 static HRESULT WINAPI
isaxattributes_getIndexFromName(
1211 ISAXAttributes
* iface
,
1214 const WCHAR
*pLocalName
,
1215 int cocalNameLength
,
1218 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1220 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), cUriLength
,
1221 debugstr_w(pLocalName
), cocalNameLength
);
1223 if(!pUri
|| !pLocalName
|| !index
) return E_POINTER
;
1225 for(i
=0; i
<This
->attr_count
; i
++)
1227 if(cUriLength
!=SysStringLen(This
->attributes
[i
].szURI
)
1228 || cocalNameLength
!=SysStringLen(This
->attributes
[i
].szLocalname
))
1230 if(cUriLength
&& memcmp(pUri
, This
->attributes
[i
].szURI
,
1231 sizeof(WCHAR
)*cUriLength
))
1233 if(cocalNameLength
&& memcmp(pLocalName
, This
->attributes
[i
].szLocalname
,
1234 sizeof(WCHAR
)*cocalNameLength
))
1241 return E_INVALIDARG
;
1244 static HRESULT WINAPI
isaxattributes_getIndexFromQName(
1245 ISAXAttributes
* iface
,
1246 const WCHAR
*pQName
,
1250 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1252 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQNameLength
);
1254 if(!pQName
|| !index
) return E_POINTER
;
1255 if(!nQNameLength
) return E_INVALIDARG
;
1257 for(i
=0; i
<This
->attr_count
; i
++)
1259 if(nQNameLength
!=SysStringLen(This
->attributes
[i
].szQName
)) continue;
1260 if(memcmp(pQName
, This
->attributes
[i
].szQName
, sizeof(WCHAR
)*nQNameLength
)) continue;
1266 return E_INVALIDARG
;
1269 static HRESULT WINAPI
isaxattributes_getType(
1270 ISAXAttributes
* iface
,
1272 const WCHAR
**pType
,
1275 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1277 FIXME("(%p)->(%d) stub\n", This
, nIndex
);
1281 static HRESULT WINAPI
isaxattributes_getTypeFromName(
1282 ISAXAttributes
* iface
,
1285 const WCHAR
*pLocalName
,
1287 const WCHAR
**pType
,
1290 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1292 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This
, debugstr_w(pUri
), nUri
,
1293 debugstr_w(pLocalName
), nLocalName
);
1297 static HRESULT WINAPI
isaxattributes_getTypeFromQName(
1298 ISAXAttributes
* iface
,
1299 const WCHAR
*pQName
,
1301 const WCHAR
**pType
,
1304 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1306 FIXME("(%p)->(%s, %d) stub\n", This
, debugstr_w(pQName
), nQName
);
1310 static HRESULT WINAPI
isaxattributes_getValue(
1311 ISAXAttributes
* iface
,
1313 const WCHAR
**value
,
1316 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1317 TRACE("(%p)->(%d)\n", This
, index
);
1319 if(!is_valid_attr_index(This
, index
)) return E_INVALIDARG
;
1320 if(!value
|| !nValue
) return E_POINTER
;
1322 *nValue
= SysStringLen(This
->attributes
[index
].szValue
);
1323 *value
= This
->attributes
[index
].szValue
;
1325 TRACE("(%s:%d)\n", debugstr_w(*value
), *nValue
);
1330 static HRESULT WINAPI
isaxattributes_getValueFromName(
1331 ISAXAttributes
* iface
,
1334 const WCHAR
*pLocalName
,
1336 const WCHAR
**pValue
,
1341 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1342 TRACE("(%p)->(%s, %d, %s, %d)\n", This
, debugstr_w(pUri
), nUri
,
1343 debugstr_w(pLocalName
), nLocalName
);
1345 hr
= ISAXAttributes_getIndexFromName(iface
,
1346 pUri
, nUri
, pLocalName
, nLocalName
, &index
);
1347 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1352 static HRESULT WINAPI
isaxattributes_getValueFromQName(
1353 ISAXAttributes
* iface
,
1354 const WCHAR
*pQName
,
1356 const WCHAR
**pValue
,
1361 saxlocator
*This
= impl_from_ISAXAttributes( iface
);
1362 TRACE("(%p)->(%s, %d)\n", This
, debugstr_w(pQName
), nQName
);
1364 hr
= ISAXAttributes_getIndexFromQName(iface
, pQName
, nQName
, &index
);
1365 if(hr
==S_OK
) hr
= ISAXAttributes_getValue(iface
, index
, pValue
, nValue
);
1370 static const struct ISAXAttributesVtbl isaxattributes_vtbl
=
1372 isaxattributes_QueryInterface
,
1373 isaxattributes_AddRef
,
1374 isaxattributes_Release
,
1375 isaxattributes_getLength
,
1376 isaxattributes_getURI
,
1377 isaxattributes_getLocalName
,
1378 isaxattributes_getQName
,
1379 isaxattributes_getName
,
1380 isaxattributes_getIndexFromName
,
1381 isaxattributes_getIndexFromQName
,
1382 isaxattributes_getType
,
1383 isaxattributes_getTypeFromName
,
1384 isaxattributes_getTypeFromQName
,
1385 isaxattributes_getValue
,
1386 isaxattributes_getValueFromName
,
1387 isaxattributes_getValueFromQName
1390 /* Libxml2 escapes '&' back to char reference '&' in attribute value,
1391 so when document has escaped value with '&' it's parsed to '&' and then
1392 escaped to '&'. This function takes care of ampersands only. */
1393 static BSTR
saxreader_get_unescaped_value(const xmlChar
*buf
, int len
)
1395 static const WCHAR ampescW
[] = {'&','#','3','8',';',0};
1396 WCHAR
*dest
, *ptrW
, *str
;
1403 str_len
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, NULL
, 0);
1404 if (len
!= -1) str_len
++;
1406 str
= heap_alloc(str_len
*sizeof(WCHAR
));
1407 if (!str
) return NULL
;
1409 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)buf
, len
, str
, str_len
);
1410 if (len
!= -1) str
[str_len
-1] = 0;
1413 while ((dest
= strstrW(ptrW
, ampescW
)))
1417 /* leave first '&' from a reference as a value */
1418 src
= dest
+ (sizeof(ampescW
)/sizeof(WCHAR
) - 1);
1421 /* move together with null terminator */
1422 memmove(dest
, src
, (strlenW(src
) + 1)*sizeof(WCHAR
));
1427 bstr
= SysAllocString(str
);
1433 static void free_attribute_values(saxlocator
*locator
)
1437 for (i
= 0; i
< locator
->attr_count
; i
++)
1439 SysFreeString(locator
->attributes
[i
].szLocalname
);
1440 locator
->attributes
[i
].szLocalname
= NULL
;
1442 SysFreeString(locator
->attributes
[i
].szValue
);
1443 locator
->attributes
[i
].szValue
= NULL
;
1445 SysFreeString(locator
->attributes
[i
].szQName
);
1446 locator
->attributes
[i
].szQName
= NULL
;
1450 static HRESULT
SAXAttributes_populate(saxlocator
*locator
,
1451 int nb_namespaces
, const xmlChar
**xmlNamespaces
,
1452 int nb_attributes
, const xmlChar
**xmlAttributes
)
1454 static const xmlChar xmlns
[] = "xmlns";
1455 static const WCHAR xmlnsW
[] = { 'x','m','l','n','s',0 };
1457 struct _attributes
*attrs
;
1460 /* skip namespace definitions */
1461 if ((locator
->saxreader
->features
& NamespacePrefixes
) == 0)
1464 locator
->attr_count
= nb_namespaces
+ nb_attributes
;
1465 if(locator
->attr_count
> locator
->attr_alloc_count
)
1467 int new_size
= locator
->attr_count
* 2;
1468 attrs
= heap_realloc_zero(locator
->attributes
, new_size
* sizeof(struct _attributes
));
1471 free_attribute_values(locator
);
1472 locator
->attr_count
= 0;
1473 return E_OUTOFMEMORY
;
1475 locator
->attributes
= attrs
;
1476 locator
->attr_alloc_count
= new_size
;
1480 attrs
= locator
->attributes
;
1483 for (i
= 0; i
< nb_namespaces
; i
++)
1485 SysFreeString(attrs
[nb_attributes
+i
].szLocalname
);
1486 attrs
[nb_attributes
+i
].szLocalname
= SysAllocStringLen(NULL
, 0);
1488 attrs
[nb_attributes
+i
].szURI
= locator
->namespaceUri
;
1490 SysFreeString(attrs
[nb_attributes
+i
].szValue
);
1491 attrs
[nb_attributes
+i
].szValue
= bstr_from_xmlChar(xmlNamespaces
[2*i
+1]);
1493 SysFreeString(attrs
[nb_attributes
+i
].szQName
);
1494 if(!xmlNamespaces
[2*i
])
1495 attrs
[nb_attributes
+i
].szQName
= SysAllocString(xmlnsW
);
1497 attrs
[nb_attributes
+i
].szQName
= QName_from_xmlChar(xmlns
, xmlNamespaces
[2*i
]);
1500 for (i
= 0; i
< nb_attributes
; i
++)
1502 static const xmlChar xmlA
[] = "xml";
1504 if (xmlStrEqual(xmlAttributes
[i
*5+1], xmlA
))
1505 attrs
[i
].szURI
= bstr_from_xmlChar(xmlAttributes
[i
*5+2]);
1507 /* that's an important feature to keep same uri pointer for every reported attribute */
1508 attrs
[i
].szURI
= find_element_uri(locator
, xmlAttributes
[i
*5+2]);
1510 SysFreeString(attrs
[i
].szLocalname
);
1511 attrs
[i
].szLocalname
= bstr_from_xmlChar(xmlAttributes
[i
*5]);
1513 SysFreeString(attrs
[i
].szValue
);
1514 attrs
[i
].szValue
= saxreader_get_unescaped_value(xmlAttributes
[i
*5+3], xmlAttributes
[i
*5+4]-xmlAttributes
[i
*5+3]);
1516 SysFreeString(attrs
[i
].szQName
);
1517 attrs
[i
].szQName
= QName_from_xmlChar(xmlAttributes
[i
*5+1], xmlAttributes
[i
*5]);
1523 /*** LibXML callbacks ***/
1524 static void libxmlStartDocument(void *ctx
)
1526 saxlocator
*This
= ctx
;
1527 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1530 if (This
->saxreader
->version
>= MSXML4
)
1532 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
-1;
1533 update_position(This
, FALSE
);
1534 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1536 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1541 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1545 /* store version value, declaration has to contain version attribute */
1546 if (This
->pParserCtxt
->standalone
!= -1)
1548 SysFreeString(This
->saxreader
->xmldecl_version
);
1549 This
->saxreader
->xmldecl_version
= bstr_from_xmlChar(This
->pParserCtxt
->version
);
1552 if (saxreader_has_handler(This
, SAXContentHandler
))
1554 if(This
->vbInterface
)
1555 hr
= IVBSAXContentHandler_startDocument(handler
->vbhandler
);
1557 hr
= ISAXContentHandler_startDocument(handler
->handler
);
1559 if (sax_callback_failed(This
, hr
))
1560 format_error_message_from_id(This
, hr
);
1564 static void libxmlEndDocument(void *ctx
)
1566 saxlocator
*This
= ctx
;
1567 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1570 if (This
->saxreader
->version
>= MSXML4
) {
1571 update_position(This
, FALSE
);
1572 if(This
->column
> 1)
1580 if(This
->ret
!= S_OK
) return;
1582 if (saxreader_has_handler(This
, SAXContentHandler
))
1584 if(This
->vbInterface
)
1585 hr
= IVBSAXContentHandler_endDocument(handler
->vbhandler
);
1587 hr
= ISAXContentHandler_endDocument(handler
->handler
);
1589 if (sax_callback_failed(This
, hr
))
1590 format_error_message_from_id(This
, hr
);
1594 static void libxmlStartElementNS(
1596 const xmlChar
*localname
,
1597 const xmlChar
*prefix
,
1600 const xmlChar
**namespaces
,
1603 const xmlChar
**attributes
)
1605 saxlocator
*This
= ctx
;
1606 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1607 element_entry
*element
;
1611 update_position(This
, TRUE
);
1612 if(*(This
->pParserCtxt
->input
->cur
) == '/')
1614 if(This
->saxreader
->version
< MSXML4
)
1617 element
= alloc_element_entry(localname
, prefix
, nb_namespaces
, namespaces
);
1618 push_element_ns(This
, element
);
1620 if (is_namespaces_enabled(This
->saxreader
))
1624 for (i
= 0; i
< nb_namespaces
&& saxreader_has_handler(This
, SAXContentHandler
); i
++)
1626 if (This
->vbInterface
)
1627 hr
= IVBSAXContentHandler_startPrefixMapping(
1629 &element
->ns
[i
].prefix
,
1630 &element
->ns
[i
].uri
);
1632 hr
= ISAXContentHandler_startPrefixMapping(
1634 element
->ns
[i
].prefix
,
1635 SysStringLen(element
->ns
[i
].prefix
),
1637 SysStringLen(element
->ns
[i
].uri
));
1639 if (sax_callback_failed(This
, hr
))
1641 format_error_message_from_id(This
, hr
);
1647 uri
= find_element_uri(This
, URI
);
1648 hr
= SAXAttributes_populate(This
, nb_namespaces
, namespaces
, nb_attributes
, attributes
);
1649 if (hr
== S_OK
&& saxreader_has_handler(This
, SAXContentHandler
))
1653 if (is_namespaces_enabled(This
->saxreader
))
1654 local
= element
->local
;
1658 if (This
->vbInterface
)
1659 hr
= IVBSAXContentHandler_startElement(handler
->vbhandler
,
1660 &uri
, &local
, &element
->qname
, &This
->IVBSAXAttributes_iface
);
1662 hr
= ISAXContentHandler_startElement(handler
->handler
,
1663 uri
, SysStringLen(uri
),
1664 local
, SysStringLen(local
),
1665 element
->qname
, SysStringLen(element
->qname
),
1666 &This
->ISAXAttributes_iface
);
1668 if (sax_callback_failed(This
, hr
))
1669 format_error_message_from_id(This
, hr
);
1673 static void libxmlEndElementNS(
1675 const xmlChar
*localname
,
1676 const xmlChar
*prefix
,
1679 saxlocator
*This
= ctx
;
1680 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1681 element_entry
*element
;
1686 update_position(This
, FALSE
);
1687 p
= This
->pParserCtxt
->input
->cur
;
1689 if (This
->saxreader
->version
>= MSXML4
)
1692 while(p
>This
->pParserCtxt
->input
->base
&& *p
!='>')
1694 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1699 else if(*(p
-1)!='>' || *(p
-2)!='/')
1702 while(p
-2>=This
->pParserCtxt
->input
->base
1703 && *(p
-2)!='<' && *(p
-1)!='/')
1705 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1711 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1714 uri
= find_element_uri(This
, URI
);
1715 element
= pop_element_ns(This
);
1717 if (!saxreader_has_handler(This
, SAXContentHandler
))
1719 free_attribute_values(This
);
1720 This
->attr_count
= 0;
1721 free_element_entry(element
);
1725 if (is_namespaces_enabled(This
->saxreader
))
1726 local
= element
->local
;
1730 if (This
->vbInterface
)
1731 hr
= IVBSAXContentHandler_endElement(
1733 &uri
, &local
, &element
->qname
);
1735 hr
= ISAXContentHandler_endElement(
1737 uri
, SysStringLen(uri
),
1738 local
, SysStringLen(local
),
1739 element
->qname
, SysStringLen(element
->qname
));
1741 free_attribute_values(This
);
1742 This
->attr_count
= 0;
1744 if (sax_callback_failed(This
, hr
))
1746 format_error_message_from_id(This
, hr
);
1747 free_element_entry(element
);
1751 if (is_namespaces_enabled(This
->saxreader
))
1754 while (iterate_endprefix_index(This
, element
, &i
) && saxreader_has_handler(This
, SAXContentHandler
))
1756 if (This
->vbInterface
)
1757 hr
= IVBSAXContentHandler_endPrefixMapping(
1758 handler
->vbhandler
, &element
->ns
[i
].prefix
);
1760 hr
= ISAXContentHandler_endPrefixMapping(
1761 handler
->handler
, element
->ns
[i
].prefix
, SysStringLen(element
->ns
[i
].prefix
));
1763 if (sax_callback_failed(This
, hr
)) break;
1766 if (sax_callback_failed(This
, hr
))
1767 format_error_message_from_id(This
, hr
);
1770 free_element_entry(element
);
1773 static void libxmlCharacters(
1778 saxlocator
*This
= ctx
;
1782 BOOL lastEvent
= FALSE
;
1784 if (!saxreader_has_handler(This
, SAXContentHandler
)) return;
1786 update_position(This
, FALSE
);
1787 cur
= (xmlChar
*)This
->pParserCtxt
->input
->cur
;
1788 while(cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='>')
1790 if(*cur
=='\n' || (*cur
=='\r' && *(cur
+1)!='\n'))
1795 for(; cur
>=This
->pParserCtxt
->input
->base
&& *cur
!='\n' && *cur
!='\r'; cur
--)
1799 if(*(ch
-1)=='\r') cur
--;
1804 while(end
-ch
<len
&& *end
!='\r') end
++;
1815 if (This
->saxreader
->version
>= MSXML4
)
1819 for(p
=cur
; p
!=end
; p
++)
1836 Chars
= pooled_bstr_from_xmlCharN(&This
->saxreader
->pool
, cur
, end
-cur
);
1837 hr
= saxreader_saxcharacters(This
, Chars
);
1839 if (sax_callback_failed(This
, hr
))
1841 format_error_message_from_id(This
, hr
);
1845 if (This
->saxreader
->version
< MSXML4
)
1846 This
->column
+= end
-cur
;
1859 if(end
-ch
== len
) break;
1863 static void libxmlSetDocumentLocator(
1865 xmlSAXLocatorPtr loc
)
1867 saxlocator
*This
= ctx
;
1868 struct saxcontenthandler_iface
*handler
= saxreader_get_contenthandler(This
->saxreader
);
1871 if (saxreader_has_handler(This
, SAXContentHandler
))
1873 if(This
->vbInterface
)
1874 hr
= IVBSAXContentHandler_putref_documentLocator(handler
->vbhandler
,
1875 &This
->IVBSAXLocator_iface
);
1877 hr
= ISAXContentHandler_putDocumentLocator(handler
->handler
, &This
->ISAXLocator_iface
);
1881 format_error_message_from_id(This
, hr
);
1884 static void libxmlComment(void *ctx
, const xmlChar
*value
)
1886 saxlocator
*This
= ctx
;
1887 struct saxlexicalhandler_iface
*handler
= saxreader_get_lexicalhandler(This
->saxreader
);
1890 const xmlChar
*p
= This
->pParserCtxt
->input
->cur
;
1892 update_position(This
, FALSE
);
1893 while(p
-4>=This
->pParserCtxt
->input
->base
1894 && memcmp(p
-4, "<!--", sizeof(char[4])))
1896 if(*p
=='\n' || (*p
=='\r' && *(p
+1)!='\n'))
1902 for(; p
>=This
->pParserCtxt
->input
->base
&& *p
!='\n' && *p
!='\r'; p
--)
1905 if (!saxreader_has_handler(This
, SAXLexicalHandler
)) return;
1907 bValue
= pooled_bstr_from_xmlChar(&This
->saxreader
->pool
, value
);
1909 if (This
->vbInterface
)
1910 hr
= IVBSAXLexicalHandler_comment(handler
->vbhandler
, &bValue
);
1912 hr
= ISAXLexicalHandler_comment(handler
->handler
, bValue
, SysStringLen(bValue
));
1915 format_error_message_from_id(This
, hr
);
1918 static void libxmlFatalError(void *ctx
, const char *msg
, ...)
1920 saxlocator
*This
= ctx
;
1921 struct saxerrorhandler_iface
*handler
= saxreader_get_errorhandler(This
->saxreader
);
1927 if(This
->ret
!= S_OK
) {
1928 xmlStopParser(This
->pParserCtxt
);
1932 va_start(args
, msg
);
1933 vsprintf(message
, msg
, args
);
1936 len
= MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, NULL
, 0);
1937 error
= heap_alloc(sizeof(WCHAR
)*len
);
1940 MultiByteToWideChar(CP_UNIXCP
, 0, message
, -1, error
, len
);
1941 TRACE("fatal error for %p: %s\n", This
, debugstr_w(error
));
1944 if (!saxreader_has_handler(This
, SAXErrorHandler
))
1946 xmlStopParser(This
->pParserCtxt
);
1952 FIXME("Error handling is not compatible.\n");
1954 if(This
->vbInterface
)
1956 BSTR bstrError
= SysAllocString(error
);
1957 IVBSAXErrorHandler_fatalError(handler
->vbhandler
, &This
->IVBSAXLocator_iface
,
1958 &bstrError
, E_FAIL
);
1959 SysFreeString(bstrError
);
1962 ISAXErrorHandler_fatalError(handler
->handler
, &This
->ISAXLocator_iface
, error
, E_FAIL
);
1966 xmlStopParser(This
->pParserCtxt
);
1970 /* The only reason this helper exists is that CDATA section are reported by chunks,
1971 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1973 This helper should be called for substring with trailing newlines.
1975 static BSTR
saxreader_get_cdata_chunk(const xmlChar
*str
, int len
)
1977 BSTR bstr
= bstr_from_xmlCharN(str
, len
), ret
;
1980 len
= SysStringLen(bstr
);
1981 ptr
= bstr
+ len
- 1;
1982 while ((*ptr
== '\r' || *ptr
== '\n') && ptr
>= bstr
)
1987 /* replace returns as:
1989 - "\r<char>" -> "\n<char>"
1995 if (*(ptr
+1) == '\r' || *(ptr
+1) == '\n')
1998 memmove(ptr
, ptr
+1, len
-- - (ptr
-bstr
));
2005 ret
= SysAllocStringLen(bstr
, len
);
2006 SysFreeString(bstr
);
2010 static void libxml_cdatablock(void *ctx
, const xmlChar
*value
, int len
)
2012 const xmlChar
*start
, *end
;
2013 saxlocator
*locator
= ctx
;
2014 struct saxlexicalhandler_iface
*lexical
= saxreader_get_lexicalhandler(locator
->saxreader
);
2019 update_position(locator
, FALSE
);
2020 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2022 if (locator
->vbInterface
)
2023 hr
= IVBSAXLexicalHandler_startCDATA(lexical
->vbhandler
);
2025 hr
= ISAXLexicalHandler_startCDATA(lexical
->handler
);
2030 format_error_message_from_id(locator
, hr
);
2040 /* scan for newlines */
2041 if (value
[i
] == '\r' || value
[i
] == '\n')
2043 /* skip newlines/linefeeds */
2046 if (value
[i
] != '\r' && value
[i
] != '\n') break;
2052 chars
= saxreader_get_cdata_chunk(start
, end
-start
);
2053 TRACE("(chunk %s)\n", debugstr_w(chars
));
2054 hr
= saxreader_saxcharacters(locator
, chars
);
2055 SysFreeString(chars
);
2064 /* no newline chars (or last chunk) report as a whole */
2065 if (!end
&& start
== value
)
2068 chars
= bstr_from_xmlCharN(start
, len
-(start
-value
));
2069 TRACE("(%s)\n", debugstr_w(chars
));
2070 hr
= saxreader_saxcharacters(locator
, chars
);
2071 SysFreeString(chars
);
2074 if (saxreader_has_handler(locator
, SAXLexicalHandler
))
2076 if (locator
->vbInterface
)
2077 hr
= IVBSAXLexicalHandler_endCDATA(lexical
->vbhandler
);
2079 hr
= ISAXLexicalHandler_endCDATA(lexical
->handler
);
2083 format_error_message_from_id(locator
, hr
);
2086 static xmlParserInputPtr
libxmlresolveentity(void *ctx
, const xmlChar
*publicid
, const xmlChar
*systemid
)
2088 FIXME("entity resolving not implemented, %s, %s\n", publicid
, systemid
);
2089 return xmlSAX2ResolveEntity(ctx
, publicid
, systemid
);
2092 /*** IVBSAXLocator interface ***/
2093 /*** IUnknown methods ***/
2094 static HRESULT WINAPI
ivbsaxlocator_QueryInterface(IVBSAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2096 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2098 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2102 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2103 IsEqualGUID( riid
, &IID_IDispatch
) ||
2104 IsEqualGUID( riid
, &IID_IVBSAXLocator
))
2108 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
2110 *ppvObject
= &This
->IVBSAXAttributes_iface
;
2114 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2115 return E_NOINTERFACE
;
2118 IVBSAXLocator_AddRef( iface
);
2123 static ULONG WINAPI
ivbsaxlocator_AddRef(IVBSAXLocator
* iface
)
2125 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2126 TRACE("%p\n", This
);
2127 return ISAXLocator_AddRef(&This
->ISAXLocator_iface
);
2130 static ULONG WINAPI
ivbsaxlocator_Release(IVBSAXLocator
* iface
)
2132 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2133 return ISAXLocator_Release(&This
->ISAXLocator_iface
);
2136 /*** IDispatch methods ***/
2137 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator
*iface
, UINT
* pctinfo
)
2139 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2141 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2148 static HRESULT WINAPI
ivbsaxlocator_GetTypeInfo(
2149 IVBSAXLocator
*iface
,
2150 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2152 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2154 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2156 return get_typeinfo(IVBSAXLocator_tid
, ppTInfo
);
2159 static HRESULT WINAPI
ivbsaxlocator_GetIDsOfNames(
2160 IVBSAXLocator
*iface
,
2162 LPOLESTR
* rgszNames
,
2167 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2168 ITypeInfo
*typeinfo
;
2171 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
2174 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2175 return E_INVALIDARG
;
2177 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2180 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2181 ITypeInfo_Release(typeinfo
);
2187 static HRESULT WINAPI
ivbsaxlocator_Invoke(
2188 IVBSAXLocator
*iface
,
2189 DISPID dispIdMember
,
2193 DISPPARAMS
* pDispParams
,
2194 VARIANT
* pVarResult
,
2195 EXCEPINFO
* pExcepInfo
,
2198 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2199 ITypeInfo
*typeinfo
;
2202 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2203 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2205 hr
= get_typeinfo(IVBSAXLocator_tid
, &typeinfo
);
2208 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXLocator_iface
, dispIdMember
, wFlags
,
2209 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2210 ITypeInfo_Release(typeinfo
);
2216 /*** IVBSAXLocator methods ***/
2217 static HRESULT WINAPI
ivbsaxlocator_get_columnNumber(
2218 IVBSAXLocator
* iface
,
2221 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2222 return ISAXLocator_getColumnNumber(&This
->ISAXLocator_iface
, pnColumn
);
2225 static HRESULT WINAPI
ivbsaxlocator_get_lineNumber(
2226 IVBSAXLocator
* iface
,
2229 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2230 return ISAXLocator_getLineNumber(&This
->ISAXLocator_iface
, pnLine
);
2233 static HRESULT WINAPI
ivbsaxlocator_get_publicId(IVBSAXLocator
* iface
, BSTR
*ret
)
2235 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2236 const WCHAR
*publicidW
;
2239 TRACE("(%p)->(%p)\n", This
, ret
);
2245 hr
= ISAXLocator_getPublicId(&This
->ISAXLocator_iface
, &publicidW
);
2249 return return_bstr(publicidW
, ret
);
2252 static HRESULT WINAPI
ivbsaxlocator_get_systemId(IVBSAXLocator
* iface
, BSTR
*ret
)
2254 saxlocator
*This
= impl_from_IVBSAXLocator( iface
);
2255 const WCHAR
*systemidW
;
2258 TRACE("(%p)->(%p)\n", This
, ret
);
2264 hr
= ISAXLocator_getSystemId(&This
->ISAXLocator_iface
, &systemidW
);
2268 return return_bstr(systemidW
, ret
);
2271 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl
=
2273 ivbsaxlocator_QueryInterface
,
2274 ivbsaxlocator_AddRef
,
2275 ivbsaxlocator_Release
,
2276 ivbsaxlocator_GetTypeInfoCount
,
2277 ivbsaxlocator_GetTypeInfo
,
2278 ivbsaxlocator_GetIDsOfNames
,
2279 ivbsaxlocator_Invoke
,
2280 ivbsaxlocator_get_columnNumber
,
2281 ivbsaxlocator_get_lineNumber
,
2282 ivbsaxlocator_get_publicId
,
2283 ivbsaxlocator_get_systemId
2286 /*** ISAXLocator interface ***/
2287 /*** IUnknown methods ***/
2288 static HRESULT WINAPI
isaxlocator_QueryInterface(ISAXLocator
* iface
, REFIID riid
, void **ppvObject
)
2290 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2292 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2296 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2297 IsEqualGUID( riid
, &IID_ISAXLocator
))
2301 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
2303 *ppvObject
= &This
->ISAXAttributes_iface
;
2307 WARN("interface %s not implemented\n", debugstr_guid(riid
));
2308 return E_NOINTERFACE
;
2311 ISAXLocator_AddRef( iface
);
2316 static ULONG WINAPI
isaxlocator_AddRef(ISAXLocator
* iface
)
2318 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2319 ULONG ref
= InterlockedIncrement( &This
->ref
);
2320 TRACE("(%p)->(%d)\n", This
, ref
);
2324 static ULONG WINAPI
isaxlocator_Release(
2327 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2328 LONG ref
= InterlockedDecrement( &This
->ref
);
2330 TRACE("(%p)->(%d)\n", This
, ref
);
2334 element_entry
*element
, *element2
;
2337 SysFreeString(This
->publicId
);
2338 SysFreeString(This
->systemId
);
2339 SysFreeString(This
->namespaceUri
);
2341 for(index
= 0; index
< This
->attr_alloc_count
; index
++)
2343 SysFreeString(This
->attributes
[index
].szLocalname
);
2344 SysFreeString(This
->attributes
[index
].szValue
);
2345 SysFreeString(This
->attributes
[index
].szQName
);
2347 heap_free(This
->attributes
);
2350 LIST_FOR_EACH_ENTRY_SAFE(element
, element2
, &This
->elements
, element_entry
, entry
)
2352 list_remove(&element
->entry
);
2353 free_element_entry(element
);
2356 ISAXXMLReader_Release(&This
->saxreader
->ISAXXMLReader_iface
);
2363 /*** ISAXLocator methods ***/
2364 static HRESULT WINAPI
isaxlocator_getColumnNumber(
2368 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2370 *pnColumn
= This
->column
;
2374 static HRESULT WINAPI
isaxlocator_getLineNumber(
2378 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2380 *pnLine
= This
->line
;
2384 static HRESULT WINAPI
isaxlocator_getPublicId(
2386 const WCHAR
** ppwchPublicId
)
2389 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2391 SysFreeString(This
->publicId
);
2393 publicId
= bstr_from_xmlChar(xmlSAX2GetPublicId(This
->pParserCtxt
));
2394 if(SysStringLen(publicId
))
2395 This
->publicId
= publicId
;
2398 SysFreeString(publicId
);
2399 This
->publicId
= NULL
;
2402 *ppwchPublicId
= This
->publicId
;
2406 static HRESULT WINAPI
isaxlocator_getSystemId(
2408 const WCHAR
** ppwchSystemId
)
2411 saxlocator
*This
= impl_from_ISAXLocator( iface
);
2413 SysFreeString(This
->systemId
);
2415 systemId
= bstr_from_xmlChar(xmlSAX2GetSystemId(This
->pParserCtxt
));
2416 if(SysStringLen(systemId
))
2417 This
->systemId
= systemId
;
2420 SysFreeString(systemId
);
2421 This
->systemId
= NULL
;
2424 *ppwchSystemId
= This
->systemId
;
2428 static const struct ISAXLocatorVtbl SAXLocatorVtbl
=
2430 isaxlocator_QueryInterface
,
2432 isaxlocator_Release
,
2433 isaxlocator_getColumnNumber
,
2434 isaxlocator_getLineNumber
,
2435 isaxlocator_getPublicId
,
2436 isaxlocator_getSystemId
2439 static HRESULT
SAXLocator_create(saxreader
*reader
, saxlocator
**ppsaxlocator
, BOOL vbInterface
)
2441 static const WCHAR w3xmlns
[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2442 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2444 saxlocator
*locator
;
2446 locator
= heap_alloc( sizeof (*locator
) );
2448 return E_OUTOFMEMORY
;
2450 locator
->IVBSAXLocator_iface
.lpVtbl
= &VBSAXLocatorVtbl
;
2451 locator
->ISAXLocator_iface
.lpVtbl
= &SAXLocatorVtbl
;
2452 locator
->IVBSAXAttributes_iface
.lpVtbl
= &ivbsaxattributes_vtbl
;
2453 locator
->ISAXAttributes_iface
.lpVtbl
= &isaxattributes_vtbl
;
2455 locator
->vbInterface
= vbInterface
;
2457 locator
->saxreader
= reader
;
2458 ISAXXMLReader_AddRef(&reader
->ISAXXMLReader_iface
);
2460 locator
->pParserCtxt
= NULL
;
2461 locator
->publicId
= NULL
;
2462 locator
->systemId
= NULL
;
2463 locator
->line
= reader
->version
< MSXML4
? 0 : 1;
2464 locator
->column
= 0;
2465 locator
->ret
= S_OK
;
2466 if (locator
->saxreader
->version
>= MSXML6
)
2467 locator
->namespaceUri
= SysAllocString(w3xmlns
);
2469 locator
->namespaceUri
= SysAllocStringLen(NULL
, 0);
2470 if(!locator
->namespaceUri
)
2472 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2474 return E_OUTOFMEMORY
;
2477 locator
->attr_alloc_count
= 8;
2478 locator
->attr_count
= 0;
2479 locator
->attributes
= heap_alloc_zero(sizeof(struct _attributes
)*locator
->attr_alloc_count
);
2480 if(!locator
->attributes
)
2482 ISAXXMLReader_Release(&reader
->ISAXXMLReader_iface
);
2483 SysFreeString(locator
->namespaceUri
);
2485 return E_OUTOFMEMORY
;
2488 list_init(&locator
->elements
);
2490 *ppsaxlocator
= locator
;
2492 TRACE("returning %p\n", *ppsaxlocator
);
2497 /*** SAXXMLReader internal functions ***/
2498 static HRESULT
internal_parseBuffer(saxreader
*This
, const char *buffer
, int size
, BOOL vbInterface
)
2500 xmlCharEncoding encoding
= XML_CHAR_ENCODING_NONE
;
2501 xmlChar
*enc_name
= NULL
;
2502 saxlocator
*locator
;
2505 TRACE("(%p)->(%p %d)\n", This
, buffer
, size
);
2507 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2513 const unsigned char *buff
= (unsigned char*)buffer
;
2515 encoding
= xmlDetectCharEncoding((xmlChar
*)buffer
, 4);
2516 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2517 TRACE("detected encoding: %s\n", enc_name
);
2518 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2519 if ((encoding
== XML_CHAR_ENCODING_UTF8
) &&
2520 buff
[0] == 0xEF && buff
[1] == 0xBB && buff
[2] == 0xBF)
2527 /* if libxml2 detection failed try to guess */
2528 if (encoding
== XML_CHAR_ENCODING_NONE
)
2530 const WCHAR
*ptr
= (WCHAR
*)buffer
;
2531 /* an xml declaration with optional encoding will still be handled by the parser */
2532 if ((size
>= 2) && *ptr
== '<' && ptr
[1] != '?')
2534 enc_name
= (xmlChar
*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE
);
2535 encoding
= XML_CHAR_ENCODING_UTF16LE
;
2538 else if (encoding
== XML_CHAR_ENCODING_UTF8
)
2539 enc_name
= (xmlChar
*)xmlGetCharEncodingName(encoding
);
2543 locator
->pParserCtxt
= xmlCreateMemoryParserCtxt(buffer
, size
);
2544 if (!locator
->pParserCtxt
)
2546 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2552 locator
->pParserCtxt
->encoding
= xmlStrdup(enc_name
);
2553 if (encoding
== XML_CHAR_ENCODING_UTF16LE
) {
2554 TRACE("switching to %s\n", enc_name
);
2555 xmlSwitchEncoding(locator
->pParserCtxt
, encoding
);
2559 xmlFree(locator
->pParserCtxt
->sax
);
2560 locator
->pParserCtxt
->sax
= &locator
->saxreader
->sax
;
2561 locator
->pParserCtxt
->userData
= locator
;
2563 This
->isParsing
= TRUE
;
2564 if(xmlParseDocument(locator
->pParserCtxt
) == -1 && locator
->ret
== S_OK
)
2568 This
->isParsing
= FALSE
;
2570 if(locator
->pParserCtxt
)
2572 locator
->pParserCtxt
->sax
= NULL
;
2573 xmlFreeParserCtxt(locator
->pParserCtxt
);
2574 locator
->pParserCtxt
= NULL
;
2577 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2581 static HRESULT
internal_parseStream(saxreader
*This
, ISequentialStream
*stream
, BOOL vbInterface
)
2583 saxlocator
*locator
;
2590 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2591 if(FAILED(hr
)) return hr
;
2593 hr
= SAXLocator_create(This
, &locator
, vbInterface
);
2594 if(FAILED(hr
)) return hr
;
2596 locator
->pParserCtxt
= xmlCreatePushParserCtxt(
2597 &locator
->saxreader
->sax
, locator
,
2598 data
, dataRead
, NULL
);
2599 if(!locator
->pParserCtxt
)
2601 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2605 This
->isParsing
= TRUE
;
2609 hr
= ISequentialStream_Read(stream
, data
, sizeof(data
), &dataRead
);
2610 if (FAILED(hr
) || !dataRead
) break;
2612 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, dataRead
, 0);
2613 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2618 ret
= xmlParseChunk(locator
->pParserCtxt
, data
, 0, 1);
2619 hr
= ret
!=XML_ERR_OK
&& locator
->ret
==S_OK
? E_FAIL
: locator
->ret
;
2623 This
->isParsing
= FALSE
;
2625 xmlFreeParserCtxt(locator
->pParserCtxt
);
2626 locator
->pParserCtxt
= NULL
;
2627 ISAXLocator_Release(&locator
->ISAXLocator_iface
);
2631 static HRESULT
internal_parse(
2638 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varInput
));
2640 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2641 free_bstr_pool(&This
->pool
);
2643 switch(V_VT(&varInput
))
2646 case VT_BSTR
|VT_BYREF
:
2648 BSTR str
= V_ISBYREF(&varInput
) ? *V_BSTRREF(&varInput
) : V_BSTR(&varInput
);
2649 hr
= internal_parseBuffer(This
, (const char*)str
, strlenW(str
)*sizeof(WCHAR
), vbInterface
);
2652 case VT_ARRAY
|VT_UI1
: {
2654 LONG lBound
, uBound
;
2657 hr
= SafeArrayGetLBound(V_ARRAY(&varInput
), 1, &lBound
);
2658 if(hr
!= S_OK
) break;
2659 hr
= SafeArrayGetUBound(V_ARRAY(&varInput
), 1, &uBound
);
2660 if(hr
!= S_OK
) break;
2661 dataRead
= (uBound
-lBound
)*SafeArrayGetElemsize(V_ARRAY(&varInput
));
2662 hr
= SafeArrayAccessData(V_ARRAY(&varInput
), &pSAData
);
2663 if(hr
!= S_OK
) break;
2664 hr
= internal_parseBuffer(This
, pSAData
, dataRead
, vbInterface
);
2665 SafeArrayUnaccessData(V_ARRAY(&varInput
));
2670 ISequentialStream
*stream
= NULL
;
2671 IXMLDOMDocument
*xmlDoc
;
2673 if (!V_UNKNOWN(&varInput
))
2674 return E_INVALIDARG
;
2676 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput
),
2677 &IID_IXMLDOMDocument
, (void**)&xmlDoc
) == S_OK
)
2681 IXMLDOMDocument_get_xml(xmlDoc
, &bstrData
);
2682 hr
= internal_parseBuffer(This
, (const char*)bstrData
,
2683 SysStringByteLen(bstrData
), vbInterface
);
2684 IXMLDOMDocument_Release(xmlDoc
);
2685 SysFreeString(bstrData
);
2689 /* try base interface first */
2690 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_ISequentialStream
, (void**)&stream
);
2692 /* this should never happen if IStream is implemented properly, but just in case */
2693 IUnknown_QueryInterface(V_UNKNOWN(&varInput
), &IID_IStream
, (void**)&stream
);
2697 hr
= internal_parseStream(This
, stream
, vbInterface
);
2698 ISequentialStream_Release(stream
);
2702 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2709 WARN("vt %d not implemented\n", V_VT(&varInput
));
2716 static HRESULT
internal_vbonDataAvailable(void *obj
, char *ptr
, DWORD len
)
2718 saxreader
*This
= obj
;
2720 return internal_parseBuffer(This
, ptr
, len
, TRUE
);
2723 static HRESULT
internal_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2725 saxreader
*This
= obj
;
2727 return internal_parseBuffer(This
, ptr
, len
, FALSE
);
2730 static HRESULT
internal_parseURL(
2739 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
2741 hr
= create_moniker_from_url(url
, &mon
);
2745 if(vbInterface
) hr
= bind_url(mon
, internal_vbonDataAvailable
, This
, &bsc
);
2746 else hr
= bind_url(mon
, internal_onDataAvailable
, This
, &bsc
);
2747 IMoniker_Release(mon
);
2752 return detach_bsc(bsc
);
2755 static HRESULT
saxreader_put_handler_from_variant(saxreader
*This
, enum saxhandler_type type
, const VARIANT
*v
, BOOL vb
)
2759 if (V_VT(v
) == VT_EMPTY
)
2760 return saxreader_put_handler(This
, type
, NULL
, vb
);
2764 case SAXDeclHandler
:
2765 riid
= vb
? &IID_IVBSAXDeclHandler
: &IID_ISAXDeclHandler
;
2767 case SAXLexicalHandler
:
2768 riid
= vb
? &IID_IVBSAXLexicalHandler
: &IID_ISAXLexicalHandler
;
2771 ERR("wrong handler type %d\n", type
);
2780 IUnknown
*handler
= NULL
;
2784 HRESULT hr
= IUnknown_QueryInterface(V_UNKNOWN(v
), riid
, (void**)&handler
);
2785 if (FAILED(hr
)) return hr
;
2788 saxreader_put_handler(This
, type
, handler
, vb
);
2789 if (handler
) IUnknown_Release(handler
);
2793 ERR("value type %d not supported\n", V_VT(v
));
2794 return E_INVALIDARG
;
2800 static HRESULT
internal_putProperty(
2808 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prop
), debugstr_variant(&value
));
2810 if (This
->isParsing
) return E_FAIL
;
2812 v
= V_VT(&value
) == (VT_VARIANT
|VT_BYREF
) ? V_VARIANTREF(&value
) : &value
;
2813 if(!memcmp(prop
, PropertyDeclHandlerW
, sizeof(PropertyDeclHandlerW
)))
2814 return saxreader_put_handler_from_variant(This
, SAXDeclHandler
, v
, vbInterface
);
2816 if(!memcmp(prop
, PropertyLexicalHandlerW
, sizeof(PropertyLexicalHandlerW
)))
2817 return saxreader_put_handler_from_variant(This
, SAXLexicalHandler
, v
, vbInterface
);
2819 if(!memcmp(prop
, PropertyMaxXMLSizeW
, sizeof(PropertyMaxXMLSizeW
)))
2821 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2822 FIXME("(%p)->(%s): max-xml-size unsupported\n", This
, debugstr_variant(v
));
2826 if(!memcmp(prop
, PropertyMaxElementDepthW
, sizeof(PropertyMaxElementDepthW
)))
2828 if (V_VT(v
) == VT_I4
&& V_I4(v
) == 0) return S_OK
;
2829 FIXME("(%p)->(%s): max-element-depth unsupported\n", This
, debugstr_variant(v
));
2833 FIXME("(%p)->(%s:%s): unsupported property\n", This
, debugstr_w(prop
), debugstr_variant(v
));
2835 if(!memcmp(prop
, PropertyCharsetW
, sizeof(PropertyCharsetW
)))
2838 if(!memcmp(prop
, PropertyDomNodeW
, sizeof(PropertyDomNodeW
)))
2841 if(!memcmp(prop
, PropertyInputSourceW
, sizeof(PropertyInputSourceW
)))
2844 if(!memcmp(prop
, PropertySchemaDeclHandlerW
, sizeof(PropertySchemaDeclHandlerW
)))
2847 if(!memcmp(prop
, PropertyXMLDeclEncodingW
, sizeof(PropertyXMLDeclEncodingW
)))
2850 if(!memcmp(prop
, PropertyXMLDeclStandaloneW
, sizeof(PropertyXMLDeclStandaloneW
)))
2853 if(!memcmp(prop
, PropertyXMLDeclVersionW
, sizeof(PropertyXMLDeclVersionW
)))
2856 return E_INVALIDARG
;
2859 static HRESULT
internal_getProperty(const saxreader
* This
, const WCHAR
*prop
, VARIANT
*value
, BOOL vb
)
2861 TRACE("(%p)->(%s)\n", This
, debugstr_w(prop
));
2863 if (!value
) return E_POINTER
;
2865 if (!memcmp(PropertyLexicalHandlerW
, prop
, sizeof(PropertyLexicalHandlerW
)))
2867 V_VT(value
) = VT_UNKNOWN
;
2868 saxreader_get_handler(This
, SAXLexicalHandler
, vb
, (void**)&V_UNKNOWN(value
));
2872 if (!memcmp(PropertyDeclHandlerW
, prop
, sizeof(PropertyDeclHandlerW
)))
2874 V_VT(value
) = VT_UNKNOWN
;
2875 saxreader_get_handler(This
, SAXDeclHandler
, vb
, (void**)&V_UNKNOWN(value
));
2879 if (!memcmp(PropertyXmlDeclVersionW
, prop
, sizeof(PropertyXmlDeclVersionW
)))
2881 V_VT(value
) = VT_BSTR
;
2882 V_BSTR(value
) = SysAllocString(This
->xmldecl_version
);
2886 FIXME("(%p)->(%s) unsupported property\n", This
, debugstr_w(prop
));
2891 /*** IVBSAXXMLReader interface ***/
2892 /*** IUnknown methods ***/
2893 static HRESULT WINAPI
saxxmlreader_QueryInterface(IVBSAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
2895 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2897 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
2901 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
2902 IsEqualGUID( riid
, &IID_IDispatch
) ||
2903 IsEqualGUID( riid
, &IID_IVBSAXXMLReader
))
2907 else if( IsEqualGUID( riid
, &IID_ISAXXMLReader
))
2909 *ppvObject
= &This
->ISAXXMLReader_iface
;
2911 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
2913 return *ppvObject
? S_OK
: E_NOINTERFACE
;
2917 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
2918 return E_NOINTERFACE
;
2921 IVBSAXXMLReader_AddRef( iface
);
2926 static ULONG WINAPI
saxxmlreader_AddRef(IVBSAXXMLReader
* iface
)
2928 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2929 TRACE("%p\n", This
);
2930 return InterlockedIncrement( &This
->ref
);
2933 static ULONG WINAPI
saxxmlreader_Release(
2934 IVBSAXXMLReader
* iface
)
2936 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2939 TRACE("%p\n", This
);
2941 ref
= InterlockedDecrement( &This
->ref
);
2946 for (i
= 0; i
< SAXHandler_Last
; i
++)
2948 struct saxanyhandler_iface
*saxiface
= &This
->saxhandlers
[i
].u
.anyhandler
;
2950 if (saxiface
->handler
)
2951 IUnknown_Release(saxiface
->handler
);
2953 if (saxiface
->vbhandler
)
2954 IUnknown_Release(saxiface
->vbhandler
);
2957 SysFreeString(This
->xmldecl_version
);
2958 free_bstr_pool(&This
->pool
);
2966 static HRESULT WINAPI
saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader
*iface
, UINT
* pctinfo
)
2968 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2969 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
2972 static HRESULT WINAPI
saxxmlreader_GetTypeInfo(
2973 IVBSAXXMLReader
*iface
,
2974 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2976 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2977 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
2978 iTInfo
, lcid
, ppTInfo
);
2981 static HRESULT WINAPI
saxxmlreader_GetIDsOfNames(
2982 IVBSAXXMLReader
*iface
,
2984 LPOLESTR
* rgszNames
,
2989 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
2990 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
2991 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
2994 static HRESULT WINAPI
saxxmlreader_Invoke(
2995 IVBSAXXMLReader
*iface
,
2996 DISPID dispIdMember
,
3000 DISPPARAMS
* pDispParams
,
3001 VARIANT
* pVarResult
,
3002 EXCEPINFO
* pExcepInfo
,
3005 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3006 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
3007 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3010 /*** IVBSAXXMLReader methods ***/
3011 static HRESULT WINAPI
saxxmlreader_getFeature(
3012 IVBSAXXMLReader
* iface
,
3014 VARIANT_BOOL
*value
)
3016 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3017 return ISAXXMLReader_getFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3020 static HRESULT WINAPI
saxxmlreader_putFeature(
3021 IVBSAXXMLReader
* iface
,
3025 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3026 return ISAXXMLReader_putFeature(&This
->ISAXXMLReader_iface
, feature_name
, value
);
3029 static HRESULT WINAPI
saxxmlreader_getProperty(
3030 IVBSAXXMLReader
* iface
,
3034 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3035 return internal_getProperty(This
, prop
, value
, TRUE
);
3038 static HRESULT WINAPI
saxxmlreader_putProperty(
3039 IVBSAXXMLReader
* iface
,
3043 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3044 return internal_putProperty(This
, pProp
, value
, TRUE
);
3047 static HRESULT WINAPI
saxxmlreader_get_entityResolver(
3048 IVBSAXXMLReader
* iface
,
3049 IVBSAXEntityResolver
**resolver
)
3051 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3052 return saxreader_get_handler(This
, SAXEntityResolver
, TRUE
, (void**)resolver
);
3055 static HRESULT WINAPI
saxxmlreader_put_entityResolver(
3056 IVBSAXXMLReader
* iface
,
3057 IVBSAXEntityResolver
*resolver
)
3059 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3060 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, TRUE
);
3063 static HRESULT WINAPI
saxxmlreader_get_contentHandler(
3064 IVBSAXXMLReader
* iface
,
3065 IVBSAXContentHandler
**handler
)
3067 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3068 return saxreader_get_handler(This
, SAXContentHandler
, TRUE
, (void**)handler
);
3071 static HRESULT WINAPI
saxxmlreader_put_contentHandler(
3072 IVBSAXXMLReader
* iface
,
3073 IVBSAXContentHandler
*handler
)
3075 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3076 return saxreader_put_handler(This
, SAXContentHandler
, handler
, TRUE
);
3079 static HRESULT WINAPI
saxxmlreader_get_dtdHandler(
3080 IVBSAXXMLReader
* iface
,
3081 IVBSAXDTDHandler
**handler
)
3083 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3084 return saxreader_get_handler(This
, SAXDTDHandler
, TRUE
, (void**)handler
);
3087 static HRESULT WINAPI
saxxmlreader_put_dtdHandler(
3088 IVBSAXXMLReader
* iface
,
3089 IVBSAXDTDHandler
*handler
)
3091 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3092 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, TRUE
);
3095 static HRESULT WINAPI
saxxmlreader_get_errorHandler(
3096 IVBSAXXMLReader
* iface
,
3097 IVBSAXErrorHandler
**handler
)
3099 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3100 return saxreader_get_handler(This
, SAXErrorHandler
, TRUE
, (void**)handler
);
3103 static HRESULT WINAPI
saxxmlreader_put_errorHandler(
3104 IVBSAXXMLReader
* iface
,
3105 IVBSAXErrorHandler
*handler
)
3107 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3108 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, TRUE
);
3111 static HRESULT WINAPI
saxxmlreader_get_baseURL(
3112 IVBSAXXMLReader
* iface
,
3115 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3117 FIXME("(%p)->(%p) stub\n", This
, pBaseUrl
);
3121 static HRESULT WINAPI
saxxmlreader_put_baseURL(
3122 IVBSAXXMLReader
* iface
,
3125 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3126 return ISAXXMLReader_putBaseURL(&This
->ISAXXMLReader_iface
, pBaseUrl
);
3129 static HRESULT WINAPI
saxxmlreader_get_secureBaseURL(
3130 IVBSAXXMLReader
* iface
,
3131 BSTR
*pSecureBaseUrl
)
3133 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3135 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3139 static HRESULT WINAPI
saxxmlreader_put_secureBaseURL(
3140 IVBSAXXMLReader
* iface
,
3143 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3144 return ISAXXMLReader_putSecureBaseURL(&This
->ISAXXMLReader_iface
, secureBaseUrl
);
3147 static HRESULT WINAPI
saxxmlreader_parse(
3148 IVBSAXXMLReader
* iface
,
3151 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3152 return internal_parse(This
, varInput
, TRUE
);
3155 static HRESULT WINAPI
saxxmlreader_parseURL(
3156 IVBSAXXMLReader
* iface
,
3159 saxreader
*This
= impl_from_IVBSAXXMLReader( iface
);
3160 return internal_parseURL(This
, url
, TRUE
);
3163 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl
=
3165 saxxmlreader_QueryInterface
,
3166 saxxmlreader_AddRef
,
3167 saxxmlreader_Release
,
3168 saxxmlreader_GetTypeInfoCount
,
3169 saxxmlreader_GetTypeInfo
,
3170 saxxmlreader_GetIDsOfNames
,
3171 saxxmlreader_Invoke
,
3172 saxxmlreader_getFeature
,
3173 saxxmlreader_putFeature
,
3174 saxxmlreader_getProperty
,
3175 saxxmlreader_putProperty
,
3176 saxxmlreader_get_entityResolver
,
3177 saxxmlreader_put_entityResolver
,
3178 saxxmlreader_get_contentHandler
,
3179 saxxmlreader_put_contentHandler
,
3180 saxxmlreader_get_dtdHandler
,
3181 saxxmlreader_put_dtdHandler
,
3182 saxxmlreader_get_errorHandler
,
3183 saxxmlreader_put_errorHandler
,
3184 saxxmlreader_get_baseURL
,
3185 saxxmlreader_put_baseURL
,
3186 saxxmlreader_get_secureBaseURL
,
3187 saxxmlreader_put_secureBaseURL
,
3189 saxxmlreader_parseURL
3192 /*** ISAXXMLReader interface ***/
3193 /*** IUnknown methods ***/
3194 static HRESULT WINAPI
isaxxmlreader_QueryInterface(ISAXXMLReader
* iface
, REFIID riid
, void **ppvObject
)
3196 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3197 return IVBSAXXMLReader_QueryInterface(&This
->IVBSAXXMLReader_iface
, riid
, ppvObject
);
3200 static ULONG WINAPI
isaxxmlreader_AddRef(ISAXXMLReader
* iface
)
3202 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3203 return IVBSAXXMLReader_AddRef(&This
->IVBSAXXMLReader_iface
);
3206 static ULONG WINAPI
isaxxmlreader_Release(ISAXXMLReader
* iface
)
3208 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3209 return IVBSAXXMLReader_Release(&This
->IVBSAXXMLReader_iface
);
3212 /*** ISAXXMLReader methods ***/
3213 static HRESULT WINAPI
isaxxmlreader_getFeature(
3214 ISAXXMLReader
* iface
,
3215 const WCHAR
*feature_name
,
3216 VARIANT_BOOL
*value
)
3218 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3219 saxreader_feature feature
;
3221 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(feature_name
), value
);
3223 feature
= get_saxreader_feature(feature_name
);
3225 if (This
->version
< MSXML4
&& feature
== ExhaustiveErrors
)
3226 return E_INVALIDARG
;
3228 if (feature
== Namespaces
||
3229 feature
== NamespacePrefixes
||
3230 feature
== ExhaustiveErrors
)
3231 return get_feature_value(This
, feature
, value
);
3233 FIXME("(%p)->(%s %p) stub\n", This
, debugstr_w(feature_name
), value
);
3237 static HRESULT WINAPI
isaxxmlreader_putFeature(
3238 ISAXXMLReader
* iface
,
3239 const WCHAR
*feature_name
,
3242 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3243 saxreader_feature feature
;
3245 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(feature_name
), value
);
3247 feature
= get_saxreader_feature(feature_name
);
3249 /* accepted cases */
3250 if ((feature
== ExhaustiveErrors
&& value
== VARIANT_FALSE
) ||
3251 feature
== Namespaces
||
3252 feature
== NamespacePrefixes
)
3254 return set_feature_value(This
, feature
, value
);
3257 if (feature
== LexicalHandlerParEntities
||
3258 feature
== ProhibitDTD
||
3259 feature
== ExternalGeneralEntities
||
3260 feature
== ExternalParameterEntities
)
3262 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3263 return set_feature_value(This
, feature
, value
);
3266 FIXME("(%p)->(%s %x) stub\n", This
, debugstr_w(feature_name
), value
);
3270 static HRESULT WINAPI
isaxxmlreader_getProperty(
3271 ISAXXMLReader
* iface
,
3275 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3276 return internal_getProperty(This
, prop
, value
, FALSE
);
3279 static HRESULT WINAPI
isaxxmlreader_putProperty(
3280 ISAXXMLReader
* iface
,
3284 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3285 return internal_putProperty(This
, pProp
, value
, FALSE
);
3288 static HRESULT WINAPI
isaxxmlreader_getEntityResolver(
3289 ISAXXMLReader
* iface
,
3290 ISAXEntityResolver
**resolver
)
3292 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3293 return saxreader_get_handler(This
, SAXEntityResolver
, FALSE
, (void**)resolver
);
3296 static HRESULT WINAPI
isaxxmlreader_putEntityResolver(
3297 ISAXXMLReader
* iface
,
3298 ISAXEntityResolver
*resolver
)
3300 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3301 return saxreader_put_handler(This
, SAXEntityResolver
, resolver
, FALSE
);
3304 static HRESULT WINAPI
isaxxmlreader_getContentHandler(
3305 ISAXXMLReader
* iface
,
3306 ISAXContentHandler
**handler
)
3308 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3309 return saxreader_get_handler(This
, SAXContentHandler
, FALSE
, (void**)handler
);
3312 static HRESULT WINAPI
isaxxmlreader_putContentHandler(
3313 ISAXXMLReader
* iface
,
3314 ISAXContentHandler
*handler
)
3316 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3317 return saxreader_put_handler(This
, SAXContentHandler
, handler
, FALSE
);
3320 static HRESULT WINAPI
isaxxmlreader_getDTDHandler(
3321 ISAXXMLReader
* iface
,
3322 ISAXDTDHandler
**handler
)
3324 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3325 return saxreader_get_handler(This
, SAXDTDHandler
, FALSE
, (void**)handler
);
3328 static HRESULT WINAPI
isaxxmlreader_putDTDHandler(
3329 ISAXXMLReader
* iface
,
3330 ISAXDTDHandler
*handler
)
3332 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3333 return saxreader_put_handler(This
, SAXDTDHandler
, handler
, FALSE
);
3336 static HRESULT WINAPI
isaxxmlreader_getErrorHandler(
3337 ISAXXMLReader
* iface
,
3338 ISAXErrorHandler
**handler
)
3340 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3341 return saxreader_get_handler(This
, SAXErrorHandler
, FALSE
, (void**)handler
);
3344 static HRESULT WINAPI
isaxxmlreader_putErrorHandler(ISAXXMLReader
* iface
, ISAXErrorHandler
*handler
)
3346 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3347 return saxreader_put_handler(This
, SAXErrorHandler
, handler
, FALSE
);
3350 static HRESULT WINAPI
isaxxmlreader_getBaseURL(
3351 ISAXXMLReader
* iface
,
3352 const WCHAR
**base_url
)
3354 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3356 FIXME("(%p)->(%p) stub\n", This
, base_url
);
3360 static HRESULT WINAPI
isaxxmlreader_putBaseURL(
3361 ISAXXMLReader
* iface
,
3362 const WCHAR
*pBaseUrl
)
3364 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3366 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(pBaseUrl
));
3370 static HRESULT WINAPI
isaxxmlreader_getSecureBaseURL(
3371 ISAXXMLReader
* iface
,
3372 const WCHAR
**pSecureBaseUrl
)
3374 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3375 FIXME("(%p)->(%p) stub\n", This
, pSecureBaseUrl
);
3379 static HRESULT WINAPI
isaxxmlreader_putSecureBaseURL(
3380 ISAXXMLReader
* iface
,
3381 const WCHAR
*secureBaseUrl
)
3383 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3385 FIXME("(%p)->(%s) stub\n", This
, debugstr_w(secureBaseUrl
));
3389 static HRESULT WINAPI
isaxxmlreader_parse(
3390 ISAXXMLReader
* iface
,
3393 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3394 return internal_parse(This
, varInput
, FALSE
);
3397 static HRESULT WINAPI
isaxxmlreader_parseURL(
3398 ISAXXMLReader
* iface
,
3401 saxreader
*This
= impl_from_ISAXXMLReader( iface
);
3402 return internal_parseURL(This
, url
, FALSE
);
3405 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl
=
3407 isaxxmlreader_QueryInterface
,
3408 isaxxmlreader_AddRef
,
3409 isaxxmlreader_Release
,
3410 isaxxmlreader_getFeature
,
3411 isaxxmlreader_putFeature
,
3412 isaxxmlreader_getProperty
,
3413 isaxxmlreader_putProperty
,
3414 isaxxmlreader_getEntityResolver
,
3415 isaxxmlreader_putEntityResolver
,
3416 isaxxmlreader_getContentHandler
,
3417 isaxxmlreader_putContentHandler
,
3418 isaxxmlreader_getDTDHandler
,
3419 isaxxmlreader_putDTDHandler
,
3420 isaxxmlreader_getErrorHandler
,
3421 isaxxmlreader_putErrorHandler
,
3422 isaxxmlreader_getBaseURL
,
3423 isaxxmlreader_putBaseURL
,
3424 isaxxmlreader_getSecureBaseURL
,
3425 isaxxmlreader_putSecureBaseURL
,
3426 isaxxmlreader_parse
,
3427 isaxxmlreader_parseURL
3430 static const tid_t saxreader_iface_tids
[] = {
3431 IVBSAXXMLReader_tid
,
3434 static dispex_static_data_t saxreader_dispex
= {
3436 IVBSAXXMLReader_tid
,
3438 saxreader_iface_tids
3441 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3445 TRACE("(%p)\n", ppObj
);
3447 reader
= heap_alloc( sizeof (*reader
) );
3449 return E_OUTOFMEMORY
;
3451 reader
->IVBSAXXMLReader_iface
.lpVtbl
= &VBSAXXMLReaderVtbl
;
3452 reader
->ISAXXMLReader_iface
.lpVtbl
= &SAXXMLReaderVtbl
;
3454 memset(reader
->saxhandlers
, 0, sizeof(reader
->saxhandlers
));
3455 reader
->isParsing
= FALSE
;
3456 reader
->xmldecl_version
= NULL
;
3457 reader
->pool
.pool
= NULL
;
3458 reader
->pool
.index
= 0;
3459 reader
->pool
.len
= 0;
3460 reader
->features
= Namespaces
| NamespacePrefixes
;
3461 reader
->version
= version
;
3463 init_dispex(&reader
->dispex
, (IUnknown
*)&reader
->IVBSAXXMLReader_iface
, &saxreader_dispex
);
3465 memset(&reader
->sax
, 0, sizeof(xmlSAXHandler
));
3466 reader
->sax
.initialized
= XML_SAX2_MAGIC
;
3467 reader
->sax
.startDocument
= libxmlStartDocument
;
3468 reader
->sax
.endDocument
= libxmlEndDocument
;
3469 reader
->sax
.startElementNs
= libxmlStartElementNS
;
3470 reader
->sax
.endElementNs
= libxmlEndElementNS
;
3471 reader
->sax
.characters
= libxmlCharacters
;
3472 reader
->sax
.setDocumentLocator
= libxmlSetDocumentLocator
;
3473 reader
->sax
.comment
= libxmlComment
;
3474 reader
->sax
.error
= libxmlFatalError
;
3475 reader
->sax
.fatalError
= libxmlFatalError
;
3476 reader
->sax
.cdataBlock
= libxml_cdatablock
;
3477 reader
->sax
.resolveEntity
= libxmlresolveentity
;
3479 *ppObj
= &reader
->IVBSAXXMLReader_iface
;
3481 TRACE("returning iface %p\n", *ppObj
);
3488 HRESULT
SAXXMLReader_create(MSXML_VERSION version
, LPVOID
*ppObj
)
3490 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3491 "libxml2 support was not present at compile time.\n");