user32/tests: Test MDI child order changing caused by WM_MDINEXT.
[wine/multimedia.git] / dlls / msxml3 / saxreader.c
blob5a0b1c287431296db430fed5e4f06d2d0f7cfb85
1 /*
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 COBJMACROS
23 #include "config.h"
25 #include <stdarg.h>
26 #ifdef HAVE_LIBXML2
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
29 # include <libxml/SAX2.h>
30 # include <libxml/parserInternals.h>
31 #endif
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winuser.h"
36 #include "winnls.h"
37 #include "ole2.h"
38 #include "msxml6.h"
39 #include "wininet.h"
40 #include "urlmon.h"
41 #include "winreg.h"
42 #include "shlwapi.h"
44 #include "wine/debug.h"
45 #include "wine/list.h"
47 #include "msxml_private.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
51 #ifdef HAVE_LIBXML2
53 typedef enum
55 FeatureUnknown = 0,
56 ExhaustiveErrors = 1 << 1,
57 ExternalGeneralEntities = 1 << 2,
58 ExternalParameterEntities = 1 << 3,
59 ForcedResync = 1 << 4,
60 NamespacePrefixes = 1 << 5,
61 Namespaces = 1 << 6,
62 ParameterEntities = 1 << 7,
63 PreserveSystemIndentifiers = 1 << 8,
64 ProhibitDTD = 1 << 9,
65 SchemaValidation = 1 << 10,
66 ServerHttpRequest = 1 << 11,
67 SuppressValidationfatalError = 1 << 12,
68 UseInlineSchema = 1 << 13,
69 UseSchemaLocation = 1 << 14,
70 LexicalHandlerParEntities = 1 << 15
71 } saxreader_feature;
73 /* feature names */
74 static const WCHAR FeatureExternalGeneralEntitiesW[] = {
75 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/',
76 'f','e','a','t','u','r','e','s','/','e','x','t','e','r','n','a','l','-','g','e','n','e','r','a','l',
77 '-','e','n','t','i','t','i','e','s',0
80 static const WCHAR FeatureExternalParameterEntitiesW[] = {
81 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
82 '/','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
85 static const WCHAR FeatureLexicalHandlerParEntitiesW[] = {
86 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
87 '/','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
90 static const WCHAR FeatureProhibitDTDW[] = {
91 'p','r','o','h','i','b','i','t','-','d','t','d',0
94 static const WCHAR FeatureNamespacesW[] = {
95 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
96 '/','n','a','m','e','s','p','a','c','e','s',0
99 static const WCHAR FeatureNamespacePrefixesW[] = {
100 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
101 '/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0
104 struct saxreader_feature_pair
106 saxreader_feature feature;
107 const WCHAR *name;
110 static const struct saxreader_feature_pair saxreader_feature_map[] = {
111 { ExternalGeneralEntities, FeatureExternalGeneralEntitiesW },
112 { ExternalParameterEntities, FeatureExternalParameterEntitiesW },
113 { LexicalHandlerParEntities, FeatureLexicalHandlerParEntitiesW },
114 { NamespacePrefixes, FeatureNamespacePrefixesW },
115 { Namespaces, FeatureNamespacesW },
116 { ProhibitDTD, FeatureProhibitDTDW }
119 static saxreader_feature get_saxreader_feature(const WCHAR *name)
121 int min, max, n, c;
123 min = 0;
124 max = sizeof(saxreader_feature_map)/sizeof(struct saxreader_feature_pair) - 1;
126 while (min <= max)
128 n = (min+max)/2;
130 c = strcmpW(saxreader_feature_map[n].name, name);
131 if (!c)
132 return saxreader_feature_map[n].feature;
134 if (c > 0)
135 max = n-1;
136 else
137 min = n+1;
140 return FeatureUnknown;
143 struct bstrpool
145 BSTR *pool;
146 unsigned int index;
147 unsigned int len;
150 typedef struct
152 BSTR prefix;
153 BSTR uri;
154 } ns;
156 typedef struct
158 struct list entry;
159 BSTR prefix;
160 BSTR local;
161 BSTR qname;
162 ns *ns; /* namespaces defined in this particular element */
163 int ns_count;
164 } element_entry;
166 enum saxhandler_type
168 SAXContentHandler = 0,
169 SAXDeclHandler,
170 SAXDTDHandler,
171 SAXEntityResolver,
172 SAXErrorHandler,
173 SAXLexicalHandler,
174 SAXHandler_Last
177 struct saxanyhandler_iface
179 IUnknown *handler;
180 IUnknown *vbhandler;
183 struct saxcontenthandler_iface
185 ISAXContentHandler *handler;
186 IVBSAXContentHandler *vbhandler;
189 struct saxerrorhandler_iface
191 ISAXErrorHandler *handler;
192 IVBSAXErrorHandler *vbhandler;
195 struct saxlexicalhandler_iface
197 ISAXLexicalHandler *handler;
198 IVBSAXLexicalHandler *vbhandler;
201 struct saxentityresolver_iface
203 ISAXEntityResolver *handler;
204 IVBSAXEntityResolver *vbhandler;
207 struct saxhandler_iface
209 union {
210 struct saxcontenthandler_iface content;
211 struct saxentityresolver_iface entityresolver;
212 struct saxerrorhandler_iface error;
213 struct saxlexicalhandler_iface lexical;
214 struct saxanyhandler_iface anyhandler;
215 } u;
218 typedef struct
220 DispatchEx dispex;
221 IVBSAXXMLReader IVBSAXXMLReader_iface;
222 ISAXXMLReader ISAXXMLReader_iface;
223 LONG ref;
225 struct saxhandler_iface saxhandlers[SAXHandler_Last];
226 xmlSAXHandler sax;
227 BOOL isParsing;
228 struct bstrpool pool;
229 saxreader_feature features;
230 BSTR xmldecl_version;
231 MSXML_VERSION version;
232 } saxreader;
234 static HRESULT saxreader_put_handler(saxreader *reader, enum saxhandler_type type, void *ptr, BOOL vb)
236 struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler;
237 IUnknown *unk = (IUnknown*)ptr;
239 if (unk)
240 IUnknown_AddRef(unk);
242 if ((vb && iface->vbhandler) || (!vb && iface->handler))
243 IUnknown_Release(vb ? iface->vbhandler : iface->handler);
245 if (vb)
246 iface->vbhandler = unk;
247 else
248 iface->handler = unk;
250 return S_OK;
253 static HRESULT saxreader_get_handler(const saxreader *reader, enum saxhandler_type type, BOOL vb, void **ret)
255 const struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler;
257 if (!ret) return E_POINTER;
259 if ((vb && iface->vbhandler) || (!vb && iface->handler))
261 if (vb)
262 IUnknown_AddRef(iface->vbhandler);
263 else
264 IUnknown_AddRef(iface->handler);
267 *ret = vb ? iface->vbhandler : iface->handler;
269 return S_OK;
272 static struct saxcontenthandler_iface *saxreader_get_contenthandler(saxreader *reader)
274 return &reader->saxhandlers[SAXContentHandler].u.content;
277 static struct saxerrorhandler_iface *saxreader_get_errorhandler(saxreader *reader)
279 return &reader->saxhandlers[SAXErrorHandler].u.error;
282 static struct saxlexicalhandler_iface *saxreader_get_lexicalhandler(saxreader *reader)
284 return &reader->saxhandlers[SAXLexicalHandler].u.lexical;
287 typedef struct
289 IVBSAXLocator IVBSAXLocator_iface;
290 ISAXLocator ISAXLocator_iface;
291 IVBSAXAttributes IVBSAXAttributes_iface;
292 ISAXAttributes ISAXAttributes_iface;
293 LONG ref;
294 saxreader *saxreader;
295 HRESULT ret;
296 xmlParserCtxtPtr pParserCtxt;
297 BSTR publicId;
298 BSTR systemId;
299 int line;
300 int column;
301 BOOL vbInterface;
302 struct list elements;
304 BSTR namespaceUri;
305 int attributesSize;
306 int nb_attributes;
307 struct _attributes
309 BSTR szLocalname;
310 BSTR szURI;
311 BSTR szValue;
312 BSTR szQName;
313 } *attributes;
314 } saxlocator;
316 static inline saxreader *impl_from_IVBSAXXMLReader( IVBSAXXMLReader *iface )
318 return CONTAINING_RECORD(iface, saxreader, IVBSAXXMLReader_iface);
321 static inline saxreader *impl_from_ISAXXMLReader( ISAXXMLReader *iface )
323 return CONTAINING_RECORD(iface, saxreader, ISAXXMLReader_iface);
326 static inline saxlocator *impl_from_IVBSAXLocator( IVBSAXLocator *iface )
328 return CONTAINING_RECORD(iface, saxlocator, IVBSAXLocator_iface);
331 static inline saxlocator *impl_from_ISAXLocator( ISAXLocator *iface )
333 return CONTAINING_RECORD(iface, saxlocator, ISAXLocator_iface);
336 static inline saxlocator *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
338 return CONTAINING_RECORD(iface, saxlocator, IVBSAXAttributes_iface);
341 static inline saxlocator *impl_from_ISAXAttributes( ISAXAttributes *iface )
343 return CONTAINING_RECORD(iface, saxlocator, ISAXAttributes_iface);
346 static inline int saxreader_has_handler(const saxlocator *locator, enum saxhandler_type type)
348 struct saxanyhandler_iface *iface = &locator->saxreader->saxhandlers[type].u.anyhandler;
349 return (locator->vbInterface && iface->vbhandler) || (!locator->vbInterface && iface->handler);
352 static HRESULT saxreader_saxcharacters(saxlocator *locator, BSTR chars)
354 struct saxcontenthandler_iface *content = saxreader_get_contenthandler(locator->saxreader);
355 HRESULT hr;
357 if (!saxreader_has_handler(locator, SAXContentHandler)) return S_OK;
359 if (locator->vbInterface)
360 hr = IVBSAXContentHandler_characters(content->vbhandler, &chars);
361 else
362 hr = ISAXContentHandler_characters(content->handler, chars, SysStringLen(chars));
364 return hr;
367 /* property names */
368 static const WCHAR PropertyCharsetW[] = {
369 'c','h','a','r','s','e','t',0
371 static const WCHAR PropertyXmlDeclVersionW[] = {
372 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
374 static const WCHAR PropertyDeclHandlerW[] = {
375 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
376 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
377 'd','e','c','l','a','r','a','t','i','o','n',
378 '-','h','a','n','d','l','e','r',0
380 static const WCHAR PropertyDomNodeW[] = {
381 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
382 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
383 'd','o','m','-','n','o','d','e',0
385 static const WCHAR PropertyInputSourceW[] = {
386 'i','n','p','u','t','-','s','o','u','r','c','e',0
388 static const WCHAR PropertyLexicalHandlerW[] = {
389 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
390 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
391 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
393 static const WCHAR PropertyMaxElementDepthW[] = {
394 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
396 static const WCHAR PropertyMaxXMLSizeW[] = {
397 'm','a','x','-','x','m','l','-','s','i','z','e',0
399 static const WCHAR PropertySchemaDeclHandlerW[] = {
400 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
401 'h','a','n','d','l','e','r',0
403 static const WCHAR PropertyXMLDeclEncodingW[] = {
404 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
406 static const WCHAR PropertyXMLDeclStandaloneW[] = {
407 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
409 static const WCHAR PropertyXMLDeclVersionW[] = {
410 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
413 static inline HRESULT set_feature_value(saxreader *reader, saxreader_feature feature, VARIANT_BOOL value)
415 /* handling of non-VARIANT_* values is version dependent */
416 if ((reader->version < MSXML4) && (value != VARIANT_TRUE))
417 value = VARIANT_FALSE;
418 if ((reader->version >= MSXML4) && (value != VARIANT_FALSE))
419 value = VARIANT_TRUE;
421 if (value == VARIANT_TRUE)
422 reader->features |= feature;
423 else
424 reader->features &= ~feature;
426 return S_OK;
429 static inline HRESULT get_feature_value(const saxreader *reader, saxreader_feature feature, VARIANT_BOOL *value)
431 *value = reader->features & feature ? VARIANT_TRUE : VARIANT_FALSE;
432 return S_OK;
435 static BOOL is_namespaces_enabled(const saxreader *reader)
437 return (reader->version < MSXML4) || (reader->features & Namespaces);
440 static BSTR build_qname(BSTR prefix, BSTR local)
442 if (prefix && *prefix)
444 BSTR qname = SysAllocStringLen(NULL, SysStringLen(prefix) + SysStringLen(local) + 1);
445 WCHAR *ptr;
447 ptr = qname;
448 strcpyW(ptr, prefix);
449 ptr += SysStringLen(prefix);
450 *ptr++ = ':';
451 strcpyW(ptr, local);
452 return qname;
454 else
455 return SysAllocString(local);
458 static element_entry* alloc_element_entry(const xmlChar *local, const xmlChar *prefix, int nb_ns,
459 const xmlChar **namespaces)
461 element_entry *ret;
462 int i;
464 ret = heap_alloc(sizeof(*ret));
465 if (!ret) return ret;
467 ret->local = bstr_from_xmlChar(local);
468 ret->prefix = bstr_from_xmlChar(prefix);
469 ret->qname = build_qname(ret->prefix, ret->local);
470 ret->ns = nb_ns ? heap_alloc(nb_ns*sizeof(ns)) : NULL;
471 ret->ns_count = nb_ns;
473 for (i=0; i < nb_ns; i++)
475 ret->ns[i].prefix = bstr_from_xmlChar(namespaces[2*i]);
476 ret->ns[i].uri = bstr_from_xmlChar(namespaces[2*i+1]);
479 return ret;
482 static void free_element_entry(element_entry *element)
484 int i;
486 for (i=0; i<element->ns_count;i++)
488 SysFreeString(element->ns[i].prefix);
489 SysFreeString(element->ns[i].uri);
492 SysFreeString(element->prefix);
493 SysFreeString(element->local);
495 heap_free(element->ns);
496 heap_free(element);
499 static void push_element_ns(saxlocator *locator, element_entry *element)
501 list_add_head(&locator->elements, &element->entry);
504 static element_entry * pop_element_ns(saxlocator *locator)
506 element_entry *element = LIST_ENTRY(list_head(&locator->elements), element_entry, entry);
508 if (element)
509 list_remove(&element->entry);
511 return element;
514 static BSTR find_element_uri(saxlocator *locator, const xmlChar *uri)
516 element_entry *element;
517 BSTR uriW;
518 int i;
520 if (!uri) return NULL;
522 uriW = bstr_from_xmlChar(uri);
524 LIST_FOR_EACH_ENTRY(element, &locator->elements, element_entry, entry)
526 for (i=0; i < element->ns_count; i++)
527 if (!strcmpW(uriW, element->ns[i].uri))
529 SysFreeString(uriW);
530 return element->ns[i].uri;
534 SysFreeString(uriW);
535 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri));
536 return NULL;
539 /* used to localize version dependent error check behaviour */
540 static inline BOOL sax_callback_failed(saxlocator *This, HRESULT hr)
542 return This->saxreader->version >= MSXML4 ? FAILED(hr) : hr != S_OK;
545 /* index value -1 means it tries to loop for a first time */
546 static inline BOOL iterate_endprefix_index(saxlocator *This, const element_entry *element, int *i)
548 if (This->saxreader->version >= MSXML4)
550 if (*i == -1) *i = 0; else ++*i;
551 return *i < element->ns_count;
553 else
555 if (*i == -1) *i = element->ns_count-1; else --*i;
556 return *i >= 0;
560 static BOOL bstr_pool_insert(struct bstrpool *pool, BSTR pool_entry)
562 if (!pool->pool)
564 pool->pool = HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(*pool->pool));
565 if (!pool->pool)
566 return FALSE;
568 pool->index = 0;
569 pool->len = 16;
571 else if (pool->index == pool->len)
573 BSTR *realloc = HeapReAlloc(GetProcessHeap(), 0, pool->pool, pool->len * 2 * sizeof(*realloc));
575 if (!realloc)
576 return FALSE;
578 pool->pool = realloc;
579 pool->len *= 2;
582 pool->pool[pool->index++] = pool_entry;
583 return TRUE;
586 static void free_bstr_pool(struct bstrpool *pool)
588 unsigned int i;
590 for (i = 0; i < pool->index; i++)
591 SysFreeString(pool->pool[i]);
593 HeapFree(GetProcessHeap(), 0, pool->pool);
595 pool->pool = NULL;
596 pool->index = pool->len = 0;
599 static BSTR bstr_from_xmlCharN(const xmlChar *buf, int len)
601 DWORD dLen;
602 BSTR bstr;
604 if (!buf)
605 return NULL;
607 dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0);
608 if(len != -1) dLen++;
609 bstr = SysAllocStringLen(NULL, dLen-1);
610 if (!bstr)
611 return NULL;
612 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, bstr, dLen);
613 if(len != -1) bstr[dLen-1] = '\0';
615 return bstr;
618 static BSTR QName_from_xmlChar(const xmlChar *prefix, const xmlChar *name)
620 xmlChar *qname;
621 BSTR bstr;
623 if(!name) return NULL;
625 if(!prefix || !*prefix)
626 return bstr_from_xmlChar(name);
628 qname = xmlBuildQName(name, prefix, NULL, 0);
629 bstr = bstr_from_xmlChar(qname);
630 xmlFree(qname);
632 return bstr;
635 static BSTR pooled_bstr_from_xmlChar(struct bstrpool *pool, const xmlChar *buf)
637 BSTR pool_entry = bstr_from_xmlChar(buf);
639 if (pool_entry && !bstr_pool_insert(pool, pool_entry))
641 SysFreeString(pool_entry);
642 return NULL;
645 return pool_entry;
648 static BSTR pooled_bstr_from_xmlCharN(struct bstrpool *pool, const xmlChar *buf, int len)
650 BSTR pool_entry = bstr_from_xmlCharN(buf, len);
652 if (pool_entry && !bstr_pool_insert(pool, pool_entry))
654 SysFreeString(pool_entry);
655 return NULL;
658 return pool_entry;
661 static void format_error_message_from_id(saxlocator *This, HRESULT hr)
663 struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader);
664 xmlStopParser(This->pParserCtxt);
665 This->ret = hr;
667 if (saxreader_has_handler(This, SAXErrorHandler))
669 WCHAR msg[1024];
670 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
671 NULL, hr, 0, msg, sizeof(msg), NULL))
673 FIXME("MSXML errors not yet supported.\n");
674 msg[0] = '\0';
677 if(This->vbInterface)
679 BSTR bstrMsg = SysAllocString(msg);
680 IVBSAXErrorHandler_fatalError(handler->vbhandler,
681 &This->IVBSAXLocator_iface, &bstrMsg, hr);
682 SysFreeString(bstrMsg);
684 else
685 ISAXErrorHandler_fatalError(handler->handler,
686 &This->ISAXLocator_iface, msg, hr);
690 static void update_position(saxlocator *This, BOOL fix_column)
692 const xmlChar *p = This->pParserCtxt->input->cur-1;
694 This->line = xmlSAX2GetLineNumber(This->pParserCtxt);
695 if(fix_column)
697 This->column = 1;
698 for(; *p!='\n' && *p!='\r' && p>=This->pParserCtxt->input->base; p--)
699 This->column++;
701 else
703 This->column = xmlSAX2GetColumnNumber(This->pParserCtxt);
707 /*** IVBSAXAttributes interface ***/
708 /*** IUnknown methods ***/
709 static HRESULT WINAPI ivbsaxattributes_QueryInterface(
710 IVBSAXAttributes* iface,
711 REFIID riid,
712 void **ppvObject)
714 saxlocator *This = impl_from_IVBSAXAttributes(iface);
715 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
716 return IVBSAXLocator_QueryInterface(&This->IVBSAXLocator_iface, riid, ppvObject);
719 static ULONG WINAPI ivbsaxattributes_AddRef(IVBSAXAttributes* iface)
721 saxlocator *This = impl_from_IVBSAXAttributes(iface);
722 return ISAXLocator_AddRef(&This->ISAXLocator_iface);
725 static ULONG WINAPI ivbsaxattributes_Release(IVBSAXAttributes* iface)
727 saxlocator *This = impl_from_IVBSAXAttributes(iface);
728 return ISAXLocator_Release(&This->ISAXLocator_iface);
731 /*** IDispatch methods ***/
732 static HRESULT WINAPI ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
734 saxlocator *This = impl_from_IVBSAXAttributes( iface );
736 TRACE("(%p)->(%p)\n", This, pctinfo);
738 *pctinfo = 1;
740 return S_OK;
743 static HRESULT WINAPI ivbsaxattributes_GetTypeInfo(
744 IVBSAXAttributes *iface,
745 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
747 saxlocator *This = impl_from_IVBSAXAttributes( iface );
748 HRESULT hr;
750 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
752 hr = get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
754 return hr;
757 static HRESULT WINAPI ivbsaxattributes_GetIDsOfNames(
758 IVBSAXAttributes *iface,
759 REFIID riid,
760 LPOLESTR* rgszNames,
761 UINT cNames,
762 LCID lcid,
763 DISPID* rgDispId)
765 saxlocator *This = impl_from_IVBSAXAttributes( iface );
766 ITypeInfo *typeinfo;
767 HRESULT hr;
769 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
770 lcid, rgDispId);
772 if(!rgszNames || cNames == 0 || !rgDispId)
773 return E_INVALIDARG;
775 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
776 if(SUCCEEDED(hr))
778 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
779 ITypeInfo_Release(typeinfo);
782 return hr;
785 static HRESULT WINAPI ivbsaxattributes_Invoke(
786 IVBSAXAttributes *iface,
787 DISPID dispIdMember,
788 REFIID riid,
789 LCID lcid,
790 WORD wFlags,
791 DISPPARAMS* pDispParams,
792 VARIANT* pVarResult,
793 EXCEPINFO* pExcepInfo,
794 UINT* puArgErr)
796 saxlocator *This = impl_from_IVBSAXAttributes( iface );
797 ITypeInfo *typeinfo;
798 HRESULT hr;
800 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
801 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
803 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
804 if(SUCCEEDED(hr))
806 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
807 pDispParams, pVarResult, pExcepInfo, puArgErr);
808 ITypeInfo_Release(typeinfo);
811 return hr;
814 /*** IVBSAXAttributes methods ***/
815 static HRESULT WINAPI ivbsaxattributes_get_length(
816 IVBSAXAttributes* iface,
817 int *nLength)
819 saxlocator *This = impl_from_IVBSAXAttributes( iface );
820 return ISAXAttributes_getLength(&This->ISAXAttributes_iface, nLength);
823 static HRESULT WINAPI ivbsaxattributes_getURI(
824 IVBSAXAttributes* iface,
825 int nIndex,
826 BSTR *uri)
828 int len;
829 saxlocator *This = impl_from_IVBSAXAttributes( iface );
830 return ISAXAttributes_getURI(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)uri, &len);
833 static HRESULT WINAPI ivbsaxattributes_getLocalName(
834 IVBSAXAttributes* iface,
835 int nIndex,
836 BSTR *localName)
838 int len;
839 saxlocator *This = impl_from_IVBSAXAttributes( iface );
840 return ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, nIndex,
841 (const WCHAR**)localName, &len);
844 static HRESULT WINAPI ivbsaxattributes_getQName(
845 IVBSAXAttributes* iface,
846 int nIndex,
847 BSTR *QName)
849 int len;
850 saxlocator *This = impl_from_IVBSAXAttributes( iface );
851 return ISAXAttributes_getQName(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)QName, &len);
854 static HRESULT WINAPI ivbsaxattributes_getIndexFromName(
855 IVBSAXAttributes* iface,
856 BSTR uri,
857 BSTR localName,
858 int *index)
860 saxlocator *This = impl_from_IVBSAXAttributes( iface );
861 return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
862 localName, SysStringLen(localName), index);
865 static HRESULT WINAPI ivbsaxattributes_getIndexFromQName(
866 IVBSAXAttributes* iface,
867 BSTR QName,
868 int *index)
870 saxlocator *This = impl_from_IVBSAXAttributes( iface );
871 return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, QName,
872 SysStringLen(QName), index);
875 static HRESULT WINAPI ivbsaxattributes_getType(
876 IVBSAXAttributes* iface,
877 int nIndex,
878 BSTR *type)
880 int len;
881 saxlocator *This = impl_from_IVBSAXAttributes( iface );
882 return ISAXAttributes_getType(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)type, &len);
885 static HRESULT WINAPI ivbsaxattributes_getTypeFromName(
886 IVBSAXAttributes* iface,
887 BSTR uri,
888 BSTR localName,
889 BSTR *type)
891 int len;
892 saxlocator *This = impl_from_IVBSAXAttributes( iface );
893 return ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
894 localName, SysStringLen(localName), (const WCHAR**)type, &len);
897 static HRESULT WINAPI ivbsaxattributes_getTypeFromQName(
898 IVBSAXAttributes* iface,
899 BSTR QName,
900 BSTR *type)
902 int len;
903 saxlocator *This = impl_from_IVBSAXAttributes( iface );
904 return ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, QName, SysStringLen(QName),
905 (const WCHAR**)type, &len);
908 static HRESULT WINAPI ivbsaxattributes_getValue(
909 IVBSAXAttributes* iface,
910 int nIndex,
911 BSTR *value)
913 int len;
914 saxlocator *This = impl_from_IVBSAXAttributes( iface );
915 return ISAXAttributes_getValue(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)value, &len);
918 static HRESULT WINAPI ivbsaxattributes_getValueFromName(
919 IVBSAXAttributes* iface,
920 BSTR uri,
921 BSTR localName,
922 BSTR *value)
924 int len;
925 saxlocator *This = impl_from_IVBSAXAttributes( iface );
926 return ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
927 localName, SysStringLen(localName), (const WCHAR**)value, &len);
930 static HRESULT WINAPI ivbsaxattributes_getValueFromQName(
931 IVBSAXAttributes* iface,
932 BSTR QName,
933 BSTR *value)
935 int len;
936 saxlocator *This = impl_from_IVBSAXAttributes( iface );
937 return ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, QName,
938 SysStringLen(QName), (const WCHAR**)value, &len);
941 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl =
943 ivbsaxattributes_QueryInterface,
944 ivbsaxattributes_AddRef,
945 ivbsaxattributes_Release,
946 ivbsaxattributes_GetTypeInfoCount,
947 ivbsaxattributes_GetTypeInfo,
948 ivbsaxattributes_GetIDsOfNames,
949 ivbsaxattributes_Invoke,
950 ivbsaxattributes_get_length,
951 ivbsaxattributes_getURI,
952 ivbsaxattributes_getLocalName,
953 ivbsaxattributes_getQName,
954 ivbsaxattributes_getIndexFromName,
955 ivbsaxattributes_getIndexFromQName,
956 ivbsaxattributes_getType,
957 ivbsaxattributes_getTypeFromName,
958 ivbsaxattributes_getTypeFromQName,
959 ivbsaxattributes_getValue,
960 ivbsaxattributes_getValueFromName,
961 ivbsaxattributes_getValueFromQName
964 /*** ISAXAttributes interface ***/
965 /*** IUnknown methods ***/
966 static HRESULT WINAPI isaxattributes_QueryInterface(
967 ISAXAttributes* iface,
968 REFIID riid,
969 void **ppvObject)
971 saxlocator *This = impl_from_ISAXAttributes(iface);
972 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
973 return ISAXLocator_QueryInterface(&This->ISAXLocator_iface, riid, ppvObject);
976 static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes* iface)
978 saxlocator *This = impl_from_ISAXAttributes(iface);
979 TRACE("%p\n", This);
980 return ISAXLocator_AddRef(&This->ISAXLocator_iface);
983 static ULONG WINAPI isaxattributes_Release(ISAXAttributes* iface)
985 saxlocator *This = impl_from_ISAXAttributes(iface);
987 TRACE("%p\n", This);
988 return ISAXLocator_Release(&This->ISAXLocator_iface);
991 /*** ISAXAttributes methods ***/
992 static HRESULT WINAPI isaxattributes_getLength(
993 ISAXAttributes* iface,
994 int *length)
996 saxlocator *This = impl_from_ISAXAttributes( iface );
998 *length = This->nb_attributes;
999 TRACE("Length set to %d\n", *length);
1000 return S_OK;
1003 static HRESULT WINAPI isaxattributes_getURI(
1004 ISAXAttributes* iface,
1005 int index,
1006 const WCHAR **url,
1007 int *size)
1009 saxlocator *This = impl_from_ISAXAttributes( iface );
1010 TRACE("(%p)->(%d)\n", This, index);
1012 if(index >= This->nb_attributes || index < 0) return E_INVALIDARG;
1013 if(!url || !size) return E_POINTER;
1015 *size = SysStringLen(This->attributes[index].szURI);
1016 *url = This->attributes[index].szURI;
1018 TRACE("(%s:%d)\n", debugstr_w(This->attributes[index].szURI), *size);
1020 return S_OK;
1023 static HRESULT WINAPI isaxattributes_getLocalName(
1024 ISAXAttributes* iface,
1025 int nIndex,
1026 const WCHAR **pLocalName,
1027 int *pLocalNameLength)
1029 saxlocator *This = impl_from_ISAXAttributes( iface );
1030 TRACE("(%p)->(%d)\n", This, nIndex);
1032 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
1033 if(!pLocalName || !pLocalNameLength) return E_POINTER;
1035 *pLocalNameLength = SysStringLen(This->attributes[nIndex].szLocalname);
1036 *pLocalName = This->attributes[nIndex].szLocalname;
1038 return S_OK;
1041 static HRESULT WINAPI isaxattributes_getQName(
1042 ISAXAttributes* iface,
1043 int nIndex,
1044 const WCHAR **pQName,
1045 int *pQNameLength)
1047 saxlocator *This = impl_from_ISAXAttributes( iface );
1048 TRACE("(%p)->(%d)\n", This, nIndex);
1050 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
1051 if(!pQName || !pQNameLength) return E_POINTER;
1053 *pQNameLength = SysStringLen(This->attributes[nIndex].szQName);
1054 *pQName = This->attributes[nIndex].szQName;
1056 return S_OK;
1059 static HRESULT WINAPI isaxattributes_getName(
1060 ISAXAttributes* iface,
1061 int index,
1062 const WCHAR **uri,
1063 int *pUriLength,
1064 const WCHAR **localName,
1065 int *pLocalNameSize,
1066 const WCHAR **QName,
1067 int *pQNameLength)
1069 saxlocator *This = impl_from_ISAXAttributes( iface );
1070 TRACE("(%p)->(%d)\n", This, index);
1072 if(index>=This->nb_attributes || index<0) return E_INVALIDARG;
1073 if(!uri || !pUriLength || !localName || !pLocalNameSize
1074 || !QName || !pQNameLength) return E_POINTER;
1076 *pUriLength = SysStringLen(This->attributes[index].szURI);
1077 *uri = This->attributes[index].szURI;
1078 *pLocalNameSize = SysStringLen(This->attributes[index].szLocalname);
1079 *localName = This->attributes[index].szLocalname;
1080 *pQNameLength = SysStringLen(This->attributes[index].szQName);
1081 *QName = This->attributes[index].szQName;
1083 TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*localName), debugstr_w(*QName));
1085 return S_OK;
1088 static HRESULT WINAPI isaxattributes_getIndexFromName(
1089 ISAXAttributes* iface,
1090 const WCHAR *pUri,
1091 int cUriLength,
1092 const WCHAR *pLocalName,
1093 int cocalNameLength,
1094 int *index)
1096 saxlocator *This = impl_from_ISAXAttributes( iface );
1097 int i;
1098 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), cUriLength,
1099 debugstr_w(pLocalName), cocalNameLength);
1101 if(!pUri || !pLocalName || !index) return E_POINTER;
1103 for(i=0; i<This->nb_attributes; i++)
1105 if(cUriLength!=SysStringLen(This->attributes[i].szURI)
1106 || cocalNameLength!=SysStringLen(This->attributes[i].szLocalname))
1107 continue;
1108 if(cUriLength && memcmp(pUri, This->attributes[i].szURI,
1109 sizeof(WCHAR)*cUriLength))
1110 continue;
1111 if(cocalNameLength && memcmp(pLocalName, This->attributes[i].szLocalname,
1112 sizeof(WCHAR)*cocalNameLength))
1113 continue;
1115 *index = i;
1116 return S_OK;
1119 return E_INVALIDARG;
1122 static HRESULT WINAPI isaxattributes_getIndexFromQName(
1123 ISAXAttributes* iface,
1124 const WCHAR *pQName,
1125 int nQNameLength,
1126 int *index)
1128 saxlocator *This = impl_from_ISAXAttributes( iface );
1129 int i;
1130 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQNameLength);
1132 if(!pQName || !index) return E_POINTER;
1133 if(!nQNameLength) return E_INVALIDARG;
1135 for(i=0; i<This->nb_attributes; i++)
1137 if(nQNameLength!=SysStringLen(This->attributes[i].szQName)) continue;
1138 if(memcmp(pQName, This->attributes[i].szQName, sizeof(WCHAR)*nQNameLength)) continue;
1140 *index = i;
1141 return S_OK;
1144 return E_INVALIDARG;
1147 static HRESULT WINAPI isaxattributes_getType(
1148 ISAXAttributes* iface,
1149 int nIndex,
1150 const WCHAR **pType,
1151 int *pTypeLength)
1153 saxlocator *This = impl_from_ISAXAttributes( iface );
1155 FIXME("(%p)->(%d) stub\n", This, nIndex);
1156 return E_NOTIMPL;
1159 static HRESULT WINAPI isaxattributes_getTypeFromName(
1160 ISAXAttributes* iface,
1161 const WCHAR *pUri,
1162 int nUri,
1163 const WCHAR *pLocalName,
1164 int nLocalName,
1165 const WCHAR **pType,
1166 int *nType)
1168 saxlocator *This = impl_from_ISAXAttributes( iface );
1170 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This, debugstr_w(pUri), nUri,
1171 debugstr_w(pLocalName), nLocalName);
1172 return E_NOTIMPL;
1175 static HRESULT WINAPI isaxattributes_getTypeFromQName(
1176 ISAXAttributes* iface,
1177 const WCHAR *pQName,
1178 int nQName,
1179 const WCHAR **pType,
1180 int *nType)
1182 saxlocator *This = impl_from_ISAXAttributes( iface );
1184 FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(pQName), nQName);
1185 return E_NOTIMPL;
1188 static HRESULT WINAPI isaxattributes_getValue(
1189 ISAXAttributes* iface,
1190 int index,
1191 const WCHAR **value,
1192 int *nValue)
1194 saxlocator *This = impl_from_ISAXAttributes( iface );
1195 TRACE("(%p)->(%d)\n", This, index);
1197 if(index>=This->nb_attributes || index<0) return E_INVALIDARG;
1198 if(!value || !nValue) return E_POINTER;
1200 *nValue = SysStringLen(This->attributes[index].szValue);
1201 *value = This->attributes[index].szValue;
1203 TRACE("(%s:%d)\n", debugstr_w(*value), *nValue);
1205 return S_OK;
1208 static HRESULT WINAPI isaxattributes_getValueFromName(
1209 ISAXAttributes* iface,
1210 const WCHAR *pUri,
1211 int nUri,
1212 const WCHAR *pLocalName,
1213 int nLocalName,
1214 const WCHAR **pValue,
1215 int *nValue)
1217 HRESULT hr;
1218 int index;
1219 saxlocator *This = impl_from_ISAXAttributes( iface );
1220 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), nUri,
1221 debugstr_w(pLocalName), nLocalName);
1223 hr = ISAXAttributes_getIndexFromName(iface,
1224 pUri, nUri, pLocalName, nLocalName, &index);
1225 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
1227 return hr;
1230 static HRESULT WINAPI isaxattributes_getValueFromQName(
1231 ISAXAttributes* iface,
1232 const WCHAR *pQName,
1233 int nQName,
1234 const WCHAR **pValue,
1235 int *nValue)
1237 HRESULT hr;
1238 int index;
1239 saxlocator *This = impl_from_ISAXAttributes( iface );
1240 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQName);
1242 hr = ISAXAttributes_getIndexFromQName(iface, pQName, nQName, &index);
1243 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
1245 return hr;
1248 static const struct ISAXAttributesVtbl isaxattributes_vtbl =
1250 isaxattributes_QueryInterface,
1251 isaxattributes_AddRef,
1252 isaxattributes_Release,
1253 isaxattributes_getLength,
1254 isaxattributes_getURI,
1255 isaxattributes_getLocalName,
1256 isaxattributes_getQName,
1257 isaxattributes_getName,
1258 isaxattributes_getIndexFromName,
1259 isaxattributes_getIndexFromQName,
1260 isaxattributes_getType,
1261 isaxattributes_getTypeFromName,
1262 isaxattributes_getTypeFromQName,
1263 isaxattributes_getValue,
1264 isaxattributes_getValueFromName,
1265 isaxattributes_getValueFromQName
1268 static HRESULT SAXAttributes_populate(saxlocator *locator,
1269 int nb_namespaces, const xmlChar **xmlNamespaces,
1270 int nb_attributes, const xmlChar **xmlAttributes)
1272 static const xmlChar xmlns[] = "xmlns";
1273 static const WCHAR xmlnsW[] = { 'x','m','l','n','s',0 };
1275 struct _attributes *attrs;
1276 int i;
1278 /* skip namespace definitions */
1279 if ((locator->saxreader->features & NamespacePrefixes) == 0)
1280 nb_namespaces = 0;
1282 locator->nb_attributes = nb_namespaces + nb_attributes;
1283 if(locator->nb_attributes > locator->attributesSize)
1285 attrs = heap_realloc(locator->attributes, sizeof(struct _attributes)*locator->nb_attributes*2);
1286 if(!attrs)
1288 locator->nb_attributes = 0;
1289 return E_OUTOFMEMORY;
1291 locator->attributes = attrs;
1293 else
1295 attrs = locator->attributes;
1298 for (i = 0; i < nb_namespaces; i++)
1300 attrs[nb_attributes+i].szLocalname = SysAllocStringLen(NULL, 0);
1301 attrs[nb_attributes+i].szURI = locator->namespaceUri;
1302 attrs[nb_attributes+i].szValue = bstr_from_xmlChar(xmlNamespaces[2*i+1]);
1303 if(!xmlNamespaces[2*i])
1304 attrs[nb_attributes+i].szQName = SysAllocString(xmlnsW);
1305 else
1306 attrs[nb_attributes+i].szQName = QName_from_xmlChar(xmlns, xmlNamespaces[2*i]);
1309 for (i = 0; i < nb_attributes; i++)
1311 static const xmlChar xmlA[] = "xml";
1313 if (xmlStrEqual(xmlAttributes[i*5+1], xmlA))
1314 attrs[i].szURI = bstr_from_xmlChar(xmlAttributes[i*5+2]);
1315 else
1316 /* that's an important feature to keep same uri pointer for every reported attribute */
1317 attrs[i].szURI = find_element_uri(locator, xmlAttributes[i*5+2]);
1319 attrs[i].szLocalname = bstr_from_xmlChar(xmlAttributes[i*5]);
1320 attrs[i].szValue = bstr_from_xmlCharN(xmlAttributes[i*5+3],
1321 xmlAttributes[i*5+4]-xmlAttributes[i*5+3]);
1322 attrs[i].szQName = QName_from_xmlChar(xmlAttributes[i*5+1],
1323 xmlAttributes[i*5]);
1326 return S_OK;
1329 /*** LibXML callbacks ***/
1330 static void libxmlStartDocument(void *ctx)
1332 saxlocator *This = ctx;
1333 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1334 HRESULT hr;
1336 if (This->saxreader->version >= MSXML4)
1338 const xmlChar *p = This->pParserCtxt->input->cur-1;
1339 update_position(This, FALSE);
1340 while(p>This->pParserCtxt->input->base && *p!='>')
1342 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1343 This->line--;
1344 p--;
1346 This->column = 0;
1347 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1348 This->column++;
1351 /* store version value, declaration has to contain version attribute */
1352 if (This->pParserCtxt->standalone != -1)
1354 SysFreeString(This->saxreader->xmldecl_version);
1355 This->saxreader->xmldecl_version = bstr_from_xmlChar(This->pParserCtxt->version);
1358 if (saxreader_has_handler(This, SAXContentHandler))
1360 if(This->vbInterface)
1361 hr = IVBSAXContentHandler_startDocument(handler->vbhandler);
1362 else
1363 hr = ISAXContentHandler_startDocument(handler->handler);
1365 if (sax_callback_failed(This, hr))
1366 format_error_message_from_id(This, hr);
1370 static void libxmlEndDocument(void *ctx)
1372 saxlocator *This = ctx;
1373 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1374 HRESULT hr;
1376 if (This->saxreader->version >= MSXML4) {
1377 update_position(This, FALSE);
1378 if(This->column > 1)
1379 This->line++;
1380 This->column = 0;
1381 } else {
1382 This->column = 0;
1383 This->line = 0;
1386 if(This->ret != S_OK) return;
1388 if (saxreader_has_handler(This, SAXContentHandler))
1390 if(This->vbInterface)
1391 hr = IVBSAXContentHandler_endDocument(handler->vbhandler);
1392 else
1393 hr = ISAXContentHandler_endDocument(handler->handler);
1395 if (sax_callback_failed(This, hr))
1396 format_error_message_from_id(This, hr);
1400 static void libxmlStartElementNS(
1401 void *ctx,
1402 const xmlChar *localname,
1403 const xmlChar *prefix,
1404 const xmlChar *URI,
1405 int nb_namespaces,
1406 const xmlChar **namespaces,
1407 int nb_attributes,
1408 int nb_defaulted,
1409 const xmlChar **attributes)
1411 saxlocator *This = ctx;
1412 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1413 element_entry *element;
1414 HRESULT hr = S_OK;
1415 BSTR uri;
1417 update_position(This, TRUE);
1418 if(*(This->pParserCtxt->input->cur) == '/')
1419 This->column++;
1420 if(This->saxreader->version < MSXML4)
1421 This->column++;
1423 element = alloc_element_entry(localname, prefix, nb_namespaces, namespaces);
1424 push_element_ns(This, element);
1426 if (is_namespaces_enabled(This->saxreader))
1428 int i;
1430 for (i = 0; i < nb_namespaces && saxreader_has_handler(This, SAXContentHandler); i++)
1432 if (This->vbInterface)
1433 hr = IVBSAXContentHandler_startPrefixMapping(
1434 handler->vbhandler,
1435 &element->ns[i].prefix,
1436 &element->ns[i].uri);
1437 else
1438 hr = ISAXContentHandler_startPrefixMapping(
1439 handler->handler,
1440 element->ns[i].prefix,
1441 SysStringLen(element->ns[i].prefix),
1442 element->ns[i].uri,
1443 SysStringLen(element->ns[i].uri));
1445 if (sax_callback_failed(This, hr))
1447 format_error_message_from_id(This, hr);
1448 return;
1453 uri = find_element_uri(This, URI);
1454 hr = SAXAttributes_populate(This, nb_namespaces, namespaces, nb_attributes, attributes);
1455 if (hr == S_OK && saxreader_has_handler(This, SAXContentHandler))
1457 BSTR local;
1459 if (is_namespaces_enabled(This->saxreader))
1460 local = element->local;
1461 else
1462 uri = local = NULL;
1464 if (This->vbInterface)
1465 hr = IVBSAXContentHandler_startElement(handler->vbhandler,
1466 &uri, &local, &element->qname, &This->IVBSAXAttributes_iface);
1467 else
1468 hr = ISAXContentHandler_startElement(handler->handler,
1469 uri, SysStringLen(uri),
1470 local, SysStringLen(local),
1471 element->qname, SysStringLen(element->qname),
1472 &This->ISAXAttributes_iface);
1474 if (sax_callback_failed(This, hr))
1475 format_error_message_from_id(This, hr);
1479 static void libxmlEndElementNS(
1480 void *ctx,
1481 const xmlChar *localname,
1482 const xmlChar *prefix,
1483 const xmlChar *URI)
1485 saxlocator *This = ctx;
1486 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1487 element_entry *element;
1488 const xmlChar *p;
1489 BSTR uri, local;
1490 HRESULT hr;
1492 update_position(This, FALSE);
1493 p = This->pParserCtxt->input->cur;
1495 if (This->saxreader->version >= MSXML4)
1497 p--;
1498 while(p>This->pParserCtxt->input->base && *p!='>')
1500 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1501 This->line--;
1502 p--;
1505 else if(*(p-1)!='>' || *(p-2)!='/')
1507 p--;
1508 while(p-2>=This->pParserCtxt->input->base
1509 && *(p-2)!='<' && *(p-1)!='/')
1511 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1512 This->line--;
1513 p--;
1516 This->column = 0;
1517 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1518 This->column++;
1520 uri = find_element_uri(This, URI);
1521 element = pop_element_ns(This);
1523 if (!saxreader_has_handler(This, SAXContentHandler))
1525 This->nb_attributes = 0;
1526 free_element_entry(element);
1527 return;
1530 if (is_namespaces_enabled(This->saxreader))
1531 local = element->local;
1532 else
1533 uri = local = NULL;
1535 if (This->vbInterface)
1536 hr = IVBSAXContentHandler_endElement(
1537 handler->vbhandler,
1538 &uri, &local, &element->qname);
1539 else
1540 hr = ISAXContentHandler_endElement(
1541 handler->handler,
1542 uri, SysStringLen(uri),
1543 local, SysStringLen(local),
1544 element->qname, SysStringLen(element->qname));
1546 This->nb_attributes = 0;
1548 if (sax_callback_failed(This, hr))
1550 format_error_message_from_id(This, hr);
1551 free_element_entry(element);
1552 return;
1555 if (is_namespaces_enabled(This->saxreader))
1557 int i = -1;
1558 while (iterate_endprefix_index(This, element, &i) && saxreader_has_handler(This, SAXContentHandler))
1560 if (This->vbInterface)
1561 hr = IVBSAXContentHandler_endPrefixMapping(
1562 handler->vbhandler, &element->ns[i].prefix);
1563 else
1564 hr = ISAXContentHandler_endPrefixMapping(
1565 handler->handler, element->ns[i].prefix, SysStringLen(element->ns[i].prefix));
1567 if (sax_callback_failed(This, hr)) break;
1570 if (sax_callback_failed(This, hr))
1571 format_error_message_from_id(This, hr);
1574 free_element_entry(element);
1577 static void libxmlCharacters(
1578 void *ctx,
1579 const xmlChar *ch,
1580 int len)
1582 saxlocator *This = ctx;
1583 BSTR Chars;
1584 HRESULT hr;
1585 xmlChar *cur, *end;
1586 BOOL lastEvent = FALSE;
1588 if (!saxreader_has_handler(This, SAXContentHandler)) return;
1590 update_position(This, FALSE);
1591 cur = (xmlChar*)This->pParserCtxt->input->cur;
1592 while(cur>=This->pParserCtxt->input->base && *cur!='>')
1594 if(*cur=='\n' || (*cur=='\r' && *(cur+1)!='\n'))
1595 This->line--;
1596 cur--;
1598 This->column = 1;
1599 for(; cur>=This->pParserCtxt->input->base && *cur!='\n' && *cur!='\r'; cur--)
1600 This->column++;
1602 cur = (xmlChar*)ch;
1603 if(*(ch-1)=='\r') cur--;
1604 end = cur;
1606 while(1)
1608 while(end-ch<len && *end!='\r') end++;
1609 if(end-ch==len)
1611 lastEvent = TRUE;
1613 else
1615 *end = '\n';
1616 end++;
1619 if (This->saxreader->version >= MSXML4)
1621 xmlChar *p;
1623 for(p=cur; p!=end; p++)
1625 if(*p=='\n')
1627 This->line++;
1628 This->column = 1;
1630 else
1632 This->column++;
1636 if(!lastEvent)
1637 This->column = 0;
1640 Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur);
1641 hr = saxreader_saxcharacters(This, Chars);
1643 if (sax_callback_failed(This, hr))
1645 format_error_message_from_id(This, hr);
1646 return;
1649 if (This->saxreader->version < MSXML4)
1650 This->column += end-cur;
1652 if(lastEvent)
1653 break;
1655 *(end-1) = '\r';
1656 if(*end == '\n')
1658 end++;
1659 This->column++;
1661 cur = end;
1663 if(end-ch == len) break;
1667 static void libxmlSetDocumentLocator(
1668 void *ctx,
1669 xmlSAXLocatorPtr loc)
1671 saxlocator *This = ctx;
1672 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1673 HRESULT hr = S_OK;
1675 if (saxreader_has_handler(This, SAXContentHandler))
1677 if(This->vbInterface)
1678 hr = IVBSAXContentHandler_putref_documentLocator(handler->vbhandler,
1679 &This->IVBSAXLocator_iface);
1680 else
1681 hr = ISAXContentHandler_putDocumentLocator(handler->handler, &This->ISAXLocator_iface);
1684 if(FAILED(hr))
1685 format_error_message_from_id(This, hr);
1688 static void libxmlComment(void *ctx, const xmlChar *value)
1690 saxlocator *This = ctx;
1691 struct saxlexicalhandler_iface *handler = saxreader_get_lexicalhandler(This->saxreader);
1692 BSTR bValue;
1693 HRESULT hr;
1694 const xmlChar *p = This->pParserCtxt->input->cur;
1696 update_position(This, FALSE);
1697 while(p-4>=This->pParserCtxt->input->base
1698 && memcmp(p-4, "<!--", sizeof(char[4])))
1700 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1701 This->line--;
1702 p--;
1705 This->column = 0;
1706 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1707 This->column++;
1709 if (!saxreader_has_handler(This, SAXLexicalHandler)) return;
1711 bValue = pooled_bstr_from_xmlChar(&This->saxreader->pool, value);
1713 if (This->vbInterface)
1714 hr = IVBSAXLexicalHandler_comment(handler->vbhandler, &bValue);
1715 else
1716 hr = ISAXLexicalHandler_comment(handler->handler, bValue, SysStringLen(bValue));
1718 if(FAILED(hr))
1719 format_error_message_from_id(This, hr);
1722 static void libxmlFatalError(void *ctx, const char *msg, ...)
1724 saxlocator *This = ctx;
1725 struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader);
1726 char message[1024];
1727 WCHAR *error;
1728 DWORD len;
1729 va_list args;
1731 if(This->ret != S_OK) {
1732 xmlStopParser(This->pParserCtxt);
1733 return;
1736 va_start(args, msg);
1737 vsprintf(message, msg, args);
1738 va_end(args);
1740 len = MultiByteToWideChar(CP_UNIXCP, 0, message, -1, NULL, 0);
1741 error = heap_alloc(sizeof(WCHAR)*len);
1742 if(error)
1744 MultiByteToWideChar(CP_UNIXCP, 0, message, -1, error, len);
1745 TRACE("fatal error for %p: %s\n", This, debugstr_w(error));
1748 if (!saxreader_has_handler(This, SAXErrorHandler))
1750 xmlStopParser(This->pParserCtxt);
1751 This->ret = E_FAIL;
1752 heap_free(error);
1753 return;
1756 FIXME("Error handling is not compatible.\n");
1758 if(This->vbInterface)
1760 BSTR bstrError = SysAllocString(error);
1761 IVBSAXErrorHandler_fatalError(handler->vbhandler, &This->IVBSAXLocator_iface,
1762 &bstrError, E_FAIL);
1763 SysFreeString(bstrError);
1765 else
1766 ISAXErrorHandler_fatalError(handler->handler, &This->ISAXLocator_iface, error, E_FAIL);
1768 heap_free(error);
1770 xmlStopParser(This->pParserCtxt);
1771 This->ret = E_FAIL;
1774 /* The only reason this helper exists is that CDATA section are reported by chunks,
1775 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1777 This helper should be called for substring with trailing newlines.
1779 static BSTR saxreader_get_cdata_chunk(const xmlChar *str, int len)
1781 BSTR bstr = bstr_from_xmlCharN(str, len), ret;
1782 WCHAR *ptr;
1784 ptr = bstr + len - 1;
1785 while ((*ptr == '\r' || *ptr == '\n') && ptr >= bstr)
1786 ptr--;
1788 while (*++ptr)
1790 /* replace returns as:
1792 - "\r<char>" -> "\n<char>"
1793 - "\r\r" -> "\r"
1794 - "\r\n" -> "\n"
1796 if (*ptr == '\r')
1798 if (*(ptr+1) == '\r' || *(ptr+1) == '\n')
1800 /* shift tail */
1801 memmove(ptr, ptr+1, len-- - (ptr-bstr));
1803 else
1804 *ptr = '\n';
1808 ret = SysAllocStringLen(bstr, len);
1809 SysFreeString(bstr);
1810 return ret;
1813 static void libxml_cdatablock(void *ctx, const xmlChar *value, int len)
1815 const xmlChar *start, *end;
1816 saxlocator *locator = ctx;
1817 struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(locator->saxreader);
1818 HRESULT hr = S_OK;
1819 BSTR chars;
1820 int i;
1822 update_position(locator, FALSE);
1823 if (saxreader_has_handler(locator, SAXLexicalHandler))
1825 if (locator->vbInterface)
1826 hr = IVBSAXLexicalHandler_startCDATA(lexical->vbhandler);
1827 else
1828 hr = ISAXLexicalHandler_startCDATA(lexical->handler);
1831 if(FAILED(hr))
1833 format_error_message_from_id(locator, hr);
1834 return;
1837 start = value;
1838 end = NULL;
1839 i = 0;
1841 while (i < len)
1843 /* scan for newlines */
1844 if (value[i] == '\r' || value[i] == '\n')
1846 /* skip newlines/linefeeds */
1847 while (i < len)
1849 if (value[i] != '\r' && value[i] != '\n') break;
1850 i++;
1852 end = &value[i];
1854 /* report */
1855 chars = saxreader_get_cdata_chunk(start, end-start);
1856 TRACE("(chunk %s)\n", debugstr_w(chars));
1857 hr = saxreader_saxcharacters(locator, chars);
1858 SysFreeString(chars);
1860 start = &value[i];
1861 end = NULL;
1863 i++;
1864 locator->column++;
1867 /* no newline chars (or last chunk) report as a whole */
1868 if (!end && start == value)
1870 /* report */
1871 chars = bstr_from_xmlCharN(start, len-(start-value));
1872 TRACE("(%s)\n", debugstr_w(chars));
1873 hr = saxreader_saxcharacters(locator, chars);
1874 SysFreeString(chars);
1877 if (saxreader_has_handler(locator, SAXLexicalHandler))
1879 if (locator->vbInterface)
1880 hr = IVBSAXLexicalHandler_endCDATA(lexical->vbhandler);
1881 else
1882 hr = ISAXLexicalHandler_endCDATA(lexical->handler);
1885 if(FAILED(hr))
1886 format_error_message_from_id(locator, hr);
1889 static xmlParserInputPtr libxmlresolveentity(void *ctx, const xmlChar *publicid, const xmlChar *systemid)
1891 FIXME("entity resolving not implemented, %s, %s\n", publicid, systemid);
1892 return xmlSAX2ResolveEntity(ctx, publicid, systemid);
1895 /*** IVBSAXLocator interface ***/
1896 /*** IUnknown methods ***/
1897 static HRESULT WINAPI ivbsaxlocator_QueryInterface(IVBSAXLocator* iface, REFIID riid, void **ppvObject)
1899 saxlocator *This = impl_from_IVBSAXLocator( iface );
1901 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject);
1903 *ppvObject = NULL;
1905 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
1906 IsEqualGUID( riid, &IID_IDispatch) ||
1907 IsEqualGUID( riid, &IID_IVBSAXLocator ))
1909 *ppvObject = iface;
1911 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
1913 *ppvObject = &This->IVBSAXAttributes_iface;
1915 else
1917 FIXME("interface %s not implemented\n", debugstr_guid(riid));
1918 return E_NOINTERFACE;
1921 IVBSAXLocator_AddRef( iface );
1923 return S_OK;
1926 static ULONG WINAPI ivbsaxlocator_AddRef(IVBSAXLocator* iface)
1928 saxlocator *This = impl_from_IVBSAXLocator( iface );
1929 TRACE("%p\n", This );
1930 return InterlockedIncrement( &This->ref );
1933 static ULONG WINAPI ivbsaxlocator_Release(
1934 IVBSAXLocator* iface)
1936 saxlocator *This = impl_from_IVBSAXLocator( iface );
1937 return ISAXLocator_Release((ISAXLocator*)&This->IVBSAXLocator_iface);
1940 /*** IDispatch methods ***/
1941 static HRESULT WINAPI ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator *iface, UINT* pctinfo )
1943 saxlocator *This = impl_from_IVBSAXLocator( iface );
1945 TRACE("(%p)->(%p)\n", This, pctinfo);
1947 *pctinfo = 1;
1949 return S_OK;
1952 static HRESULT WINAPI ivbsaxlocator_GetTypeInfo(
1953 IVBSAXLocator *iface,
1954 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
1956 saxlocator *This = impl_from_IVBSAXLocator( iface );
1957 HRESULT hr;
1959 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1961 hr = get_typeinfo(IVBSAXLocator_tid, ppTInfo);
1963 return hr;
1966 static HRESULT WINAPI ivbsaxlocator_GetIDsOfNames(
1967 IVBSAXLocator *iface,
1968 REFIID riid,
1969 LPOLESTR* rgszNames,
1970 UINT cNames,
1971 LCID lcid,
1972 DISPID* rgDispId)
1974 saxlocator *This = impl_from_IVBSAXLocator( iface );
1975 ITypeInfo *typeinfo;
1976 HRESULT hr;
1978 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1979 lcid, rgDispId);
1981 if(!rgszNames || cNames == 0 || !rgDispId)
1982 return E_INVALIDARG;
1984 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo);
1985 if(SUCCEEDED(hr))
1987 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1988 ITypeInfo_Release(typeinfo);
1991 return hr;
1994 static HRESULT WINAPI ivbsaxlocator_Invoke(
1995 IVBSAXLocator *iface,
1996 DISPID dispIdMember,
1997 REFIID riid,
1998 LCID lcid,
1999 WORD wFlags,
2000 DISPPARAMS* pDispParams,
2001 VARIANT* pVarResult,
2002 EXCEPINFO* pExcepInfo,
2003 UINT* puArgErr)
2005 saxlocator *This = impl_from_IVBSAXLocator( iface );
2006 ITypeInfo *typeinfo;
2007 HRESULT hr;
2009 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2010 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2012 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo);
2013 if(SUCCEEDED(hr))
2015 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXLocator_iface, dispIdMember, wFlags,
2016 pDispParams, pVarResult, pExcepInfo, puArgErr);
2017 ITypeInfo_Release(typeinfo);
2020 return hr;
2023 /*** IVBSAXLocator methods ***/
2024 static HRESULT WINAPI ivbsaxlocator_get_columnNumber(
2025 IVBSAXLocator* iface,
2026 int *pnColumn)
2028 saxlocator *This = impl_from_IVBSAXLocator( iface );
2029 return ISAXLocator_getColumnNumber((ISAXLocator*)&This->IVBSAXLocator_iface, pnColumn);
2032 static HRESULT WINAPI ivbsaxlocator_get_lineNumber(
2033 IVBSAXLocator* iface,
2034 int *pnLine)
2036 saxlocator *This = impl_from_IVBSAXLocator( iface );
2037 return ISAXLocator_getLineNumber((ISAXLocator*)&This->IVBSAXLocator_iface, pnLine);
2040 static HRESULT WINAPI ivbsaxlocator_get_publicId(
2041 IVBSAXLocator* iface,
2042 BSTR* publicId)
2044 saxlocator *This = impl_from_IVBSAXLocator( iface );
2045 return ISAXLocator_getPublicId((ISAXLocator*)&This->IVBSAXLocator_iface,
2046 (const WCHAR**)publicId);
2049 static HRESULT WINAPI ivbsaxlocator_get_systemId(
2050 IVBSAXLocator* iface,
2051 BSTR* systemId)
2053 saxlocator *This = impl_from_IVBSAXLocator( iface );
2054 return ISAXLocator_getSystemId((ISAXLocator*)&This->IVBSAXLocator_iface,
2055 (const WCHAR**)systemId);
2058 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl =
2060 ivbsaxlocator_QueryInterface,
2061 ivbsaxlocator_AddRef,
2062 ivbsaxlocator_Release,
2063 ivbsaxlocator_GetTypeInfoCount,
2064 ivbsaxlocator_GetTypeInfo,
2065 ivbsaxlocator_GetIDsOfNames,
2066 ivbsaxlocator_Invoke,
2067 ivbsaxlocator_get_columnNumber,
2068 ivbsaxlocator_get_lineNumber,
2069 ivbsaxlocator_get_publicId,
2070 ivbsaxlocator_get_systemId
2073 /*** ISAXLocator interface ***/
2074 /*** IUnknown methods ***/
2075 static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject)
2077 saxlocator *This = impl_from_ISAXLocator( iface );
2079 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
2081 *ppvObject = NULL;
2083 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2084 IsEqualGUID( riid, &IID_ISAXLocator ))
2086 *ppvObject = iface;
2088 else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
2090 *ppvObject = &This->ISAXAttributes_iface;
2092 else
2094 WARN("interface %s not implemented\n", debugstr_guid(riid));
2095 return E_NOINTERFACE;
2098 ISAXLocator_AddRef( iface );
2100 return S_OK;
2103 static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface)
2105 saxlocator *This = impl_from_ISAXLocator( iface );
2106 ULONG ref = InterlockedIncrement( &This->ref );
2107 TRACE("(%p)->(%d)\n", This, ref);
2108 return ref;
2111 static ULONG WINAPI isaxlocator_Release(
2112 ISAXLocator* iface)
2114 saxlocator *This = impl_from_ISAXLocator( iface );
2115 LONG ref = InterlockedDecrement( &This->ref );
2117 TRACE("(%p)->(%d)\n", This, ref );
2119 if (ref == 0)
2121 element_entry *element, *element2;
2122 int index;
2124 SysFreeString(This->publicId);
2125 SysFreeString(This->systemId);
2126 SysFreeString(This->namespaceUri);
2128 for(index=0; index<This->nb_attributes; index++)
2130 SysFreeString(This->attributes[index].szLocalname);
2131 SysFreeString(This->attributes[index].szValue);
2132 SysFreeString(This->attributes[index].szQName);
2134 heap_free(This->attributes);
2136 /* element stack */
2137 LIST_FOR_EACH_ENTRY_SAFE(element, element2, &This->elements, element_entry, entry)
2139 list_remove(&element->entry);
2140 free_element_entry(element);
2143 ISAXXMLReader_Release(&This->saxreader->ISAXXMLReader_iface);
2144 heap_free( This );
2147 return ref;
2150 /*** ISAXLocator methods ***/
2151 static HRESULT WINAPI isaxlocator_getColumnNumber(
2152 ISAXLocator* iface,
2153 int *pnColumn)
2155 saxlocator *This = impl_from_ISAXLocator( iface );
2157 *pnColumn = This->column;
2158 return S_OK;
2161 static HRESULT WINAPI isaxlocator_getLineNumber(
2162 ISAXLocator* iface,
2163 int *pnLine)
2165 saxlocator *This = impl_from_ISAXLocator( iface );
2167 *pnLine = This->line;
2168 return S_OK;
2171 static HRESULT WINAPI isaxlocator_getPublicId(
2172 ISAXLocator* iface,
2173 const WCHAR ** ppwchPublicId)
2175 BSTR publicId;
2176 saxlocator *This = impl_from_ISAXLocator( iface );
2178 SysFreeString(This->publicId);
2180 publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt));
2181 if(SysStringLen(publicId))
2182 This->publicId = publicId;
2183 else
2185 SysFreeString(publicId);
2186 This->publicId = NULL;
2189 *ppwchPublicId = This->publicId;
2190 return S_OK;
2193 static HRESULT WINAPI isaxlocator_getSystemId(
2194 ISAXLocator* iface,
2195 const WCHAR ** ppwchSystemId)
2197 BSTR systemId;
2198 saxlocator *This = impl_from_ISAXLocator( iface );
2200 SysFreeString(This->systemId);
2202 systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt));
2203 if(SysStringLen(systemId))
2204 This->systemId = systemId;
2205 else
2207 SysFreeString(systemId);
2208 This->systemId = NULL;
2211 *ppwchSystemId = This->systemId;
2212 return S_OK;
2215 static const struct ISAXLocatorVtbl SAXLocatorVtbl =
2217 isaxlocator_QueryInterface,
2218 isaxlocator_AddRef,
2219 isaxlocator_Release,
2220 isaxlocator_getColumnNumber,
2221 isaxlocator_getLineNumber,
2222 isaxlocator_getPublicId,
2223 isaxlocator_getSystemId
2226 static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator, BOOL vbInterface)
2228 static const WCHAR w3xmlns[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2229 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2231 saxlocator *locator;
2233 locator = heap_alloc( sizeof (*locator) );
2234 if( !locator )
2235 return E_OUTOFMEMORY;
2237 locator->IVBSAXLocator_iface.lpVtbl = &VBSAXLocatorVtbl;
2238 locator->ISAXLocator_iface.lpVtbl = &SAXLocatorVtbl;
2239 locator->IVBSAXAttributes_iface.lpVtbl = &ivbsaxattributes_vtbl;
2240 locator->ISAXAttributes_iface.lpVtbl = &isaxattributes_vtbl;
2241 locator->ref = 1;
2242 locator->vbInterface = vbInterface;
2244 locator->saxreader = reader;
2245 ISAXXMLReader_AddRef(&reader->ISAXXMLReader_iface);
2247 locator->pParserCtxt = NULL;
2248 locator->publicId = NULL;
2249 locator->systemId = NULL;
2250 locator->line = reader->version < MSXML4 ? 0 : 1;
2251 locator->column = 0;
2252 locator->ret = S_OK;
2253 if (locator->saxreader->version >= MSXML6)
2254 locator->namespaceUri = SysAllocString(w3xmlns);
2255 else
2256 locator->namespaceUri = SysAllocStringLen(NULL, 0);
2257 if(!locator->namespaceUri)
2259 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2260 heap_free(locator);
2261 return E_OUTOFMEMORY;
2264 locator->attributesSize = 8;
2265 locator->nb_attributes = 0;
2266 locator->attributes = heap_alloc(sizeof(struct _attributes)*locator->attributesSize);
2267 if(!locator->attributes)
2269 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2270 SysFreeString(locator->namespaceUri);
2271 heap_free(locator);
2272 return E_OUTOFMEMORY;
2275 list_init(&locator->elements);
2277 *ppsaxlocator = locator;
2279 TRACE("returning %p\n", *ppsaxlocator);
2281 return S_OK;
2284 /*** SAXXMLReader internal functions ***/
2285 static HRESULT internal_parseBuffer(saxreader *This, const char *buffer, int size, BOOL vbInterface)
2287 xmlCharEncoding encoding = XML_CHAR_ENCODING_NONE;
2288 xmlChar *enc_name = NULL;
2289 saxlocator *locator;
2290 HRESULT hr;
2292 TRACE("(%p)->(%p %d)\n", This, buffer, size);
2294 hr = SAXLocator_create(This, &locator, vbInterface);
2295 if (FAILED(hr))
2296 return hr;
2298 if (size >= 4)
2300 const unsigned char *buff = (unsigned char*)buffer;
2302 encoding = xmlDetectCharEncoding((xmlChar*)buffer, 4);
2303 enc_name = (xmlChar*)xmlGetCharEncodingName(encoding);
2304 TRACE("detected encoding: %s\n", enc_name);
2305 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2306 if ((encoding == XML_CHAR_ENCODING_UTF8) &&
2307 buff[0] == 0xEF && buff[1] == 0xBB && buff[2] == 0xBF)
2309 buffer += 3;
2310 size -= 3;
2314 /* if libxml2 detection failed try to guess */
2315 if (encoding == XML_CHAR_ENCODING_NONE)
2317 const WCHAR *ptr = (WCHAR*)buffer;
2318 /* xml declaration with possibly specfied encoding will be still handled by parser */
2319 if ((size >= 2) && *ptr == '<' && ptr[1] != '?')
2321 enc_name = (xmlChar*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE);
2322 encoding = XML_CHAR_ENCODING_UTF16LE;
2325 else if (encoding == XML_CHAR_ENCODING_UTF8)
2326 enc_name = (xmlChar*)xmlGetCharEncodingName(encoding);
2327 else
2328 enc_name = NULL;
2330 locator->pParserCtxt = xmlCreateMemoryParserCtxt(buffer, size);
2331 if (!locator->pParserCtxt)
2333 ISAXLocator_Release(&locator->ISAXLocator_iface);
2334 return E_FAIL;
2337 if (enc_name)
2339 locator->pParserCtxt->encoding = xmlStrdup(enc_name);
2340 if (encoding == XML_CHAR_ENCODING_UTF16LE) {
2341 TRACE("switching to %s\n", enc_name);
2342 xmlSwitchEncoding(locator->pParserCtxt, encoding);
2346 xmlFree(locator->pParserCtxt->sax);
2347 locator->pParserCtxt->sax = &locator->saxreader->sax;
2348 locator->pParserCtxt->userData = locator;
2350 This->isParsing = TRUE;
2351 if(xmlParseDocument(locator->pParserCtxt) == -1 && locator->ret == S_OK)
2352 hr = E_FAIL;
2353 else
2354 hr = locator->ret;
2355 This->isParsing = FALSE;
2357 if(locator->pParserCtxt)
2359 locator->pParserCtxt->sax = NULL;
2360 xmlFreeParserCtxt(locator->pParserCtxt);
2361 locator->pParserCtxt = NULL;
2364 ISAXLocator_Release(&locator->ISAXLocator_iface);
2365 return hr;
2368 static HRESULT internal_parseStream(saxreader *This, ISequentialStream *stream, BOOL vbInterface)
2370 saxlocator *locator;
2371 HRESULT hr;
2372 ULONG dataRead;
2373 char data[1024];
2374 int ret;
2376 dataRead = 0;
2377 hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead);
2378 if(FAILED(hr)) return hr;
2380 hr = SAXLocator_create(This, &locator, vbInterface);
2381 if(FAILED(hr)) return hr;
2383 locator->pParserCtxt = xmlCreatePushParserCtxt(
2384 &locator->saxreader->sax, locator,
2385 data, dataRead, NULL);
2386 if(!locator->pParserCtxt)
2388 ISAXLocator_Release(&locator->ISAXLocator_iface);
2389 return E_FAIL;
2392 This->isParsing = TRUE;
2394 if(dataRead != sizeof(data))
2396 ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
2397 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2399 else
2401 while(1)
2403 dataRead = 0;
2404 hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead);
2405 if (FAILED(hr)) break;
2407 ret = xmlParseChunk(locator->pParserCtxt, data, dataRead, 0);
2408 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2410 if (hr != S_OK) break;
2412 if (dataRead != sizeof(data))
2414 ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
2415 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2416 break;
2421 This->isParsing = FALSE;
2423 xmlFreeParserCtxt(locator->pParserCtxt);
2424 locator->pParserCtxt = NULL;
2425 ISAXLocator_Release(&locator->ISAXLocator_iface);
2426 return hr;
2429 static HRESULT internal_parse(
2430 saxreader* This,
2431 VARIANT varInput,
2432 BOOL vbInterface)
2434 HRESULT hr;
2436 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varInput));
2438 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2439 free_bstr_pool(&This->pool);
2441 switch(V_VT(&varInput))
2443 case VT_BSTR:
2444 hr = internal_parseBuffer(This, (const char*)V_BSTR(&varInput),
2445 strlenW(V_BSTR(&varInput))*sizeof(WCHAR), vbInterface);
2446 break;
2447 case VT_ARRAY|VT_UI1: {
2448 void *pSAData;
2449 LONG lBound, uBound;
2450 ULONG dataRead;
2452 hr = SafeArrayGetLBound(V_ARRAY(&varInput), 1, &lBound);
2453 if(hr != S_OK) break;
2454 hr = SafeArrayGetUBound(V_ARRAY(&varInput), 1, &uBound);
2455 if(hr != S_OK) break;
2456 dataRead = (uBound-lBound)*SafeArrayGetElemsize(V_ARRAY(&varInput));
2457 hr = SafeArrayAccessData(V_ARRAY(&varInput), &pSAData);
2458 if(hr != S_OK) break;
2459 hr = internal_parseBuffer(This, pSAData, dataRead, vbInterface);
2460 SafeArrayUnaccessData(V_ARRAY(&varInput));
2461 break;
2463 case VT_UNKNOWN:
2464 case VT_DISPATCH: {
2465 IPersistStream *persistStream;
2466 ISequentialStream *stream = NULL;
2467 IXMLDOMDocument *xmlDoc;
2469 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2470 &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK)
2472 BSTR bstrData;
2474 IXMLDOMDocument_get_xml(xmlDoc, &bstrData);
2475 hr = internal_parseBuffer(This, (const char*)bstrData,
2476 SysStringByteLen(bstrData), vbInterface);
2477 IXMLDOMDocument_Release(xmlDoc);
2478 SysFreeString(bstrData);
2479 break;
2482 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2483 &IID_IPersistStream, (void**)&persistStream) == S_OK)
2485 IStream *stream_copy;
2487 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream_copy);
2488 if(hr != S_OK)
2490 IPersistStream_Release(persistStream);
2491 return hr;
2494 hr = IPersistStream_Save(persistStream, stream_copy, TRUE);
2495 IPersistStream_Release(persistStream);
2496 if(hr == S_OK)
2497 IStream_QueryInterface(stream_copy, &IID_ISequentialStream, (void**)&stream);
2499 IStream_Release(stream_copy);
2502 /* try base interface first */
2503 if(!stream)
2505 IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_ISequentialStream, (void**)&stream);
2506 if (!stream)
2507 /* this should never happen if IStream is implemented properly, but just in case */
2508 IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream);
2511 if(stream)
2513 hr = internal_parseStream(This, stream, vbInterface);
2514 ISequentialStream_Release(stream);
2516 else
2518 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2519 hr = E_INVALIDARG;
2522 break;
2524 default:
2525 WARN("vt %d not implemented\n", V_VT(&varInput));
2526 hr = E_INVALIDARG;
2529 return hr;
2532 static HRESULT internal_vbonDataAvailable(void *obj, char *ptr, DWORD len)
2534 saxreader *This = obj;
2536 return internal_parseBuffer(This, ptr, len, TRUE);
2539 static HRESULT internal_onDataAvailable(void *obj, char *ptr, DWORD len)
2541 saxreader *This = obj;
2543 return internal_parseBuffer(This, ptr, len, FALSE);
2546 static HRESULT internal_parseURL(
2547 saxreader* This,
2548 const WCHAR *url,
2549 BOOL vbInterface)
2551 IMoniker *mon;
2552 bsc_t *bsc;
2553 HRESULT hr;
2555 TRACE("(%p)->(%s)\n", This, debugstr_w(url));
2557 hr = create_moniker_from_url(url, &mon);
2558 if(FAILED(hr))
2559 return hr;
2561 if(vbInterface) hr = bind_url(mon, internal_vbonDataAvailable, This, &bsc);
2562 else hr = bind_url(mon, internal_onDataAvailable, This, &bsc);
2563 IMoniker_Release(mon);
2565 if(FAILED(hr))
2566 return hr;
2568 return detach_bsc(bsc);
2571 static HRESULT internal_putProperty(
2572 saxreader* This,
2573 const WCHAR *prop,
2574 VARIANT value,
2575 BOOL vbInterface)
2577 TRACE("(%p)->(%s %s)\n", This, debugstr_w(prop), debugstr_variant(&value));
2579 if(!memcmp(prop, PropertyDeclHandlerW, sizeof(PropertyDeclHandlerW)))
2581 if(This->isParsing) return E_FAIL;
2583 switch (V_VT(&value))
2585 case VT_EMPTY:
2586 saxreader_put_handler(This, SAXDeclHandler, NULL, vbInterface);
2587 break;
2588 case VT_UNKNOWN:
2590 IUnknown *handler = NULL;
2592 if (V_UNKNOWN(&value))
2594 HRESULT hr;
2596 if (vbInterface)
2597 hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXDeclHandler, (void**)&handler);
2598 else
2599 hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_ISAXDeclHandler, (void**)&handler);
2600 if (FAILED(hr)) return hr;
2603 saxreader_put_handler(This, SAXDeclHandler, handler, vbInterface);
2604 if (handler) IUnknown_Release(handler);
2605 break;
2607 default:
2608 return E_INVALIDARG;
2611 return S_OK;
2614 if(!memcmp(prop, PropertyLexicalHandlerW, sizeof(PropertyLexicalHandlerW)))
2616 if(This->isParsing) return E_FAIL;
2618 switch (V_VT(&value))
2620 case VT_EMPTY:
2621 saxreader_put_handler(This, SAXLexicalHandler, NULL, vbInterface);
2622 break;
2623 case VT_UNKNOWN:
2625 IUnknown *handler = NULL;
2627 if (V_UNKNOWN(&value))
2629 HRESULT hr;
2631 if (vbInterface)
2632 hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXLexicalHandler, (void**)&handler);
2633 else
2634 hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_ISAXLexicalHandler, (void**)&handler);
2635 if (FAILED(hr)) return hr;
2638 saxreader_put_handler(This, SAXLexicalHandler, handler, vbInterface);
2639 if (handler) IUnknown_Release(handler);
2640 break;
2642 default:
2643 return E_INVALIDARG;
2646 return S_OK;
2649 if(!memcmp(prop, PropertyMaxXMLSizeW, sizeof(PropertyMaxXMLSizeW)))
2651 if (V_VT(&value) == VT_I4 && V_I4(&value) == 0) return S_OK;
2652 FIXME("(%p)->(%s): max-xml-size unsupported\n", This, debugstr_variant(&value));
2653 return E_NOTIMPL;
2656 if(!memcmp(prop, PropertyMaxElementDepthW, sizeof(PropertyMaxElementDepthW)))
2658 if (V_VT(&value) == VT_I4 && V_I4(&value) == 0) return S_OK;
2659 FIXME("(%p)->(%s): max-element-depth unsupported\n", This, debugstr_variant(&value));
2660 return E_NOTIMPL;
2663 FIXME("(%p)->(%s:%s): unsupported property\n", This, debugstr_w(prop), debugstr_variant(&value));
2665 if(!memcmp(prop, PropertyCharsetW, sizeof(PropertyCharsetW)))
2666 return E_NOTIMPL;
2668 if(!memcmp(prop, PropertyDomNodeW, sizeof(PropertyDomNodeW)))
2669 return E_FAIL;
2671 if(!memcmp(prop, PropertyInputSourceW, sizeof(PropertyInputSourceW)))
2672 return E_NOTIMPL;
2674 if(!memcmp(prop, PropertySchemaDeclHandlerW, sizeof(PropertySchemaDeclHandlerW)))
2675 return E_NOTIMPL;
2677 if(!memcmp(prop, PropertyXMLDeclEncodingW, sizeof(PropertyXMLDeclEncodingW)))
2678 return E_FAIL;
2680 if(!memcmp(prop, PropertyXMLDeclStandaloneW, sizeof(PropertyXMLDeclStandaloneW)))
2681 return E_FAIL;
2683 if(!memcmp(prop, PropertyXMLDeclVersionW, sizeof(PropertyXMLDeclVersionW)))
2684 return E_FAIL;
2686 return E_INVALIDARG;
2689 static HRESULT internal_getProperty(const saxreader* This, const WCHAR *prop, VARIANT *value, BOOL vb)
2691 TRACE("(%p)->(%s)\n", This, debugstr_w(prop));
2693 if (!value) return E_POINTER;
2695 if (!memcmp(PropertyLexicalHandlerW, prop, sizeof(PropertyLexicalHandlerW)))
2697 V_VT(value) = VT_UNKNOWN;
2698 saxreader_get_handler(This, SAXLexicalHandler, vb, (void**)&V_UNKNOWN(value));
2699 return S_OK;
2702 if (!memcmp(PropertyDeclHandlerW, prop, sizeof(PropertyDeclHandlerW)))
2704 V_VT(value) = VT_UNKNOWN;
2705 saxreader_get_handler(This, SAXDeclHandler, vb, (void**)&V_UNKNOWN(value));
2706 return S_OK;
2709 if (!memcmp(PropertyXmlDeclVersionW, prop, sizeof(PropertyXmlDeclVersionW)))
2711 V_VT(value) = VT_BSTR;
2712 V_BSTR(value) = SysAllocString(This->xmldecl_version);
2713 return S_OK;
2716 FIXME("(%p)->(%s) unsupported property\n", This, debugstr_w(prop));
2718 return E_NOTIMPL;
2721 /*** IVBSAXXMLReader interface ***/
2722 /*** IUnknown methods ***/
2723 static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject)
2725 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2727 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
2729 *ppvObject = NULL;
2731 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2732 IsEqualGUID( riid, &IID_IDispatch ) ||
2733 IsEqualGUID( riid, &IID_IVBSAXXMLReader ))
2735 *ppvObject = iface;
2737 else if( IsEqualGUID( riid, &IID_ISAXXMLReader ))
2739 *ppvObject = &This->ISAXXMLReader_iface;
2741 else if (dispex_query_interface(&This->dispex, riid, ppvObject))
2743 return *ppvObject ? S_OK : E_NOINTERFACE;
2745 else
2747 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2748 return E_NOINTERFACE;
2751 IVBSAXXMLReader_AddRef( iface );
2753 return S_OK;
2756 static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface)
2758 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2759 TRACE("%p\n", This );
2760 return InterlockedIncrement( &This->ref );
2763 static ULONG WINAPI saxxmlreader_Release(
2764 IVBSAXXMLReader* iface)
2766 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2767 LONG ref;
2769 TRACE("%p\n", This );
2771 ref = InterlockedDecrement( &This->ref );
2772 if ( ref == 0 )
2774 int i;
2776 for (i = 0; i < SAXHandler_Last; i++)
2778 struct saxanyhandler_iface *iface = &This->saxhandlers[i].u.anyhandler;
2780 if (iface->handler)
2781 IUnknown_Release(iface->handler);
2783 if (iface->vbhandler)
2784 IUnknown_Release(iface->vbhandler);
2787 SysFreeString(This->xmldecl_version);
2788 free_bstr_pool(&This->pool);
2790 release_dispex(&This->dispex);
2791 heap_free( This );
2794 return ref;
2796 /*** IDispatch ***/
2797 static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo )
2799 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2800 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2803 static HRESULT WINAPI saxxmlreader_GetTypeInfo(
2804 IVBSAXXMLReader *iface,
2805 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
2807 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2808 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
2809 iTInfo, lcid, ppTInfo);
2812 static HRESULT WINAPI saxxmlreader_GetIDsOfNames(
2813 IVBSAXXMLReader *iface,
2814 REFIID riid,
2815 LPOLESTR* rgszNames,
2816 UINT cNames,
2817 LCID lcid,
2818 DISPID* rgDispId)
2820 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2821 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2822 riid, rgszNames, cNames, lcid, rgDispId);
2825 static HRESULT WINAPI saxxmlreader_Invoke(
2826 IVBSAXXMLReader *iface,
2827 DISPID dispIdMember,
2828 REFIID riid,
2829 LCID lcid,
2830 WORD wFlags,
2831 DISPPARAMS* pDispParams,
2832 VARIANT* pVarResult,
2833 EXCEPINFO* pExcepInfo,
2834 UINT* puArgErr)
2836 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2837 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
2838 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2841 /*** IVBSAXXMLReader methods ***/
2842 static HRESULT WINAPI saxxmlreader_getFeature(
2843 IVBSAXXMLReader* iface,
2844 const WCHAR *feature_name,
2845 VARIANT_BOOL *value)
2847 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2848 saxreader_feature feature;
2850 TRACE("(%p)->(%s %p)\n", This, debugstr_w(feature_name), value);
2852 feature = get_saxreader_feature(feature_name);
2853 if (feature == Namespaces || feature == NamespacePrefixes)
2854 return get_feature_value(This, feature, value);
2856 FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(feature_name), value);
2857 return E_NOTIMPL;
2860 static HRESULT WINAPI saxxmlreader_putFeature(
2861 IVBSAXXMLReader* iface,
2862 const WCHAR *feature_name,
2863 VARIANT_BOOL value)
2865 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2866 saxreader_feature feature;
2868 TRACE("(%p)->(%s %x)\n", This, debugstr_w(feature_name), value);
2870 feature = get_saxreader_feature(feature_name);
2872 /* accepted cases */
2873 if ((feature == ExternalGeneralEntities && value == VARIANT_FALSE) ||
2874 (feature == ExternalParameterEntities && value == VARIANT_FALSE) ||
2875 feature == Namespaces ||
2876 feature == NamespacePrefixes)
2878 return set_feature_value(This, feature, value);
2881 if (feature == LexicalHandlerParEntities || feature == ProhibitDTD)
2883 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
2884 return set_feature_value(This, feature, value);
2887 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
2888 return E_NOTIMPL;
2891 static HRESULT WINAPI saxxmlreader_getProperty(
2892 IVBSAXXMLReader* iface,
2893 const WCHAR *prop,
2894 VARIANT *value)
2896 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2897 return internal_getProperty(This, prop, value, TRUE);
2900 static HRESULT WINAPI saxxmlreader_putProperty(
2901 IVBSAXXMLReader* iface,
2902 const WCHAR *pProp,
2903 VARIANT value)
2905 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2906 return internal_putProperty(This, pProp, value, TRUE);
2909 static HRESULT WINAPI saxxmlreader_get_entityResolver(
2910 IVBSAXXMLReader* iface,
2911 IVBSAXEntityResolver **resolver)
2913 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2914 return saxreader_get_handler(This, SAXEntityResolver, TRUE, (void**)resolver);
2917 static HRESULT WINAPI saxxmlreader_put_entityResolver(
2918 IVBSAXXMLReader* iface,
2919 IVBSAXEntityResolver *resolver)
2921 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2922 return saxreader_put_handler(This, SAXEntityResolver, resolver, TRUE);
2925 static HRESULT WINAPI saxxmlreader_get_contentHandler(
2926 IVBSAXXMLReader* iface,
2927 IVBSAXContentHandler **handler)
2929 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2930 return saxreader_get_handler(This, SAXContentHandler, TRUE, (void**)handler);
2933 static HRESULT WINAPI saxxmlreader_put_contentHandler(
2934 IVBSAXXMLReader* iface,
2935 IVBSAXContentHandler *handler)
2937 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2938 return saxreader_put_handler(This, SAXContentHandler, handler, TRUE);
2941 static HRESULT WINAPI saxxmlreader_get_dtdHandler(
2942 IVBSAXXMLReader* iface,
2943 IVBSAXDTDHandler **handler)
2945 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2946 return saxreader_get_handler(This, SAXDTDHandler, TRUE, (void**)handler);
2949 static HRESULT WINAPI saxxmlreader_put_dtdHandler(
2950 IVBSAXXMLReader* iface,
2951 IVBSAXDTDHandler *handler)
2953 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2954 return saxreader_put_handler(This, SAXDTDHandler, handler, TRUE);
2957 static HRESULT WINAPI saxxmlreader_get_errorHandler(
2958 IVBSAXXMLReader* iface,
2959 IVBSAXErrorHandler **handler)
2961 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2962 return saxreader_get_handler(This, SAXErrorHandler, TRUE, (void**)handler);
2965 static HRESULT WINAPI saxxmlreader_put_errorHandler(
2966 IVBSAXXMLReader* iface,
2967 IVBSAXErrorHandler *handler)
2969 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2970 return saxreader_put_handler(This, SAXErrorHandler, handler, TRUE);
2973 static HRESULT WINAPI saxxmlreader_get_baseURL(
2974 IVBSAXXMLReader* iface,
2975 const WCHAR **pBaseUrl)
2977 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2979 FIXME("(%p)->(%p) stub\n", This, pBaseUrl);
2980 return E_NOTIMPL;
2983 static HRESULT WINAPI saxxmlreader_put_baseURL(
2984 IVBSAXXMLReader* iface,
2985 const WCHAR *pBaseUrl)
2987 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2989 FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
2990 return E_NOTIMPL;
2993 static HRESULT WINAPI saxxmlreader_get_secureBaseURL(
2994 IVBSAXXMLReader* iface,
2995 const WCHAR **pSecureBaseUrl)
2997 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2999 FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
3000 return E_NOTIMPL;
3004 static HRESULT WINAPI saxxmlreader_put_secureBaseURL(
3005 IVBSAXXMLReader* iface,
3006 const WCHAR *secureBaseUrl)
3008 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3010 FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
3011 return E_NOTIMPL;
3014 static HRESULT WINAPI saxxmlreader_parse(
3015 IVBSAXXMLReader* iface,
3016 VARIANT varInput)
3018 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3019 return internal_parse(This, varInput, TRUE);
3022 static HRESULT WINAPI saxxmlreader_parseURL(
3023 IVBSAXXMLReader* iface,
3024 const WCHAR *url)
3026 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3027 return internal_parseURL(This, url, TRUE);
3030 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl =
3032 saxxmlreader_QueryInterface,
3033 saxxmlreader_AddRef,
3034 saxxmlreader_Release,
3035 saxxmlreader_GetTypeInfoCount,
3036 saxxmlreader_GetTypeInfo,
3037 saxxmlreader_GetIDsOfNames,
3038 saxxmlreader_Invoke,
3039 saxxmlreader_getFeature,
3040 saxxmlreader_putFeature,
3041 saxxmlreader_getProperty,
3042 saxxmlreader_putProperty,
3043 saxxmlreader_get_entityResolver,
3044 saxxmlreader_put_entityResolver,
3045 saxxmlreader_get_contentHandler,
3046 saxxmlreader_put_contentHandler,
3047 saxxmlreader_get_dtdHandler,
3048 saxxmlreader_put_dtdHandler,
3049 saxxmlreader_get_errorHandler,
3050 saxxmlreader_put_errorHandler,
3051 saxxmlreader_get_baseURL,
3052 saxxmlreader_put_baseURL,
3053 saxxmlreader_get_secureBaseURL,
3054 saxxmlreader_put_secureBaseURL,
3055 saxxmlreader_parse,
3056 saxxmlreader_parseURL
3059 /*** ISAXXMLReader interface ***/
3060 /*** IUnknown methods ***/
3061 static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject)
3063 saxreader *This = impl_from_ISAXXMLReader( iface );
3064 return saxxmlreader_QueryInterface(&This->IVBSAXXMLReader_iface, riid, ppvObject);
3067 static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface)
3069 saxreader *This = impl_from_ISAXXMLReader( iface );
3070 return saxxmlreader_AddRef(&This->IVBSAXXMLReader_iface);
3073 static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface)
3075 saxreader *This = impl_from_ISAXXMLReader( iface );
3076 return saxxmlreader_Release(&This->IVBSAXXMLReader_iface);
3079 /*** ISAXXMLReader methods ***/
3080 static HRESULT WINAPI isaxxmlreader_getFeature(
3081 ISAXXMLReader* iface,
3082 const WCHAR *pFeature,
3083 VARIANT_BOOL *pValue)
3085 saxreader *This = impl_from_ISAXXMLReader( iface );
3086 return IVBSAXXMLReader_getFeature(&This->IVBSAXXMLReader_iface, pFeature, pValue);
3089 static HRESULT WINAPI isaxxmlreader_putFeature(
3090 ISAXXMLReader* iface,
3091 const WCHAR *pFeature,
3092 VARIANT_BOOL vfValue)
3094 saxreader *This = impl_from_ISAXXMLReader( iface );
3095 return IVBSAXXMLReader_putFeature(&This->IVBSAXXMLReader_iface, pFeature, vfValue);
3098 static HRESULT WINAPI isaxxmlreader_getProperty(
3099 ISAXXMLReader* iface,
3100 const WCHAR *prop,
3101 VARIANT *value)
3103 saxreader *This = impl_from_ISAXXMLReader( iface );
3104 return internal_getProperty(This, prop, value, FALSE);
3107 static HRESULT WINAPI isaxxmlreader_putProperty(
3108 ISAXXMLReader* iface,
3109 const WCHAR *pProp,
3110 VARIANT value)
3112 saxreader *This = impl_from_ISAXXMLReader( iface );
3113 return internal_putProperty(This, pProp, value, FALSE);
3116 static HRESULT WINAPI isaxxmlreader_getEntityResolver(
3117 ISAXXMLReader* iface,
3118 ISAXEntityResolver **resolver)
3120 saxreader *This = impl_from_ISAXXMLReader( iface );
3121 return saxreader_get_handler(This, SAXEntityResolver, FALSE, (void**)resolver);
3124 static HRESULT WINAPI isaxxmlreader_putEntityResolver(
3125 ISAXXMLReader* iface,
3126 ISAXEntityResolver *resolver)
3128 saxreader *This = impl_from_ISAXXMLReader( iface );
3129 return saxreader_put_handler(This, SAXEntityResolver, resolver, FALSE);
3132 static HRESULT WINAPI isaxxmlreader_getContentHandler(
3133 ISAXXMLReader* iface,
3134 ISAXContentHandler **handler)
3136 saxreader *This = impl_from_ISAXXMLReader( iface );
3137 return saxreader_get_handler(This, SAXContentHandler, FALSE, (void**)handler);
3140 static HRESULT WINAPI isaxxmlreader_putContentHandler(
3141 ISAXXMLReader* iface,
3142 ISAXContentHandler *handler)
3144 saxreader *This = impl_from_ISAXXMLReader( iface );
3145 return saxreader_put_handler(This, SAXContentHandler, handler, FALSE);
3148 static HRESULT WINAPI isaxxmlreader_getDTDHandler(
3149 ISAXXMLReader* iface,
3150 ISAXDTDHandler **handler)
3152 saxreader *This = impl_from_ISAXXMLReader( iface );
3153 return saxreader_get_handler(This, SAXDTDHandler, FALSE, (void**)handler);
3156 static HRESULT WINAPI isaxxmlreader_putDTDHandler(
3157 ISAXXMLReader* iface,
3158 ISAXDTDHandler *handler)
3160 saxreader *This = impl_from_ISAXXMLReader( iface );
3161 return saxreader_put_handler(This, SAXDTDHandler, handler, FALSE);
3164 static HRESULT WINAPI isaxxmlreader_getErrorHandler(
3165 ISAXXMLReader* iface,
3166 ISAXErrorHandler **handler)
3168 saxreader *This = impl_from_ISAXXMLReader( iface );
3169 return saxreader_get_handler(This, SAXErrorHandler, FALSE, (void**)handler);
3172 static HRESULT WINAPI isaxxmlreader_putErrorHandler(ISAXXMLReader* iface, ISAXErrorHandler *handler)
3174 saxreader *This = impl_from_ISAXXMLReader( iface );
3175 return saxreader_put_handler(This, SAXErrorHandler, handler, FALSE);
3178 static HRESULT WINAPI isaxxmlreader_getBaseURL(
3179 ISAXXMLReader* iface,
3180 const WCHAR **pBaseUrl)
3182 saxreader *This = impl_from_ISAXXMLReader( iface );
3183 return IVBSAXXMLReader_get_baseURL(&This->IVBSAXXMLReader_iface, pBaseUrl);
3186 static HRESULT WINAPI isaxxmlreader_putBaseURL(
3187 ISAXXMLReader* iface,
3188 const WCHAR *pBaseUrl)
3190 saxreader *This = impl_from_ISAXXMLReader( iface );
3191 return IVBSAXXMLReader_put_baseURL(&This->IVBSAXXMLReader_iface, pBaseUrl);
3194 static HRESULT WINAPI isaxxmlreader_getSecureBaseURL(
3195 ISAXXMLReader* iface,
3196 const WCHAR **pSecureBaseUrl)
3198 saxreader *This = impl_from_ISAXXMLReader( iface );
3199 return IVBSAXXMLReader_get_secureBaseURL(&This->IVBSAXXMLReader_iface, pSecureBaseUrl);
3202 static HRESULT WINAPI isaxxmlreader_putSecureBaseURL(
3203 ISAXXMLReader* iface,
3204 const WCHAR *secureBaseUrl)
3206 saxreader *This = impl_from_ISAXXMLReader( iface );
3207 return IVBSAXXMLReader_put_secureBaseURL(&This->IVBSAXXMLReader_iface, secureBaseUrl);
3210 static HRESULT WINAPI isaxxmlreader_parse(
3211 ISAXXMLReader* iface,
3212 VARIANT varInput)
3214 saxreader *This = impl_from_ISAXXMLReader( iface );
3215 return internal_parse(This, varInput, FALSE);
3218 static HRESULT WINAPI isaxxmlreader_parseURL(
3219 ISAXXMLReader* iface,
3220 const WCHAR *url)
3222 saxreader *This = impl_from_ISAXXMLReader( iface );
3223 return internal_parseURL(This, url, FALSE);
3226 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl =
3228 isaxxmlreader_QueryInterface,
3229 isaxxmlreader_AddRef,
3230 isaxxmlreader_Release,
3231 isaxxmlreader_getFeature,
3232 isaxxmlreader_putFeature,
3233 isaxxmlreader_getProperty,
3234 isaxxmlreader_putProperty,
3235 isaxxmlreader_getEntityResolver,
3236 isaxxmlreader_putEntityResolver,
3237 isaxxmlreader_getContentHandler,
3238 isaxxmlreader_putContentHandler,
3239 isaxxmlreader_getDTDHandler,
3240 isaxxmlreader_putDTDHandler,
3241 isaxxmlreader_getErrorHandler,
3242 isaxxmlreader_putErrorHandler,
3243 isaxxmlreader_getBaseURL,
3244 isaxxmlreader_putBaseURL,
3245 isaxxmlreader_getSecureBaseURL,
3246 isaxxmlreader_putSecureBaseURL,
3247 isaxxmlreader_parse,
3248 isaxxmlreader_parseURL
3251 static const tid_t saxreader_iface_tids[] = {
3252 IVBSAXXMLReader_tid,
3255 static dispex_static_data_t saxreader_dispex = {
3256 NULL,
3257 IVBSAXXMLReader_tid,
3258 NULL,
3259 saxreader_iface_tids
3262 HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *outer, LPVOID *ppObj)
3264 saxreader *reader;
3266 TRACE("(%p, %p)\n", outer, ppObj);
3268 reader = heap_alloc( sizeof (*reader) );
3269 if( !reader )
3270 return E_OUTOFMEMORY;
3272 reader->IVBSAXXMLReader_iface.lpVtbl = &VBSAXXMLReaderVtbl;
3273 reader->ISAXXMLReader_iface.lpVtbl = &SAXXMLReaderVtbl;
3274 reader->ref = 1;
3275 memset(reader->saxhandlers, 0, sizeof(reader->saxhandlers));
3276 reader->isParsing = FALSE;
3277 reader->xmldecl_version = NULL;
3278 reader->pool.pool = NULL;
3279 reader->pool.index = 0;
3280 reader->pool.len = 0;
3281 reader->features = Namespaces | NamespacePrefixes;
3282 reader->version = version;
3284 init_dispex(&reader->dispex, (IUnknown*)&reader->IVBSAXXMLReader_iface, &saxreader_dispex);
3286 memset(&reader->sax, 0, sizeof(xmlSAXHandler));
3287 reader->sax.initialized = XML_SAX2_MAGIC;
3288 reader->sax.startDocument = libxmlStartDocument;
3289 reader->sax.endDocument = libxmlEndDocument;
3290 reader->sax.startElementNs = libxmlStartElementNS;
3291 reader->sax.endElementNs = libxmlEndElementNS;
3292 reader->sax.characters = libxmlCharacters;
3293 reader->sax.setDocumentLocator = libxmlSetDocumentLocator;
3294 reader->sax.comment = libxmlComment;
3295 reader->sax.error = libxmlFatalError;
3296 reader->sax.fatalError = libxmlFatalError;
3297 reader->sax.cdataBlock = libxml_cdatablock;
3298 reader->sax.resolveEntity = libxmlresolveentity;
3300 *ppObj = &reader->IVBSAXXMLReader_iface;
3302 TRACE("returning iface %p\n", *ppObj);
3304 return S_OK;
3307 #else
3309 HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *pUnkOuter, LPVOID *ppObj)
3311 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3312 "libxml2 support was not present at compile time.\n");
3313 return E_NOTIMPL;
3316 #endif