msxml3: Implement a common way to store and get callback interface pointers.
[wine.git] / dlls / msxml3 / saxreader.c
blobbdfdcab7ad18fdecae7c7fecc3e35b30ea25a61a
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 SAXErrorHandler,
172 SAXLexicalHandler,
173 SAXHandler_Last
176 struct saxhandler_iface
178 IUnknown *handler;
179 IUnknown *vbhandler;
182 struct saxcontenthandler_iface
184 ISAXContentHandler *handler;
185 IVBSAXContentHandler *vbhandler;
188 struct saxerrorhandler_iface
190 ISAXErrorHandler *handler;
191 IVBSAXErrorHandler *vbhandler;
194 struct saxlexicalhandler_iface
196 ISAXLexicalHandler *handler;
197 IVBSAXLexicalHandler *vbhandler;
200 typedef struct
202 DispatchEx dispex;
203 IVBSAXXMLReader IVBSAXXMLReader_iface;
204 ISAXXMLReader ISAXXMLReader_iface;
205 LONG ref;
207 struct saxhandler_iface saxhandlers[SAXHandler_Last];
208 xmlSAXHandler sax;
209 BOOL isParsing;
210 struct bstrpool pool;
211 saxreader_feature features;
212 MSXML_VERSION version;
213 } saxreader;
215 static HRESULT saxreader_put_handler(saxreader *reader, enum saxhandler_type type, void *ptr, BOOL vb)
217 struct saxhandler_iface *iface = &reader->saxhandlers[type];
218 IUnknown *unk = (IUnknown*)ptr;
220 if (unk)
221 IUnknown_AddRef(unk);
223 if ((vb && iface->vbhandler) || (!vb && iface->handler))
224 IUnknown_Release(vb ? iface->vbhandler : iface->handler);
226 if (vb)
227 iface->vbhandler = unk;
228 else
229 iface->handler = unk;
231 return S_OK;
234 static HRESULT saxreader_get_handler(const saxreader *reader, enum saxhandler_type type, BOOL vb, void **ret)
236 const struct saxhandler_iface *iface = &reader->saxhandlers[type];
238 if (!ret) return E_POINTER;
240 if ((vb && iface->vbhandler) || (!vb && iface->handler))
242 if (vb)
243 IUnknown_AddRef(iface->vbhandler);
244 else
245 IUnknown_AddRef(iface->handler);
248 *ret = vb ? iface->vbhandler : iface->handler;
250 return S_OK;
253 static struct saxcontenthandler_iface *saxreader_get_contenthandler(saxreader *reader)
255 return (struct saxcontenthandler_iface*)&reader->saxhandlers[SAXContentHandler];
258 static struct saxerrorhandler_iface *saxreader_get_errorhandler(saxreader *reader)
260 return (struct saxerrorhandler_iface*)&reader->saxhandlers[SAXErrorHandler];
263 static struct saxlexicalhandler_iface *saxreader_get_lexicalhandler(saxreader *reader)
265 return (struct saxlexicalhandler_iface*)&reader->saxhandlers[SAXLexicalHandler];
268 typedef struct
270 IVBSAXLocator IVBSAXLocator_iface;
271 ISAXLocator ISAXLocator_iface;
272 IVBSAXAttributes IVBSAXAttributes_iface;
273 ISAXAttributes ISAXAttributes_iface;
274 LONG ref;
275 saxreader *saxreader;
276 HRESULT ret;
277 xmlParserCtxtPtr pParserCtxt;
278 WCHAR *publicId;
279 WCHAR *systemId;
280 int line;
281 int column;
282 BOOL vbInterface;
283 struct list elements;
285 BSTR namespaceUri;
286 int attributesSize;
287 int nb_attributes;
288 struct _attributes
290 BSTR szLocalname;
291 BSTR szURI;
292 BSTR szValue;
293 BSTR szQName;
294 } *attributes;
295 } saxlocator;
297 static inline saxreader *impl_from_IVBSAXXMLReader( IVBSAXXMLReader *iface )
299 return CONTAINING_RECORD(iface, saxreader, IVBSAXXMLReader_iface);
302 static inline saxreader *impl_from_ISAXXMLReader( ISAXXMLReader *iface )
304 return CONTAINING_RECORD(iface, saxreader, ISAXXMLReader_iface);
307 static inline saxlocator *impl_from_IVBSAXLocator( IVBSAXLocator *iface )
309 return CONTAINING_RECORD(iface, saxlocator, IVBSAXLocator_iface);
312 static inline saxlocator *impl_from_ISAXLocator( ISAXLocator *iface )
314 return CONTAINING_RECORD(iface, saxlocator, ISAXLocator_iface);
317 static inline saxlocator *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
319 return CONTAINING_RECORD(iface, saxlocator, IVBSAXAttributes_iface);
322 static inline saxlocator *impl_from_ISAXAttributes( ISAXAttributes *iface )
324 return CONTAINING_RECORD(iface, saxlocator, ISAXAttributes_iface);
327 /* property names */
328 static const WCHAR PropertyCharsetW[] = {
329 'c','h','a','r','s','e','t',0
331 static const WCHAR PropertyDeclHandlerW[] = {
332 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
333 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
334 'd','e','c','l','a','r','a','t','i','o','n',
335 '-','h','a','n','d','l','e','r',0
337 static const WCHAR PropertyDomNodeW[] = {
338 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
339 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
340 'd','o','m','-','n','o','d','e',0
342 static const WCHAR PropertyInputSourceW[] = {
343 'i','n','p','u','t','-','s','o','u','r','c','e',0
345 static const WCHAR PropertyLexicalHandlerW[] = {
346 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
347 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
348 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
350 static const WCHAR PropertyMaxElementDepthW[] = {
351 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
353 static const WCHAR PropertyMaxXMLSizeW[] = {
354 'm','a','x','-','x','m','l','-','s','i','z','e',0
356 static const WCHAR PropertySchemaDeclHandlerW[] = {
357 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
358 'h','a','n','d','l','e','r',0
360 static const WCHAR PropertyXMLDeclEncodingW[] = {
361 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
363 static const WCHAR PropertyXMLDeclStandaloneW[] = {
364 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
366 static const WCHAR PropertyXMLDeclVersionW[] = {
367 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
370 static inline HRESULT set_feature_value(saxreader *reader, saxreader_feature feature, VARIANT_BOOL value)
372 /* handling of non-VARIANT_* values is version dependent */
373 if ((reader->version < MSXML4) && (value != VARIANT_TRUE))
374 value = VARIANT_FALSE;
375 if ((reader->version >= MSXML4) && (value != VARIANT_FALSE))
376 value = VARIANT_TRUE;
378 if (value == VARIANT_TRUE)
379 reader->features |= feature;
380 else
381 reader->features &= ~feature;
383 return S_OK;
386 static inline HRESULT get_feature_value(const saxreader *reader, saxreader_feature feature, VARIANT_BOOL *value)
388 *value = reader->features & feature ? VARIANT_TRUE : VARIANT_FALSE;
389 return S_OK;
392 static BOOL is_namespaces_enabled(const saxreader *reader)
394 return (reader->version < MSXML4) || (reader->features & Namespaces);
397 static inline int has_content_handler(const saxlocator *locator)
399 return (locator->vbInterface && locator->saxreader->saxhandlers[SAXContentHandler].vbhandler) ||
400 (!locator->vbInterface && locator->saxreader->saxhandlers[SAXContentHandler].handler);
403 static inline int has_lexical_handler(const saxlocator *locator)
405 return (locator->vbInterface && locator->saxreader->saxhandlers[SAXLexicalHandler].vbhandler) ||
406 (!locator->vbInterface && locator->saxreader->saxhandlers[SAXLexicalHandler].handler);
409 static inline int has_error_handler(const saxlocator *locator)
411 return (locator->vbInterface && locator->saxreader->saxhandlers[SAXErrorHandler].vbhandler) ||
412 (!locator->vbInterface && locator->saxreader->saxhandlers[SAXErrorHandler].handler);
415 static BSTR build_qname(BSTR prefix, BSTR local)
417 if (prefix && *prefix)
419 BSTR qname = SysAllocStringLen(NULL, SysStringLen(prefix) + SysStringLen(local) + 1);
420 WCHAR *ptr;
422 ptr = qname;
423 strcpyW(ptr, prefix);
424 ptr += SysStringLen(prefix);
425 *ptr++ = ':';
426 strcpyW(ptr, local);
427 return qname;
429 else
430 return SysAllocString(local);
433 static element_entry* alloc_element_entry(const xmlChar *local, const xmlChar *prefix, int nb_ns,
434 const xmlChar **namespaces)
436 element_entry *ret;
437 int i;
439 ret = heap_alloc(sizeof(*ret));
440 if (!ret) return ret;
442 ret->local = bstr_from_xmlChar(local);
443 ret->prefix = bstr_from_xmlChar(prefix);
444 ret->qname = build_qname(ret->prefix, ret->local);
445 ret->ns = nb_ns ? heap_alloc(nb_ns*sizeof(ns)) : NULL;
446 ret->ns_count = nb_ns;
448 for (i=0; i < nb_ns; i++)
450 ret->ns[i].prefix = bstr_from_xmlChar(namespaces[2*i]);
451 ret->ns[i].uri = bstr_from_xmlChar(namespaces[2*i+1]);
454 return ret;
457 static void free_element_entry(element_entry *element)
459 int i;
461 for (i=0; i<element->ns_count;i++)
463 SysFreeString(element->ns[i].prefix);
464 SysFreeString(element->ns[i].uri);
467 SysFreeString(element->prefix);
468 SysFreeString(element->local);
470 heap_free(element->ns);
471 heap_free(element);
474 static void push_element_ns(saxlocator *locator, element_entry *element)
476 list_add_head(&locator->elements, &element->entry);
479 static element_entry * pop_element_ns(saxlocator *locator)
481 element_entry *element = LIST_ENTRY(list_head(&locator->elements), element_entry, entry);
483 if (element)
484 list_remove(&element->entry);
486 return element;
489 static BSTR find_element_uri(saxlocator *locator, const xmlChar *uri)
491 element_entry *element;
492 BSTR uriW;
493 int i;
495 if (!uri) return NULL;
497 uriW = bstr_from_xmlChar(uri);
499 LIST_FOR_EACH_ENTRY(element, &locator->elements, element_entry, entry)
501 for (i=0; i < element->ns_count; i++)
502 if (!strcmpW(uriW, element->ns[i].uri))
504 SysFreeString(uriW);
505 return element->ns[i].uri;
509 SysFreeString(uriW);
510 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri));
511 return NULL;
514 /* used to localize version dependent error check behaviour */
515 static inline BOOL sax_callback_failed(saxlocator *This, HRESULT hr)
517 return This->saxreader->version >= MSXML4 ? FAILED(hr) : hr != S_OK;
520 /* index value -1 means it tries to loop for a first time */
521 static inline BOOL iterate_endprefix_index(saxlocator *This, const element_entry *element, int *i)
523 if (This->saxreader->version >= MSXML4)
525 if (*i == -1) *i = 0; else ++*i;
526 return *i < element->ns_count;
528 else
530 if (*i == -1) *i = element->ns_count-1; else --*i;
531 return *i >= 0;
535 static BOOL bstr_pool_insert(struct bstrpool *pool, BSTR pool_entry)
537 if (!pool->pool)
539 pool->pool = HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(*pool->pool));
540 if (!pool->pool)
541 return FALSE;
543 pool->index = 0;
544 pool->len = 16;
546 else if (pool->index == pool->len)
548 BSTR *realloc = HeapReAlloc(GetProcessHeap(), 0, pool->pool, pool->len * 2 * sizeof(*realloc));
550 if (!realloc)
551 return FALSE;
553 pool->pool = realloc;
554 pool->len *= 2;
557 pool->pool[pool->index++] = pool_entry;
558 return TRUE;
561 static void free_bstr_pool(struct bstrpool *pool)
563 unsigned int i;
565 for (i = 0; i < pool->index; i++)
566 SysFreeString(pool->pool[i]);
568 HeapFree(GetProcessHeap(), 0, pool->pool);
570 pool->pool = NULL;
571 pool->index = pool->len = 0;
574 static BSTR bstr_from_xmlCharN(const xmlChar *buf, int len)
576 DWORD dLen;
577 BSTR bstr;
579 if (!buf)
580 return NULL;
582 dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0);
583 if(len != -1) dLen++;
584 bstr = SysAllocStringLen(NULL, dLen-1);
585 if (!bstr)
586 return NULL;
587 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, bstr, dLen);
588 if(len != -1) bstr[dLen-1] = '\0';
590 return bstr;
593 static BSTR QName_from_xmlChar(const xmlChar *prefix, const xmlChar *name)
595 xmlChar *qname;
596 BSTR bstr;
598 if(!name) return NULL;
600 if(!prefix || !*prefix)
601 return bstr_from_xmlChar(name);
603 qname = xmlBuildQName(name, prefix, NULL, 0);
604 bstr = bstr_from_xmlChar(qname);
605 xmlFree(qname);
607 return bstr;
610 static BSTR pooled_bstr_from_xmlChar(struct bstrpool *pool, const xmlChar *buf)
612 BSTR pool_entry = bstr_from_xmlChar(buf);
614 if (pool_entry && !bstr_pool_insert(pool, pool_entry))
616 SysFreeString(pool_entry);
617 return NULL;
620 return pool_entry;
623 static BSTR pooled_bstr_from_xmlCharN(struct bstrpool *pool, const xmlChar *buf, int len)
625 BSTR pool_entry = bstr_from_xmlCharN(buf, len);
627 if (pool_entry && !bstr_pool_insert(pool, pool_entry))
629 SysFreeString(pool_entry);
630 return NULL;
633 return pool_entry;
636 static void format_error_message_from_id(saxlocator *This, HRESULT hr)
638 struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader);
639 xmlStopParser(This->pParserCtxt);
640 This->ret = hr;
642 if(has_error_handler(This))
644 WCHAR msg[1024];
645 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
646 NULL, hr, 0, msg, sizeof(msg), NULL))
648 FIXME("MSXML errors not yet supported.\n");
649 msg[0] = '\0';
652 if(This->vbInterface)
654 BSTR bstrMsg = SysAllocString(msg);
655 IVBSAXErrorHandler_fatalError(handler->vbhandler,
656 &This->IVBSAXLocator_iface, &bstrMsg, hr);
657 SysFreeString(bstrMsg);
659 else
660 ISAXErrorHandler_fatalError(handler->handler,
661 &This->ISAXLocator_iface, msg, hr);
665 static void update_position(saxlocator *This, BOOL fix_column)
667 const xmlChar *p = This->pParserCtxt->input->cur-1;
669 This->line = xmlSAX2GetLineNumber(This->pParserCtxt);
670 if(fix_column)
672 This->column = 1;
673 for(; *p!='\n' && *p!='\r' && p>=This->pParserCtxt->input->base; p--)
674 This->column++;
676 else
678 This->column = xmlSAX2GetColumnNumber(This->pParserCtxt);
682 /*** IVBSAXAttributes interface ***/
683 /*** IUnknown methods ***/
684 static HRESULT WINAPI ivbsaxattributes_QueryInterface(
685 IVBSAXAttributes* iface,
686 REFIID riid,
687 void **ppvObject)
689 saxlocator *This = impl_from_IVBSAXAttributes(iface);
690 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
691 return IVBSAXLocator_QueryInterface(&This->IVBSAXLocator_iface, riid, ppvObject);
694 static ULONG WINAPI ivbsaxattributes_AddRef(IVBSAXAttributes* iface)
696 saxlocator *This = impl_from_IVBSAXAttributes(iface);
697 return ISAXLocator_AddRef(&This->ISAXLocator_iface);
700 static ULONG WINAPI ivbsaxattributes_Release(IVBSAXAttributes* iface)
702 saxlocator *This = impl_from_IVBSAXAttributes(iface);
703 return ISAXLocator_Release(&This->ISAXLocator_iface);
706 /*** IDispatch methods ***/
707 static HRESULT WINAPI ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
709 saxlocator *This = impl_from_IVBSAXAttributes( iface );
711 TRACE("(%p)->(%p)\n", This, pctinfo);
713 *pctinfo = 1;
715 return S_OK;
718 static HRESULT WINAPI ivbsaxattributes_GetTypeInfo(
719 IVBSAXAttributes *iface,
720 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
722 saxlocator *This = impl_from_IVBSAXAttributes( iface );
723 HRESULT hr;
725 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
727 hr = get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
729 return hr;
732 static HRESULT WINAPI ivbsaxattributes_GetIDsOfNames(
733 IVBSAXAttributes *iface,
734 REFIID riid,
735 LPOLESTR* rgszNames,
736 UINT cNames,
737 LCID lcid,
738 DISPID* rgDispId)
740 saxlocator *This = impl_from_IVBSAXAttributes( iface );
741 ITypeInfo *typeinfo;
742 HRESULT hr;
744 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
745 lcid, rgDispId);
747 if(!rgszNames || cNames == 0 || !rgDispId)
748 return E_INVALIDARG;
750 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
751 if(SUCCEEDED(hr))
753 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
754 ITypeInfo_Release(typeinfo);
757 return hr;
760 static HRESULT WINAPI ivbsaxattributes_Invoke(
761 IVBSAXAttributes *iface,
762 DISPID dispIdMember,
763 REFIID riid,
764 LCID lcid,
765 WORD wFlags,
766 DISPPARAMS* pDispParams,
767 VARIANT* pVarResult,
768 EXCEPINFO* pExcepInfo,
769 UINT* puArgErr)
771 saxlocator *This = impl_from_IVBSAXAttributes( iface );
772 ITypeInfo *typeinfo;
773 HRESULT hr;
775 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
776 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
778 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
779 if(SUCCEEDED(hr))
781 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
782 pDispParams, pVarResult, pExcepInfo, puArgErr);
783 ITypeInfo_Release(typeinfo);
786 return hr;
789 /*** IVBSAXAttributes methods ***/
790 static HRESULT WINAPI ivbsaxattributes_get_length(
791 IVBSAXAttributes* iface,
792 int *nLength)
794 saxlocator *This = impl_from_IVBSAXAttributes( iface );
795 return ISAXAttributes_getLength(&This->ISAXAttributes_iface, nLength);
798 static HRESULT WINAPI ivbsaxattributes_getURI(
799 IVBSAXAttributes* iface,
800 int nIndex,
801 BSTR *uri)
803 int len;
804 saxlocator *This = impl_from_IVBSAXAttributes( iface );
805 return ISAXAttributes_getURI(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)uri, &len);
808 static HRESULT WINAPI ivbsaxattributes_getLocalName(
809 IVBSAXAttributes* iface,
810 int nIndex,
811 BSTR *localName)
813 int len;
814 saxlocator *This = impl_from_IVBSAXAttributes( iface );
815 return ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, nIndex,
816 (const WCHAR**)localName, &len);
819 static HRESULT WINAPI ivbsaxattributes_getQName(
820 IVBSAXAttributes* iface,
821 int nIndex,
822 BSTR *QName)
824 int len;
825 saxlocator *This = impl_from_IVBSAXAttributes( iface );
826 return ISAXAttributes_getQName(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)QName, &len);
829 static HRESULT WINAPI ivbsaxattributes_getIndexFromName(
830 IVBSAXAttributes* iface,
831 BSTR uri,
832 BSTR localName,
833 int *index)
835 saxlocator *This = impl_from_IVBSAXAttributes( iface );
836 return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
837 localName, SysStringLen(localName), index);
840 static HRESULT WINAPI ivbsaxattributes_getIndexFromQName(
841 IVBSAXAttributes* iface,
842 BSTR QName,
843 int *index)
845 saxlocator *This = impl_from_IVBSAXAttributes( iface );
846 return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, QName,
847 SysStringLen(QName), index);
850 static HRESULT WINAPI ivbsaxattributes_getType(
851 IVBSAXAttributes* iface,
852 int nIndex,
853 BSTR *type)
855 int len;
856 saxlocator *This = impl_from_IVBSAXAttributes( iface );
857 return ISAXAttributes_getType(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)type, &len);
860 static HRESULT WINAPI ivbsaxattributes_getTypeFromName(
861 IVBSAXAttributes* iface,
862 BSTR uri,
863 BSTR localName,
864 BSTR *type)
866 int len;
867 saxlocator *This = impl_from_IVBSAXAttributes( iface );
868 return ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
869 localName, SysStringLen(localName), (const WCHAR**)type, &len);
872 static HRESULT WINAPI ivbsaxattributes_getTypeFromQName(
873 IVBSAXAttributes* iface,
874 BSTR QName,
875 BSTR *type)
877 int len;
878 saxlocator *This = impl_from_IVBSAXAttributes( iface );
879 return ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, QName, SysStringLen(QName),
880 (const WCHAR**)type, &len);
883 static HRESULT WINAPI ivbsaxattributes_getValue(
884 IVBSAXAttributes* iface,
885 int nIndex,
886 BSTR *value)
888 int len;
889 saxlocator *This = impl_from_IVBSAXAttributes( iface );
890 return ISAXAttributes_getValue(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)value, &len);
893 static HRESULT WINAPI ivbsaxattributes_getValueFromName(
894 IVBSAXAttributes* iface,
895 BSTR uri,
896 BSTR localName,
897 BSTR *value)
899 int len;
900 saxlocator *This = impl_from_IVBSAXAttributes( iface );
901 return ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
902 localName, SysStringLen(localName), (const WCHAR**)value, &len);
905 static HRESULT WINAPI ivbsaxattributes_getValueFromQName(
906 IVBSAXAttributes* iface,
907 BSTR QName,
908 BSTR *value)
910 int len;
911 saxlocator *This = impl_from_IVBSAXAttributes( iface );
912 return ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, QName,
913 SysStringLen(QName), (const WCHAR**)value, &len);
916 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl =
918 ivbsaxattributes_QueryInterface,
919 ivbsaxattributes_AddRef,
920 ivbsaxattributes_Release,
921 ivbsaxattributes_GetTypeInfoCount,
922 ivbsaxattributes_GetTypeInfo,
923 ivbsaxattributes_GetIDsOfNames,
924 ivbsaxattributes_Invoke,
925 ivbsaxattributes_get_length,
926 ivbsaxattributes_getURI,
927 ivbsaxattributes_getLocalName,
928 ivbsaxattributes_getQName,
929 ivbsaxattributes_getIndexFromName,
930 ivbsaxattributes_getIndexFromQName,
931 ivbsaxattributes_getType,
932 ivbsaxattributes_getTypeFromName,
933 ivbsaxattributes_getTypeFromQName,
934 ivbsaxattributes_getValue,
935 ivbsaxattributes_getValueFromName,
936 ivbsaxattributes_getValueFromQName
939 /*** ISAXAttributes interface ***/
940 /*** IUnknown methods ***/
941 static HRESULT WINAPI isaxattributes_QueryInterface(
942 ISAXAttributes* iface,
943 REFIID riid,
944 void **ppvObject)
946 saxlocator *This = impl_from_ISAXAttributes(iface);
947 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
948 return ISAXLocator_QueryInterface(&This->ISAXLocator_iface, riid, ppvObject);
951 static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes* iface)
953 saxlocator *This = impl_from_ISAXAttributes(iface);
954 TRACE("%p\n", This);
955 return ISAXLocator_AddRef(&This->ISAXLocator_iface);
958 static ULONG WINAPI isaxattributes_Release(ISAXAttributes* iface)
960 saxlocator *This = impl_from_ISAXAttributes(iface);
962 TRACE("%p\n", This);
963 return ISAXLocator_Release(&This->ISAXLocator_iface);
966 /*** ISAXAttributes methods ***/
967 static HRESULT WINAPI isaxattributes_getLength(
968 ISAXAttributes* iface,
969 int *length)
971 saxlocator *This = impl_from_ISAXAttributes( iface );
973 *length = This->nb_attributes;
974 TRACE("Length set to %d\n", *length);
975 return S_OK;
978 static HRESULT WINAPI isaxattributes_getURI(
979 ISAXAttributes* iface,
980 int index,
981 const WCHAR **url,
982 int *size)
984 saxlocator *This = impl_from_ISAXAttributes( iface );
985 TRACE("(%p)->(%d)\n", This, index);
987 if(index >= This->nb_attributes || index < 0) return E_INVALIDARG;
988 if(!url || !size) return E_POINTER;
990 *size = SysStringLen(This->attributes[index].szURI);
991 *url = This->attributes[index].szURI;
993 TRACE("(%s:%d)\n", debugstr_w(This->attributes[index].szURI), *size);
995 return S_OK;
998 static HRESULT WINAPI isaxattributes_getLocalName(
999 ISAXAttributes* iface,
1000 int nIndex,
1001 const WCHAR **pLocalName,
1002 int *pLocalNameLength)
1004 saxlocator *This = impl_from_ISAXAttributes( iface );
1005 TRACE("(%p)->(%d)\n", This, nIndex);
1007 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
1008 if(!pLocalName || !pLocalNameLength) return E_POINTER;
1010 *pLocalNameLength = SysStringLen(This->attributes[nIndex].szLocalname);
1011 *pLocalName = This->attributes[nIndex].szLocalname;
1013 return S_OK;
1016 static HRESULT WINAPI isaxattributes_getQName(
1017 ISAXAttributes* iface,
1018 int nIndex,
1019 const WCHAR **pQName,
1020 int *pQNameLength)
1022 saxlocator *This = impl_from_ISAXAttributes( iface );
1023 TRACE("(%p)->(%d)\n", This, nIndex);
1025 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
1026 if(!pQName || !pQNameLength) return E_POINTER;
1028 *pQNameLength = SysStringLen(This->attributes[nIndex].szQName);
1029 *pQName = This->attributes[nIndex].szQName;
1031 return S_OK;
1034 static HRESULT WINAPI isaxattributes_getName(
1035 ISAXAttributes* iface,
1036 int index,
1037 const WCHAR **uri,
1038 int *pUriLength,
1039 const WCHAR **localName,
1040 int *pLocalNameSize,
1041 const WCHAR **QName,
1042 int *pQNameLength)
1044 saxlocator *This = impl_from_ISAXAttributes( iface );
1045 TRACE("(%p)->(%d)\n", This, index);
1047 if(index>=This->nb_attributes || index<0) return E_INVALIDARG;
1048 if(!uri || !pUriLength || !localName || !pLocalNameSize
1049 || !QName || !pQNameLength) return E_POINTER;
1051 *pUriLength = SysStringLen(This->attributes[index].szURI);
1052 *uri = This->attributes[index].szURI;
1053 *pLocalNameSize = SysStringLen(This->attributes[index].szLocalname);
1054 *localName = This->attributes[index].szLocalname;
1055 *pQNameLength = SysStringLen(This->attributes[index].szQName);
1056 *QName = This->attributes[index].szQName;
1058 TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*localName), debugstr_w(*QName));
1060 return S_OK;
1063 static HRESULT WINAPI isaxattributes_getIndexFromName(
1064 ISAXAttributes* iface,
1065 const WCHAR *pUri,
1066 int cUriLength,
1067 const WCHAR *pLocalName,
1068 int cocalNameLength,
1069 int *index)
1071 saxlocator *This = impl_from_ISAXAttributes( iface );
1072 int i;
1073 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), cUriLength,
1074 debugstr_w(pLocalName), cocalNameLength);
1076 if(!pUri || !pLocalName || !index) return E_POINTER;
1078 for(i=0; i<This->nb_attributes; i++)
1080 if(cUriLength!=SysStringLen(This->attributes[i].szURI)
1081 || cocalNameLength!=SysStringLen(This->attributes[i].szLocalname))
1082 continue;
1083 if(cUriLength && memcmp(pUri, This->attributes[i].szURI,
1084 sizeof(WCHAR)*cUriLength))
1085 continue;
1086 if(cocalNameLength && memcmp(pLocalName, This->attributes[i].szLocalname,
1087 sizeof(WCHAR)*cocalNameLength))
1088 continue;
1090 *index = i;
1091 return S_OK;
1094 return E_INVALIDARG;
1097 static HRESULT WINAPI isaxattributes_getIndexFromQName(
1098 ISAXAttributes* iface,
1099 const WCHAR *pQName,
1100 int nQNameLength,
1101 int *index)
1103 saxlocator *This = impl_from_ISAXAttributes( iface );
1104 int i;
1105 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQNameLength);
1107 if(!pQName || !index) return E_POINTER;
1108 if(!nQNameLength) return E_INVALIDARG;
1110 for(i=0; i<This->nb_attributes; i++)
1112 if(nQNameLength!=SysStringLen(This->attributes[i].szQName)) continue;
1113 if(memcmp(pQName, This->attributes[i].szQName, sizeof(WCHAR)*nQNameLength)) continue;
1115 *index = i;
1116 return S_OK;
1119 return E_INVALIDARG;
1122 static HRESULT WINAPI isaxattributes_getType(
1123 ISAXAttributes* iface,
1124 int nIndex,
1125 const WCHAR **pType,
1126 int *pTypeLength)
1128 saxlocator *This = impl_from_ISAXAttributes( iface );
1130 FIXME("(%p)->(%d) stub\n", This, nIndex);
1131 return E_NOTIMPL;
1134 static HRESULT WINAPI isaxattributes_getTypeFromName(
1135 ISAXAttributes* iface,
1136 const WCHAR *pUri,
1137 int nUri,
1138 const WCHAR *pLocalName,
1139 int nLocalName,
1140 const WCHAR **pType,
1141 int *nType)
1143 saxlocator *This = impl_from_ISAXAttributes( iface );
1145 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This, debugstr_w(pUri), nUri,
1146 debugstr_w(pLocalName), nLocalName);
1147 return E_NOTIMPL;
1150 static HRESULT WINAPI isaxattributes_getTypeFromQName(
1151 ISAXAttributes* iface,
1152 const WCHAR *pQName,
1153 int nQName,
1154 const WCHAR **pType,
1155 int *nType)
1157 saxlocator *This = impl_from_ISAXAttributes( iface );
1159 FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(pQName), nQName);
1160 return E_NOTIMPL;
1163 static HRESULT WINAPI isaxattributes_getValue(
1164 ISAXAttributes* iface,
1165 int index,
1166 const WCHAR **value,
1167 int *nValue)
1169 saxlocator *This = impl_from_ISAXAttributes( iface );
1170 TRACE("(%p)->(%d)\n", This, index);
1172 if(index>=This->nb_attributes || index<0) return E_INVALIDARG;
1173 if(!value || !nValue) return E_POINTER;
1175 *nValue = SysStringLen(This->attributes[index].szValue);
1176 *value = This->attributes[index].szValue;
1178 TRACE("(%s:%d)\n", debugstr_w(*value), *nValue);
1180 return S_OK;
1183 static HRESULT WINAPI isaxattributes_getValueFromName(
1184 ISAXAttributes* iface,
1185 const WCHAR *pUri,
1186 int nUri,
1187 const WCHAR *pLocalName,
1188 int nLocalName,
1189 const WCHAR **pValue,
1190 int *nValue)
1192 HRESULT hr;
1193 int index;
1194 saxlocator *This = impl_from_ISAXAttributes( iface );
1195 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), nUri,
1196 debugstr_w(pLocalName), nLocalName);
1198 hr = ISAXAttributes_getIndexFromName(iface,
1199 pUri, nUri, pLocalName, nLocalName, &index);
1200 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
1202 return hr;
1205 static HRESULT WINAPI isaxattributes_getValueFromQName(
1206 ISAXAttributes* iface,
1207 const WCHAR *pQName,
1208 int nQName,
1209 const WCHAR **pValue,
1210 int *nValue)
1212 HRESULT hr;
1213 int index;
1214 saxlocator *This = impl_from_ISAXAttributes( iface );
1215 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQName);
1217 hr = ISAXAttributes_getIndexFromQName(iface, pQName, nQName, &index);
1218 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
1220 return hr;
1223 static const struct ISAXAttributesVtbl isaxattributes_vtbl =
1225 isaxattributes_QueryInterface,
1226 isaxattributes_AddRef,
1227 isaxattributes_Release,
1228 isaxattributes_getLength,
1229 isaxattributes_getURI,
1230 isaxattributes_getLocalName,
1231 isaxattributes_getQName,
1232 isaxattributes_getName,
1233 isaxattributes_getIndexFromName,
1234 isaxattributes_getIndexFromQName,
1235 isaxattributes_getType,
1236 isaxattributes_getTypeFromName,
1237 isaxattributes_getTypeFromQName,
1238 isaxattributes_getValue,
1239 isaxattributes_getValueFromName,
1240 isaxattributes_getValueFromQName
1243 static HRESULT SAXAttributes_populate(saxlocator *locator,
1244 int nb_namespaces, const xmlChar **xmlNamespaces,
1245 int nb_attributes, const xmlChar **xmlAttributes)
1247 static const xmlChar xmlns[] = "xmlns";
1248 static const WCHAR xmlnsW[] = { 'x','m','l','n','s',0 };
1250 struct _attributes *attrs;
1251 int i;
1253 /* skip namespace definitions */
1254 if ((locator->saxreader->features & NamespacePrefixes) == 0)
1255 nb_namespaces = 0;
1257 locator->nb_attributes = nb_namespaces + nb_attributes;
1258 if(locator->nb_attributes > locator->attributesSize)
1260 attrs = heap_realloc(locator->attributes, sizeof(struct _attributes)*locator->nb_attributes*2);
1261 if(!attrs)
1263 locator->nb_attributes = 0;
1264 return E_OUTOFMEMORY;
1266 locator->attributes = attrs;
1268 else
1270 attrs = locator->attributes;
1273 for (i = 0; i < nb_namespaces; i++)
1275 attrs[nb_attributes+i].szLocalname = SysAllocStringLen(NULL, 0);
1276 attrs[nb_attributes+i].szURI = locator->namespaceUri;
1277 attrs[nb_attributes+i].szValue = bstr_from_xmlChar(xmlNamespaces[2*i+1]);
1278 if(!xmlNamespaces[2*i])
1279 attrs[nb_attributes+i].szQName = SysAllocString(xmlnsW);
1280 else
1281 attrs[nb_attributes+i].szQName = QName_from_xmlChar(xmlns, xmlNamespaces[2*i]);
1284 for (i = 0; i < nb_attributes; i++)
1286 static const xmlChar xmlA[] = "xml";
1288 if (xmlStrEqual(xmlAttributes[i*5+1], xmlA))
1289 attrs[i].szURI = bstr_from_xmlChar(xmlAttributes[i*5+2]);
1290 else
1291 /* that's an important feature to keep same uri pointer for every reported attribute */
1292 attrs[i].szURI = find_element_uri(locator, xmlAttributes[i*5+2]);
1294 attrs[i].szLocalname = bstr_from_xmlChar(xmlAttributes[i*5]);
1295 attrs[i].szValue = bstr_from_xmlCharN(xmlAttributes[i*5+3],
1296 xmlAttributes[i*5+4]-xmlAttributes[i*5+3]);
1297 attrs[i].szQName = QName_from_xmlChar(xmlAttributes[i*5+1],
1298 xmlAttributes[i*5]);
1301 return S_OK;
1304 /*** LibXML callbacks ***/
1305 static void libxmlStartDocument(void *ctx)
1307 saxlocator *This = ctx;
1308 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1309 HRESULT hr;
1311 if (This->saxreader->version >= MSXML4)
1313 const xmlChar *p = This->pParserCtxt->input->cur-1;
1314 update_position(This, FALSE);
1315 while(p>This->pParserCtxt->input->base && *p!='>')
1317 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1318 This->line--;
1319 p--;
1321 This->column = 0;
1322 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1323 This->column++;
1326 if(has_content_handler(This))
1328 if(This->vbInterface)
1329 hr = IVBSAXContentHandler_startDocument(handler->vbhandler);
1330 else
1331 hr = ISAXContentHandler_startDocument(handler->handler);
1333 if (sax_callback_failed(This, hr))
1334 format_error_message_from_id(This, hr);
1338 static void libxmlEndDocument(void *ctx)
1340 saxlocator *This = ctx;
1341 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1342 HRESULT hr;
1344 if (This->saxreader->version >= MSXML4) {
1345 update_position(This, FALSE);
1346 if(This->column > 1)
1347 This->line++;
1348 This->column = 0;
1349 } else {
1350 This->column = 0;
1351 This->line = 0;
1354 if(This->ret != S_OK) return;
1356 if(has_content_handler(This))
1358 if(This->vbInterface)
1359 hr = IVBSAXContentHandler_endDocument(handler->vbhandler);
1360 else
1361 hr = ISAXContentHandler_endDocument(handler->handler);
1363 if (sax_callback_failed(This, hr))
1364 format_error_message_from_id(This, hr);
1368 static void libxmlStartElementNS(
1369 void *ctx,
1370 const xmlChar *localname,
1371 const xmlChar *prefix,
1372 const xmlChar *URI,
1373 int nb_namespaces,
1374 const xmlChar **namespaces,
1375 int nb_attributes,
1376 int nb_defaulted,
1377 const xmlChar **attributes)
1379 saxlocator *This = ctx;
1380 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1381 element_entry *element;
1382 HRESULT hr = S_OK;
1383 BSTR uri;
1385 update_position(This, TRUE);
1386 if(*(This->pParserCtxt->input->cur) == '/')
1387 This->column++;
1388 if(This->saxreader->version < MSXML4)
1389 This->column++;
1391 element = alloc_element_entry(localname, prefix, nb_namespaces, namespaces);
1392 push_element_ns(This, element);
1394 if (is_namespaces_enabled(This->saxreader))
1396 int i;
1398 for (i = 0; i < nb_namespaces && has_content_handler(This); i++)
1400 if (This->vbInterface)
1401 hr = IVBSAXContentHandler_startPrefixMapping(
1402 handler->vbhandler,
1403 &element->ns[i].prefix,
1404 &element->ns[i].uri);
1405 else
1406 hr = ISAXContentHandler_startPrefixMapping(
1407 handler->handler,
1408 element->ns[i].prefix,
1409 SysStringLen(element->ns[i].prefix),
1410 element->ns[i].uri,
1411 SysStringLen(element->ns[i].uri));
1413 if (sax_callback_failed(This, hr))
1415 format_error_message_from_id(This, hr);
1416 return;
1421 uri = find_element_uri(This, URI);
1422 hr = SAXAttributes_populate(This, nb_namespaces, namespaces, nb_attributes, attributes);
1423 if (hr == S_OK && has_content_handler(This))
1425 BSTR local;
1427 if (is_namespaces_enabled(This->saxreader))
1428 local = element->local;
1429 else
1430 uri = local = NULL;
1432 if (This->vbInterface)
1433 hr = IVBSAXContentHandler_startElement(handler->vbhandler,
1434 &uri, &local, &element->qname, &This->IVBSAXAttributes_iface);
1435 else
1436 hr = ISAXContentHandler_startElement(handler->handler,
1437 uri, SysStringLen(uri),
1438 local, SysStringLen(local),
1439 element->qname, SysStringLen(element->qname),
1440 &This->ISAXAttributes_iface);
1442 if (sax_callback_failed(This, hr))
1443 format_error_message_from_id(This, hr);
1447 static void libxmlEndElementNS(
1448 void *ctx,
1449 const xmlChar *localname,
1450 const xmlChar *prefix,
1451 const xmlChar *URI)
1453 saxlocator *This = ctx;
1454 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1455 element_entry *element;
1456 const xmlChar *p;
1457 BSTR uri, local;
1458 HRESULT hr;
1460 update_position(This, FALSE);
1461 p = This->pParserCtxt->input->cur;
1463 if (This->saxreader->version >= MSXML4)
1465 p--;
1466 while(p>This->pParserCtxt->input->base && *p!='>')
1468 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1469 This->line--;
1470 p--;
1473 else if(*(p-1)!='>' || *(p-2)!='/')
1475 p--;
1476 while(p-2>=This->pParserCtxt->input->base
1477 && *(p-2)!='<' && *(p-1)!='/')
1479 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1480 This->line--;
1481 p--;
1484 This->column = 0;
1485 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1486 This->column++;
1488 uri = find_element_uri(This, URI);
1489 element = pop_element_ns(This);
1491 if (!has_content_handler(This))
1493 This->nb_attributes = 0;
1494 free_element_entry(element);
1495 return;
1498 if (is_namespaces_enabled(This->saxreader))
1499 local = element->local;
1500 else
1501 uri = local = NULL;
1503 if (This->vbInterface)
1504 hr = IVBSAXContentHandler_endElement(
1505 handler->vbhandler,
1506 &uri, &local, &element->qname);
1507 else
1508 hr = ISAXContentHandler_endElement(
1509 handler->handler,
1510 uri, SysStringLen(uri),
1511 local, SysStringLen(local),
1512 element->qname, SysStringLen(element->qname));
1514 This->nb_attributes = 0;
1516 if (sax_callback_failed(This, hr))
1518 format_error_message_from_id(This, hr);
1519 free_element_entry(element);
1520 return;
1523 if (is_namespaces_enabled(This->saxreader))
1525 int i = -1;
1526 while (iterate_endprefix_index(This, element, &i) && has_content_handler(This))
1528 if (This->vbInterface)
1529 hr = IVBSAXContentHandler_endPrefixMapping(
1530 handler->vbhandler, &element->ns[i].prefix);
1531 else
1532 hr = ISAXContentHandler_endPrefixMapping(
1533 handler->handler, element->ns[i].prefix, SysStringLen(element->ns[i].prefix));
1535 if (sax_callback_failed(This, hr)) break;
1538 if (sax_callback_failed(This, hr))
1539 format_error_message_from_id(This, hr);
1542 free_element_entry(element);
1545 static void libxmlCharacters(
1546 void *ctx,
1547 const xmlChar *ch,
1548 int len)
1550 saxlocator *This = ctx;
1551 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1552 BSTR Chars;
1553 HRESULT hr;
1554 xmlChar *cur, *end;
1555 BOOL lastEvent = FALSE;
1557 if(!(has_content_handler(This))) return;
1559 update_position(This, FALSE);
1560 cur = (xmlChar*)This->pParserCtxt->input->cur;
1561 while(cur>=This->pParserCtxt->input->base && *cur!='>')
1563 if(*cur=='\n' || (*cur=='\r' && *(cur+1)!='\n'))
1564 This->line--;
1565 cur--;
1567 This->column = 1;
1568 for(; cur>=This->pParserCtxt->input->base && *cur!='\n' && *cur!='\r'; cur--)
1569 This->column++;
1571 cur = (xmlChar*)ch;
1572 if(*(ch-1)=='\r') cur--;
1573 end = cur;
1575 while(1)
1577 while(end-ch<len && *end!='\r') end++;
1578 if(end-ch==len)
1580 lastEvent = TRUE;
1582 else
1584 *end = '\n';
1585 end++;
1588 if (This->saxreader->version >= MSXML4)
1590 xmlChar *p;
1592 for(p=cur; p!=end; p++)
1594 if(*p=='\n')
1596 This->line++;
1597 This->column = 1;
1599 else
1601 This->column++;
1605 if(!lastEvent)
1606 This->column = 0;
1609 Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur);
1610 if(This->vbInterface)
1611 hr = IVBSAXContentHandler_characters(handler->vbhandler, &Chars);
1612 else
1613 hr = ISAXContentHandler_characters(handler->handler, Chars, SysStringLen(Chars));
1615 if (sax_callback_failed(This, hr))
1617 format_error_message_from_id(This, hr);
1618 return;
1621 if (This->saxreader->version < MSXML4)
1622 This->column += end-cur;
1624 if(lastEvent)
1625 break;
1627 *(end-1) = '\r';
1628 if(*end == '\n')
1630 end++;
1631 This->column++;
1633 cur = end;
1635 if(end-ch == len) break;
1639 static void libxmlSetDocumentLocator(
1640 void *ctx,
1641 xmlSAXLocatorPtr loc)
1643 saxlocator *This = ctx;
1644 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1645 HRESULT hr = S_OK;
1647 if(has_content_handler(This))
1649 if(This->vbInterface)
1650 hr = IVBSAXContentHandler_putref_documentLocator(handler->vbhandler,
1651 &This->IVBSAXLocator_iface);
1652 else
1653 hr = ISAXContentHandler_putDocumentLocator(handler->handler, &This->ISAXLocator_iface);
1656 if(FAILED(hr))
1657 format_error_message_from_id(This, hr);
1660 static void libxmlComment(void *ctx, const xmlChar *value)
1662 saxlocator *This = ctx;
1663 struct saxlexicalhandler_iface *handler = saxreader_get_lexicalhandler(This->saxreader);
1664 BSTR bValue;
1665 HRESULT hr;
1666 const xmlChar *p = This->pParserCtxt->input->cur;
1668 update_position(This, FALSE);
1669 while(p-4>=This->pParserCtxt->input->base
1670 && memcmp(p-4, "<!--", sizeof(char[4])))
1672 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1673 This->line--;
1674 p--;
1677 This->column = 0;
1678 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1679 This->column++;
1681 if (!has_lexical_handler(This)) return;
1683 bValue = pooled_bstr_from_xmlChar(&This->saxreader->pool, value);
1685 if (This->vbInterface)
1686 hr = IVBSAXLexicalHandler_comment(handler->vbhandler, &bValue);
1687 else
1688 hr = ISAXLexicalHandler_comment(handler->handler, bValue, SysStringLen(bValue));
1690 if(FAILED(hr))
1691 format_error_message_from_id(This, hr);
1694 static void libxmlFatalError(void *ctx, const char *msg, ...)
1696 saxlocator *This = ctx;
1697 struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader);
1698 char message[1024];
1699 WCHAR *error;
1700 DWORD len;
1701 va_list args;
1703 if(This->ret != S_OK) {
1704 xmlStopParser(This->pParserCtxt);
1705 return;
1708 va_start(args, msg);
1709 vsprintf(message, msg, args);
1710 va_end(args);
1712 len = MultiByteToWideChar(CP_UNIXCP, 0, message, -1, NULL, 0);
1713 error = heap_alloc(sizeof(WCHAR)*len);
1714 if(error)
1716 MultiByteToWideChar(CP_UNIXCP, 0, message, -1, error, len);
1717 TRACE("fatal error for %p: %s\n", This, debugstr_w(error));
1720 if(!has_error_handler(This))
1722 xmlStopParser(This->pParserCtxt);
1723 This->ret = E_FAIL;
1724 heap_free(error);
1725 return;
1728 FIXME("Error handling is not compatible.\n");
1730 if(This->vbInterface)
1732 BSTR bstrError = SysAllocString(error);
1733 IVBSAXErrorHandler_fatalError(handler->vbhandler, &This->IVBSAXLocator_iface,
1734 &bstrError, E_FAIL);
1735 SysFreeString(bstrError);
1737 else
1738 ISAXErrorHandler_fatalError(handler->handler, &This->ISAXLocator_iface, error, E_FAIL);
1740 heap_free(error);
1742 xmlStopParser(This->pParserCtxt);
1743 This->ret = E_FAIL;
1746 static void libxmlCDataBlock(void *ctx, const xmlChar *value, int len)
1748 saxlocator *This = ctx;
1749 struct saxcontenthandler_iface *content = saxreader_get_contenthandler(This->saxreader);
1750 struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(This->saxreader);
1751 HRESULT hr = S_OK;
1752 xmlChar *beg = (xmlChar*)This->pParserCtxt->input->cur-len;
1753 xmlChar *cur, *end;
1754 int realLen;
1755 BSTR Chars;
1756 BOOL lastEvent = FALSE, change;
1758 update_position(This, FALSE);
1759 while(beg-9>=This->pParserCtxt->input->base
1760 && memcmp(beg-9, "<![CDATA[", sizeof(char[9])))
1762 if(*beg=='\n' || (*beg=='\r' && *(beg+1)!='\n'))
1763 This->line--;
1764 beg--;
1766 This->column = 0;
1767 for(; beg>=This->pParserCtxt->input->base && *beg!='\n' && *beg!='\r'; beg--)
1768 This->column++;
1770 if (has_lexical_handler(This))
1772 if (This->vbInterface)
1773 hr = IVBSAXLexicalHandler_startCDATA(lexical->vbhandler);
1774 else
1775 hr = ISAXLexicalHandler_startCDATA(lexical->handler);
1778 if(FAILED(hr))
1780 format_error_message_from_id(This, hr);
1781 return;
1784 realLen = This->pParserCtxt->input->cur-beg-3;
1785 cur = beg;
1786 end = beg;
1788 while(1)
1790 while(end-beg<realLen && *end!='\r') end++;
1791 if(end-beg==realLen)
1793 end--;
1794 lastEvent = TRUE;
1796 else if(end-beg==realLen-1 && *end=='\r' && *(end+1)=='\n')
1797 lastEvent = TRUE;
1799 if(*end == '\r') change = TRUE;
1800 else change = FALSE;
1802 if(change) *end = '\n';
1804 if (has_content_handler(This))
1806 Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur+1);
1807 if (This->vbInterface)
1808 hr = IVBSAXContentHandler_characters(content->vbhandler, &Chars);
1809 else
1810 hr = ISAXContentHandler_characters(content->handler, Chars, SysStringLen(Chars));
1813 if(change) *end = '\r';
1815 if(lastEvent)
1816 break;
1818 This->column += end-cur+2;
1819 end += 2;
1820 cur = end;
1823 if (has_lexical_handler(This))
1825 if (This->vbInterface)
1826 hr = IVBSAXLexicalHandler_endCDATA(lexical->vbhandler);
1827 else
1828 hr = ISAXLexicalHandler_endCDATA(lexical->handler);
1831 if(FAILED(hr))
1832 format_error_message_from_id(This, hr);
1834 This->column += 4+end-cur;
1837 /*** IVBSAXLocator interface ***/
1838 /*** IUnknown methods ***/
1839 static HRESULT WINAPI ivbsaxlocator_QueryInterface(IVBSAXLocator* iface, REFIID riid, void **ppvObject)
1841 saxlocator *This = impl_from_IVBSAXLocator( iface );
1843 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject);
1845 *ppvObject = NULL;
1847 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
1848 IsEqualGUID( riid, &IID_IDispatch) ||
1849 IsEqualGUID( riid, &IID_IVBSAXLocator ))
1851 *ppvObject = iface;
1853 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
1855 *ppvObject = &This->IVBSAXAttributes_iface;
1857 else
1859 FIXME("interface %s not implemented\n", debugstr_guid(riid));
1860 return E_NOINTERFACE;
1863 IVBSAXLocator_AddRef( iface );
1865 return S_OK;
1868 static ULONG WINAPI ivbsaxlocator_AddRef(IVBSAXLocator* iface)
1870 saxlocator *This = impl_from_IVBSAXLocator( iface );
1871 TRACE("%p\n", This );
1872 return InterlockedIncrement( &This->ref );
1875 static ULONG WINAPI ivbsaxlocator_Release(
1876 IVBSAXLocator* iface)
1878 saxlocator *This = impl_from_IVBSAXLocator( iface );
1879 return ISAXLocator_Release((ISAXLocator*)&This->IVBSAXLocator_iface);
1882 /*** IDispatch methods ***/
1883 static HRESULT WINAPI ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator *iface, UINT* pctinfo )
1885 saxlocator *This = impl_from_IVBSAXLocator( iface );
1887 TRACE("(%p)->(%p)\n", This, pctinfo);
1889 *pctinfo = 1;
1891 return S_OK;
1894 static HRESULT WINAPI ivbsaxlocator_GetTypeInfo(
1895 IVBSAXLocator *iface,
1896 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
1898 saxlocator *This = impl_from_IVBSAXLocator( iface );
1899 HRESULT hr;
1901 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1903 hr = get_typeinfo(IVBSAXLocator_tid, ppTInfo);
1905 return hr;
1908 static HRESULT WINAPI ivbsaxlocator_GetIDsOfNames(
1909 IVBSAXLocator *iface,
1910 REFIID riid,
1911 LPOLESTR* rgszNames,
1912 UINT cNames,
1913 LCID lcid,
1914 DISPID* rgDispId)
1916 saxlocator *This = impl_from_IVBSAXLocator( iface );
1917 ITypeInfo *typeinfo;
1918 HRESULT hr;
1920 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1921 lcid, rgDispId);
1923 if(!rgszNames || cNames == 0 || !rgDispId)
1924 return E_INVALIDARG;
1926 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo);
1927 if(SUCCEEDED(hr))
1929 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1930 ITypeInfo_Release(typeinfo);
1933 return hr;
1936 static HRESULT WINAPI ivbsaxlocator_Invoke(
1937 IVBSAXLocator *iface,
1938 DISPID dispIdMember,
1939 REFIID riid,
1940 LCID lcid,
1941 WORD wFlags,
1942 DISPPARAMS* pDispParams,
1943 VARIANT* pVarResult,
1944 EXCEPINFO* pExcepInfo,
1945 UINT* puArgErr)
1947 saxlocator *This = impl_from_IVBSAXLocator( iface );
1948 ITypeInfo *typeinfo;
1949 HRESULT hr;
1951 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1952 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1954 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo);
1955 if(SUCCEEDED(hr))
1957 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXLocator_iface, dispIdMember, wFlags,
1958 pDispParams, pVarResult, pExcepInfo, puArgErr);
1959 ITypeInfo_Release(typeinfo);
1962 return hr;
1965 /*** IVBSAXLocator methods ***/
1966 static HRESULT WINAPI ivbsaxlocator_get_columnNumber(
1967 IVBSAXLocator* iface,
1968 int *pnColumn)
1970 saxlocator *This = impl_from_IVBSAXLocator( iface );
1971 return ISAXLocator_getColumnNumber((ISAXLocator*)&This->IVBSAXLocator_iface, pnColumn);
1974 static HRESULT WINAPI ivbsaxlocator_get_lineNumber(
1975 IVBSAXLocator* iface,
1976 int *pnLine)
1978 saxlocator *This = impl_from_IVBSAXLocator( iface );
1979 return ISAXLocator_getLineNumber((ISAXLocator*)&This->IVBSAXLocator_iface, pnLine);
1982 static HRESULT WINAPI ivbsaxlocator_get_publicId(
1983 IVBSAXLocator* iface,
1984 BSTR* publicId)
1986 saxlocator *This = impl_from_IVBSAXLocator( iface );
1987 return ISAXLocator_getPublicId((ISAXLocator*)&This->IVBSAXLocator_iface,
1988 (const WCHAR**)publicId);
1991 static HRESULT WINAPI ivbsaxlocator_get_systemId(
1992 IVBSAXLocator* iface,
1993 BSTR* systemId)
1995 saxlocator *This = impl_from_IVBSAXLocator( iface );
1996 return ISAXLocator_getSystemId((ISAXLocator*)&This->IVBSAXLocator_iface,
1997 (const WCHAR**)systemId);
2000 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl =
2002 ivbsaxlocator_QueryInterface,
2003 ivbsaxlocator_AddRef,
2004 ivbsaxlocator_Release,
2005 ivbsaxlocator_GetTypeInfoCount,
2006 ivbsaxlocator_GetTypeInfo,
2007 ivbsaxlocator_GetIDsOfNames,
2008 ivbsaxlocator_Invoke,
2009 ivbsaxlocator_get_columnNumber,
2010 ivbsaxlocator_get_lineNumber,
2011 ivbsaxlocator_get_publicId,
2012 ivbsaxlocator_get_systemId
2015 /*** ISAXLocator interface ***/
2016 /*** IUnknown methods ***/
2017 static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject)
2019 saxlocator *This = impl_from_ISAXLocator( iface );
2021 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
2023 *ppvObject = NULL;
2025 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2026 IsEqualGUID( riid, &IID_ISAXLocator ))
2028 *ppvObject = iface;
2030 else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
2032 *ppvObject = &This->ISAXAttributes_iface;
2034 else
2036 WARN("interface %s not implemented\n", debugstr_guid(riid));
2037 return E_NOINTERFACE;
2040 ISAXLocator_AddRef( iface );
2042 return S_OK;
2045 static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface)
2047 saxlocator *This = impl_from_ISAXLocator( iface );
2048 ULONG ref = InterlockedIncrement( &This->ref );
2049 TRACE("(%p)->(%d)\n", This, ref);
2050 return ref;
2053 static ULONG WINAPI isaxlocator_Release(
2054 ISAXLocator* iface)
2056 saxlocator *This = impl_from_ISAXLocator( iface );
2057 LONG ref = InterlockedDecrement( &This->ref );
2059 TRACE("(%p)->(%d)\n", This, ref );
2061 if (ref == 0)
2063 element_entry *element, *element2;
2064 int index;
2066 SysFreeString(This->publicId);
2067 SysFreeString(This->systemId);
2068 SysFreeString(This->namespaceUri);
2070 for(index=0; index<This->nb_attributes; index++)
2072 SysFreeString(This->attributes[index].szLocalname);
2073 SysFreeString(This->attributes[index].szValue);
2074 SysFreeString(This->attributes[index].szQName);
2076 heap_free(This->attributes);
2078 /* element stack */
2079 LIST_FOR_EACH_ENTRY_SAFE(element, element2, &This->elements, element_entry, entry)
2081 list_remove(&element->entry);
2082 free_element_entry(element);
2085 ISAXXMLReader_Release(&This->saxreader->ISAXXMLReader_iface);
2086 heap_free( This );
2089 return ref;
2092 /*** ISAXLocator methods ***/
2093 static HRESULT WINAPI isaxlocator_getColumnNumber(
2094 ISAXLocator* iface,
2095 int *pnColumn)
2097 saxlocator *This = impl_from_ISAXLocator( iface );
2099 *pnColumn = This->column;
2100 return S_OK;
2103 static HRESULT WINAPI isaxlocator_getLineNumber(
2104 ISAXLocator* iface,
2105 int *pnLine)
2107 saxlocator *This = impl_from_ISAXLocator( iface );
2109 *pnLine = This->line;
2110 return S_OK;
2113 static HRESULT WINAPI isaxlocator_getPublicId(
2114 ISAXLocator* iface,
2115 const WCHAR ** ppwchPublicId)
2117 BSTR publicId;
2118 saxlocator *This = impl_from_ISAXLocator( iface );
2120 SysFreeString(This->publicId);
2122 publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt));
2123 if(SysStringLen(publicId))
2124 This->publicId = (WCHAR*)&publicId;
2125 else
2127 SysFreeString(publicId);
2128 This->publicId = NULL;
2131 *ppwchPublicId = This->publicId;
2132 return S_OK;
2135 static HRESULT WINAPI isaxlocator_getSystemId(
2136 ISAXLocator* iface,
2137 const WCHAR ** ppwchSystemId)
2139 BSTR systemId;
2140 saxlocator *This = impl_from_ISAXLocator( iface );
2142 SysFreeString(This->systemId);
2144 systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt));
2145 if(SysStringLen(systemId))
2146 This->systemId = (WCHAR*)&systemId;
2147 else
2149 SysFreeString(systemId);
2150 This->systemId = NULL;
2153 *ppwchSystemId = This->systemId;
2154 return S_OK;
2157 static const struct ISAXLocatorVtbl SAXLocatorVtbl =
2159 isaxlocator_QueryInterface,
2160 isaxlocator_AddRef,
2161 isaxlocator_Release,
2162 isaxlocator_getColumnNumber,
2163 isaxlocator_getLineNumber,
2164 isaxlocator_getPublicId,
2165 isaxlocator_getSystemId
2168 static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator, BOOL vbInterface)
2170 static const WCHAR w3xmlns[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2171 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2173 saxlocator *locator;
2175 locator = heap_alloc( sizeof (*locator) );
2176 if( !locator )
2177 return E_OUTOFMEMORY;
2179 locator->IVBSAXLocator_iface.lpVtbl = &VBSAXLocatorVtbl;
2180 locator->ISAXLocator_iface.lpVtbl = &SAXLocatorVtbl;
2181 locator->IVBSAXAttributes_iface.lpVtbl = &ivbsaxattributes_vtbl;
2182 locator->ISAXAttributes_iface.lpVtbl = &isaxattributes_vtbl;
2183 locator->ref = 1;
2184 locator->vbInterface = vbInterface;
2186 locator->saxreader = reader;
2187 ISAXXMLReader_AddRef(&reader->ISAXXMLReader_iface);
2189 locator->pParserCtxt = NULL;
2190 locator->publicId = NULL;
2191 locator->systemId = NULL;
2192 locator->line = reader->version < MSXML4 ? 0 : 1;
2193 locator->column = 0;
2194 locator->ret = S_OK;
2195 if (locator->saxreader->version >= MSXML6)
2196 locator->namespaceUri = SysAllocString(w3xmlns);
2197 else
2198 locator->namespaceUri = SysAllocStringLen(NULL, 0);
2199 if(!locator->namespaceUri)
2201 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2202 heap_free(locator);
2203 return E_OUTOFMEMORY;
2206 locator->attributesSize = 8;
2207 locator->nb_attributes = 0;
2208 locator->attributes = heap_alloc(sizeof(struct _attributes)*locator->attributesSize);
2209 if(!locator->attributes)
2211 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2212 SysFreeString(locator->namespaceUri);
2213 heap_free(locator);
2214 return E_OUTOFMEMORY;
2217 list_init(&locator->elements);
2219 *ppsaxlocator = locator;
2221 TRACE("returning %p\n", *ppsaxlocator);
2223 return S_OK;
2226 /*** SAXXMLReader internal functions ***/
2227 static HRESULT internal_parseBuffer(saxreader *This, const char *buffer, int size, BOOL vbInterface)
2229 xmlCharEncoding encoding = XML_CHAR_ENCODING_NONE;
2230 xmlChar *enc_name = NULL;
2231 saxlocator *locator;
2232 HRESULT hr;
2234 TRACE("(%p)->(%p %d)\n", This, buffer, size);
2236 hr = SAXLocator_create(This, &locator, vbInterface);
2237 if (FAILED(hr))
2238 return hr;
2240 if (size >= 4)
2242 const unsigned char *buff = (unsigned char*)buffer;
2244 encoding = xmlDetectCharEncoding((xmlChar*)buffer, 4);
2245 enc_name = (xmlChar*)xmlGetCharEncodingName(encoding);
2246 TRACE("detected encoding: %s\n", enc_name);
2247 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2248 if ((encoding == XML_CHAR_ENCODING_UTF8) &&
2249 buff[0] == 0xEF && buff[1] == 0xBB && buff[2] == 0xBF)
2251 buffer += 3;
2252 size -= 3;
2256 /* if libxml2 detection failed try to guess */
2257 if (encoding == XML_CHAR_ENCODING_NONE)
2259 const WCHAR *ptr = (WCHAR*)buffer;
2260 /* xml declaration with possibly specfied encoding will be still handled by parser */
2261 if ((size >= 2) && *ptr == '<' && ptr[1] != '?')
2263 enc_name = (xmlChar*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE);
2264 encoding = XML_CHAR_ENCODING_UTF16LE;
2267 else if (encoding == XML_CHAR_ENCODING_UTF8)
2268 enc_name = (xmlChar*)xmlGetCharEncodingName(encoding);
2269 else
2270 enc_name = NULL;
2272 locator->pParserCtxt = xmlCreateMemoryParserCtxt(buffer, size);
2273 if (!locator->pParserCtxt)
2275 ISAXLocator_Release(&locator->ISAXLocator_iface);
2276 return E_FAIL;
2279 if (enc_name)
2281 locator->pParserCtxt->encoding = xmlStrdup(enc_name);
2282 if (encoding == XML_CHAR_ENCODING_UTF16LE) {
2283 TRACE("switching to %s\n", enc_name);
2284 xmlSwitchEncoding(locator->pParserCtxt, encoding);
2288 xmlFree(locator->pParserCtxt->sax);
2289 locator->pParserCtxt->sax = &locator->saxreader->sax;
2290 locator->pParserCtxt->userData = locator;
2292 This->isParsing = TRUE;
2293 if(xmlParseDocument(locator->pParserCtxt) == -1 && locator->ret == S_OK)
2294 hr = E_FAIL;
2295 else
2296 hr = locator->ret;
2297 This->isParsing = FALSE;
2299 if(locator->pParserCtxt)
2301 locator->pParserCtxt->sax = NULL;
2302 xmlFreeParserCtxt(locator->pParserCtxt);
2303 locator->pParserCtxt = NULL;
2306 ISAXLocator_Release(&locator->ISAXLocator_iface);
2307 return hr;
2310 static HRESULT internal_parseStream(saxreader *This, IStream *stream, BOOL vbInterface)
2312 saxlocator *locator;
2313 HRESULT hr;
2314 ULONG dataRead;
2315 char data[1024];
2316 int ret;
2318 dataRead = 0;
2319 hr = IStream_Read(stream, data, sizeof(data), &dataRead);
2320 if(FAILED(hr)) return hr;
2322 hr = SAXLocator_create(This, &locator, vbInterface);
2323 if(FAILED(hr)) return hr;
2325 locator->pParserCtxt = xmlCreatePushParserCtxt(
2326 &locator->saxreader->sax, locator,
2327 data, dataRead, NULL);
2328 if(!locator->pParserCtxt)
2330 ISAXLocator_Release(&locator->ISAXLocator_iface);
2331 return E_FAIL;
2334 This->isParsing = TRUE;
2336 if(dataRead != sizeof(data))
2338 ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
2339 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2341 else
2343 while(1)
2345 dataRead = 0;
2346 hr = IStream_Read(stream, data, sizeof(data), &dataRead);
2347 if (FAILED(hr)) break;
2349 ret = xmlParseChunk(locator->pParserCtxt, data, dataRead, 0);
2350 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2352 if (hr != S_OK) break;
2354 if (dataRead != sizeof(data))
2356 ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
2357 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2358 break;
2363 This->isParsing = FALSE;
2365 xmlFreeParserCtxt(locator->pParserCtxt);
2366 locator->pParserCtxt = NULL;
2367 ISAXLocator_Release(&locator->ISAXLocator_iface);
2368 return hr;
2371 static HRESULT internal_getEntityResolver(
2372 saxreader *This,
2373 void *pEntityResolver,
2374 BOOL vbInterface)
2376 FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
2377 return E_NOTIMPL;
2380 static HRESULT internal_putEntityResolver(
2381 saxreader *This,
2382 void *pEntityResolver,
2383 BOOL vbInterface)
2385 FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
2386 return E_NOTIMPL;
2389 static HRESULT internal_parse(
2390 saxreader* This,
2391 VARIANT varInput,
2392 BOOL vbInterface)
2394 HRESULT hr;
2396 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varInput));
2398 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2399 free_bstr_pool(&This->pool);
2401 switch(V_VT(&varInput))
2403 case VT_BSTR:
2404 hr = internal_parseBuffer(This, (const char*)V_BSTR(&varInput),
2405 strlenW(V_BSTR(&varInput))*sizeof(WCHAR), vbInterface);
2406 break;
2407 case VT_ARRAY|VT_UI1: {
2408 void *pSAData;
2409 LONG lBound, uBound;
2410 ULONG dataRead;
2412 hr = SafeArrayGetLBound(V_ARRAY(&varInput), 1, &lBound);
2413 if(hr != S_OK) break;
2414 hr = SafeArrayGetUBound(V_ARRAY(&varInput), 1, &uBound);
2415 if(hr != S_OK) break;
2416 dataRead = (uBound-lBound)*SafeArrayGetElemsize(V_ARRAY(&varInput));
2417 hr = SafeArrayAccessData(V_ARRAY(&varInput), &pSAData);
2418 if(hr != S_OK) break;
2419 hr = internal_parseBuffer(This, pSAData, dataRead, vbInterface);
2420 SafeArrayUnaccessData(V_ARRAY(&varInput));
2421 break;
2423 case VT_UNKNOWN:
2424 case VT_DISPATCH: {
2425 IPersistStream *persistStream;
2426 IStream *stream = NULL;
2427 IXMLDOMDocument *xmlDoc;
2429 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2430 &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK)
2432 BSTR bstrData;
2434 IXMLDOMDocument_get_xml(xmlDoc, &bstrData);
2435 hr = internal_parseBuffer(This, (const char*)bstrData,
2436 SysStringByteLen(bstrData), vbInterface);
2437 IXMLDOMDocument_Release(xmlDoc);
2438 SysFreeString(bstrData);
2439 break;
2442 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2443 &IID_IPersistStream, (void**)&persistStream) == S_OK)
2445 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
2446 if(hr != S_OK)
2448 IPersistStream_Release(persistStream);
2449 return hr;
2452 hr = IPersistStream_Save(persistStream, stream, TRUE);
2453 IPersistStream_Release(persistStream);
2454 if(hr != S_OK)
2456 IStream_Release(stream);
2457 stream = NULL;
2461 if(stream || IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2462 &IID_IStream, (void**)&stream) == S_OK)
2464 hr = internal_parseStream(This, stream, vbInterface);
2465 IStream_Release(stream);
2466 break;
2469 default:
2470 WARN("vt %d not implemented\n", V_VT(&varInput));
2471 hr = E_INVALIDARG;
2474 return hr;
2477 static HRESULT internal_vbonDataAvailable(void *obj, char *ptr, DWORD len)
2479 saxreader *This = obj;
2481 return internal_parseBuffer(This, ptr, len, TRUE);
2484 static HRESULT internal_onDataAvailable(void *obj, char *ptr, DWORD len)
2486 saxreader *This = obj;
2488 return internal_parseBuffer(This, ptr, len, FALSE);
2491 static HRESULT internal_parseURL(
2492 saxreader* This,
2493 const WCHAR *url,
2494 BOOL vbInterface)
2496 IMoniker *mon;
2497 bsc_t *bsc;
2498 HRESULT hr;
2500 TRACE("(%p)->(%s)\n", This, debugstr_w(url));
2502 hr = create_moniker_from_url(url, &mon);
2503 if(FAILED(hr))
2504 return hr;
2506 if(vbInterface) hr = bind_url(mon, internal_vbonDataAvailable, This, &bsc);
2507 else hr = bind_url(mon, internal_onDataAvailable, This, &bsc);
2508 IMoniker_Release(mon);
2510 if(FAILED(hr))
2511 return hr;
2513 return detach_bsc(bsc);
2516 static HRESULT internal_putProperty(
2517 saxreader* This,
2518 const WCHAR *prop,
2519 VARIANT value,
2520 BOOL vbInterface)
2522 TRACE("(%p)->(%s %s)\n", This, debugstr_w(prop), debugstr_variant(&value));
2524 if(!memcmp(prop, PropertyDeclHandlerW, sizeof(PropertyDeclHandlerW)))
2526 if(This->isParsing) return E_FAIL;
2528 switch (V_VT(&value))
2530 case VT_EMPTY:
2531 saxreader_put_handler(This, SAXDeclHandler, NULL, vbInterface);
2532 break;
2533 case VT_UNKNOWN:
2535 IUnknown *handler = NULL;
2537 if (V_UNKNOWN(&value))
2539 HRESULT hr;
2541 if (vbInterface)
2542 hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXDeclHandler, (void**)&handler);
2543 else
2544 hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_ISAXDeclHandler, (void**)&handler);
2545 if (FAILED(hr)) return hr;
2548 saxreader_put_handler(This, SAXDeclHandler, handler, vbInterface);
2549 if (handler) IUnknown_Release(handler);
2550 break;
2552 default:
2553 return E_INVALIDARG;
2556 return S_OK;
2559 if(!memcmp(prop, PropertyLexicalHandlerW, sizeof(PropertyLexicalHandlerW)))
2561 if(This->isParsing) return E_FAIL;
2563 switch (V_VT(&value))
2565 case VT_EMPTY:
2566 saxreader_put_handler(This, SAXLexicalHandler, NULL, vbInterface);
2567 break;
2568 case VT_UNKNOWN:
2570 IUnknown *handler = NULL;
2572 if (V_UNKNOWN(&value))
2574 HRESULT hr;
2576 if (vbInterface)
2577 hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXLexicalHandler, (void**)&handler);
2578 else
2579 hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_ISAXLexicalHandler, (void**)&handler);
2580 if (FAILED(hr)) return hr;
2583 saxreader_put_handler(This, SAXLexicalHandler, handler, vbInterface);
2584 if (handler) IUnknown_Release(handler);
2585 break;
2587 default:
2588 return E_INVALIDARG;
2591 return S_OK;
2594 if(!memcmp(prop, PropertyMaxXMLSizeW, sizeof(PropertyMaxXMLSizeW)))
2596 if (V_VT(&value) == VT_I4 && V_I4(&value) == 0) return S_OK;
2597 FIXME("(%p)->(%s): max-xml-size unsupported\n", This, debugstr_variant(&value));
2598 return E_NOTIMPL;
2601 if(!memcmp(prop, PropertyMaxElementDepthW, sizeof(PropertyMaxElementDepthW)))
2603 if (V_VT(&value) == VT_I4 && V_I4(&value) == 0) return S_OK;
2604 FIXME("(%p)->(%s): max-element-depth unsupported\n", This, debugstr_variant(&value));
2605 return E_NOTIMPL;
2608 FIXME("(%p)->(%s:%s): unsupported property\n", This, debugstr_w(prop), debugstr_variant(&value));
2610 if(!memcmp(prop, PropertyCharsetW, sizeof(PropertyCharsetW)))
2611 return E_NOTIMPL;
2613 if(!memcmp(prop, PropertyDomNodeW, sizeof(PropertyDomNodeW)))
2614 return E_FAIL;
2616 if(!memcmp(prop, PropertyInputSourceW, sizeof(PropertyInputSourceW)))
2617 return E_NOTIMPL;
2619 if(!memcmp(prop, PropertySchemaDeclHandlerW, sizeof(PropertySchemaDeclHandlerW)))
2620 return E_NOTIMPL;
2622 if(!memcmp(prop, PropertyXMLDeclEncodingW, sizeof(PropertyXMLDeclEncodingW)))
2623 return E_FAIL;
2625 if(!memcmp(prop, PropertyXMLDeclStandaloneW, sizeof(PropertyXMLDeclStandaloneW)))
2626 return E_FAIL;
2628 if(!memcmp(prop, PropertyXMLDeclVersionW, sizeof(PropertyXMLDeclVersionW)))
2629 return E_FAIL;
2631 return E_INVALIDARG;
2634 static HRESULT internal_getProperty(const saxreader* This, const WCHAR *prop, VARIANT *value, BOOL vb)
2636 TRACE("(%p)->(%s)\n", This, debugstr_w(prop));
2638 if (!value) return E_POINTER;
2640 if (!memcmp(PropertyLexicalHandlerW, prop, sizeof(PropertyLexicalHandlerW)))
2642 V_VT(value) = VT_UNKNOWN;
2643 saxreader_get_handler(This, SAXLexicalHandler, vb, (void**)&V_UNKNOWN(value));
2644 return S_OK;
2647 if (!memcmp(PropertyDeclHandlerW, prop, sizeof(PropertyDeclHandlerW)))
2649 V_VT(value) = VT_UNKNOWN;
2650 saxreader_get_handler(This, SAXDeclHandler, vb, (void**)&V_UNKNOWN(value));
2651 return S_OK;
2654 FIXME("(%p)->(%s) unsupported property\n", This, debugstr_w(prop));
2656 return E_NOTIMPL;
2659 /*** IVBSAXXMLReader interface ***/
2660 /*** IUnknown methods ***/
2661 static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject)
2663 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2665 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
2667 *ppvObject = NULL;
2669 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2670 IsEqualGUID( riid, &IID_IDispatch ) ||
2671 IsEqualGUID( riid, &IID_IVBSAXXMLReader ))
2673 *ppvObject = iface;
2675 else if( IsEqualGUID( riid, &IID_ISAXXMLReader ))
2677 *ppvObject = &This->ISAXXMLReader_iface;
2679 else if (dispex_query_interface(&This->dispex, riid, ppvObject))
2681 return *ppvObject ? S_OK : E_NOINTERFACE;
2683 else
2685 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2686 return E_NOINTERFACE;
2689 IVBSAXXMLReader_AddRef( iface );
2691 return S_OK;
2694 static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface)
2696 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2697 TRACE("%p\n", This );
2698 return InterlockedIncrement( &This->ref );
2701 static ULONG WINAPI saxxmlreader_Release(
2702 IVBSAXXMLReader* iface)
2704 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2705 LONG ref;
2707 TRACE("%p\n", This );
2709 ref = InterlockedDecrement( &This->ref );
2710 if ( ref == 0 )
2712 int i;
2714 for (i = 0; i < SAXHandler_Last; i++)
2716 struct saxhandler_iface *iface = &This->saxhandlers[i];
2718 if (iface->handler)
2719 IUnknown_Release(iface->handler);
2721 if (iface->vbhandler)
2722 IUnknown_Release(iface->vbhandler);
2725 free_bstr_pool(&This->pool);
2727 release_dispex(&This->dispex);
2728 heap_free( This );
2731 return ref;
2733 /*** IDispatch ***/
2734 static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo )
2736 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2737 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2740 static HRESULT WINAPI saxxmlreader_GetTypeInfo(
2741 IVBSAXXMLReader *iface,
2742 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
2744 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2745 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
2746 iTInfo, lcid, ppTInfo);
2749 static HRESULT WINAPI saxxmlreader_GetIDsOfNames(
2750 IVBSAXXMLReader *iface,
2751 REFIID riid,
2752 LPOLESTR* rgszNames,
2753 UINT cNames,
2754 LCID lcid,
2755 DISPID* rgDispId)
2757 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2758 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2759 riid, rgszNames, cNames, lcid, rgDispId);
2762 static HRESULT WINAPI saxxmlreader_Invoke(
2763 IVBSAXXMLReader *iface,
2764 DISPID dispIdMember,
2765 REFIID riid,
2766 LCID lcid,
2767 WORD wFlags,
2768 DISPPARAMS* pDispParams,
2769 VARIANT* pVarResult,
2770 EXCEPINFO* pExcepInfo,
2771 UINT* puArgErr)
2773 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2774 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
2775 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2778 /*** IVBSAXXMLReader methods ***/
2779 static HRESULT WINAPI saxxmlreader_getFeature(
2780 IVBSAXXMLReader* iface,
2781 const WCHAR *feature_name,
2782 VARIANT_BOOL *value)
2784 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2785 saxreader_feature feature;
2787 TRACE("(%p)->(%s %p)\n", This, debugstr_w(feature_name), value);
2789 feature = get_saxreader_feature(feature_name);
2790 if (feature == Namespaces || feature == NamespacePrefixes)
2791 return get_feature_value(This, feature, value);
2793 FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(feature_name), value);
2794 return E_NOTIMPL;
2797 static HRESULT WINAPI saxxmlreader_putFeature(
2798 IVBSAXXMLReader* iface,
2799 const WCHAR *feature_name,
2800 VARIANT_BOOL value)
2802 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2803 saxreader_feature feature;
2805 TRACE("(%p)->(%s %x)\n", This, debugstr_w(feature_name), value);
2807 feature = get_saxreader_feature(feature_name);
2809 /* accepted cases */
2810 if ((feature == ExternalGeneralEntities && value == VARIANT_FALSE) ||
2811 (feature == ExternalParameterEntities && value == VARIANT_FALSE) ||
2812 feature == Namespaces ||
2813 feature == NamespacePrefixes)
2815 return set_feature_value(This, feature, value);
2818 if (feature == LexicalHandlerParEntities || feature == ProhibitDTD)
2820 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
2821 return set_feature_value(This, feature, value);
2824 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
2825 return E_NOTIMPL;
2828 static HRESULT WINAPI saxxmlreader_getProperty(
2829 IVBSAXXMLReader* iface,
2830 const WCHAR *prop,
2831 VARIANT *value)
2833 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2834 return internal_getProperty(This, prop, value, TRUE);
2837 static HRESULT WINAPI saxxmlreader_putProperty(
2838 IVBSAXXMLReader* iface,
2839 const WCHAR *pProp,
2840 VARIANT value)
2842 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2843 return internal_putProperty(This, pProp, value, TRUE);
2846 static HRESULT WINAPI saxxmlreader_get_entityResolver(
2847 IVBSAXXMLReader* iface,
2848 IVBSAXEntityResolver **pEntityResolver)
2850 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2851 return internal_getEntityResolver(This, pEntityResolver, TRUE);
2854 static HRESULT WINAPI saxxmlreader_put_entityResolver(
2855 IVBSAXXMLReader* iface,
2856 IVBSAXEntityResolver *pEntityResolver)
2858 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2859 return internal_putEntityResolver(This, pEntityResolver, TRUE);
2862 static HRESULT WINAPI saxxmlreader_get_contentHandler(
2863 IVBSAXXMLReader* iface,
2864 IVBSAXContentHandler **handler)
2866 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2867 return saxreader_get_handler(This, SAXContentHandler, TRUE, (void**)handler);
2870 static HRESULT WINAPI saxxmlreader_put_contentHandler(
2871 IVBSAXXMLReader* iface,
2872 IVBSAXContentHandler *handler)
2874 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2875 return saxreader_put_handler(This, SAXContentHandler, handler, TRUE);
2878 static HRESULT WINAPI saxxmlreader_get_dtdHandler(
2879 IVBSAXXMLReader* iface,
2880 IVBSAXDTDHandler **handler)
2882 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2883 return saxreader_get_handler(This, SAXDTDHandler, TRUE, (void**)handler);
2886 static HRESULT WINAPI saxxmlreader_put_dtdHandler(
2887 IVBSAXXMLReader* iface,
2888 IVBSAXDTDHandler *handler)
2890 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2891 return saxreader_put_handler(This, SAXDTDHandler, handler, TRUE);
2894 static HRESULT WINAPI saxxmlreader_get_errorHandler(
2895 IVBSAXXMLReader* iface,
2896 IVBSAXErrorHandler **handler)
2898 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2899 return saxreader_get_handler(This, SAXErrorHandler, TRUE, (void**)handler);
2902 static HRESULT WINAPI saxxmlreader_put_errorHandler(
2903 IVBSAXXMLReader* iface,
2904 IVBSAXErrorHandler *handler)
2906 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2907 return saxreader_put_handler(This, SAXErrorHandler, handler, TRUE);
2910 static HRESULT WINAPI saxxmlreader_get_baseURL(
2911 IVBSAXXMLReader* iface,
2912 const WCHAR **pBaseUrl)
2914 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2916 FIXME("(%p)->(%p) stub\n", This, pBaseUrl);
2917 return E_NOTIMPL;
2920 static HRESULT WINAPI saxxmlreader_put_baseURL(
2921 IVBSAXXMLReader* iface,
2922 const WCHAR *pBaseUrl)
2924 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2926 FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
2927 return E_NOTIMPL;
2930 static HRESULT WINAPI saxxmlreader_get_secureBaseURL(
2931 IVBSAXXMLReader* iface,
2932 const WCHAR **pSecureBaseUrl)
2934 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2936 FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
2937 return E_NOTIMPL;
2941 static HRESULT WINAPI saxxmlreader_put_secureBaseURL(
2942 IVBSAXXMLReader* iface,
2943 const WCHAR *secureBaseUrl)
2945 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2947 FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
2948 return E_NOTIMPL;
2951 static HRESULT WINAPI saxxmlreader_parse(
2952 IVBSAXXMLReader* iface,
2953 VARIANT varInput)
2955 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2956 return internal_parse(This, varInput, TRUE);
2959 static HRESULT WINAPI saxxmlreader_parseURL(
2960 IVBSAXXMLReader* iface,
2961 const WCHAR *url)
2963 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2964 return internal_parseURL(This, url, TRUE);
2967 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl =
2969 saxxmlreader_QueryInterface,
2970 saxxmlreader_AddRef,
2971 saxxmlreader_Release,
2972 saxxmlreader_GetTypeInfoCount,
2973 saxxmlreader_GetTypeInfo,
2974 saxxmlreader_GetIDsOfNames,
2975 saxxmlreader_Invoke,
2976 saxxmlreader_getFeature,
2977 saxxmlreader_putFeature,
2978 saxxmlreader_getProperty,
2979 saxxmlreader_putProperty,
2980 saxxmlreader_get_entityResolver,
2981 saxxmlreader_put_entityResolver,
2982 saxxmlreader_get_contentHandler,
2983 saxxmlreader_put_contentHandler,
2984 saxxmlreader_get_dtdHandler,
2985 saxxmlreader_put_dtdHandler,
2986 saxxmlreader_get_errorHandler,
2987 saxxmlreader_put_errorHandler,
2988 saxxmlreader_get_baseURL,
2989 saxxmlreader_put_baseURL,
2990 saxxmlreader_get_secureBaseURL,
2991 saxxmlreader_put_secureBaseURL,
2992 saxxmlreader_parse,
2993 saxxmlreader_parseURL
2996 /*** ISAXXMLReader interface ***/
2997 /*** IUnknown methods ***/
2998 static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject)
3000 saxreader *This = impl_from_ISAXXMLReader( iface );
3001 return saxxmlreader_QueryInterface(&This->IVBSAXXMLReader_iface, riid, ppvObject);
3004 static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface)
3006 saxreader *This = impl_from_ISAXXMLReader( iface );
3007 return saxxmlreader_AddRef(&This->IVBSAXXMLReader_iface);
3010 static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface)
3012 saxreader *This = impl_from_ISAXXMLReader( iface );
3013 return saxxmlreader_Release(&This->IVBSAXXMLReader_iface);
3016 /*** ISAXXMLReader methods ***/
3017 static HRESULT WINAPI isaxxmlreader_getFeature(
3018 ISAXXMLReader* iface,
3019 const WCHAR *pFeature,
3020 VARIANT_BOOL *pValue)
3022 saxreader *This = impl_from_ISAXXMLReader( iface );
3023 return IVBSAXXMLReader_getFeature(&This->IVBSAXXMLReader_iface, pFeature, pValue);
3026 static HRESULT WINAPI isaxxmlreader_putFeature(
3027 ISAXXMLReader* iface,
3028 const WCHAR *pFeature,
3029 VARIANT_BOOL vfValue)
3031 saxreader *This = impl_from_ISAXXMLReader( iface );
3032 return IVBSAXXMLReader_putFeature(&This->IVBSAXXMLReader_iface, pFeature, vfValue);
3035 static HRESULT WINAPI isaxxmlreader_getProperty(
3036 ISAXXMLReader* iface,
3037 const WCHAR *prop,
3038 VARIANT *value)
3040 saxreader *This = impl_from_ISAXXMLReader( iface );
3041 return internal_getProperty(This, prop, value, FALSE);
3044 static HRESULT WINAPI isaxxmlreader_putProperty(
3045 ISAXXMLReader* iface,
3046 const WCHAR *pProp,
3047 VARIANT value)
3049 saxreader *This = impl_from_ISAXXMLReader( iface );
3050 return internal_putProperty(This, pProp, value, FALSE);
3053 static HRESULT WINAPI isaxxmlreader_getEntityResolver(
3054 ISAXXMLReader* iface,
3055 ISAXEntityResolver **ppEntityResolver)
3057 saxreader *This = impl_from_ISAXXMLReader( iface );
3058 return internal_getEntityResolver(This, ppEntityResolver, FALSE);
3061 static HRESULT WINAPI isaxxmlreader_putEntityResolver(
3062 ISAXXMLReader* iface,
3063 ISAXEntityResolver *pEntityResolver)
3065 saxreader *This = impl_from_ISAXXMLReader( iface );
3066 return internal_putEntityResolver(This, pEntityResolver, FALSE);
3069 static HRESULT WINAPI isaxxmlreader_getContentHandler(
3070 ISAXXMLReader* iface,
3071 ISAXContentHandler **handler)
3073 saxreader *This = impl_from_ISAXXMLReader( iface );
3074 return saxreader_get_handler(This, SAXContentHandler, FALSE, (void**)handler);
3077 static HRESULT WINAPI isaxxmlreader_putContentHandler(
3078 ISAXXMLReader* iface,
3079 ISAXContentHandler *handler)
3081 saxreader *This = impl_from_ISAXXMLReader( iface );
3082 return saxreader_put_handler(This, SAXContentHandler, handler, FALSE);
3085 static HRESULT WINAPI isaxxmlreader_getDTDHandler(
3086 ISAXXMLReader* iface,
3087 ISAXDTDHandler **handler)
3089 saxreader *This = impl_from_ISAXXMLReader( iface );
3090 return saxreader_get_handler(This, SAXDTDHandler, FALSE, (void**)handler);
3093 static HRESULT WINAPI isaxxmlreader_putDTDHandler(
3094 ISAXXMLReader* iface,
3095 ISAXDTDHandler *handler)
3097 saxreader *This = impl_from_ISAXXMLReader( iface );
3098 return saxreader_put_handler(This, SAXDTDHandler, handler, FALSE);
3101 static HRESULT WINAPI isaxxmlreader_getErrorHandler(
3102 ISAXXMLReader* iface,
3103 ISAXErrorHandler **handler)
3105 saxreader *This = impl_from_ISAXXMLReader( iface );
3106 return saxreader_get_handler(This, SAXErrorHandler, FALSE, (void**)handler);
3109 static HRESULT WINAPI isaxxmlreader_putErrorHandler(ISAXXMLReader* iface, ISAXErrorHandler *handler)
3111 saxreader *This = impl_from_ISAXXMLReader( iface );
3112 return saxreader_put_handler(This, SAXErrorHandler, handler, FALSE);
3115 static HRESULT WINAPI isaxxmlreader_getBaseURL(
3116 ISAXXMLReader* iface,
3117 const WCHAR **pBaseUrl)
3119 saxreader *This = impl_from_ISAXXMLReader( iface );
3120 return IVBSAXXMLReader_get_baseURL(&This->IVBSAXXMLReader_iface, pBaseUrl);
3123 static HRESULT WINAPI isaxxmlreader_putBaseURL(
3124 ISAXXMLReader* iface,
3125 const WCHAR *pBaseUrl)
3127 saxreader *This = impl_from_ISAXXMLReader( iface );
3128 return IVBSAXXMLReader_put_baseURL(&This->IVBSAXXMLReader_iface, pBaseUrl);
3131 static HRESULT WINAPI isaxxmlreader_getSecureBaseURL(
3132 ISAXXMLReader* iface,
3133 const WCHAR **pSecureBaseUrl)
3135 saxreader *This = impl_from_ISAXXMLReader( iface );
3136 return IVBSAXXMLReader_get_secureBaseURL(&This->IVBSAXXMLReader_iface, pSecureBaseUrl);
3139 static HRESULT WINAPI isaxxmlreader_putSecureBaseURL(
3140 ISAXXMLReader* iface,
3141 const WCHAR *secureBaseUrl)
3143 saxreader *This = impl_from_ISAXXMLReader( iface );
3144 return IVBSAXXMLReader_put_secureBaseURL(&This->IVBSAXXMLReader_iface, secureBaseUrl);
3147 static HRESULT WINAPI isaxxmlreader_parse(
3148 ISAXXMLReader* iface,
3149 VARIANT varInput)
3151 saxreader *This = impl_from_ISAXXMLReader( iface );
3152 return internal_parse(This, varInput, FALSE);
3155 static HRESULT WINAPI isaxxmlreader_parseURL(
3156 ISAXXMLReader* iface,
3157 const WCHAR *url)
3159 saxreader *This = impl_from_ISAXXMLReader( iface );
3160 return internal_parseURL(This, url, FALSE);
3163 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl =
3165 isaxxmlreader_QueryInterface,
3166 isaxxmlreader_AddRef,
3167 isaxxmlreader_Release,
3168 isaxxmlreader_getFeature,
3169 isaxxmlreader_putFeature,
3170 isaxxmlreader_getProperty,
3171 isaxxmlreader_putProperty,
3172 isaxxmlreader_getEntityResolver,
3173 isaxxmlreader_putEntityResolver,
3174 isaxxmlreader_getContentHandler,
3175 isaxxmlreader_putContentHandler,
3176 isaxxmlreader_getDTDHandler,
3177 isaxxmlreader_putDTDHandler,
3178 isaxxmlreader_getErrorHandler,
3179 isaxxmlreader_putErrorHandler,
3180 isaxxmlreader_getBaseURL,
3181 isaxxmlreader_putBaseURL,
3182 isaxxmlreader_getSecureBaseURL,
3183 isaxxmlreader_putSecureBaseURL,
3184 isaxxmlreader_parse,
3185 isaxxmlreader_parseURL
3188 static const tid_t saxreader_iface_tids[] = {
3189 IVBSAXXMLReader_tid,
3192 static dispex_static_data_t saxreader_dispex = {
3193 NULL,
3194 IVBSAXXMLReader_tid,
3195 NULL,
3196 saxreader_iface_tids
3199 HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *outer, LPVOID *ppObj)
3201 saxreader *reader;
3203 TRACE("(%p, %p)\n", outer, ppObj);
3205 reader = heap_alloc( sizeof (*reader) );
3206 if( !reader )
3207 return E_OUTOFMEMORY;
3209 reader->IVBSAXXMLReader_iface.lpVtbl = &VBSAXXMLReaderVtbl;
3210 reader->ISAXXMLReader_iface.lpVtbl = &SAXXMLReaderVtbl;
3211 reader->ref = 1;
3212 memset(reader->saxhandlers, 0, sizeof(reader->saxhandlers));
3213 reader->isParsing = FALSE;
3214 reader->pool.pool = NULL;
3215 reader->pool.index = 0;
3216 reader->pool.len = 0;
3217 reader->features = Namespaces | NamespacePrefixes;
3218 reader->version = version;
3220 init_dispex(&reader->dispex, (IUnknown*)&reader->IVBSAXXMLReader_iface, &saxreader_dispex);
3222 memset(&reader->sax, 0, sizeof(xmlSAXHandler));
3223 reader->sax.initialized = XML_SAX2_MAGIC;
3224 reader->sax.startDocument = libxmlStartDocument;
3225 reader->sax.endDocument = libxmlEndDocument;
3226 reader->sax.startElementNs = libxmlStartElementNS;
3227 reader->sax.endElementNs = libxmlEndElementNS;
3228 reader->sax.characters = libxmlCharacters;
3229 reader->sax.setDocumentLocator = libxmlSetDocumentLocator;
3230 reader->sax.comment = libxmlComment;
3231 reader->sax.error = libxmlFatalError;
3232 reader->sax.fatalError = libxmlFatalError;
3233 reader->sax.cdataBlock = libxmlCDataBlock;
3235 *ppObj = &reader->IVBSAXXMLReader_iface;
3237 TRACE("returning iface %p\n", *ppObj);
3239 return S_OK;
3242 #else
3244 HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *pUnkOuter, LPVOID *ppObj)
3246 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3247 "libxml2 support was not present at compile time.\n");
3248 return E_NOTIMPL;
3251 #endif