TESTING -- override pthreads to fix gstreamer v5
[wine/multimedia.git] / dlls / msxml3 / mxwriter.c
blob5778345c0ea38e82d2d7f5f0554db02a722afed8
1 /*
2 * MXWriter implementation
4 * Copyright 2011-2014 Nikolay Sivov for CodeWeavers
5 * Copyright 2011 Thomas Mullaly
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define COBJMACROS
23 #include "config.h"
25 #include <stdarg.h>
26 #ifdef HAVE_LIBXML2
27 # include <libxml/parser.h>
28 #endif
30 #include "windef.h"
31 #include "winbase.h"
32 #include "ole2.h"
34 #include "msxml6.h"
36 #include "wine/debug.h"
38 #include "msxml_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
42 static const WCHAR emptyW[] = {0};
43 static const WCHAR spaceW[] = {' '};
44 static const WCHAR quotW[] = {'\"'};
45 static const WCHAR closetagW[] = {'>','\r','\n'};
46 static const WCHAR crlfW[] = {'\r','\n'};
47 static const WCHAR entityW[] = {'<','!','E','N','T','I','T','Y',' '};
49 /* should be ordered as encoding names are sorted */
50 typedef enum
52 XmlEncoding_ISO_8859_1 = 0,
53 XmlEncoding_ISO_8859_13,
54 XmlEncoding_ISO_8859_15,
55 XmlEncoding_ISO_8859_2,
56 XmlEncoding_ISO_8859_3,
57 XmlEncoding_ISO_8859_4,
58 XmlEncoding_ISO_8859_5,
59 XmlEncoding_ISO_8859_7,
60 XmlEncoding_ISO_8859_9,
61 XmlEncoding_UTF16,
62 XmlEncoding_UTF8,
63 XmlEncoding_Unknown
64 } xml_encoding;
66 struct xml_encoding_data
68 const WCHAR *encoding;
69 xml_encoding enc;
70 UINT cp;
73 static const WCHAR iso_8859_1W[] = {'i','s','o','-','8','8','5','9','-','1',0};
74 static const WCHAR iso_8859_2W[] = {'i','s','o','-','8','8','5','9','-','2',0};
75 static const WCHAR iso_8859_3W[] = {'i','s','o','-','8','8','5','9','-','3',0};
76 static const WCHAR iso_8859_4W[] = {'i','s','o','-','8','8','5','9','-','4',0};
77 static const WCHAR iso_8859_5W[] = {'i','s','o','-','8','8','5','9','-','5',0};
78 static const WCHAR iso_8859_7W[] = {'i','s','o','-','8','8','5','9','-','7',0};
79 static const WCHAR iso_8859_9W[] = {'i','s','o','-','8','8','5','9','-','9',0};
80 static const WCHAR iso_8859_13W[] = {'i','s','o','-','8','8','5','9','-','1','3',0};
81 static const WCHAR iso_8859_15W[] = {'i','s','o','-','8','8','5','9','-','1','5',0};
82 static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
83 static const WCHAR utf8W[] = {'U','T','F','-','8',0};
85 static const struct xml_encoding_data xml_encoding_map[] = {
86 { iso_8859_1W, XmlEncoding_ISO_8859_1, 28591 },
87 { iso_8859_13W, XmlEncoding_ISO_8859_13, 28603 },
88 { iso_8859_15W, XmlEncoding_ISO_8859_15, 28605 },
89 { iso_8859_2W, XmlEncoding_ISO_8859_2, 28592 },
90 { iso_8859_3W, XmlEncoding_ISO_8859_3, 28593 },
91 { iso_8859_4W, XmlEncoding_ISO_8859_4, 28594 },
92 { iso_8859_5W, XmlEncoding_ISO_8859_5, 28595 },
93 { iso_8859_7W, XmlEncoding_ISO_8859_7, 28597 },
94 { iso_8859_9W, XmlEncoding_ISO_8859_9, 28599 },
95 { utf16W, XmlEncoding_UTF16, ~0 },
96 { utf8W, XmlEncoding_UTF8, CP_UTF8 }
99 typedef enum
101 OutputBuffer_Native = 0x001,
102 OutputBuffer_Encoded = 0x010,
103 OutputBuffer_Both = 0x100
104 } output_mode;
106 typedef enum
108 MXWriter_BOM = 0,
109 MXWriter_DisableEscaping,
110 MXWriter_Indent,
111 MXWriter_OmitXmlDecl,
112 MXWriter_Standalone,
113 MXWriter_LastProp
114 } mxwriter_prop;
116 typedef enum
118 EscapeValue,
119 EscapeText
120 } escape_mode;
122 typedef struct
124 char *data;
125 unsigned int allocated;
126 unsigned int written;
127 } encoded_buffer;
129 typedef struct
131 encoded_buffer utf16;
132 encoded_buffer encoded;
133 UINT code_page;
134 } output_buffer;
136 typedef struct
138 DispatchEx dispex;
139 IMXWriter IMXWriter_iface;
140 ISAXContentHandler ISAXContentHandler_iface;
141 ISAXLexicalHandler ISAXLexicalHandler_iface;
142 ISAXDeclHandler ISAXDeclHandler_iface;
143 ISAXDTDHandler ISAXDTDHandler_iface;
144 ISAXErrorHandler ISAXErrorHandler_iface;
145 IVBSAXDeclHandler IVBSAXDeclHandler_iface;
146 IVBSAXLexicalHandler IVBSAXLexicalHandler_iface;
147 IVBSAXContentHandler IVBSAXContentHandler_iface;
148 IVBSAXDTDHandler IVBSAXDTDHandler_iface;
149 IVBSAXErrorHandler IVBSAXErrorHandler_iface;
151 LONG ref;
152 MSXML_VERSION class_version;
154 VARIANT_BOOL props[MXWriter_LastProp];
155 BOOL prop_changed;
156 BOOL cdata;
158 BOOL text; /* last node was text node, so we shouldn't indent next node */
159 BOOL newline; /* newline was already added as a part of previous call */
160 UINT indent; /* indentation level for next node */
162 BSTR version;
164 BSTR encoding; /* exact property value */
165 xml_encoding xml_enc;
167 /* contains a pending (or not closed yet) element name or NULL if
168 we don't have to close */
169 BSTR element;
171 IStream *dest;
172 ULONG dest_written;
174 output_buffer *buffer;
175 } mxwriter;
177 typedef struct
179 BSTR qname;
180 BSTR local;
181 BSTR uri;
182 BSTR type;
183 BSTR value;
184 } mxattribute;
186 typedef struct
188 DispatchEx dispex;
189 IMXAttributes IMXAttributes_iface;
190 ISAXAttributes ISAXAttributes_iface;
191 IVBSAXAttributes IVBSAXAttributes_iface;
192 LONG ref;
194 MSXML_VERSION class_version;
196 mxattribute *attr;
197 int length;
198 int allocated;
199 } mxattributes;
201 static inline mxattributes *impl_from_IMXAttributes( IMXAttributes *iface )
203 return CONTAINING_RECORD(iface, mxattributes, IMXAttributes_iface);
206 static inline mxattributes *impl_from_ISAXAttributes( ISAXAttributes *iface )
208 return CONTAINING_RECORD(iface, mxattributes, ISAXAttributes_iface);
211 static inline mxattributes *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
213 return CONTAINING_RECORD(iface, mxattributes, IVBSAXAttributes_iface);
216 static HRESULT mxattributes_grow(mxattributes *This)
218 if (This->length < This->allocated) return S_OK;
220 This->allocated *= 2;
221 This->attr = heap_realloc(This->attr, This->allocated*sizeof(mxattribute));
223 return This->attr ? S_OK : E_OUTOFMEMORY;
226 static xml_encoding parse_encoding_name(const WCHAR *encoding)
228 int min, max, n, c;
230 min = 0;
231 max = sizeof(xml_encoding_map)/sizeof(struct xml_encoding_data) - 1;
233 while (min <= max)
235 n = (min+max)/2;
237 c = strcmpiW(xml_encoding_map[n].encoding, encoding);
238 if (!c)
239 return xml_encoding_map[n].enc;
241 if (c > 0)
242 max = n-1;
243 else
244 min = n+1;
247 return XmlEncoding_Unknown;
250 static HRESULT init_encoded_buffer(encoded_buffer *buffer)
252 const int initial_len = 0x2000;
253 buffer->data = heap_alloc(initial_len);
254 if (!buffer->data) return E_OUTOFMEMORY;
256 memset(buffer->data, 0, 4);
257 buffer->allocated = initial_len;
258 buffer->written = 0;
260 return S_OK;
263 static void free_encoded_buffer(encoded_buffer *buffer)
265 heap_free(buffer->data);
268 static HRESULT get_code_page(xml_encoding encoding, UINT *cp)
270 const struct xml_encoding_data *data;
272 if (encoding == XmlEncoding_Unknown)
274 FIXME("unsupported encoding %d\n", encoding);
275 return E_NOTIMPL;
278 data = &xml_encoding_map[encoding];
279 *cp = data->cp;
281 return S_OK;
284 static HRESULT alloc_output_buffer(xml_encoding encoding, output_buffer **buffer)
286 output_buffer *ret;
287 HRESULT hr;
289 ret = heap_alloc(sizeof(*ret));
290 if (!ret) return E_OUTOFMEMORY;
292 hr = get_code_page(encoding, &ret->code_page);
293 if (hr != S_OK) {
294 heap_free(ret);
295 return hr;
298 hr = init_encoded_buffer(&ret->utf16);
299 if (hr != S_OK) {
300 heap_free(ret);
301 return hr;
304 /* currently we always create a default output buffer that is UTF-16 only,
305 but it's possible to allocate with specific encoding too */
306 if (encoding != XmlEncoding_UTF16) {
307 hr = init_encoded_buffer(&ret->encoded);
308 if (hr != S_OK) {
309 free_encoded_buffer(&ret->utf16);
310 heap_free(ret);
311 return hr;
314 else
315 memset(&ret->encoded, 0, sizeof(ret->encoded));
317 *buffer = ret;
319 return S_OK;
322 static void free_output_buffer(output_buffer *buffer)
324 free_encoded_buffer(&buffer->encoded);
325 free_encoded_buffer(&buffer->utf16);
326 heap_free(buffer);
329 static void grow_buffer(encoded_buffer *buffer, int length)
331 /* grow if needed, plus 4 bytes to be sure null terminator will fit in */
332 if (buffer->allocated < buffer->written + length + 4)
334 int grown_size = max(2*buffer->allocated, buffer->allocated + length);
335 buffer->data = heap_realloc(buffer->data, grown_size);
336 buffer->allocated = grown_size;
340 static HRESULT write_output_buffer_mode(output_buffer *buffer, output_mode mode, const WCHAR *data, int len)
342 int length;
343 char *ptr;
345 if (mode & (OutputBuffer_Encoded | OutputBuffer_Both)) {
346 if (buffer->code_page != ~0)
348 length = WideCharToMultiByte(buffer->code_page, 0, data, len, NULL, 0, NULL, NULL);
349 grow_buffer(&buffer->encoded, length);
350 ptr = buffer->encoded.data + buffer->encoded.written;
351 length = WideCharToMultiByte(buffer->code_page, 0, data, len, ptr, length, NULL, NULL);
352 buffer->encoded.written += len == -1 ? length-1 : length;
356 if (mode & (OutputBuffer_Native | OutputBuffer_Both)) {
357 /* WCHAR data just copied */
358 length = len == -1 ? strlenW(data) : len;
359 if (length)
361 length *= sizeof(WCHAR);
363 grow_buffer(&buffer->utf16, length);
364 ptr = buffer->utf16.data + buffer->utf16.written;
366 memcpy(ptr, data, length);
367 buffer->utf16.written += length;
368 ptr += length;
369 /* null termination */
370 memset(ptr, 0, sizeof(WCHAR));
374 return S_OK;
377 static HRESULT write_output_buffer(output_buffer *buffer, const WCHAR *data, int len)
379 return write_output_buffer_mode(buffer, OutputBuffer_Both, data, len);
382 static HRESULT write_output_buffer_quoted(output_buffer *buffer, const WCHAR *data, int len)
384 write_output_buffer(buffer, quotW, 1);
385 write_output_buffer(buffer, data, len);
386 write_output_buffer(buffer, quotW, 1);
388 return S_OK;
391 /* frees buffer data, reallocates with a default lengths */
392 static void close_output_buffer(mxwriter *This)
394 heap_free(This->buffer->utf16.data);
395 heap_free(This->buffer->encoded.data);
396 init_encoded_buffer(&This->buffer->utf16);
397 init_encoded_buffer(&This->buffer->encoded);
398 get_code_page(This->xml_enc, &This->buffer->code_page);
401 /* Escapes special characters like:
402 '<' -> "&lt;"
403 '&' -> "&amp;"
404 '"' -> "&quot;"
405 '>' -> "&gt;"
407 On call 'len' contains a length of 'str' in chars or -1 if it's null terminated.
408 After a call it's updated with actual new length if it wasn't -1 initially.
410 static WCHAR *get_escaped_string(const WCHAR *str, escape_mode mode, int *len)
412 static const WCHAR ltW[] = {'&','l','t',';'};
413 static const WCHAR ampW[] = {'&','a','m','p',';'};
414 static const WCHAR equotW[] = {'&','q','u','o','t',';'};
415 static const WCHAR gtW[] = {'&','g','t',';'};
417 const int default_alloc = 100;
418 const int grow_thresh = 10;
419 int p = *len, conv_len;
420 WCHAR *ptr, *ret;
422 /* default buffer size to something if length is unknown */
423 conv_len = *len == -1 ? default_alloc : max(2**len, default_alloc);
424 ptr = ret = heap_alloc(conv_len*sizeof(WCHAR));
426 while (*str && p)
428 if (ptr - ret > conv_len - grow_thresh)
430 int written = ptr - ret;
431 conv_len *= 2;
432 ptr = ret = heap_realloc(ret, conv_len*sizeof(WCHAR));
433 ptr += written;
436 switch (*str)
438 case '<':
439 memcpy(ptr, ltW, sizeof(ltW));
440 ptr += sizeof(ltW)/sizeof(WCHAR);
441 break;
442 case '&':
443 memcpy(ptr, ampW, sizeof(ampW));
444 ptr += sizeof(ampW)/sizeof(WCHAR);
445 break;
446 case '>':
447 memcpy(ptr, gtW, sizeof(gtW));
448 ptr += sizeof(gtW)/sizeof(WCHAR);
449 break;
450 case '"':
451 if (mode == EscapeValue)
453 memcpy(ptr, equotW, sizeof(equotW));
454 ptr += sizeof(equotW)/sizeof(WCHAR);
455 break;
457 /* fallthrough for text mode */
458 default:
459 *ptr++ = *str;
460 break;
463 str++;
464 if (*len != -1) p--;
467 if (*len != -1) *len = ptr-ret;
468 *++ptr = 0;
470 return ret;
473 static void write_prolog_buffer(mxwriter *This)
475 static const WCHAR versionW[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','='};
476 static const WCHAR encodingW[] = {' ','e','n','c','o','d','i','n','g','=','\"'};
477 static const WCHAR standaloneW[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
478 static const WCHAR yesW[] = {'y','e','s','\"','?','>'};
479 static const WCHAR noW[] = {'n','o','\"','?','>'};
481 /* version */
482 write_output_buffer(This->buffer, versionW, sizeof(versionW)/sizeof(WCHAR));
483 write_output_buffer_quoted(This->buffer, This->version, -1);
485 /* encoding */
486 write_output_buffer(This->buffer, encodingW, sizeof(encodingW)/sizeof(WCHAR));
488 /* always write UTF-16 to WCHAR buffer */
489 write_output_buffer_mode(This->buffer, OutputBuffer_Native, utf16W, sizeof(utf16W)/sizeof(WCHAR) - 1);
490 write_output_buffer_mode(This->buffer, OutputBuffer_Encoded, This->encoding, -1);
491 write_output_buffer(This->buffer, quotW, 1);
493 /* standalone */
494 write_output_buffer(This->buffer, standaloneW, sizeof(standaloneW)/sizeof(WCHAR));
495 if (This->props[MXWriter_Standalone] == VARIANT_TRUE)
496 write_output_buffer(This->buffer, yesW, sizeof(yesW)/sizeof(WCHAR));
497 else
498 write_output_buffer(This->buffer, noW, sizeof(noW)/sizeof(WCHAR));
500 write_output_buffer(This->buffer, crlfW, sizeof(crlfW)/sizeof(WCHAR));
501 This->newline = TRUE;
504 /* Attempts to the write data from the mxwriter's buffer to
505 * the destination stream (if there is one).
507 static HRESULT write_data_to_stream(mxwriter *This)
509 encoded_buffer *buffer;
510 ULONG written = 0;
511 HRESULT hr;
513 if (!This->dest)
514 return S_OK;
516 if (This->xml_enc != XmlEncoding_UTF16)
517 buffer = &This->buffer->encoded;
518 else
519 buffer = &This->buffer->utf16;
521 if (This->dest_written > buffer->written) {
522 ERR("Failed sanity check! Not sure what to do... (%d > %d)\n", This->dest_written, buffer->written);
523 return E_FAIL;
524 } else if (This->dest_written == buffer->written && This->xml_enc != XmlEncoding_UTF8)
525 /* Windows seems to make an empty write call when the encoding is UTF-8 and
526 * all the data has been written to the stream. It doesn't seem make this call
527 * for any other encodings.
529 return S_OK;
531 /* Write the current content from the output buffer into 'dest'.
532 * TODO: Check what Windows does if the IStream doesn't write all of
533 * the data we give it at once.
535 hr = IStream_Write(This->dest, buffer->data+This->dest_written,
536 buffer->written-This->dest_written, &written);
537 if (FAILED(hr)) {
538 WARN("Failed to write data to IStream (0x%08x)\n", hr);
539 return hr;
542 This->dest_written += written;
543 return hr;
546 /* Newly added element start tag left unclosed cause for empty elements
547 we have to close it differently. */
548 static void close_element_starttag(const mxwriter *This)
550 static const WCHAR gtW[] = {'>'};
551 if (!This->element) return;
552 write_output_buffer(This->buffer, gtW, 1);
555 static void write_node_indent(mxwriter *This)
557 static const WCHAR tabW[] = {'\t'};
558 int indent = This->indent;
560 if (!This->props[MXWriter_Indent] || This->text)
562 This->text = FALSE;
563 return;
566 /* This is to workaround PI output logic that always puts newline chars,
567 document prolog PI does that too. */
568 if (!This->newline)
569 write_output_buffer(This->buffer, crlfW, sizeof(crlfW)/sizeof(WCHAR));
570 while (indent--)
571 write_output_buffer(This->buffer, tabW, 1);
573 This->newline = FALSE;
574 This->text = FALSE;
577 static inline void writer_inc_indent(mxwriter *This)
579 This->indent++;
582 static inline void writer_dec_indent(mxwriter *This)
584 if (This->indent) This->indent--;
585 /* depth is decreased only when element is closed, meaning it's not a text node
586 at this point */
587 This->text = FALSE;
590 static void set_element_name(mxwriter *This, const WCHAR *name, int len)
592 SysFreeString(This->element);
593 if (name)
594 This->element = len != -1 ? SysAllocStringLen(name, len) : SysAllocString(name);
595 else
596 This->element = NULL;
599 static inline HRESULT flush_output_buffer(mxwriter *This)
601 close_element_starttag(This);
602 set_element_name(This, NULL, 0);
603 This->cdata = FALSE;
604 return write_data_to_stream(This);
607 /* Resets the mxwriter's output buffer by closing it, then creating a new
608 * output buffer using the given encoding.
610 static inline void reset_output_buffer(mxwriter *This)
612 close_output_buffer(This);
613 This->dest_written = 0;
616 static HRESULT writer_set_property(mxwriter *writer, mxwriter_prop property, VARIANT_BOOL value)
618 writer->props[property] = value;
619 writer->prop_changed = TRUE;
620 return S_OK;
623 static HRESULT writer_get_property(const mxwriter *writer, mxwriter_prop property, VARIANT_BOOL *value)
625 if (!value) return E_POINTER;
626 *value = writer->props[property];
627 return S_OK;
630 static inline mxwriter *impl_from_IMXWriter(IMXWriter *iface)
632 return CONTAINING_RECORD(iface, mxwriter, IMXWriter_iface);
635 static inline mxwriter *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
637 return CONTAINING_RECORD(iface, mxwriter, ISAXContentHandler_iface);
640 static inline mxwriter *impl_from_IVBSAXContentHandler(IVBSAXContentHandler *iface)
642 return CONTAINING_RECORD(iface, mxwriter, IVBSAXContentHandler_iface);
645 static inline mxwriter *impl_from_ISAXLexicalHandler(ISAXLexicalHandler *iface)
647 return CONTAINING_RECORD(iface, mxwriter, ISAXLexicalHandler_iface);
650 static inline mxwriter *impl_from_IVBSAXLexicalHandler(IVBSAXLexicalHandler *iface)
652 return CONTAINING_RECORD(iface, mxwriter, IVBSAXLexicalHandler_iface);
655 static inline mxwriter *impl_from_ISAXDeclHandler(ISAXDeclHandler *iface)
657 return CONTAINING_RECORD(iface, mxwriter, ISAXDeclHandler_iface);
660 static inline mxwriter *impl_from_IVBSAXDeclHandler(IVBSAXDeclHandler *iface)
662 return CONTAINING_RECORD(iface, mxwriter, IVBSAXDeclHandler_iface);
665 static inline mxwriter *impl_from_ISAXDTDHandler(ISAXDTDHandler *iface)
667 return CONTAINING_RECORD(iface, mxwriter, ISAXDTDHandler_iface);
670 static inline mxwriter *impl_from_IVBSAXDTDHandler(IVBSAXDTDHandler *iface)
672 return CONTAINING_RECORD(iface, mxwriter, IVBSAXDTDHandler_iface);
675 static inline mxwriter *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
677 return CONTAINING_RECORD(iface, mxwriter, ISAXErrorHandler_iface);
680 static inline mxwriter *impl_from_IVBSAXErrorHandler(IVBSAXErrorHandler *iface)
682 return CONTAINING_RECORD(iface, mxwriter, IVBSAXErrorHandler_iface);
685 static HRESULT WINAPI mxwriter_QueryInterface(IMXWriter *iface, REFIID riid, void **obj)
687 mxwriter *This = impl_from_IMXWriter( iface );
689 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
691 *obj = NULL;
693 if ( IsEqualGUID( riid, &IID_IMXWriter ) ||
694 IsEqualGUID( riid, &IID_IDispatch ) ||
695 IsEqualGUID( riid, &IID_IUnknown ) )
697 *obj = &This->IMXWriter_iface;
699 else if ( IsEqualGUID( riid, &IID_ISAXContentHandler ) )
701 *obj = &This->ISAXContentHandler_iface;
703 else if ( IsEqualGUID( riid, &IID_ISAXLexicalHandler ) )
705 *obj = &This->ISAXLexicalHandler_iface;
707 else if ( IsEqualGUID( riid, &IID_ISAXDeclHandler ) )
709 *obj = &This->ISAXDeclHandler_iface;
711 else if ( IsEqualGUID( riid, &IID_ISAXDTDHandler ) )
713 *obj = &This->ISAXDTDHandler_iface;
715 else if ( IsEqualGUID( riid, &IID_ISAXErrorHandler ) )
717 *obj = &This->ISAXErrorHandler_iface;
719 else if ( IsEqualGUID( riid, &IID_IVBSAXDeclHandler ) )
721 *obj = &This->IVBSAXDeclHandler_iface;
723 else if ( IsEqualGUID( riid, &IID_IVBSAXLexicalHandler ) )
725 *obj = &This->IVBSAXLexicalHandler_iface;
727 else if ( IsEqualGUID( riid, &IID_IVBSAXContentHandler ) )
729 *obj = &This->IVBSAXContentHandler_iface;
731 else if ( IsEqualGUID( riid, &IID_IVBSAXDTDHandler ) )
733 *obj = &This->IVBSAXDTDHandler_iface;
735 else if ( IsEqualGUID( riid, &IID_IVBSAXErrorHandler ) )
737 *obj = &This->IVBSAXErrorHandler_iface;
739 else if (dispex_query_interface(&This->dispex, riid, obj))
741 return *obj ? S_OK : E_NOINTERFACE;
743 else
745 ERR("interface %s not implemented\n", debugstr_guid(riid));
746 *obj = NULL;
747 return E_NOINTERFACE;
750 IMXWriter_AddRef(iface);
751 return S_OK;
754 static ULONG WINAPI mxwriter_AddRef(IMXWriter *iface)
756 mxwriter *This = impl_from_IMXWriter( iface );
757 LONG ref = InterlockedIncrement(&This->ref);
759 TRACE("(%p)->(%d)\n", This, ref);
761 return ref;
764 static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
766 mxwriter *This = impl_from_IMXWriter( iface );
767 ULONG ref = InterlockedDecrement(&This->ref);
769 TRACE("(%p)->(%d)\n", This, ref);
771 if(!ref)
773 /* Windows flushes the buffer when the interface is destroyed. */
774 flush_output_buffer(This);
775 free_output_buffer(This->buffer);
777 if (This->dest) IStream_Release(This->dest);
778 SysFreeString(This->version);
779 SysFreeString(This->encoding);
781 SysFreeString(This->element);
782 heap_free(This);
785 return ref;
788 static HRESULT WINAPI mxwriter_GetTypeInfoCount(IMXWriter *iface, UINT* pctinfo)
790 mxwriter *This = impl_from_IMXWriter( iface );
791 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
794 static HRESULT WINAPI mxwriter_GetTypeInfo(
795 IMXWriter *iface,
796 UINT iTInfo, LCID lcid,
797 ITypeInfo** ppTInfo )
799 mxwriter *This = impl_from_IMXWriter( iface );
800 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
801 iTInfo, lcid, ppTInfo);
804 static HRESULT WINAPI mxwriter_GetIDsOfNames(
805 IMXWriter *iface,
806 REFIID riid, LPOLESTR* rgszNames,
807 UINT cNames, LCID lcid, DISPID* rgDispId )
809 mxwriter *This = impl_from_IMXWriter( iface );
810 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
811 riid, rgszNames, cNames, lcid, rgDispId);
814 static HRESULT WINAPI mxwriter_Invoke(
815 IMXWriter *iface,
816 DISPID dispIdMember, REFIID riid, LCID lcid,
817 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
818 EXCEPINFO* pExcepInfo, UINT* puArgErr )
820 mxwriter *This = impl_from_IMXWriter( iface );
821 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
822 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
825 static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
827 mxwriter *This = impl_from_IMXWriter( iface );
828 HRESULT hr;
830 TRACE("(%p)->(%s)\n", This, debugstr_variant(&dest));
832 hr = flush_output_buffer(This);
833 if (FAILED(hr))
834 return hr;
836 switch (V_VT(&dest))
838 case VT_EMPTY:
840 if (This->dest) IStream_Release(This->dest);
841 This->dest = NULL;
842 reset_output_buffer(This);
843 break;
845 case VT_UNKNOWN:
847 IStream *stream;
849 hr = IUnknown_QueryInterface(V_UNKNOWN(&dest), &IID_IStream, (void**)&stream);
850 if (hr == S_OK)
852 /* Recreate the output buffer to make sure it's using the correct encoding. */
853 reset_output_buffer(This);
855 if (This->dest) IStream_Release(This->dest);
856 This->dest = stream;
857 break;
860 FIXME("unhandled interface type for VT_UNKNOWN destination\n");
861 return E_NOTIMPL;
863 default:
864 FIXME("unhandled destination type %s\n", debugstr_variant(&dest));
865 return E_NOTIMPL;
868 return S_OK;
871 static HRESULT WINAPI mxwriter_get_output(IMXWriter *iface, VARIANT *dest)
873 mxwriter *This = impl_from_IMXWriter( iface );
875 TRACE("(%p)->(%p)\n", This, dest);
877 if (!dest) return E_POINTER;
879 if (!This->dest)
881 HRESULT hr = flush_output_buffer(This);
882 if (FAILED(hr))
883 return hr;
885 V_VT(dest) = VT_BSTR;
886 V_BSTR(dest) = SysAllocString((WCHAR*)This->buffer->utf16.data);
888 return S_OK;
891 /* we only support IStream output so far */
892 V_VT(dest) = VT_UNKNOWN;
893 V_UNKNOWN(dest) = (IUnknown*)This->dest;
894 IStream_AddRef(This->dest);
896 return S_OK;
899 static HRESULT WINAPI mxwriter_put_encoding(IMXWriter *iface, BSTR encoding)
901 mxwriter *This = impl_from_IMXWriter( iface );
902 xml_encoding enc;
903 HRESULT hr;
905 TRACE("(%p)->(%s)\n", This, debugstr_w(encoding));
907 enc = parse_encoding_name(encoding);
908 if (enc == XmlEncoding_Unknown)
910 FIXME("unsupported encoding %s\n", debugstr_w(encoding));
911 return E_INVALIDARG;
914 hr = flush_output_buffer(This);
915 if (FAILED(hr))
916 return hr;
918 SysReAllocString(&This->encoding, encoding);
919 This->xml_enc = enc;
921 TRACE("got encoding %d\n", This->xml_enc);
922 reset_output_buffer(This);
923 return S_OK;
926 static HRESULT WINAPI mxwriter_get_encoding(IMXWriter *iface, BSTR *encoding)
928 mxwriter *This = impl_from_IMXWriter( iface );
930 TRACE("(%p)->(%p)\n", This, encoding);
932 if (!encoding) return E_POINTER;
934 *encoding = SysAllocString(This->encoding);
935 if (!*encoding) return E_OUTOFMEMORY;
937 return S_OK;
940 static HRESULT WINAPI mxwriter_put_byteOrderMark(IMXWriter *iface, VARIANT_BOOL value)
942 mxwriter *This = impl_from_IMXWriter( iface );
944 TRACE("(%p)->(%d)\n", This, value);
945 return writer_set_property(This, MXWriter_BOM, value);
948 static HRESULT WINAPI mxwriter_get_byteOrderMark(IMXWriter *iface, VARIANT_BOOL *value)
950 mxwriter *This = impl_from_IMXWriter( iface );
952 TRACE("(%p)->(%p)\n", This, value);
953 return writer_get_property(This, MXWriter_BOM, value);
956 static HRESULT WINAPI mxwriter_put_indent(IMXWriter *iface, VARIANT_BOOL value)
958 mxwriter *This = impl_from_IMXWriter( iface );
960 TRACE("(%p)->(%d)\n", This, value);
961 return writer_set_property(This, MXWriter_Indent, value);
964 static HRESULT WINAPI mxwriter_get_indent(IMXWriter *iface, VARIANT_BOOL *value)
966 mxwriter *This = impl_from_IMXWriter( iface );
968 TRACE("(%p)->(%p)\n", This, value);
969 return writer_get_property(This, MXWriter_Indent, value);
972 static HRESULT WINAPI mxwriter_put_standalone(IMXWriter *iface, VARIANT_BOOL value)
974 mxwriter *This = impl_from_IMXWriter( iface );
976 TRACE("(%p)->(%d)\n", This, value);
977 return writer_set_property(This, MXWriter_Standalone, value);
980 static HRESULT WINAPI mxwriter_get_standalone(IMXWriter *iface, VARIANT_BOOL *value)
982 mxwriter *This = impl_from_IMXWriter( iface );
984 TRACE("(%p)->(%p)\n", This, value);
985 return writer_get_property(This, MXWriter_Standalone, value);
988 static HRESULT WINAPI mxwriter_put_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL value)
990 mxwriter *This = impl_from_IMXWriter( iface );
992 TRACE("(%p)->(%d)\n", This, value);
993 return writer_set_property(This, MXWriter_OmitXmlDecl, value);
996 static HRESULT WINAPI mxwriter_get_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL *value)
998 mxwriter *This = impl_from_IMXWriter( iface );
1000 TRACE("(%p)->(%p)\n", This, value);
1001 return writer_get_property(This, MXWriter_OmitXmlDecl, value);
1004 static HRESULT WINAPI mxwriter_put_version(IMXWriter *iface, BSTR version)
1006 mxwriter *This = impl_from_IMXWriter( iface );
1008 TRACE("(%p)->(%s)\n", This, debugstr_w(version));
1010 if (!version) return E_INVALIDARG;
1012 SysFreeString(This->version);
1013 This->version = SysAllocString(version);
1015 return S_OK;
1018 static HRESULT WINAPI mxwriter_get_version(IMXWriter *iface, BSTR *version)
1020 mxwriter *This = impl_from_IMXWriter( iface );
1022 TRACE("(%p)->(%p)\n", This, version);
1024 if (!version) return E_POINTER;
1026 return return_bstr(This->version, version);
1029 static HRESULT WINAPI mxwriter_put_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL value)
1031 mxwriter *This = impl_from_IMXWriter( iface );
1033 TRACE("(%p)->(%d)\n", This, value);
1034 return writer_set_property(This, MXWriter_DisableEscaping, value);
1037 static HRESULT WINAPI mxwriter_get_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL *value)
1039 mxwriter *This = impl_from_IMXWriter( iface );
1041 TRACE("(%p)->(%p)\n", This, value);
1042 return writer_get_property(This, MXWriter_DisableEscaping, value);
1045 static HRESULT WINAPI mxwriter_flush(IMXWriter *iface)
1047 mxwriter *This = impl_from_IMXWriter( iface );
1048 TRACE("(%p)\n", This);
1049 return flush_output_buffer(This);
1052 static const struct IMXWriterVtbl MXWriterVtbl =
1054 mxwriter_QueryInterface,
1055 mxwriter_AddRef,
1056 mxwriter_Release,
1057 mxwriter_GetTypeInfoCount,
1058 mxwriter_GetTypeInfo,
1059 mxwriter_GetIDsOfNames,
1060 mxwriter_Invoke,
1061 mxwriter_put_output,
1062 mxwriter_get_output,
1063 mxwriter_put_encoding,
1064 mxwriter_get_encoding,
1065 mxwriter_put_byteOrderMark,
1066 mxwriter_get_byteOrderMark,
1067 mxwriter_put_indent,
1068 mxwriter_get_indent,
1069 mxwriter_put_standalone,
1070 mxwriter_get_standalone,
1071 mxwriter_put_omitXMLDeclaration,
1072 mxwriter_get_omitXMLDeclaration,
1073 mxwriter_put_version,
1074 mxwriter_get_version,
1075 mxwriter_put_disableOutputEscaping,
1076 mxwriter_get_disableOutputEscaping,
1077 mxwriter_flush
1080 /*** ISAXContentHandler ***/
1081 static HRESULT WINAPI SAXContentHandler_QueryInterface(
1082 ISAXContentHandler *iface,
1083 REFIID riid,
1084 void **obj)
1086 mxwriter *This = impl_from_ISAXContentHandler( iface );
1087 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1090 static ULONG WINAPI SAXContentHandler_AddRef(ISAXContentHandler *iface)
1092 mxwriter *This = impl_from_ISAXContentHandler( iface );
1093 return IMXWriter_AddRef(&This->IMXWriter_iface);
1096 static ULONG WINAPI SAXContentHandler_Release(ISAXContentHandler *iface)
1098 mxwriter *This = impl_from_ISAXContentHandler( iface );
1099 return IMXWriter_Release(&This->IMXWriter_iface);
1102 static HRESULT WINAPI SAXContentHandler_putDocumentLocator(
1103 ISAXContentHandler *iface,
1104 ISAXLocator *locator)
1106 mxwriter *This = impl_from_ISAXContentHandler( iface );
1107 FIXME("(%p)->(%p)\n", This, locator);
1108 return E_NOTIMPL;
1111 static HRESULT WINAPI SAXContentHandler_startDocument(ISAXContentHandler *iface)
1113 mxwriter *This = impl_from_ISAXContentHandler( iface );
1115 TRACE("(%p)\n", This);
1117 /* If properties have been changed since the last "endDocument" call
1118 * we need to reset the output buffer. If we don't the output buffer
1119 * could end up with multiple XML documents in it, plus this seems to
1120 * be how Windows works.
1122 if (This->prop_changed) {
1123 reset_output_buffer(This);
1124 This->prop_changed = FALSE;
1127 if (This->props[MXWriter_OmitXmlDecl] == VARIANT_TRUE) return S_OK;
1129 write_prolog_buffer(This);
1131 if (This->dest && This->xml_enc == XmlEncoding_UTF16) {
1132 static const char utf16BOM[] = {0xff,0xfe};
1134 if (This->props[MXWriter_BOM] == VARIANT_TRUE)
1135 /* Windows passes a NULL pointer as the pcbWritten parameter and
1136 * ignores any error codes returned from this Write call.
1138 IStream_Write(This->dest, utf16BOM, sizeof(utf16BOM), NULL);
1141 return S_OK;
1144 static HRESULT WINAPI SAXContentHandler_endDocument(ISAXContentHandler *iface)
1146 mxwriter *This = impl_from_ISAXContentHandler( iface );
1147 TRACE("(%p)\n", This);
1148 This->prop_changed = FALSE;
1149 return flush_output_buffer(This);
1152 static HRESULT WINAPI SAXContentHandler_startPrefixMapping(
1153 ISAXContentHandler *iface,
1154 const WCHAR *prefix,
1155 int nprefix,
1156 const WCHAR *uri,
1157 int nuri)
1159 mxwriter *This = impl_from_ISAXContentHandler( iface );
1160 TRACE("(%p)->(%s %s)\n", This, debugstr_wn(prefix, nprefix), debugstr_wn(uri, nuri));
1161 return S_OK;
1164 static HRESULT WINAPI SAXContentHandler_endPrefixMapping(
1165 ISAXContentHandler *iface,
1166 const WCHAR *prefix,
1167 int nprefix)
1169 mxwriter *This = impl_from_ISAXContentHandler( iface );
1170 TRACE("(%p)->(%s)\n", This, debugstr_wn(prefix, nprefix));
1171 return S_OK;
1174 static void mxwriter_write_attribute(mxwriter *writer, const WCHAR *qname, int qname_len,
1175 const WCHAR *value, int value_len, BOOL escape)
1177 static const WCHAR eqW[] = {'='};
1179 /* space separator in front of every attribute */
1180 write_output_buffer(writer->buffer, spaceW, 1);
1181 write_output_buffer(writer->buffer, qname, qname_len);
1182 write_output_buffer(writer->buffer, eqW, 1);
1184 if (escape)
1186 WCHAR *escaped = get_escaped_string(value, EscapeValue, &value_len);
1187 write_output_buffer_quoted(writer->buffer, escaped, value_len);
1188 heap_free(escaped);
1190 else
1191 write_output_buffer_quoted(writer->buffer, value, value_len);
1194 static void mxwriter_write_starttag(mxwriter *writer, const WCHAR *qname, int len)
1196 static const WCHAR ltW[] = {'<'};
1198 close_element_starttag(writer);
1199 set_element_name(writer, qname ? qname : emptyW, qname ? len : 0);
1201 write_node_indent(writer);
1203 write_output_buffer(writer->buffer, ltW, 1);
1204 write_output_buffer(writer->buffer, qname ? qname : emptyW, qname ? len : 0);
1205 writer_inc_indent(writer);
1208 static HRESULT WINAPI SAXContentHandler_startElement(
1209 ISAXContentHandler *iface,
1210 const WCHAR *namespaceUri,
1211 int nnamespaceUri,
1212 const WCHAR *local_name,
1213 int nlocal_name,
1214 const WCHAR *QName,
1215 int nQName,
1216 ISAXAttributes *attr)
1218 mxwriter *This = impl_from_ISAXContentHandler( iface );
1220 TRACE("(%p)->(%s %s %s %p)\n", This, debugstr_wn(namespaceUri, nnamespaceUri),
1221 debugstr_wn(local_name, nlocal_name), debugstr_wn(QName, nQName), attr);
1223 if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1224 (nQName == -1 && This->class_version == MSXML6))
1225 return E_INVALIDARG;
1227 mxwriter_write_starttag(This, QName, nQName);
1229 if (attr)
1231 int length, i, escape;
1232 HRESULT hr;
1234 hr = ISAXAttributes_getLength(attr, &length);
1235 if (FAILED(hr)) return hr;
1237 escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
1238 (This->class_version == MSXML4 || This->class_version == MSXML6);
1240 for (i = 0; i < length; i++)
1242 int qname_len = 0, value_len = 0;
1243 const WCHAR *qname, *value;
1245 hr = ISAXAttributes_getQName(attr, i, &qname, &qname_len);
1246 if (FAILED(hr)) return hr;
1248 hr = ISAXAttributes_getValue(attr, i, &value, &value_len);
1249 if (FAILED(hr)) return hr;
1251 mxwriter_write_attribute(This, qname, qname_len, value, value_len, escape);
1255 return S_OK;
1258 static HRESULT WINAPI SAXContentHandler_endElement(
1259 ISAXContentHandler *iface,
1260 const WCHAR *namespaceUri,
1261 int nnamespaceUri,
1262 const WCHAR * local_name,
1263 int nlocal_name,
1264 const WCHAR *QName,
1265 int nQName)
1267 mxwriter *This = impl_from_ISAXContentHandler( iface );
1269 TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(namespaceUri, nnamespaceUri), nnamespaceUri,
1270 debugstr_wn(local_name, nlocal_name), nlocal_name, debugstr_wn(QName, nQName), nQName);
1272 if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1273 (nQName == -1 && This->class_version == MSXML6))
1274 return E_INVALIDARG;
1276 writer_dec_indent(This);
1278 if (This->element)
1280 static const WCHAR closeW[] = {'/','>'};
1281 write_output_buffer(This->buffer, closeW, 2);
1283 else
1285 static const WCHAR closetagW[] = {'<','/'};
1286 static const WCHAR gtW[] = {'>'};
1288 write_node_indent(This);
1289 write_output_buffer(This->buffer, closetagW, 2);
1290 write_output_buffer(This->buffer, QName, nQName);
1291 write_output_buffer(This->buffer, gtW, 1);
1294 set_element_name(This, NULL, 0);
1296 return S_OK;
1299 static HRESULT WINAPI SAXContentHandler_characters(
1300 ISAXContentHandler *iface,
1301 const WCHAR *chars,
1302 int nchars)
1304 mxwriter *This = impl_from_ISAXContentHandler( iface );
1306 TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1308 if (!chars) return E_INVALIDARG;
1310 close_element_starttag(This);
1311 set_element_name(This, NULL, 0);
1313 if (!This->cdata)
1314 This->text = TRUE;
1316 if (nchars)
1318 if (This->cdata || This->props[MXWriter_DisableEscaping] == VARIANT_TRUE)
1319 write_output_buffer(This->buffer, chars, nchars);
1320 else
1322 int len = nchars;
1323 WCHAR *escaped;
1325 escaped = get_escaped_string(chars, EscapeText, &len);
1326 write_output_buffer(This->buffer, escaped, len);
1327 heap_free(escaped);
1331 return S_OK;
1334 static HRESULT WINAPI SAXContentHandler_ignorableWhitespace(
1335 ISAXContentHandler *iface,
1336 const WCHAR *chars,
1337 int nchars)
1339 mxwriter *This = impl_from_ISAXContentHandler( iface );
1341 TRACE("(%p)->(%s)\n", This, debugstr_wn(chars, nchars));
1343 if (!chars) return E_INVALIDARG;
1345 write_output_buffer(This->buffer, chars, nchars);
1347 return S_OK;
1350 static HRESULT WINAPI SAXContentHandler_processingInstruction(
1351 ISAXContentHandler *iface,
1352 const WCHAR *target,
1353 int ntarget,
1354 const WCHAR *data,
1355 int ndata)
1357 mxwriter *This = impl_from_ISAXContentHandler( iface );
1358 static const WCHAR openpiW[] = {'<','?'};
1359 static const WCHAR closepiW[] = {'?','>','\r','\n'};
1361 TRACE("(%p)->(%s %s)\n", This, debugstr_wn(target, ntarget), debugstr_wn(data, ndata));
1363 if (!target) return E_INVALIDARG;
1365 write_node_indent(This);
1366 write_output_buffer(This->buffer, openpiW, sizeof(openpiW)/sizeof(WCHAR));
1368 if (*target)
1369 write_output_buffer(This->buffer, target, ntarget);
1371 if (data && *data && ndata)
1373 write_output_buffer(This->buffer, spaceW, 1);
1374 write_output_buffer(This->buffer, data, ndata);
1377 write_output_buffer(This->buffer, closepiW, sizeof(closepiW)/sizeof(WCHAR));
1378 This->newline = TRUE;
1380 return S_OK;
1383 static HRESULT WINAPI SAXContentHandler_skippedEntity(
1384 ISAXContentHandler *iface,
1385 const WCHAR *name,
1386 int nname)
1388 mxwriter *This = impl_from_ISAXContentHandler( iface );
1389 FIXME("(%p)->(%s)\n", This, debugstr_wn(name, nname));
1390 return E_NOTIMPL;
1393 static const struct ISAXContentHandlerVtbl SAXContentHandlerVtbl =
1395 SAXContentHandler_QueryInterface,
1396 SAXContentHandler_AddRef,
1397 SAXContentHandler_Release,
1398 SAXContentHandler_putDocumentLocator,
1399 SAXContentHandler_startDocument,
1400 SAXContentHandler_endDocument,
1401 SAXContentHandler_startPrefixMapping,
1402 SAXContentHandler_endPrefixMapping,
1403 SAXContentHandler_startElement,
1404 SAXContentHandler_endElement,
1405 SAXContentHandler_characters,
1406 SAXContentHandler_ignorableWhitespace,
1407 SAXContentHandler_processingInstruction,
1408 SAXContentHandler_skippedEntity
1411 /*** ISAXLexicalHandler ***/
1412 static HRESULT WINAPI SAXLexicalHandler_QueryInterface(ISAXLexicalHandler *iface,
1413 REFIID riid, void **obj)
1415 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1416 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1419 static ULONG WINAPI SAXLexicalHandler_AddRef(ISAXLexicalHandler *iface)
1421 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1422 return IMXWriter_AddRef(&This->IMXWriter_iface);
1425 static ULONG WINAPI SAXLexicalHandler_Release(ISAXLexicalHandler *iface)
1427 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1428 return IMXWriter_Release(&This->IMXWriter_iface);
1431 static HRESULT WINAPI SAXLexicalHandler_startDTD(ISAXLexicalHandler *iface,
1432 const WCHAR *name, int name_len, const WCHAR *publicId, int publicId_len,
1433 const WCHAR *systemId, int systemId_len)
1435 static const WCHAR doctypeW[] = {'<','!','D','O','C','T','Y','P','E',' '};
1436 static const WCHAR openintW[] = {'[','\r','\n'};
1438 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1440 TRACE("(%p)->(%s %s %s)\n", This, debugstr_wn(name, name_len), debugstr_wn(publicId, publicId_len),
1441 debugstr_wn(systemId, systemId_len));
1443 if (!name) return E_INVALIDARG;
1445 write_output_buffer(This->buffer, doctypeW, sizeof(doctypeW)/sizeof(WCHAR));
1447 if (*name)
1449 write_output_buffer(This->buffer, name, name_len);
1450 write_output_buffer(This->buffer, spaceW, 1);
1453 if (publicId)
1455 static const WCHAR publicW[] = {'P','U','B','L','I','C',' '};
1457 write_output_buffer(This->buffer, publicW, sizeof(publicW)/sizeof(WCHAR));
1458 write_output_buffer_quoted(This->buffer, publicId, publicId_len);
1460 if (!systemId) return E_INVALIDARG;
1462 if (*publicId)
1463 write_output_buffer(This->buffer, spaceW, 1);
1465 write_output_buffer_quoted(This->buffer, systemId, systemId_len);
1467 if (*systemId)
1468 write_output_buffer(This->buffer, spaceW, 1);
1470 else if (systemId)
1472 static const WCHAR systemW[] = {'S','Y','S','T','E','M',' '};
1474 write_output_buffer(This->buffer, systemW, sizeof(systemW)/sizeof(WCHAR));
1475 write_output_buffer_quoted(This->buffer, systemId, systemId_len);
1476 if (*systemId)
1477 write_output_buffer(This->buffer, spaceW, 1);
1480 write_output_buffer(This->buffer, openintW, sizeof(openintW)/sizeof(WCHAR));
1482 return S_OK;
1485 static HRESULT WINAPI SAXLexicalHandler_endDTD(ISAXLexicalHandler *iface)
1487 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1488 static const WCHAR closedtdW[] = {']','>','\r','\n'};
1490 TRACE("(%p)\n", This);
1492 write_output_buffer(This->buffer, closedtdW, sizeof(closedtdW)/sizeof(WCHAR));
1494 return S_OK;
1497 static HRESULT WINAPI SAXLexicalHandler_startEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1499 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1500 FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1501 return E_NOTIMPL;
1504 static HRESULT WINAPI SAXLexicalHandler_endEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1506 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1507 FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1508 return E_NOTIMPL;
1511 static HRESULT WINAPI SAXLexicalHandler_startCDATA(ISAXLexicalHandler *iface)
1513 static const WCHAR scdataW[] = {'<','!','[','C','D','A','T','A','['};
1514 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1516 TRACE("(%p)\n", This);
1518 write_node_indent(This);
1519 write_output_buffer(This->buffer, scdataW, sizeof(scdataW)/sizeof(WCHAR));
1520 This->cdata = TRUE;
1522 return S_OK;
1525 static HRESULT WINAPI SAXLexicalHandler_endCDATA(ISAXLexicalHandler *iface)
1527 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1528 static const WCHAR ecdataW[] = {']',']','>'};
1530 TRACE("(%p)\n", This);
1532 write_output_buffer(This->buffer, ecdataW, sizeof(ecdataW)/sizeof(WCHAR));
1533 This->cdata = FALSE;
1535 return S_OK;
1538 static HRESULT WINAPI SAXLexicalHandler_comment(ISAXLexicalHandler *iface, const WCHAR *chars, int nchars)
1540 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1541 static const WCHAR copenW[] = {'<','!','-','-'};
1542 static const WCHAR ccloseW[] = {'-','-','>','\r','\n'};
1544 TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1546 if (!chars) return E_INVALIDARG;
1548 close_element_starttag(This);
1549 write_node_indent(This);
1551 write_output_buffer(This->buffer, copenW, sizeof(copenW)/sizeof(WCHAR));
1552 if (nchars)
1553 write_output_buffer(This->buffer, chars, nchars);
1554 write_output_buffer(This->buffer, ccloseW, sizeof(ccloseW)/sizeof(WCHAR));
1556 return S_OK;
1559 static const struct ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl =
1561 SAXLexicalHandler_QueryInterface,
1562 SAXLexicalHandler_AddRef,
1563 SAXLexicalHandler_Release,
1564 SAXLexicalHandler_startDTD,
1565 SAXLexicalHandler_endDTD,
1566 SAXLexicalHandler_startEntity,
1567 SAXLexicalHandler_endEntity,
1568 SAXLexicalHandler_startCDATA,
1569 SAXLexicalHandler_endCDATA,
1570 SAXLexicalHandler_comment
1573 /*** ISAXDeclHandler ***/
1574 static HRESULT WINAPI SAXDeclHandler_QueryInterface(ISAXDeclHandler *iface,
1575 REFIID riid, void **obj)
1577 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1578 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1581 static ULONG WINAPI SAXDeclHandler_AddRef(ISAXDeclHandler *iface)
1583 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1584 return IMXWriter_AddRef(&This->IMXWriter_iface);
1587 static ULONG WINAPI SAXDeclHandler_Release(ISAXDeclHandler *iface)
1589 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1590 return IMXWriter_Release(&This->IMXWriter_iface);
1593 static HRESULT WINAPI SAXDeclHandler_elementDecl(ISAXDeclHandler *iface,
1594 const WCHAR *name, int n_name, const WCHAR *model, int n_model)
1596 static const WCHAR elementW[] = {'<','!','E','L','E','M','E','N','T',' '};
1597 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1599 TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1600 debugstr_wn(model, n_model), n_model);
1602 if (!name || !model) return E_INVALIDARG;
1604 write_output_buffer(This->buffer, elementW, sizeof(elementW)/sizeof(WCHAR));
1605 if (n_name) {
1606 write_output_buffer(This->buffer, name, n_name);
1607 write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR));
1609 if (n_model)
1610 write_output_buffer(This->buffer, model, n_model);
1611 write_output_buffer(This->buffer, closetagW, sizeof(closetagW)/sizeof(WCHAR));
1613 return S_OK;
1616 static HRESULT WINAPI SAXDeclHandler_attributeDecl(ISAXDeclHandler *iface,
1617 const WCHAR *element, int n_element, const WCHAR *attr, int n_attr,
1618 const WCHAR *type, int n_type, const WCHAR *Default, int n_default,
1619 const WCHAR *value, int n_value)
1621 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1622 static const WCHAR attlistW[] = {'<','!','A','T','T','L','I','S','T',' '};
1623 static const WCHAR closetagW[] = {'>','\r','\n'};
1625 TRACE("(%p)->(%s:%d %s:%d %s:%d %s:%d %s:%d)\n", This, debugstr_wn(element, n_element), n_element,
1626 debugstr_wn(attr, n_attr), n_attr, debugstr_wn(type, n_type), n_type, debugstr_wn(Default, n_default), n_default,
1627 debugstr_wn(value, n_value), n_value);
1629 write_output_buffer(This->buffer, attlistW, sizeof(attlistW)/sizeof(WCHAR));
1630 if (n_element) {
1631 write_output_buffer(This->buffer, element, n_element);
1632 write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR));
1635 if (n_attr) {
1636 write_output_buffer(This->buffer, attr, n_attr);
1637 write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR));
1640 if (n_type) {
1641 write_output_buffer(This->buffer, type, n_type);
1642 write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR));
1645 if (n_default) {
1646 write_output_buffer(This->buffer, Default, n_default);
1647 write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR));
1650 if (n_value)
1651 write_output_buffer_quoted(This->buffer, value, n_value);
1653 write_output_buffer(This->buffer, closetagW, sizeof(closetagW)/sizeof(WCHAR));
1655 return S_OK;
1658 static HRESULT WINAPI SAXDeclHandler_internalEntityDecl(ISAXDeclHandler *iface,
1659 const WCHAR *name, int n_name, const WCHAR *value, int n_value)
1661 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1663 TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1664 debugstr_wn(value, n_value), n_value);
1666 if (!name || !value) return E_INVALIDARG;
1668 write_output_buffer(This->buffer, entityW, sizeof(entityW)/sizeof(WCHAR));
1669 if (n_name) {
1670 write_output_buffer(This->buffer, name, n_name);
1671 write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR));
1674 if (n_value)
1675 write_output_buffer_quoted(This->buffer, value, n_value);
1677 write_output_buffer(This->buffer, closetagW, sizeof(closetagW)/sizeof(WCHAR));
1679 return S_OK;
1682 static HRESULT WINAPI SAXDeclHandler_externalEntityDecl(ISAXDeclHandler *iface,
1683 const WCHAR *name, int n_name, const WCHAR *publicId, int n_publicId,
1684 const WCHAR *systemId, int n_systemId)
1686 static const WCHAR publicW[] = {'P','U','B','L','I','C',' '};
1687 static const WCHAR systemW[] = {'S','Y','S','T','E','M',' '};
1688 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1690 TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1691 debugstr_wn(publicId, n_publicId), n_publicId, debugstr_wn(systemId, n_systemId), n_systemId);
1693 if (!name) return E_INVALIDARG;
1694 if (publicId && !systemId) return E_INVALIDARG;
1695 if (!publicId && !systemId) return E_INVALIDARG;
1697 write_output_buffer(This->buffer, entityW, sizeof(entityW)/sizeof(WCHAR));
1698 if (n_name) {
1699 write_output_buffer(This->buffer, name, n_name);
1700 write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR));
1703 if (publicId)
1705 write_output_buffer(This->buffer, publicW, sizeof(publicW)/sizeof(WCHAR));
1706 write_output_buffer_quoted(This->buffer, publicId, n_publicId);
1707 write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR));
1708 write_output_buffer_quoted(This->buffer, systemId, n_systemId);
1710 else
1712 write_output_buffer(This->buffer, systemW, sizeof(systemW)/sizeof(WCHAR));
1713 write_output_buffer_quoted(This->buffer, systemId, n_systemId);
1716 write_output_buffer(This->buffer, closetagW, sizeof(closetagW)/sizeof(WCHAR));
1718 return S_OK;
1721 static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl = {
1722 SAXDeclHandler_QueryInterface,
1723 SAXDeclHandler_AddRef,
1724 SAXDeclHandler_Release,
1725 SAXDeclHandler_elementDecl,
1726 SAXDeclHandler_attributeDecl,
1727 SAXDeclHandler_internalEntityDecl,
1728 SAXDeclHandler_externalEntityDecl
1731 /*** IVBSAXDeclHandler ***/
1732 static HRESULT WINAPI VBSAXDeclHandler_QueryInterface(IVBSAXDeclHandler *iface,
1733 REFIID riid, void **obj)
1735 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1736 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1739 static ULONG WINAPI VBSAXDeclHandler_AddRef(IVBSAXDeclHandler *iface)
1741 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1742 return IMXWriter_AddRef(&This->IMXWriter_iface);
1745 static ULONG WINAPI VBSAXDeclHandler_Release(IVBSAXDeclHandler *iface)
1747 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1748 return IMXWriter_Release(&This->IMXWriter_iface);
1751 static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfoCount(IVBSAXDeclHandler *iface, UINT* pctinfo)
1753 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1754 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1757 static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfo(IVBSAXDeclHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1759 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1760 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1763 static HRESULT WINAPI VBSAXDeclHandler_GetIDsOfNames(IVBSAXDeclHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1764 UINT cNames, LCID lcid, DISPID* rgDispId )
1766 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1767 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1770 static HRESULT WINAPI VBSAXDeclHandler_Invoke(IVBSAXDeclHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1771 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1773 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1774 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1775 pExcepInfo, puArgErr);
1778 static HRESULT WINAPI VBSAXDeclHandler_elementDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *model)
1780 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1782 TRACE("(%p)->(%p %p)\n", This, name, model);
1784 if (!name || !model)
1785 return E_POINTER;
1787 return ISAXDeclHandler_elementDecl(&This->ISAXDeclHandler_iface, *name, -1, *model, -1);
1790 static HRESULT WINAPI VBSAXDeclHandler_attributeDecl(IVBSAXDeclHandler *iface,
1791 BSTR *element, BSTR *attr, BSTR *type, BSTR *default_value, BSTR *value)
1793 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1795 TRACE("(%p)->(%p %p %p %p %p)\n", This, element, attr, type, default_value, value);
1797 if (!element || !attr || !type || !default_value || !value)
1798 return E_POINTER;
1800 return ISAXDeclHandler_attributeDecl(&This->ISAXDeclHandler_iface, *element, -1, *attr, -1, *type, -1,
1801 *default_value, -1, *value, -1);
1804 static HRESULT WINAPI VBSAXDeclHandler_internalEntityDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *value)
1806 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1808 TRACE("(%p)->(%p %p)\n", This, name, value);
1810 if (!name || !value)
1811 return E_POINTER;
1813 return ISAXDeclHandler_internalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *value, -1);
1816 static HRESULT WINAPI VBSAXDeclHandler_externalEntityDecl(IVBSAXDeclHandler *iface,
1817 BSTR *name, BSTR *publicid, BSTR *systemid)
1819 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1821 TRACE("(%p)->(%p %p %p)\n", This, name, publicid, systemid);
1823 if (!name || !publicid || !systemid)
1824 return E_POINTER;
1826 return ISAXDeclHandler_externalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *publicid, -1, *systemid, -1);
1829 static const IVBSAXDeclHandlerVtbl VBSAXDeclHandlerVtbl = {
1830 VBSAXDeclHandler_QueryInterface,
1831 VBSAXDeclHandler_AddRef,
1832 VBSAXDeclHandler_Release,
1833 VBSAXDeclHandler_GetTypeInfoCount,
1834 VBSAXDeclHandler_GetTypeInfo,
1835 VBSAXDeclHandler_GetIDsOfNames,
1836 VBSAXDeclHandler_Invoke,
1837 VBSAXDeclHandler_elementDecl,
1838 VBSAXDeclHandler_attributeDecl,
1839 VBSAXDeclHandler_internalEntityDecl,
1840 VBSAXDeclHandler_externalEntityDecl
1843 /*** IVBSAXLexicalHandler ***/
1844 static HRESULT WINAPI VBSAXLexicalHandler_QueryInterface(IVBSAXLexicalHandler *iface,
1845 REFIID riid, void **obj)
1847 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1848 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1851 static ULONG WINAPI VBSAXLexicalHandler_AddRef(IVBSAXLexicalHandler *iface)
1853 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1854 return IMXWriter_AddRef(&This->IMXWriter_iface);
1857 static ULONG WINAPI VBSAXLexicalHandler_Release(IVBSAXLexicalHandler *iface)
1859 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1860 return IMXWriter_Release(&This->IMXWriter_iface);
1863 static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfoCount(IVBSAXLexicalHandler *iface, UINT* pctinfo)
1865 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1866 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1869 static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfo(IVBSAXLexicalHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1871 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1872 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1875 static HRESULT WINAPI VBSAXLexicalHandler_GetIDsOfNames(IVBSAXLexicalHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1876 UINT cNames, LCID lcid, DISPID* rgDispId )
1878 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1879 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1882 static HRESULT WINAPI VBSAXLexicalHandler_Invoke(IVBSAXLexicalHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1883 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1885 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1886 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1887 pExcepInfo, puArgErr);
1890 static HRESULT WINAPI VBSAXLexicalHandler_startDTD(IVBSAXLexicalHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
1892 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1894 TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
1896 if (!name || !publicId || !systemId)
1897 return E_POINTER;
1899 return ISAXLexicalHandler_startDTD(&This->ISAXLexicalHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
1902 static HRESULT WINAPI VBSAXLexicalHandler_endDTD(IVBSAXLexicalHandler *iface)
1904 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1905 return ISAXLexicalHandler_endDTD(&This->ISAXLexicalHandler_iface);
1908 static HRESULT WINAPI VBSAXLexicalHandler_startEntity(IVBSAXLexicalHandler *iface, BSTR *name)
1910 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1912 TRACE("(%p)->(%p)\n", This, name);
1914 if (!name)
1915 return E_POINTER;
1917 return ISAXLexicalHandler_startEntity(&This->ISAXLexicalHandler_iface, *name, -1);
1920 static HRESULT WINAPI VBSAXLexicalHandler_endEntity(IVBSAXLexicalHandler *iface, BSTR *name)
1922 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1924 TRACE("(%p)->(%p)\n", This, name);
1926 if (!name)
1927 return E_POINTER;
1929 return ISAXLexicalHandler_endEntity(&This->ISAXLexicalHandler_iface, *name, -1);
1932 static HRESULT WINAPI VBSAXLexicalHandler_startCDATA(IVBSAXLexicalHandler *iface)
1934 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1935 return ISAXLexicalHandler_startCDATA(&This->ISAXLexicalHandler_iface);
1938 static HRESULT WINAPI VBSAXLexicalHandler_endCDATA(IVBSAXLexicalHandler *iface)
1940 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1941 return ISAXLexicalHandler_endCDATA(&This->ISAXLexicalHandler_iface);
1944 static HRESULT WINAPI VBSAXLexicalHandler_comment(IVBSAXLexicalHandler *iface, BSTR *chars)
1946 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1948 TRACE("(%p)->(%p)\n", This, chars);
1950 if (!chars)
1951 return E_POINTER;
1953 return ISAXLexicalHandler_comment(&This->ISAXLexicalHandler_iface, *chars, -1);
1956 static const IVBSAXLexicalHandlerVtbl VBSAXLexicalHandlerVtbl = {
1957 VBSAXLexicalHandler_QueryInterface,
1958 VBSAXLexicalHandler_AddRef,
1959 VBSAXLexicalHandler_Release,
1960 VBSAXLexicalHandler_GetTypeInfoCount,
1961 VBSAXLexicalHandler_GetTypeInfo,
1962 VBSAXLexicalHandler_GetIDsOfNames,
1963 VBSAXLexicalHandler_Invoke,
1964 VBSAXLexicalHandler_startDTD,
1965 VBSAXLexicalHandler_endDTD,
1966 VBSAXLexicalHandler_startEntity,
1967 VBSAXLexicalHandler_endEntity,
1968 VBSAXLexicalHandler_startCDATA,
1969 VBSAXLexicalHandler_endCDATA,
1970 VBSAXLexicalHandler_comment
1973 /*** IVBSAXContentHandler ***/
1974 static HRESULT WINAPI VBSAXContentHandler_QueryInterface(IVBSAXContentHandler *iface, REFIID riid, void **obj)
1976 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
1977 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1980 static ULONG WINAPI VBSAXContentHandler_AddRef(IVBSAXContentHandler *iface)
1982 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
1983 return IMXWriter_AddRef(&This->IMXWriter_iface);
1986 static ULONG WINAPI VBSAXContentHandler_Release(IVBSAXContentHandler *iface)
1988 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
1989 return IMXWriter_Release(&This->IMXWriter_iface);
1992 static HRESULT WINAPI VBSAXContentHandler_GetTypeInfoCount(IVBSAXContentHandler *iface, UINT* pctinfo)
1994 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
1995 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1998 static HRESULT WINAPI VBSAXContentHandler_GetTypeInfo(IVBSAXContentHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2000 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2001 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2004 static HRESULT WINAPI VBSAXContentHandler_GetIDsOfNames(IVBSAXContentHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2005 UINT cNames, LCID lcid, DISPID* rgDispId )
2007 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2008 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2011 static HRESULT WINAPI VBSAXContentHandler_Invoke(IVBSAXContentHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2012 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2014 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2015 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2016 pExcepInfo, puArgErr);
2019 static HRESULT WINAPI VBSAXContentHandler_putref_documentLocator(IVBSAXContentHandler *iface, IVBSAXLocator *locator)
2021 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2022 TRACE("(%p)->(%p)\n", This, locator);
2023 return S_OK;
2026 static HRESULT WINAPI VBSAXContentHandler_startDocument(IVBSAXContentHandler *iface)
2028 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2029 return ISAXContentHandler_startDocument(&This->ISAXContentHandler_iface);
2032 static HRESULT WINAPI VBSAXContentHandler_endDocument(IVBSAXContentHandler *iface)
2034 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2035 return ISAXContentHandler_endDocument(&This->ISAXContentHandler_iface);
2038 static HRESULT WINAPI VBSAXContentHandler_startPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix, BSTR *uri)
2040 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2042 TRACE("(%p)->(%p %p)\n", This, prefix, uri);
2044 if (!prefix || !uri)
2045 return E_POINTER;
2047 return ISAXContentHandler_startPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1, *uri, -1);
2050 static HRESULT WINAPI VBSAXContentHandler_endPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix)
2052 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2054 TRACE("(%p)->(%p)\n", This, prefix);
2056 if (!prefix)
2057 return E_POINTER;
2059 return ISAXContentHandler_endPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1);
2062 static HRESULT WINAPI VBSAXContentHandler_startElement(IVBSAXContentHandler *iface,
2063 BSTR *namespaceURI, BSTR *localName, BSTR *QName, IVBSAXAttributes *attrs)
2065 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2067 TRACE("(%p)->(%p %p %p %p)\n", This, namespaceURI, localName, QName, attrs);
2069 if (!namespaceURI || !localName || !QName)
2070 return E_POINTER;
2072 TRACE("(%s %s %s)\n", debugstr_w(*namespaceURI), debugstr_w(*localName), debugstr_w(*QName));
2074 mxwriter_write_starttag(This, *QName, SysStringLen(*QName));
2076 if (attrs)
2078 int length, i, escape;
2079 HRESULT hr;
2081 hr = IVBSAXAttributes_get_length(attrs, &length);
2082 if (FAILED(hr)) return hr;
2084 escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
2085 (This->class_version == MSXML4 || This->class_version == MSXML6);
2087 for (i = 0; i < length; i++)
2089 BSTR qname, value;
2091 hr = IVBSAXAttributes_getQName(attrs, i, &qname);
2092 if (FAILED(hr)) return hr;
2094 hr = IVBSAXAttributes_getValue(attrs, i, &value);
2095 if (FAILED(hr))
2097 SysFreeString(qname);
2098 return hr;
2101 mxwriter_write_attribute(This, qname, SysStringLen(qname), value, SysStringLen(value), escape);
2102 SysFreeString(qname);
2103 SysFreeString(value);
2107 return S_OK;
2110 static HRESULT WINAPI VBSAXContentHandler_endElement(IVBSAXContentHandler *iface, BSTR *namespaceURI,
2111 BSTR *localName, BSTR *QName)
2113 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2115 TRACE("(%p)->(%p %p %p)\n", This, namespaceURI, localName, QName);
2117 if (!namespaceURI || !localName || !QName)
2118 return E_POINTER;
2120 return ISAXContentHandler_endElement(&This->ISAXContentHandler_iface,
2121 *namespaceURI, SysStringLen(*namespaceURI),
2122 *localName, SysStringLen(*localName),
2123 *QName, SysStringLen(*QName));
2126 static HRESULT WINAPI VBSAXContentHandler_characters(IVBSAXContentHandler *iface, BSTR *chars)
2128 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2130 TRACE("(%p)->(%p)\n", This, chars);
2132 if (!chars)
2133 return E_POINTER;
2135 return ISAXContentHandler_characters(&This->ISAXContentHandler_iface, *chars, -1);
2138 static HRESULT WINAPI VBSAXContentHandler_ignorableWhitespace(IVBSAXContentHandler *iface, BSTR *chars)
2140 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2142 TRACE("(%p)->(%p)\n", This, chars);
2144 if (!chars)
2145 return E_POINTER;
2147 return ISAXContentHandler_ignorableWhitespace(&This->ISAXContentHandler_iface, *chars, -1);
2150 static HRESULT WINAPI VBSAXContentHandler_processingInstruction(IVBSAXContentHandler *iface,
2151 BSTR *target, BSTR *data)
2153 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2155 TRACE("(%p)->(%p %p)\n", This, target, data);
2157 if (!target || !data)
2158 return E_POINTER;
2160 return ISAXContentHandler_processingInstruction(&This->ISAXContentHandler_iface, *target, -1, *data, -1);
2163 static HRESULT WINAPI VBSAXContentHandler_skippedEntity(IVBSAXContentHandler *iface, BSTR *name)
2165 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2167 TRACE("(%p)->(%p)\n", This, name);
2169 if (!name)
2170 return E_POINTER;
2172 return ISAXContentHandler_skippedEntity(&This->ISAXContentHandler_iface, *name, -1);
2175 static const IVBSAXContentHandlerVtbl VBSAXContentHandlerVtbl = {
2176 VBSAXContentHandler_QueryInterface,
2177 VBSAXContentHandler_AddRef,
2178 VBSAXContentHandler_Release,
2179 VBSAXContentHandler_GetTypeInfoCount,
2180 VBSAXContentHandler_GetTypeInfo,
2181 VBSAXContentHandler_GetIDsOfNames,
2182 VBSAXContentHandler_Invoke,
2183 VBSAXContentHandler_putref_documentLocator,
2184 VBSAXContentHandler_startDocument,
2185 VBSAXContentHandler_endDocument,
2186 VBSAXContentHandler_startPrefixMapping,
2187 VBSAXContentHandler_endPrefixMapping,
2188 VBSAXContentHandler_startElement,
2189 VBSAXContentHandler_endElement,
2190 VBSAXContentHandler_characters,
2191 VBSAXContentHandler_ignorableWhitespace,
2192 VBSAXContentHandler_processingInstruction,
2193 VBSAXContentHandler_skippedEntity
2196 static HRESULT WINAPI SAXDTDHandler_QueryInterface(ISAXDTDHandler *iface, REFIID riid, void **obj)
2198 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2199 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2202 static ULONG WINAPI SAXDTDHandler_AddRef(ISAXDTDHandler *iface)
2204 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2205 return IMXWriter_AddRef(&This->IMXWriter_iface);
2208 static ULONG WINAPI SAXDTDHandler_Release(ISAXDTDHandler *iface)
2210 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2211 return IMXWriter_Release(&This->IMXWriter_iface);
2214 static HRESULT WINAPI SAXDTDHandler_notationDecl(ISAXDTDHandler *iface,
2215 const WCHAR *name, INT nname,
2216 const WCHAR *publicid, INT npublicid,
2217 const WCHAR *systemid, INT nsystemid)
2219 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2220 FIXME("(%p)->(%s:%d, %s:%d, %s:%d): stub\n", This, debugstr_wn(name, nname), nname,
2221 debugstr_wn(publicid, npublicid), npublicid, debugstr_wn(systemid, nsystemid), nsystemid);
2222 return E_NOTIMPL;
2225 static HRESULT WINAPI SAXDTDHandler_unparsedEntityDecl(ISAXDTDHandler *iface,
2226 const WCHAR *name, INT nname,
2227 const WCHAR *publicid, INT npublicid,
2228 const WCHAR *systemid, INT nsystemid,
2229 const WCHAR *notation, INT nnotation)
2231 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2232 FIXME("(%p)->(%s:%d, %s:%d, %s:%d, %s:%d): stub\n", This, debugstr_wn(name, nname), nname,
2233 debugstr_wn(publicid, npublicid), npublicid, debugstr_wn(systemid, nsystemid), nsystemid,
2234 debugstr_wn(notation, nnotation), nnotation);
2235 return E_NOTIMPL;
2238 static const ISAXDTDHandlerVtbl SAXDTDHandlerVtbl = {
2239 SAXDTDHandler_QueryInterface,
2240 SAXDTDHandler_AddRef,
2241 SAXDTDHandler_Release,
2242 SAXDTDHandler_notationDecl,
2243 SAXDTDHandler_unparsedEntityDecl
2246 /*** IVBSAXDTDHandler ***/
2247 static HRESULT WINAPI VBSAXDTDHandler_QueryInterface(IVBSAXDTDHandler *iface, REFIID riid, void **obj)
2249 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2250 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2253 static ULONG WINAPI VBSAXDTDHandler_AddRef(IVBSAXDTDHandler *iface)
2255 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2256 return IMXWriter_AddRef(&This->IMXWriter_iface);
2259 static ULONG WINAPI VBSAXDTDHandler_Release(IVBSAXDTDHandler *iface)
2261 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2262 return IMXWriter_Release(&This->IMXWriter_iface);
2265 static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfoCount(IVBSAXDTDHandler *iface, UINT* pctinfo)
2267 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2268 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2271 static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfo(IVBSAXDTDHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2273 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2274 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2277 static HRESULT WINAPI VBSAXDTDHandler_GetIDsOfNames(IVBSAXDTDHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2278 UINT cNames, LCID lcid, DISPID* rgDispId )
2280 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2281 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2284 static HRESULT WINAPI VBSAXDTDHandler_Invoke(IVBSAXDTDHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2285 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2287 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2288 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2289 pExcepInfo, puArgErr);
2292 static HRESULT WINAPI VBSAXDTDHandler_notationDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
2294 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2296 TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
2298 if (!name || !publicId || !systemId)
2299 return E_POINTER;
2301 return ISAXDTDHandler_notationDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
2304 static HRESULT WINAPI VBSAXDTDHandler_unparsedEntityDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId,
2305 BSTR *systemId, BSTR *notation)
2307 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2309 TRACE("(%p)->(%p %p %p %p)\n", This, name, publicId, systemId, notation);
2311 if (!name || !publicId || !systemId || !notation)
2312 return E_POINTER;
2314 return ISAXDTDHandler_unparsedEntityDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1,
2315 *systemId, -1, *notation, -1);
2318 static const IVBSAXDTDHandlerVtbl VBSAXDTDHandlerVtbl = {
2319 VBSAXDTDHandler_QueryInterface,
2320 VBSAXDTDHandler_AddRef,
2321 VBSAXDTDHandler_Release,
2322 VBSAXDTDHandler_GetTypeInfoCount,
2323 VBSAXDTDHandler_GetTypeInfo,
2324 VBSAXDTDHandler_GetIDsOfNames,
2325 VBSAXDTDHandler_Invoke,
2326 VBSAXDTDHandler_notationDecl,
2327 VBSAXDTDHandler_unparsedEntityDecl
2330 /* ISAXErrorHandler */
2331 static HRESULT WINAPI SAXErrorHandler_QueryInterface(ISAXErrorHandler *iface, REFIID riid, void **obj)
2333 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2334 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2337 static ULONG WINAPI SAXErrorHandler_AddRef(ISAXErrorHandler *iface)
2339 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2340 return IMXWriter_AddRef(&This->IMXWriter_iface);
2343 static ULONG WINAPI SAXErrorHandler_Release(ISAXErrorHandler *iface)
2345 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2346 return IMXWriter_Release(&This->IMXWriter_iface);
2349 static HRESULT WINAPI SAXErrorHandler_error(ISAXErrorHandler *iface,
2350 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2352 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2354 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2356 return E_NOTIMPL;
2359 static HRESULT WINAPI SAXErrorHandler_fatalError(ISAXErrorHandler *iface,
2360 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2362 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2364 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2366 return E_NOTIMPL;
2369 static HRESULT WINAPI SAXErrorHandler_ignorableWarning(ISAXErrorHandler *iface,
2370 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2372 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2374 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2376 return E_NOTIMPL;
2379 static const ISAXErrorHandlerVtbl SAXErrorHandlerVtbl = {
2380 SAXErrorHandler_QueryInterface,
2381 SAXErrorHandler_AddRef,
2382 SAXErrorHandler_Release,
2383 SAXErrorHandler_error,
2384 SAXErrorHandler_fatalError,
2385 SAXErrorHandler_ignorableWarning
2388 /*** IVBSAXErrorHandler ***/
2389 static HRESULT WINAPI VBSAXErrorHandler_QueryInterface(IVBSAXErrorHandler *iface, REFIID riid, void **obj)
2391 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2392 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2395 static ULONG WINAPI VBSAXErrorHandler_AddRef(IVBSAXErrorHandler *iface)
2397 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2398 return IMXWriter_AddRef(&This->IMXWriter_iface);
2401 static ULONG WINAPI VBSAXErrorHandler_Release(IVBSAXErrorHandler *iface)
2403 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2404 return IMXWriter_Release(&This->IMXWriter_iface);
2407 static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfoCount(IVBSAXErrorHandler *iface, UINT* pctinfo)
2409 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2410 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2413 static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfo(IVBSAXErrorHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2415 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2416 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2419 static HRESULT WINAPI VBSAXErrorHandler_GetIDsOfNames(IVBSAXErrorHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2420 UINT cNames, LCID lcid, DISPID* rgDispId )
2422 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2423 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2426 static HRESULT WINAPI VBSAXErrorHandler_Invoke(IVBSAXErrorHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2427 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2429 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2430 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2431 pExcepInfo, puArgErr);
2434 static HRESULT WINAPI VBSAXErrorHandler_error(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2436 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2437 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2438 return E_NOTIMPL;
2441 static HRESULT WINAPI VBSAXErrorHandler_fatalError(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2443 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2444 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2445 return E_NOTIMPL;
2448 static HRESULT WINAPI VBSAXErrorHandler_ignorableWarning(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2450 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2451 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2452 return E_NOTIMPL;
2455 static const IVBSAXErrorHandlerVtbl VBSAXErrorHandlerVtbl = {
2456 VBSAXErrorHandler_QueryInterface,
2457 VBSAXErrorHandler_AddRef,
2458 VBSAXErrorHandler_Release,
2459 VBSAXErrorHandler_GetTypeInfoCount,
2460 VBSAXErrorHandler_GetTypeInfo,
2461 VBSAXErrorHandler_GetIDsOfNames,
2462 VBSAXErrorHandler_Invoke,
2463 VBSAXErrorHandler_error,
2464 VBSAXErrorHandler_fatalError,
2465 VBSAXErrorHandler_ignorableWarning
2468 static const tid_t mxwriter_iface_tids[] = {
2469 IMXWriter_tid,
2473 static dispex_static_data_t mxwriter_dispex = {
2474 NULL,
2475 IMXWriter_tid,
2476 NULL,
2477 mxwriter_iface_tids
2480 HRESULT MXWriter_create(MSXML_VERSION version, void **ppObj)
2482 static const WCHAR version10W[] = {'1','.','0',0};
2483 mxwriter *This;
2484 HRESULT hr;
2486 TRACE("(%p)\n", ppObj);
2488 This = heap_alloc( sizeof (*This) );
2489 if(!This)
2490 return E_OUTOFMEMORY;
2492 This->IMXWriter_iface.lpVtbl = &MXWriterVtbl;
2493 This->ISAXContentHandler_iface.lpVtbl = &SAXContentHandlerVtbl;
2494 This->ISAXLexicalHandler_iface.lpVtbl = &SAXLexicalHandlerVtbl;
2495 This->ISAXDeclHandler_iface.lpVtbl = &SAXDeclHandlerVtbl;
2496 This->ISAXDTDHandler_iface.lpVtbl = &SAXDTDHandlerVtbl;
2497 This->ISAXErrorHandler_iface.lpVtbl = &SAXErrorHandlerVtbl;
2498 This->IVBSAXDeclHandler_iface.lpVtbl = &VBSAXDeclHandlerVtbl;
2499 This->IVBSAXLexicalHandler_iface.lpVtbl = &VBSAXLexicalHandlerVtbl;
2500 This->IVBSAXContentHandler_iface.lpVtbl = &VBSAXContentHandlerVtbl;
2501 This->IVBSAXDTDHandler_iface.lpVtbl = &VBSAXDTDHandlerVtbl;
2502 This->IVBSAXErrorHandler_iface.lpVtbl = &VBSAXErrorHandlerVtbl;
2503 This->ref = 1;
2504 This->class_version = version;
2506 This->props[MXWriter_BOM] = VARIANT_TRUE;
2507 This->props[MXWriter_DisableEscaping] = VARIANT_FALSE;
2508 This->props[MXWriter_Indent] = VARIANT_FALSE;
2509 This->props[MXWriter_OmitXmlDecl] = VARIANT_FALSE;
2510 This->props[MXWriter_Standalone] = VARIANT_FALSE;
2511 This->prop_changed = FALSE;
2512 This->encoding = SysAllocString(utf16W);
2513 This->version = SysAllocString(version10W);
2514 This->xml_enc = XmlEncoding_UTF16;
2516 This->element = NULL;
2517 This->cdata = FALSE;
2518 This->indent = 0;
2519 This->text = FALSE;
2520 This->newline = FALSE;
2522 This->dest = NULL;
2523 This->dest_written = 0;
2525 hr = alloc_output_buffer(This->xml_enc, &This->buffer);
2526 if (hr != S_OK) {
2527 SysFreeString(This->encoding);
2528 SysFreeString(This->version);
2529 heap_free(This);
2530 return hr;
2533 init_dispex(&This->dispex, (IUnknown*)&This->IMXWriter_iface, &mxwriter_dispex);
2535 *ppObj = &This->IMXWriter_iface;
2537 TRACE("returning iface %p\n", *ppObj);
2539 return S_OK;
2542 static HRESULT WINAPI MXAttributes_QueryInterface(IMXAttributes *iface, REFIID riid, void **ppObj)
2544 mxattributes *This = impl_from_IMXAttributes( iface );
2546 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppObj);
2548 *ppObj = NULL;
2550 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2551 IsEqualGUID( riid, &IID_IDispatch ) ||
2552 IsEqualGUID( riid, &IID_IMXAttributes ))
2554 *ppObj = iface;
2556 else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
2558 *ppObj = &This->ISAXAttributes_iface;
2560 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
2562 *ppObj = &This->IVBSAXAttributes_iface;
2564 else if (dispex_query_interface(&This->dispex, riid, ppObj))
2566 return *ppObj ? S_OK : E_NOINTERFACE;
2568 else
2570 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2571 return E_NOINTERFACE;
2574 IMXAttributes_AddRef( iface );
2576 return S_OK;
2579 static ULONG WINAPI MXAttributes_AddRef(IMXAttributes *iface)
2581 mxattributes *This = impl_from_IMXAttributes( iface );
2582 ULONG ref = InterlockedIncrement( &This->ref );
2583 TRACE("(%p)->(%d)\n", This, ref );
2584 return ref;
2587 static ULONG WINAPI MXAttributes_Release(IMXAttributes *iface)
2589 mxattributes *This = impl_from_IMXAttributes( iface );
2590 LONG ref = InterlockedDecrement( &This->ref );
2592 TRACE("(%p)->(%d)\n", This, ref);
2594 if (ref == 0)
2596 int i;
2598 for (i = 0; i < This->length; i++)
2600 SysFreeString(This->attr[i].qname);
2601 SysFreeString(This->attr[i].local);
2602 SysFreeString(This->attr[i].uri);
2603 SysFreeString(This->attr[i].type);
2604 SysFreeString(This->attr[i].value);
2607 heap_free(This->attr);
2608 heap_free(This);
2611 return ref;
2614 static HRESULT WINAPI MXAttributes_GetTypeInfoCount(IMXAttributes *iface, UINT* pctinfo)
2616 mxattributes *This = impl_from_IMXAttributes( iface );
2617 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2620 static HRESULT WINAPI MXAttributes_GetTypeInfo(IMXAttributes *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2622 mxattributes *This = impl_from_IMXAttributes( iface );
2623 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2626 static HRESULT WINAPI MXAttributes_GetIDsOfNames(
2627 IMXAttributes *iface,
2628 REFIID riid,
2629 LPOLESTR* rgszNames,
2630 UINT cNames,
2631 LCID lcid,
2632 DISPID* rgDispId)
2634 mxattributes *This = impl_from_IMXAttributes( iface );
2635 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2636 riid, rgszNames, cNames, lcid, rgDispId);
2639 static HRESULT WINAPI MXAttributes_Invoke(
2640 IMXAttributes *iface,
2641 DISPID dispIdMember,
2642 REFIID riid,
2643 LCID lcid,
2644 WORD wFlags,
2645 DISPPARAMS* pDispParams,
2646 VARIANT* pVarResult,
2647 EXCEPINFO* pExcepInfo,
2648 UINT* puArgErr)
2650 mxattributes *This = impl_from_IMXAttributes( iface );
2651 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
2652 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2655 static HRESULT WINAPI MXAttributes_addAttribute(IMXAttributes *iface,
2656 BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2658 mxattributes *This = impl_from_IMXAttributes( iface );
2659 mxattribute *attr;
2660 HRESULT hr;
2662 TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(uri), debugstr_w(localName),
2663 debugstr_w(QName), debugstr_w(type), debugstr_w(value));
2665 if ((!uri || !localName || !QName || !type || !value) && This->class_version != MSXML6)
2666 return E_INVALIDARG;
2668 /* ensure array is large enough */
2669 hr = mxattributes_grow(This);
2670 if (hr != S_OK) return hr;
2672 attr = &This->attr[This->length];
2674 attr->qname = SysAllocString(QName);
2675 attr->local = SysAllocString(localName);
2676 attr->uri = SysAllocString(uri);
2677 attr->type = SysAllocString(type ? type : emptyW);
2678 attr->value = SysAllocString(value);
2679 This->length++;
2681 return S_OK;
2684 static HRESULT WINAPI MXAttributes_addAttributeFromIndex(IMXAttributes *iface,
2685 VARIANT atts, int index)
2687 mxattributes *This = impl_from_IMXAttributes( iface );
2688 FIXME("(%p)->(%s %d): stub\n", This, debugstr_variant(&atts), index);
2689 return E_NOTIMPL;
2692 static HRESULT WINAPI MXAttributes_clear(IMXAttributes *iface)
2694 mxattributes *This = impl_from_IMXAttributes( iface );
2695 int i;
2697 TRACE("(%p)\n", This);
2699 for (i = 0; i < This->length; i++)
2701 SysFreeString(This->attr[i].qname);
2702 SysFreeString(This->attr[i].local);
2703 SysFreeString(This->attr[i].uri);
2704 SysFreeString(This->attr[i].type);
2705 SysFreeString(This->attr[i].value);
2706 memset(&This->attr[i], 0, sizeof(mxattribute));
2709 This->length = 0;
2711 return S_OK;
2714 static mxattribute *get_attribute_byindex(mxattributes *attrs, int index)
2716 if (index < 0 || index >= attrs->length) return NULL;
2717 return &attrs->attr[index];
2720 static HRESULT WINAPI MXAttributes_removeAttribute(IMXAttributes *iface, int index)
2722 mxattributes *This = impl_from_IMXAttributes( iface );
2723 mxattribute *dst;
2725 TRACE("(%p)->(%d)\n", This, index);
2727 if (!(dst = get_attribute_byindex(This, index))) return E_INVALIDARG;
2729 /* no need to remove last attribute, just make it inaccessible */
2730 if (index + 1 == This->length)
2732 This->length--;
2733 return S_OK;
2736 memmove(dst, dst + 1, (This->length-index-1)*sizeof(*dst));
2737 This->length--;
2739 return S_OK;
2742 static HRESULT WINAPI MXAttributes_setAttribute(IMXAttributes *iface, int index,
2743 BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2745 mxattributes *This = impl_from_IMXAttributes( iface );
2746 FIXME("(%p)->(%d %s %s %s %s %s): stub\n", This, index, debugstr_w(uri),
2747 debugstr_w(localName), debugstr_w(QName), debugstr_w(type), debugstr_w(value));
2748 return E_NOTIMPL;
2751 static HRESULT WINAPI MXAttributes_setAttributes(IMXAttributes *iface, VARIANT atts)
2753 mxattributes *This = impl_from_IMXAttributes( iface );
2754 FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&atts));
2755 return E_NOTIMPL;
2758 static HRESULT WINAPI MXAttributes_setLocalName(IMXAttributes *iface, int index,
2759 BSTR localName)
2761 mxattributes *This = impl_from_IMXAttributes( iface );
2762 mxattribute *attr;
2764 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(localName));
2766 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2768 SysFreeString(attr->local);
2769 attr->local = SysAllocString(localName);
2771 return S_OK;
2774 static HRESULT WINAPI MXAttributes_setQName(IMXAttributes *iface, int index, BSTR QName)
2776 mxattributes *This = impl_from_IMXAttributes( iface );
2777 mxattribute *attr;
2779 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(QName));
2781 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2783 SysFreeString(attr->qname);
2784 attr->qname = SysAllocString(QName);
2786 return S_OK;
2789 static HRESULT WINAPI MXAttributes_setURI(IMXAttributes *iface, int index, BSTR uri)
2791 mxattributes *This = impl_from_IMXAttributes( iface );
2792 mxattribute *attr;
2794 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(uri));
2796 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2798 SysFreeString(attr->uri);
2799 attr->uri = SysAllocString(uri);
2801 return S_OK;
2804 static HRESULT WINAPI MXAttributes_setValue(IMXAttributes *iface, int index, BSTR value)
2806 mxattributes *This = impl_from_IMXAttributes( iface );
2807 mxattribute *attr;
2809 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(value));
2811 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2813 SysFreeString(attr->value);
2814 attr->value = SysAllocString(value);
2816 return S_OK;
2819 static const IMXAttributesVtbl MXAttributesVtbl = {
2820 MXAttributes_QueryInterface,
2821 MXAttributes_AddRef,
2822 MXAttributes_Release,
2823 MXAttributes_GetTypeInfoCount,
2824 MXAttributes_GetTypeInfo,
2825 MXAttributes_GetIDsOfNames,
2826 MXAttributes_Invoke,
2827 MXAttributes_addAttribute,
2828 MXAttributes_addAttributeFromIndex,
2829 MXAttributes_clear,
2830 MXAttributes_removeAttribute,
2831 MXAttributes_setAttribute,
2832 MXAttributes_setAttributes,
2833 MXAttributes_setLocalName,
2834 MXAttributes_setQName,
2835 MXAttributes_setURI,
2836 MXAttributes_setValue
2839 static HRESULT WINAPI SAXAttributes_QueryInterface(ISAXAttributes *iface, REFIID riid, void **ppObj)
2841 mxattributes *This = impl_from_ISAXAttributes( iface );
2842 return IMXAttributes_QueryInterface(&This->IMXAttributes_iface, riid, ppObj);
2845 static ULONG WINAPI SAXAttributes_AddRef(ISAXAttributes *iface)
2847 mxattributes *This = impl_from_ISAXAttributes( iface );
2848 return IMXAttributes_AddRef(&This->IMXAttributes_iface);
2851 static ULONG WINAPI SAXAttributes_Release(ISAXAttributes *iface)
2853 mxattributes *This = impl_from_ISAXAttributes( iface );
2854 return IMXAttributes_Release(&This->IMXAttributes_iface);
2857 static HRESULT WINAPI SAXAttributes_getLength(ISAXAttributes *iface, int *length)
2859 mxattributes *This = impl_from_ISAXAttributes( iface );
2860 TRACE("(%p)->(%p)\n", This, length);
2862 if (!length && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
2863 return E_POINTER;
2865 *length = This->length;
2867 return S_OK;
2870 static HRESULT WINAPI SAXAttributes_getURI(ISAXAttributes *iface, int index, const WCHAR **uri,
2871 int *len)
2873 mxattributes *This = impl_from_ISAXAttributes( iface );
2875 TRACE("(%p)->(%d %p %p)\n", This, index, uri, len);
2877 if (index >= This->length || index < 0) return E_INVALIDARG;
2878 if (!uri || !len) return E_POINTER;
2880 *len = SysStringLen(This->attr[index].uri);
2881 *uri = This->attr[index].uri;
2883 return S_OK;
2886 static HRESULT WINAPI SAXAttributes_getLocalName(ISAXAttributes *iface, int index, const WCHAR **name,
2887 int *len)
2889 mxattributes *This = impl_from_ISAXAttributes( iface );
2891 TRACE("(%p)->(%d %p %p)\n", This, index, name, len);
2893 if (index >= This->length || index < 0) return E_INVALIDARG;
2894 if (!name || !len) return E_POINTER;
2896 *len = SysStringLen(This->attr[index].local);
2897 *name = This->attr[index].local;
2899 return S_OK;
2902 static HRESULT WINAPI SAXAttributes_getQName(ISAXAttributes *iface, int index, const WCHAR **qname, int *length)
2904 mxattributes *This = impl_from_ISAXAttributes( iface );
2906 TRACE("(%p)->(%d %p %p)\n", This, index, qname, length);
2908 if (index >= This->length) return E_INVALIDARG;
2909 if (!qname || !length) return E_POINTER;
2911 *qname = This->attr[index].qname;
2912 *length = SysStringLen(This->attr[index].qname);
2914 return S_OK;
2917 static HRESULT WINAPI SAXAttributes_getName(ISAXAttributes *iface, int index, const WCHAR **uri, int *uri_len,
2918 const WCHAR **local, int *local_len, const WCHAR **qname, int *qname_len)
2920 mxattributes *This = impl_from_ISAXAttributes( iface );
2922 TRACE("(%p)->(%d %p %p %p %p %p %p)\n", This, index, uri, uri_len, local, local_len, qname, qname_len);
2924 if (index >= This->length || index < 0)
2925 return E_INVALIDARG;
2927 if (!uri || !uri_len || !local || !local_len || !qname || !qname_len)
2928 return E_POINTER;
2930 *uri_len = SysStringLen(This->attr[index].uri);
2931 *uri = This->attr[index].uri;
2933 *local_len = SysStringLen(This->attr[index].local);
2934 *local = This->attr[index].local;
2936 *qname_len = SysStringLen(This->attr[index].qname);
2937 *qname = This->attr[index].qname;
2939 TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*local), debugstr_w(*qname));
2941 return S_OK;
2944 static HRESULT WINAPI SAXAttributes_getIndexFromName(ISAXAttributes *iface, const WCHAR *uri, int uri_len,
2945 const WCHAR *name, int len, int *index)
2947 mxattributes *This = impl_from_ISAXAttributes( iface );
2948 int i;
2950 TRACE("(%p)->(%s:%d %s:%d %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
2951 debugstr_wn(name, len), len, index);
2953 if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
2954 return E_POINTER;
2956 if (!uri || !name || !index) return E_INVALIDARG;
2958 for (i = 0; i < This->length; i++)
2960 if (uri_len != SysStringLen(This->attr[i].uri)) continue;
2961 if (strncmpW(uri, This->attr[i].uri, uri_len)) continue;
2963 if (len != SysStringLen(This->attr[i].local)) continue;
2964 if (strncmpW(name, This->attr[i].local, len)) continue;
2966 *index = i;
2967 return S_OK;
2970 return E_INVALIDARG;
2973 static HRESULT WINAPI SAXAttributes_getIndexFromQName(ISAXAttributes *iface, const WCHAR *qname,
2974 int len, int *index)
2976 mxattributes *This = impl_from_ISAXAttributes( iface );
2977 int i;
2979 TRACE("(%p)->(%s:%d %p)\n", This, debugstr_wn(qname, len), len, index);
2981 if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
2982 return E_POINTER;
2984 if (!qname || !index || !len) return E_INVALIDARG;
2986 for (i = 0; i < This->length; i++)
2988 if (len != SysStringLen(This->attr[i].qname)) continue;
2989 if (strncmpW(qname, This->attr[i].qname, len)) continue;
2991 *index = i;
2992 return S_OK;
2995 return E_INVALIDARG;
2998 static HRESULT WINAPI SAXAttributes_getType(ISAXAttributes *iface, int index, const WCHAR **type,
2999 int *len)
3001 mxattributes *This = impl_from_ISAXAttributes( iface );
3003 TRACE("(%p)->(%d %p %p)\n", This, index, type, len);
3005 if (index >= This->length) return E_INVALIDARG;
3007 if ((!type || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3008 return E_POINTER;
3010 *type = This->attr[index].type;
3011 *len = SysStringLen(This->attr[index].type);
3013 return S_OK;
3016 static HRESULT WINAPI SAXAttributes_getTypeFromName(ISAXAttributes *iface, const WCHAR * pUri, int nUri,
3017 const WCHAR * pLocalName, int nLocalName, const WCHAR ** pType, int * nType)
3019 mxattributes *This = impl_from_ISAXAttributes( iface );
3020 FIXME("(%p)->(%s:%d %s:%d %p %p): stub\n", This, debugstr_wn(pUri, nUri), nUri,
3021 debugstr_wn(pLocalName, nLocalName), nLocalName, pType, nType);
3022 return E_NOTIMPL;
3025 static HRESULT WINAPI SAXAttributes_getTypeFromQName(ISAXAttributes *iface, const WCHAR * pQName,
3026 int nQName, const WCHAR ** pType, int * nType)
3028 mxattributes *This = impl_from_ISAXAttributes( iface );
3029 FIXME("(%p)->(%s:%d %p %p): stub\n", This, debugstr_wn(pQName, nQName), nQName, pType, nType);
3030 return E_NOTIMPL;
3033 static HRESULT WINAPI SAXAttributes_getValue(ISAXAttributes *iface, int index, const WCHAR **value,
3034 int *len)
3036 mxattributes *This = impl_from_ISAXAttributes( iface );
3038 TRACE("(%p)->(%d %p %p)\n", This, index, value, len);
3040 if (index >= This->length) return E_INVALIDARG;
3042 if ((!value || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3043 return E_POINTER;
3045 *value = This->attr[index].value;
3046 *len = SysStringLen(This->attr[index].value);
3048 return S_OK;
3051 static HRESULT WINAPI SAXAttributes_getValueFromName(ISAXAttributes *iface, const WCHAR *uri,
3052 int uri_len, const WCHAR *name, int name_len, const WCHAR **value, int *value_len)
3054 mxattributes *This = impl_from_ISAXAttributes( iface );
3055 HRESULT hr;
3056 int index;
3058 TRACE("(%p)->(%s:%d %s:%d %p %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
3059 debugstr_wn(name, name_len), name_len, value, value_len);
3061 if (!uri || !name || !value || !value_len)
3062 return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3064 hr = ISAXAttributes_getIndexFromName(iface, uri, uri_len, name, name_len, &index);
3065 if (hr == S_OK)
3066 hr = ISAXAttributes_getValue(iface, index, value, value_len);
3068 return hr;
3071 static HRESULT WINAPI SAXAttributes_getValueFromQName(ISAXAttributes *iface, const WCHAR *qname,
3072 int qname_len, const WCHAR **value, int *value_len)
3074 mxattributes *This = impl_from_ISAXAttributes( iface );
3075 HRESULT hr;
3076 int index;
3078 TRACE("(%p)->(%s:%d %p %p)\n", This, debugstr_wn(qname, qname_len), qname_len, value, value_len);
3080 if (!qname || !value || !value_len)
3081 return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3083 hr = ISAXAttributes_getIndexFromQName(iface, qname, qname_len, &index);
3084 if (hr == S_OK)
3085 hr = ISAXAttributes_getValue(iface, index, value, value_len);
3087 return hr;
3090 static const ISAXAttributesVtbl SAXAttributesVtbl = {
3091 SAXAttributes_QueryInterface,
3092 SAXAttributes_AddRef,
3093 SAXAttributes_Release,
3094 SAXAttributes_getLength,
3095 SAXAttributes_getURI,
3096 SAXAttributes_getLocalName,
3097 SAXAttributes_getQName,
3098 SAXAttributes_getName,
3099 SAXAttributes_getIndexFromName,
3100 SAXAttributes_getIndexFromQName,
3101 SAXAttributes_getType,
3102 SAXAttributes_getTypeFromName,
3103 SAXAttributes_getTypeFromQName,
3104 SAXAttributes_getValue,
3105 SAXAttributes_getValueFromName,
3106 SAXAttributes_getValueFromQName
3109 static HRESULT WINAPI VBSAXAttributes_QueryInterface(
3110 IVBSAXAttributes* iface,
3111 REFIID riid,
3112 void **ppvObject)
3114 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3115 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
3116 return ISAXAttributes_QueryInterface(&This->ISAXAttributes_iface, riid, ppvObject);
3119 static ULONG WINAPI VBSAXAttributes_AddRef(IVBSAXAttributes* iface)
3121 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3122 return ISAXAttributes_AddRef(&This->ISAXAttributes_iface);
3125 static ULONG WINAPI VBSAXAttributes_Release(IVBSAXAttributes* iface)
3127 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3128 return ISAXAttributes_Release(&This->ISAXAttributes_iface);
3131 static HRESULT WINAPI VBSAXAttributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
3133 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3135 TRACE("(%p)->(%p)\n", This, pctinfo);
3137 *pctinfo = 1;
3139 return S_OK;
3142 static HRESULT WINAPI VBSAXAttributes_GetTypeInfo(
3143 IVBSAXAttributes *iface,
3144 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
3146 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3147 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
3148 return get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
3151 static HRESULT WINAPI VBSAXAttributes_GetIDsOfNames(
3152 IVBSAXAttributes *iface,
3153 REFIID riid,
3154 LPOLESTR* rgszNames,
3155 UINT cNames,
3156 LCID lcid,
3157 DISPID* rgDispId)
3159 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3160 ITypeInfo *typeinfo;
3161 HRESULT hr;
3163 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
3164 lcid, rgDispId);
3166 if(!rgszNames || cNames == 0 || !rgDispId)
3167 return E_INVALIDARG;
3169 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
3170 if(SUCCEEDED(hr))
3172 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
3173 ITypeInfo_Release(typeinfo);
3176 return hr;
3179 static HRESULT WINAPI VBSAXAttributes_Invoke(
3180 IVBSAXAttributes *iface,
3181 DISPID dispIdMember,
3182 REFIID riid,
3183 LCID lcid,
3184 WORD wFlags,
3185 DISPPARAMS* pDispParams,
3186 VARIANT* pVarResult,
3187 EXCEPINFO* pExcepInfo,
3188 UINT* puArgErr)
3190 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3191 ITypeInfo *typeinfo;
3192 HRESULT hr;
3194 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
3195 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3197 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
3198 if(SUCCEEDED(hr))
3200 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
3201 pDispParams, pVarResult, pExcepInfo, puArgErr);
3202 ITypeInfo_Release(typeinfo);
3205 return hr;
3208 static HRESULT WINAPI VBSAXAttributes_get_length(IVBSAXAttributes* iface, int *len)
3210 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3211 return ISAXAttributes_getLength(&This->ISAXAttributes_iface, len);
3214 static HRESULT WINAPI VBSAXAttributes_getURI(IVBSAXAttributes* iface, int index, BSTR *uri)
3216 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3217 const WCHAR *uriW;
3218 HRESULT hr;
3219 int len;
3221 TRACE("(%p)->(%d %p)\n", This, index, uri);
3223 if (!uri)
3224 return E_POINTER;
3226 *uri = NULL;
3227 hr = ISAXAttributes_getURI(&This->ISAXAttributes_iface, index, &uriW, &len);
3228 if (FAILED(hr))
3229 return hr;
3231 return return_bstrn(uriW, len, uri);
3234 static HRESULT WINAPI VBSAXAttributes_getLocalName(IVBSAXAttributes* iface, int index, BSTR *name)
3236 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3237 const WCHAR *nameW;
3238 HRESULT hr;
3239 int len;
3241 TRACE("(%p)->(%d %p)\n", This, index, name);
3243 if (!name)
3244 return E_POINTER;
3246 *name = NULL;
3247 hr = ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, index, &nameW, &len);
3248 if (FAILED(hr))
3249 return hr;
3251 return return_bstrn(nameW, len, name);
3254 static HRESULT WINAPI VBSAXAttributes_getQName(IVBSAXAttributes* iface, int index, BSTR *qname)
3256 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3257 const WCHAR *qnameW;
3258 HRESULT hr;
3259 int len;
3261 TRACE("(%p)->(%d %p)\n", This, index, qname);
3263 if (!qname)
3264 return E_POINTER;
3266 *qname = NULL;
3267 hr = ISAXAttributes_getQName(&This->ISAXAttributes_iface, index, &qnameW, &len);
3268 if (FAILED(hr))
3269 return hr;
3271 return return_bstrn(qnameW, len, qname);
3274 static HRESULT WINAPI VBSAXAttributes_getIndexFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name, int *index)
3276 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3277 return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3278 name, SysStringLen(name), index);
3281 static HRESULT WINAPI VBSAXAttributes_getIndexFromQName(IVBSAXAttributes* iface, BSTR qname, int *index)
3283 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3284 return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, qname,
3285 SysStringLen(qname), index);
3288 static HRESULT WINAPI VBSAXAttributes_getType(IVBSAXAttributes* iface, int index, BSTR *type)
3290 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3291 const WCHAR *typeW;
3292 HRESULT hr;
3293 int len;
3295 TRACE("(%p)->(%d %p)\n", This, index, type);
3297 if (!type)
3298 return E_POINTER;
3300 *type = NULL;
3301 hr = ISAXAttributes_getType(&This->ISAXAttributes_iface, index, &typeW, &len);
3302 if (FAILED(hr))
3303 return hr;
3305 return return_bstrn(typeW, len, type);
3308 static HRESULT WINAPI VBSAXAttributes_getTypeFromName(IVBSAXAttributes* iface, BSTR uri,
3309 BSTR name, BSTR *type)
3311 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3312 const WCHAR *typeW;
3313 HRESULT hr;
3314 int len;
3316 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), type);
3318 if (!type)
3319 return E_POINTER;
3321 *type = NULL;
3322 hr = ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3323 name, SysStringLen(name), &typeW, &len);
3324 if (FAILED(hr))
3325 return hr;
3327 return return_bstrn(typeW, len, type);
3330 static HRESULT WINAPI VBSAXAttributes_getTypeFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *type)
3332 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3333 const WCHAR *typeW;
3334 HRESULT hr;
3335 int len;
3337 TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), type);
3339 if (!type)
3340 return E_POINTER;
3342 *type = NULL;
3343 hr = ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3344 &typeW, &len);
3345 if (FAILED(hr))
3346 return hr;
3348 return return_bstrn(typeW, len, type);
3351 static HRESULT WINAPI VBSAXAttributes_getValue(IVBSAXAttributes* iface, int index, BSTR *value)
3353 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3354 const WCHAR *valueW;
3355 HRESULT hr;
3356 int len;
3358 TRACE("(%p)->(%d %p)\n", This, index, value);
3360 if (!value)
3361 return E_POINTER;
3363 *value = NULL;
3364 hr = ISAXAttributes_getValue(&This->ISAXAttributes_iface, index, &valueW, &len);
3365 if (FAILED(hr))
3366 return hr;
3368 return return_bstrn(valueW, len, value);
3371 static HRESULT WINAPI VBSAXAttributes_getValueFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name,
3372 BSTR *value)
3374 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3375 const WCHAR *valueW;
3376 HRESULT hr;
3377 int len;
3379 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), value);
3381 if (!value)
3382 return E_POINTER;
3384 *value = NULL;
3385 hr = ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3386 name, SysStringLen(name), &valueW, &len);
3387 if (FAILED(hr))
3388 return hr;
3390 return return_bstrn(valueW, len, value);
3393 static HRESULT WINAPI VBSAXAttributes_getValueFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *value)
3395 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3396 const WCHAR *valueW;
3397 HRESULT hr;
3398 int len;
3400 TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), value);
3402 if (!value)
3403 return E_POINTER;
3405 *value = NULL;
3406 hr = ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3407 &valueW, &len);
3408 if (FAILED(hr))
3409 return hr;
3411 return return_bstrn(valueW, len, value);
3414 static const struct IVBSAXAttributesVtbl VBSAXAttributesVtbl =
3416 VBSAXAttributes_QueryInterface,
3417 VBSAXAttributes_AddRef,
3418 VBSAXAttributes_Release,
3419 VBSAXAttributes_GetTypeInfoCount,
3420 VBSAXAttributes_GetTypeInfo,
3421 VBSAXAttributes_GetIDsOfNames,
3422 VBSAXAttributes_Invoke,
3423 VBSAXAttributes_get_length,
3424 VBSAXAttributes_getURI,
3425 VBSAXAttributes_getLocalName,
3426 VBSAXAttributes_getQName,
3427 VBSAXAttributes_getIndexFromName,
3428 VBSAXAttributes_getIndexFromQName,
3429 VBSAXAttributes_getType,
3430 VBSAXAttributes_getTypeFromName,
3431 VBSAXAttributes_getTypeFromQName,
3432 VBSAXAttributes_getValue,
3433 VBSAXAttributes_getValueFromName,
3434 VBSAXAttributes_getValueFromQName
3437 static const tid_t mxattrs_iface_tids[] = {
3438 IMXAttributes_tid,
3442 static dispex_static_data_t mxattrs_dispex = {
3443 NULL,
3444 IMXAttributes_tid,
3445 NULL,
3446 mxattrs_iface_tids
3449 HRESULT SAXAttributes_create(MSXML_VERSION version, void **ppObj)
3451 static const int default_count = 10;
3452 mxattributes *This;
3454 TRACE("(%p)\n", ppObj);
3456 This = heap_alloc( sizeof (*This) );
3457 if( !This )
3458 return E_OUTOFMEMORY;
3460 This->IMXAttributes_iface.lpVtbl = &MXAttributesVtbl;
3461 This->ISAXAttributes_iface.lpVtbl = &SAXAttributesVtbl;
3462 This->IVBSAXAttributes_iface.lpVtbl = &VBSAXAttributesVtbl;
3463 This->ref = 1;
3465 This->class_version = version;
3467 This->attr = heap_alloc(default_count*sizeof(mxattribute));
3468 This->length = 0;
3469 This->allocated = default_count;
3471 *ppObj = &This->IMXAttributes_iface;
3473 init_dispex(&This->dispex, (IUnknown*)&This->IMXAttributes_iface, &mxattrs_dispex);
3475 TRACE("returning iface %p\n", *ppObj);
3477 return S_OK;