msxml4/tests: Copy namespaces as attributes tests.
[wine.git] / dlls / msxml3 / mxwriter.c
blob4a2844bcf087580ac18cef4a81a406128c2a8675
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
24 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
30 #include "msxml6.h"
32 #include "wine/debug.h"
34 #include "msxml_dispex.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
38 static const WCHAR emptyW[] = {0};
39 static const WCHAR spaceW[] = {' '};
40 static const WCHAR quotW[] = {'\"'};
41 static const WCHAR closetagW[] = {'>','\r','\n'};
42 static const WCHAR crlfW[] = {'\r','\n'};
43 static const WCHAR entityW[] = {'<','!','E','N','T','I','T','Y',' '};
44 static const WCHAR publicW[] = {'P','U','B','L','I','C',' '};
45 static const WCHAR systemW[] = {'S','Y','S','T','E','M',' '};
47 /* should be ordered as encoding names are sorted */
48 typedef enum
50 XmlEncoding_ISO_8859_1 = 0,
51 XmlEncoding_ISO_8859_13,
52 XmlEncoding_ISO_8859_15,
53 XmlEncoding_ISO_8859_2,
54 XmlEncoding_ISO_8859_3,
55 XmlEncoding_ISO_8859_4,
56 XmlEncoding_ISO_8859_5,
57 XmlEncoding_ISO_8859_7,
58 XmlEncoding_ISO_8859_9,
59 XmlEncoding_UTF16,
60 XmlEncoding_UTF8,
61 XmlEncoding_windows_1250,
62 XmlEncoding_windows_1251,
63 XmlEncoding_windows_1252,
64 XmlEncoding_windows_1253,
65 XmlEncoding_windows_1254,
66 XmlEncoding_windows_1255,
67 XmlEncoding_windows_1256,
68 XmlEncoding_windows_1257,
69 XmlEncoding_windows_1258,
70 XmlEncoding_Unknown
71 } xml_encoding;
73 struct xml_encoding_data
75 const WCHAR *encoding;
76 xml_encoding enc;
77 UINT cp;
80 static const WCHAR iso_8859_1W[] = {'i','s','o','-','8','8','5','9','-','1',0};
81 static const WCHAR iso_8859_2W[] = {'i','s','o','-','8','8','5','9','-','2',0};
82 static const WCHAR iso_8859_3W[] = {'i','s','o','-','8','8','5','9','-','3',0};
83 static const WCHAR iso_8859_4W[] = {'i','s','o','-','8','8','5','9','-','4',0};
84 static const WCHAR iso_8859_5W[] = {'i','s','o','-','8','8','5','9','-','5',0};
85 static const WCHAR iso_8859_7W[] = {'i','s','o','-','8','8','5','9','-','7',0};
86 static const WCHAR iso_8859_9W[] = {'i','s','o','-','8','8','5','9','-','9',0};
87 static const WCHAR iso_8859_13W[] = {'i','s','o','-','8','8','5','9','-','1','3',0};
88 static const WCHAR iso_8859_15W[] = {'i','s','o','-','8','8','5','9','-','1','5',0};
89 static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
90 static const WCHAR utf8W[] = {'U','T','F','-','8',0};
91 static const WCHAR windows_1250W[] = {'w','i','n','d','o','w','s','-','1','2','5','0',0};
92 static const WCHAR windows_1251W[] = {'w','i','n','d','o','w','s','-','1','2','5','1',0};
93 static const WCHAR windows_1252W[] = {'w','i','n','d','o','w','s','-','1','2','5','2',0};
94 static const WCHAR windows_1253W[] = {'w','i','n','d','o','w','s','-','1','2','5','3',0};
95 static const WCHAR windows_1254W[] = {'w','i','n','d','o','w','s','-','1','2','5','4',0};
96 static const WCHAR windows_1255W[] = {'w','i','n','d','o','w','s','-','1','2','5','5',0};
97 static const WCHAR windows_1256W[] = {'w','i','n','d','o','w','s','-','1','2','5','6',0};
98 static const WCHAR windows_1257W[] = {'w','i','n','d','o','w','s','-','1','2','5','7',0};
99 static const WCHAR windows_1258W[] = {'w','i','n','d','o','w','s','-','1','2','5','8',0};
101 static const struct xml_encoding_data xml_encoding_map[] = {
102 { iso_8859_1W, XmlEncoding_ISO_8859_1, 28591 },
103 { iso_8859_13W, XmlEncoding_ISO_8859_13, 28603 },
104 { iso_8859_15W, XmlEncoding_ISO_8859_15, 28605 },
105 { iso_8859_2W, XmlEncoding_ISO_8859_2, 28592 },
106 { iso_8859_3W, XmlEncoding_ISO_8859_3, 28593 },
107 { iso_8859_4W, XmlEncoding_ISO_8859_4, 28594 },
108 { iso_8859_5W, XmlEncoding_ISO_8859_5, 28595 },
109 { iso_8859_7W, XmlEncoding_ISO_8859_7, 28597 },
110 { iso_8859_9W, XmlEncoding_ISO_8859_9, 28599 },
111 { utf16W, XmlEncoding_UTF16, ~0 },
112 { utf8W, XmlEncoding_UTF8, CP_UTF8 },
113 { windows_1250W,XmlEncoding_windows_1250, 1250 },
114 { windows_1251W,XmlEncoding_windows_1251, 1251 },
115 { windows_1252W,XmlEncoding_windows_1252, 1252 },
116 { windows_1253W,XmlEncoding_windows_1253, 1253 },
117 { windows_1254W,XmlEncoding_windows_1254, 1254 },
118 { windows_1255W,XmlEncoding_windows_1255, 1255 },
119 { windows_1256W,XmlEncoding_windows_1256, 1256 },
120 { windows_1257W,XmlEncoding_windows_1257, 1257 },
121 { windows_1258W,XmlEncoding_windows_1258, 1258 }
124 typedef enum
126 MXWriter_BOM = 0,
127 MXWriter_DisableEscaping,
128 MXWriter_Indent,
129 MXWriter_OmitXmlDecl,
130 MXWriter_Standalone,
131 MXWriter_LastProp
132 } mxwriter_prop;
134 typedef enum
136 EscapeValue,
137 EscapeText
138 } escape_mode;
140 typedef struct
142 struct list entry;
143 char *data;
144 unsigned int allocated;
145 unsigned int written;
146 } encoded_buffer;
148 typedef struct
150 encoded_buffer encoded;
151 UINT code_page;
152 UINT utf16_total; /* total number of bytes written since last buffer reinitialization */
153 struct list blocks; /* only used when output was not set, for BSTR case */
154 } output_buffer;
156 typedef struct
158 DispatchEx dispex;
159 IMXWriter IMXWriter_iface;
160 ISAXContentHandler ISAXContentHandler_iface;
161 ISAXLexicalHandler ISAXLexicalHandler_iface;
162 ISAXDeclHandler ISAXDeclHandler_iface;
163 ISAXDTDHandler ISAXDTDHandler_iface;
164 ISAXErrorHandler ISAXErrorHandler_iface;
165 IVBSAXDeclHandler IVBSAXDeclHandler_iface;
166 IVBSAXLexicalHandler IVBSAXLexicalHandler_iface;
167 IVBSAXContentHandler IVBSAXContentHandler_iface;
168 IVBSAXDTDHandler IVBSAXDTDHandler_iface;
169 IVBSAXErrorHandler IVBSAXErrorHandler_iface;
171 LONG ref;
172 MSXML_VERSION class_version;
174 VARIANT_BOOL props[MXWriter_LastProp];
175 BOOL prop_changed;
176 BOOL cdata;
178 BOOL text; /* last node was text node, so we shouldn't indent next node */
179 BOOL newline; /* newline was already added as a part of previous call */
180 UINT indent; /* indentation level for next node */
182 BSTR version;
184 BSTR encoding; /* exact property value */
185 xml_encoding xml_enc;
187 /* contains a pending (or not closed yet) element name or NULL if
188 we don't have to close */
189 BSTR element;
191 IStream *dest;
193 output_buffer buffer;
194 } mxwriter;
196 typedef struct
198 BSTR qname;
199 BSTR local;
200 BSTR uri;
201 BSTR type;
202 BSTR value;
203 } mxattribute;
205 typedef struct
207 DispatchEx dispex;
208 IMXAttributes IMXAttributes_iface;
209 ISAXAttributes ISAXAttributes_iface;
210 IVBSAXAttributes IVBSAXAttributes_iface;
211 LONG ref;
213 MSXML_VERSION class_version;
215 mxattribute *attr;
216 int length;
217 int allocated;
218 } mxattributes;
220 static inline mxattributes *impl_from_IMXAttributes( IMXAttributes *iface )
222 return CONTAINING_RECORD(iface, mxattributes, IMXAttributes_iface);
225 static inline mxattributes *impl_from_ISAXAttributes( ISAXAttributes *iface )
227 return CONTAINING_RECORD(iface, mxattributes, ISAXAttributes_iface);
230 static inline mxattributes *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
232 return CONTAINING_RECORD(iface, mxattributes, IVBSAXAttributes_iface);
235 static HRESULT mxattributes_grow(mxattributes *This)
237 if (This->length < This->allocated) return S_OK;
239 This->allocated *= 2;
240 This->attr = heap_realloc(This->attr, This->allocated*sizeof(mxattribute));
242 return This->attr ? S_OK : E_OUTOFMEMORY;
245 static xml_encoding parse_encoding_name(const WCHAR *encoding)
247 int min, max, n, c;
249 min = 0;
250 max = ARRAY_SIZE(xml_encoding_map) - 1;
252 while (min <= max)
254 n = (min+max)/2;
256 c = lstrcmpiW(xml_encoding_map[n].encoding, encoding);
257 if (!c)
258 return xml_encoding_map[n].enc;
260 if (c > 0)
261 max = n-1;
262 else
263 min = n+1;
266 return XmlEncoding_Unknown;
269 static HRESULT init_encoded_buffer(encoded_buffer *buffer)
271 const int initial_len = 0x1000;
272 buffer->data = heap_alloc(initial_len);
273 if (!buffer->data) return E_OUTOFMEMORY;
275 memset(buffer->data, 0, 4);
276 buffer->allocated = initial_len;
277 buffer->written = 0;
279 return S_OK;
282 static void free_encoded_buffer(encoded_buffer *buffer)
284 heap_free(buffer->data);
287 static HRESULT get_code_page(xml_encoding encoding, UINT *cp)
289 const struct xml_encoding_data *data;
291 if (encoding == XmlEncoding_Unknown)
293 FIXME("unsupported encoding %d\n", encoding);
294 return E_NOTIMPL;
297 data = &xml_encoding_map[encoding];
298 *cp = data->cp;
300 return S_OK;
303 static HRESULT init_output_buffer(xml_encoding encoding, output_buffer *buffer)
305 HRESULT hr;
307 hr = get_code_page(encoding, &buffer->code_page);
308 if (hr != S_OK)
309 return hr;
311 hr = init_encoded_buffer(&buffer->encoded);
312 if (hr != S_OK)
313 return hr;
315 list_init(&buffer->blocks);
316 buffer->utf16_total = 0;
318 return S_OK;
321 static void free_output_buffer(output_buffer *buffer)
323 encoded_buffer *cur, *cur2;
325 free_encoded_buffer(&buffer->encoded);
327 LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &buffer->blocks, encoded_buffer, entry)
329 list_remove(&cur->entry);
330 free_encoded_buffer(cur);
331 heap_free(cur);
335 static HRESULT write_output_buffer(mxwriter *writer, const WCHAR *data, int len)
337 output_buffer *buffer = &writer->buffer;
338 encoded_buffer *buff;
339 ULONG written;
340 int src_len;
342 if (!len || !*data)
343 return S_OK;
345 src_len = len == -1 ? lstrlenW(data) : len;
346 if (writer->dest)
348 buff = &buffer->encoded;
350 if (buffer->code_page == ~0)
352 unsigned int avail = buff->allocated - buff->written;
354 src_len *= sizeof(WCHAR);
355 written = min(avail, src_len);
357 /* fill internal buffer first */
358 if (avail)
360 memcpy(buff->data + buff->written, data, written);
361 data += written / sizeof(WCHAR);
362 buff->written += written;
363 avail -= written;
364 src_len -= written;
367 if (!avail)
369 IStream_Write(writer->dest, buff->data, buff->written, &written);
370 buff->written = 0;
371 if (src_len >= buff->allocated)
372 IStream_Write(writer->dest, data, src_len, &written);
373 else if (src_len)
375 memcpy(buff->data, data, src_len);
376 buff->written += src_len;
380 else
382 unsigned int avail = buff->allocated - buff->written;
383 int length;
385 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, NULL, 0, NULL, NULL);
386 if (avail >= length)
388 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, buff->data + buff->written, length, NULL, NULL);
389 buff->written += length;
391 else
393 /* drain what we go so far */
394 if (buff->written)
396 IStream_Write(writer->dest, buff->data, buff->written, &written);
397 buff->written = 0;
398 avail = buff->allocated;
401 if (avail >= length)
403 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, buff->data + buff->written, length, NULL, NULL);
404 buff->written += length;
406 else
408 char *mb;
410 /* if current chunk is larger than total buffer size, convert it at once using temporary allocated buffer */
411 mb = heap_alloc(length);
412 if (!mb)
413 return E_OUTOFMEMORY;
415 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, mb, length, NULL, NULL);
416 IStream_Write(writer->dest, mb, length, &written);
417 heap_free(mb);
422 /* When writer has no output set we have to accumulate everything to return it later in a form of BSTR.
423 To achieve that:
425 - fill a buffer already allocated as part of output buffer;
426 - when current buffer is full, allocate another one and switch to it; buffers themselves never grow,
427 but are linked together, with head pointing to first allocated buffer after initial one got filled;
428 - later during get_output() contents are concatenated by copying one after another to destination BSTR buffer,
429 that's returned to the client. */
430 else
432 /* select last used block */
433 if (list_empty(&buffer->blocks))
434 buff = &buffer->encoded;
435 else
436 buff = LIST_ENTRY(list_tail(&buffer->blocks), encoded_buffer, entry);
438 src_len *= sizeof(WCHAR);
439 while (src_len)
441 unsigned int avail = buff->allocated - buff->written;
442 unsigned int written = min(avail, src_len);
444 if (avail)
446 memcpy(buff->data + buff->written, data, written);
447 buff->written += written;
448 buffer->utf16_total += written;
449 src_len -= written;
452 /* alloc new block if needed and retry */
453 if (src_len)
455 encoded_buffer *next = heap_alloc(sizeof(*next));
456 HRESULT hr;
458 if (FAILED(hr = init_encoded_buffer(next))) {
459 heap_free(next);
460 return hr;
463 list_add_tail(&buffer->blocks, &next->entry);
464 buff = next;
469 return S_OK;
472 static HRESULT write_output_buffer_quoted(mxwriter *writer, const WCHAR *data, int len)
474 write_output_buffer(writer, quotW, 1);
475 write_output_buffer(writer, data, len);
476 write_output_buffer(writer, quotW, 1);
478 return S_OK;
481 /* frees buffer data, reallocates with a default lengths */
482 static void close_output_buffer(mxwriter *writer)
484 encoded_buffer *cur, *cur2;
486 heap_free(writer->buffer.encoded.data);
488 LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &writer->buffer.blocks, encoded_buffer, entry)
490 list_remove(&cur->entry);
491 free_encoded_buffer(cur);
492 heap_free(cur);
495 init_encoded_buffer(&writer->buffer.encoded);
496 get_code_page(writer->xml_enc, &writer->buffer.code_page);
497 writer->buffer.utf16_total = 0;
498 list_init(&writer->buffer.blocks);
501 /* Escapes special characters like:
502 '<' -> "&lt;"
503 '&' -> "&amp;"
504 '"' -> "&quot;"
505 '>' -> "&gt;"
507 On call 'len' contains a length of 'str' in chars or -1 if it's null terminated.
508 After a call it's updated with actual new length if it wasn't -1 initially.
510 static WCHAR *get_escaped_string(const WCHAR *str, escape_mode mode, int *len)
512 static const WCHAR ltW[] = {'&','l','t',';'};
513 static const WCHAR ampW[] = {'&','a','m','p',';'};
514 static const WCHAR equotW[] = {'&','q','u','o','t',';'};
515 static const WCHAR gtW[] = {'&','g','t',';'};
517 const int default_alloc = 100;
518 const int grow_thresh = 10;
519 int p = *len, conv_len;
520 WCHAR *ptr, *ret;
522 /* default buffer size to something if length is unknown */
523 conv_len = max(2**len, default_alloc);
524 ptr = ret = heap_alloc(conv_len*sizeof(WCHAR));
526 while (p)
528 if (ptr - ret > conv_len - grow_thresh)
530 int written = ptr - ret;
531 conv_len *= 2;
532 ptr = ret = heap_realloc(ret, conv_len*sizeof(WCHAR));
533 ptr += written;
536 switch (*str)
538 case '<':
539 memcpy(ptr, ltW, sizeof(ltW));
540 ptr += ARRAY_SIZE(ltW);
541 break;
542 case '&':
543 memcpy(ptr, ampW, sizeof(ampW));
544 ptr += ARRAY_SIZE(ampW);
545 break;
546 case '>':
547 memcpy(ptr, gtW, sizeof(gtW));
548 ptr += ARRAY_SIZE(gtW);
549 break;
550 case '"':
551 if (mode == EscapeValue)
553 memcpy(ptr, equotW, sizeof(equotW));
554 ptr += ARRAY_SIZE(equotW);
555 break;
557 /* fallthrough for text mode */
558 default:
559 *ptr++ = *str;
560 break;
563 str++;
564 p--;
567 *len = ptr-ret;
568 *++ptr = 0;
570 return ret;
573 static void write_prolog_buffer(mxwriter *writer)
575 static const WCHAR versionW[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','='};
576 static const WCHAR encodingW[] = {' ','e','n','c','o','d','i','n','g','=','\"'};
577 static const WCHAR standaloneW[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
578 static const WCHAR yesW[] = {'y','e','s','\"','?','>'};
579 static const WCHAR noW[] = {'n','o','\"','?','>'};
581 /* version */
582 write_output_buffer(writer, versionW, ARRAY_SIZE(versionW));
583 write_output_buffer_quoted(writer, writer->version, -1);
585 /* encoding */
586 write_output_buffer(writer, encodingW, ARRAY_SIZE(encodingW));
588 if (writer->dest)
589 write_output_buffer(writer, writer->encoding, -1);
590 else
591 write_output_buffer(writer, utf16W, ARRAY_SIZE(utf16W) - 1);
592 write_output_buffer(writer, quotW, 1);
594 /* standalone */
595 write_output_buffer(writer, standaloneW, ARRAY_SIZE(standaloneW));
596 if (writer->props[MXWriter_Standalone] == VARIANT_TRUE)
597 write_output_buffer(writer, yesW, ARRAY_SIZE(yesW));
598 else
599 write_output_buffer(writer, noW, ARRAY_SIZE(noW));
601 write_output_buffer(writer, crlfW, ARRAY_SIZE(crlfW));
602 writer->newline = TRUE;
605 /* Attempts to the write data from the mxwriter's buffer to
606 * the destination stream (if there is one).
608 static HRESULT write_data_to_stream(mxwriter *writer)
610 encoded_buffer *buffer = &writer->buffer.encoded;
611 ULONG written = 0;
613 if (!writer->dest)
614 return S_OK;
616 if (buffer->written == 0)
618 if (writer->xml_enc == XmlEncoding_UTF8)
619 IStream_Write(writer->dest, buffer->data, 0, &written);
621 else
623 IStream_Write(writer->dest, buffer->data, buffer->written, &written);
624 buffer->written = 0;
627 return S_OK;
630 /* Newly added element start tag left unclosed cause for empty elements
631 we have to close it differently. */
632 static void close_element_starttag(mxwriter *writer)
634 static const WCHAR gtW[] = {'>'};
635 if (!writer->element) return;
636 write_output_buffer(writer, gtW, 1);
639 static void write_node_indent(mxwriter *writer)
641 static const WCHAR tabW[] = {'\t'};
642 int indent = writer->indent;
644 if (!writer->props[MXWriter_Indent] || writer->text)
646 writer->text = FALSE;
647 return;
650 /* This is to workaround PI output logic that always puts newline chars,
651 document prolog PI does that too. */
652 if (!writer->newline)
653 write_output_buffer(writer, crlfW, ARRAY_SIZE(crlfW));
654 while (indent--)
655 write_output_buffer(writer, tabW, 1);
657 writer->newline = FALSE;
658 writer->text = FALSE;
661 static inline void writer_inc_indent(mxwriter *This)
663 This->indent++;
666 static inline void writer_dec_indent(mxwriter *This)
668 if (This->indent) This->indent--;
669 /* depth is decreased only when element is closed, meaning it's not a text node
670 at this point */
671 This->text = FALSE;
674 static void set_element_name(mxwriter *This, const WCHAR *name, int len)
676 SysFreeString(This->element);
677 if (name)
678 This->element = len != -1 ? SysAllocStringLen(name, len) : SysAllocString(name);
679 else
680 This->element = NULL;
683 static inline HRESULT flush_output_buffer(mxwriter *This)
685 close_element_starttag(This);
686 set_element_name(This, NULL, 0);
687 This->cdata = FALSE;
688 return write_data_to_stream(This);
691 static HRESULT writer_set_property(mxwriter *writer, mxwriter_prop property, VARIANT_BOOL value)
693 writer->props[property] = value;
694 writer->prop_changed = TRUE;
695 return S_OK;
698 static HRESULT writer_get_property(const mxwriter *writer, mxwriter_prop property, VARIANT_BOOL *value)
700 if (!value) return E_POINTER;
701 *value = writer->props[property];
702 return S_OK;
705 static inline mxwriter *impl_from_IMXWriter(IMXWriter *iface)
707 return CONTAINING_RECORD(iface, mxwriter, IMXWriter_iface);
710 static inline mxwriter *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
712 return CONTAINING_RECORD(iface, mxwriter, ISAXContentHandler_iface);
715 static inline mxwriter *impl_from_IVBSAXContentHandler(IVBSAXContentHandler *iface)
717 return CONTAINING_RECORD(iface, mxwriter, IVBSAXContentHandler_iface);
720 static inline mxwriter *impl_from_ISAXLexicalHandler(ISAXLexicalHandler *iface)
722 return CONTAINING_RECORD(iface, mxwriter, ISAXLexicalHandler_iface);
725 static inline mxwriter *impl_from_IVBSAXLexicalHandler(IVBSAXLexicalHandler *iface)
727 return CONTAINING_RECORD(iface, mxwriter, IVBSAXLexicalHandler_iface);
730 static inline mxwriter *impl_from_ISAXDeclHandler(ISAXDeclHandler *iface)
732 return CONTAINING_RECORD(iface, mxwriter, ISAXDeclHandler_iface);
735 static inline mxwriter *impl_from_IVBSAXDeclHandler(IVBSAXDeclHandler *iface)
737 return CONTAINING_RECORD(iface, mxwriter, IVBSAXDeclHandler_iface);
740 static inline mxwriter *impl_from_ISAXDTDHandler(ISAXDTDHandler *iface)
742 return CONTAINING_RECORD(iface, mxwriter, ISAXDTDHandler_iface);
745 static inline mxwriter *impl_from_IVBSAXDTDHandler(IVBSAXDTDHandler *iface)
747 return CONTAINING_RECORD(iface, mxwriter, IVBSAXDTDHandler_iface);
750 static inline mxwriter *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
752 return CONTAINING_RECORD(iface, mxwriter, ISAXErrorHandler_iface);
755 static inline mxwriter *impl_from_IVBSAXErrorHandler(IVBSAXErrorHandler *iface)
757 return CONTAINING_RECORD(iface, mxwriter, IVBSAXErrorHandler_iface);
760 static HRESULT WINAPI mxwriter_QueryInterface(IMXWriter *iface, REFIID riid, void **obj)
762 mxwriter *This = impl_from_IMXWriter( iface );
764 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
766 *obj = NULL;
768 if ( IsEqualGUID( riid, &IID_IMXWriter ) ||
769 IsEqualGUID( riid, &IID_IDispatch ) ||
770 IsEqualGUID( riid, &IID_IUnknown ) )
772 *obj = &This->IMXWriter_iface;
774 else if ( IsEqualGUID( riid, &IID_ISAXContentHandler ) )
776 *obj = &This->ISAXContentHandler_iface;
778 else if ( IsEqualGUID( riid, &IID_ISAXLexicalHandler ) )
780 *obj = &This->ISAXLexicalHandler_iface;
782 else if ( IsEqualGUID( riid, &IID_ISAXDeclHandler ) )
784 *obj = &This->ISAXDeclHandler_iface;
786 else if ( IsEqualGUID( riid, &IID_ISAXDTDHandler ) )
788 *obj = &This->ISAXDTDHandler_iface;
790 else if ( IsEqualGUID( riid, &IID_ISAXErrorHandler ) )
792 *obj = &This->ISAXErrorHandler_iface;
794 else if ( IsEqualGUID( riid, &IID_IVBSAXDeclHandler ) )
796 *obj = &This->IVBSAXDeclHandler_iface;
798 else if ( IsEqualGUID( riid, &IID_IVBSAXLexicalHandler ) )
800 *obj = &This->IVBSAXLexicalHandler_iface;
802 else if ( IsEqualGUID( riid, &IID_IVBSAXContentHandler ) )
804 *obj = &This->IVBSAXContentHandler_iface;
806 else if ( IsEqualGUID( riid, &IID_IVBSAXDTDHandler ) )
808 *obj = &This->IVBSAXDTDHandler_iface;
810 else if ( IsEqualGUID( riid, &IID_IVBSAXErrorHandler ) )
812 *obj = &This->IVBSAXErrorHandler_iface;
814 else if (dispex_query_interface(&This->dispex, riid, obj))
816 return *obj ? S_OK : E_NOINTERFACE;
818 else
820 ERR("interface %s not implemented\n", debugstr_guid(riid));
821 *obj = NULL;
822 return E_NOINTERFACE;
825 IMXWriter_AddRef(iface);
826 return S_OK;
829 static ULONG WINAPI mxwriter_AddRef(IMXWriter *iface)
831 mxwriter *writer = impl_from_IMXWriter(iface);
832 LONG ref = InterlockedIncrement(&writer->ref);
834 TRACE("%p, refcount %lu.\n", iface, ref);
836 return ref;
839 static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
841 mxwriter *This = impl_from_IMXWriter( iface );
842 ULONG ref = InterlockedDecrement(&This->ref);
844 TRACE("%p, refcount %lu.\n", iface, ref);
846 if (!ref)
848 /* Windows flushes the buffer when the interface is destroyed. */
849 flush_output_buffer(This);
850 free_output_buffer(&This->buffer);
852 if (This->dest) IStream_Release(This->dest);
853 SysFreeString(This->version);
854 SysFreeString(This->encoding);
856 SysFreeString(This->element);
857 heap_free(This);
860 return ref;
863 static HRESULT WINAPI mxwriter_GetTypeInfoCount(IMXWriter *iface, UINT* pctinfo)
865 mxwriter *This = impl_from_IMXWriter( iface );
866 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
869 static HRESULT WINAPI mxwriter_GetTypeInfo(
870 IMXWriter *iface,
871 UINT iTInfo, LCID lcid,
872 ITypeInfo** ppTInfo )
874 mxwriter *This = impl_from_IMXWriter( iface );
875 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
876 iTInfo, lcid, ppTInfo);
879 static HRESULT WINAPI mxwriter_GetIDsOfNames(
880 IMXWriter *iface,
881 REFIID riid, LPOLESTR* rgszNames,
882 UINT cNames, LCID lcid, DISPID* rgDispId )
884 mxwriter *This = impl_from_IMXWriter( iface );
885 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
886 riid, rgszNames, cNames, lcid, rgDispId);
889 static HRESULT WINAPI mxwriter_Invoke(
890 IMXWriter *iface,
891 DISPID dispIdMember, REFIID riid, LCID lcid,
892 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
893 EXCEPINFO* pExcepInfo, UINT* puArgErr )
895 mxwriter *This = impl_from_IMXWriter( iface );
896 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
897 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
900 static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
902 mxwriter *This = impl_from_IMXWriter( iface );
903 HRESULT hr;
905 TRACE("(%p)->(%s)\n", This, debugstr_variant(&dest));
907 hr = flush_output_buffer(This);
908 if (FAILED(hr))
909 return hr;
911 switch (V_VT(&dest))
913 case VT_EMPTY:
915 if (This->dest) IStream_Release(This->dest);
916 This->dest = NULL;
917 close_output_buffer(This);
918 break;
920 case VT_UNKNOWN:
922 IStream *stream;
924 hr = IUnknown_QueryInterface(V_UNKNOWN(&dest), &IID_IStream, (void**)&stream);
925 if (hr == S_OK)
927 /* Recreate the output buffer to make sure it's using the correct encoding. */
928 close_output_buffer(This);
930 if (This->dest) IStream_Release(This->dest);
931 This->dest = stream;
932 break;
935 FIXME("unhandled interface type for VT_UNKNOWN destination\n");
936 return E_NOTIMPL;
938 default:
939 FIXME("unhandled destination type %s\n", debugstr_variant(&dest));
940 return E_NOTIMPL;
943 return S_OK;
946 static HRESULT WINAPI mxwriter_get_output(IMXWriter *iface, VARIANT *dest)
948 mxwriter *This = impl_from_IMXWriter( iface );
950 TRACE("(%p)->(%p)\n", This, dest);
952 if (!dest) return E_POINTER;
954 if (This->dest)
956 /* we only support IStream output so far */
957 V_VT(dest) = VT_UNKNOWN;
958 V_UNKNOWN(dest) = (IUnknown*)This->dest;
959 IStream_AddRef(This->dest);
961 else
963 encoded_buffer *buff;
964 char *dest_ptr;
965 HRESULT hr;
967 hr = flush_output_buffer(This);
968 if (FAILED(hr))
969 return hr;
971 V_VT(dest) = VT_BSTR;
972 V_BSTR(dest) = SysAllocStringLen(NULL, This->buffer.utf16_total / sizeof(WCHAR));
973 if (!V_BSTR(dest))
974 return E_OUTOFMEMORY;
976 dest_ptr = (char*)V_BSTR(dest);
977 buff = &This->buffer.encoded;
979 if (buff->written)
981 memcpy(dest_ptr, buff->data, buff->written);
982 dest_ptr += buff->written;
985 LIST_FOR_EACH_ENTRY(buff, &This->buffer.blocks, encoded_buffer, entry)
987 memcpy(dest_ptr, buff->data, buff->written);
988 dest_ptr += buff->written;
992 return S_OK;
995 static HRESULT WINAPI mxwriter_put_encoding(IMXWriter *iface, BSTR encoding)
997 mxwriter *This = impl_from_IMXWriter( iface );
998 xml_encoding enc;
999 HRESULT hr;
1001 TRACE("(%p)->(%s)\n", This, debugstr_w(encoding));
1003 enc = parse_encoding_name(encoding);
1004 if (enc == XmlEncoding_Unknown)
1006 FIXME("unsupported encoding %s\n", debugstr_w(encoding));
1007 return E_INVALIDARG;
1010 hr = flush_output_buffer(This);
1011 if (FAILED(hr))
1012 return hr;
1014 SysReAllocString(&This->encoding, encoding);
1015 This->xml_enc = enc;
1017 TRACE("got encoding %d\n", This->xml_enc);
1018 close_output_buffer(This);
1019 return S_OK;
1022 static HRESULT WINAPI mxwriter_get_encoding(IMXWriter *iface, BSTR *encoding)
1024 mxwriter *This = impl_from_IMXWriter( iface );
1026 TRACE("(%p)->(%p)\n", This, encoding);
1028 if (!encoding) return E_POINTER;
1030 *encoding = SysAllocString(This->encoding);
1031 if (!*encoding) return E_OUTOFMEMORY;
1033 return S_OK;
1036 static HRESULT WINAPI mxwriter_put_byteOrderMark(IMXWriter *iface, VARIANT_BOOL value)
1038 mxwriter *This = impl_from_IMXWriter( iface );
1040 TRACE("(%p)->(%d)\n", This, value);
1041 return writer_set_property(This, MXWriter_BOM, value);
1044 static HRESULT WINAPI mxwriter_get_byteOrderMark(IMXWriter *iface, VARIANT_BOOL *value)
1046 mxwriter *This = impl_from_IMXWriter( iface );
1048 TRACE("(%p)->(%p)\n", This, value);
1049 return writer_get_property(This, MXWriter_BOM, value);
1052 static HRESULT WINAPI mxwriter_put_indent(IMXWriter *iface, VARIANT_BOOL value)
1054 mxwriter *This = impl_from_IMXWriter( iface );
1056 TRACE("(%p)->(%d)\n", This, value);
1057 return writer_set_property(This, MXWriter_Indent, value);
1060 static HRESULT WINAPI mxwriter_get_indent(IMXWriter *iface, VARIANT_BOOL *value)
1062 mxwriter *This = impl_from_IMXWriter( iface );
1064 TRACE("(%p)->(%p)\n", This, value);
1065 return writer_get_property(This, MXWriter_Indent, value);
1068 static HRESULT WINAPI mxwriter_put_standalone(IMXWriter *iface, VARIANT_BOOL value)
1070 mxwriter *This = impl_from_IMXWriter( iface );
1072 TRACE("(%p)->(%d)\n", This, value);
1073 return writer_set_property(This, MXWriter_Standalone, value);
1076 static HRESULT WINAPI mxwriter_get_standalone(IMXWriter *iface, VARIANT_BOOL *value)
1078 mxwriter *This = impl_from_IMXWriter( iface );
1080 TRACE("(%p)->(%p)\n", This, value);
1081 return writer_get_property(This, MXWriter_Standalone, value);
1084 static HRESULT WINAPI mxwriter_put_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL value)
1086 mxwriter *This = impl_from_IMXWriter( iface );
1088 TRACE("(%p)->(%d)\n", This, value);
1089 return writer_set_property(This, MXWriter_OmitXmlDecl, value);
1092 static HRESULT WINAPI mxwriter_get_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL *value)
1094 mxwriter *This = impl_from_IMXWriter( iface );
1096 TRACE("(%p)->(%p)\n", This, value);
1097 return writer_get_property(This, MXWriter_OmitXmlDecl, value);
1100 static HRESULT WINAPI mxwriter_put_version(IMXWriter *iface, BSTR version)
1102 mxwriter *This = impl_from_IMXWriter( iface );
1104 TRACE("(%p)->(%s)\n", This, debugstr_w(version));
1106 if (!version) return E_INVALIDARG;
1108 SysFreeString(This->version);
1109 This->version = SysAllocString(version);
1111 return S_OK;
1114 static HRESULT WINAPI mxwriter_get_version(IMXWriter *iface, BSTR *version)
1116 mxwriter *This = impl_from_IMXWriter( iface );
1118 TRACE("(%p)->(%p)\n", This, version);
1120 if (!version) return E_POINTER;
1122 return return_bstr(This->version, version);
1125 static HRESULT WINAPI mxwriter_put_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL value)
1127 mxwriter *This = impl_from_IMXWriter( iface );
1129 TRACE("(%p)->(%d)\n", This, value);
1130 return writer_set_property(This, MXWriter_DisableEscaping, value);
1133 static HRESULT WINAPI mxwriter_get_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL *value)
1135 mxwriter *This = impl_from_IMXWriter( iface );
1137 TRACE("(%p)->(%p)\n", This, value);
1138 return writer_get_property(This, MXWriter_DisableEscaping, value);
1141 static HRESULT WINAPI mxwriter_flush(IMXWriter *iface)
1143 mxwriter *This = impl_from_IMXWriter( iface );
1144 TRACE("(%p)\n", This);
1145 return flush_output_buffer(This);
1148 static const struct IMXWriterVtbl MXWriterVtbl =
1150 mxwriter_QueryInterface,
1151 mxwriter_AddRef,
1152 mxwriter_Release,
1153 mxwriter_GetTypeInfoCount,
1154 mxwriter_GetTypeInfo,
1155 mxwriter_GetIDsOfNames,
1156 mxwriter_Invoke,
1157 mxwriter_put_output,
1158 mxwriter_get_output,
1159 mxwriter_put_encoding,
1160 mxwriter_get_encoding,
1161 mxwriter_put_byteOrderMark,
1162 mxwriter_get_byteOrderMark,
1163 mxwriter_put_indent,
1164 mxwriter_get_indent,
1165 mxwriter_put_standalone,
1166 mxwriter_get_standalone,
1167 mxwriter_put_omitXMLDeclaration,
1168 mxwriter_get_omitXMLDeclaration,
1169 mxwriter_put_version,
1170 mxwriter_get_version,
1171 mxwriter_put_disableOutputEscaping,
1172 mxwriter_get_disableOutputEscaping,
1173 mxwriter_flush
1176 /*** ISAXContentHandler ***/
1177 static HRESULT WINAPI SAXContentHandler_QueryInterface(
1178 ISAXContentHandler *iface,
1179 REFIID riid,
1180 void **obj)
1182 mxwriter *This = impl_from_ISAXContentHandler( iface );
1183 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1186 static ULONG WINAPI SAXContentHandler_AddRef(ISAXContentHandler *iface)
1188 mxwriter *This = impl_from_ISAXContentHandler( iface );
1189 return IMXWriter_AddRef(&This->IMXWriter_iface);
1192 static ULONG WINAPI SAXContentHandler_Release(ISAXContentHandler *iface)
1194 mxwriter *This = impl_from_ISAXContentHandler( iface );
1195 return IMXWriter_Release(&This->IMXWriter_iface);
1198 static HRESULT WINAPI SAXContentHandler_putDocumentLocator(
1199 ISAXContentHandler *iface,
1200 ISAXLocator *locator)
1202 mxwriter *This = impl_from_ISAXContentHandler( iface );
1203 FIXME("(%p)->(%p)\n", This, locator);
1204 return E_NOTIMPL;
1207 static HRESULT WINAPI SAXContentHandler_startDocument(ISAXContentHandler *iface)
1209 mxwriter *This = impl_from_ISAXContentHandler( iface );
1211 TRACE("(%p)\n", This);
1213 /* If properties have been changed since the last "endDocument" call
1214 * we need to reset the output buffer. If we don't the output buffer
1215 * could end up with multiple XML documents in it, plus this seems to
1216 * be how Windows works.
1218 if (This->prop_changed) {
1219 close_output_buffer(This);
1220 This->prop_changed = FALSE;
1223 if (This->props[MXWriter_OmitXmlDecl] == VARIANT_TRUE) return S_OK;
1225 write_prolog_buffer(This);
1227 if (This->dest && This->xml_enc == XmlEncoding_UTF16) {
1228 static const char utf16BOM[] = {0xff,0xfe};
1230 if (This->props[MXWriter_BOM] == VARIANT_TRUE)
1231 /* Windows passes a NULL pointer as the pcbWritten parameter and
1232 * ignores any error codes returned from this Write call.
1234 IStream_Write(This->dest, utf16BOM, sizeof(utf16BOM), NULL);
1237 return S_OK;
1240 static HRESULT WINAPI SAXContentHandler_endDocument(ISAXContentHandler *iface)
1242 mxwriter *This = impl_from_ISAXContentHandler( iface );
1243 TRACE("(%p)\n", This);
1244 This->prop_changed = FALSE;
1245 return flush_output_buffer(This);
1248 static HRESULT WINAPI SAXContentHandler_startPrefixMapping(
1249 ISAXContentHandler *iface,
1250 const WCHAR *prefix,
1251 int nprefix,
1252 const WCHAR *uri,
1253 int nuri)
1255 mxwriter *This = impl_from_ISAXContentHandler( iface );
1256 TRACE("(%p)->(%s %s)\n", This, debugstr_wn(prefix, nprefix), debugstr_wn(uri, nuri));
1257 return S_OK;
1260 static HRESULT WINAPI SAXContentHandler_endPrefixMapping(
1261 ISAXContentHandler *iface,
1262 const WCHAR *prefix,
1263 int nprefix)
1265 mxwriter *This = impl_from_ISAXContentHandler( iface );
1266 TRACE("(%p)->(%s)\n", This, debugstr_wn(prefix, nprefix));
1267 return S_OK;
1270 static void mxwriter_write_attribute(mxwriter *writer, const WCHAR *qname, int qname_len,
1271 const WCHAR *value, int value_len, BOOL escape)
1273 static const WCHAR eqW[] = {'='};
1275 /* space separator in front of every attribute */
1276 write_output_buffer(writer, spaceW, 1);
1277 write_output_buffer(writer, qname, qname_len);
1278 write_output_buffer(writer, eqW, 1);
1280 if (escape)
1282 WCHAR *escaped = get_escaped_string(value, EscapeValue, &value_len);
1283 write_output_buffer_quoted(writer, escaped, value_len);
1284 heap_free(escaped);
1286 else
1287 write_output_buffer_quoted(writer, value, value_len);
1290 static void mxwriter_write_starttag(mxwriter *writer, const WCHAR *qname, int len)
1292 static const WCHAR ltW[] = {'<'};
1294 close_element_starttag(writer);
1295 set_element_name(writer, qname ? qname : emptyW, qname ? len : 0);
1297 write_node_indent(writer);
1299 write_output_buffer(writer, ltW, 1);
1300 write_output_buffer(writer, qname ? qname : emptyW, qname ? len : 0);
1301 writer_inc_indent(writer);
1304 static HRESULT WINAPI SAXContentHandler_startElement(
1305 ISAXContentHandler *iface,
1306 const WCHAR *namespaceUri,
1307 int nnamespaceUri,
1308 const WCHAR *local_name,
1309 int nlocal_name,
1310 const WCHAR *QName,
1311 int nQName,
1312 ISAXAttributes *attr)
1314 mxwriter *This = impl_from_ISAXContentHandler( iface );
1316 TRACE("(%p)->(%s %s %s %p)\n", This, debugstr_wn(namespaceUri, nnamespaceUri),
1317 debugstr_wn(local_name, nlocal_name), debugstr_wn(QName, nQName), attr);
1319 if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1320 (nQName == -1 && This->class_version == MSXML6))
1321 return E_INVALIDARG;
1323 mxwriter_write_starttag(This, QName, nQName);
1325 if (attr)
1327 int length, i, escape;
1328 HRESULT hr;
1330 hr = ISAXAttributes_getLength(attr, &length);
1331 if (FAILED(hr)) return hr;
1333 escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
1334 (This->class_version == MSXML4 || This->class_version == MSXML6);
1336 for (i = 0; i < length; i++)
1338 int qname_len = 0, value_len = 0;
1339 const WCHAR *qname, *value;
1341 hr = ISAXAttributes_getQName(attr, i, &qname, &qname_len);
1342 if (FAILED(hr)) return hr;
1344 hr = ISAXAttributes_getValue(attr, i, &value, &value_len);
1345 if (FAILED(hr)) return hr;
1347 mxwriter_write_attribute(This, qname, qname_len, value, value_len, escape);
1351 return S_OK;
1354 static HRESULT WINAPI SAXContentHandler_endElement(
1355 ISAXContentHandler *iface,
1356 const WCHAR *namespaceUri,
1357 int nnamespaceUri,
1358 const WCHAR * local_name,
1359 int nlocal_name,
1360 const WCHAR *QName,
1361 int nQName)
1363 mxwriter *This = impl_from_ISAXContentHandler( iface );
1365 TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(namespaceUri, nnamespaceUri), nnamespaceUri,
1366 debugstr_wn(local_name, nlocal_name), nlocal_name, debugstr_wn(QName, nQName), nQName);
1368 if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1369 (nQName == -1 && This->class_version == MSXML6))
1370 return E_INVALIDARG;
1372 writer_dec_indent(This);
1374 if (This->element)
1376 static const WCHAR closeW[] = {'/','>'};
1377 write_output_buffer(This, closeW, 2);
1379 else
1381 static const WCHAR closetagW[] = {'<','/'};
1382 static const WCHAR gtW[] = {'>'};
1384 write_node_indent(This);
1385 write_output_buffer(This, closetagW, 2);
1386 write_output_buffer(This, QName, nQName);
1387 write_output_buffer(This, gtW, 1);
1390 set_element_name(This, NULL, 0);
1392 return S_OK;
1395 static HRESULT WINAPI SAXContentHandler_characters(
1396 ISAXContentHandler *iface,
1397 const WCHAR *chars,
1398 int nchars)
1400 mxwriter *This = impl_from_ISAXContentHandler( iface );
1402 TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1404 if (!chars) return E_INVALIDARG;
1406 close_element_starttag(This);
1407 set_element_name(This, NULL, 0);
1409 if (!This->cdata)
1410 This->text = TRUE;
1412 if (nchars)
1414 if (This->cdata || This->props[MXWriter_DisableEscaping] == VARIANT_TRUE)
1415 write_output_buffer(This, chars, nchars);
1416 else
1418 int len = nchars;
1419 WCHAR *escaped;
1421 escaped = get_escaped_string(chars, EscapeText, &len);
1422 write_output_buffer(This, escaped, len);
1423 heap_free(escaped);
1427 return S_OK;
1430 static HRESULT WINAPI SAXContentHandler_ignorableWhitespace(
1431 ISAXContentHandler *iface,
1432 const WCHAR *chars,
1433 int nchars)
1435 mxwriter *This = impl_from_ISAXContentHandler( iface );
1437 TRACE("(%p)->(%s)\n", This, debugstr_wn(chars, nchars));
1439 if (!chars) return E_INVALIDARG;
1441 write_output_buffer(This, chars, nchars);
1443 return S_OK;
1446 static HRESULT WINAPI SAXContentHandler_processingInstruction(
1447 ISAXContentHandler *iface,
1448 const WCHAR *target,
1449 int ntarget,
1450 const WCHAR *data,
1451 int ndata)
1453 mxwriter *This = impl_from_ISAXContentHandler( iface );
1454 static const WCHAR openpiW[] = {'<','?'};
1455 static const WCHAR closepiW[] = {'?','>','\r','\n'};
1457 TRACE("(%p)->(%s %s)\n", This, debugstr_wn(target, ntarget), debugstr_wn(data, ndata));
1459 if (!target) return E_INVALIDARG;
1461 write_node_indent(This);
1462 write_output_buffer(This, openpiW, ARRAY_SIZE(openpiW));
1464 if (*target)
1465 write_output_buffer(This, target, ntarget);
1467 if (data && *data && ndata)
1469 write_output_buffer(This, spaceW, 1);
1470 write_output_buffer(This, data, ndata);
1473 write_output_buffer(This, closepiW, ARRAY_SIZE(closepiW));
1474 This->newline = TRUE;
1476 return S_OK;
1479 static HRESULT WINAPI SAXContentHandler_skippedEntity(
1480 ISAXContentHandler *iface,
1481 const WCHAR *name,
1482 int nname)
1484 mxwriter *This = impl_from_ISAXContentHandler( iface );
1485 FIXME("(%p)->(%s)\n", This, debugstr_wn(name, nname));
1486 return E_NOTIMPL;
1489 static const struct ISAXContentHandlerVtbl SAXContentHandlerVtbl =
1491 SAXContentHandler_QueryInterface,
1492 SAXContentHandler_AddRef,
1493 SAXContentHandler_Release,
1494 SAXContentHandler_putDocumentLocator,
1495 SAXContentHandler_startDocument,
1496 SAXContentHandler_endDocument,
1497 SAXContentHandler_startPrefixMapping,
1498 SAXContentHandler_endPrefixMapping,
1499 SAXContentHandler_startElement,
1500 SAXContentHandler_endElement,
1501 SAXContentHandler_characters,
1502 SAXContentHandler_ignorableWhitespace,
1503 SAXContentHandler_processingInstruction,
1504 SAXContentHandler_skippedEntity
1507 /*** ISAXLexicalHandler ***/
1508 static HRESULT WINAPI SAXLexicalHandler_QueryInterface(ISAXLexicalHandler *iface,
1509 REFIID riid, void **obj)
1511 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1512 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1515 static ULONG WINAPI SAXLexicalHandler_AddRef(ISAXLexicalHandler *iface)
1517 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1518 return IMXWriter_AddRef(&This->IMXWriter_iface);
1521 static ULONG WINAPI SAXLexicalHandler_Release(ISAXLexicalHandler *iface)
1523 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1524 return IMXWriter_Release(&This->IMXWriter_iface);
1527 static HRESULT WINAPI SAXLexicalHandler_startDTD(ISAXLexicalHandler *iface,
1528 const WCHAR *name, int name_len, const WCHAR *publicId, int publicId_len,
1529 const WCHAR *systemId, int systemId_len)
1531 static const WCHAR doctypeW[] = {'<','!','D','O','C','T','Y','P','E',' '};
1532 static const WCHAR openintW[] = {'[','\r','\n'};
1534 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1536 TRACE("(%p)->(%s %s %s)\n", This, debugstr_wn(name, name_len), debugstr_wn(publicId, publicId_len),
1537 debugstr_wn(systemId, systemId_len));
1539 if (!name) return E_INVALIDARG;
1541 write_output_buffer(This, doctypeW, ARRAY_SIZE(doctypeW));
1543 if (*name)
1545 write_output_buffer(This, name, name_len);
1546 write_output_buffer(This, spaceW, 1);
1549 if (publicId)
1551 write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
1552 write_output_buffer_quoted(This, publicId, publicId_len);
1554 if (!systemId) return E_INVALIDARG;
1556 if (*publicId)
1557 write_output_buffer(This, spaceW, 1);
1559 write_output_buffer_quoted(This, systemId, systemId_len);
1561 if (*systemId)
1562 write_output_buffer(This, spaceW, 1);
1564 else if (systemId)
1566 write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
1567 write_output_buffer_quoted(This, systemId, systemId_len);
1568 if (*systemId)
1569 write_output_buffer(This, spaceW, 1);
1572 write_output_buffer(This, openintW, ARRAY_SIZE(openintW));
1574 return S_OK;
1577 static HRESULT WINAPI SAXLexicalHandler_endDTD(ISAXLexicalHandler *iface)
1579 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1580 static const WCHAR closedtdW[] = {']','>','\r','\n'};
1582 TRACE("(%p)\n", This);
1584 write_output_buffer(This, closedtdW, ARRAY_SIZE(closedtdW));
1586 return S_OK;
1589 static HRESULT WINAPI SAXLexicalHandler_startEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1591 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1592 FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1593 return E_NOTIMPL;
1596 static HRESULT WINAPI SAXLexicalHandler_endEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1598 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1599 FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1600 return E_NOTIMPL;
1603 static HRESULT WINAPI SAXLexicalHandler_startCDATA(ISAXLexicalHandler *iface)
1605 static const WCHAR scdataW[] = {'<','!','[','C','D','A','T','A','['};
1606 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1608 TRACE("(%p)\n", This);
1610 write_node_indent(This);
1611 write_output_buffer(This, scdataW, ARRAY_SIZE(scdataW));
1612 This->cdata = TRUE;
1614 return S_OK;
1617 static HRESULT WINAPI SAXLexicalHandler_endCDATA(ISAXLexicalHandler *iface)
1619 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1620 static const WCHAR ecdataW[] = {']',']','>'};
1622 TRACE("(%p)\n", This);
1624 write_output_buffer(This, ecdataW, ARRAY_SIZE(ecdataW));
1625 This->cdata = FALSE;
1627 return S_OK;
1630 static HRESULT WINAPI SAXLexicalHandler_comment(ISAXLexicalHandler *iface, const WCHAR *chars, int nchars)
1632 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1633 static const WCHAR copenW[] = {'<','!','-','-'};
1634 static const WCHAR ccloseW[] = {'-','-','>','\r','\n'};
1636 TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1638 if (!chars) return E_INVALIDARG;
1640 close_element_starttag(This);
1641 write_node_indent(This);
1643 write_output_buffer(This, copenW, ARRAY_SIZE(copenW));
1644 if (nchars)
1645 write_output_buffer(This, chars, nchars);
1646 write_output_buffer(This, ccloseW, ARRAY_SIZE(ccloseW));
1648 return S_OK;
1651 static const struct ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl =
1653 SAXLexicalHandler_QueryInterface,
1654 SAXLexicalHandler_AddRef,
1655 SAXLexicalHandler_Release,
1656 SAXLexicalHandler_startDTD,
1657 SAXLexicalHandler_endDTD,
1658 SAXLexicalHandler_startEntity,
1659 SAXLexicalHandler_endEntity,
1660 SAXLexicalHandler_startCDATA,
1661 SAXLexicalHandler_endCDATA,
1662 SAXLexicalHandler_comment
1665 /*** ISAXDeclHandler ***/
1666 static HRESULT WINAPI SAXDeclHandler_QueryInterface(ISAXDeclHandler *iface,
1667 REFIID riid, void **obj)
1669 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1670 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1673 static ULONG WINAPI SAXDeclHandler_AddRef(ISAXDeclHandler *iface)
1675 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1676 return IMXWriter_AddRef(&This->IMXWriter_iface);
1679 static ULONG WINAPI SAXDeclHandler_Release(ISAXDeclHandler *iface)
1681 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1682 return IMXWriter_Release(&This->IMXWriter_iface);
1685 static HRESULT WINAPI SAXDeclHandler_elementDecl(ISAXDeclHandler *iface,
1686 const WCHAR *name, int n_name, const WCHAR *model, int n_model)
1688 static const WCHAR elementW[] = {'<','!','E','L','E','M','E','N','T',' '};
1689 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1691 TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1692 debugstr_wn(model, n_model), n_model);
1694 if (!name || !model) return E_INVALIDARG;
1696 write_output_buffer(This, elementW, ARRAY_SIZE(elementW));
1697 if (n_name) {
1698 write_output_buffer(This, name, n_name);
1699 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1701 if (n_model)
1702 write_output_buffer(This, model, n_model);
1703 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1705 return S_OK;
1708 static HRESULT WINAPI SAXDeclHandler_attributeDecl(ISAXDeclHandler *iface,
1709 const WCHAR *element, int n_element, const WCHAR *attr, int n_attr,
1710 const WCHAR *type, int n_type, const WCHAR *Default, int n_default,
1711 const WCHAR *value, int n_value)
1713 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1714 static const WCHAR attlistW[] = {'<','!','A','T','T','L','I','S','T',' '};
1715 static const WCHAR closetagW[] = {'>','\r','\n'};
1717 TRACE("(%p)->(%s:%d %s:%d %s:%d %s:%d %s:%d)\n", This, debugstr_wn(element, n_element), n_element,
1718 debugstr_wn(attr, n_attr), n_attr, debugstr_wn(type, n_type), n_type, debugstr_wn(Default, n_default), n_default,
1719 debugstr_wn(value, n_value), n_value);
1721 write_output_buffer(This, attlistW, ARRAY_SIZE(attlistW));
1722 if (n_element) {
1723 write_output_buffer(This, element, n_element);
1724 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1727 if (n_attr) {
1728 write_output_buffer(This, attr, n_attr);
1729 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1732 if (n_type) {
1733 write_output_buffer(This, type, n_type);
1734 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1737 if (n_default) {
1738 write_output_buffer(This, Default, n_default);
1739 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1742 if (n_value)
1743 write_output_buffer_quoted(This, value, n_value);
1745 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1747 return S_OK;
1750 static HRESULT WINAPI SAXDeclHandler_internalEntityDecl(ISAXDeclHandler *iface,
1751 const WCHAR *name, int n_name, const WCHAR *value, int n_value)
1753 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1755 TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1756 debugstr_wn(value, n_value), n_value);
1758 if (!name || !value) return E_INVALIDARG;
1760 write_output_buffer(This, entityW, ARRAY_SIZE(entityW));
1761 if (n_name) {
1762 write_output_buffer(This, name, n_name);
1763 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1766 if (n_value)
1767 write_output_buffer_quoted(This, value, n_value);
1769 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1771 return S_OK;
1774 static HRESULT WINAPI SAXDeclHandler_externalEntityDecl(ISAXDeclHandler *iface,
1775 const WCHAR *name, int n_name, const WCHAR *publicId, int n_publicId,
1776 const WCHAR *systemId, int n_systemId)
1778 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1780 TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1781 debugstr_wn(publicId, n_publicId), n_publicId, debugstr_wn(systemId, n_systemId), n_systemId);
1783 if (!name || !systemId) return E_INVALIDARG;
1785 write_output_buffer(This, entityW, ARRAY_SIZE(entityW));
1786 if (n_name) {
1787 write_output_buffer(This, name, n_name);
1788 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1791 if (publicId)
1793 write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
1794 write_output_buffer_quoted(This, publicId, n_publicId);
1795 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1796 write_output_buffer_quoted(This, systemId, n_systemId);
1798 else
1800 write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
1801 write_output_buffer_quoted(This, systemId, n_systemId);
1804 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1806 return S_OK;
1809 static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl = {
1810 SAXDeclHandler_QueryInterface,
1811 SAXDeclHandler_AddRef,
1812 SAXDeclHandler_Release,
1813 SAXDeclHandler_elementDecl,
1814 SAXDeclHandler_attributeDecl,
1815 SAXDeclHandler_internalEntityDecl,
1816 SAXDeclHandler_externalEntityDecl
1819 /*** IVBSAXDeclHandler ***/
1820 static HRESULT WINAPI VBSAXDeclHandler_QueryInterface(IVBSAXDeclHandler *iface,
1821 REFIID riid, void **obj)
1823 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1824 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1827 static ULONG WINAPI VBSAXDeclHandler_AddRef(IVBSAXDeclHandler *iface)
1829 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1830 return IMXWriter_AddRef(&This->IMXWriter_iface);
1833 static ULONG WINAPI VBSAXDeclHandler_Release(IVBSAXDeclHandler *iface)
1835 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1836 return IMXWriter_Release(&This->IMXWriter_iface);
1839 static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfoCount(IVBSAXDeclHandler *iface, UINT* pctinfo)
1841 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1842 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1845 static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfo(IVBSAXDeclHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1847 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1848 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1851 static HRESULT WINAPI VBSAXDeclHandler_GetIDsOfNames(IVBSAXDeclHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1852 UINT cNames, LCID lcid, DISPID* rgDispId )
1854 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1855 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1858 static HRESULT WINAPI VBSAXDeclHandler_Invoke(IVBSAXDeclHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1859 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1861 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1862 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1863 pExcepInfo, puArgErr);
1866 static HRESULT WINAPI VBSAXDeclHandler_elementDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *model)
1868 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1870 TRACE("(%p)->(%p %p)\n", This, name, model);
1872 if (!name || !model)
1873 return E_POINTER;
1875 return ISAXDeclHandler_elementDecl(&This->ISAXDeclHandler_iface, *name, -1, *model, -1);
1878 static HRESULT WINAPI VBSAXDeclHandler_attributeDecl(IVBSAXDeclHandler *iface,
1879 BSTR *element, BSTR *attr, BSTR *type, BSTR *default_value, BSTR *value)
1881 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1883 TRACE("(%p)->(%p %p %p %p %p)\n", This, element, attr, type, default_value, value);
1885 if (!element || !attr || !type || !default_value || !value)
1886 return E_POINTER;
1888 return ISAXDeclHandler_attributeDecl(&This->ISAXDeclHandler_iface, *element, -1, *attr, -1, *type, -1,
1889 *default_value, -1, *value, -1);
1892 static HRESULT WINAPI VBSAXDeclHandler_internalEntityDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *value)
1894 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1896 TRACE("(%p)->(%p %p)\n", This, name, value);
1898 if (!name || !value)
1899 return E_POINTER;
1901 return ISAXDeclHandler_internalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *value, -1);
1904 static HRESULT WINAPI VBSAXDeclHandler_externalEntityDecl(IVBSAXDeclHandler *iface,
1905 BSTR *name, BSTR *publicid, BSTR *systemid)
1907 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1909 TRACE("(%p)->(%p %p %p)\n", This, name, publicid, systemid);
1911 if (!name || !publicid || !systemid)
1912 return E_POINTER;
1914 return ISAXDeclHandler_externalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *publicid, -1, *systemid, -1);
1917 static const IVBSAXDeclHandlerVtbl VBSAXDeclHandlerVtbl = {
1918 VBSAXDeclHandler_QueryInterface,
1919 VBSAXDeclHandler_AddRef,
1920 VBSAXDeclHandler_Release,
1921 VBSAXDeclHandler_GetTypeInfoCount,
1922 VBSAXDeclHandler_GetTypeInfo,
1923 VBSAXDeclHandler_GetIDsOfNames,
1924 VBSAXDeclHandler_Invoke,
1925 VBSAXDeclHandler_elementDecl,
1926 VBSAXDeclHandler_attributeDecl,
1927 VBSAXDeclHandler_internalEntityDecl,
1928 VBSAXDeclHandler_externalEntityDecl
1931 /*** IVBSAXLexicalHandler ***/
1932 static HRESULT WINAPI VBSAXLexicalHandler_QueryInterface(IVBSAXLexicalHandler *iface,
1933 REFIID riid, void **obj)
1935 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1936 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1939 static ULONG WINAPI VBSAXLexicalHandler_AddRef(IVBSAXLexicalHandler *iface)
1941 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1942 return IMXWriter_AddRef(&This->IMXWriter_iface);
1945 static ULONG WINAPI VBSAXLexicalHandler_Release(IVBSAXLexicalHandler *iface)
1947 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1948 return IMXWriter_Release(&This->IMXWriter_iface);
1951 static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfoCount(IVBSAXLexicalHandler *iface, UINT* pctinfo)
1953 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1954 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1957 static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfo(IVBSAXLexicalHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1959 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1960 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1963 static HRESULT WINAPI VBSAXLexicalHandler_GetIDsOfNames(IVBSAXLexicalHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1964 UINT cNames, LCID lcid, DISPID* rgDispId )
1966 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1967 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1970 static HRESULT WINAPI VBSAXLexicalHandler_Invoke(IVBSAXLexicalHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1971 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1973 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1974 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1975 pExcepInfo, puArgErr);
1978 static HRESULT WINAPI VBSAXLexicalHandler_startDTD(IVBSAXLexicalHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
1980 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1982 TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
1984 if (!name || !publicId || !systemId)
1985 return E_POINTER;
1987 return ISAXLexicalHandler_startDTD(&This->ISAXLexicalHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
1990 static HRESULT WINAPI VBSAXLexicalHandler_endDTD(IVBSAXLexicalHandler *iface)
1992 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1993 return ISAXLexicalHandler_endDTD(&This->ISAXLexicalHandler_iface);
1996 static HRESULT WINAPI VBSAXLexicalHandler_startEntity(IVBSAXLexicalHandler *iface, BSTR *name)
1998 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2000 TRACE("(%p)->(%p)\n", This, name);
2002 if (!name)
2003 return E_POINTER;
2005 return ISAXLexicalHandler_startEntity(&This->ISAXLexicalHandler_iface, *name, -1);
2008 static HRESULT WINAPI VBSAXLexicalHandler_endEntity(IVBSAXLexicalHandler *iface, BSTR *name)
2010 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2012 TRACE("(%p)->(%p)\n", This, name);
2014 if (!name)
2015 return E_POINTER;
2017 return ISAXLexicalHandler_endEntity(&This->ISAXLexicalHandler_iface, *name, -1);
2020 static HRESULT WINAPI VBSAXLexicalHandler_startCDATA(IVBSAXLexicalHandler *iface)
2022 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2023 return ISAXLexicalHandler_startCDATA(&This->ISAXLexicalHandler_iface);
2026 static HRESULT WINAPI VBSAXLexicalHandler_endCDATA(IVBSAXLexicalHandler *iface)
2028 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2029 return ISAXLexicalHandler_endCDATA(&This->ISAXLexicalHandler_iface);
2032 static HRESULT WINAPI VBSAXLexicalHandler_comment(IVBSAXLexicalHandler *iface, BSTR *chars)
2034 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2036 TRACE("(%p)->(%p)\n", This, chars);
2038 if (!chars)
2039 return E_POINTER;
2041 return ISAXLexicalHandler_comment(&This->ISAXLexicalHandler_iface, *chars, -1);
2044 static const IVBSAXLexicalHandlerVtbl VBSAXLexicalHandlerVtbl = {
2045 VBSAXLexicalHandler_QueryInterface,
2046 VBSAXLexicalHandler_AddRef,
2047 VBSAXLexicalHandler_Release,
2048 VBSAXLexicalHandler_GetTypeInfoCount,
2049 VBSAXLexicalHandler_GetTypeInfo,
2050 VBSAXLexicalHandler_GetIDsOfNames,
2051 VBSAXLexicalHandler_Invoke,
2052 VBSAXLexicalHandler_startDTD,
2053 VBSAXLexicalHandler_endDTD,
2054 VBSAXLexicalHandler_startEntity,
2055 VBSAXLexicalHandler_endEntity,
2056 VBSAXLexicalHandler_startCDATA,
2057 VBSAXLexicalHandler_endCDATA,
2058 VBSAXLexicalHandler_comment
2061 /*** IVBSAXContentHandler ***/
2062 static HRESULT WINAPI VBSAXContentHandler_QueryInterface(IVBSAXContentHandler *iface, REFIID riid, void **obj)
2064 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2065 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2068 static ULONG WINAPI VBSAXContentHandler_AddRef(IVBSAXContentHandler *iface)
2070 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2071 return IMXWriter_AddRef(&This->IMXWriter_iface);
2074 static ULONG WINAPI VBSAXContentHandler_Release(IVBSAXContentHandler *iface)
2076 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2077 return IMXWriter_Release(&This->IMXWriter_iface);
2080 static HRESULT WINAPI VBSAXContentHandler_GetTypeInfoCount(IVBSAXContentHandler *iface, UINT* pctinfo)
2082 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2083 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2086 static HRESULT WINAPI VBSAXContentHandler_GetTypeInfo(IVBSAXContentHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2088 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2089 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2092 static HRESULT WINAPI VBSAXContentHandler_GetIDsOfNames(IVBSAXContentHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2093 UINT cNames, LCID lcid, DISPID* rgDispId )
2095 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2096 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2099 static HRESULT WINAPI VBSAXContentHandler_Invoke(IVBSAXContentHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2100 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2102 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2103 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2104 pExcepInfo, puArgErr);
2107 static HRESULT WINAPI VBSAXContentHandler_putref_documentLocator(IVBSAXContentHandler *iface, IVBSAXLocator *locator)
2109 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2110 TRACE("(%p)->(%p)\n", This, locator);
2111 return S_OK;
2114 static HRESULT WINAPI VBSAXContentHandler_startDocument(IVBSAXContentHandler *iface)
2116 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2117 return ISAXContentHandler_startDocument(&This->ISAXContentHandler_iface);
2120 static HRESULT WINAPI VBSAXContentHandler_endDocument(IVBSAXContentHandler *iface)
2122 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2123 return ISAXContentHandler_endDocument(&This->ISAXContentHandler_iface);
2126 static HRESULT WINAPI VBSAXContentHandler_startPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix, BSTR *uri)
2128 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2130 TRACE("(%p)->(%p %p)\n", This, prefix, uri);
2132 if (!prefix || !uri)
2133 return E_POINTER;
2135 return ISAXContentHandler_startPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1, *uri, -1);
2138 static HRESULT WINAPI VBSAXContentHandler_endPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix)
2140 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2142 TRACE("(%p)->(%p)\n", This, prefix);
2144 if (!prefix)
2145 return E_POINTER;
2147 return ISAXContentHandler_endPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1);
2150 static HRESULT WINAPI VBSAXContentHandler_startElement(IVBSAXContentHandler *iface,
2151 BSTR *namespaceURI, BSTR *localName, BSTR *QName, IVBSAXAttributes *attrs)
2153 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2155 TRACE("(%p)->(%p %p %p %p)\n", This, namespaceURI, localName, QName, attrs);
2157 if (!namespaceURI || !*namespaceURI || !localName || !QName)
2158 return E_INVALIDARG;
2160 TRACE("(%s %s %s)\n", debugstr_w(*namespaceURI), debugstr_w(*localName), debugstr_w(*QName));
2162 mxwriter_write_starttag(This, *QName, SysStringLen(*QName));
2164 if (attrs)
2166 int length, i, escape;
2167 HRESULT hr;
2169 hr = IVBSAXAttributes_get_length(attrs, &length);
2170 if (FAILED(hr)) return hr;
2172 escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
2173 (This->class_version == MSXML4 || This->class_version == MSXML6);
2175 for (i = 0; i < length; i++)
2177 BSTR qname, value;
2179 hr = IVBSAXAttributes_getQName(attrs, i, &qname);
2180 if (FAILED(hr)) return hr;
2182 hr = IVBSAXAttributes_getValue(attrs, i, &value);
2183 if (FAILED(hr))
2185 SysFreeString(qname);
2186 return hr;
2189 mxwriter_write_attribute(This, qname, SysStringLen(qname), value, SysStringLen(value), escape);
2190 SysFreeString(qname);
2191 SysFreeString(value);
2195 return S_OK;
2198 static HRESULT WINAPI VBSAXContentHandler_endElement(IVBSAXContentHandler *iface, BSTR *namespaceURI,
2199 BSTR *localName, BSTR *QName)
2201 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2203 TRACE("(%p)->(%p %p %p)\n", This, namespaceURI, localName, QName);
2205 if (!namespaceURI || !localName || !QName)
2206 return E_POINTER;
2208 return ISAXContentHandler_endElement(&This->ISAXContentHandler_iface,
2209 *namespaceURI, SysStringLen(*namespaceURI),
2210 *localName, SysStringLen(*localName),
2211 *QName, SysStringLen(*QName));
2214 static HRESULT WINAPI VBSAXContentHandler_characters(IVBSAXContentHandler *iface, BSTR *chars)
2216 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2218 TRACE("(%p)->(%p)\n", This, chars);
2220 if (!chars)
2221 return E_POINTER;
2223 return ISAXContentHandler_characters(&This->ISAXContentHandler_iface, *chars, SysStringLen(*chars));
2226 static HRESULT WINAPI VBSAXContentHandler_ignorableWhitespace(IVBSAXContentHandler *iface, BSTR *chars)
2228 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2230 TRACE("(%p)->(%p)\n", This, chars);
2232 if (!chars)
2233 return E_POINTER;
2235 return ISAXContentHandler_ignorableWhitespace(&This->ISAXContentHandler_iface, *chars, -1);
2238 static HRESULT WINAPI VBSAXContentHandler_processingInstruction(IVBSAXContentHandler *iface,
2239 BSTR *target, BSTR *data)
2241 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2243 TRACE("(%p)->(%p %p)\n", This, target, data);
2245 if (!target || !data)
2246 return E_POINTER;
2248 return ISAXContentHandler_processingInstruction(&This->ISAXContentHandler_iface, *target, -1, *data, -1);
2251 static HRESULT WINAPI VBSAXContentHandler_skippedEntity(IVBSAXContentHandler *iface, BSTR *name)
2253 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2255 TRACE("(%p)->(%p)\n", This, name);
2257 if (!name)
2258 return E_POINTER;
2260 return ISAXContentHandler_skippedEntity(&This->ISAXContentHandler_iface, *name, -1);
2263 static const IVBSAXContentHandlerVtbl VBSAXContentHandlerVtbl = {
2264 VBSAXContentHandler_QueryInterface,
2265 VBSAXContentHandler_AddRef,
2266 VBSAXContentHandler_Release,
2267 VBSAXContentHandler_GetTypeInfoCount,
2268 VBSAXContentHandler_GetTypeInfo,
2269 VBSAXContentHandler_GetIDsOfNames,
2270 VBSAXContentHandler_Invoke,
2271 VBSAXContentHandler_putref_documentLocator,
2272 VBSAXContentHandler_startDocument,
2273 VBSAXContentHandler_endDocument,
2274 VBSAXContentHandler_startPrefixMapping,
2275 VBSAXContentHandler_endPrefixMapping,
2276 VBSAXContentHandler_startElement,
2277 VBSAXContentHandler_endElement,
2278 VBSAXContentHandler_characters,
2279 VBSAXContentHandler_ignorableWhitespace,
2280 VBSAXContentHandler_processingInstruction,
2281 VBSAXContentHandler_skippedEntity
2284 static HRESULT WINAPI SAXDTDHandler_QueryInterface(ISAXDTDHandler *iface, REFIID riid, void **obj)
2286 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2287 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2290 static ULONG WINAPI SAXDTDHandler_AddRef(ISAXDTDHandler *iface)
2292 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2293 return IMXWriter_AddRef(&This->IMXWriter_iface);
2296 static ULONG WINAPI SAXDTDHandler_Release(ISAXDTDHandler *iface)
2298 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2299 return IMXWriter_Release(&This->IMXWriter_iface);
2302 static HRESULT WINAPI SAXDTDHandler_notationDecl(ISAXDTDHandler *iface,
2303 const WCHAR *name, INT n_name,
2304 const WCHAR *publicid, INT n_publicid,
2305 const WCHAR *systemid, INT n_systemid)
2307 static const WCHAR notationW[] = {'<','!','N','O','T','A','T','I','O','N',' '};
2308 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2310 TRACE("(%p)->(%s:%d, %s:%d, %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
2311 debugstr_wn(publicid, n_publicid), n_publicid, debugstr_wn(systemid, n_systemid), n_systemid);
2313 if (!name || !n_name)
2314 return E_INVALIDARG;
2316 write_output_buffer(This, notationW, ARRAY_SIZE(notationW));
2317 write_output_buffer(This, name, n_name);
2319 if (!publicid && !systemid)
2320 return E_INVALIDARG;
2322 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
2323 if (publicid)
2325 write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
2326 write_output_buffer_quoted(This, publicid, n_publicid);
2327 if (systemid)
2329 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
2330 write_output_buffer_quoted(This, systemid, n_systemid);
2333 else
2335 write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
2336 write_output_buffer_quoted(This, systemid, n_systemid);
2339 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
2341 return S_OK;
2344 static HRESULT WINAPI SAXDTDHandler_unparsedEntityDecl(ISAXDTDHandler *iface,
2345 const WCHAR *name, INT nname,
2346 const WCHAR *publicid, INT npublicid,
2347 const WCHAR *systemid, INT nsystemid,
2348 const WCHAR *notation, INT nnotation)
2350 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2351 FIXME("(%p)->(%s:%d, %s:%d, %s:%d, %s:%d): stub\n", This, debugstr_wn(name, nname), nname,
2352 debugstr_wn(publicid, npublicid), npublicid, debugstr_wn(systemid, nsystemid), nsystemid,
2353 debugstr_wn(notation, nnotation), nnotation);
2354 return E_NOTIMPL;
2357 static const ISAXDTDHandlerVtbl SAXDTDHandlerVtbl = {
2358 SAXDTDHandler_QueryInterface,
2359 SAXDTDHandler_AddRef,
2360 SAXDTDHandler_Release,
2361 SAXDTDHandler_notationDecl,
2362 SAXDTDHandler_unparsedEntityDecl
2365 /*** IVBSAXDTDHandler ***/
2366 static HRESULT WINAPI VBSAXDTDHandler_QueryInterface(IVBSAXDTDHandler *iface, REFIID riid, void **obj)
2368 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2369 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2372 static ULONG WINAPI VBSAXDTDHandler_AddRef(IVBSAXDTDHandler *iface)
2374 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2375 return IMXWriter_AddRef(&This->IMXWriter_iface);
2378 static ULONG WINAPI VBSAXDTDHandler_Release(IVBSAXDTDHandler *iface)
2380 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2381 return IMXWriter_Release(&This->IMXWriter_iface);
2384 static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfoCount(IVBSAXDTDHandler *iface, UINT* pctinfo)
2386 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2387 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2390 static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfo(IVBSAXDTDHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2392 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2393 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2396 static HRESULT WINAPI VBSAXDTDHandler_GetIDsOfNames(IVBSAXDTDHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2397 UINT cNames, LCID lcid, DISPID* rgDispId )
2399 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2400 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2403 static HRESULT WINAPI VBSAXDTDHandler_Invoke(IVBSAXDTDHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2404 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2406 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2407 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2408 pExcepInfo, puArgErr);
2411 static HRESULT WINAPI VBSAXDTDHandler_notationDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
2413 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2415 TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
2417 if (!name || !publicId || !systemId)
2418 return E_POINTER;
2420 return ISAXDTDHandler_notationDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
2423 static HRESULT WINAPI VBSAXDTDHandler_unparsedEntityDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId,
2424 BSTR *systemId, BSTR *notation)
2426 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2428 TRACE("(%p)->(%p %p %p %p)\n", This, name, publicId, systemId, notation);
2430 if (!name || !publicId || !systemId || !notation)
2431 return E_POINTER;
2433 return ISAXDTDHandler_unparsedEntityDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1,
2434 *systemId, -1, *notation, -1);
2437 static const IVBSAXDTDHandlerVtbl VBSAXDTDHandlerVtbl = {
2438 VBSAXDTDHandler_QueryInterface,
2439 VBSAXDTDHandler_AddRef,
2440 VBSAXDTDHandler_Release,
2441 VBSAXDTDHandler_GetTypeInfoCount,
2442 VBSAXDTDHandler_GetTypeInfo,
2443 VBSAXDTDHandler_GetIDsOfNames,
2444 VBSAXDTDHandler_Invoke,
2445 VBSAXDTDHandler_notationDecl,
2446 VBSAXDTDHandler_unparsedEntityDecl
2449 /* ISAXErrorHandler */
2450 static HRESULT WINAPI SAXErrorHandler_QueryInterface(ISAXErrorHandler *iface, REFIID riid, void **obj)
2452 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2453 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2456 static ULONG WINAPI SAXErrorHandler_AddRef(ISAXErrorHandler *iface)
2458 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2459 return IMXWriter_AddRef(&This->IMXWriter_iface);
2462 static ULONG WINAPI SAXErrorHandler_Release(ISAXErrorHandler *iface)
2464 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2465 return IMXWriter_Release(&This->IMXWriter_iface);
2468 static HRESULT WINAPI SAXErrorHandler_error(ISAXErrorHandler *iface,
2469 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2471 FIXME("%p, %p, %s, %#lx.\n", iface, locator, debugstr_w(message), hr);
2473 return E_NOTIMPL;
2476 static HRESULT WINAPI SAXErrorHandler_fatalError(ISAXErrorHandler *iface,
2477 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2479 FIXME("%p, %p, %s, %#lx.\n", iface, locator, debugstr_w(message), hr);
2481 return E_NOTIMPL;
2484 static HRESULT WINAPI SAXErrorHandler_ignorableWarning(ISAXErrorHandler *iface,
2485 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2487 FIXME("%p, %p, %s, %#lx.\n", iface, locator, debugstr_w(message), hr);
2489 return E_NOTIMPL;
2492 static const ISAXErrorHandlerVtbl SAXErrorHandlerVtbl = {
2493 SAXErrorHandler_QueryInterface,
2494 SAXErrorHandler_AddRef,
2495 SAXErrorHandler_Release,
2496 SAXErrorHandler_error,
2497 SAXErrorHandler_fatalError,
2498 SAXErrorHandler_ignorableWarning
2501 /*** IVBSAXErrorHandler ***/
2502 static HRESULT WINAPI VBSAXErrorHandler_QueryInterface(IVBSAXErrorHandler *iface, REFIID riid, void **obj)
2504 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2505 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2508 static ULONG WINAPI VBSAXErrorHandler_AddRef(IVBSAXErrorHandler *iface)
2510 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2511 return IMXWriter_AddRef(&This->IMXWriter_iface);
2514 static ULONG WINAPI VBSAXErrorHandler_Release(IVBSAXErrorHandler *iface)
2516 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2517 return IMXWriter_Release(&This->IMXWriter_iface);
2520 static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfoCount(IVBSAXErrorHandler *iface, UINT* pctinfo)
2522 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2523 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2526 static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfo(IVBSAXErrorHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2528 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2529 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2532 static HRESULT WINAPI VBSAXErrorHandler_GetIDsOfNames(IVBSAXErrorHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2533 UINT cNames, LCID lcid, DISPID* rgDispId )
2535 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2536 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2539 static HRESULT WINAPI VBSAXErrorHandler_Invoke(IVBSAXErrorHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2540 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2542 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2543 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2544 pExcepInfo, puArgErr);
2547 static HRESULT WINAPI VBSAXErrorHandler_error(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2549 FIXME("%p, %p, %p, %lx: stub\n", iface, locator, message, code);
2550 return E_NOTIMPL;
2553 static HRESULT WINAPI VBSAXErrorHandler_fatalError(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2555 FIXME("%p, %p, %p, %lx: stub\n", iface, locator, message, code);
2556 return E_NOTIMPL;
2559 static HRESULT WINAPI VBSAXErrorHandler_ignorableWarning(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2561 FIXME("%p, %p, %p, %lx: stub\n", iface, locator, message, code);
2562 return E_NOTIMPL;
2565 static const IVBSAXErrorHandlerVtbl VBSAXErrorHandlerVtbl = {
2566 VBSAXErrorHandler_QueryInterface,
2567 VBSAXErrorHandler_AddRef,
2568 VBSAXErrorHandler_Release,
2569 VBSAXErrorHandler_GetTypeInfoCount,
2570 VBSAXErrorHandler_GetTypeInfo,
2571 VBSAXErrorHandler_GetIDsOfNames,
2572 VBSAXErrorHandler_Invoke,
2573 VBSAXErrorHandler_error,
2574 VBSAXErrorHandler_fatalError,
2575 VBSAXErrorHandler_ignorableWarning
2578 static const tid_t mxwriter_iface_tids[] = {
2579 IMXWriter_tid,
2583 static dispex_static_data_t mxwriter_dispex = {
2584 NULL,
2585 IMXWriter_tid,
2586 NULL,
2587 mxwriter_iface_tids
2590 HRESULT MXWriter_create(MSXML_VERSION version, void **ppObj)
2592 static const WCHAR version10W[] = {'1','.','0',0};
2593 mxwriter *This;
2594 HRESULT hr;
2596 TRACE("(%p)\n", ppObj);
2598 This = heap_alloc( sizeof (*This) );
2599 if(!This)
2600 return E_OUTOFMEMORY;
2602 This->IMXWriter_iface.lpVtbl = &MXWriterVtbl;
2603 This->ISAXContentHandler_iface.lpVtbl = &SAXContentHandlerVtbl;
2604 This->ISAXLexicalHandler_iface.lpVtbl = &SAXLexicalHandlerVtbl;
2605 This->ISAXDeclHandler_iface.lpVtbl = &SAXDeclHandlerVtbl;
2606 This->ISAXDTDHandler_iface.lpVtbl = &SAXDTDHandlerVtbl;
2607 This->ISAXErrorHandler_iface.lpVtbl = &SAXErrorHandlerVtbl;
2608 This->IVBSAXDeclHandler_iface.lpVtbl = &VBSAXDeclHandlerVtbl;
2609 This->IVBSAXLexicalHandler_iface.lpVtbl = &VBSAXLexicalHandlerVtbl;
2610 This->IVBSAXContentHandler_iface.lpVtbl = &VBSAXContentHandlerVtbl;
2611 This->IVBSAXDTDHandler_iface.lpVtbl = &VBSAXDTDHandlerVtbl;
2612 This->IVBSAXErrorHandler_iface.lpVtbl = &VBSAXErrorHandlerVtbl;
2613 This->ref = 1;
2614 This->class_version = version;
2616 This->props[MXWriter_BOM] = VARIANT_TRUE;
2617 This->props[MXWriter_DisableEscaping] = VARIANT_FALSE;
2618 This->props[MXWriter_Indent] = VARIANT_FALSE;
2619 This->props[MXWriter_OmitXmlDecl] = VARIANT_FALSE;
2620 This->props[MXWriter_Standalone] = VARIANT_FALSE;
2621 This->prop_changed = FALSE;
2622 This->encoding = SysAllocString(utf16W);
2623 This->version = SysAllocString(version10W);
2624 This->xml_enc = XmlEncoding_UTF16;
2626 This->element = NULL;
2627 This->cdata = FALSE;
2628 This->indent = 0;
2629 This->text = FALSE;
2630 This->newline = FALSE;
2632 This->dest = NULL;
2634 hr = init_output_buffer(This->xml_enc, &This->buffer);
2635 if (hr != S_OK) {
2636 SysFreeString(This->encoding);
2637 SysFreeString(This->version);
2638 heap_free(This);
2639 return hr;
2642 init_dispex(&This->dispex, (IUnknown*)&This->IMXWriter_iface, &mxwriter_dispex);
2644 *ppObj = &This->IMXWriter_iface;
2646 TRACE("returning iface %p\n", *ppObj);
2648 return S_OK;
2651 static HRESULT WINAPI MXAttributes_QueryInterface(IMXAttributes *iface, REFIID riid, void **ppObj)
2653 mxattributes *This = impl_from_IMXAttributes( iface );
2655 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppObj);
2657 *ppObj = NULL;
2659 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2660 IsEqualGUID( riid, &IID_IDispatch ) ||
2661 IsEqualGUID( riid, &IID_IMXAttributes ))
2663 *ppObj = iface;
2665 else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
2667 *ppObj = &This->ISAXAttributes_iface;
2669 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
2671 *ppObj = &This->IVBSAXAttributes_iface;
2673 else if (dispex_query_interface(&This->dispex, riid, ppObj))
2675 return *ppObj ? S_OK : E_NOINTERFACE;
2677 else
2679 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2680 return E_NOINTERFACE;
2683 IMXAttributes_AddRef( iface );
2685 return S_OK;
2688 static ULONG WINAPI MXAttributes_AddRef(IMXAttributes *iface)
2690 mxattributes *This = impl_from_IMXAttributes( iface );
2691 ULONG ref = InterlockedIncrement( &This->ref );
2692 TRACE("%p, refcount %lu.\n", iface, ref );
2693 return ref;
2696 static ULONG WINAPI MXAttributes_Release(IMXAttributes *iface)
2698 mxattributes *This = impl_from_IMXAttributes( iface );
2699 ULONG ref = InterlockedDecrement( &This->ref );
2701 TRACE("%p, refcount %lu.\n", iface, ref);
2703 if (!ref)
2705 int i;
2707 for (i = 0; i < This->length; i++)
2709 SysFreeString(This->attr[i].qname);
2710 SysFreeString(This->attr[i].local);
2711 SysFreeString(This->attr[i].uri);
2712 SysFreeString(This->attr[i].type);
2713 SysFreeString(This->attr[i].value);
2716 heap_free(This->attr);
2717 heap_free(This);
2720 return ref;
2723 static HRESULT WINAPI MXAttributes_GetTypeInfoCount(IMXAttributes *iface, UINT* pctinfo)
2725 mxattributes *This = impl_from_IMXAttributes( iface );
2726 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2729 static HRESULT WINAPI MXAttributes_GetTypeInfo(IMXAttributes *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2731 mxattributes *This = impl_from_IMXAttributes( iface );
2732 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2735 static HRESULT WINAPI MXAttributes_GetIDsOfNames(
2736 IMXAttributes *iface,
2737 REFIID riid,
2738 LPOLESTR* rgszNames,
2739 UINT cNames,
2740 LCID lcid,
2741 DISPID* rgDispId)
2743 mxattributes *This = impl_from_IMXAttributes( iface );
2744 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2745 riid, rgszNames, cNames, lcid, rgDispId);
2748 static HRESULT WINAPI MXAttributes_Invoke(
2749 IMXAttributes *iface,
2750 DISPID dispIdMember,
2751 REFIID riid,
2752 LCID lcid,
2753 WORD wFlags,
2754 DISPPARAMS* pDispParams,
2755 VARIANT* pVarResult,
2756 EXCEPINFO* pExcepInfo,
2757 UINT* puArgErr)
2759 mxattributes *This = impl_from_IMXAttributes( iface );
2760 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
2761 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2764 static HRESULT WINAPI MXAttributes_addAttribute(IMXAttributes *iface,
2765 BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2767 mxattributes *This = impl_from_IMXAttributes( iface );
2768 mxattribute *attr;
2769 HRESULT hr;
2771 TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(uri), debugstr_w(localName),
2772 debugstr_w(QName), debugstr_w(type), debugstr_w(value));
2774 if ((!uri || !localName || !QName || !type || !value) && This->class_version != MSXML6)
2775 return E_INVALIDARG;
2777 /* ensure array is large enough */
2778 hr = mxattributes_grow(This);
2779 if (hr != S_OK) return hr;
2781 attr = &This->attr[This->length];
2783 attr->qname = SysAllocString(QName);
2784 attr->local = SysAllocString(localName);
2785 attr->uri = SysAllocString(uri);
2786 attr->type = SysAllocString(type ? type : emptyW);
2787 attr->value = SysAllocString(value);
2788 This->length++;
2790 return S_OK;
2793 static HRESULT WINAPI MXAttributes_addAttributeFromIndex(IMXAttributes *iface,
2794 VARIANT atts, int index)
2796 mxattributes *This = impl_from_IMXAttributes( iface );
2797 FIXME("(%p)->(%s %d): stub\n", This, debugstr_variant(&atts), index);
2798 return E_NOTIMPL;
2801 static HRESULT WINAPI MXAttributes_clear(IMXAttributes *iface)
2803 mxattributes *This = impl_from_IMXAttributes( iface );
2804 int i;
2806 TRACE("(%p)\n", This);
2808 for (i = 0; i < This->length; i++)
2810 SysFreeString(This->attr[i].qname);
2811 SysFreeString(This->attr[i].local);
2812 SysFreeString(This->attr[i].uri);
2813 SysFreeString(This->attr[i].type);
2814 SysFreeString(This->attr[i].value);
2815 memset(&This->attr[i], 0, sizeof(mxattribute));
2818 This->length = 0;
2820 return S_OK;
2823 static mxattribute *get_attribute_byindex(mxattributes *attrs, int index)
2825 if (index < 0 || index >= attrs->length) return NULL;
2826 return &attrs->attr[index];
2829 static HRESULT WINAPI MXAttributes_removeAttribute(IMXAttributes *iface, int index)
2831 mxattributes *This = impl_from_IMXAttributes( iface );
2832 mxattribute *dst;
2834 TRACE("(%p)->(%d)\n", This, index);
2836 if (!(dst = get_attribute_byindex(This, index))) return E_INVALIDARG;
2838 /* no need to remove last attribute, just make it inaccessible */
2839 if (index + 1 == This->length)
2841 This->length--;
2842 return S_OK;
2845 memmove(dst, dst + 1, (This->length-index-1)*sizeof(*dst));
2846 This->length--;
2848 return S_OK;
2851 static HRESULT WINAPI MXAttributes_setAttribute(IMXAttributes *iface, int index,
2852 BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2854 mxattributes *This = impl_from_IMXAttributes( iface );
2855 FIXME("(%p)->(%d %s %s %s %s %s): stub\n", This, index, debugstr_w(uri),
2856 debugstr_w(localName), debugstr_w(QName), debugstr_w(type), debugstr_w(value));
2857 return E_NOTIMPL;
2860 static HRESULT WINAPI MXAttributes_setAttributes(IMXAttributes *iface, VARIANT atts)
2862 mxattributes *This = impl_from_IMXAttributes( iface );
2863 FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&atts));
2864 return E_NOTIMPL;
2867 static HRESULT WINAPI MXAttributes_setLocalName(IMXAttributes *iface, int index,
2868 BSTR localName)
2870 mxattributes *This = impl_from_IMXAttributes( iface );
2871 mxattribute *attr;
2873 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(localName));
2875 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2877 SysFreeString(attr->local);
2878 attr->local = SysAllocString(localName);
2880 return S_OK;
2883 static HRESULT WINAPI MXAttributes_setQName(IMXAttributes *iface, int index, BSTR QName)
2885 mxattributes *This = impl_from_IMXAttributes( iface );
2886 mxattribute *attr;
2888 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(QName));
2890 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2892 SysFreeString(attr->qname);
2893 attr->qname = SysAllocString(QName);
2895 return S_OK;
2898 static HRESULT WINAPI MXAttributes_setURI(IMXAttributes *iface, int index, BSTR uri)
2900 mxattributes *This = impl_from_IMXAttributes( iface );
2901 mxattribute *attr;
2903 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(uri));
2905 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2907 SysFreeString(attr->uri);
2908 attr->uri = SysAllocString(uri);
2910 return S_OK;
2913 static HRESULT WINAPI MXAttributes_setValue(IMXAttributes *iface, int index, BSTR value)
2915 mxattributes *This = impl_from_IMXAttributes( iface );
2916 mxattribute *attr;
2918 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(value));
2920 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2922 SysFreeString(attr->value);
2923 attr->value = SysAllocString(value);
2925 return S_OK;
2928 static const IMXAttributesVtbl MXAttributesVtbl = {
2929 MXAttributes_QueryInterface,
2930 MXAttributes_AddRef,
2931 MXAttributes_Release,
2932 MXAttributes_GetTypeInfoCount,
2933 MXAttributes_GetTypeInfo,
2934 MXAttributes_GetIDsOfNames,
2935 MXAttributes_Invoke,
2936 MXAttributes_addAttribute,
2937 MXAttributes_addAttributeFromIndex,
2938 MXAttributes_clear,
2939 MXAttributes_removeAttribute,
2940 MXAttributes_setAttribute,
2941 MXAttributes_setAttributes,
2942 MXAttributes_setLocalName,
2943 MXAttributes_setQName,
2944 MXAttributes_setURI,
2945 MXAttributes_setValue
2948 static HRESULT WINAPI SAXAttributes_QueryInterface(ISAXAttributes *iface, REFIID riid, void **ppObj)
2950 mxattributes *This = impl_from_ISAXAttributes( iface );
2951 return IMXAttributes_QueryInterface(&This->IMXAttributes_iface, riid, ppObj);
2954 static ULONG WINAPI SAXAttributes_AddRef(ISAXAttributes *iface)
2956 mxattributes *This = impl_from_ISAXAttributes( iface );
2957 return IMXAttributes_AddRef(&This->IMXAttributes_iface);
2960 static ULONG WINAPI SAXAttributes_Release(ISAXAttributes *iface)
2962 mxattributes *This = impl_from_ISAXAttributes( iface );
2963 return IMXAttributes_Release(&This->IMXAttributes_iface);
2966 static HRESULT WINAPI SAXAttributes_getLength(ISAXAttributes *iface, int *length)
2968 mxattributes *This = impl_from_ISAXAttributes( iface );
2969 TRACE("(%p)->(%p)\n", This, length);
2971 if (!length && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
2972 return E_POINTER;
2974 *length = This->length;
2976 return S_OK;
2979 static HRESULT WINAPI SAXAttributes_getURI(ISAXAttributes *iface, int index, const WCHAR **uri,
2980 int *len)
2982 mxattributes *This = impl_from_ISAXAttributes( iface );
2984 TRACE("(%p)->(%d %p %p)\n", This, index, uri, len);
2986 if (index >= This->length || index < 0) return E_INVALIDARG;
2987 if (!uri || !len) return E_POINTER;
2989 *len = SysStringLen(This->attr[index].uri);
2990 *uri = This->attr[index].uri;
2992 return S_OK;
2995 static HRESULT WINAPI SAXAttributes_getLocalName(ISAXAttributes *iface, int index, const WCHAR **name,
2996 int *len)
2998 mxattributes *This = impl_from_ISAXAttributes( iface );
3000 TRACE("(%p)->(%d %p %p)\n", This, index, name, len);
3002 if (index >= This->length || index < 0) return E_INVALIDARG;
3003 if (!name || !len) return E_POINTER;
3005 *len = SysStringLen(This->attr[index].local);
3006 *name = This->attr[index].local;
3008 return S_OK;
3011 static HRESULT WINAPI SAXAttributes_getQName(ISAXAttributes *iface, int index, const WCHAR **qname, int *length)
3013 mxattributes *This = impl_from_ISAXAttributes( iface );
3015 TRACE("(%p)->(%d %p %p)\n", This, index, qname, length);
3017 if (index >= This->length) return E_INVALIDARG;
3018 if (!qname || !length) return E_POINTER;
3020 *qname = This->attr[index].qname;
3021 *length = SysStringLen(This->attr[index].qname);
3023 return S_OK;
3026 static HRESULT WINAPI SAXAttributes_getName(ISAXAttributes *iface, int index, const WCHAR **uri, int *uri_len,
3027 const WCHAR **local, int *local_len, const WCHAR **qname, int *qname_len)
3029 mxattributes *This = impl_from_ISAXAttributes( iface );
3031 TRACE("(%p)->(%d %p %p %p %p %p %p)\n", This, index, uri, uri_len, local, local_len, qname, qname_len);
3033 if (index >= This->length || index < 0)
3034 return E_INVALIDARG;
3036 if (!uri || !uri_len || !local || !local_len || !qname || !qname_len)
3037 return E_POINTER;
3039 *uri_len = SysStringLen(This->attr[index].uri);
3040 *uri = This->attr[index].uri;
3042 *local_len = SysStringLen(This->attr[index].local);
3043 *local = This->attr[index].local;
3045 *qname_len = SysStringLen(This->attr[index].qname);
3046 *qname = This->attr[index].qname;
3048 TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*local), debugstr_w(*qname));
3050 return S_OK;
3053 static HRESULT WINAPI SAXAttributes_getIndexFromName(ISAXAttributes *iface, const WCHAR *uri, int uri_len,
3054 const WCHAR *name, int len, int *index)
3056 mxattributes *This = impl_from_ISAXAttributes( iface );
3057 int i;
3059 TRACE("(%p)->(%s:%d %s:%d %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
3060 debugstr_wn(name, len), len, index);
3062 if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3063 return E_POINTER;
3065 if (!uri || !name || !index) return E_INVALIDARG;
3067 for (i = 0; i < This->length; i++)
3069 if (uri_len != SysStringLen(This->attr[i].uri)) continue;
3070 if (wcsncmp(uri, This->attr[i].uri, uri_len)) continue;
3072 if (len != SysStringLen(This->attr[i].local)) continue;
3073 if (wcsncmp(name, This->attr[i].local, len)) continue;
3075 *index = i;
3076 return S_OK;
3079 return E_INVALIDARG;
3082 static HRESULT WINAPI SAXAttributes_getIndexFromQName(ISAXAttributes *iface, const WCHAR *qname,
3083 int len, int *index)
3085 mxattributes *This = impl_from_ISAXAttributes( iface );
3086 int i;
3088 TRACE("(%p)->(%s:%d %p)\n", This, debugstr_wn(qname, len), len, index);
3090 if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3091 return E_POINTER;
3093 if (!qname || !index || !len) return E_INVALIDARG;
3095 for (i = 0; i < This->length; i++)
3097 if (len != SysStringLen(This->attr[i].qname)) continue;
3098 if (wcsncmp(qname, This->attr[i].qname, len)) continue;
3100 *index = i;
3101 return S_OK;
3104 return E_INVALIDARG;
3107 static HRESULT WINAPI SAXAttributes_getType(ISAXAttributes *iface, int index, const WCHAR **type,
3108 int *len)
3110 mxattributes *This = impl_from_ISAXAttributes( iface );
3112 TRACE("(%p)->(%d %p %p)\n", This, index, type, len);
3114 if (index >= This->length) return E_INVALIDARG;
3116 if ((!type || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3117 return E_POINTER;
3119 *type = This->attr[index].type;
3120 *len = SysStringLen(This->attr[index].type);
3122 return S_OK;
3125 static HRESULT WINAPI SAXAttributes_getTypeFromName(ISAXAttributes *iface, const WCHAR * pUri, int nUri,
3126 const WCHAR * pLocalName, int nLocalName, const WCHAR ** pType, int * nType)
3128 mxattributes *This = impl_from_ISAXAttributes( iface );
3129 FIXME("(%p)->(%s:%d %s:%d %p %p): stub\n", This, debugstr_wn(pUri, nUri), nUri,
3130 debugstr_wn(pLocalName, nLocalName), nLocalName, pType, nType);
3131 return E_NOTIMPL;
3134 static HRESULT WINAPI SAXAttributes_getTypeFromQName(ISAXAttributes *iface, const WCHAR * pQName,
3135 int nQName, const WCHAR ** pType, int * nType)
3137 mxattributes *This = impl_from_ISAXAttributes( iface );
3138 FIXME("(%p)->(%s:%d %p %p): stub\n", This, debugstr_wn(pQName, nQName), nQName, pType, nType);
3139 return E_NOTIMPL;
3142 static HRESULT WINAPI SAXAttributes_getValue(ISAXAttributes *iface, int index, const WCHAR **value,
3143 int *len)
3145 mxattributes *This = impl_from_ISAXAttributes( iface );
3147 TRACE("(%p)->(%d %p %p)\n", This, index, value, len);
3149 if (index >= This->length) return E_INVALIDARG;
3151 if ((!value || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3152 return E_POINTER;
3154 *value = This->attr[index].value;
3155 *len = SysStringLen(This->attr[index].value);
3157 return S_OK;
3160 static HRESULT WINAPI SAXAttributes_getValueFromName(ISAXAttributes *iface, const WCHAR *uri,
3161 int uri_len, const WCHAR *name, int name_len, const WCHAR **value, int *value_len)
3163 mxattributes *This = impl_from_ISAXAttributes( iface );
3164 HRESULT hr;
3165 int index;
3167 TRACE("(%p)->(%s:%d %s:%d %p %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
3168 debugstr_wn(name, name_len), name_len, value, value_len);
3170 if (!uri || !name || !value || !value_len)
3171 return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3173 hr = ISAXAttributes_getIndexFromName(iface, uri, uri_len, name, name_len, &index);
3174 if (hr == S_OK)
3175 hr = ISAXAttributes_getValue(iface, index, value, value_len);
3177 return hr;
3180 static HRESULT WINAPI SAXAttributes_getValueFromQName(ISAXAttributes *iface, const WCHAR *qname,
3181 int qname_len, const WCHAR **value, int *value_len)
3183 mxattributes *This = impl_from_ISAXAttributes( iface );
3184 HRESULT hr;
3185 int index;
3187 TRACE("(%p)->(%s:%d %p %p)\n", This, debugstr_wn(qname, qname_len), qname_len, value, value_len);
3189 if (!qname || !value || !value_len)
3190 return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3192 hr = ISAXAttributes_getIndexFromQName(iface, qname, qname_len, &index);
3193 if (hr == S_OK)
3194 hr = ISAXAttributes_getValue(iface, index, value, value_len);
3196 return hr;
3199 static const ISAXAttributesVtbl SAXAttributesVtbl = {
3200 SAXAttributes_QueryInterface,
3201 SAXAttributes_AddRef,
3202 SAXAttributes_Release,
3203 SAXAttributes_getLength,
3204 SAXAttributes_getURI,
3205 SAXAttributes_getLocalName,
3206 SAXAttributes_getQName,
3207 SAXAttributes_getName,
3208 SAXAttributes_getIndexFromName,
3209 SAXAttributes_getIndexFromQName,
3210 SAXAttributes_getType,
3211 SAXAttributes_getTypeFromName,
3212 SAXAttributes_getTypeFromQName,
3213 SAXAttributes_getValue,
3214 SAXAttributes_getValueFromName,
3215 SAXAttributes_getValueFromQName
3218 static HRESULT WINAPI VBSAXAttributes_QueryInterface(
3219 IVBSAXAttributes* iface,
3220 REFIID riid,
3221 void **ppvObject)
3223 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3224 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
3225 return ISAXAttributes_QueryInterface(&This->ISAXAttributes_iface, riid, ppvObject);
3228 static ULONG WINAPI VBSAXAttributes_AddRef(IVBSAXAttributes* iface)
3230 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3231 return ISAXAttributes_AddRef(&This->ISAXAttributes_iface);
3234 static ULONG WINAPI VBSAXAttributes_Release(IVBSAXAttributes* iface)
3236 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3237 return ISAXAttributes_Release(&This->ISAXAttributes_iface);
3240 static HRESULT WINAPI VBSAXAttributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
3242 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3244 TRACE("(%p)->(%p)\n", This, pctinfo);
3246 *pctinfo = 1;
3248 return S_OK;
3251 static HRESULT WINAPI VBSAXAttributes_GetTypeInfo(
3252 IVBSAXAttributes *iface,
3253 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
3255 TRACE("%p, %u, %lx, %p.\n", iface, iTInfo, lcid, ppTInfo);
3257 return get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
3260 static HRESULT WINAPI VBSAXAttributes_GetIDsOfNames(
3261 IVBSAXAttributes *iface,
3262 REFIID riid,
3263 LPOLESTR* rgszNames,
3264 UINT cNames,
3265 LCID lcid,
3266 DISPID* rgDispId)
3268 ITypeInfo *typeinfo;
3269 HRESULT hr;
3271 TRACE("%p, %s, %p, %u, %lx, %p.\n", iface, debugstr_guid(riid), rgszNames, cNames,
3272 lcid, rgDispId);
3274 if(!rgszNames || cNames == 0 || !rgDispId)
3275 return E_INVALIDARG;
3277 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
3278 if(SUCCEEDED(hr))
3280 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
3281 ITypeInfo_Release(typeinfo);
3284 return hr;
3287 static HRESULT WINAPI VBSAXAttributes_Invoke(
3288 IVBSAXAttributes *iface,
3289 DISPID dispIdMember,
3290 REFIID riid,
3291 LCID lcid,
3292 WORD wFlags,
3293 DISPPARAMS* pDispParams,
3294 VARIANT* pVarResult,
3295 EXCEPINFO* pExcepInfo,
3296 UINT* puArgErr)
3298 ITypeInfo *typeinfo;
3299 HRESULT hr;
3301 TRACE("%p, %ld, %s, %lx, %d, %p, %p, %p, %p.\n", iface, dispIdMember, debugstr_guid(riid),
3302 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3304 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
3305 if(SUCCEEDED(hr))
3307 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3308 ITypeInfo_Release(typeinfo);
3311 return hr;
3314 static HRESULT WINAPI VBSAXAttributes_get_length(IVBSAXAttributes* iface, int *len)
3316 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3317 return ISAXAttributes_getLength(&This->ISAXAttributes_iface, len);
3320 static HRESULT WINAPI VBSAXAttributes_getURI(IVBSAXAttributes* iface, int index, BSTR *uri)
3322 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3323 const WCHAR *uriW;
3324 HRESULT hr;
3325 int len;
3327 TRACE("(%p)->(%d %p)\n", This, index, uri);
3329 if (!uri)
3330 return E_POINTER;
3332 *uri = NULL;
3333 hr = ISAXAttributes_getURI(&This->ISAXAttributes_iface, index, &uriW, &len);
3334 if (FAILED(hr))
3335 return hr;
3337 return return_bstrn(uriW, len, uri);
3340 static HRESULT WINAPI VBSAXAttributes_getLocalName(IVBSAXAttributes* iface, int index, BSTR *name)
3342 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3343 const WCHAR *nameW;
3344 HRESULT hr;
3345 int len;
3347 TRACE("(%p)->(%d %p)\n", This, index, name);
3349 if (!name)
3350 return E_POINTER;
3352 *name = NULL;
3353 hr = ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, index, &nameW, &len);
3354 if (FAILED(hr))
3355 return hr;
3357 return return_bstrn(nameW, len, name);
3360 static HRESULT WINAPI VBSAXAttributes_getQName(IVBSAXAttributes* iface, int index, BSTR *qname)
3362 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3363 const WCHAR *qnameW;
3364 HRESULT hr;
3365 int len;
3367 TRACE("(%p)->(%d %p)\n", This, index, qname);
3369 if (!qname)
3370 return E_POINTER;
3372 *qname = NULL;
3373 hr = ISAXAttributes_getQName(&This->ISAXAttributes_iface, index, &qnameW, &len);
3374 if (FAILED(hr))
3375 return hr;
3377 return return_bstrn(qnameW, len, qname);
3380 static HRESULT WINAPI VBSAXAttributes_getIndexFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name, int *index)
3382 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3383 return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3384 name, SysStringLen(name), index);
3387 static HRESULT WINAPI VBSAXAttributes_getIndexFromQName(IVBSAXAttributes* iface, BSTR qname, int *index)
3389 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3390 return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, qname,
3391 SysStringLen(qname), index);
3394 static HRESULT WINAPI VBSAXAttributes_getType(IVBSAXAttributes* iface, int index, BSTR *type)
3396 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3397 const WCHAR *typeW;
3398 HRESULT hr;
3399 int len;
3401 TRACE("(%p)->(%d %p)\n", This, index, type);
3403 if (!type)
3404 return E_POINTER;
3406 *type = NULL;
3407 hr = ISAXAttributes_getType(&This->ISAXAttributes_iface, index, &typeW, &len);
3408 if (FAILED(hr))
3409 return hr;
3411 return return_bstrn(typeW, len, type);
3414 static HRESULT WINAPI VBSAXAttributes_getTypeFromName(IVBSAXAttributes* iface, BSTR uri,
3415 BSTR name, BSTR *type)
3417 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3418 const WCHAR *typeW;
3419 HRESULT hr;
3420 int len;
3422 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), type);
3424 if (!type)
3425 return E_POINTER;
3427 *type = NULL;
3428 hr = ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3429 name, SysStringLen(name), &typeW, &len);
3430 if (FAILED(hr))
3431 return hr;
3433 return return_bstrn(typeW, len, type);
3436 static HRESULT WINAPI VBSAXAttributes_getTypeFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *type)
3438 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3439 const WCHAR *typeW;
3440 HRESULT hr;
3441 int len;
3443 TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), type);
3445 if (!type)
3446 return E_POINTER;
3448 *type = NULL;
3449 hr = ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3450 &typeW, &len);
3451 if (FAILED(hr))
3452 return hr;
3454 return return_bstrn(typeW, len, type);
3457 static HRESULT WINAPI VBSAXAttributes_getValue(IVBSAXAttributes* iface, int index, BSTR *value)
3459 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3460 const WCHAR *valueW;
3461 HRESULT hr;
3462 int len;
3464 TRACE("(%p)->(%d %p)\n", This, index, value);
3466 if (!value)
3467 return E_POINTER;
3469 *value = NULL;
3470 hr = ISAXAttributes_getValue(&This->ISAXAttributes_iface, index, &valueW, &len);
3471 if (FAILED(hr))
3472 return hr;
3474 return return_bstrn(valueW, len, value);
3477 static HRESULT WINAPI VBSAXAttributes_getValueFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name,
3478 BSTR *value)
3480 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3481 const WCHAR *valueW;
3482 HRESULT hr;
3483 int len;
3485 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), value);
3487 if (!value)
3488 return E_POINTER;
3490 *value = NULL;
3491 hr = ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3492 name, SysStringLen(name), &valueW, &len);
3493 if (FAILED(hr))
3494 return hr;
3496 return return_bstrn(valueW, len, value);
3499 static HRESULT WINAPI VBSAXAttributes_getValueFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *value)
3501 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3502 const WCHAR *valueW;
3503 HRESULT hr;
3504 int len;
3506 TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), value);
3508 if (!value)
3509 return E_POINTER;
3511 *value = NULL;
3512 hr = ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3513 &valueW, &len);
3514 if (FAILED(hr))
3515 return hr;
3517 return return_bstrn(valueW, len, value);
3520 static const struct IVBSAXAttributesVtbl VBSAXAttributesVtbl =
3522 VBSAXAttributes_QueryInterface,
3523 VBSAXAttributes_AddRef,
3524 VBSAXAttributes_Release,
3525 VBSAXAttributes_GetTypeInfoCount,
3526 VBSAXAttributes_GetTypeInfo,
3527 VBSAXAttributes_GetIDsOfNames,
3528 VBSAXAttributes_Invoke,
3529 VBSAXAttributes_get_length,
3530 VBSAXAttributes_getURI,
3531 VBSAXAttributes_getLocalName,
3532 VBSAXAttributes_getQName,
3533 VBSAXAttributes_getIndexFromName,
3534 VBSAXAttributes_getIndexFromQName,
3535 VBSAXAttributes_getType,
3536 VBSAXAttributes_getTypeFromName,
3537 VBSAXAttributes_getTypeFromQName,
3538 VBSAXAttributes_getValue,
3539 VBSAXAttributes_getValueFromName,
3540 VBSAXAttributes_getValueFromQName
3543 static const tid_t mxattrs_iface_tids[] = {
3544 IMXAttributes_tid,
3548 static dispex_static_data_t mxattrs_dispex = {
3549 NULL,
3550 IMXAttributes_tid,
3551 NULL,
3552 mxattrs_iface_tids
3555 HRESULT SAXAttributes_create(MSXML_VERSION version, void **ppObj)
3557 static const int default_count = 10;
3558 mxattributes *This;
3560 TRACE("(%p)\n", ppObj);
3562 This = heap_alloc( sizeof (*This) );
3563 if( !This )
3564 return E_OUTOFMEMORY;
3566 This->IMXAttributes_iface.lpVtbl = &MXAttributesVtbl;
3567 This->ISAXAttributes_iface.lpVtbl = &SAXAttributesVtbl;
3568 This->IVBSAXAttributes_iface.lpVtbl = &VBSAXAttributesVtbl;
3569 This->ref = 1;
3571 This->class_version = version;
3573 This->attr = heap_alloc(default_count*sizeof(mxattribute));
3574 This->length = 0;
3575 This->allocated = default_count;
3577 *ppObj = &This->IMXAttributes_iface;
3579 init_dispex(&This->dispex, (IUnknown*)&This->IMXAttributes_iface, &mxattrs_dispex);
3581 TRACE("returning iface %p\n", *ppObj);
3583 return S_OK;