ReactOS 0.4.15-dev-7942-gd23573b
saxreader.c
Go to the documentation of this file.
1/*
2 * SAX Reader implementation
3 *
4 * Copyright 2008 Alistair Leslie-Hughes
5 * Copyright 2008 Piotr Caban
6 *
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.
11 *
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.
16 *
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
20 */
21#define COBJMACROS
22
23#include "config.h"
24
25#include <stdarg.h>
26#ifdef HAVE_LIBXML2
27# include <libxml/parser.h>
28# include <libxml/xmlerror.h>
29# include <libxml/SAX2.h>
31#endif
32
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"
43
44#include "wine/debug.h"
45
46#include "msxml_private.h"
47
48#ifdef HAVE_LIBXML2
49
51
52typedef enum
53{
54 FeatureUnknown = 0,
55 ExhaustiveErrors = 1 << 1,
56 ExternalGeneralEntities = 1 << 2,
57 ExternalParameterEntities = 1 << 3,
58 ForcedResync = 1 << 4,
59 NamespacePrefixes = 1 << 5,
60 Namespaces = 1 << 6,
61 ParameterEntities = 1 << 7,
62 PreserveSystemIndentifiers = 1 << 8,
63 ProhibitDTD = 1 << 9,
64 SchemaValidation = 1 << 10,
65 ServerHttpRequest = 1 << 11,
66 SuppressValidationfatalError = 1 << 12,
67 UseInlineSchema = 1 << 13,
68 UseSchemaLocation = 1 << 14,
69 LexicalHandlerParEntities = 1 << 15
70} saxreader_feature;
71
72/* feature names */
73static const WCHAR FeatureExternalGeneralEntitiesW[] = {
74 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/',
75 'f','e','a','t','u','r','e','s','/','e','x','t','e','r','n','a','l','-','g','e','n','e','r','a','l',
76 '-','e','n','t','i','t','i','e','s',0
77};
78
79static const WCHAR FeatureExternalParameterEntitiesW[] = {
80 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
81 '/','e','x','t','e','r','n','a','l','-','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0
82};
83
84static const WCHAR FeatureLexicalHandlerParEntitiesW[] = {
85 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
86 '/','l','e','x','i','c','a','l','-','h','a','n','d','l','e','r','/','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0
87};
88
89static const WCHAR FeatureProhibitDTDW[] = {
90 'p','r','o','h','i','b','i','t','-','d','t','d',0
91};
92
93static const WCHAR FeatureNamespacesW[] = {
94 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
95 '/','n','a','m','e','s','p','a','c','e','s',0
96};
97
98static const WCHAR FeatureNamespacePrefixesW[] = {
99 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
100 '/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0
101};
102
103static const WCHAR ExhaustiveErrorsW[] = {
104 'e','x','h','a','u','s','t','i','v','e','-','e','r','r','o','r','s',0
105};
106
107static const WCHAR SchemaValidationW[] = {
108 's','c','h','e','m','a','-','v','a','l','i','d','a','t','i','o','n',0
109};
110
111struct saxreader_feature_pair
112{
113 saxreader_feature feature;
114 const WCHAR *name;
115};
116
117static const struct saxreader_feature_pair saxreader_feature_map[] = {
118 { ExhaustiveErrors, ExhaustiveErrorsW },
119 { ExternalGeneralEntities, FeatureExternalGeneralEntitiesW },
120 { ExternalParameterEntities, FeatureExternalParameterEntitiesW },
121 { LexicalHandlerParEntities, FeatureLexicalHandlerParEntitiesW },
122 { NamespacePrefixes, FeatureNamespacePrefixesW },
123 { Namespaces, FeatureNamespacesW },
124 { ProhibitDTD, FeatureProhibitDTDW },
125 { SchemaValidation, SchemaValidationW },
126};
127
128static saxreader_feature get_saxreader_feature(const WCHAR *name)
129{
130 int min, max, n, c;
131
132 min = 0;
133 max = ARRAY_SIZE(saxreader_feature_map) - 1;
134
135 while (min <= max)
136 {
137 n = (min+max)/2;
138
139 c = strcmpW(saxreader_feature_map[n].name, name);
140 if (!c)
141 return saxreader_feature_map[n].feature;
142
143 if (c > 0)
144 max = n-1;
145 else
146 min = n+1;
147 }
148
149 return FeatureUnknown;
150}
151
152static const WCHAR empty_str;
153
154struct bstrpool
155{
156 BSTR *pool;
157 unsigned int index;
158 unsigned int len;
159};
160
161typedef struct
162{
163 BSTR prefix;
164 BSTR uri;
165} ns;
166
167typedef struct
168{
169 struct list entry;
170 BSTR prefix;
171 BSTR local;
172 BSTR qname;
173 ns *ns; /* namespaces defined in this particular element */
174 int ns_count;
175} element_entry;
176
177enum saxhandler_type
178{
179 SAXContentHandler = 0,
180 SAXDeclHandler,
181 SAXDTDHandler,
182 SAXEntityResolver,
183 SAXErrorHandler,
184 SAXLexicalHandler,
185 SAXHandler_Last
186};
187
188struct saxanyhandler_iface
189{
191 IUnknown *vbhandler;
192};
193
194struct saxcontenthandler_iface
195{
196 ISAXContentHandler *handler;
197 IVBSAXContentHandler *vbhandler;
198};
199
200struct saxerrorhandler_iface
201{
202 ISAXErrorHandler *handler;
203 IVBSAXErrorHandler *vbhandler;
204};
205
206struct saxlexicalhandler_iface
207{
208 ISAXLexicalHandler *handler;
209 IVBSAXLexicalHandler *vbhandler;
210};
211
212struct saxentityresolver_iface
213{
214 ISAXEntityResolver *handler;
215 IVBSAXEntityResolver *vbhandler;
216};
217
218struct saxhandler_iface
219{
220 union {
221 struct saxcontenthandler_iface content;
222 struct saxentityresolver_iface entityresolver;
223 struct saxerrorhandler_iface error;
224 struct saxlexicalhandler_iface lexical;
225 struct saxanyhandler_iface anyhandler;
226 } u;
227};
228
229typedef struct
230{
231 DispatchEx dispex;
232 IVBSAXXMLReader IVBSAXXMLReader_iface;
233 ISAXXMLReader ISAXXMLReader_iface;
234 LONG ref;
235
236 struct saxhandler_iface saxhandlers[SAXHandler_Last];
238 BOOL isParsing;
239 struct bstrpool pool;
240 saxreader_feature features;
241 BSTR xmldecl_version;
243} saxreader;
244
245static HRESULT saxreader_put_handler(saxreader *reader, enum saxhandler_type type, void *ptr, BOOL vb)
246{
247 struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler;
248 IUnknown *unk = (IUnknown*)ptr;
249
250 if (unk)
251 IUnknown_AddRef(unk);
252
253 if ((vb && iface->vbhandler) || (!vb && iface->handler))
254 IUnknown_Release(vb ? iface->vbhandler : iface->handler);
255
256 if (vb)
257 iface->vbhandler = unk;
258 else
259 iface->handler = unk;
260
261 return S_OK;
262}
263
264static HRESULT saxreader_get_handler(const saxreader *reader, enum saxhandler_type type, BOOL vb, void **ret)
265{
266 const struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler;
267
268 if (!ret) return E_POINTER;
269
270 if ((vb && iface->vbhandler) || (!vb && iface->handler))
271 {
272 if (vb)
273 IUnknown_AddRef(iface->vbhandler);
274 else
275 IUnknown_AddRef(iface->handler);
276 }
277
278 *ret = vb ? iface->vbhandler : iface->handler;
279
280 return S_OK;
281}
282
283static struct saxcontenthandler_iface *saxreader_get_contenthandler(saxreader *reader)
284{
285 return &reader->saxhandlers[SAXContentHandler].u.content;
286}
287
288static struct saxerrorhandler_iface *saxreader_get_errorhandler(saxreader *reader)
289{
290 return &reader->saxhandlers[SAXErrorHandler].u.error;
291}
292
293static struct saxlexicalhandler_iface *saxreader_get_lexicalhandler(saxreader *reader)
294{
295 return &reader->saxhandlers[SAXLexicalHandler].u.lexical;
296}
297
298typedef struct
299{
300 IVBSAXLocator IVBSAXLocator_iface;
301 ISAXLocator ISAXLocator_iface;
302 IVBSAXAttributes IVBSAXAttributes_iface;
303 ISAXAttributes ISAXAttributes_iface;
304 LONG ref;
305 saxreader *saxreader;
306 HRESULT ret;
307 xmlParserCtxtPtr pParserCtxt;
308 BSTR publicId;
309 BSTR systemId;
310 int line;
311 int column;
312 BOOL vbInterface;
313 struct list elements;
314
315 BSTR namespaceUri;
316 int attr_alloc_count;
317 int attr_count;
318 struct _attributes
319 {
320 BSTR szLocalname;
321 BSTR szURI;
322 BSTR szValue;
323 BSTR szQName;
324 } *attributes;
325} saxlocator;
326
327static inline saxreader *impl_from_IVBSAXXMLReader( IVBSAXXMLReader *iface )
328{
329 return CONTAINING_RECORD(iface, saxreader, IVBSAXXMLReader_iface);
330}
331
332static inline saxreader *impl_from_ISAXXMLReader( ISAXXMLReader *iface )
333{
334 return CONTAINING_RECORD(iface, saxreader, ISAXXMLReader_iface);
335}
336
337static inline saxlocator *impl_from_IVBSAXLocator( IVBSAXLocator *iface )
338{
339 return CONTAINING_RECORD(iface, saxlocator, IVBSAXLocator_iface);
340}
341
342static inline saxlocator *impl_from_ISAXLocator( ISAXLocator *iface )
343{
344 return CONTAINING_RECORD(iface, saxlocator, ISAXLocator_iface);
345}
346
347static inline saxlocator *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
348{
349 return CONTAINING_RECORD(iface, saxlocator, IVBSAXAttributes_iface);
350}
351
352static inline saxlocator *impl_from_ISAXAttributes( ISAXAttributes *iface )
353{
354 return CONTAINING_RECORD(iface, saxlocator, ISAXAttributes_iface);
355}
356
357static inline BOOL saxreader_has_handler(const saxlocator *locator, enum saxhandler_type type)
358{
359 struct saxanyhandler_iface *iface = &locator->saxreader->saxhandlers[type].u.anyhandler;
360 return (locator->vbInterface && iface->vbhandler) || (!locator->vbInterface && iface->handler);
361}
362
363static HRESULT saxreader_saxcharacters(saxlocator *locator, BSTR chars)
364{
365 struct saxcontenthandler_iface *content = saxreader_get_contenthandler(locator->saxreader);
366 HRESULT hr;
367
368 if (!saxreader_has_handler(locator, SAXContentHandler)) return S_OK;
369
370 if (locator->vbInterface)
371 hr = IVBSAXContentHandler_characters(content->vbhandler, &chars);
372 else
373 hr = ISAXContentHandler_characters(content->handler, chars, SysStringLen(chars));
374
375 return hr;
376}
377
378/* property names */
379static const WCHAR PropertyCharsetW[] = {
380 'c','h','a','r','s','e','t',0
381};
382static const WCHAR PropertyXmlDeclVersionW[] = {
383 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
384};
385static const WCHAR PropertyDeclHandlerW[] = {
386 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
387 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
388 'd','e','c','l','a','r','a','t','i','o','n',
389 '-','h','a','n','d','l','e','r',0
390};
391static const WCHAR PropertyDomNodeW[] = {
392 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
393 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
394 'd','o','m','-','n','o','d','e',0
395};
396static const WCHAR PropertyInputSourceW[] = {
397 'i','n','p','u','t','-','s','o','u','r','c','e',0
398};
399static const WCHAR PropertyLexicalHandlerW[] = {
400 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
401 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
402 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
403};
404static const WCHAR PropertyMaxElementDepthW[] = {
405 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
406};
407static const WCHAR PropertyMaxXMLSizeW[] = {
408 'm','a','x','-','x','m','l','-','s','i','z','e',0
409};
410static const WCHAR PropertySchemaDeclHandlerW[] = {
411 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
412 'h','a','n','d','l','e','r',0
413};
414static const WCHAR PropertyXMLDeclEncodingW[] = {
415 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
416};
417static const WCHAR PropertyXMLDeclStandaloneW[] = {
418 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
419};
420static const WCHAR PropertyXMLDeclVersionW[] = {
421 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
422};
423
424static inline HRESULT set_feature_value(saxreader *reader, saxreader_feature feature, VARIANT_BOOL value)
425{
426 /* handling of non-VARIANT_* values is version dependent */
427 if ((reader->version < MSXML4) && (value != VARIANT_TRUE))
428 value = VARIANT_FALSE;
429 if ((reader->version >= MSXML4) && (value != VARIANT_FALSE))
430 value = VARIANT_TRUE;
431
432 if (value == VARIANT_TRUE)
433 reader->features |= feature;
434 else
435 reader->features &= ~feature;
436
437 return S_OK;
438}
439
440static inline HRESULT get_feature_value(const saxreader *reader, saxreader_feature feature, VARIANT_BOOL *value)
441{
442 *value = reader->features & feature ? VARIANT_TRUE : VARIANT_FALSE;
443 return S_OK;
444}
445
446static BOOL is_namespaces_enabled(const saxreader *reader)
447{
448 return (reader->version < MSXML4) || (reader->features & Namespaces);
449}
450
451static BSTR build_qname(BSTR prefix, BSTR local)
452{
453 if (prefix && *prefix)
454 {
455 BSTR qname = SysAllocStringLen(NULL, SysStringLen(prefix) + SysStringLen(local) + 1);
456 WCHAR *ptr;
457
458 ptr = qname;
459 strcpyW(ptr, prefix);
460 ptr += SysStringLen(prefix);
461 *ptr++ = ':';
462 strcpyW(ptr, local);
463 return qname;
464 }
465 else
466 return SysAllocString(local);
467}
468
469static element_entry* alloc_element_entry(const xmlChar *local, const xmlChar *prefix, int nb_ns,
470 const xmlChar **namespaces)
471{
472 element_entry *ret;
473 int i;
474
475 ret = heap_alloc(sizeof(*ret));
476 if (!ret) return ret;
477
478 ret->local = bstr_from_xmlChar(local);
479 ret->prefix = bstr_from_xmlChar(prefix);
480 ret->qname = build_qname(ret->prefix, ret->local);
481 ret->ns = nb_ns ? heap_alloc(nb_ns*sizeof(ns)) : NULL;
482 ret->ns_count = nb_ns;
483
484 for (i=0; i < nb_ns; i++)
485 {
486 ret->ns[i].prefix = bstr_from_xmlChar(namespaces[2*i]);
487 ret->ns[i].uri = bstr_from_xmlChar(namespaces[2*i+1]);
488 }
489
490 return ret;
491}
492
493static void free_element_entry(element_entry *element)
494{
495 int i;
496
497 for (i=0; i<element->ns_count;i++)
498 {
499 SysFreeString(element->ns[i].prefix);
500 SysFreeString(element->ns[i].uri);
501 }
502
504 SysFreeString(element->local);
506
509}
510
511static void push_element_ns(saxlocator *locator, element_entry *element)
512{
513 list_add_head(&locator->elements, &element->entry);
514}
515
516static element_entry * pop_element_ns(saxlocator *locator)
517{
518 element_entry *element = LIST_ENTRY(list_head(&locator->elements), element_entry, entry);
519
520 if (element)
522
523 return element;
524}
525
526static BSTR find_element_uri(saxlocator *locator, const xmlChar *uri)
527{
528 element_entry *element;
529 BSTR uriW;
530 int i;
531
532 if (!uri) return NULL;
533
534 uriW = bstr_from_xmlChar(uri);
535
536 LIST_FOR_EACH_ENTRY(element, &locator->elements, element_entry, entry)
537 {
538 for (i=0; i < element->ns_count; i++)
539 if (!strcmpW(uriW, element->ns[i].uri))
540 {
541 SysFreeString(uriW);
542 return element->ns[i].uri;
543 }
544 }
545
546 SysFreeString(uriW);
547 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri));
548 return NULL;
549}
550
551/* used to localize version dependent error check behaviour */
552static inline BOOL sax_callback_failed(saxlocator *This, HRESULT hr)
553{
554 return This->saxreader->version >= MSXML4 ? FAILED(hr) : hr != S_OK;
555}
556
557/* index value -1 means it tries to loop for a first time */
558static inline BOOL iterate_endprefix_index(saxlocator *This, const element_entry *element, int *i)
559{
560 if (This->saxreader->version >= MSXML4)
561 {
562 if (*i == -1) *i = 0; else ++*i;
563 return *i < element->ns_count;
564 }
565 else
566 {
567 if (*i == -1) *i = element->ns_count-1; else --*i;
568 return *i >= 0;
569 }
570}
571
572static BOOL bstr_pool_insert(struct bstrpool *pool, BSTR pool_entry)
573{
574 if (!pool->pool)
575 {
576 pool->pool = heap_alloc(16 * sizeof(*pool->pool));
577 if (!pool->pool)
578 return FALSE;
579
580 pool->index = 0;
581 pool->len = 16;
582 }
583 else if (pool->index == pool->len)
584 {
585 BSTR *realloc = heap_realloc(pool->pool, pool->len * 2 * sizeof(*realloc));
586
587 if (!realloc)
588 return FALSE;
589
590 pool->pool = realloc;
591 pool->len *= 2;
592 }
593
594 pool->pool[pool->index++] = pool_entry;
595 return TRUE;
596}
597
598static void free_bstr_pool(struct bstrpool *pool)
599{
600 unsigned int i;
601
602 for (i = 0; i < pool->index; i++)
603 SysFreeString(pool->pool[i]);
604
605 heap_free(pool->pool);
606
607 pool->pool = NULL;
608 pool->index = pool->len = 0;
609}
610
611static BSTR bstr_from_xmlCharN(const xmlChar *buf, int len)
612{
613 DWORD dLen;
614 BSTR bstr;
615
616 if (!buf)
617 return NULL;
618
619 dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0);
620 if(len != -1) dLen++;
621 bstr = SysAllocStringLen(NULL, dLen-1);
622 if (!bstr)
623 return NULL;
624 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, bstr, dLen);
625 if(len != -1) bstr[dLen-1] = '\0';
626
627 return bstr;
628}
629
630static BSTR QName_from_xmlChar(const xmlChar *prefix, const xmlChar *name)
631{
632 xmlChar *qname;
633 BSTR bstr;
634
635 if(!name) return NULL;
636
637 if(!prefix || !*prefix)
638 return bstr_from_xmlChar(name);
639
640 qname = xmlBuildQName(name, prefix, NULL, 0);
641 bstr = bstr_from_xmlChar(qname);
642 xmlFree(qname);
643
644 return bstr;
645}
646
647static BSTR pooled_bstr_from_xmlChar(struct bstrpool *pool, const xmlChar *buf)
648{
649 BSTR pool_entry = bstr_from_xmlChar(buf);
650
651 if (pool_entry && !bstr_pool_insert(pool, pool_entry))
652 {
653 SysFreeString(pool_entry);
654 return NULL;
655 }
656
657 return pool_entry;
658}
659
660static BSTR pooled_bstr_from_xmlCharN(struct bstrpool *pool, const xmlChar *buf, int len)
661{
662 BSTR pool_entry = bstr_from_xmlCharN(buf, len);
663
664 if (pool_entry && !bstr_pool_insert(pool, pool_entry))
665 {
666 SysFreeString(pool_entry);
667 return NULL;
668 }
669
670 return pool_entry;
671}
672
673static void format_error_message_from_id(saxlocator *This, HRESULT hr)
674{
675 struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader);
676 xmlStopParser(This->pParserCtxt);
677 This->ret = hr;
678
679 if (saxreader_has_handler(This, SAXErrorHandler))
680 {
681 WCHAR msg[1024];
683 NULL, hr, 0, msg, ARRAY_SIZE(msg), NULL))
684 {
685 FIXME("MSXML errors not yet supported.\n");
686 msg[0] = '\0';
687 }
688
689 if(This->vbInterface)
690 {
691 BSTR bstrMsg = SysAllocString(msg);
692 IVBSAXErrorHandler_fatalError(handler->vbhandler,
693 &This->IVBSAXLocator_iface, &bstrMsg, hr);
694 SysFreeString(bstrMsg);
695 }
696 else
697 ISAXErrorHandler_fatalError(handler->handler,
698 &This->ISAXLocator_iface, msg, hr);
699 }
700}
701
702static void update_position(saxlocator *This, BOOL fix_column)
703{
704 const xmlChar *p = This->pParserCtxt->input->cur-1;
705 const xmlChar *baseP = This->pParserCtxt->input->base;
706
707 This->line = xmlSAX2GetLineNumber(This->pParserCtxt);
708 if(fix_column)
709 {
710 This->column = 1;
711 for(;p>=baseP && *p!='\n' && *p!='\r'; p--)
712 This->column++;
713 }
714 else
715 {
716 This->column = xmlSAX2GetColumnNumber(This->pParserCtxt);
717 }
718}
719
720/*** IVBSAXAttributes interface ***/
721static HRESULT WINAPI ivbsaxattributes_QueryInterface(
722 IVBSAXAttributes* iface,
723 REFIID riid,
724 void **ppvObject)
725{
726 saxlocator *This = impl_from_IVBSAXAttributes(iface);
727 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
728 return IVBSAXLocator_QueryInterface(&This->IVBSAXLocator_iface, riid, ppvObject);
729}
730
731static ULONG WINAPI ivbsaxattributes_AddRef(IVBSAXAttributes* iface)
732{
733 saxlocator *This = impl_from_IVBSAXAttributes(iface);
734 return IVBSAXLocator_AddRef(&This->IVBSAXLocator_iface);
735}
736
737static ULONG WINAPI ivbsaxattributes_Release(IVBSAXAttributes* iface)
738{
739 saxlocator *This = impl_from_IVBSAXAttributes(iface);
740 return IVBSAXLocator_Release(&This->IVBSAXLocator_iface);
741}
742
743static HRESULT WINAPI ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
744{
745 saxlocator *This = impl_from_IVBSAXAttributes( iface );
746
747 TRACE("(%p)->(%p)\n", This, pctinfo);
748
749 *pctinfo = 1;
750
751 return S_OK;
752}
753
754static HRESULT WINAPI ivbsaxattributes_GetTypeInfo(
755 IVBSAXAttributes *iface,
756 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
757{
758 saxlocator *This = impl_from_IVBSAXAttributes( iface );
759
760 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
761
762 return get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
763}
764
765static HRESULT WINAPI ivbsaxattributes_GetIDsOfNames(
766 IVBSAXAttributes *iface,
767 REFIID riid,
768 LPOLESTR* rgszNames,
769 UINT cNames,
770 LCID lcid,
771 DISPID* rgDispId)
772{
773 saxlocator *This = impl_from_IVBSAXAttributes( iface );
775 HRESULT hr;
776
777 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
778 lcid, rgDispId);
779
780 if(!rgszNames || cNames == 0 || !rgDispId)
781 return E_INVALIDARG;
782
784 if(SUCCEEDED(hr))
785 {
786 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
787 ITypeInfo_Release(typeinfo);
788 }
789
790 return hr;
791}
792
793static HRESULT WINAPI ivbsaxattributes_Invoke(
794 IVBSAXAttributes *iface,
795 DISPID dispIdMember,
796 REFIID riid,
797 LCID lcid,
798 WORD wFlags,
799 DISPPARAMS* pDispParams,
800 VARIANT* pVarResult,
801 EXCEPINFO* pExcepInfo,
802 UINT* puArgErr)
803{
804 saxlocator *This = impl_from_IVBSAXAttributes( iface );
806 HRESULT hr;
807
808 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
809 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
810
812 if(SUCCEEDED(hr))
813 {
814 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
815 pDispParams, pVarResult, pExcepInfo, puArgErr);
816 ITypeInfo_Release(typeinfo);
817 }
818
819 return hr;
820}
821
822/*** IVBSAXAttributes methods ***/
823static HRESULT WINAPI ivbsaxattributes_get_length(
824 IVBSAXAttributes* iface,
825 int *nLength)
826{
827 saxlocator *This = impl_from_IVBSAXAttributes( iface );
828 return ISAXAttributes_getLength(&This->ISAXAttributes_iface, nLength);
829}
830
831static HRESULT WINAPI ivbsaxattributes_getURI(
832 IVBSAXAttributes* iface,
833 int nIndex,
834 BSTR *uri)
835{
836 saxlocator *This = impl_from_IVBSAXAttributes( iface );
837 const WCHAR *uriW;
838 HRESULT hr;
839 int len;
840
841 TRACE("(%p)->(%d %p)\n", This, nIndex, uri);
842
843 if (!uri)
844 return E_POINTER;
845
846 *uri = NULL;
847 hr = ISAXAttributes_getURI(&This->ISAXAttributes_iface, nIndex, &uriW, &len);
848 if (FAILED(hr))
849 return hr;
850
851 return return_bstrn(uriW, len, uri);
852}
853
854static HRESULT WINAPI ivbsaxattributes_getLocalName(
855 IVBSAXAttributes* iface,
856 int nIndex,
857 BSTR *name)
858{
859 saxlocator *This = impl_from_IVBSAXAttributes( iface );
860 const WCHAR *nameW;
861 HRESULT hr;
862 int len;
863
864 TRACE("(%p)->(%d %p)\n", This, nIndex, name);
865
866 if (!name)
867 return E_POINTER;
868
869 *name = NULL;
870 hr = ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, nIndex, &nameW, &len);
871 if (FAILED(hr))
872 return hr;
873
874 return return_bstrn(nameW, len, name);
875}
876
877static HRESULT WINAPI ivbsaxattributes_getQName(
878 IVBSAXAttributes* iface,
879 int nIndex,
880 BSTR *QName)
881{
882 saxlocator *This = impl_from_IVBSAXAttributes( iface );
883 const WCHAR *nameW;
884 HRESULT hr;
885 int len;
886
887 TRACE("(%p)->(%d %p)\n", This, nIndex, QName);
888
889 if (!QName)
890 return E_POINTER;
891
892 *QName = NULL;
893 hr = ISAXAttributes_getQName(&This->ISAXAttributes_iface, nIndex, &nameW, &len);
894 if (FAILED(hr))
895 return hr;
896
897 return return_bstrn(nameW, len, QName);
898}
899
900static HRESULT WINAPI ivbsaxattributes_getIndexFromName(
901 IVBSAXAttributes* iface,
902 BSTR uri,
903 BSTR localName,
904 int *index)
905{
906 saxlocator *This = impl_from_IVBSAXAttributes( iface );
907 return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
908 localName, SysStringLen(localName), index);
909}
910
911static HRESULT WINAPI ivbsaxattributes_getIndexFromQName(
912 IVBSAXAttributes* iface,
913 BSTR QName,
914 int *index)
915{
916 saxlocator *This = impl_from_IVBSAXAttributes( iface );
917 return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, QName,
918 SysStringLen(QName), index);
919}
920
921static HRESULT WINAPI ivbsaxattributes_getType(
922 IVBSAXAttributes* iface,
923 int nIndex,
924 BSTR *type)
925{
926 saxlocator *This = impl_from_IVBSAXAttributes( iface );
927 const WCHAR *typeW;
928 HRESULT hr;
929 int len;
930
931 TRACE("(%p)->(%d %p)\n", This, nIndex, type);
932
933 if (!type)
934 return E_POINTER;
935
936 *type = NULL;
937 hr = ISAXAttributes_getType(&This->ISAXAttributes_iface, nIndex, &typeW, &len);
938 if (FAILED(hr))
939 return hr;
940
941 return return_bstrn(typeW, len, type);
942}
943
944static HRESULT WINAPI ivbsaxattributes_getTypeFromName(
945 IVBSAXAttributes* iface,
946 BSTR uri,
947 BSTR localName,
948 BSTR *type)
949{
950 saxlocator *This = impl_from_IVBSAXAttributes( iface );
951 const WCHAR *typeW;
952 HRESULT hr;
953 int len;
954
955 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(localName), type);
956
957 if (!type)
958 return E_POINTER;
959
960 *type = NULL;
961 hr = ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
962 localName, SysStringLen(localName), &typeW, &len);
963 if (FAILED(hr))
964 return hr;
965
966 return return_bstrn(typeW, len, type);
967}
968
969static HRESULT WINAPI ivbsaxattributes_getTypeFromQName(
970 IVBSAXAttributes* iface,
971 BSTR QName,
972 BSTR *type)
973{
974 saxlocator *This = impl_from_IVBSAXAttributes( iface );
975 const WCHAR *typeW;
976 HRESULT hr;
977 int len;
978
979 TRACE("(%p)->(%s %p)\n", This, debugstr_w(QName), type);
980
981 if (!type)
982 return E_POINTER;
983
984 *type = NULL;
985 hr = ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, QName, SysStringLen(QName),
986 &typeW, &len);
987 if (FAILED(hr))
988 return hr;
989
990 return return_bstrn(typeW, len, type);
991}
992
993static HRESULT WINAPI ivbsaxattributes_getValue(
994 IVBSAXAttributes* iface,
995 int nIndex,
996 BSTR *value)
997{
998 saxlocator *This = impl_from_IVBSAXAttributes( iface );
999 const WCHAR *valueW;
1000 HRESULT hr;
1001 int len;
1002
1003 TRACE("(%p)->(%d %p)\n", This, nIndex, value);
1004
1005 if (!value)
1006 return E_POINTER;
1007
1008 *value = NULL;
1009 hr = ISAXAttributes_getValue(&This->ISAXAttributes_iface, nIndex, &valueW, &len);
1010 if (FAILED(hr))
1011 return hr;
1012
1013 return return_bstrn(valueW, len, value);
1014}
1015
1016static HRESULT WINAPI ivbsaxattributes_getValueFromName(
1017 IVBSAXAttributes* iface,
1018 BSTR uri,
1019 BSTR localName,
1020 BSTR *value)
1021{
1022 saxlocator *This = impl_from_IVBSAXAttributes( iface );
1023 const WCHAR *valueW;
1024 HRESULT hr;
1025 int len;
1026
1027 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(localName), value);
1028
1029 if (!value)
1030 return E_POINTER;
1031
1032 *value = NULL;
1033 hr = ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
1034 localName, SysStringLen(localName), &valueW, &len);
1035 if (FAILED(hr))
1036 return hr;
1037
1038 return return_bstrn(valueW, len, value);
1039}
1040
1041static HRESULT WINAPI ivbsaxattributes_getValueFromQName(
1042 IVBSAXAttributes* iface,
1043 BSTR QName,
1044 BSTR *value)
1045{
1046 saxlocator *This = impl_from_IVBSAXAttributes( iface );
1047 const WCHAR *valueW;
1048 HRESULT hr;
1049 int len;
1050
1051 TRACE("(%p)->(%s %p)\n", This, debugstr_w(QName), value);
1052
1053 if (!value)
1054 return E_POINTER;
1055
1056 *value = NULL;
1057 hr = ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, QName,
1058 SysStringLen(QName), &valueW, &len);
1059 if (FAILED(hr))
1060 return hr;
1061
1062 return return_bstrn(valueW, len, value);
1063}
1064
1065static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl =
1066{
1067 ivbsaxattributes_QueryInterface,
1068 ivbsaxattributes_AddRef,
1069 ivbsaxattributes_Release,
1070 ivbsaxattributes_GetTypeInfoCount,
1071 ivbsaxattributes_GetTypeInfo,
1072 ivbsaxattributes_GetIDsOfNames,
1073 ivbsaxattributes_Invoke,
1074 ivbsaxattributes_get_length,
1075 ivbsaxattributes_getURI,
1076 ivbsaxattributes_getLocalName,
1077 ivbsaxattributes_getQName,
1078 ivbsaxattributes_getIndexFromName,
1079 ivbsaxattributes_getIndexFromQName,
1080 ivbsaxattributes_getType,
1081 ivbsaxattributes_getTypeFromName,
1082 ivbsaxattributes_getTypeFromQName,
1083 ivbsaxattributes_getValue,
1084 ivbsaxattributes_getValueFromName,
1085 ivbsaxattributes_getValueFromQName
1086};
1087
1088/*** ISAXAttributes interface ***/
1089/*** IUnknown methods ***/
1091 ISAXAttributes* iface,
1092 REFIID riid,
1093 void **ppvObject)
1094{
1095 saxlocator *This = impl_from_ISAXAttributes(iface);
1096 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
1097 return ISAXLocator_QueryInterface(&This->ISAXLocator_iface, riid, ppvObject);
1098}
1099
1100static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes* iface)
1101{
1102 saxlocator *This = impl_from_ISAXAttributes(iface);
1103 TRACE("%p\n", This);
1104 return ISAXLocator_AddRef(&This->ISAXLocator_iface);
1105}
1106
1107static ULONG WINAPI isaxattributes_Release(ISAXAttributes* iface)
1108{
1109 saxlocator *This = impl_from_ISAXAttributes(iface);
1110
1111 TRACE("%p\n", This);
1112 return ISAXLocator_Release(&This->ISAXLocator_iface);
1113}
1114
1115/*** ISAXAttributes methods ***/
1117 ISAXAttributes* iface,
1118 int *length)
1119{
1120 saxlocator *This = impl_from_ISAXAttributes( iface );
1121
1122 *length = This->attr_count;
1123 TRACE("Length set to %d\n", *length);
1124 return S_OK;
1125}
1126
1127static inline BOOL is_valid_attr_index(const saxlocator *locator, int index)
1128{
1129 return index < locator->attr_count && index >= 0;
1130}
1131
1133 ISAXAttributes* iface,
1134 int index,
1135 const WCHAR **url,
1136 int *size)
1137{
1138 saxlocator *This = impl_from_ISAXAttributes( iface );
1139 TRACE("(%p)->(%d)\n", This, index);
1140
1141 if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
1142 if(!url || !size) return E_POINTER;
1143
1144 *size = SysStringLen(This->attributes[index].szURI);
1145 *url = This->attributes[index].szURI;
1146
1147 TRACE("(%s:%d)\n", debugstr_w(This->attributes[index].szURI), *size);
1148
1149 return S_OK;
1150}
1151
1153 ISAXAttributes* iface,
1154 int index,
1155 const WCHAR **pLocalName,
1156 int *pLocalNameLength)
1157{
1158 saxlocator *This = impl_from_ISAXAttributes( iface );
1159 TRACE("(%p)->(%d)\n", This, index);
1160
1161 if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
1162 if(!pLocalName || !pLocalNameLength) return E_POINTER;
1163
1164 *pLocalNameLength = SysStringLen(This->attributes[index].szLocalname);
1165 *pLocalName = This->attributes[index].szLocalname;
1166
1167 return S_OK;
1168}
1169
1171 ISAXAttributes* iface,
1172 int index,
1173 const WCHAR **pQName,
1174 int *pQNameLength)
1175{
1176 saxlocator *This = impl_from_ISAXAttributes( iface );
1177 TRACE("(%p)->(%d)\n", This, index);
1178
1179 if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
1180 if(!pQName || !pQNameLength) return E_POINTER;
1181
1182 *pQNameLength = SysStringLen(This->attributes[index].szQName);
1183 *pQName = This->attributes[index].szQName;
1184
1185 return S_OK;
1186}
1187
1189 ISAXAttributes* iface,
1190 int index,
1191 const WCHAR **uri,
1192 int *pUriLength,
1193 const WCHAR **localName,
1194 int *pLocalNameSize,
1195 const WCHAR **QName,
1196 int *pQNameLength)
1197{
1198 saxlocator *This = impl_from_ISAXAttributes( iface );
1199 TRACE("(%p)->(%d)\n", This, index);
1200
1201 if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
1202 if(!uri || !pUriLength || !localName || !pLocalNameSize
1203 || !QName || !pQNameLength) return E_POINTER;
1204
1205 *pUriLength = SysStringLen(This->attributes[index].szURI);
1206 *uri = This->attributes[index].szURI;
1207 *pLocalNameSize = SysStringLen(This->attributes[index].szLocalname);
1208 *localName = This->attributes[index].szLocalname;
1209 *pQNameLength = SysStringLen(This->attributes[index].szQName);
1210 *QName = This->attributes[index].szQName;
1211
1212 TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*localName), debugstr_w(*QName));
1213
1214 return S_OK;
1215}
1216
1218 ISAXAttributes* iface,
1219 const WCHAR *pUri,
1220 int cUriLength,
1221 const WCHAR *pLocalName,
1222 int cocalNameLength,
1223 int *index)
1224{
1225 saxlocator *This = impl_from_ISAXAttributes( iface );
1226 int i;
1227 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), cUriLength,
1228 debugstr_w(pLocalName), cocalNameLength);
1229
1230 if(!pUri || !pLocalName || !index) return E_POINTER;
1231
1232 for(i=0; i<This->attr_count; i++)
1233 {
1234 if(cUriLength!=SysStringLen(This->attributes[i].szURI)
1235 || cocalNameLength!=SysStringLen(This->attributes[i].szLocalname))
1236 continue;
1237 if(cUriLength && memcmp(pUri, This->attributes[i].szURI,
1238 sizeof(WCHAR)*cUriLength))
1239 continue;
1240 if(cocalNameLength && memcmp(pLocalName, This->attributes[i].szLocalname,
1241 sizeof(WCHAR)*cocalNameLength))
1242 continue;
1243
1244 *index = i;
1245 return S_OK;
1246 }
1247
1248 return E_INVALIDARG;
1249}
1250
1252 ISAXAttributes* iface,
1253 const WCHAR *pQName,
1254 int nQNameLength,
1255 int *index)
1256{
1257 saxlocator *This = impl_from_ISAXAttributes( iface );
1258 int i;
1259 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQNameLength);
1260
1261 if(!pQName || !index) return E_POINTER;
1262 if(!nQNameLength) return E_INVALIDARG;
1263
1264 for(i=0; i<This->attr_count; i++)
1265 {
1266 if(nQNameLength!=SysStringLen(This->attributes[i].szQName)) continue;
1267 if(memcmp(pQName, This->attributes[i].szQName, sizeof(WCHAR)*nQNameLength)) continue;
1268
1269 *index = i;
1270 return S_OK;
1271 }
1272
1273 return E_INVALIDARG;
1274}
1275
1277 ISAXAttributes* iface,
1278 int nIndex,
1279 const WCHAR **pType,
1280 int *pTypeLength)
1281{
1282 saxlocator *This = impl_from_ISAXAttributes( iface );
1283
1284 FIXME("(%p)->(%d) stub\n", This, nIndex);
1285 return E_NOTIMPL;
1286}
1287
1289 ISAXAttributes* iface,
1290 const WCHAR *pUri,
1291 int nUri,
1292 const WCHAR *pLocalName,
1293 int nLocalName,
1294 const WCHAR **pType,
1295 int *nType)
1296{
1297 saxlocator *This = impl_from_ISAXAttributes( iface );
1298
1299 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This, debugstr_w(pUri), nUri,
1300 debugstr_w(pLocalName), nLocalName);
1301 return E_NOTIMPL;
1302}
1303
1305 ISAXAttributes* iface,
1306 const WCHAR *pQName,
1307 int nQName,
1308 const WCHAR **pType,
1309 int *nType)
1310{
1311 saxlocator *This = impl_from_ISAXAttributes( iface );
1312
1313 FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(pQName), nQName);
1314 return E_NOTIMPL;
1315}
1316
1318 ISAXAttributes* iface,
1319 int index,
1320 const WCHAR **value,
1321 int *nValue)
1322{
1323 saxlocator *This = impl_from_ISAXAttributes( iface );
1324 TRACE("(%p)->(%d)\n", This, index);
1325
1326 if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
1327 if(!value || !nValue) return E_POINTER;
1328
1329 *nValue = SysStringLen(This->attributes[index].szValue);
1330 *value = This->attributes[index].szValue;
1331
1332 TRACE("(%s:%d)\n", debugstr_w(*value), *nValue);
1333
1334 return S_OK;
1335}
1336
1338 ISAXAttributes* iface,
1339 const WCHAR *pUri,
1340 int nUri,
1341 const WCHAR *pLocalName,
1342 int nLocalName,
1343 const WCHAR **pValue,
1344 int *nValue)
1345{
1346 HRESULT hr;
1347 int index;
1348 saxlocator *This = impl_from_ISAXAttributes( iface );
1349 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), nUri,
1350 debugstr_w(pLocalName), nLocalName);
1351
1352 hr = ISAXAttributes_getIndexFromName(iface,
1353 pUri, nUri, pLocalName, nLocalName, &index);
1354 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
1355
1356 return hr;
1357}
1358
1360 ISAXAttributes* iface,
1361 const WCHAR *pQName,
1362 int nQName,
1363 const WCHAR **pValue,
1364 int *nValue)
1365{
1366 HRESULT hr;
1367 int index;
1368 saxlocator *This = impl_from_ISAXAttributes( iface );
1369 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQName);
1370
1371 hr = ISAXAttributes_getIndexFromQName(iface, pQName, nQName, &index);
1372 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
1373
1374 return hr;
1375}
1376
1377static const struct ISAXAttributesVtbl isaxattributes_vtbl =
1378{
1395};
1396
1397/* Libxml2 escapes '&' back to char reference '&#38;' in attribute value,
1398 so when document has escaped value with '&amp;' it's parsed to '&' and then
1399 escaped to '&#38;'. This function takes care of ampersands only. */
1400static BSTR saxreader_get_unescaped_value(const xmlChar *buf, int len)
1401{
1402 static const WCHAR ampescW[] = {'&','#','3','8',';',0};
1403 WCHAR *dest, *ptrW, *str;
1404 DWORD str_len;
1405 BSTR bstr;
1406
1407 if (!buf)
1408 return NULL;
1409
1411 if (len != -1) str_len++;
1412
1413 str = heap_alloc(str_len*sizeof(WCHAR));
1414 if (!str) return NULL;
1415
1417 if (len != -1) str[str_len-1] = 0;
1418
1419 ptrW = str;
1420 while ((dest = strstrW(ptrW, ampescW)))
1421 {
1422 WCHAR *src;
1423
1424 /* leave first '&' from a reference as a value */
1425 src = dest + ARRAY_SIZE(ampescW) - 1;
1426 dest++;
1427
1428 /* move together with null terminator */
1429 memmove(dest, src, (strlenW(src) + 1)*sizeof(WCHAR));
1430
1431 ptrW++;
1432 }
1433
1434 bstr = SysAllocString(str);
1435 heap_free(str);
1436
1437 return bstr;
1438}
1439
1440static void free_attribute_values(saxlocator *locator)
1441{
1442 int i;
1443
1444 for (i = 0; i < locator->attr_count; i++)
1445 {
1446 SysFreeString(locator->attributes[i].szLocalname);
1447 locator->attributes[i].szLocalname = NULL;
1448
1449 SysFreeString(locator->attributes[i].szValue);
1450 locator->attributes[i].szValue = NULL;
1451
1452 SysFreeString(locator->attributes[i].szQName);
1453 locator->attributes[i].szQName = NULL;
1454 }
1455}
1456
1457static HRESULT SAXAttributes_populate(saxlocator *locator,
1458 int nb_namespaces, const xmlChar **xmlNamespaces,
1459 int nb_attributes, const xmlChar **xmlAttributes)
1460{
1461 static const xmlChar xmlns[] = "xmlns";
1462 static const WCHAR xmlnsW[] = { 'x','m','l','n','s',0 };
1463
1464 struct _attributes *attrs;
1465 int i;
1466
1467 /* skip namespace definitions */
1468 if ((locator->saxreader->features & NamespacePrefixes) == 0)
1469 nb_namespaces = 0;
1470
1471 locator->attr_count = nb_namespaces + nb_attributes;
1472 if(locator->attr_count > locator->attr_alloc_count)
1473 {
1474 int new_size = locator->attr_count * 2;
1475 attrs = heap_realloc_zero(locator->attributes, new_size * sizeof(struct _attributes));
1476 if(!attrs)
1477 {
1478 free_attribute_values(locator);
1479 locator->attr_count = 0;
1480 return E_OUTOFMEMORY;
1481 }
1482 locator->attributes = attrs;
1483 locator->attr_alloc_count = new_size;
1484 }
1485 else
1486 {
1487 attrs = locator->attributes;
1488 }
1489
1490 for (i = 0; i < nb_namespaces; i++)
1491 {
1492 SysFreeString(attrs[nb_attributes+i].szLocalname);
1493 attrs[nb_attributes+i].szLocalname = SysAllocStringLen(NULL, 0);
1494
1495 attrs[nb_attributes+i].szURI = locator->namespaceUri;
1496
1497 SysFreeString(attrs[nb_attributes+i].szValue);
1498 attrs[nb_attributes+i].szValue = bstr_from_xmlChar(xmlNamespaces[2*i+1]);
1499
1500 SysFreeString(attrs[nb_attributes+i].szQName);
1501 if(!xmlNamespaces[2*i])
1502 attrs[nb_attributes+i].szQName = SysAllocString(xmlnsW);
1503 else
1504 attrs[nb_attributes+i].szQName = QName_from_xmlChar(xmlns, xmlNamespaces[2*i]);
1505 }
1506
1507 for (i = 0; i < nb_attributes; i++)
1508 {
1509 static const xmlChar xmlA[] = "xml";
1510
1511 if (xmlStrEqual(xmlAttributes[i*5+1], xmlA))
1512 attrs[i].szURI = bstr_from_xmlChar(xmlAttributes[i*5+2]);
1513 else
1514 /* that's an important feature to keep same uri pointer for every reported attribute */
1515 attrs[i].szURI = find_element_uri(locator, xmlAttributes[i*5+2]);
1516
1517 SysFreeString(attrs[i].szLocalname);
1518 attrs[i].szLocalname = bstr_from_xmlChar(xmlAttributes[i*5]);
1519
1520 SysFreeString(attrs[i].szValue);
1521 attrs[i].szValue = saxreader_get_unescaped_value(xmlAttributes[i*5+3], xmlAttributes[i*5+4]-xmlAttributes[i*5+3]);
1522
1523 SysFreeString(attrs[i].szQName);
1524 attrs[i].szQName = QName_from_xmlChar(xmlAttributes[i*5+1], xmlAttributes[i*5]);
1525 }
1526
1527 return S_OK;
1528}
1529
1530/*** LibXML callbacks ***/
1531static void libxmlStartDocument(void *ctx)
1532{
1533 saxlocator *This = ctx;
1534 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1535 HRESULT hr;
1536
1537 if (This->saxreader->version >= MSXML4)
1538 {
1539 const xmlChar *p = This->pParserCtxt->input->cur-1;
1540 update_position(This, FALSE);
1541 while(p>This->pParserCtxt->input->base && *p!='>')
1542 {
1543 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1544 This->line--;
1545 p--;
1546 }
1547 This->column = 0;
1548 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1549 This->column++;
1550 }
1551
1552 /* store version value, declaration has to contain version attribute */
1553 if (This->pParserCtxt->standalone != -1)
1554 {
1555 SysFreeString(This->saxreader->xmldecl_version);
1556 This->saxreader->xmldecl_version = bstr_from_xmlChar(This->pParserCtxt->version);
1557 }
1558
1559 if (saxreader_has_handler(This, SAXContentHandler))
1560 {
1561 if(This->vbInterface)
1562 hr = IVBSAXContentHandler_startDocument(handler->vbhandler);
1563 else
1564 hr = ISAXContentHandler_startDocument(handler->handler);
1565
1566 if (sax_callback_failed(This, hr))
1567 format_error_message_from_id(This, hr);
1568 }
1569}
1570
1571static void libxmlEndDocument(void *ctx)
1572{
1573 saxlocator *This = ctx;
1574 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1575 HRESULT hr;
1576
1577 if (This->saxreader->version >= MSXML4) {
1578 update_position(This, FALSE);
1579 if(This->column > 1)
1580 This->line++;
1581 This->column = 0;
1582 } else {
1583 This->column = 0;
1584 This->line = 0;
1585 }
1586
1587 if(This->ret != S_OK) return;
1588
1589 if (saxreader_has_handler(This, SAXContentHandler))
1590 {
1591 if(This->vbInterface)
1592 hr = IVBSAXContentHandler_endDocument(handler->vbhandler);
1593 else
1594 hr = ISAXContentHandler_endDocument(handler->handler);
1595
1596 if (sax_callback_failed(This, hr))
1597 format_error_message_from_id(This, hr);
1598 }
1599}
1600
1601static void libxmlStartElementNS(
1602 void *ctx,
1603 const xmlChar *localname,
1604 const xmlChar *prefix,
1605 const xmlChar *URI,
1606 int nb_namespaces,
1607 const xmlChar **namespaces,
1608 int nb_attributes,
1609 int nb_defaulted,
1610 const xmlChar **attributes)
1611{
1612 saxlocator *This = ctx;
1613 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1614 element_entry *element;
1615 HRESULT hr = S_OK;
1616 BSTR uri;
1617
1618 update_position(This, TRUE);
1619 if(*(This->pParserCtxt->input->cur) == '/')
1620 This->column++;
1621 if(This->saxreader->version < MSXML4)
1622 This->column++;
1623
1624 element = alloc_element_entry(localname, prefix, nb_namespaces, namespaces);
1625 push_element_ns(This, element);
1626
1627 if (is_namespaces_enabled(This->saxreader))
1628 {
1629 int i;
1630
1631 for (i = 0; i < nb_namespaces && saxreader_has_handler(This, SAXContentHandler); i++)
1632 {
1633 if (This->vbInterface)
1634 hr = IVBSAXContentHandler_startPrefixMapping(
1635 handler->vbhandler,
1636 &element->ns[i].prefix,
1637 &element->ns[i].uri);
1638 else
1639 hr = ISAXContentHandler_startPrefixMapping(
1640 handler->handler,
1641 element->ns[i].prefix,
1642 SysStringLen(element->ns[i].prefix),
1643 element->ns[i].uri,
1644 SysStringLen(element->ns[i].uri));
1645
1646 if (sax_callback_failed(This, hr))
1647 {
1648 format_error_message_from_id(This, hr);
1649 return;
1650 }
1651 }
1652 }
1653
1654 uri = find_element_uri(This, URI);
1655 hr = SAXAttributes_populate(This, nb_namespaces, namespaces, nb_attributes, attributes);
1656 if (hr == S_OK && saxreader_has_handler(This, SAXContentHandler))
1657 {
1658 BSTR local;
1659
1660 if (is_namespaces_enabled(This->saxreader))
1661 local = element->local;
1662 else
1663 uri = local = NULL;
1664
1665 if (This->vbInterface)
1666 hr = IVBSAXContentHandler_startElement(handler->vbhandler,
1667 &uri, &local, &element->qname, &This->IVBSAXAttributes_iface);
1668 else
1669 hr = ISAXContentHandler_startElement(handler->handler,
1673 &This->ISAXAttributes_iface);
1674
1675 if (sax_callback_failed(This, hr))
1676 format_error_message_from_id(This, hr);
1677 }
1678}
1679
1680static void libxmlEndElementNS(
1681 void *ctx,
1682 const xmlChar *localname,
1683 const xmlChar *prefix,
1684 const xmlChar *URI)
1685{
1686 saxlocator *This = ctx;
1687 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1688 element_entry *element;
1689 const xmlChar *p;
1690 BSTR uri, local;
1691 HRESULT hr;
1692
1693 update_position(This, FALSE);
1694 p = This->pParserCtxt->input->cur;
1695
1696 if (This->saxreader->version >= MSXML4)
1697 {
1698 p--;
1699 while(p>This->pParserCtxt->input->base && *p!='>')
1700 {
1701 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1702 This->line--;
1703 p--;
1704 }
1705 }
1706 else if(*(p-1)!='>' || *(p-2)!='/')
1707 {
1708 p--;
1709 while(p-2>=This->pParserCtxt->input->base
1710 && *(p-2)!='<' && *(p-1)!='/')
1711 {
1712 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1713 This->line--;
1714 p--;
1715 }
1716 }
1717 This->column = 0;
1718 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1719 This->column++;
1720
1721 uri = find_element_uri(This, URI);
1722 element = pop_element_ns(This);
1723
1724 if (!saxreader_has_handler(This, SAXContentHandler))
1725 {
1726 free_attribute_values(This);
1727 This->attr_count = 0;
1728 free_element_entry(element);
1729 return;
1730 }
1731
1732 if (is_namespaces_enabled(This->saxreader))
1733 local = element->local;
1734 else
1735 uri = local = NULL;
1736
1737 if (This->vbInterface)
1738 hr = IVBSAXContentHandler_endElement(
1739 handler->vbhandler,
1740 &uri, &local, &element->qname);
1741 else
1742 hr = ISAXContentHandler_endElement(
1743 handler->handler,
1747
1748 free_attribute_values(This);
1749 This->attr_count = 0;
1750
1751 if (sax_callback_failed(This, hr))
1752 {
1753 format_error_message_from_id(This, hr);
1754 free_element_entry(element);
1755 return;
1756 }
1757
1758 if (is_namespaces_enabled(This->saxreader))
1759 {
1760 int i = -1;
1761 while (iterate_endprefix_index(This, element, &i) && saxreader_has_handler(This, SAXContentHandler))
1762 {
1763 if (This->vbInterface)
1764 hr = IVBSAXContentHandler_endPrefixMapping(
1765 handler->vbhandler, &element->ns[i].prefix);
1766 else
1767 hr = ISAXContentHandler_endPrefixMapping(
1768 handler->handler, element->ns[i].prefix, SysStringLen(element->ns[i].prefix));
1769
1770 if (sax_callback_failed(This, hr)) break;
1771 }
1772
1773 if (sax_callback_failed(This, hr))
1774 format_error_message_from_id(This, hr);
1775 }
1776
1777 free_element_entry(element);
1778}
1779
1780static void libxmlCharacters(
1781 void *ctx,
1782 const xmlChar *ch,
1783 int len)
1784{
1785 saxlocator *This = ctx;
1786 BSTR Chars;
1787 HRESULT hr;
1788 xmlChar *cur, *end;
1789 BOOL lastEvent = FALSE;
1790
1791 if (!saxreader_has_handler(This, SAXContentHandler)) return;
1792
1793 update_position(This, FALSE);
1794 cur = (xmlChar*)This->pParserCtxt->input->cur;
1795 while(cur>=This->pParserCtxt->input->base && *cur!='>')
1796 {
1797 if(*cur=='\n' || (*cur=='\r' && *(cur+1)!='\n'))
1798 This->line--;
1799 cur--;
1800 }
1801 This->column = 1;
1802 for(; cur>=This->pParserCtxt->input->base && *cur!='\n' && *cur!='\r'; cur--)
1803 This->column++;
1804
1805 cur = (xmlChar*)ch;
1806 if(*(ch-1)=='\r') cur--;
1807 end = cur;
1808
1809 while(1)
1810 {
1811 while(end-ch<len && *end!='\r') end++;
1812 if(end-ch==len)
1813 {
1814 lastEvent = TRUE;
1815 }
1816 else
1817 {
1818 *end = '\n';
1819 end++;
1820 }
1821
1822 if (This->saxreader->version >= MSXML4)
1823 {
1824 xmlChar *p;
1825
1826 for(p=cur; p!=end; p++)
1827 {
1828 if(*p=='\n')
1829 {
1830 This->line++;
1831 This->column = 1;
1832 }
1833 else
1834 {
1835 This->column++;
1836 }
1837 }
1838
1839 if(!lastEvent)
1840 This->column = 0;
1841 }
1842
1843 Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur);
1844 hr = saxreader_saxcharacters(This, Chars);
1845
1846 if (sax_callback_failed(This, hr))
1847 {
1848 format_error_message_from_id(This, hr);
1849 return;
1850 }
1851
1852 if (This->saxreader->version < MSXML4)
1853 This->column += end-cur;
1854
1855 if(lastEvent)
1856 break;
1857
1858 *(end-1) = '\r';
1859 if(*end == '\n')
1860 {
1861 end++;
1862 This->column++;
1863 }
1864 cur = end;
1865
1866 if(end-ch == len) break;
1867 }
1868}
1869
1870static void libxmlSetDocumentLocator(
1871 void *ctx,
1872 xmlSAXLocatorPtr loc)
1873{
1874 saxlocator *This = ctx;
1875 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1876 HRESULT hr = S_OK;
1877
1878 if (saxreader_has_handler(This, SAXContentHandler))
1879 {
1880 if(This->vbInterface)
1881 hr = IVBSAXContentHandler_putref_documentLocator(handler->vbhandler,
1882 &This->IVBSAXLocator_iface);
1883 else
1884 hr = ISAXContentHandler_putDocumentLocator(handler->handler, &This->ISAXLocator_iface);
1885 }
1886
1887 if(FAILED(hr))
1888 format_error_message_from_id(This, hr);
1889}
1890
1891static void libxmlComment(void *ctx, const xmlChar *value)
1892{
1893 saxlocator *This = ctx;
1894 struct saxlexicalhandler_iface *handler = saxreader_get_lexicalhandler(This->saxreader);
1895 BSTR bValue;
1896 HRESULT hr;
1897 const xmlChar *p = This->pParserCtxt->input->cur;
1898
1899 update_position(This, FALSE);
1900 while(p-4>=This->pParserCtxt->input->base
1901 && memcmp(p-4, "<!--", sizeof(char[4])))
1902 {
1903 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1904 This->line--;
1905 p--;
1906 }
1907
1908 This->column = 0;
1909 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1910 This->column++;
1911
1912 if (!saxreader_has_handler(This, SAXLexicalHandler)) return;
1913
1914 bValue = pooled_bstr_from_xmlChar(&This->saxreader->pool, value);
1915
1916 if (This->vbInterface)
1917 hr = IVBSAXLexicalHandler_comment(handler->vbhandler, &bValue);
1918 else
1919 hr = ISAXLexicalHandler_comment(handler->handler, bValue, SysStringLen(bValue));
1920
1921 if(FAILED(hr))
1922 format_error_message_from_id(This, hr);
1923}
1924
1925static void libxmlFatalError(void *ctx, const char *msg, ...)
1926{
1927 saxlocator *This = ctx;
1928 struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader);
1929 char message[1024];
1930 WCHAR *error;
1931 DWORD len;
1932 va_list args;
1933
1934 if(This->ret != S_OK) {
1935 xmlStopParser(This->pParserCtxt);
1936 return;
1937 }
1938
1939 va_start(args, msg);
1941 va_end(args);
1942
1944 error = heap_alloc(sizeof(WCHAR)*len);
1945 if(error)
1946 {
1948 TRACE("fatal error for %p: %s\n", This, debugstr_w(error));
1949 }
1950
1951 if (!saxreader_has_handler(This, SAXErrorHandler))
1952 {
1953 xmlStopParser(This->pParserCtxt);
1954 This->ret = E_FAIL;
1956 return;
1957 }
1958
1959 FIXME("Error handling is not compatible.\n");
1960
1961 if(This->vbInterface)
1962 {
1963 BSTR bstrError = SysAllocString(error);
1964 IVBSAXErrorHandler_fatalError(handler->vbhandler, &This->IVBSAXLocator_iface,
1965 &bstrError, E_FAIL);
1966 SysFreeString(bstrError);
1967 }
1968 else
1969 ISAXErrorHandler_fatalError(handler->handler, &This->ISAXLocator_iface, error, E_FAIL);
1970
1972
1973 xmlStopParser(This->pParserCtxt);
1974 This->ret = E_FAIL;
1975}
1976
1977/* The only reason this helper exists is that CDATA section are reported by chunks,
1978 newlines are used as delimiter. More than that, reader even alters input data before reporting.
1979
1980 This helper should be called for substring with trailing newlines.
1981*/
1982static BSTR saxreader_get_cdata_chunk(const xmlChar *str, int len)
1983{
1984 BSTR bstr = bstr_from_xmlCharN(str, len), ret;
1985 WCHAR *ptr;
1986
1987 len = SysStringLen(bstr);
1988 ptr = bstr + len - 1;
1989 while ((*ptr == '\r' || *ptr == '\n') && ptr >= bstr)
1990 ptr--;
1991
1992 while (*++ptr)
1993 {
1994 /* replace returns as:
1995
1996 - "\r<char>" -> "\n<char>"
1997 - "\r\r" -> "\r"
1998 - "\r\n" -> "\n"
1999 */
2000 if (*ptr == '\r')
2001 {
2002 if (*(ptr+1) == '\r' || *(ptr+1) == '\n')
2003 {
2004 /* shift tail */
2005 memmove(ptr, ptr+1, len-- - (ptr-bstr));
2006 }
2007 else
2008 *ptr = '\n';
2009 }
2010 }
2011
2012 ret = SysAllocStringLen(bstr, len);
2013 SysFreeString(bstr);
2014 return ret;
2015}
2016
2017static void libxml_cdatablock(void *ctx, const xmlChar *value, int len)
2018{
2019 const xmlChar *start, *end;
2020 saxlocator *locator = ctx;
2021 struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(locator->saxreader);
2022 HRESULT hr = S_OK;
2023 BSTR chars;
2024 int i;
2025
2026 update_position(locator, FALSE);
2027 if (saxreader_has_handler(locator, SAXLexicalHandler))
2028 {
2029 if (locator->vbInterface)
2030 hr = IVBSAXLexicalHandler_startCDATA(lexical->vbhandler);
2031 else
2032 hr = ISAXLexicalHandler_startCDATA(lexical->handler);
2033 }
2034
2035 if(FAILED(hr))
2036 {
2037 format_error_message_from_id(locator, hr);
2038 return;
2039 }
2040
2041 start = value;
2042 end = NULL;
2043 i = 0;
2044
2045 while (i < len)
2046 {
2047 /* scan for newlines */
2048 if (value[i] == '\r' || value[i] == '\n')
2049 {
2050 /* skip newlines/linefeeds */
2051 while (i < len)
2052 {
2053 if (value[i] != '\r' && value[i] != '\n') break;
2054 i++;
2055 }
2056 end = &value[i];
2057
2058 /* report */
2059 chars = saxreader_get_cdata_chunk(start, end-start);
2060 TRACE("(chunk %s)\n", debugstr_w(chars));
2061 hr = saxreader_saxcharacters(locator, chars);
2062 SysFreeString(chars);
2063
2064 start = &value[i];
2065 end = NULL;
2066 }
2067 i++;
2068 locator->column++;
2069 }
2070
2071 /* no newline chars (or last chunk) report as a whole */
2072 if (!end && start == value)
2073 {
2074 /* report */
2075 chars = bstr_from_xmlCharN(start, len-(start-value));
2076 TRACE("(%s)\n", debugstr_w(chars));
2077 hr = saxreader_saxcharacters(locator, chars);
2078 SysFreeString(chars);
2079 }
2080
2081 if (saxreader_has_handler(locator, SAXLexicalHandler))
2082 {
2083 if (locator->vbInterface)
2084 hr = IVBSAXLexicalHandler_endCDATA(lexical->vbhandler);
2085 else
2086 hr = ISAXLexicalHandler_endCDATA(lexical->handler);
2087 }
2088
2089 if(FAILED(hr))
2090 format_error_message_from_id(locator, hr);
2091}
2092
2093static xmlParserInputPtr libxmlresolveentity(void *ctx, const xmlChar *publicid, const xmlChar *systemid)
2094{
2095 FIXME("entity resolving not implemented, %s, %s\n", publicid, systemid);
2096 return xmlSAX2ResolveEntity(ctx, publicid, systemid);
2097}
2098
2099/*** IVBSAXLocator interface ***/
2100/*** IUnknown methods ***/
2101static HRESULT WINAPI ivbsaxlocator_QueryInterface(IVBSAXLocator* iface, REFIID riid, void **ppvObject)
2102{
2103 saxlocator *This = impl_from_IVBSAXLocator( iface );
2104
2105 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject);
2106
2107 *ppvObject = NULL;
2108
2109 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2111 IsEqualGUID( riid, &IID_IVBSAXLocator ))
2112 {
2113 *ppvObject = iface;
2114 }
2115 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
2116 {
2117 *ppvObject = &This->IVBSAXAttributes_iface;
2118 }
2119 else
2120 {
2121 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2122 return E_NOINTERFACE;
2123 }
2124
2125 IVBSAXLocator_AddRef( iface );
2126
2127 return S_OK;
2128}
2129
2130static ULONG WINAPI ivbsaxlocator_AddRef(IVBSAXLocator* iface)
2131{
2132 saxlocator *This = impl_from_IVBSAXLocator( iface );
2133 TRACE("%p\n", This );
2134 return ISAXLocator_AddRef(&This->ISAXLocator_iface);
2135}
2136
2137static ULONG WINAPI ivbsaxlocator_Release(IVBSAXLocator* iface)
2138{
2139 saxlocator *This = impl_from_IVBSAXLocator( iface );
2140 return ISAXLocator_Release(&This->ISAXLocator_iface);
2141}
2142
2143/*** IDispatch methods ***/
2144static HRESULT WINAPI ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator *iface, UINT* pctinfo )
2145{
2146 saxlocator *This = impl_from_IVBSAXLocator( iface );
2147
2148 TRACE("(%p)->(%p)\n", This, pctinfo);
2149
2150 *pctinfo = 1;
2151
2152 return S_OK;
2153}
2154
2155static HRESULT WINAPI ivbsaxlocator_GetTypeInfo(
2156 IVBSAXLocator *iface,
2157 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
2158{
2159 saxlocator *This = impl_from_IVBSAXLocator( iface );
2160
2161 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
2162
2163 return get_typeinfo(IVBSAXLocator_tid, ppTInfo);
2164}
2165
2166static HRESULT WINAPI ivbsaxlocator_GetIDsOfNames(
2167 IVBSAXLocator *iface,
2168 REFIID riid,
2169 LPOLESTR* rgszNames,
2170 UINT cNames,
2171 LCID lcid,
2172 DISPID* rgDispId)
2173{
2174 saxlocator *This = impl_from_IVBSAXLocator( iface );
2176 HRESULT hr;
2177
2178 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
2179 lcid, rgDispId);
2180
2181 if(!rgszNames || cNames == 0 || !rgDispId)
2182 return E_INVALIDARG;
2183
2185 if(SUCCEEDED(hr))
2186 {
2187 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
2188 ITypeInfo_Release(typeinfo);
2189 }
2190
2191 return hr;
2192}
2193
2194static HRESULT WINAPI ivbsaxlocator_Invoke(
2195 IVBSAXLocator *iface,
2196 DISPID dispIdMember,
2197 REFIID riid,
2198 LCID lcid,
2199 WORD wFlags,
2200 DISPPARAMS* pDispParams,
2201 VARIANT* pVarResult,
2202 EXCEPINFO* pExcepInfo,
2203 UINT* puArgErr)
2204{
2205 saxlocator *This = impl_from_IVBSAXLocator( iface );
2207 HRESULT hr;
2208
2209 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2210 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2211
2213 if(SUCCEEDED(hr))
2214 {
2215 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXLocator_iface, dispIdMember, wFlags,
2216 pDispParams, pVarResult, pExcepInfo, puArgErr);
2217 ITypeInfo_Release(typeinfo);
2218 }
2219
2220 return hr;
2221}
2222
2223/*** IVBSAXLocator methods ***/
2224static HRESULT WINAPI ivbsaxlocator_get_columnNumber(
2225 IVBSAXLocator* iface,
2226 int *pnColumn)
2227{
2228 saxlocator *This = impl_from_IVBSAXLocator( iface );
2229 return ISAXLocator_getColumnNumber(&This->ISAXLocator_iface, pnColumn);
2230}
2231
2232static HRESULT WINAPI ivbsaxlocator_get_lineNumber(
2233 IVBSAXLocator* iface,
2234 int *pnLine)
2235{
2236 saxlocator *This = impl_from_IVBSAXLocator( iface );
2237 return ISAXLocator_getLineNumber(&This->ISAXLocator_iface, pnLine);
2238}
2239
2240static HRESULT WINAPI ivbsaxlocator_get_publicId(IVBSAXLocator* iface, BSTR *ret)
2241{
2242 saxlocator *This = impl_from_IVBSAXLocator( iface );
2243 const WCHAR *publicidW;
2244 HRESULT hr;
2245
2246 TRACE("(%p)->(%p)\n", This, ret);
2247
2248 if (!ret)
2249 return E_POINTER;
2250
2251 *ret = NULL;
2252 hr = ISAXLocator_getPublicId(&This->ISAXLocator_iface, &publicidW);
2253 if (FAILED(hr))
2254 return hr;
2255
2256 return return_bstr(publicidW, ret);
2257}
2258
2259static HRESULT WINAPI ivbsaxlocator_get_systemId(IVBSAXLocator* iface, BSTR *ret)
2260{
2261 saxlocator *This = impl_from_IVBSAXLocator( iface );
2262 const WCHAR *systemidW;
2263 HRESULT hr;
2264
2265 TRACE("(%p)->(%p)\n", This, ret);
2266
2267 if (!ret)
2268 return E_POINTER;
2269
2270 *ret = NULL;
2271 hr = ISAXLocator_getSystemId(&This->ISAXLocator_iface, &systemidW);
2272 if (FAILED(hr))
2273 return hr;
2274
2275 return return_bstr(systemidW, ret);
2276}
2277
2278static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl =
2279{
2280 ivbsaxlocator_QueryInterface,
2281 ivbsaxlocator_AddRef,
2282 ivbsaxlocator_Release,
2283 ivbsaxlocator_GetTypeInfoCount,
2284 ivbsaxlocator_GetTypeInfo,
2285 ivbsaxlocator_GetIDsOfNames,
2286 ivbsaxlocator_Invoke,
2287 ivbsaxlocator_get_columnNumber,
2288 ivbsaxlocator_get_lineNumber,
2289 ivbsaxlocator_get_publicId,
2290 ivbsaxlocator_get_systemId
2291};
2292
2293/*** ISAXLocator interface ***/
2294/*** IUnknown methods ***/
2295static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject)
2296{
2297 saxlocator *This = impl_from_ISAXLocator( iface );
2298
2299 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
2300
2301 *ppvObject = NULL;
2302
2303 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2304 IsEqualGUID( riid, &IID_ISAXLocator ))
2305 {
2306 *ppvObject = iface;
2307 }
2308 else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
2309 {
2310 *ppvObject = &This->ISAXAttributes_iface;
2311 }
2312 else
2313 {
2314 WARN("interface %s not implemented\n", debugstr_guid(riid));
2315 return E_NOINTERFACE;
2316 }
2317
2318 ISAXLocator_AddRef( iface );
2319
2320 return S_OK;
2321}
2322
2323static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface)
2324{
2325 saxlocator *This = impl_from_ISAXLocator( iface );
2327 TRACE("(%p)->(%d)\n", This, ref);
2328 return ref;
2329}
2330
2331static ULONG WINAPI isaxlocator_Release(
2332 ISAXLocator* iface)
2333{
2334 saxlocator *This = impl_from_ISAXLocator( iface );
2335 LONG ref = InterlockedDecrement( &This->ref );
2336
2337 TRACE("(%p)->(%d)\n", This, ref );
2338
2339 if (ref == 0)
2340 {
2341 element_entry *element, *element2;
2342 int index;
2343
2344 SysFreeString(This->publicId);
2345 SysFreeString(This->systemId);
2346 SysFreeString(This->namespaceUri);
2347
2348 for(index = 0; index < This->attr_alloc_count; index++)
2349 {
2350 SysFreeString(This->attributes[index].szLocalname);
2351 SysFreeString(This->attributes[index].szValue);
2352 SysFreeString(This->attributes[index].szQName);
2353 }
2354 heap_free(This->attributes);
2355
2356 /* element stack */
2357 LIST_FOR_EACH_ENTRY_SAFE(element, element2, &This->elements, element_entry, entry)
2358 {
2360 free_element_entry(element);
2361 }
2362
2363 ISAXXMLReader_Release(&This->saxreader->ISAXXMLReader_iface);
2364 heap_free( This );
2365 }
2366
2367 return ref;
2368}
2369
2370/*** ISAXLocator methods ***/
2371static HRESULT WINAPI isaxlocator_getColumnNumber(
2372 ISAXLocator* iface,
2373 int *pnColumn)
2374{
2375 saxlocator *This = impl_from_ISAXLocator( iface );
2376
2377 *pnColumn = This->column;
2378 return S_OK;
2379}
2380
2381static HRESULT WINAPI isaxlocator_getLineNumber(
2382 ISAXLocator* iface,
2383 int *pnLine)
2384{
2385 saxlocator *This = impl_from_ISAXLocator( iface );
2386
2387 *pnLine = This->line;
2388 return S_OK;
2389}
2390
2391static HRESULT WINAPI isaxlocator_getPublicId(
2392 ISAXLocator* iface,
2393 const WCHAR ** ppwchPublicId)
2394{
2395 BSTR publicId;
2396 saxlocator *This = impl_from_ISAXLocator( iface );
2397
2398 SysFreeString(This->publicId);
2399
2400 publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt));
2401 if(SysStringLen(publicId))
2402 This->publicId = publicId;
2403 else
2404 {
2405 SysFreeString(publicId);
2406 This->publicId = NULL;
2407 }
2408
2409 *ppwchPublicId = This->publicId;
2410 return S_OK;
2411}
2412
2413static HRESULT WINAPI isaxlocator_getSystemId(
2414 ISAXLocator* iface,
2415 const WCHAR ** ppwchSystemId)
2416{
2417 BSTR systemId;
2418 saxlocator *This = impl_from_ISAXLocator( iface );
2419
2420 SysFreeString(This->systemId);
2421
2422 systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt));
2423 if(SysStringLen(systemId))
2424 This->systemId = systemId;
2425 else
2426 {
2427 SysFreeString(systemId);
2428 This->systemId = NULL;
2429 }
2430
2431 *ppwchSystemId = This->systemId;
2432 return S_OK;
2433}
2434
2435static const struct ISAXLocatorVtbl SAXLocatorVtbl =
2436{
2437 isaxlocator_QueryInterface,
2438 isaxlocator_AddRef,
2439 isaxlocator_Release,
2440 isaxlocator_getColumnNumber,
2441 isaxlocator_getLineNumber,
2442 isaxlocator_getPublicId,
2443 isaxlocator_getSystemId
2444};
2445
2446static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator, BOOL vbInterface)
2447{
2448 static const WCHAR w3xmlns[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2449 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2450
2451 saxlocator *locator;
2452
2453 locator = heap_alloc( sizeof (*locator) );
2454 if( !locator )
2455 return E_OUTOFMEMORY;
2456
2457 locator->IVBSAXLocator_iface.lpVtbl = &VBSAXLocatorVtbl;
2458 locator->ISAXLocator_iface.lpVtbl = &SAXLocatorVtbl;
2459 locator->IVBSAXAttributes_iface.lpVtbl = &ivbsaxattributes_vtbl;
2460 locator->ISAXAttributes_iface.lpVtbl = &isaxattributes_vtbl;
2461 locator->ref = 1;
2462 locator->vbInterface = vbInterface;
2463
2464 locator->saxreader = reader;
2465 ISAXXMLReader_AddRef(&reader->ISAXXMLReader_iface);
2466
2467 locator->pParserCtxt = NULL;
2468 locator->publicId = NULL;
2469 locator->systemId = NULL;
2470 locator->line = reader->version < MSXML4 ? 0 : 1;
2471 locator->column = 0;
2472 locator->ret = S_OK;
2473 if (locator->saxreader->version >= MSXML6)
2474 locator->namespaceUri = SysAllocString(w3xmlns);
2475 else
2476 locator->namespaceUri = SysAllocStringLen(NULL, 0);
2477 if(!locator->namespaceUri)
2478 {
2479 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2481 return E_OUTOFMEMORY;
2482 }
2483
2484 locator->attr_alloc_count = 8;
2485 locator->attr_count = 0;
2486 locator->attributes = heap_alloc_zero(sizeof(struct _attributes)*locator->attr_alloc_count);
2487 if(!locator->attributes)
2488 {
2489 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2490 SysFreeString(locator->namespaceUri);
2492 return E_OUTOFMEMORY;
2493 }
2494
2495 list_init(&locator->elements);
2496
2497 *ppsaxlocator = locator;
2498
2499 TRACE("returning %p\n", *ppsaxlocator);
2500
2501 return S_OK;
2502}
2503
2504/*** SAXXMLReader internal functions ***/
2505static HRESULT internal_parseBuffer(saxreader *This, const char *buffer, int size, BOOL vbInterface)
2506{
2509 saxlocator *locator;
2510 HRESULT hr;
2511
2512 TRACE("(%p)->(%p %d)\n", This, buffer, size);
2513
2514 hr = SAXLocator_create(This, &locator, vbInterface);
2515 if (FAILED(hr))
2516 return hr;
2517
2518 if (size >= 4)
2519 {
2520 const unsigned char *buff = (unsigned char*)buffer;
2521
2524 TRACE("detected encoding: %s\n", enc_name);
2525 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2527 buff[0] == 0xEF && buff[1] == 0xBB && buff[2] == 0xBF)
2528 {
2529 buffer += 3;
2530 size -= 3;
2531 }
2532 }
2533
2534 /* if libxml2 detection failed try to guess */
2536 {
2537 const WCHAR *ptr = (WCHAR*)buffer;
2538 /* an xml declaration with optional encoding will still be handled by the parser */
2539 if ((size >= 2) && *ptr == '<' && ptr[1] != '?')
2540 {
2543 }
2544 }
2545 else if (encoding == XML_CHAR_ENCODING_UTF8)
2547 else
2548 enc_name = NULL;
2549
2551 if (!locator->pParserCtxt)
2552 {
2553 ISAXLocator_Release(&locator->ISAXLocator_iface);
2554 return E_FAIL;
2555 }
2556
2557 if (enc_name)
2558 {
2559 locator->pParserCtxt->encoding = xmlStrdup(enc_name);
2561 TRACE("switching to %s\n", enc_name);
2562 xmlSwitchEncoding(locator->pParserCtxt, encoding);
2563 }
2564 }
2565
2566 xmlFree(locator->pParserCtxt->sax);
2567 locator->pParserCtxt->sax = &locator->saxreader->sax;
2568 locator->pParserCtxt->userData = locator;
2569
2570 This->isParsing = TRUE;
2571 if(xmlParseDocument(locator->pParserCtxt) == -1 && locator->ret == S_OK)
2572 hr = E_FAIL;
2573 else
2574 hr = locator->ret;
2575 This->isParsing = FALSE;
2576
2577 if(locator->pParserCtxt)
2578 {
2579 locator->pParserCtxt->sax = NULL;
2580 xmlFreeParserCtxt(locator->pParserCtxt);
2581 locator->pParserCtxt = NULL;
2582 }
2583
2584 ISAXLocator_Release(&locator->ISAXLocator_iface);
2585 return hr;
2586}
2587
2588static HRESULT internal_parseStream(saxreader *This, ISequentialStream *stream, BOOL vbInterface)
2589{
2590 saxlocator *locator;
2591 HRESULT hr;
2592 ULONG dataRead;
2593 char data[2048];
2594 int ret;
2595
2596 dataRead = 0;
2597 hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead);
2598 if(FAILED(hr)) return hr;
2599
2600 hr = SAXLocator_create(This, &locator, vbInterface);
2601 if(FAILED(hr)) return hr;
2602
2603 locator->pParserCtxt = xmlCreatePushParserCtxt(
2604 &locator->saxreader->sax, locator,
2605 data, dataRead, NULL);
2606 if(!locator->pParserCtxt)
2607 {
2608 ISAXLocator_Release(&locator->ISAXLocator_iface);
2609 return E_FAIL;
2610 }
2611
2612 This->isParsing = TRUE;
2613
2614 do {
2615 dataRead = 0;
2616 hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead);
2617 if (FAILED(hr) || !dataRead) break;
2618
2619 ret = xmlParseChunk(locator->pParserCtxt, data, dataRead, 0);
2620 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2621 }while(hr == S_OK);
2622
2623 if(SUCCEEDED(hr))
2624 {
2625 ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
2626 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2627 }
2628
2629
2630 This->isParsing = FALSE;
2631
2632 xmlFreeParserCtxt(locator->pParserCtxt);
2633 locator->pParserCtxt = NULL;
2634 ISAXLocator_Release(&locator->ISAXLocator_iface);
2635 return hr;
2636}
2637
2638static HRESULT internal_parse(
2639 saxreader* This,
2640 VARIANT varInput,
2641 BOOL vbInterface)
2642{
2643 HRESULT hr;
2644
2645 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varInput));
2646
2647 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2648 free_bstr_pool(&This->pool);
2649
2650 switch(V_VT(&varInput))
2651 {
2652 case VT_BSTR:
2653 case VT_BSTR|VT_BYREF:
2654 {
2655 BSTR str = V_ISBYREF(&varInput) ? *V_BSTRREF(&varInput) : V_BSTR(&varInput);
2656 hr = internal_parseBuffer(This, (const char*)str, strlenW(str)*sizeof(WCHAR), vbInterface);
2657 break;
2658 }
2659 case VT_ARRAY|VT_UI1: {
2660 void *pSAData;
2661 LONG lBound, uBound;
2662 ULONG dataRead;
2663
2664 hr = SafeArrayGetLBound(V_ARRAY(&varInput), 1, &lBound);
2665 if(hr != S_OK) break;
2666 hr = SafeArrayGetUBound(V_ARRAY(&varInput), 1, &uBound);
2667 if(hr != S_OK) break;
2668 dataRead = (uBound-lBound)*SafeArrayGetElemsize(V_ARRAY(&varInput));
2669 hr = SafeArrayAccessData(V_ARRAY(&varInput), &pSAData);
2670 if(hr != S_OK) break;
2671 hr = internal_parseBuffer(This, pSAData, dataRead, vbInterface);
2672 SafeArrayUnaccessData(V_ARRAY(&varInput));
2673 break;
2674 }
2675 case VT_UNKNOWN:
2676 case VT_DISPATCH: {
2679
2680 if (!V_UNKNOWN(&varInput))
2681 return E_INVALIDARG;
2682
2683 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2684 &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK)
2685 {
2686 BSTR bstrData;
2687
2688 IXMLDOMDocument_get_xml(xmlDoc, &bstrData);
2689 hr = internal_parseBuffer(This, (const char*)bstrData,
2690 SysStringByteLen(bstrData), vbInterface);
2691 IXMLDOMDocument_Release(xmlDoc);
2692 SysFreeString(bstrData);
2693 break;
2694 }
2695
2696 /* try base interface first */
2697 IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_ISequentialStream, (void**)&stream);
2698 if (!stream)
2699 /* this should never happen if IStream is implemented properly, but just in case */
2700 IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream);
2701
2702 if(stream)
2703 {
2704 hr = internal_parseStream(This, stream, vbInterface);
2705 ISequentialStream_Release(stream);
2706 }
2707 else
2708 {
2709 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2710 hr = E_INVALIDARG;
2711 }
2712
2713 break;
2714 }
2715 default:
2716 WARN("vt %d not implemented\n", V_VT(&varInput));
2717 hr = E_INVALIDARG;
2718 }
2719
2720 return hr;
2721}
2722
2723static HRESULT internal_vbonDataAvailable(void *obj, char *ptr, DWORD len)
2724{
2725 saxreader *This = obj;
2726
2727 return internal_parseBuffer(This, ptr, len, TRUE);
2728}
2729
2730static HRESULT internal_onDataAvailable(void *obj, char *ptr, DWORD len)
2731{
2732 saxreader *This = obj;
2733
2734 return internal_parseBuffer(This, ptr, len, FALSE);
2735}
2736
2737static HRESULT internal_parseURL(
2738 saxreader* This,
2739 const WCHAR *url,
2740 BOOL vbInterface)
2741{
2742 IMoniker *mon;
2743 bsc_t *bsc;
2744 HRESULT hr;
2745
2746 TRACE("(%p)->(%s)\n", This, debugstr_w(url));
2747
2749 if(FAILED(hr))
2750 return hr;
2751
2752 if(vbInterface) hr = bind_url(mon, internal_vbonDataAvailable, This, &bsc);
2753 else hr = bind_url(mon, internal_onDataAvailable, This, &bsc);
2754 IMoniker_Release(mon);
2755
2756 if(FAILED(hr))
2757 return hr;
2758
2759 return detach_bsc(bsc);
2760}
2761
2762static HRESULT saxreader_put_handler_from_variant(saxreader *This, enum saxhandler_type type, const VARIANT *v, BOOL vb)
2763{
2764 const IID *riid;
2765
2766 if (V_VT(v) == VT_EMPTY)
2767 return saxreader_put_handler(This, type, NULL, vb);
2768
2769 switch (type)
2770 {
2771 case SAXDeclHandler:
2772 riid = vb ? &IID_IVBSAXDeclHandler : &IID_ISAXDeclHandler;
2773 break;
2774 case SAXLexicalHandler:
2775 riid = vb ? &IID_IVBSAXLexicalHandler : &IID_ISAXLexicalHandler;
2776 break;
2777 default:
2778 ERR("wrong handler type %d\n", type);
2779 return E_FAIL;
2780 }
2781
2782 switch (V_VT(v))
2783 {
2784 case VT_DISPATCH:
2785 case VT_UNKNOWN:
2786 {
2788
2789 if (V_UNKNOWN(v))
2790 {
2791 HRESULT hr = IUnknown_QueryInterface(V_UNKNOWN(v), riid, (void**)&handler);
2792 if (FAILED(hr)) return hr;
2793 }
2794
2795 saxreader_put_handler(This, type, handler, vb);
2796 if (handler) IUnknown_Release(handler);
2797 break;
2798 }
2799 default:
2800 ERR("value type %d not supported\n", V_VT(v));
2801 return E_INVALIDARG;
2802 }
2803
2804 return S_OK;
2805}
2806
2807static HRESULT internal_putProperty(
2808 saxreader* This,
2809 const WCHAR *prop,
2810 VARIANT value,
2811 BOOL vbInterface)
2812{
2813 VARIANT *v;
2814
2815 TRACE("(%p)->(%s %s)\n", This, debugstr_w(prop), debugstr_variant(&value));
2816
2817 if (This->isParsing) return E_FAIL;
2818
2820 if(!memcmp(prop, PropertyDeclHandlerW, sizeof(PropertyDeclHandlerW)))
2821 return saxreader_put_handler_from_variant(This, SAXDeclHandler, v, vbInterface);
2822
2823 if(!memcmp(prop, PropertyLexicalHandlerW, sizeof(PropertyLexicalHandlerW)))
2824 return saxreader_put_handler_from_variant(This, SAXLexicalHandler, v, vbInterface);
2825
2826 if(!memcmp(prop, PropertyMaxXMLSizeW, sizeof(PropertyMaxXMLSizeW)))
2827 {
2828 if (V_VT(v) == VT_I4 && V_I4(v) == 0) return S_OK;
2829 FIXME("(%p)->(%s): max-xml-size unsupported\n", This, debugstr_variant(v));
2830 return E_NOTIMPL;
2831 }
2832
2833 if(!memcmp(prop, PropertyMaxElementDepthW, sizeof(PropertyMaxElementDepthW)))
2834 {
2835 if (V_VT(v) == VT_I4 && V_I4(v) == 0) return S_OK;
2836 FIXME("(%p)->(%s): max-element-depth unsupported\n", This, debugstr_variant(v));
2837 return E_NOTIMPL;
2838 }
2839
2840 FIXME("(%p)->(%s:%s): unsupported property\n", This, debugstr_w(prop), debugstr_variant(v));
2841
2842 if(!memcmp(prop, PropertyCharsetW, sizeof(PropertyCharsetW)))
2843 return E_NOTIMPL;
2844
2845 if(!memcmp(prop, PropertyDomNodeW, sizeof(PropertyDomNodeW)))
2846 return E_FAIL;
2847
2848 if(!memcmp(prop, PropertyInputSourceW, sizeof(PropertyInputSourceW)))
2849 return E_NOTIMPL;
2850
2851 if(!memcmp(prop, PropertySchemaDeclHandlerW, sizeof(PropertySchemaDeclHandlerW)))
2852 return E_NOTIMPL;
2853
2854 if(!memcmp(prop, PropertyXMLDeclEncodingW, sizeof(PropertyXMLDeclEncodingW)))
2855 return E_FAIL;
2856
2857 if(!memcmp(prop, PropertyXMLDeclStandaloneW, sizeof(PropertyXMLDeclStandaloneW)))
2858 return E_FAIL;
2859
2860 if(!memcmp(prop, PropertyXMLDeclVersionW, sizeof(PropertyXMLDeclVersionW)))
2861 return E_FAIL;
2862
2863 return E_INVALIDARG;
2864}
2865
2866static HRESULT internal_getProperty(const saxreader* This, const WCHAR *prop, VARIANT *value, BOOL vb)
2867{
2868 TRACE("(%p)->(%s)\n", This, debugstr_w(prop));
2869
2870 if (!value) return E_POINTER;
2871
2872 if (!memcmp(PropertyLexicalHandlerW, prop, sizeof(PropertyLexicalHandlerW)))
2873 {
2875 saxreader_get_handler(This, SAXLexicalHandler, vb, (void**)&V_UNKNOWN(value));
2876 return S_OK;
2877 }
2878
2879 if (!memcmp(PropertyDeclHandlerW, prop, sizeof(PropertyDeclHandlerW)))
2880 {
2882 saxreader_get_handler(This, SAXDeclHandler, vb, (void**)&V_UNKNOWN(value));
2883 return S_OK;
2884 }
2885
2886 if (!memcmp(PropertyXmlDeclVersionW, prop, sizeof(PropertyXmlDeclVersionW)))
2887 {
2888 V_VT(value) = VT_BSTR;
2889 V_BSTR(value) = SysAllocString(This->xmldecl_version);
2890 return S_OK;
2891 }
2892
2893 FIXME("(%p)->(%s) unsupported property\n", This, debugstr_w(prop));
2894
2895 return E_NOTIMPL;
2896}
2897
2898/*** IVBSAXXMLReader interface ***/
2899/*** IUnknown methods ***/
2900static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject)
2901{
2902 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2903
2904 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
2905
2906 *ppvObject = NULL;
2907
2908 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2910 IsEqualGUID( riid, &IID_IVBSAXXMLReader ))
2911 {
2912 *ppvObject = iface;
2913 }
2914 else if( IsEqualGUID( riid, &IID_ISAXXMLReader ))
2915 {
2916 *ppvObject = &This->ISAXXMLReader_iface;
2917 }
2918 else if (dispex_query_interface(&This->dispex, riid, ppvObject))
2919 {
2920 return *ppvObject ? S_OK : E_NOINTERFACE;
2921 }
2922 else
2923 {
2924 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2925 return E_NOINTERFACE;
2926 }
2927
2928 IVBSAXXMLReader_AddRef( iface );
2929
2930 return S_OK;
2931}
2932
2933static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface)
2934{
2935 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2936 TRACE("%p\n", This );
2937 return InterlockedIncrement( &This->ref );
2938}
2939
2940static ULONG WINAPI saxxmlreader_Release(
2941 IVBSAXXMLReader* iface)
2942{
2943 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2944 LONG ref;
2945
2946 TRACE("%p\n", This );
2947
2948 ref = InterlockedDecrement( &This->ref );
2949 if ( ref == 0 )
2950 {
2951 int i;
2952
2953 for (i = 0; i < SAXHandler_Last; i++)
2954 {
2955 struct saxanyhandler_iface *saxiface = &This->saxhandlers[i].u.anyhandler;
2956
2957 if (saxiface->handler)
2958 IUnknown_Release(saxiface->handler);
2959
2960 if (saxiface->vbhandler)
2961 IUnknown_Release(saxiface->vbhandler);
2962 }
2963
2964 SysFreeString(This->xmldecl_version);
2965 free_bstr_pool(&This->pool);
2966
2967 heap_free( This );
2968 }
2969
2970 return ref;
2971}
2972/*** IDispatch ***/
2973static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo )
2974{
2975 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2976 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2977}
2978
2979static HRESULT WINAPI saxxmlreader_GetTypeInfo(
2980 IVBSAXXMLReader *iface,
2981 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
2982{
2983 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2984 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
2985 iTInfo, lcid, ppTInfo);
2986}
2987
2988static HRESULT WINAPI saxxmlreader_GetIDsOfNames(
2989 IVBSAXXMLReader *iface,
2990 REFIID riid,
2991 LPOLESTR* rgszNames,
2992 UINT cNames,
2993 LCID lcid,
2994 DISPID* rgDispId)
2995{
2996 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2997 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2998 riid, rgszNames, cNames, lcid, rgDispId);
2999}
3000
3001static HRESULT WINAPI saxxmlreader_Invoke(
3002 IVBSAXXMLReader *iface,
3003 DISPID dispIdMember,
3004 REFIID riid,
3005 LCID lcid,
3006 WORD wFlags,
3007 DISPPARAMS* pDispParams,
3008 VARIANT* pVarResult,
3009 EXCEPINFO* pExcepInfo,
3010 UINT* puArgErr)
3011{
3012 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3013 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
3014 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3015}
3016
3017/*** IVBSAXXMLReader methods ***/
3018static HRESULT WINAPI saxxmlreader_getFeature(
3019 IVBSAXXMLReader* iface,
3020 BSTR feature_name,
3022{
3023 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3024 return ISAXXMLReader_getFeature(&This->ISAXXMLReader_iface, feature_name, value);
3025}
3026
3027static HRESULT WINAPI saxxmlreader_putFeature(
3028 IVBSAXXMLReader* iface,
3029 BSTR feature_name,
3031{
3032 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3033 return ISAXXMLReader_putFeature(&This->ISAXXMLReader_iface, feature_name, value);
3034}
3035
3036static HRESULT WINAPI saxxmlreader_getProperty(
3037 IVBSAXXMLReader* iface,
3038 BSTR prop,
3039 VARIANT *value)
3040{
3041 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3042 return internal_getProperty(This, prop, value, TRUE);
3043}
3044
3045static HRESULT WINAPI saxxmlreader_putProperty(
3046 IVBSAXXMLReader* iface,
3047 BSTR pProp,
3048 VARIANT value)
3049{
3050 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3051 return internal_putProperty(This, pProp, value, TRUE);
3052}
3053
3054static HRESULT WINAPI saxxmlreader_get_entityResolver(
3055 IVBSAXXMLReader* iface,
3056 IVBSAXEntityResolver **resolver)
3057{
3058 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3059 return saxreader_get_handler(This, SAXEntityResolver, TRUE, (void**)resolver);
3060}
3061
3062static HRESULT WINAPI saxxmlreader_put_entityResolver(
3063 IVBSAXXMLReader* iface,
3064 IVBSAXEntityResolver *resolver)
3065{
3066 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3067 return saxreader_put_handler(This, SAXEntityResolver, resolver, TRUE);
3068}
3069
3070static HRESULT WINAPI saxxmlreader_get_contentHandler(
3071 IVBSAXXMLReader* iface,
3072 IVBSAXContentHandler **handler)
3073{
3074 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3075 return saxreader_get_handler(This, SAXContentHandler, TRUE, (void**)handler);
3076}
3077
3078static HRESULT WINAPI saxxmlreader_put_contentHandler(
3079 IVBSAXXMLReader* iface,
3080 IVBSAXContentHandler *handler)
3081{
3082 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3083 return saxreader_put_handler(This, SAXContentHandler, handler, TRUE);
3084}
3085
3086static HRESULT WINAPI saxxmlreader_get_dtdHandler(
3087 IVBSAXXMLReader* iface,
3088 IVBSAXDTDHandler **handler)
3089{
3090 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3091 return saxreader_get_handler(This, SAXDTDHandler, TRUE, (void**)handler);
3092}
3093
3094static HRESULT WINAPI saxxmlreader_put_dtdHandler(
3095 IVBSAXXMLReader* iface,
3096 IVBSAXDTDHandler *handler)
3097{
3098 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3099 return saxreader_put_handler(This, SAXDTDHandler, handler, TRUE);
3100}
3101
3102static HRESULT WINAPI saxxmlreader_get_errorHandler(
3103 IVBSAXXMLReader* iface,
3104 IVBSAXErrorHandler **handler)
3105{
3106 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3107 return saxreader_get_handler(This, SAXErrorHandler, TRUE, (void**)handler);
3108}
3109
3110static HRESULT WINAPI saxxmlreader_put_errorHandler(
3111 IVBSAXXMLReader* iface,
3112 IVBSAXErrorHandler *handler)
3113{
3114 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3115 return saxreader_put_handler(This, SAXErrorHandler, handler, TRUE);
3116}
3117
3118static HRESULT WINAPI saxxmlreader_get_baseURL(
3119 IVBSAXXMLReader* iface,
3120 BSTR *pBaseUrl)
3121{
3122 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3123
3124 FIXME("(%p)->(%p) stub\n", This, pBaseUrl);
3125 return E_NOTIMPL;
3126}
3127
3128static HRESULT WINAPI saxxmlreader_put_baseURL(
3129 IVBSAXXMLReader* iface,
3130 BSTR pBaseUrl)
3131{
3132 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3133 return ISAXXMLReader_putBaseURL(&This->ISAXXMLReader_iface, pBaseUrl);
3134}
3135
3136static HRESULT WINAPI saxxmlreader_get_secureBaseURL(
3137 IVBSAXXMLReader* iface,
3138 BSTR *pSecureBaseUrl)
3139{
3140 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3141
3142 FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
3143 return E_NOTIMPL;
3144}
3145
3146static HRESULT WINAPI saxxmlreader_put_secureBaseURL(
3147 IVBSAXXMLReader* iface,
3148 BSTR secureBaseUrl)
3149{
3150 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3151 return ISAXXMLReader_putSecureBaseURL(&This->ISAXXMLReader_iface, secureBaseUrl);
3152}
3153
3154static HRESULT WINAPI saxxmlreader_parse(
3155 IVBSAXXMLReader* iface,
3156 VARIANT varInput)
3157{
3158 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3159 return internal_parse(This, varInput, TRUE);
3160}
3161
3162static HRESULT WINAPI saxxmlreader_parseURL(
3163 IVBSAXXMLReader* iface,
3164 BSTR url)
3165{
3166 saxreader *This = impl_from_IVBSAXXMLReader( iface );
3167 return internal_parseURL(This, url, TRUE);
3168}
3169
3170static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl =
3171{
3172 saxxmlreader_QueryInterface,
3173 saxxmlreader_AddRef,
3174 saxxmlreader_Release,
3175 saxxmlreader_GetTypeInfoCount,
3176 saxxmlreader_GetTypeInfo,
3177 saxxmlreader_GetIDsOfNames,
3178 saxxmlreader_Invoke,
3179 saxxmlreader_getFeature,
3180 saxxmlreader_putFeature,
3181 saxxmlreader_getProperty,
3182 saxxmlreader_putProperty,
3183 saxxmlreader_get_entityResolver,
3184 saxxmlreader_put_entityResolver,
3185 saxxmlreader_get_contentHandler,
3186 saxxmlreader_put_contentHandler,
3187 saxxmlreader_get_dtdHandler,
3188 saxxmlreader_put_dtdHandler,
3189 saxxmlreader_get_errorHandler,
3190 saxxmlreader_put_errorHandler,
3191 saxxmlreader_get_baseURL,
3192 saxxmlreader_put_baseURL,
3193 saxxmlreader_get_secureBaseURL,
3194 saxxmlreader_put_secureBaseURL,
3195 saxxmlreader_parse,
3196 saxxmlreader_parseURL
3197};
3198
3199/*** ISAXXMLReader interface ***/
3200/*** IUnknown methods ***/
3201static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject)
3202{
3203 saxreader *This = impl_from_ISAXXMLReader( iface );
3204 return IVBSAXXMLReader_QueryInterface(&This->IVBSAXXMLReader_iface, riid, ppvObject);
3205}
3206
3207static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface)
3208{
3209 saxreader *This = impl_from_ISAXXMLReader( iface );
3210 return IVBSAXXMLReader_AddRef(&This->IVBSAXXMLReader_iface);
3211}
3212
3213static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface)
3214{
3215 saxreader *This = impl_from_ISAXXMLReader( iface );
3216 return IVBSAXXMLReader_Release(&This->IVBSAXXMLReader_iface);
3217}
3218
3219/*** ISAXXMLReader methods ***/
3220static HRESULT WINAPI isaxxmlreader_getFeature(
3221 ISAXXMLReader* iface,
3222 const WCHAR *feature_name,
3224{
3225 saxreader *This = impl_from_ISAXXMLReader( iface );
3226 saxreader_feature feature;
3227
3228 TRACE("(%p)->(%s %p)\n", This, debugstr_w(feature_name), value);
3229
3230 feature = get_saxreader_feature(feature_name);
3231
3232 if (This->version < MSXML4 && (feature == ExhaustiveErrors || feature == SchemaValidation))
3233 return E_INVALIDARG;
3234
3235 if (feature == Namespaces ||
3236 feature == NamespacePrefixes ||
3237 feature == ExhaustiveErrors ||
3238 feature == SchemaValidation)
3239 return get_feature_value(This, feature, value);
3240
3241 FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(feature_name), value);
3242 return E_NOTIMPL;
3243}
3244
3245static HRESULT WINAPI isaxxmlreader_putFeature(
3246 ISAXXMLReader* iface,
3247 const WCHAR *feature_name,
3249{
3250 saxreader *This = impl_from_ISAXXMLReader( iface );
3251 saxreader_feature feature;
3252
3253 TRACE("(%p)->(%s %x)\n", This, debugstr_w(feature_name), value);
3254
3255 feature = get_saxreader_feature(feature_name);
3256
3257 /* accepted cases */
3258 if ((feature == ExhaustiveErrors && value == VARIANT_FALSE) ||
3259 (feature == SchemaValidation && value == VARIANT_FALSE) ||
3260 feature == Namespaces ||
3261 feature == NamespacePrefixes)
3262 {
3263 return set_feature_value(This, feature, value);
3264 }
3265
3266 if (feature == LexicalHandlerParEntities ||
3267 feature == ProhibitDTD ||
3268 feature == ExternalGeneralEntities ||
3269 feature == ExternalParameterEntities)
3270 {
3271 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
3272 return set_feature_value(This, feature, value);
3273 }
3274
3275 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
3276 return E_NOTIMPL;
3277}
3278
3279static HRESULT WINAPI isaxxmlreader_getProperty(
3280 ISAXXMLReader* iface,
3281 const WCHAR *prop,
3282 VARIANT *value)
3283{
3284 saxreader *This = impl_from_ISAXXMLReader( iface );
3285 return internal_getProperty(This, prop, value, FALSE);
3286}
3287
3288static HRESULT WINAPI isaxxmlreader_putProperty(
3289 ISAXXMLReader* iface,
3290 const WCHAR *pProp,
3291 VARIANT value)
3292{
3293 saxreader *This = impl_from_ISAXXMLReader( iface );
3294 return internal_putProperty(This, pProp, value, FALSE);
3295}
3296
3297static HRESULT WINAPI isaxxmlreader_getEntityResolver(
3298 ISAXXMLReader* iface,
3299 ISAXEntityResolver **resolver)
3300{
3301 saxreader *This = impl_from_ISAXXMLReader( iface );
3302 return saxreader_get_handler(This, SAXEntityResolver, FALSE, (void**)resolver);
3303}
3304
3305static HRESULT WINAPI isaxxmlreader_putEntityResolver(
3306 ISAXXMLReader* iface,
3307 ISAXEntityResolver *resolver)
3308{
3309 saxreader *This = impl_from_ISAXXMLReader( iface );
3310 return saxreader_put_handler(This, SAXEntityResolver, resolver, FALSE);
3311}
3312
3313static HRESULT WINAPI isaxxmlreader_getContentHandler(
3314 ISAXXMLReader* iface,
3315 ISAXContentHandler **handler)
3316{
3317 saxreader *This = impl_from_ISAXXMLReader( iface );
3318 return saxreader_get_handler(This, SAXContentHandler, FALSE, (void**)handler);
3319}
3320
3321static HRESULT WINAPI isaxxmlreader_putContentHandler(
3322 ISAXXMLReader* iface,
3323 ISAXContentHandler *handler)
3324{
3325 saxreader *This = impl_from_ISAXXMLReader( iface );
3326 return saxreader_put_handler(This, SAXContentHandler, handler, FALSE);
3327}
3328
3329static HRESULT WINAPI isaxxmlreader_getDTDHandler(
3330 ISAXXMLReader* iface,
3331 ISAXDTDHandler **handler)
3332{
3333 saxreader *This = impl_from_ISAXXMLReader( iface );
3334 return saxreader_get_handler(This, SAXDTDHandler, FALSE, (void**)handler);
3335}
3336
3337static HRESULT WINAPI isaxxmlreader_putDTDHandler(
3338 ISAXXMLReader* iface,
3339 ISAXDTDHandler *handler)
3340{
3341 saxreader *This = impl_from_ISAXXMLReader( iface );
3342 return saxreader_put_handler(This, SAXDTDHandler, handler, FALSE);
3343}
3344
3345static HRESULT WINAPI isaxxmlreader_getErrorHandler(
3346 ISAXXMLReader* iface,
3347 ISAXErrorHandler **handler)
3348{
3349 saxreader *This = impl_from_ISAXXMLReader( iface );
3350 return saxreader_get_handler(This, SAXErrorHandler, FALSE, (void**)handler);
3351}
3352
3353static HRESULT WINAPI isaxxmlreader_putErrorHandler(ISAXXMLReader* iface, ISAXErrorHandler *handler)
3354{
3355 saxreader *This = impl_from_ISAXXMLReader( iface );
3356 return saxreader_put_handler(This, SAXErrorHandler, handler, FALSE);
3357}
3358
3359static HRESULT WINAPI isaxxmlreader_getBaseURL(
3360 ISAXXMLReader* iface,
3361 const WCHAR **base_url)
3362{
3363 saxreader *This = impl_from_ISAXXMLReader( iface );
3364
3365 FIXME("(%p)->(%p) stub\n", This, base_url);
3366 return E_NOTIMPL;
3367}
3368
3369static HRESULT WINAPI isaxxmlreader_putBaseURL(
3370 ISAXXMLReader* iface,
3371 const WCHAR *pBaseUrl)
3372{
3373 saxreader *This = impl_from_ISAXXMLReader( iface );
3374
3375 FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
3376 return E_NOTIMPL;
3377}
3378
3379static HRESULT WINAPI isaxxmlreader_getSecureBaseURL(
3380 ISAXXMLReader* iface,
3381 const WCHAR **pSecureBaseUrl)
3382{
3383 saxreader *This = impl_from_ISAXXMLReader( iface );
3384 FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
3385 return E_NOTIMPL;
3386}
3387
3388static HRESULT WINAPI isaxxmlreader_putSecureBaseURL(
3389 ISAXXMLReader* iface,
3390 const WCHAR *secureBaseUrl)
3391{
3392 saxreader *This = impl_from_ISAXXMLReader( iface );
3393
3394 FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
3395 return E_NOTIMPL;
3396}
3397
3398static HRESULT WINAPI isaxxmlreader_parse(
3399 ISAXXMLReader* iface,
3400 VARIANT varInput)
3401{
3402 saxreader *This = impl_from_ISAXXMLReader( iface );
3403 return internal_parse(This, varInput, FALSE);
3404}
3405
3406static HRESULT WINAPI isaxxmlreader_parseURL(
3407 ISAXXMLReader* iface,
3408 const WCHAR *url)
3409{
3410 saxreader *This = impl_from_ISAXXMLReader( iface );
3411 return internal_parseURL(This, url, FALSE);
3412}
3413
3414static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl =
3415{
3416 isaxxmlreader_QueryInterface,
3417 isaxxmlreader_AddRef,
3418 isaxxmlreader_Release,
3419 isaxxmlreader_getFeature,
3420 isaxxmlreader_putFeature,
3421 isaxxmlreader_getProperty,
3422 isaxxmlreader_putProperty,
3423 isaxxmlreader_getEntityResolver,
3424 isaxxmlreader_putEntityResolver,
3425 isaxxmlreader_getContentHandler,
3426 isaxxmlreader_putContentHandler,
3427 isaxxmlreader_getDTDHandler,
3428 isaxxmlreader_putDTDHandler,
3429 isaxxmlreader_getErrorHandler,
3430 isaxxmlreader_putErrorHandler,
3431 isaxxmlreader_getBaseURL,
3432 isaxxmlreader_putBaseURL,
3433 isaxxmlreader_getSecureBaseURL,
3434 isaxxmlreader_putSecureBaseURL,
3435 isaxxmlreader_parse,
3436 isaxxmlreader_parseURL
3437};
3438
3439static const tid_t saxreader_iface_tids[] = {
3441 0
3442};
3443static dispex_static_data_t saxreader_dispex = {
3444 NULL,
3446 NULL,
3447 saxreader_iface_tids
3448};
3449
3451{
3452 saxreader *reader;
3453
3454 TRACE("(%p)\n", ppObj);
3455
3456 reader = heap_alloc( sizeof (*reader) );
3457 if( !reader )
3458 return E_OUTOFMEMORY;
3459
3460 reader->IVBSAXXMLReader_iface.lpVtbl = &VBSAXXMLReaderVtbl;
3461 reader->ISAXXMLReader_iface.lpVtbl = &SAXXMLReaderVtbl;
3462 reader->ref = 1;
3463 memset(reader->saxhandlers, 0, sizeof(reader->saxhandlers));
3464 reader->isParsing = FALSE;
3465 reader->xmldecl_version = NULL;
3466 reader->pool.pool = NULL;
3467 reader->pool.index = 0;
3468 reader->pool.len = 0;
3469 reader->features = Namespaces | NamespacePrefixes;
3470 reader->version = version;
3471
3472 init_dispex(&reader->dispex, (IUnknown*)&reader->IVBSAXXMLReader_iface, &saxreader_dispex);
3473
3474 memset(&reader->sax, 0, sizeof(xmlSAXHandler));
3475 reader->sax.initialized = XML_SAX2_MAGIC;
3476 reader->sax.startDocument = libxmlStartDocument;
3477 reader->sax.endDocument = libxmlEndDocument;
3478 reader->sax.startElementNs = libxmlStartElementNS;
3479 reader->sax.endElementNs = libxmlEndElementNS;
3480 reader->sax.characters = libxmlCharacters;
3481 reader->sax.setDocumentLocator = libxmlSetDocumentLocator;
3482 reader->sax.comment = libxmlComment;
3483 reader->sax.error = libxmlFatalError;
3484 reader->sax.fatalError = libxmlFatalError;
3485 reader->sax.cdataBlock = libxml_cdatablock;
3486 reader->sax.resolveEntity = libxmlresolveentity;
3487
3488 *ppObj = &reader->IVBSAXXMLReader_iface;
3489
3490 TRACE("returning iface %p\n", *ppObj);
3491
3492 return S_OK;
3493}
3494
3495#else
3496
3498{
3499 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3500 "libxml2 support was not present at compile time.\n");
3501 return E_NOTIMPL;
3502}
3503
3504#endif
XMLPUBFUN int XMLCALL xmlSAX2GetColumnNumber(void *ctx)
Definition: SAX2.c:259
XMLPUBFUN const xmlChar *XMLCALL xmlSAX2GetSystemId(void *ctx)
Definition: SAX2.c:227
XMLPUBFUN xmlParserInputPtr XMLCALL xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
Definition: SAX2.c:489
XMLPUBFUN const xmlChar *XMLCALL xmlSAX2GetPublicId(void *ctx)
XMLPUBFUN int XMLCALL xmlSAX2GetLineNumber(void *ctx)
Definition: SAX2.c:243
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
HRESULT get_typeinfo(enum type_id tid, ITypeInfo **ret)
Definition: apps.c:124
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static const WCHAR nameW[]
Definition: main.c:46
#define index(s, c)
Definition: various.h:29
static const TCHAR empty_str[]
Definition: dialog.c:20
#define ARRAY_SIZE(A)
Definition: main.h:33
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
HRESULT detach_bsc(bsc_t *bsc)
Definition: bsc.c:331
HRESULT bind_url(IMoniker *mon, HRESULT(*onDataAvailable)(void *, char *, DWORD), void *obj, bsc_t **ret)
Definition: bsc.c:288
HRESULT create_moniker_from_url(LPCWSTR url, IMoniker **mon)
Definition: bsc.c:273
Definition: list.h:37
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define realloc
Definition: debug_ros.c:6
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
content
Definition: atl_ax.c:994
#define CP_UNIXCP
Definition: compat.h:79
OLECHAR * BSTR
Definition: compat.h:2293
short VARIANT_BOOL
Definition: compat.h:2290
#define MultiByteToWideChar
Definition: compat.h:110
@ VT_BSTR
Definition: compat.h:2303
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_BYREF
Definition: compat.h:2342
@ VT_ARRAY
Definition: compat.h:2341
@ VT_VARIANT
Definition: compat.h:2307
@ VT_I4
Definition: compat.h:2298
@ VT_EMPTY
Definition: compat.h:2295
@ VT_DISPATCH
Definition: compat.h:2304
@ VT_UI1
Definition: compat.h:2311
static const WCHAR version[]
Definition: asmname.c:66
static const WCHAR valueW[]
Definition: object.c:48
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7482
HRESULT SAXXMLReader_create(MSXML_VERSION version, LPVOID *ppObj)
Definition: saxreader.c:3497
HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
Definition: safearray.c:1033
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
HRESULT WINAPI SafeArrayGetLBound(SAFEARRAY *psa, UINT nDim, LONG *plLbound)
Definition: safearray.c:1066
UINT WINAPI SafeArrayGetElemsize(SAFEARRAY *psa)
Definition: safearray.c:1114
static const WCHAR typeW[]
Definition: name.c:51
static WCHAR xmlnsW[]
Definition: reader.c:228
xmlCharEncoding
Definition: encoding.h:56
@ XML_CHAR_ENCODING_UTF8
Definition: encoding.h:59
@ XML_CHAR_ENCODING_UTF16LE
Definition: encoding.h:60
@ XML_CHAR_ENCODING_NONE
Definition: encoding.h:58
XMLPUBFUN const char *XMLCALL xmlGetCharEncodingName(xmlCharEncoding enc)
Definition: encoding.c:1254
XMLPUBFUN xmlCharEncoding XMLCALL xmlDetectCharEncoding(const unsigned char *in, int len)
Definition: encoding.c:952
static unsigned char buff[32768]
Definition: fatten.c:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
#define local
Definition: zutil.h:30
PWCHAR pValue
FxCollectionEntry * cur
GLuint start
Definition: gl.h:1545
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
static const char * enc_name(unsigned char enc)
Definition: id3.c:433
tid_t
Definition: ieframe.h:311
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:919
#define c
Definition: ke_i.h:80
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define MESSAGE
Definition: options.h:86
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR url[]
Definition: encode.c:1432
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
const char * base_url
Definition: mimeole.c:1466
static HRESULT WINAPI isaxattributes_getTypeFromQName(ISAXAttributes *iface, const WCHAR *pQName, int nQName, const WCHAR **pType, int *nType)
Definition: saxreader.c:1605
static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes *iface)
Definition: saxreader.c:1486
static HRESULT WINAPI isaxattributes_getLength(ISAXAttributes *iface, int *length)
Definition: saxreader.c:1496
static ULONG WINAPI isaxattributes_Release(ISAXAttributes *iface)
Definition: saxreader.c:1491
static HRESULT WINAPI isaxattributes_getValue(ISAXAttributes *iface, int index, const WCHAR **value, int *nValue)
Definition: saxreader.c:1616
static HRESULT WINAPI isaxattributes_getValueFromQName(ISAXAttributes *iface, const WCHAR *pQName, int nQName, const WCHAR **pValue, int *nValue)
Definition: saxreader.c:1650
static HRESULT WINAPI isaxattributes_getValueFromName(ISAXAttributes *iface, const WCHAR *pUri, int nUri, const WCHAR *pLocalName, int nLocalName, const WCHAR **pValue, int *nValue)
Definition: saxreader.c:1637
static HRESULT WINAPI isaxattributes_getIndexFromName(ISAXAttributes *iface, const WCHAR *pUri, int cUriLength, const WCHAR *pLocalName, int cocalNameLength, int *index)
Definition: saxreader.c:1560
static HRESULT WINAPI isaxattributes_getQName(ISAXAttributes *iface, int index, const WCHAR **QName, int *QNameLength)
Definition: saxreader.c:1522
static HRESULT WINAPI isaxattributes_getType(ISAXAttributes *iface, int nIndex, const WCHAR **pType, int *pTypeLength)
Definition: saxreader.c:1582
static HRESULT WINAPI isaxattributes_QueryInterface(ISAXAttributes *iface, REFIID riid, void **ppvObject)
Definition: saxreader.c:1467
static HRESULT WINAPI isaxattributes_getName(ISAXAttributes *iface, int nIndex, const WCHAR **pUri, int *pUriLength, const WCHAR **pLocalName, int *pLocalNameSize, const WCHAR **pQName, int *pQNameLength)
Definition: saxreader.c:1546
static HRESULT WINAPI isaxattributes_getIndexFromQName(ISAXAttributes *iface, const WCHAR *pQName, int nQNameLength, int *index)
Definition: saxreader.c:1572
static HRESULT WINAPI isaxattributes_getLocalName(ISAXAttributes *iface, int nIndex, const WCHAR **pLocalName, int *pLocalNameLength)
Definition: saxreader.c:1512
static HRESULT WINAPI isaxattributes_getTypeFromName(ISAXAttributes *iface, const WCHAR *pUri, int nUri, const WCHAR *pLocalName, int nLocalName, const WCHAR **pType, int *nType)
Definition: saxreader.c:1592
static HRESULT WINAPI isaxattributes_getURI(ISAXAttributes *iface, int nIndex, const WCHAR **pUrl, int *pUriSize)
Definition: saxreader.c:1502
static char * dest
Definition: rtl.c:135
static LPOLESTR
Definition: stg_prop.c:27
static VARIANTARG static DISPID
Definition: ordinal.c:52
INTERNETFEATURELIST feature
Definition: misc.c:1719
const char * uri
Definition: sec_mgr.c:1588
static IBindStatusCallbackEx bsc
Definition: url.c:2150
#define min(a, b)
Definition: monoChain.cc:55
BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv)
Definition: dispex.c:1656
MSXML_VERSION
Definition: msxml_private.h:34
@ MSXML4
Definition: msxml_private.h:39
@ MSXML6
Definition: msxml_private.h:40
@ IVBSAXLocator_tid
Definition: msxml_private.h:78
@ IVBSAXXMLReader_tid
Definition: msxml_private.h:80
@ IVBSAXAttributes_tid
Definition: msxml_private.h:71
static HRESULT return_bstrn(const WCHAR *value, int len, BSTR *p)
static HRESULT return_bstr(const WCHAR *value, BSTR *p)
static mxattributes * impl_from_IVBSAXAttributes(IVBSAXAttributes *iface)
Definition: mxwriter.c:208
static mxattributes * impl_from_ISAXAttributes(ISAXAttributes *iface)
Definition: mxwriter.c:203
unsigned int UINT
Definition: ndis.h:50
UINT WINAPI SysStringByteLen(BSTR str)
Definition: oleaut.c:215
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_BSTRREF(A)
Definition: oleauto.h:227
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_ISBYREF(A)
Definition: oleauto.h:217
#define V_VARIANTREF(A)
Definition: oleauto.h:283
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_I4(A)
Definition: oleauto.h:247
const GUID IID_IDispatch
XMLPUBFUN int XMLCALL xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
XMLPUBFUN xmlParserCtxtPtr XMLCALL xmlCreateMemoryParserCtxt(const char *buffer, int size)
Definition: parser.c:14339
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define strcmpW(s1, s2)
Definition: unicode.h:38
#define strstrW(d, s)
Definition: unicode.h:32
#define strlenW(s)
Definition: unicode.h:28
#define strcpyW(d, s)
Definition: unicode.h:29
const WCHAR * str
DWORD LCID
Definition: nls.h:13
#define CP_UTF8
Definition: nls.h:20
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBFUN void XMLCALL xmlStopParser(xmlParserCtxtPtr ctxt)
Definition: parser.c:12583
XMLPUBFUN void XMLCALL xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
XMLPUBFUN int XMLCALL xmlParseDocument(xmlParserCtxtPtr ctxt)
Definition: parser.c:10697
#define XML_SAX2_MAGIC
Definition: parser.h:671
XMLPUBFUN xmlChar *XMLCALL xmlBuildQName(const xmlChar *ncname, const xmlChar *prefix, xmlChar *memory, int len)
struct _xmlDoc xmlDoc
Definition: tree.h:549
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
Definition: tree.h:551
Definition: match.c:390
Definition: bsc.c:46
struct list ns
Definition: writer.c:91
strval prefix
Definition: reader.c:259
strval qname
Definition: reader.c:261
struct list entry
Definition: reader.c:258
Definition: parser.c:49
Definition: list.h:15
Definition: tftpd.h:60
Definition: name.c:39
Definition: mxnamespace.c:45
Definition: reader.h:84
Definition: send.c:48
Definition: parse.h:23
#define max(a, b)
Definition: svc.c:63
#define LIST_ENTRY(type)
Definition: queue.h:175
#define str_len
Definition: treelist.c:89
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:94
int ret
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
_In_ DWORD nLength
Definition: wincon.h:473
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_POINTER
Definition: winerror.h:2365
@ XML_ERR_OK
Definition: xmlerror.h:100
static int sax
Definition: xmllint.c:193
static char * encoding
Definition: xmllint.c:155
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:67
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:160
unsigned char xmlChar
Definition: xmlstring.h:28