winegcc: Add entry symbol underscore when building linker command.
[wine.git] / dlls / msxml3 / mxwriter.c
blob029e9aac0d06244186b04f84e8a1c26772458e2d
1 /*
2 * MXWriter implementation
4 * Copyright 2011-2014, 2016 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"
37 #include "wine/list.h"
39 #include "msxml_private.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
43 static const WCHAR emptyW[] = {0};
44 static const WCHAR spaceW[] = {' '};
45 static const WCHAR quotW[] = {'\"'};
46 static const WCHAR closetagW[] = {'>','\r','\n'};
47 static const WCHAR crlfW[] = {'\r','\n'};
48 static const WCHAR entityW[] = {'<','!','E','N','T','I','T','Y',' '};
49 static const WCHAR publicW[] = {'P','U','B','L','I','C',' '};
50 static const WCHAR systemW[] = {'S','Y','S','T','E','M',' '};
52 /* should be ordered as encoding names are sorted */
53 typedef enum
55 XmlEncoding_ISO_8859_1 = 0,
56 XmlEncoding_ISO_8859_13,
57 XmlEncoding_ISO_8859_15,
58 XmlEncoding_ISO_8859_2,
59 XmlEncoding_ISO_8859_3,
60 XmlEncoding_ISO_8859_4,
61 XmlEncoding_ISO_8859_5,
62 XmlEncoding_ISO_8859_7,
63 XmlEncoding_ISO_8859_9,
64 XmlEncoding_UTF16,
65 XmlEncoding_UTF8,
66 XmlEncoding_windows_1250,
67 XmlEncoding_windows_1251,
68 XmlEncoding_windows_1252,
69 XmlEncoding_windows_1253,
70 XmlEncoding_windows_1254,
71 XmlEncoding_windows_1255,
72 XmlEncoding_windows_1256,
73 XmlEncoding_windows_1257,
74 XmlEncoding_windows_1258,
75 XmlEncoding_Unknown
76 } xml_encoding;
78 struct xml_encoding_data
80 const WCHAR *encoding;
81 xml_encoding enc;
82 UINT cp;
85 static const WCHAR iso_8859_1W[] = {'i','s','o','-','8','8','5','9','-','1',0};
86 static const WCHAR iso_8859_2W[] = {'i','s','o','-','8','8','5','9','-','2',0};
87 static const WCHAR iso_8859_3W[] = {'i','s','o','-','8','8','5','9','-','3',0};
88 static const WCHAR iso_8859_4W[] = {'i','s','o','-','8','8','5','9','-','4',0};
89 static const WCHAR iso_8859_5W[] = {'i','s','o','-','8','8','5','9','-','5',0};
90 static const WCHAR iso_8859_7W[] = {'i','s','o','-','8','8','5','9','-','7',0};
91 static const WCHAR iso_8859_9W[] = {'i','s','o','-','8','8','5','9','-','9',0};
92 static const WCHAR iso_8859_13W[] = {'i','s','o','-','8','8','5','9','-','1','3',0};
93 static const WCHAR iso_8859_15W[] = {'i','s','o','-','8','8','5','9','-','1','5',0};
94 static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
95 static const WCHAR utf8W[] = {'U','T','F','-','8',0};
96 static const WCHAR windows_1250W[] = {'w','i','n','d','o','w','s','-','1','2','5','0',0};
97 static const WCHAR windows_1251W[] = {'w','i','n','d','o','w','s','-','1','2','5','1',0};
98 static const WCHAR windows_1252W[] = {'w','i','n','d','o','w','s','-','1','2','5','2',0};
99 static const WCHAR windows_1253W[] = {'w','i','n','d','o','w','s','-','1','2','5','3',0};
100 static const WCHAR windows_1254W[] = {'w','i','n','d','o','w','s','-','1','2','5','4',0};
101 static const WCHAR windows_1255W[] = {'w','i','n','d','o','w','s','-','1','2','5','5',0};
102 static const WCHAR windows_1256W[] = {'w','i','n','d','o','w','s','-','1','2','5','6',0};
103 static const WCHAR windows_1257W[] = {'w','i','n','d','o','w','s','-','1','2','5','7',0};
104 static const WCHAR windows_1258W[] = {'w','i','n','d','o','w','s','-','1','2','5','8',0};
106 static const struct xml_encoding_data xml_encoding_map[] = {
107 { iso_8859_1W, XmlEncoding_ISO_8859_1, 28591 },
108 { iso_8859_13W, XmlEncoding_ISO_8859_13, 28603 },
109 { iso_8859_15W, XmlEncoding_ISO_8859_15, 28605 },
110 { iso_8859_2W, XmlEncoding_ISO_8859_2, 28592 },
111 { iso_8859_3W, XmlEncoding_ISO_8859_3, 28593 },
112 { iso_8859_4W, XmlEncoding_ISO_8859_4, 28594 },
113 { iso_8859_5W, XmlEncoding_ISO_8859_5, 28595 },
114 { iso_8859_7W, XmlEncoding_ISO_8859_7, 28597 },
115 { iso_8859_9W, XmlEncoding_ISO_8859_9, 28599 },
116 { utf16W, XmlEncoding_UTF16, ~0 },
117 { utf8W, XmlEncoding_UTF8, CP_UTF8 },
118 { windows_1250W,XmlEncoding_windows_1250, 1250 },
119 { windows_1251W,XmlEncoding_windows_1251, 1251 },
120 { windows_1252W,XmlEncoding_windows_1252, 1252 },
121 { windows_1253W,XmlEncoding_windows_1253, 1253 },
122 { windows_1254W,XmlEncoding_windows_1254, 1254 },
123 { windows_1255W,XmlEncoding_windows_1255, 1255 },
124 { windows_1256W,XmlEncoding_windows_1256, 1256 },
125 { windows_1257W,XmlEncoding_windows_1257, 1257 },
126 { windows_1258W,XmlEncoding_windows_1258, 1258 }
129 typedef enum
131 MXWriter_BOM = 0,
132 MXWriter_DisableEscaping,
133 MXWriter_Indent,
134 MXWriter_OmitXmlDecl,
135 MXWriter_Standalone,
136 MXWriter_LastProp
137 } mxwriter_prop;
139 typedef enum
141 EscapeValue,
142 EscapeText
143 } escape_mode;
145 typedef struct
147 struct list entry;
148 char *data;
149 unsigned int allocated;
150 unsigned int written;
151 } encoded_buffer;
153 typedef struct
155 encoded_buffer encoded;
156 UINT code_page;
157 UINT utf16_total; /* total number of bytes written since last buffer reinitialization */
158 struct list blocks; /* only used when output was not set, for BSTR case */
159 } output_buffer;
161 typedef struct
163 DispatchEx dispex;
164 IMXWriter IMXWriter_iface;
165 ISAXContentHandler ISAXContentHandler_iface;
166 ISAXLexicalHandler ISAXLexicalHandler_iface;
167 ISAXDeclHandler ISAXDeclHandler_iface;
168 ISAXDTDHandler ISAXDTDHandler_iface;
169 ISAXErrorHandler ISAXErrorHandler_iface;
170 IVBSAXDeclHandler IVBSAXDeclHandler_iface;
171 IVBSAXLexicalHandler IVBSAXLexicalHandler_iface;
172 IVBSAXContentHandler IVBSAXContentHandler_iface;
173 IVBSAXDTDHandler IVBSAXDTDHandler_iface;
174 IVBSAXErrorHandler IVBSAXErrorHandler_iface;
176 LONG ref;
177 MSXML_VERSION class_version;
179 VARIANT_BOOL props[MXWriter_LastProp];
180 BOOL prop_changed;
181 BOOL cdata;
183 BOOL text; /* last node was text node, so we shouldn't indent next node */
184 BOOL newline; /* newline was already added as a part of previous call */
185 UINT indent; /* indentation level for next node */
187 BSTR version;
189 BSTR encoding; /* exact property value */
190 xml_encoding xml_enc;
192 /* contains a pending (or not closed yet) element name or NULL if
193 we don't have to close */
194 BSTR element;
196 IStream *dest;
198 output_buffer buffer;
199 } mxwriter;
201 typedef struct
203 BSTR qname;
204 BSTR local;
205 BSTR uri;
206 BSTR type;
207 BSTR value;
208 } mxattribute;
210 typedef struct
212 DispatchEx dispex;
213 IMXAttributes IMXAttributes_iface;
214 ISAXAttributes ISAXAttributes_iface;
215 IVBSAXAttributes IVBSAXAttributes_iface;
216 LONG ref;
218 MSXML_VERSION class_version;
220 mxattribute *attr;
221 int length;
222 int allocated;
223 } mxattributes;
225 static inline mxattributes *impl_from_IMXAttributes( IMXAttributes *iface )
227 return CONTAINING_RECORD(iface, mxattributes, IMXAttributes_iface);
230 static inline mxattributes *impl_from_ISAXAttributes( ISAXAttributes *iface )
232 return CONTAINING_RECORD(iface, mxattributes, ISAXAttributes_iface);
235 static inline mxattributes *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
237 return CONTAINING_RECORD(iface, mxattributes, IVBSAXAttributes_iface);
240 static HRESULT mxattributes_grow(mxattributes *This)
242 if (This->length < This->allocated) return S_OK;
244 This->allocated *= 2;
245 This->attr = heap_realloc(This->attr, This->allocated*sizeof(mxattribute));
247 return This->attr ? S_OK : E_OUTOFMEMORY;
250 static xml_encoding parse_encoding_name(const WCHAR *encoding)
252 int min, max, n, c;
254 min = 0;
255 max = ARRAY_SIZE(xml_encoding_map) - 1;
257 while (min <= max)
259 n = (min+max)/2;
261 c = strcmpiW(xml_encoding_map[n].encoding, encoding);
262 if (!c)
263 return xml_encoding_map[n].enc;
265 if (c > 0)
266 max = n-1;
267 else
268 min = n+1;
271 return XmlEncoding_Unknown;
274 static HRESULT init_encoded_buffer(encoded_buffer *buffer)
276 const int initial_len = 0x1000;
277 buffer->data = heap_alloc(initial_len);
278 if (!buffer->data) return E_OUTOFMEMORY;
280 memset(buffer->data, 0, 4);
281 buffer->allocated = initial_len;
282 buffer->written = 0;
284 return S_OK;
287 static void free_encoded_buffer(encoded_buffer *buffer)
289 heap_free(buffer->data);
292 static HRESULT get_code_page(xml_encoding encoding, UINT *cp)
294 const struct xml_encoding_data *data;
296 if (encoding == XmlEncoding_Unknown)
298 FIXME("unsupported encoding %d\n", encoding);
299 return E_NOTIMPL;
302 data = &xml_encoding_map[encoding];
303 *cp = data->cp;
305 return S_OK;
308 static HRESULT init_output_buffer(xml_encoding encoding, output_buffer *buffer)
310 HRESULT hr;
312 hr = get_code_page(encoding, &buffer->code_page);
313 if (hr != S_OK)
314 return hr;
316 hr = init_encoded_buffer(&buffer->encoded);
317 if (hr != S_OK)
318 return hr;
320 list_init(&buffer->blocks);
321 buffer->utf16_total = 0;
323 return S_OK;
326 static void free_output_buffer(output_buffer *buffer)
328 encoded_buffer *cur, *cur2;
330 free_encoded_buffer(&buffer->encoded);
332 LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &buffer->blocks, encoded_buffer, entry)
334 list_remove(&cur->entry);
335 free_encoded_buffer(cur);
336 heap_free(cur);
340 static HRESULT write_output_buffer(mxwriter *writer, const WCHAR *data, int len)
342 output_buffer *buffer = &writer->buffer;
343 encoded_buffer *buff;
344 unsigned int written;
345 int src_len;
347 if (!len || !*data)
348 return S_OK;
350 src_len = len == -1 ? strlenW(data) : len;
351 if (writer->dest)
353 buff = &buffer->encoded;
355 if (buffer->code_page == ~0)
357 unsigned int avail = buff->allocated - buff->written;
359 src_len *= sizeof(WCHAR);
360 written = min(avail, src_len);
362 /* fill internal buffer first */
363 if (avail)
365 memcpy(buff->data + buff->written, data, written);
366 data += written / sizeof(WCHAR);
367 buff->written += written;
368 avail -= written;
369 src_len -= written;
372 if (!avail)
374 IStream_Write(writer->dest, buff->data, buff->written, &written);
375 buff->written = 0;
376 if (src_len >= buff->allocated)
377 IStream_Write(writer->dest, data, src_len, &written);
378 else if (src_len)
380 memcpy(buff->data, data, src_len);
381 buff->written += src_len;
385 else
387 unsigned int avail = buff->allocated - buff->written;
388 int length;
390 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, NULL, 0, NULL, NULL);
391 if (avail >= length)
393 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, buff->data + buff->written, length, NULL, NULL);
394 buff->written += length;
396 else
398 /* drain what we go so far */
399 if (buff->written)
401 IStream_Write(writer->dest, buff->data, buff->written, &written);
402 buff->written = 0;
403 avail = buff->allocated;
406 if (avail >= length)
408 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, buff->data + buff->written, length, NULL, NULL);
409 buff->written += length;
411 else
413 char *mb;
415 /* if current chunk is larger than total buffer size, convert it at once using temporary allocated buffer */
416 mb = heap_alloc(length);
417 if (!mb)
418 return E_OUTOFMEMORY;
420 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, mb, length, NULL, NULL);
421 IStream_Write(writer->dest, mb, length, &written);
422 heap_free(mb);
427 /* When writer has no output set we have to accumulate everything to return it later in a form of BSTR.
428 To achieve that:
430 - fill a buffer already allocated as part of output buffer;
431 - when current buffer is full, allocate another one and switch to it; buffers themselves never grow,
432 but are linked together, with head pointing to first allocated buffer after initial one got filled;
433 - later during get_output() contents are concatenated by copying one after another to destination BSTR buffer,
434 that's returned to the client. */
435 else
437 /* select last used block */
438 if (list_empty(&buffer->blocks))
439 buff = &buffer->encoded;
440 else
441 buff = LIST_ENTRY(list_tail(&buffer->blocks), encoded_buffer, entry);
443 src_len *= sizeof(WCHAR);
444 while (src_len)
446 unsigned int avail = buff->allocated - buff->written;
447 unsigned int written = min(avail, src_len);
449 if (avail)
451 memcpy(buff->data + buff->written, data, written);
452 buff->written += written;
453 buffer->utf16_total += written;
454 src_len -= written;
457 /* alloc new block if needed and retry */
458 if (src_len)
460 encoded_buffer *next = heap_alloc(sizeof(*next));
461 HRESULT hr;
463 if (FAILED(hr = init_encoded_buffer(next))) {
464 heap_free(next);
465 return hr;
468 list_add_tail(&buffer->blocks, &next->entry);
469 buff = next;
474 return S_OK;
477 static HRESULT write_output_buffer_quoted(mxwriter *writer, const WCHAR *data, int len)
479 write_output_buffer(writer, quotW, 1);
480 write_output_buffer(writer, data, len);
481 write_output_buffer(writer, quotW, 1);
483 return S_OK;
486 /* frees buffer data, reallocates with a default lengths */
487 static void close_output_buffer(mxwriter *writer)
489 encoded_buffer *cur, *cur2;
491 heap_free(writer->buffer.encoded.data);
493 LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &writer->buffer.blocks, encoded_buffer, entry)
495 list_remove(&cur->entry);
496 free_encoded_buffer(cur);
497 heap_free(cur);
500 init_encoded_buffer(&writer->buffer.encoded);
501 get_code_page(writer->xml_enc, &writer->buffer.code_page);
502 writer->buffer.utf16_total = 0;
503 list_init(&writer->buffer.blocks);
506 /* Escapes special characters like:
507 '<' -> "&lt;"
508 '&' -> "&amp;"
509 '"' -> "&quot;"
510 '>' -> "&gt;"
512 On call 'len' contains a length of 'str' in chars or -1 if it's null terminated.
513 After a call it's updated with actual new length if it wasn't -1 initially.
515 static WCHAR *get_escaped_string(const WCHAR *str, escape_mode mode, int *len)
517 static const WCHAR ltW[] = {'&','l','t',';'};
518 static const WCHAR ampW[] = {'&','a','m','p',';'};
519 static const WCHAR equotW[] = {'&','q','u','o','t',';'};
520 static const WCHAR gtW[] = {'&','g','t',';'};
522 const int default_alloc = 100;
523 const int grow_thresh = 10;
524 int p = *len, conv_len;
525 WCHAR *ptr, *ret;
527 /* default buffer size to something if length is unknown */
528 conv_len = max(2**len, default_alloc);
529 ptr = ret = heap_alloc(conv_len*sizeof(WCHAR));
531 while (p)
533 if (ptr - ret > conv_len - grow_thresh)
535 int written = ptr - ret;
536 conv_len *= 2;
537 ptr = ret = heap_realloc(ret, conv_len*sizeof(WCHAR));
538 ptr += written;
541 switch (*str)
543 case '<':
544 memcpy(ptr, ltW, sizeof(ltW));
545 ptr += ARRAY_SIZE(ltW);
546 break;
547 case '&':
548 memcpy(ptr, ampW, sizeof(ampW));
549 ptr += ARRAY_SIZE(ampW);
550 break;
551 case '>':
552 memcpy(ptr, gtW, sizeof(gtW));
553 ptr += ARRAY_SIZE(gtW);
554 break;
555 case '"':
556 if (mode == EscapeValue)
558 memcpy(ptr, equotW, sizeof(equotW));
559 ptr += ARRAY_SIZE(equotW);
560 break;
562 /* fallthrough for text mode */
563 default:
564 *ptr++ = *str;
565 break;
568 str++;
569 p--;
572 *len = ptr-ret;
573 *++ptr = 0;
575 return ret;
578 static void write_prolog_buffer(mxwriter *writer)
580 static const WCHAR versionW[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','='};
581 static const WCHAR encodingW[] = {' ','e','n','c','o','d','i','n','g','=','\"'};
582 static const WCHAR standaloneW[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
583 static const WCHAR yesW[] = {'y','e','s','\"','?','>'};
584 static const WCHAR noW[] = {'n','o','\"','?','>'};
586 /* version */
587 write_output_buffer(writer, versionW, ARRAY_SIZE(versionW));
588 write_output_buffer_quoted(writer, writer->version, -1);
590 /* encoding */
591 write_output_buffer(writer, encodingW, ARRAY_SIZE(encodingW));
593 if (writer->dest)
594 write_output_buffer(writer, writer->encoding, -1);
595 else
596 write_output_buffer(writer, utf16W, ARRAY_SIZE(utf16W) - 1);
597 write_output_buffer(writer, quotW, 1);
599 /* standalone */
600 write_output_buffer(writer, standaloneW, ARRAY_SIZE(standaloneW));
601 if (writer->props[MXWriter_Standalone] == VARIANT_TRUE)
602 write_output_buffer(writer, yesW, ARRAY_SIZE(yesW));
603 else
604 write_output_buffer(writer, noW, ARRAY_SIZE(noW));
606 write_output_buffer(writer, crlfW, ARRAY_SIZE(crlfW));
607 writer->newline = TRUE;
610 /* Attempts to the write data from the mxwriter's buffer to
611 * the destination stream (if there is one).
613 static HRESULT write_data_to_stream(mxwriter *writer)
615 encoded_buffer *buffer = &writer->buffer.encoded;
616 ULONG written = 0;
618 if (!writer->dest)
619 return S_OK;
621 if (buffer->written == 0)
623 if (writer->xml_enc == XmlEncoding_UTF8)
624 IStream_Write(writer->dest, buffer->data, 0, &written);
626 else
628 IStream_Write(writer->dest, buffer->data, buffer->written, &written);
629 buffer->written = 0;
632 return S_OK;
635 /* Newly added element start tag left unclosed cause for empty elements
636 we have to close it differently. */
637 static void close_element_starttag(mxwriter *writer)
639 static const WCHAR gtW[] = {'>'};
640 if (!writer->element) return;
641 write_output_buffer(writer, gtW, 1);
644 static void write_node_indent(mxwriter *writer)
646 static const WCHAR tabW[] = {'\t'};
647 int indent = writer->indent;
649 if (!writer->props[MXWriter_Indent] || writer->text)
651 writer->text = FALSE;
652 return;
655 /* This is to workaround PI output logic that always puts newline chars,
656 document prolog PI does that too. */
657 if (!writer->newline)
658 write_output_buffer(writer, crlfW, ARRAY_SIZE(crlfW));
659 while (indent--)
660 write_output_buffer(writer, tabW, 1);
662 writer->newline = FALSE;
663 writer->text = FALSE;
666 static inline void writer_inc_indent(mxwriter *This)
668 This->indent++;
671 static inline void writer_dec_indent(mxwriter *This)
673 if (This->indent) This->indent--;
674 /* depth is decreased only when element is closed, meaning it's not a text node
675 at this point */
676 This->text = FALSE;
679 static void set_element_name(mxwriter *This, const WCHAR *name, int len)
681 SysFreeString(This->element);
682 if (name)
683 This->element = len != -1 ? SysAllocStringLen(name, len) : SysAllocString(name);
684 else
685 This->element = NULL;
688 static inline HRESULT flush_output_buffer(mxwriter *This)
690 close_element_starttag(This);
691 set_element_name(This, NULL, 0);
692 This->cdata = FALSE;
693 return write_data_to_stream(This);
696 /* Resets the mxwriter's output buffer by closing it, then creating a new
697 * output buffer using the given encoding.
699 static inline void reset_output_buffer(mxwriter *This)
701 close_output_buffer(This);
704 static HRESULT writer_set_property(mxwriter *writer, mxwriter_prop property, VARIANT_BOOL value)
706 writer->props[property] = value;
707 writer->prop_changed = TRUE;
708 return S_OK;
711 static HRESULT writer_get_property(const mxwriter *writer, mxwriter_prop property, VARIANT_BOOL *value)
713 if (!value) return E_POINTER;
714 *value = writer->props[property];
715 return S_OK;
718 static inline mxwriter *impl_from_IMXWriter(IMXWriter *iface)
720 return CONTAINING_RECORD(iface, mxwriter, IMXWriter_iface);
723 static inline mxwriter *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
725 return CONTAINING_RECORD(iface, mxwriter, ISAXContentHandler_iface);
728 static inline mxwriter *impl_from_IVBSAXContentHandler(IVBSAXContentHandler *iface)
730 return CONTAINING_RECORD(iface, mxwriter, IVBSAXContentHandler_iface);
733 static inline mxwriter *impl_from_ISAXLexicalHandler(ISAXLexicalHandler *iface)
735 return CONTAINING_RECORD(iface, mxwriter, ISAXLexicalHandler_iface);
738 static inline mxwriter *impl_from_IVBSAXLexicalHandler(IVBSAXLexicalHandler *iface)
740 return CONTAINING_RECORD(iface, mxwriter, IVBSAXLexicalHandler_iface);
743 static inline mxwriter *impl_from_ISAXDeclHandler(ISAXDeclHandler *iface)
745 return CONTAINING_RECORD(iface, mxwriter, ISAXDeclHandler_iface);
748 static inline mxwriter *impl_from_IVBSAXDeclHandler(IVBSAXDeclHandler *iface)
750 return CONTAINING_RECORD(iface, mxwriter, IVBSAXDeclHandler_iface);
753 static inline mxwriter *impl_from_ISAXDTDHandler(ISAXDTDHandler *iface)
755 return CONTAINING_RECORD(iface, mxwriter, ISAXDTDHandler_iface);
758 static inline mxwriter *impl_from_IVBSAXDTDHandler(IVBSAXDTDHandler *iface)
760 return CONTAINING_RECORD(iface, mxwriter, IVBSAXDTDHandler_iface);
763 static inline mxwriter *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
765 return CONTAINING_RECORD(iface, mxwriter, ISAXErrorHandler_iface);
768 static inline mxwriter *impl_from_IVBSAXErrorHandler(IVBSAXErrorHandler *iface)
770 return CONTAINING_RECORD(iface, mxwriter, IVBSAXErrorHandler_iface);
773 static HRESULT WINAPI mxwriter_QueryInterface(IMXWriter *iface, REFIID riid, void **obj)
775 mxwriter *This = impl_from_IMXWriter( iface );
777 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
779 *obj = NULL;
781 if ( IsEqualGUID( riid, &IID_IMXWriter ) ||
782 IsEqualGUID( riid, &IID_IDispatch ) ||
783 IsEqualGUID( riid, &IID_IUnknown ) )
785 *obj = &This->IMXWriter_iface;
787 else if ( IsEqualGUID( riid, &IID_ISAXContentHandler ) )
789 *obj = &This->ISAXContentHandler_iface;
791 else if ( IsEqualGUID( riid, &IID_ISAXLexicalHandler ) )
793 *obj = &This->ISAXLexicalHandler_iface;
795 else if ( IsEqualGUID( riid, &IID_ISAXDeclHandler ) )
797 *obj = &This->ISAXDeclHandler_iface;
799 else if ( IsEqualGUID( riid, &IID_ISAXDTDHandler ) )
801 *obj = &This->ISAXDTDHandler_iface;
803 else if ( IsEqualGUID( riid, &IID_ISAXErrorHandler ) )
805 *obj = &This->ISAXErrorHandler_iface;
807 else if ( IsEqualGUID( riid, &IID_IVBSAXDeclHandler ) )
809 *obj = &This->IVBSAXDeclHandler_iface;
811 else if ( IsEqualGUID( riid, &IID_IVBSAXLexicalHandler ) )
813 *obj = &This->IVBSAXLexicalHandler_iface;
815 else if ( IsEqualGUID( riid, &IID_IVBSAXContentHandler ) )
817 *obj = &This->IVBSAXContentHandler_iface;
819 else if ( IsEqualGUID( riid, &IID_IVBSAXDTDHandler ) )
821 *obj = &This->IVBSAXDTDHandler_iface;
823 else if ( IsEqualGUID( riid, &IID_IVBSAXErrorHandler ) )
825 *obj = &This->IVBSAXErrorHandler_iface;
827 else if (dispex_query_interface(&This->dispex, riid, obj))
829 return *obj ? S_OK : E_NOINTERFACE;
831 else
833 ERR("interface %s not implemented\n", debugstr_guid(riid));
834 *obj = NULL;
835 return E_NOINTERFACE;
838 IMXWriter_AddRef(iface);
839 return S_OK;
842 static ULONG WINAPI mxwriter_AddRef(IMXWriter *iface)
844 mxwriter *This = impl_from_IMXWriter( iface );
845 LONG ref = InterlockedIncrement(&This->ref);
847 TRACE("(%p)->(%d)\n", This, ref);
849 return ref;
852 static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
854 mxwriter *This = impl_from_IMXWriter( iface );
855 ULONG ref = InterlockedDecrement(&This->ref);
857 TRACE("(%p)->(%d)\n", This, ref);
859 if(!ref)
861 /* Windows flushes the buffer when the interface is destroyed. */
862 flush_output_buffer(This);
863 free_output_buffer(&This->buffer);
865 if (This->dest) IStream_Release(This->dest);
866 SysFreeString(This->version);
867 SysFreeString(This->encoding);
869 SysFreeString(This->element);
870 heap_free(This);
873 return ref;
876 static HRESULT WINAPI mxwriter_GetTypeInfoCount(IMXWriter *iface, UINT* pctinfo)
878 mxwriter *This = impl_from_IMXWriter( iface );
879 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
882 static HRESULT WINAPI mxwriter_GetTypeInfo(
883 IMXWriter *iface,
884 UINT iTInfo, LCID lcid,
885 ITypeInfo** ppTInfo )
887 mxwriter *This = impl_from_IMXWriter( iface );
888 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
889 iTInfo, lcid, ppTInfo);
892 static HRESULT WINAPI mxwriter_GetIDsOfNames(
893 IMXWriter *iface,
894 REFIID riid, LPOLESTR* rgszNames,
895 UINT cNames, LCID lcid, DISPID* rgDispId )
897 mxwriter *This = impl_from_IMXWriter( iface );
898 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
899 riid, rgszNames, cNames, lcid, rgDispId);
902 static HRESULT WINAPI mxwriter_Invoke(
903 IMXWriter *iface,
904 DISPID dispIdMember, REFIID riid, LCID lcid,
905 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
906 EXCEPINFO* pExcepInfo, UINT* puArgErr )
908 mxwriter *This = impl_from_IMXWriter( iface );
909 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
910 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
913 static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
915 mxwriter *This = impl_from_IMXWriter( iface );
916 HRESULT hr;
918 TRACE("(%p)->(%s)\n", This, debugstr_variant(&dest));
920 hr = flush_output_buffer(This);
921 if (FAILED(hr))
922 return hr;
924 switch (V_VT(&dest))
926 case VT_EMPTY:
928 if (This->dest) IStream_Release(This->dest);
929 This->dest = NULL;
930 reset_output_buffer(This);
931 break;
933 case VT_UNKNOWN:
935 IStream *stream;
937 hr = IUnknown_QueryInterface(V_UNKNOWN(&dest), &IID_IStream, (void**)&stream);
938 if (hr == S_OK)
940 /* Recreate the output buffer to make sure it's using the correct encoding. */
941 reset_output_buffer(This);
943 if (This->dest) IStream_Release(This->dest);
944 This->dest = stream;
945 break;
948 FIXME("unhandled interface type for VT_UNKNOWN destination\n");
949 return E_NOTIMPL;
951 default:
952 FIXME("unhandled destination type %s\n", debugstr_variant(&dest));
953 return E_NOTIMPL;
956 return S_OK;
959 static HRESULT WINAPI mxwriter_get_output(IMXWriter *iface, VARIANT *dest)
961 mxwriter *This = impl_from_IMXWriter( iface );
963 TRACE("(%p)->(%p)\n", This, dest);
965 if (!dest) return E_POINTER;
967 if (This->dest)
969 /* we only support IStream output so far */
970 V_VT(dest) = VT_UNKNOWN;
971 V_UNKNOWN(dest) = (IUnknown*)This->dest;
972 IStream_AddRef(This->dest);
974 else
976 encoded_buffer *buff;
977 char *dest_ptr;
978 HRESULT hr;
980 hr = flush_output_buffer(This);
981 if (FAILED(hr))
982 return hr;
984 V_VT(dest) = VT_BSTR;
985 V_BSTR(dest) = SysAllocStringLen(NULL, This->buffer.utf16_total / sizeof(WCHAR));
986 if (!V_BSTR(dest))
987 return E_OUTOFMEMORY;
989 dest_ptr = (char*)V_BSTR(dest);
990 buff = &This->buffer.encoded;
992 if (buff->written)
994 memcpy(dest_ptr, buff->data, buff->written);
995 dest_ptr += buff->written;
998 LIST_FOR_EACH_ENTRY(buff, &This->buffer.blocks, encoded_buffer, entry)
1000 memcpy(dest_ptr, buff->data, buff->written);
1001 dest_ptr += buff->written;
1005 return S_OK;
1008 static HRESULT WINAPI mxwriter_put_encoding(IMXWriter *iface, BSTR encoding)
1010 mxwriter *This = impl_from_IMXWriter( iface );
1011 xml_encoding enc;
1012 HRESULT hr;
1014 TRACE("(%p)->(%s)\n", This, debugstr_w(encoding));
1016 enc = parse_encoding_name(encoding);
1017 if (enc == XmlEncoding_Unknown)
1019 FIXME("unsupported encoding %s\n", debugstr_w(encoding));
1020 return E_INVALIDARG;
1023 hr = flush_output_buffer(This);
1024 if (FAILED(hr))
1025 return hr;
1027 SysReAllocString(&This->encoding, encoding);
1028 This->xml_enc = enc;
1030 TRACE("got encoding %d\n", This->xml_enc);
1031 reset_output_buffer(This);
1032 return S_OK;
1035 static HRESULT WINAPI mxwriter_get_encoding(IMXWriter *iface, BSTR *encoding)
1037 mxwriter *This = impl_from_IMXWriter( iface );
1039 TRACE("(%p)->(%p)\n", This, encoding);
1041 if (!encoding) return E_POINTER;
1043 *encoding = SysAllocString(This->encoding);
1044 if (!*encoding) return E_OUTOFMEMORY;
1046 return S_OK;
1049 static HRESULT WINAPI mxwriter_put_byteOrderMark(IMXWriter *iface, VARIANT_BOOL value)
1051 mxwriter *This = impl_from_IMXWriter( iface );
1053 TRACE("(%p)->(%d)\n", This, value);
1054 return writer_set_property(This, MXWriter_BOM, value);
1057 static HRESULT WINAPI mxwriter_get_byteOrderMark(IMXWriter *iface, VARIANT_BOOL *value)
1059 mxwriter *This = impl_from_IMXWriter( iface );
1061 TRACE("(%p)->(%p)\n", This, value);
1062 return writer_get_property(This, MXWriter_BOM, value);
1065 static HRESULT WINAPI mxwriter_put_indent(IMXWriter *iface, VARIANT_BOOL value)
1067 mxwriter *This = impl_from_IMXWriter( iface );
1069 TRACE("(%p)->(%d)\n", This, value);
1070 return writer_set_property(This, MXWriter_Indent, value);
1073 static HRESULT WINAPI mxwriter_get_indent(IMXWriter *iface, VARIANT_BOOL *value)
1075 mxwriter *This = impl_from_IMXWriter( iface );
1077 TRACE("(%p)->(%p)\n", This, value);
1078 return writer_get_property(This, MXWriter_Indent, value);
1081 static HRESULT WINAPI mxwriter_put_standalone(IMXWriter *iface, VARIANT_BOOL value)
1083 mxwriter *This = impl_from_IMXWriter( iface );
1085 TRACE("(%p)->(%d)\n", This, value);
1086 return writer_set_property(This, MXWriter_Standalone, value);
1089 static HRESULT WINAPI mxwriter_get_standalone(IMXWriter *iface, VARIANT_BOOL *value)
1091 mxwriter *This = impl_from_IMXWriter( iface );
1093 TRACE("(%p)->(%p)\n", This, value);
1094 return writer_get_property(This, MXWriter_Standalone, value);
1097 static HRESULT WINAPI mxwriter_put_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL value)
1099 mxwriter *This = impl_from_IMXWriter( iface );
1101 TRACE("(%p)->(%d)\n", This, value);
1102 return writer_set_property(This, MXWriter_OmitXmlDecl, value);
1105 static HRESULT WINAPI mxwriter_get_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL *value)
1107 mxwriter *This = impl_from_IMXWriter( iface );
1109 TRACE("(%p)->(%p)\n", This, value);
1110 return writer_get_property(This, MXWriter_OmitXmlDecl, value);
1113 static HRESULT WINAPI mxwriter_put_version(IMXWriter *iface, BSTR version)
1115 mxwriter *This = impl_from_IMXWriter( iface );
1117 TRACE("(%p)->(%s)\n", This, debugstr_w(version));
1119 if (!version) return E_INVALIDARG;
1121 SysFreeString(This->version);
1122 This->version = SysAllocString(version);
1124 return S_OK;
1127 static HRESULT WINAPI mxwriter_get_version(IMXWriter *iface, BSTR *version)
1129 mxwriter *This = impl_from_IMXWriter( iface );
1131 TRACE("(%p)->(%p)\n", This, version);
1133 if (!version) return E_POINTER;
1135 return return_bstr(This->version, version);
1138 static HRESULT WINAPI mxwriter_put_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL value)
1140 mxwriter *This = impl_from_IMXWriter( iface );
1142 TRACE("(%p)->(%d)\n", This, value);
1143 return writer_set_property(This, MXWriter_DisableEscaping, value);
1146 static HRESULT WINAPI mxwriter_get_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL *value)
1148 mxwriter *This = impl_from_IMXWriter( iface );
1150 TRACE("(%p)->(%p)\n", This, value);
1151 return writer_get_property(This, MXWriter_DisableEscaping, value);
1154 static HRESULT WINAPI mxwriter_flush(IMXWriter *iface)
1156 mxwriter *This = impl_from_IMXWriter( iface );
1157 TRACE("(%p)\n", This);
1158 return flush_output_buffer(This);
1161 static const struct IMXWriterVtbl MXWriterVtbl =
1163 mxwriter_QueryInterface,
1164 mxwriter_AddRef,
1165 mxwriter_Release,
1166 mxwriter_GetTypeInfoCount,
1167 mxwriter_GetTypeInfo,
1168 mxwriter_GetIDsOfNames,
1169 mxwriter_Invoke,
1170 mxwriter_put_output,
1171 mxwriter_get_output,
1172 mxwriter_put_encoding,
1173 mxwriter_get_encoding,
1174 mxwriter_put_byteOrderMark,
1175 mxwriter_get_byteOrderMark,
1176 mxwriter_put_indent,
1177 mxwriter_get_indent,
1178 mxwriter_put_standalone,
1179 mxwriter_get_standalone,
1180 mxwriter_put_omitXMLDeclaration,
1181 mxwriter_get_omitXMLDeclaration,
1182 mxwriter_put_version,
1183 mxwriter_get_version,
1184 mxwriter_put_disableOutputEscaping,
1185 mxwriter_get_disableOutputEscaping,
1186 mxwriter_flush
1189 /*** ISAXContentHandler ***/
1190 static HRESULT WINAPI SAXContentHandler_QueryInterface(
1191 ISAXContentHandler *iface,
1192 REFIID riid,
1193 void **obj)
1195 mxwriter *This = impl_from_ISAXContentHandler( iface );
1196 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1199 static ULONG WINAPI SAXContentHandler_AddRef(ISAXContentHandler *iface)
1201 mxwriter *This = impl_from_ISAXContentHandler( iface );
1202 return IMXWriter_AddRef(&This->IMXWriter_iface);
1205 static ULONG WINAPI SAXContentHandler_Release(ISAXContentHandler *iface)
1207 mxwriter *This = impl_from_ISAXContentHandler( iface );
1208 return IMXWriter_Release(&This->IMXWriter_iface);
1211 static HRESULT WINAPI SAXContentHandler_putDocumentLocator(
1212 ISAXContentHandler *iface,
1213 ISAXLocator *locator)
1215 mxwriter *This = impl_from_ISAXContentHandler( iface );
1216 FIXME("(%p)->(%p)\n", This, locator);
1217 return E_NOTIMPL;
1220 static HRESULT WINAPI SAXContentHandler_startDocument(ISAXContentHandler *iface)
1222 mxwriter *This = impl_from_ISAXContentHandler( iface );
1224 TRACE("(%p)\n", This);
1226 /* If properties have been changed since the last "endDocument" call
1227 * we need to reset the output buffer. If we don't the output buffer
1228 * could end up with multiple XML documents in it, plus this seems to
1229 * be how Windows works.
1231 if (This->prop_changed) {
1232 reset_output_buffer(This);
1233 This->prop_changed = FALSE;
1236 if (This->props[MXWriter_OmitXmlDecl] == VARIANT_TRUE) return S_OK;
1238 write_prolog_buffer(This);
1240 if (This->dest && This->xml_enc == XmlEncoding_UTF16) {
1241 static const char utf16BOM[] = {0xff,0xfe};
1243 if (This->props[MXWriter_BOM] == VARIANT_TRUE)
1244 /* Windows passes a NULL pointer as the pcbWritten parameter and
1245 * ignores any error codes returned from this Write call.
1247 IStream_Write(This->dest, utf16BOM, sizeof(utf16BOM), NULL);
1250 return S_OK;
1253 static HRESULT WINAPI SAXContentHandler_endDocument(ISAXContentHandler *iface)
1255 mxwriter *This = impl_from_ISAXContentHandler( iface );
1256 TRACE("(%p)\n", This);
1257 This->prop_changed = FALSE;
1258 return flush_output_buffer(This);
1261 static HRESULT WINAPI SAXContentHandler_startPrefixMapping(
1262 ISAXContentHandler *iface,
1263 const WCHAR *prefix,
1264 int nprefix,
1265 const WCHAR *uri,
1266 int nuri)
1268 mxwriter *This = impl_from_ISAXContentHandler( iface );
1269 TRACE("(%p)->(%s %s)\n", This, debugstr_wn(prefix, nprefix), debugstr_wn(uri, nuri));
1270 return S_OK;
1273 static HRESULT WINAPI SAXContentHandler_endPrefixMapping(
1274 ISAXContentHandler *iface,
1275 const WCHAR *prefix,
1276 int nprefix)
1278 mxwriter *This = impl_from_ISAXContentHandler( iface );
1279 TRACE("(%p)->(%s)\n", This, debugstr_wn(prefix, nprefix));
1280 return S_OK;
1283 static void mxwriter_write_attribute(mxwriter *writer, const WCHAR *qname, int qname_len,
1284 const WCHAR *value, int value_len, BOOL escape)
1286 static const WCHAR eqW[] = {'='};
1288 /* space separator in front of every attribute */
1289 write_output_buffer(writer, spaceW, 1);
1290 write_output_buffer(writer, qname, qname_len);
1291 write_output_buffer(writer, eqW, 1);
1293 if (escape)
1295 WCHAR *escaped = get_escaped_string(value, EscapeValue, &value_len);
1296 write_output_buffer_quoted(writer, escaped, value_len);
1297 heap_free(escaped);
1299 else
1300 write_output_buffer_quoted(writer, value, value_len);
1303 static void mxwriter_write_starttag(mxwriter *writer, const WCHAR *qname, int len)
1305 static const WCHAR ltW[] = {'<'};
1307 close_element_starttag(writer);
1308 set_element_name(writer, qname ? qname : emptyW, qname ? len : 0);
1310 write_node_indent(writer);
1312 write_output_buffer(writer, ltW, 1);
1313 write_output_buffer(writer, qname ? qname : emptyW, qname ? len : 0);
1314 writer_inc_indent(writer);
1317 static HRESULT WINAPI SAXContentHandler_startElement(
1318 ISAXContentHandler *iface,
1319 const WCHAR *namespaceUri,
1320 int nnamespaceUri,
1321 const WCHAR *local_name,
1322 int nlocal_name,
1323 const WCHAR *QName,
1324 int nQName,
1325 ISAXAttributes *attr)
1327 mxwriter *This = impl_from_ISAXContentHandler( iface );
1329 TRACE("(%p)->(%s %s %s %p)\n", This, debugstr_wn(namespaceUri, nnamespaceUri),
1330 debugstr_wn(local_name, nlocal_name), debugstr_wn(QName, nQName), attr);
1332 if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1333 (nQName == -1 && This->class_version == MSXML6))
1334 return E_INVALIDARG;
1336 mxwriter_write_starttag(This, QName, nQName);
1338 if (attr)
1340 int length, i, escape;
1341 HRESULT hr;
1343 hr = ISAXAttributes_getLength(attr, &length);
1344 if (FAILED(hr)) return hr;
1346 escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
1347 (This->class_version == MSXML4 || This->class_version == MSXML6);
1349 for (i = 0; i < length; i++)
1351 int qname_len = 0, value_len = 0;
1352 const WCHAR *qname, *value;
1354 hr = ISAXAttributes_getQName(attr, i, &qname, &qname_len);
1355 if (FAILED(hr)) return hr;
1357 hr = ISAXAttributes_getValue(attr, i, &value, &value_len);
1358 if (FAILED(hr)) return hr;
1360 mxwriter_write_attribute(This, qname, qname_len, value, value_len, escape);
1364 return S_OK;
1367 static HRESULT WINAPI SAXContentHandler_endElement(
1368 ISAXContentHandler *iface,
1369 const WCHAR *namespaceUri,
1370 int nnamespaceUri,
1371 const WCHAR * local_name,
1372 int nlocal_name,
1373 const WCHAR *QName,
1374 int nQName)
1376 mxwriter *This = impl_from_ISAXContentHandler( iface );
1378 TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(namespaceUri, nnamespaceUri), nnamespaceUri,
1379 debugstr_wn(local_name, nlocal_name), nlocal_name, debugstr_wn(QName, nQName), nQName);
1381 if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1382 (nQName == -1 && This->class_version == MSXML6))
1383 return E_INVALIDARG;
1385 writer_dec_indent(This);
1387 if (This->element)
1389 static const WCHAR closeW[] = {'/','>'};
1390 write_output_buffer(This, closeW, 2);
1392 else
1394 static const WCHAR closetagW[] = {'<','/'};
1395 static const WCHAR gtW[] = {'>'};
1397 write_node_indent(This);
1398 write_output_buffer(This, closetagW, 2);
1399 write_output_buffer(This, QName, nQName);
1400 write_output_buffer(This, gtW, 1);
1403 set_element_name(This, NULL, 0);
1405 return S_OK;
1408 static HRESULT WINAPI SAXContentHandler_characters(
1409 ISAXContentHandler *iface,
1410 const WCHAR *chars,
1411 int nchars)
1413 mxwriter *This = impl_from_ISAXContentHandler( iface );
1415 TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1417 if (!chars) return E_INVALIDARG;
1419 close_element_starttag(This);
1420 set_element_name(This, NULL, 0);
1422 if (!This->cdata)
1423 This->text = TRUE;
1425 if (nchars)
1427 if (This->cdata || This->props[MXWriter_DisableEscaping] == VARIANT_TRUE)
1428 write_output_buffer(This, chars, nchars);
1429 else
1431 int len = nchars;
1432 WCHAR *escaped;
1434 escaped = get_escaped_string(chars, EscapeText, &len);
1435 write_output_buffer(This, escaped, len);
1436 heap_free(escaped);
1440 return S_OK;
1443 static HRESULT WINAPI SAXContentHandler_ignorableWhitespace(
1444 ISAXContentHandler *iface,
1445 const WCHAR *chars,
1446 int nchars)
1448 mxwriter *This = impl_from_ISAXContentHandler( iface );
1450 TRACE("(%p)->(%s)\n", This, debugstr_wn(chars, nchars));
1452 if (!chars) return E_INVALIDARG;
1454 write_output_buffer(This, chars, nchars);
1456 return S_OK;
1459 static HRESULT WINAPI SAXContentHandler_processingInstruction(
1460 ISAXContentHandler *iface,
1461 const WCHAR *target,
1462 int ntarget,
1463 const WCHAR *data,
1464 int ndata)
1466 mxwriter *This = impl_from_ISAXContentHandler( iface );
1467 static const WCHAR openpiW[] = {'<','?'};
1468 static const WCHAR closepiW[] = {'?','>','\r','\n'};
1470 TRACE("(%p)->(%s %s)\n", This, debugstr_wn(target, ntarget), debugstr_wn(data, ndata));
1472 if (!target) return E_INVALIDARG;
1474 write_node_indent(This);
1475 write_output_buffer(This, openpiW, ARRAY_SIZE(openpiW));
1477 if (*target)
1478 write_output_buffer(This, target, ntarget);
1480 if (data && *data && ndata)
1482 write_output_buffer(This, spaceW, 1);
1483 write_output_buffer(This, data, ndata);
1486 write_output_buffer(This, closepiW, ARRAY_SIZE(closepiW));
1487 This->newline = TRUE;
1489 return S_OK;
1492 static HRESULT WINAPI SAXContentHandler_skippedEntity(
1493 ISAXContentHandler *iface,
1494 const WCHAR *name,
1495 int nname)
1497 mxwriter *This = impl_from_ISAXContentHandler( iface );
1498 FIXME("(%p)->(%s)\n", This, debugstr_wn(name, nname));
1499 return E_NOTIMPL;
1502 static const struct ISAXContentHandlerVtbl SAXContentHandlerVtbl =
1504 SAXContentHandler_QueryInterface,
1505 SAXContentHandler_AddRef,
1506 SAXContentHandler_Release,
1507 SAXContentHandler_putDocumentLocator,
1508 SAXContentHandler_startDocument,
1509 SAXContentHandler_endDocument,
1510 SAXContentHandler_startPrefixMapping,
1511 SAXContentHandler_endPrefixMapping,
1512 SAXContentHandler_startElement,
1513 SAXContentHandler_endElement,
1514 SAXContentHandler_characters,
1515 SAXContentHandler_ignorableWhitespace,
1516 SAXContentHandler_processingInstruction,
1517 SAXContentHandler_skippedEntity
1520 /*** ISAXLexicalHandler ***/
1521 static HRESULT WINAPI SAXLexicalHandler_QueryInterface(ISAXLexicalHandler *iface,
1522 REFIID riid, void **obj)
1524 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1525 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1528 static ULONG WINAPI SAXLexicalHandler_AddRef(ISAXLexicalHandler *iface)
1530 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1531 return IMXWriter_AddRef(&This->IMXWriter_iface);
1534 static ULONG WINAPI SAXLexicalHandler_Release(ISAXLexicalHandler *iface)
1536 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1537 return IMXWriter_Release(&This->IMXWriter_iface);
1540 static HRESULT WINAPI SAXLexicalHandler_startDTD(ISAXLexicalHandler *iface,
1541 const WCHAR *name, int name_len, const WCHAR *publicId, int publicId_len,
1542 const WCHAR *systemId, int systemId_len)
1544 static const WCHAR doctypeW[] = {'<','!','D','O','C','T','Y','P','E',' '};
1545 static const WCHAR openintW[] = {'[','\r','\n'};
1547 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1549 TRACE("(%p)->(%s %s %s)\n", This, debugstr_wn(name, name_len), debugstr_wn(publicId, publicId_len),
1550 debugstr_wn(systemId, systemId_len));
1552 if (!name) return E_INVALIDARG;
1554 write_output_buffer(This, doctypeW, ARRAY_SIZE(doctypeW));
1556 if (*name)
1558 write_output_buffer(This, name, name_len);
1559 write_output_buffer(This, spaceW, 1);
1562 if (publicId)
1564 write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
1565 write_output_buffer_quoted(This, publicId, publicId_len);
1567 if (!systemId) return E_INVALIDARG;
1569 if (*publicId)
1570 write_output_buffer(This, spaceW, 1);
1572 write_output_buffer_quoted(This, systemId, systemId_len);
1574 if (*systemId)
1575 write_output_buffer(This, spaceW, 1);
1577 else if (systemId)
1579 write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
1580 write_output_buffer_quoted(This, systemId, systemId_len);
1581 if (*systemId)
1582 write_output_buffer(This, spaceW, 1);
1585 write_output_buffer(This, openintW, ARRAY_SIZE(openintW));
1587 return S_OK;
1590 static HRESULT WINAPI SAXLexicalHandler_endDTD(ISAXLexicalHandler *iface)
1592 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1593 static const WCHAR closedtdW[] = {']','>','\r','\n'};
1595 TRACE("(%p)\n", This);
1597 write_output_buffer(This, closedtdW, ARRAY_SIZE(closedtdW));
1599 return S_OK;
1602 static HRESULT WINAPI SAXLexicalHandler_startEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1604 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1605 FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1606 return E_NOTIMPL;
1609 static HRESULT WINAPI SAXLexicalHandler_endEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1611 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1612 FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1613 return E_NOTIMPL;
1616 static HRESULT WINAPI SAXLexicalHandler_startCDATA(ISAXLexicalHandler *iface)
1618 static const WCHAR scdataW[] = {'<','!','[','C','D','A','T','A','['};
1619 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1621 TRACE("(%p)\n", This);
1623 write_node_indent(This);
1624 write_output_buffer(This, scdataW, ARRAY_SIZE(scdataW));
1625 This->cdata = TRUE;
1627 return S_OK;
1630 static HRESULT WINAPI SAXLexicalHandler_endCDATA(ISAXLexicalHandler *iface)
1632 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1633 static const WCHAR ecdataW[] = {']',']','>'};
1635 TRACE("(%p)\n", This);
1637 write_output_buffer(This, ecdataW, ARRAY_SIZE(ecdataW));
1638 This->cdata = FALSE;
1640 return S_OK;
1643 static HRESULT WINAPI SAXLexicalHandler_comment(ISAXLexicalHandler *iface, const WCHAR *chars, int nchars)
1645 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1646 static const WCHAR copenW[] = {'<','!','-','-'};
1647 static const WCHAR ccloseW[] = {'-','-','>','\r','\n'};
1649 TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1651 if (!chars) return E_INVALIDARG;
1653 close_element_starttag(This);
1654 write_node_indent(This);
1656 write_output_buffer(This, copenW, ARRAY_SIZE(copenW));
1657 if (nchars)
1658 write_output_buffer(This, chars, nchars);
1659 write_output_buffer(This, ccloseW, ARRAY_SIZE(ccloseW));
1661 return S_OK;
1664 static const struct ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl =
1666 SAXLexicalHandler_QueryInterface,
1667 SAXLexicalHandler_AddRef,
1668 SAXLexicalHandler_Release,
1669 SAXLexicalHandler_startDTD,
1670 SAXLexicalHandler_endDTD,
1671 SAXLexicalHandler_startEntity,
1672 SAXLexicalHandler_endEntity,
1673 SAXLexicalHandler_startCDATA,
1674 SAXLexicalHandler_endCDATA,
1675 SAXLexicalHandler_comment
1678 /*** ISAXDeclHandler ***/
1679 static HRESULT WINAPI SAXDeclHandler_QueryInterface(ISAXDeclHandler *iface,
1680 REFIID riid, void **obj)
1682 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1683 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1686 static ULONG WINAPI SAXDeclHandler_AddRef(ISAXDeclHandler *iface)
1688 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1689 return IMXWriter_AddRef(&This->IMXWriter_iface);
1692 static ULONG WINAPI SAXDeclHandler_Release(ISAXDeclHandler *iface)
1694 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1695 return IMXWriter_Release(&This->IMXWriter_iface);
1698 static HRESULT WINAPI SAXDeclHandler_elementDecl(ISAXDeclHandler *iface,
1699 const WCHAR *name, int n_name, const WCHAR *model, int n_model)
1701 static const WCHAR elementW[] = {'<','!','E','L','E','M','E','N','T',' '};
1702 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1704 TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1705 debugstr_wn(model, n_model), n_model);
1707 if (!name || !model) return E_INVALIDARG;
1709 write_output_buffer(This, elementW, ARRAY_SIZE(elementW));
1710 if (n_name) {
1711 write_output_buffer(This, name, n_name);
1712 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1714 if (n_model)
1715 write_output_buffer(This, model, n_model);
1716 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1718 return S_OK;
1721 static HRESULT WINAPI SAXDeclHandler_attributeDecl(ISAXDeclHandler *iface,
1722 const WCHAR *element, int n_element, const WCHAR *attr, int n_attr,
1723 const WCHAR *type, int n_type, const WCHAR *Default, int n_default,
1724 const WCHAR *value, int n_value)
1726 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1727 static const WCHAR attlistW[] = {'<','!','A','T','T','L','I','S','T',' '};
1728 static const WCHAR closetagW[] = {'>','\r','\n'};
1730 TRACE("(%p)->(%s:%d %s:%d %s:%d %s:%d %s:%d)\n", This, debugstr_wn(element, n_element), n_element,
1731 debugstr_wn(attr, n_attr), n_attr, debugstr_wn(type, n_type), n_type, debugstr_wn(Default, n_default), n_default,
1732 debugstr_wn(value, n_value), n_value);
1734 write_output_buffer(This, attlistW, ARRAY_SIZE(attlistW));
1735 if (n_element) {
1736 write_output_buffer(This, element, n_element);
1737 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1740 if (n_attr) {
1741 write_output_buffer(This, attr, n_attr);
1742 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1745 if (n_type) {
1746 write_output_buffer(This, type, n_type);
1747 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1750 if (n_default) {
1751 write_output_buffer(This, Default, n_default);
1752 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1755 if (n_value)
1756 write_output_buffer_quoted(This, value, n_value);
1758 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1760 return S_OK;
1763 static HRESULT WINAPI SAXDeclHandler_internalEntityDecl(ISAXDeclHandler *iface,
1764 const WCHAR *name, int n_name, const WCHAR *value, int n_value)
1766 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1768 TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1769 debugstr_wn(value, n_value), n_value);
1771 if (!name || !value) return E_INVALIDARG;
1773 write_output_buffer(This, entityW, ARRAY_SIZE(entityW));
1774 if (n_name) {
1775 write_output_buffer(This, name, n_name);
1776 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1779 if (n_value)
1780 write_output_buffer_quoted(This, value, n_value);
1782 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1784 return S_OK;
1787 static HRESULT WINAPI SAXDeclHandler_externalEntityDecl(ISAXDeclHandler *iface,
1788 const WCHAR *name, int n_name, const WCHAR *publicId, int n_publicId,
1789 const WCHAR *systemId, int n_systemId)
1791 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1793 TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1794 debugstr_wn(publicId, n_publicId), n_publicId, debugstr_wn(systemId, n_systemId), n_systemId);
1796 if (!name || !systemId) return E_INVALIDARG;
1798 write_output_buffer(This, entityW, ARRAY_SIZE(entityW));
1799 if (n_name) {
1800 write_output_buffer(This, name, n_name);
1801 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1804 if (publicId)
1806 write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
1807 write_output_buffer_quoted(This, publicId, n_publicId);
1808 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1809 write_output_buffer_quoted(This, systemId, n_systemId);
1811 else
1813 write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
1814 write_output_buffer_quoted(This, systemId, n_systemId);
1817 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1819 return S_OK;
1822 static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl = {
1823 SAXDeclHandler_QueryInterface,
1824 SAXDeclHandler_AddRef,
1825 SAXDeclHandler_Release,
1826 SAXDeclHandler_elementDecl,
1827 SAXDeclHandler_attributeDecl,
1828 SAXDeclHandler_internalEntityDecl,
1829 SAXDeclHandler_externalEntityDecl
1832 /*** IVBSAXDeclHandler ***/
1833 static HRESULT WINAPI VBSAXDeclHandler_QueryInterface(IVBSAXDeclHandler *iface,
1834 REFIID riid, void **obj)
1836 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1837 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1840 static ULONG WINAPI VBSAXDeclHandler_AddRef(IVBSAXDeclHandler *iface)
1842 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1843 return IMXWriter_AddRef(&This->IMXWriter_iface);
1846 static ULONG WINAPI VBSAXDeclHandler_Release(IVBSAXDeclHandler *iface)
1848 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1849 return IMXWriter_Release(&This->IMXWriter_iface);
1852 static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfoCount(IVBSAXDeclHandler *iface, UINT* pctinfo)
1854 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1855 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1858 static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfo(IVBSAXDeclHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1860 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1861 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1864 static HRESULT WINAPI VBSAXDeclHandler_GetIDsOfNames(IVBSAXDeclHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1865 UINT cNames, LCID lcid, DISPID* rgDispId )
1867 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1868 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1871 static HRESULT WINAPI VBSAXDeclHandler_Invoke(IVBSAXDeclHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1872 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1874 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1875 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1876 pExcepInfo, puArgErr);
1879 static HRESULT WINAPI VBSAXDeclHandler_elementDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *model)
1881 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1883 TRACE("(%p)->(%p %p)\n", This, name, model);
1885 if (!name || !model)
1886 return E_POINTER;
1888 return ISAXDeclHandler_elementDecl(&This->ISAXDeclHandler_iface, *name, -1, *model, -1);
1891 static HRESULT WINAPI VBSAXDeclHandler_attributeDecl(IVBSAXDeclHandler *iface,
1892 BSTR *element, BSTR *attr, BSTR *type, BSTR *default_value, BSTR *value)
1894 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1896 TRACE("(%p)->(%p %p %p %p %p)\n", This, element, attr, type, default_value, value);
1898 if (!element || !attr || !type || !default_value || !value)
1899 return E_POINTER;
1901 return ISAXDeclHandler_attributeDecl(&This->ISAXDeclHandler_iface, *element, -1, *attr, -1, *type, -1,
1902 *default_value, -1, *value, -1);
1905 static HRESULT WINAPI VBSAXDeclHandler_internalEntityDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *value)
1907 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1909 TRACE("(%p)->(%p %p)\n", This, name, value);
1911 if (!name || !value)
1912 return E_POINTER;
1914 return ISAXDeclHandler_internalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *value, -1);
1917 static HRESULT WINAPI VBSAXDeclHandler_externalEntityDecl(IVBSAXDeclHandler *iface,
1918 BSTR *name, BSTR *publicid, BSTR *systemid)
1920 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1922 TRACE("(%p)->(%p %p %p)\n", This, name, publicid, systemid);
1924 if (!name || !publicid || !systemid)
1925 return E_POINTER;
1927 return ISAXDeclHandler_externalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *publicid, -1, *systemid, -1);
1930 static const IVBSAXDeclHandlerVtbl VBSAXDeclHandlerVtbl = {
1931 VBSAXDeclHandler_QueryInterface,
1932 VBSAXDeclHandler_AddRef,
1933 VBSAXDeclHandler_Release,
1934 VBSAXDeclHandler_GetTypeInfoCount,
1935 VBSAXDeclHandler_GetTypeInfo,
1936 VBSAXDeclHandler_GetIDsOfNames,
1937 VBSAXDeclHandler_Invoke,
1938 VBSAXDeclHandler_elementDecl,
1939 VBSAXDeclHandler_attributeDecl,
1940 VBSAXDeclHandler_internalEntityDecl,
1941 VBSAXDeclHandler_externalEntityDecl
1944 /*** IVBSAXLexicalHandler ***/
1945 static HRESULT WINAPI VBSAXLexicalHandler_QueryInterface(IVBSAXLexicalHandler *iface,
1946 REFIID riid, void **obj)
1948 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1949 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1952 static ULONG WINAPI VBSAXLexicalHandler_AddRef(IVBSAXLexicalHandler *iface)
1954 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1955 return IMXWriter_AddRef(&This->IMXWriter_iface);
1958 static ULONG WINAPI VBSAXLexicalHandler_Release(IVBSAXLexicalHandler *iface)
1960 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1961 return IMXWriter_Release(&This->IMXWriter_iface);
1964 static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfoCount(IVBSAXLexicalHandler *iface, UINT* pctinfo)
1966 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1967 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1970 static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfo(IVBSAXLexicalHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1972 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1973 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1976 static HRESULT WINAPI VBSAXLexicalHandler_GetIDsOfNames(IVBSAXLexicalHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1977 UINT cNames, LCID lcid, DISPID* rgDispId )
1979 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1980 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1983 static HRESULT WINAPI VBSAXLexicalHandler_Invoke(IVBSAXLexicalHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1984 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1986 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1987 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1988 pExcepInfo, puArgErr);
1991 static HRESULT WINAPI VBSAXLexicalHandler_startDTD(IVBSAXLexicalHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
1993 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1995 TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
1997 if (!name || !publicId || !systemId)
1998 return E_POINTER;
2000 return ISAXLexicalHandler_startDTD(&This->ISAXLexicalHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
2003 static HRESULT WINAPI VBSAXLexicalHandler_endDTD(IVBSAXLexicalHandler *iface)
2005 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2006 return ISAXLexicalHandler_endDTD(&This->ISAXLexicalHandler_iface);
2009 static HRESULT WINAPI VBSAXLexicalHandler_startEntity(IVBSAXLexicalHandler *iface, BSTR *name)
2011 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2013 TRACE("(%p)->(%p)\n", This, name);
2015 if (!name)
2016 return E_POINTER;
2018 return ISAXLexicalHandler_startEntity(&This->ISAXLexicalHandler_iface, *name, -1);
2021 static HRESULT WINAPI VBSAXLexicalHandler_endEntity(IVBSAXLexicalHandler *iface, BSTR *name)
2023 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2025 TRACE("(%p)->(%p)\n", This, name);
2027 if (!name)
2028 return E_POINTER;
2030 return ISAXLexicalHandler_endEntity(&This->ISAXLexicalHandler_iface, *name, -1);
2033 static HRESULT WINAPI VBSAXLexicalHandler_startCDATA(IVBSAXLexicalHandler *iface)
2035 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2036 return ISAXLexicalHandler_startCDATA(&This->ISAXLexicalHandler_iface);
2039 static HRESULT WINAPI VBSAXLexicalHandler_endCDATA(IVBSAXLexicalHandler *iface)
2041 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2042 return ISAXLexicalHandler_endCDATA(&This->ISAXLexicalHandler_iface);
2045 static HRESULT WINAPI VBSAXLexicalHandler_comment(IVBSAXLexicalHandler *iface, BSTR *chars)
2047 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2049 TRACE("(%p)->(%p)\n", This, chars);
2051 if (!chars)
2052 return E_POINTER;
2054 return ISAXLexicalHandler_comment(&This->ISAXLexicalHandler_iface, *chars, -1);
2057 static const IVBSAXLexicalHandlerVtbl VBSAXLexicalHandlerVtbl = {
2058 VBSAXLexicalHandler_QueryInterface,
2059 VBSAXLexicalHandler_AddRef,
2060 VBSAXLexicalHandler_Release,
2061 VBSAXLexicalHandler_GetTypeInfoCount,
2062 VBSAXLexicalHandler_GetTypeInfo,
2063 VBSAXLexicalHandler_GetIDsOfNames,
2064 VBSAXLexicalHandler_Invoke,
2065 VBSAXLexicalHandler_startDTD,
2066 VBSAXLexicalHandler_endDTD,
2067 VBSAXLexicalHandler_startEntity,
2068 VBSAXLexicalHandler_endEntity,
2069 VBSAXLexicalHandler_startCDATA,
2070 VBSAXLexicalHandler_endCDATA,
2071 VBSAXLexicalHandler_comment
2074 /*** IVBSAXContentHandler ***/
2075 static HRESULT WINAPI VBSAXContentHandler_QueryInterface(IVBSAXContentHandler *iface, REFIID riid, void **obj)
2077 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2078 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2081 static ULONG WINAPI VBSAXContentHandler_AddRef(IVBSAXContentHandler *iface)
2083 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2084 return IMXWriter_AddRef(&This->IMXWriter_iface);
2087 static ULONG WINAPI VBSAXContentHandler_Release(IVBSAXContentHandler *iface)
2089 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2090 return IMXWriter_Release(&This->IMXWriter_iface);
2093 static HRESULT WINAPI VBSAXContentHandler_GetTypeInfoCount(IVBSAXContentHandler *iface, UINT* pctinfo)
2095 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2096 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2099 static HRESULT WINAPI VBSAXContentHandler_GetTypeInfo(IVBSAXContentHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2101 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2102 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2105 static HRESULT WINAPI VBSAXContentHandler_GetIDsOfNames(IVBSAXContentHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2106 UINT cNames, LCID lcid, DISPID* rgDispId )
2108 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2109 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2112 static HRESULT WINAPI VBSAXContentHandler_Invoke(IVBSAXContentHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2113 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2115 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2116 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2117 pExcepInfo, puArgErr);
2120 static HRESULT WINAPI VBSAXContentHandler_putref_documentLocator(IVBSAXContentHandler *iface, IVBSAXLocator *locator)
2122 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2123 TRACE("(%p)->(%p)\n", This, locator);
2124 return S_OK;
2127 static HRESULT WINAPI VBSAXContentHandler_startDocument(IVBSAXContentHandler *iface)
2129 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2130 return ISAXContentHandler_startDocument(&This->ISAXContentHandler_iface);
2133 static HRESULT WINAPI VBSAXContentHandler_endDocument(IVBSAXContentHandler *iface)
2135 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2136 return ISAXContentHandler_endDocument(&This->ISAXContentHandler_iface);
2139 static HRESULT WINAPI VBSAXContentHandler_startPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix, BSTR *uri)
2141 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2143 TRACE("(%p)->(%p %p)\n", This, prefix, uri);
2145 if (!prefix || !uri)
2146 return E_POINTER;
2148 return ISAXContentHandler_startPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1, *uri, -1);
2151 static HRESULT WINAPI VBSAXContentHandler_endPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix)
2153 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2155 TRACE("(%p)->(%p)\n", This, prefix);
2157 if (!prefix)
2158 return E_POINTER;
2160 return ISAXContentHandler_endPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1);
2163 static HRESULT WINAPI VBSAXContentHandler_startElement(IVBSAXContentHandler *iface,
2164 BSTR *namespaceURI, BSTR *localName, BSTR *QName, IVBSAXAttributes *attrs)
2166 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2168 TRACE("(%p)->(%p %p %p %p)\n", This, namespaceURI, localName, QName, attrs);
2170 if (!namespaceURI || !localName || !QName)
2171 return E_POINTER;
2173 TRACE("(%s %s %s)\n", debugstr_w(*namespaceURI), debugstr_w(*localName), debugstr_w(*QName));
2175 mxwriter_write_starttag(This, *QName, SysStringLen(*QName));
2177 if (attrs)
2179 int length, i, escape;
2180 HRESULT hr;
2182 hr = IVBSAXAttributes_get_length(attrs, &length);
2183 if (FAILED(hr)) return hr;
2185 escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
2186 (This->class_version == MSXML4 || This->class_version == MSXML6);
2188 for (i = 0; i < length; i++)
2190 BSTR qname, value;
2192 hr = IVBSAXAttributes_getQName(attrs, i, &qname);
2193 if (FAILED(hr)) return hr;
2195 hr = IVBSAXAttributes_getValue(attrs, i, &value);
2196 if (FAILED(hr))
2198 SysFreeString(qname);
2199 return hr;
2202 mxwriter_write_attribute(This, qname, SysStringLen(qname), value, SysStringLen(value), escape);
2203 SysFreeString(qname);
2204 SysFreeString(value);
2208 return S_OK;
2211 static HRESULT WINAPI VBSAXContentHandler_endElement(IVBSAXContentHandler *iface, BSTR *namespaceURI,
2212 BSTR *localName, BSTR *QName)
2214 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2216 TRACE("(%p)->(%p %p %p)\n", This, namespaceURI, localName, QName);
2218 if (!namespaceURI || !localName || !QName)
2219 return E_POINTER;
2221 return ISAXContentHandler_endElement(&This->ISAXContentHandler_iface,
2222 *namespaceURI, SysStringLen(*namespaceURI),
2223 *localName, SysStringLen(*localName),
2224 *QName, SysStringLen(*QName));
2227 static HRESULT WINAPI VBSAXContentHandler_characters(IVBSAXContentHandler *iface, BSTR *chars)
2229 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2231 TRACE("(%p)->(%p)\n", This, chars);
2233 if (!chars)
2234 return E_POINTER;
2236 return ISAXContentHandler_characters(&This->ISAXContentHandler_iface, *chars, SysStringLen(*chars));
2239 static HRESULT WINAPI VBSAXContentHandler_ignorableWhitespace(IVBSAXContentHandler *iface, BSTR *chars)
2241 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2243 TRACE("(%p)->(%p)\n", This, chars);
2245 if (!chars)
2246 return E_POINTER;
2248 return ISAXContentHandler_ignorableWhitespace(&This->ISAXContentHandler_iface, *chars, -1);
2251 static HRESULT WINAPI VBSAXContentHandler_processingInstruction(IVBSAXContentHandler *iface,
2252 BSTR *target, BSTR *data)
2254 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2256 TRACE("(%p)->(%p %p)\n", This, target, data);
2258 if (!target || !data)
2259 return E_POINTER;
2261 return ISAXContentHandler_processingInstruction(&This->ISAXContentHandler_iface, *target, -1, *data, -1);
2264 static HRESULT WINAPI VBSAXContentHandler_skippedEntity(IVBSAXContentHandler *iface, BSTR *name)
2266 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2268 TRACE("(%p)->(%p)\n", This, name);
2270 if (!name)
2271 return E_POINTER;
2273 return ISAXContentHandler_skippedEntity(&This->ISAXContentHandler_iface, *name, -1);
2276 static const IVBSAXContentHandlerVtbl VBSAXContentHandlerVtbl = {
2277 VBSAXContentHandler_QueryInterface,
2278 VBSAXContentHandler_AddRef,
2279 VBSAXContentHandler_Release,
2280 VBSAXContentHandler_GetTypeInfoCount,
2281 VBSAXContentHandler_GetTypeInfo,
2282 VBSAXContentHandler_GetIDsOfNames,
2283 VBSAXContentHandler_Invoke,
2284 VBSAXContentHandler_putref_documentLocator,
2285 VBSAXContentHandler_startDocument,
2286 VBSAXContentHandler_endDocument,
2287 VBSAXContentHandler_startPrefixMapping,
2288 VBSAXContentHandler_endPrefixMapping,
2289 VBSAXContentHandler_startElement,
2290 VBSAXContentHandler_endElement,
2291 VBSAXContentHandler_characters,
2292 VBSAXContentHandler_ignorableWhitespace,
2293 VBSAXContentHandler_processingInstruction,
2294 VBSAXContentHandler_skippedEntity
2297 static HRESULT WINAPI SAXDTDHandler_QueryInterface(ISAXDTDHandler *iface, REFIID riid, void **obj)
2299 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2300 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2303 static ULONG WINAPI SAXDTDHandler_AddRef(ISAXDTDHandler *iface)
2305 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2306 return IMXWriter_AddRef(&This->IMXWriter_iface);
2309 static ULONG WINAPI SAXDTDHandler_Release(ISAXDTDHandler *iface)
2311 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2312 return IMXWriter_Release(&This->IMXWriter_iface);
2315 static HRESULT WINAPI SAXDTDHandler_notationDecl(ISAXDTDHandler *iface,
2316 const WCHAR *name, INT n_name,
2317 const WCHAR *publicid, INT n_publicid,
2318 const WCHAR *systemid, INT n_systemid)
2320 static const WCHAR notationW[] = {'<','!','N','O','T','A','T','I','O','N',' '};
2321 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2323 TRACE("(%p)->(%s:%d, %s:%d, %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
2324 debugstr_wn(publicid, n_publicid), n_publicid, debugstr_wn(systemid, n_systemid), n_systemid);
2326 if (!name || !n_name)
2327 return E_INVALIDARG;
2329 write_output_buffer(This, notationW, ARRAY_SIZE(notationW));
2330 write_output_buffer(This, name, n_name);
2332 if (!publicid && !systemid)
2333 return E_INVALIDARG;
2335 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
2336 if (publicid)
2338 write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
2339 write_output_buffer_quoted(This, publicid, n_publicid);
2340 if (systemid)
2342 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
2343 write_output_buffer_quoted(This, systemid, n_systemid);
2346 else
2348 write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
2349 write_output_buffer_quoted(This, systemid, n_systemid);
2352 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
2354 return S_OK;
2357 static HRESULT WINAPI SAXDTDHandler_unparsedEntityDecl(ISAXDTDHandler *iface,
2358 const WCHAR *name, INT nname,
2359 const WCHAR *publicid, INT npublicid,
2360 const WCHAR *systemid, INT nsystemid,
2361 const WCHAR *notation, INT nnotation)
2363 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2364 FIXME("(%p)->(%s:%d, %s:%d, %s:%d, %s:%d): stub\n", This, debugstr_wn(name, nname), nname,
2365 debugstr_wn(publicid, npublicid), npublicid, debugstr_wn(systemid, nsystemid), nsystemid,
2366 debugstr_wn(notation, nnotation), nnotation);
2367 return E_NOTIMPL;
2370 static const ISAXDTDHandlerVtbl SAXDTDHandlerVtbl = {
2371 SAXDTDHandler_QueryInterface,
2372 SAXDTDHandler_AddRef,
2373 SAXDTDHandler_Release,
2374 SAXDTDHandler_notationDecl,
2375 SAXDTDHandler_unparsedEntityDecl
2378 /*** IVBSAXDTDHandler ***/
2379 static HRESULT WINAPI VBSAXDTDHandler_QueryInterface(IVBSAXDTDHandler *iface, REFIID riid, void **obj)
2381 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2382 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2385 static ULONG WINAPI VBSAXDTDHandler_AddRef(IVBSAXDTDHandler *iface)
2387 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2388 return IMXWriter_AddRef(&This->IMXWriter_iface);
2391 static ULONG WINAPI VBSAXDTDHandler_Release(IVBSAXDTDHandler *iface)
2393 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2394 return IMXWriter_Release(&This->IMXWriter_iface);
2397 static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfoCount(IVBSAXDTDHandler *iface, UINT* pctinfo)
2399 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2400 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2403 static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfo(IVBSAXDTDHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2405 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2406 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2409 static HRESULT WINAPI VBSAXDTDHandler_GetIDsOfNames(IVBSAXDTDHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2410 UINT cNames, LCID lcid, DISPID* rgDispId )
2412 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2413 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2416 static HRESULT WINAPI VBSAXDTDHandler_Invoke(IVBSAXDTDHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2417 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2419 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2420 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2421 pExcepInfo, puArgErr);
2424 static HRESULT WINAPI VBSAXDTDHandler_notationDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
2426 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2428 TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
2430 if (!name || !publicId || !systemId)
2431 return E_POINTER;
2433 return ISAXDTDHandler_notationDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
2436 static HRESULT WINAPI VBSAXDTDHandler_unparsedEntityDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId,
2437 BSTR *systemId, BSTR *notation)
2439 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2441 TRACE("(%p)->(%p %p %p %p)\n", This, name, publicId, systemId, notation);
2443 if (!name || !publicId || !systemId || !notation)
2444 return E_POINTER;
2446 return ISAXDTDHandler_unparsedEntityDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1,
2447 *systemId, -1, *notation, -1);
2450 static const IVBSAXDTDHandlerVtbl VBSAXDTDHandlerVtbl = {
2451 VBSAXDTDHandler_QueryInterface,
2452 VBSAXDTDHandler_AddRef,
2453 VBSAXDTDHandler_Release,
2454 VBSAXDTDHandler_GetTypeInfoCount,
2455 VBSAXDTDHandler_GetTypeInfo,
2456 VBSAXDTDHandler_GetIDsOfNames,
2457 VBSAXDTDHandler_Invoke,
2458 VBSAXDTDHandler_notationDecl,
2459 VBSAXDTDHandler_unparsedEntityDecl
2462 /* ISAXErrorHandler */
2463 static HRESULT WINAPI SAXErrorHandler_QueryInterface(ISAXErrorHandler *iface, REFIID riid, void **obj)
2465 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2466 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2469 static ULONG WINAPI SAXErrorHandler_AddRef(ISAXErrorHandler *iface)
2471 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2472 return IMXWriter_AddRef(&This->IMXWriter_iface);
2475 static ULONG WINAPI SAXErrorHandler_Release(ISAXErrorHandler *iface)
2477 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2478 return IMXWriter_Release(&This->IMXWriter_iface);
2481 static HRESULT WINAPI SAXErrorHandler_error(ISAXErrorHandler *iface,
2482 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2484 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2486 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2488 return E_NOTIMPL;
2491 static HRESULT WINAPI SAXErrorHandler_fatalError(ISAXErrorHandler *iface,
2492 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2494 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2496 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2498 return E_NOTIMPL;
2501 static HRESULT WINAPI SAXErrorHandler_ignorableWarning(ISAXErrorHandler *iface,
2502 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2504 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2506 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2508 return E_NOTIMPL;
2511 static const ISAXErrorHandlerVtbl SAXErrorHandlerVtbl = {
2512 SAXErrorHandler_QueryInterface,
2513 SAXErrorHandler_AddRef,
2514 SAXErrorHandler_Release,
2515 SAXErrorHandler_error,
2516 SAXErrorHandler_fatalError,
2517 SAXErrorHandler_ignorableWarning
2520 /*** IVBSAXErrorHandler ***/
2521 static HRESULT WINAPI VBSAXErrorHandler_QueryInterface(IVBSAXErrorHandler *iface, REFIID riid, void **obj)
2523 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2524 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2527 static ULONG WINAPI VBSAXErrorHandler_AddRef(IVBSAXErrorHandler *iface)
2529 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2530 return IMXWriter_AddRef(&This->IMXWriter_iface);
2533 static ULONG WINAPI VBSAXErrorHandler_Release(IVBSAXErrorHandler *iface)
2535 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2536 return IMXWriter_Release(&This->IMXWriter_iface);
2539 static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfoCount(IVBSAXErrorHandler *iface, UINT* pctinfo)
2541 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2542 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2545 static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfo(IVBSAXErrorHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2547 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2548 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2551 static HRESULT WINAPI VBSAXErrorHandler_GetIDsOfNames(IVBSAXErrorHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2552 UINT cNames, LCID lcid, DISPID* rgDispId )
2554 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2555 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2558 static HRESULT WINAPI VBSAXErrorHandler_Invoke(IVBSAXErrorHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2559 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2561 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2562 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2563 pExcepInfo, puArgErr);
2566 static HRESULT WINAPI VBSAXErrorHandler_error(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2568 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2569 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2570 return E_NOTIMPL;
2573 static HRESULT WINAPI VBSAXErrorHandler_fatalError(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2575 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2576 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2577 return E_NOTIMPL;
2580 static HRESULT WINAPI VBSAXErrorHandler_ignorableWarning(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2582 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2583 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2584 return E_NOTIMPL;
2587 static const IVBSAXErrorHandlerVtbl VBSAXErrorHandlerVtbl = {
2588 VBSAXErrorHandler_QueryInterface,
2589 VBSAXErrorHandler_AddRef,
2590 VBSAXErrorHandler_Release,
2591 VBSAXErrorHandler_GetTypeInfoCount,
2592 VBSAXErrorHandler_GetTypeInfo,
2593 VBSAXErrorHandler_GetIDsOfNames,
2594 VBSAXErrorHandler_Invoke,
2595 VBSAXErrorHandler_error,
2596 VBSAXErrorHandler_fatalError,
2597 VBSAXErrorHandler_ignorableWarning
2600 static const tid_t mxwriter_iface_tids[] = {
2601 IMXWriter_tid,
2605 static dispex_static_data_t mxwriter_dispex = {
2606 NULL,
2607 IMXWriter_tid,
2608 NULL,
2609 mxwriter_iface_tids
2612 HRESULT MXWriter_create(MSXML_VERSION version, void **ppObj)
2614 static const WCHAR version10W[] = {'1','.','0',0};
2615 mxwriter *This;
2616 HRESULT hr;
2618 TRACE("(%p)\n", ppObj);
2620 This = heap_alloc( sizeof (*This) );
2621 if(!This)
2622 return E_OUTOFMEMORY;
2624 This->IMXWriter_iface.lpVtbl = &MXWriterVtbl;
2625 This->ISAXContentHandler_iface.lpVtbl = &SAXContentHandlerVtbl;
2626 This->ISAXLexicalHandler_iface.lpVtbl = &SAXLexicalHandlerVtbl;
2627 This->ISAXDeclHandler_iface.lpVtbl = &SAXDeclHandlerVtbl;
2628 This->ISAXDTDHandler_iface.lpVtbl = &SAXDTDHandlerVtbl;
2629 This->ISAXErrorHandler_iface.lpVtbl = &SAXErrorHandlerVtbl;
2630 This->IVBSAXDeclHandler_iface.lpVtbl = &VBSAXDeclHandlerVtbl;
2631 This->IVBSAXLexicalHandler_iface.lpVtbl = &VBSAXLexicalHandlerVtbl;
2632 This->IVBSAXContentHandler_iface.lpVtbl = &VBSAXContentHandlerVtbl;
2633 This->IVBSAXDTDHandler_iface.lpVtbl = &VBSAXDTDHandlerVtbl;
2634 This->IVBSAXErrorHandler_iface.lpVtbl = &VBSAXErrorHandlerVtbl;
2635 This->ref = 1;
2636 This->class_version = version;
2638 This->props[MXWriter_BOM] = VARIANT_TRUE;
2639 This->props[MXWriter_DisableEscaping] = VARIANT_FALSE;
2640 This->props[MXWriter_Indent] = VARIANT_FALSE;
2641 This->props[MXWriter_OmitXmlDecl] = VARIANT_FALSE;
2642 This->props[MXWriter_Standalone] = VARIANT_FALSE;
2643 This->prop_changed = FALSE;
2644 This->encoding = SysAllocString(utf16W);
2645 This->version = SysAllocString(version10W);
2646 This->xml_enc = XmlEncoding_UTF16;
2648 This->element = NULL;
2649 This->cdata = FALSE;
2650 This->indent = 0;
2651 This->text = FALSE;
2652 This->newline = FALSE;
2654 This->dest = NULL;
2656 hr = init_output_buffer(This->xml_enc, &This->buffer);
2657 if (hr != S_OK) {
2658 SysFreeString(This->encoding);
2659 SysFreeString(This->version);
2660 heap_free(This);
2661 return hr;
2664 init_dispex(&This->dispex, (IUnknown*)&This->IMXWriter_iface, &mxwriter_dispex);
2666 *ppObj = &This->IMXWriter_iface;
2668 TRACE("returning iface %p\n", *ppObj);
2670 return S_OK;
2673 static HRESULT WINAPI MXAttributes_QueryInterface(IMXAttributes *iface, REFIID riid, void **ppObj)
2675 mxattributes *This = impl_from_IMXAttributes( iface );
2677 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppObj);
2679 *ppObj = NULL;
2681 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2682 IsEqualGUID( riid, &IID_IDispatch ) ||
2683 IsEqualGUID( riid, &IID_IMXAttributes ))
2685 *ppObj = iface;
2687 else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
2689 *ppObj = &This->ISAXAttributes_iface;
2691 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
2693 *ppObj = &This->IVBSAXAttributes_iface;
2695 else if (dispex_query_interface(&This->dispex, riid, ppObj))
2697 return *ppObj ? S_OK : E_NOINTERFACE;
2699 else
2701 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2702 return E_NOINTERFACE;
2705 IMXAttributes_AddRef( iface );
2707 return S_OK;
2710 static ULONG WINAPI MXAttributes_AddRef(IMXAttributes *iface)
2712 mxattributes *This = impl_from_IMXAttributes( iface );
2713 ULONG ref = InterlockedIncrement( &This->ref );
2714 TRACE("(%p)->(%d)\n", This, ref );
2715 return ref;
2718 static ULONG WINAPI MXAttributes_Release(IMXAttributes *iface)
2720 mxattributes *This = impl_from_IMXAttributes( iface );
2721 LONG ref = InterlockedDecrement( &This->ref );
2723 TRACE("(%p)->(%d)\n", This, ref);
2725 if (ref == 0)
2727 int i;
2729 for (i = 0; i < This->length; i++)
2731 SysFreeString(This->attr[i].qname);
2732 SysFreeString(This->attr[i].local);
2733 SysFreeString(This->attr[i].uri);
2734 SysFreeString(This->attr[i].type);
2735 SysFreeString(This->attr[i].value);
2738 heap_free(This->attr);
2739 heap_free(This);
2742 return ref;
2745 static HRESULT WINAPI MXAttributes_GetTypeInfoCount(IMXAttributes *iface, UINT* pctinfo)
2747 mxattributes *This = impl_from_IMXAttributes( iface );
2748 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2751 static HRESULT WINAPI MXAttributes_GetTypeInfo(IMXAttributes *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2753 mxattributes *This = impl_from_IMXAttributes( iface );
2754 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2757 static HRESULT WINAPI MXAttributes_GetIDsOfNames(
2758 IMXAttributes *iface,
2759 REFIID riid,
2760 LPOLESTR* rgszNames,
2761 UINT cNames,
2762 LCID lcid,
2763 DISPID* rgDispId)
2765 mxattributes *This = impl_from_IMXAttributes( iface );
2766 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2767 riid, rgszNames, cNames, lcid, rgDispId);
2770 static HRESULT WINAPI MXAttributes_Invoke(
2771 IMXAttributes *iface,
2772 DISPID dispIdMember,
2773 REFIID riid,
2774 LCID lcid,
2775 WORD wFlags,
2776 DISPPARAMS* pDispParams,
2777 VARIANT* pVarResult,
2778 EXCEPINFO* pExcepInfo,
2779 UINT* puArgErr)
2781 mxattributes *This = impl_from_IMXAttributes( iface );
2782 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
2783 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2786 static HRESULT WINAPI MXAttributes_addAttribute(IMXAttributes *iface,
2787 BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2789 mxattributes *This = impl_from_IMXAttributes( iface );
2790 mxattribute *attr;
2791 HRESULT hr;
2793 TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(uri), debugstr_w(localName),
2794 debugstr_w(QName), debugstr_w(type), debugstr_w(value));
2796 if ((!uri || !localName || !QName || !type || !value) && This->class_version != MSXML6)
2797 return E_INVALIDARG;
2799 /* ensure array is large enough */
2800 hr = mxattributes_grow(This);
2801 if (hr != S_OK) return hr;
2803 attr = &This->attr[This->length];
2805 attr->qname = SysAllocString(QName);
2806 attr->local = SysAllocString(localName);
2807 attr->uri = SysAllocString(uri);
2808 attr->type = SysAllocString(type ? type : emptyW);
2809 attr->value = SysAllocString(value);
2810 This->length++;
2812 return S_OK;
2815 static HRESULT WINAPI MXAttributes_addAttributeFromIndex(IMXAttributes *iface,
2816 VARIANT atts, int index)
2818 mxattributes *This = impl_from_IMXAttributes( iface );
2819 FIXME("(%p)->(%s %d): stub\n", This, debugstr_variant(&atts), index);
2820 return E_NOTIMPL;
2823 static HRESULT WINAPI MXAttributes_clear(IMXAttributes *iface)
2825 mxattributes *This = impl_from_IMXAttributes( iface );
2826 int i;
2828 TRACE("(%p)\n", This);
2830 for (i = 0; i < This->length; i++)
2832 SysFreeString(This->attr[i].qname);
2833 SysFreeString(This->attr[i].local);
2834 SysFreeString(This->attr[i].uri);
2835 SysFreeString(This->attr[i].type);
2836 SysFreeString(This->attr[i].value);
2837 memset(&This->attr[i], 0, sizeof(mxattribute));
2840 This->length = 0;
2842 return S_OK;
2845 static mxattribute *get_attribute_byindex(mxattributes *attrs, int index)
2847 if (index < 0 || index >= attrs->length) return NULL;
2848 return &attrs->attr[index];
2851 static HRESULT WINAPI MXAttributes_removeAttribute(IMXAttributes *iface, int index)
2853 mxattributes *This = impl_from_IMXAttributes( iface );
2854 mxattribute *dst;
2856 TRACE("(%p)->(%d)\n", This, index);
2858 if (!(dst = get_attribute_byindex(This, index))) return E_INVALIDARG;
2860 /* no need to remove last attribute, just make it inaccessible */
2861 if (index + 1 == This->length)
2863 This->length--;
2864 return S_OK;
2867 memmove(dst, dst + 1, (This->length-index-1)*sizeof(*dst));
2868 This->length--;
2870 return S_OK;
2873 static HRESULT WINAPI MXAttributes_setAttribute(IMXAttributes *iface, int index,
2874 BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2876 mxattributes *This = impl_from_IMXAttributes( iface );
2877 FIXME("(%p)->(%d %s %s %s %s %s): stub\n", This, index, debugstr_w(uri),
2878 debugstr_w(localName), debugstr_w(QName), debugstr_w(type), debugstr_w(value));
2879 return E_NOTIMPL;
2882 static HRESULT WINAPI MXAttributes_setAttributes(IMXAttributes *iface, VARIANT atts)
2884 mxattributes *This = impl_from_IMXAttributes( iface );
2885 FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&atts));
2886 return E_NOTIMPL;
2889 static HRESULT WINAPI MXAttributes_setLocalName(IMXAttributes *iface, int index,
2890 BSTR localName)
2892 mxattributes *This = impl_from_IMXAttributes( iface );
2893 mxattribute *attr;
2895 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(localName));
2897 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2899 SysFreeString(attr->local);
2900 attr->local = SysAllocString(localName);
2902 return S_OK;
2905 static HRESULT WINAPI MXAttributes_setQName(IMXAttributes *iface, int index, BSTR QName)
2907 mxattributes *This = impl_from_IMXAttributes( iface );
2908 mxattribute *attr;
2910 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(QName));
2912 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2914 SysFreeString(attr->qname);
2915 attr->qname = SysAllocString(QName);
2917 return S_OK;
2920 static HRESULT WINAPI MXAttributes_setURI(IMXAttributes *iface, int index, BSTR uri)
2922 mxattributes *This = impl_from_IMXAttributes( iface );
2923 mxattribute *attr;
2925 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(uri));
2927 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2929 SysFreeString(attr->uri);
2930 attr->uri = SysAllocString(uri);
2932 return S_OK;
2935 static HRESULT WINAPI MXAttributes_setValue(IMXAttributes *iface, int index, BSTR value)
2937 mxattributes *This = impl_from_IMXAttributes( iface );
2938 mxattribute *attr;
2940 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(value));
2942 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2944 SysFreeString(attr->value);
2945 attr->value = SysAllocString(value);
2947 return S_OK;
2950 static const IMXAttributesVtbl MXAttributesVtbl = {
2951 MXAttributes_QueryInterface,
2952 MXAttributes_AddRef,
2953 MXAttributes_Release,
2954 MXAttributes_GetTypeInfoCount,
2955 MXAttributes_GetTypeInfo,
2956 MXAttributes_GetIDsOfNames,
2957 MXAttributes_Invoke,
2958 MXAttributes_addAttribute,
2959 MXAttributes_addAttributeFromIndex,
2960 MXAttributes_clear,
2961 MXAttributes_removeAttribute,
2962 MXAttributes_setAttribute,
2963 MXAttributes_setAttributes,
2964 MXAttributes_setLocalName,
2965 MXAttributes_setQName,
2966 MXAttributes_setURI,
2967 MXAttributes_setValue
2970 static HRESULT WINAPI SAXAttributes_QueryInterface(ISAXAttributes *iface, REFIID riid, void **ppObj)
2972 mxattributes *This = impl_from_ISAXAttributes( iface );
2973 return IMXAttributes_QueryInterface(&This->IMXAttributes_iface, riid, ppObj);
2976 static ULONG WINAPI SAXAttributes_AddRef(ISAXAttributes *iface)
2978 mxattributes *This = impl_from_ISAXAttributes( iface );
2979 return IMXAttributes_AddRef(&This->IMXAttributes_iface);
2982 static ULONG WINAPI SAXAttributes_Release(ISAXAttributes *iface)
2984 mxattributes *This = impl_from_ISAXAttributes( iface );
2985 return IMXAttributes_Release(&This->IMXAttributes_iface);
2988 static HRESULT WINAPI SAXAttributes_getLength(ISAXAttributes *iface, int *length)
2990 mxattributes *This = impl_from_ISAXAttributes( iface );
2991 TRACE("(%p)->(%p)\n", This, length);
2993 if (!length && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
2994 return E_POINTER;
2996 *length = This->length;
2998 return S_OK;
3001 static HRESULT WINAPI SAXAttributes_getURI(ISAXAttributes *iface, int index, const WCHAR **uri,
3002 int *len)
3004 mxattributes *This = impl_from_ISAXAttributes( iface );
3006 TRACE("(%p)->(%d %p %p)\n", This, index, uri, len);
3008 if (index >= This->length || index < 0) return E_INVALIDARG;
3009 if (!uri || !len) return E_POINTER;
3011 *len = SysStringLen(This->attr[index].uri);
3012 *uri = This->attr[index].uri;
3014 return S_OK;
3017 static HRESULT WINAPI SAXAttributes_getLocalName(ISAXAttributes *iface, int index, const WCHAR **name,
3018 int *len)
3020 mxattributes *This = impl_from_ISAXAttributes( iface );
3022 TRACE("(%p)->(%d %p %p)\n", This, index, name, len);
3024 if (index >= This->length || index < 0) return E_INVALIDARG;
3025 if (!name || !len) return E_POINTER;
3027 *len = SysStringLen(This->attr[index].local);
3028 *name = This->attr[index].local;
3030 return S_OK;
3033 static HRESULT WINAPI SAXAttributes_getQName(ISAXAttributes *iface, int index, const WCHAR **qname, int *length)
3035 mxattributes *This = impl_from_ISAXAttributes( iface );
3037 TRACE("(%p)->(%d %p %p)\n", This, index, qname, length);
3039 if (index >= This->length) return E_INVALIDARG;
3040 if (!qname || !length) return E_POINTER;
3042 *qname = This->attr[index].qname;
3043 *length = SysStringLen(This->attr[index].qname);
3045 return S_OK;
3048 static HRESULT WINAPI SAXAttributes_getName(ISAXAttributes *iface, int index, const WCHAR **uri, int *uri_len,
3049 const WCHAR **local, int *local_len, const WCHAR **qname, int *qname_len)
3051 mxattributes *This = impl_from_ISAXAttributes( iface );
3053 TRACE("(%p)->(%d %p %p %p %p %p %p)\n", This, index, uri, uri_len, local, local_len, qname, qname_len);
3055 if (index >= This->length || index < 0)
3056 return E_INVALIDARG;
3058 if (!uri || !uri_len || !local || !local_len || !qname || !qname_len)
3059 return E_POINTER;
3061 *uri_len = SysStringLen(This->attr[index].uri);
3062 *uri = This->attr[index].uri;
3064 *local_len = SysStringLen(This->attr[index].local);
3065 *local = This->attr[index].local;
3067 *qname_len = SysStringLen(This->attr[index].qname);
3068 *qname = This->attr[index].qname;
3070 TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*local), debugstr_w(*qname));
3072 return S_OK;
3075 static HRESULT WINAPI SAXAttributes_getIndexFromName(ISAXAttributes *iface, const WCHAR *uri, int uri_len,
3076 const WCHAR *name, int len, int *index)
3078 mxattributes *This = impl_from_ISAXAttributes( iface );
3079 int i;
3081 TRACE("(%p)->(%s:%d %s:%d %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
3082 debugstr_wn(name, len), len, index);
3084 if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3085 return E_POINTER;
3087 if (!uri || !name || !index) return E_INVALIDARG;
3089 for (i = 0; i < This->length; i++)
3091 if (uri_len != SysStringLen(This->attr[i].uri)) continue;
3092 if (strncmpW(uri, This->attr[i].uri, uri_len)) continue;
3094 if (len != SysStringLen(This->attr[i].local)) continue;
3095 if (strncmpW(name, This->attr[i].local, len)) continue;
3097 *index = i;
3098 return S_OK;
3101 return E_INVALIDARG;
3104 static HRESULT WINAPI SAXAttributes_getIndexFromQName(ISAXAttributes *iface, const WCHAR *qname,
3105 int len, int *index)
3107 mxattributes *This = impl_from_ISAXAttributes( iface );
3108 int i;
3110 TRACE("(%p)->(%s:%d %p)\n", This, debugstr_wn(qname, len), len, index);
3112 if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3113 return E_POINTER;
3115 if (!qname || !index || !len) return E_INVALIDARG;
3117 for (i = 0; i < This->length; i++)
3119 if (len != SysStringLen(This->attr[i].qname)) continue;
3120 if (strncmpW(qname, This->attr[i].qname, len)) continue;
3122 *index = i;
3123 return S_OK;
3126 return E_INVALIDARG;
3129 static HRESULT WINAPI SAXAttributes_getType(ISAXAttributes *iface, int index, const WCHAR **type,
3130 int *len)
3132 mxattributes *This = impl_from_ISAXAttributes( iface );
3134 TRACE("(%p)->(%d %p %p)\n", This, index, type, len);
3136 if (index >= This->length) return E_INVALIDARG;
3138 if ((!type || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3139 return E_POINTER;
3141 *type = This->attr[index].type;
3142 *len = SysStringLen(This->attr[index].type);
3144 return S_OK;
3147 static HRESULT WINAPI SAXAttributes_getTypeFromName(ISAXAttributes *iface, const WCHAR * pUri, int nUri,
3148 const WCHAR * pLocalName, int nLocalName, const WCHAR ** pType, int * nType)
3150 mxattributes *This = impl_from_ISAXAttributes( iface );
3151 FIXME("(%p)->(%s:%d %s:%d %p %p): stub\n", This, debugstr_wn(pUri, nUri), nUri,
3152 debugstr_wn(pLocalName, nLocalName), nLocalName, pType, nType);
3153 return E_NOTIMPL;
3156 static HRESULT WINAPI SAXAttributes_getTypeFromQName(ISAXAttributes *iface, const WCHAR * pQName,
3157 int nQName, const WCHAR ** pType, int * nType)
3159 mxattributes *This = impl_from_ISAXAttributes( iface );
3160 FIXME("(%p)->(%s:%d %p %p): stub\n", This, debugstr_wn(pQName, nQName), nQName, pType, nType);
3161 return E_NOTIMPL;
3164 static HRESULT WINAPI SAXAttributes_getValue(ISAXAttributes *iface, int index, const WCHAR **value,
3165 int *len)
3167 mxattributes *This = impl_from_ISAXAttributes( iface );
3169 TRACE("(%p)->(%d %p %p)\n", This, index, value, len);
3171 if (index >= This->length) return E_INVALIDARG;
3173 if ((!value || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3174 return E_POINTER;
3176 *value = This->attr[index].value;
3177 *len = SysStringLen(This->attr[index].value);
3179 return S_OK;
3182 static HRESULT WINAPI SAXAttributes_getValueFromName(ISAXAttributes *iface, const WCHAR *uri,
3183 int uri_len, const WCHAR *name, int name_len, const WCHAR **value, int *value_len)
3185 mxattributes *This = impl_from_ISAXAttributes( iface );
3186 HRESULT hr;
3187 int index;
3189 TRACE("(%p)->(%s:%d %s:%d %p %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
3190 debugstr_wn(name, name_len), name_len, value, value_len);
3192 if (!uri || !name || !value || !value_len)
3193 return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3195 hr = ISAXAttributes_getIndexFromName(iface, uri, uri_len, name, name_len, &index);
3196 if (hr == S_OK)
3197 hr = ISAXAttributes_getValue(iface, index, value, value_len);
3199 return hr;
3202 static HRESULT WINAPI SAXAttributes_getValueFromQName(ISAXAttributes *iface, const WCHAR *qname,
3203 int qname_len, const WCHAR **value, int *value_len)
3205 mxattributes *This = impl_from_ISAXAttributes( iface );
3206 HRESULT hr;
3207 int index;
3209 TRACE("(%p)->(%s:%d %p %p)\n", This, debugstr_wn(qname, qname_len), qname_len, value, value_len);
3211 if (!qname || !value || !value_len)
3212 return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3214 hr = ISAXAttributes_getIndexFromQName(iface, qname, qname_len, &index);
3215 if (hr == S_OK)
3216 hr = ISAXAttributes_getValue(iface, index, value, value_len);
3218 return hr;
3221 static const ISAXAttributesVtbl SAXAttributesVtbl = {
3222 SAXAttributes_QueryInterface,
3223 SAXAttributes_AddRef,
3224 SAXAttributes_Release,
3225 SAXAttributes_getLength,
3226 SAXAttributes_getURI,
3227 SAXAttributes_getLocalName,
3228 SAXAttributes_getQName,
3229 SAXAttributes_getName,
3230 SAXAttributes_getIndexFromName,
3231 SAXAttributes_getIndexFromQName,
3232 SAXAttributes_getType,
3233 SAXAttributes_getTypeFromName,
3234 SAXAttributes_getTypeFromQName,
3235 SAXAttributes_getValue,
3236 SAXAttributes_getValueFromName,
3237 SAXAttributes_getValueFromQName
3240 static HRESULT WINAPI VBSAXAttributes_QueryInterface(
3241 IVBSAXAttributes* iface,
3242 REFIID riid,
3243 void **ppvObject)
3245 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3246 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
3247 return ISAXAttributes_QueryInterface(&This->ISAXAttributes_iface, riid, ppvObject);
3250 static ULONG WINAPI VBSAXAttributes_AddRef(IVBSAXAttributes* iface)
3252 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3253 return ISAXAttributes_AddRef(&This->ISAXAttributes_iface);
3256 static ULONG WINAPI VBSAXAttributes_Release(IVBSAXAttributes* iface)
3258 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3259 return ISAXAttributes_Release(&This->ISAXAttributes_iface);
3262 static HRESULT WINAPI VBSAXAttributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
3264 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3266 TRACE("(%p)->(%p)\n", This, pctinfo);
3268 *pctinfo = 1;
3270 return S_OK;
3273 static HRESULT WINAPI VBSAXAttributes_GetTypeInfo(
3274 IVBSAXAttributes *iface,
3275 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
3277 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3278 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
3279 return get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
3282 static HRESULT WINAPI VBSAXAttributes_GetIDsOfNames(
3283 IVBSAXAttributes *iface,
3284 REFIID riid,
3285 LPOLESTR* rgszNames,
3286 UINT cNames,
3287 LCID lcid,
3288 DISPID* rgDispId)
3290 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3291 ITypeInfo *typeinfo;
3292 HRESULT hr;
3294 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
3295 lcid, rgDispId);
3297 if(!rgszNames || cNames == 0 || !rgDispId)
3298 return E_INVALIDARG;
3300 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
3301 if(SUCCEEDED(hr))
3303 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
3304 ITypeInfo_Release(typeinfo);
3307 return hr;
3310 static HRESULT WINAPI VBSAXAttributes_Invoke(
3311 IVBSAXAttributes *iface,
3312 DISPID dispIdMember,
3313 REFIID riid,
3314 LCID lcid,
3315 WORD wFlags,
3316 DISPPARAMS* pDispParams,
3317 VARIANT* pVarResult,
3318 EXCEPINFO* pExcepInfo,
3319 UINT* puArgErr)
3321 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3322 ITypeInfo *typeinfo;
3323 HRESULT hr;
3325 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
3326 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3328 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
3329 if(SUCCEEDED(hr))
3331 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
3332 pDispParams, pVarResult, pExcepInfo, puArgErr);
3333 ITypeInfo_Release(typeinfo);
3336 return hr;
3339 static HRESULT WINAPI VBSAXAttributes_get_length(IVBSAXAttributes* iface, int *len)
3341 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3342 return ISAXAttributes_getLength(&This->ISAXAttributes_iface, len);
3345 static HRESULT WINAPI VBSAXAttributes_getURI(IVBSAXAttributes* iface, int index, BSTR *uri)
3347 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3348 const WCHAR *uriW;
3349 HRESULT hr;
3350 int len;
3352 TRACE("(%p)->(%d %p)\n", This, index, uri);
3354 if (!uri)
3355 return E_POINTER;
3357 *uri = NULL;
3358 hr = ISAXAttributes_getURI(&This->ISAXAttributes_iface, index, &uriW, &len);
3359 if (FAILED(hr))
3360 return hr;
3362 return return_bstrn(uriW, len, uri);
3365 static HRESULT WINAPI VBSAXAttributes_getLocalName(IVBSAXAttributes* iface, int index, BSTR *name)
3367 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3368 const WCHAR *nameW;
3369 HRESULT hr;
3370 int len;
3372 TRACE("(%p)->(%d %p)\n", This, index, name);
3374 if (!name)
3375 return E_POINTER;
3377 *name = NULL;
3378 hr = ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, index, &nameW, &len);
3379 if (FAILED(hr))
3380 return hr;
3382 return return_bstrn(nameW, len, name);
3385 static HRESULT WINAPI VBSAXAttributes_getQName(IVBSAXAttributes* iface, int index, BSTR *qname)
3387 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3388 const WCHAR *qnameW;
3389 HRESULT hr;
3390 int len;
3392 TRACE("(%p)->(%d %p)\n", This, index, qname);
3394 if (!qname)
3395 return E_POINTER;
3397 *qname = NULL;
3398 hr = ISAXAttributes_getQName(&This->ISAXAttributes_iface, index, &qnameW, &len);
3399 if (FAILED(hr))
3400 return hr;
3402 return return_bstrn(qnameW, len, qname);
3405 static HRESULT WINAPI VBSAXAttributes_getIndexFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name, int *index)
3407 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3408 return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3409 name, SysStringLen(name), index);
3412 static HRESULT WINAPI VBSAXAttributes_getIndexFromQName(IVBSAXAttributes* iface, BSTR qname, int *index)
3414 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3415 return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, qname,
3416 SysStringLen(qname), index);
3419 static HRESULT WINAPI VBSAXAttributes_getType(IVBSAXAttributes* iface, int index, BSTR *type)
3421 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3422 const WCHAR *typeW;
3423 HRESULT hr;
3424 int len;
3426 TRACE("(%p)->(%d %p)\n", This, index, type);
3428 if (!type)
3429 return E_POINTER;
3431 *type = NULL;
3432 hr = ISAXAttributes_getType(&This->ISAXAttributes_iface, index, &typeW, &len);
3433 if (FAILED(hr))
3434 return hr;
3436 return return_bstrn(typeW, len, type);
3439 static HRESULT WINAPI VBSAXAttributes_getTypeFromName(IVBSAXAttributes* iface, BSTR uri,
3440 BSTR name, BSTR *type)
3442 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3443 const WCHAR *typeW;
3444 HRESULT hr;
3445 int len;
3447 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), type);
3449 if (!type)
3450 return E_POINTER;
3452 *type = NULL;
3453 hr = ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3454 name, SysStringLen(name), &typeW, &len);
3455 if (FAILED(hr))
3456 return hr;
3458 return return_bstrn(typeW, len, type);
3461 static HRESULT WINAPI VBSAXAttributes_getTypeFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *type)
3463 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3464 const WCHAR *typeW;
3465 HRESULT hr;
3466 int len;
3468 TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), type);
3470 if (!type)
3471 return E_POINTER;
3473 *type = NULL;
3474 hr = ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3475 &typeW, &len);
3476 if (FAILED(hr))
3477 return hr;
3479 return return_bstrn(typeW, len, type);
3482 static HRESULT WINAPI VBSAXAttributes_getValue(IVBSAXAttributes* iface, int index, BSTR *value)
3484 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3485 const WCHAR *valueW;
3486 HRESULT hr;
3487 int len;
3489 TRACE("(%p)->(%d %p)\n", This, index, value);
3491 if (!value)
3492 return E_POINTER;
3494 *value = NULL;
3495 hr = ISAXAttributes_getValue(&This->ISAXAttributes_iface, index, &valueW, &len);
3496 if (FAILED(hr))
3497 return hr;
3499 return return_bstrn(valueW, len, value);
3502 static HRESULT WINAPI VBSAXAttributes_getValueFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name,
3503 BSTR *value)
3505 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3506 const WCHAR *valueW;
3507 HRESULT hr;
3508 int len;
3510 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), value);
3512 if (!value)
3513 return E_POINTER;
3515 *value = NULL;
3516 hr = ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3517 name, SysStringLen(name), &valueW, &len);
3518 if (FAILED(hr))
3519 return hr;
3521 return return_bstrn(valueW, len, value);
3524 static HRESULT WINAPI VBSAXAttributes_getValueFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *value)
3526 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3527 const WCHAR *valueW;
3528 HRESULT hr;
3529 int len;
3531 TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), value);
3533 if (!value)
3534 return E_POINTER;
3536 *value = NULL;
3537 hr = ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3538 &valueW, &len);
3539 if (FAILED(hr))
3540 return hr;
3542 return return_bstrn(valueW, len, value);
3545 static const struct IVBSAXAttributesVtbl VBSAXAttributesVtbl =
3547 VBSAXAttributes_QueryInterface,
3548 VBSAXAttributes_AddRef,
3549 VBSAXAttributes_Release,
3550 VBSAXAttributes_GetTypeInfoCount,
3551 VBSAXAttributes_GetTypeInfo,
3552 VBSAXAttributes_GetIDsOfNames,
3553 VBSAXAttributes_Invoke,
3554 VBSAXAttributes_get_length,
3555 VBSAXAttributes_getURI,
3556 VBSAXAttributes_getLocalName,
3557 VBSAXAttributes_getQName,
3558 VBSAXAttributes_getIndexFromName,
3559 VBSAXAttributes_getIndexFromQName,
3560 VBSAXAttributes_getType,
3561 VBSAXAttributes_getTypeFromName,
3562 VBSAXAttributes_getTypeFromQName,
3563 VBSAXAttributes_getValue,
3564 VBSAXAttributes_getValueFromName,
3565 VBSAXAttributes_getValueFromQName
3568 static const tid_t mxattrs_iface_tids[] = {
3569 IMXAttributes_tid,
3573 static dispex_static_data_t mxattrs_dispex = {
3574 NULL,
3575 IMXAttributes_tid,
3576 NULL,
3577 mxattrs_iface_tids
3580 HRESULT SAXAttributes_create(MSXML_VERSION version, void **ppObj)
3582 static const int default_count = 10;
3583 mxattributes *This;
3585 TRACE("(%p)\n", ppObj);
3587 This = heap_alloc( sizeof (*This) );
3588 if( !This )
3589 return E_OUTOFMEMORY;
3591 This->IMXAttributes_iface.lpVtbl = &MXAttributesVtbl;
3592 This->ISAXAttributes_iface.lpVtbl = &SAXAttributesVtbl;
3593 This->IVBSAXAttributes_iface.lpVtbl = &VBSAXAttributesVtbl;
3594 This->ref = 1;
3596 This->class_version = version;
3598 This->attr = heap_alloc(default_count*sizeof(mxattribute));
3599 This->length = 0;
3600 This->allocated = default_count;
3602 *ppObj = &This->IMXAttributes_iface;
3604 init_dispex(&This->dispex, (IUnknown*)&This->IMXAttributes_iface, &mxattrs_dispex);
3606 TRACE("returning iface %p\n", *ppObj);
3608 return S_OK;