mfplat: Implement GetScanline0AndPitch() for d3d11 buffers.
[wine/zf.git] / dlls / msxml3 / mxwriter.c
blobac3c0fa59c3e92bc26335237e89971870e96f1cb
1 /*
2 * MXWriter implementation
4 * Copyright 2011-2014, 2016 Nikolay Sivov for CodeWeavers
5 * Copyright 2011 Thomas Mullaly
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define COBJMACROS
23 #include "config.h"
25 #include <stdarg.h>
26 #ifdef HAVE_LIBXML2
27 # include <libxml/parser.h>
28 #endif
30 #include "windef.h"
31 #include "winbase.h"
32 #include "ole2.h"
34 #include "msxml6.h"
36 #include "wine/debug.h"
37 #include "wine/list.h"
39 #include "msxml_private.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
43 static const WCHAR emptyW[] = {0};
44 static const WCHAR spaceW[] = {' '};
45 static const WCHAR quotW[] = {'\"'};
46 static const WCHAR closetagW[] = {'>','\r','\n'};
47 static const WCHAR crlfW[] = {'\r','\n'};
48 static const WCHAR entityW[] = {'<','!','E','N','T','I','T','Y',' '};
49 static const WCHAR publicW[] = {'P','U','B','L','I','C',' '};
50 static const WCHAR systemW[] = {'S','Y','S','T','E','M',' '};
52 /* should be ordered as encoding names are sorted */
53 typedef enum
55 XmlEncoding_ISO_8859_1 = 0,
56 XmlEncoding_ISO_8859_13,
57 XmlEncoding_ISO_8859_15,
58 XmlEncoding_ISO_8859_2,
59 XmlEncoding_ISO_8859_3,
60 XmlEncoding_ISO_8859_4,
61 XmlEncoding_ISO_8859_5,
62 XmlEncoding_ISO_8859_7,
63 XmlEncoding_ISO_8859_9,
64 XmlEncoding_UTF16,
65 XmlEncoding_UTF8,
66 XmlEncoding_windows_1250,
67 XmlEncoding_windows_1251,
68 XmlEncoding_windows_1252,
69 XmlEncoding_windows_1253,
70 XmlEncoding_windows_1254,
71 XmlEncoding_windows_1255,
72 XmlEncoding_windows_1256,
73 XmlEncoding_windows_1257,
74 XmlEncoding_windows_1258,
75 XmlEncoding_Unknown
76 } xml_encoding;
78 struct xml_encoding_data
80 const WCHAR *encoding;
81 xml_encoding enc;
82 UINT cp;
85 static const WCHAR iso_8859_1W[] = {'i','s','o','-','8','8','5','9','-','1',0};
86 static const WCHAR iso_8859_2W[] = {'i','s','o','-','8','8','5','9','-','2',0};
87 static const WCHAR iso_8859_3W[] = {'i','s','o','-','8','8','5','9','-','3',0};
88 static const WCHAR iso_8859_4W[] = {'i','s','o','-','8','8','5','9','-','4',0};
89 static const WCHAR iso_8859_5W[] = {'i','s','o','-','8','8','5','9','-','5',0};
90 static const WCHAR iso_8859_7W[] = {'i','s','o','-','8','8','5','9','-','7',0};
91 static const WCHAR iso_8859_9W[] = {'i','s','o','-','8','8','5','9','-','9',0};
92 static const WCHAR iso_8859_13W[] = {'i','s','o','-','8','8','5','9','-','1','3',0};
93 static const WCHAR iso_8859_15W[] = {'i','s','o','-','8','8','5','9','-','1','5',0};
94 static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
95 static const WCHAR utf8W[] = {'U','T','F','-','8',0};
96 static const WCHAR windows_1250W[] = {'w','i','n','d','o','w','s','-','1','2','5','0',0};
97 static const WCHAR windows_1251W[] = {'w','i','n','d','o','w','s','-','1','2','5','1',0};
98 static const WCHAR windows_1252W[] = {'w','i','n','d','o','w','s','-','1','2','5','2',0};
99 static const WCHAR windows_1253W[] = {'w','i','n','d','o','w','s','-','1','2','5','3',0};
100 static const WCHAR windows_1254W[] = {'w','i','n','d','o','w','s','-','1','2','5','4',0};
101 static const WCHAR windows_1255W[] = {'w','i','n','d','o','w','s','-','1','2','5','5',0};
102 static const WCHAR windows_1256W[] = {'w','i','n','d','o','w','s','-','1','2','5','6',0};
103 static const WCHAR windows_1257W[] = {'w','i','n','d','o','w','s','-','1','2','5','7',0};
104 static const WCHAR windows_1258W[] = {'w','i','n','d','o','w','s','-','1','2','5','8',0};
106 static const struct xml_encoding_data xml_encoding_map[] = {
107 { iso_8859_1W, XmlEncoding_ISO_8859_1, 28591 },
108 { iso_8859_13W, XmlEncoding_ISO_8859_13, 28603 },
109 { iso_8859_15W, XmlEncoding_ISO_8859_15, 28605 },
110 { iso_8859_2W, XmlEncoding_ISO_8859_2, 28592 },
111 { iso_8859_3W, XmlEncoding_ISO_8859_3, 28593 },
112 { iso_8859_4W, XmlEncoding_ISO_8859_4, 28594 },
113 { iso_8859_5W, XmlEncoding_ISO_8859_5, 28595 },
114 { iso_8859_7W, XmlEncoding_ISO_8859_7, 28597 },
115 { iso_8859_9W, XmlEncoding_ISO_8859_9, 28599 },
116 { utf16W, XmlEncoding_UTF16, ~0 },
117 { utf8W, XmlEncoding_UTF8, CP_UTF8 },
118 { windows_1250W,XmlEncoding_windows_1250, 1250 },
119 { windows_1251W,XmlEncoding_windows_1251, 1251 },
120 { windows_1252W,XmlEncoding_windows_1252, 1252 },
121 { windows_1253W,XmlEncoding_windows_1253, 1253 },
122 { windows_1254W,XmlEncoding_windows_1254, 1254 },
123 { windows_1255W,XmlEncoding_windows_1255, 1255 },
124 { windows_1256W,XmlEncoding_windows_1256, 1256 },
125 { windows_1257W,XmlEncoding_windows_1257, 1257 },
126 { windows_1258W,XmlEncoding_windows_1258, 1258 }
129 typedef enum
131 MXWriter_BOM = 0,
132 MXWriter_DisableEscaping,
133 MXWriter_Indent,
134 MXWriter_OmitXmlDecl,
135 MXWriter_Standalone,
136 MXWriter_LastProp
137 } mxwriter_prop;
139 typedef enum
141 EscapeValue,
142 EscapeText
143 } escape_mode;
145 typedef struct
147 struct list entry;
148 char *data;
149 unsigned int allocated;
150 unsigned int written;
151 } encoded_buffer;
153 typedef struct
155 encoded_buffer encoded;
156 UINT code_page;
157 UINT utf16_total; /* total number of bytes written since last buffer reinitialization */
158 struct list blocks; /* only used when output was not set, for BSTR case */
159 } output_buffer;
161 typedef struct
163 DispatchEx dispex;
164 IMXWriter IMXWriter_iface;
165 ISAXContentHandler ISAXContentHandler_iface;
166 ISAXLexicalHandler ISAXLexicalHandler_iface;
167 ISAXDeclHandler ISAXDeclHandler_iface;
168 ISAXDTDHandler ISAXDTDHandler_iface;
169 ISAXErrorHandler ISAXErrorHandler_iface;
170 IVBSAXDeclHandler IVBSAXDeclHandler_iface;
171 IVBSAXLexicalHandler IVBSAXLexicalHandler_iface;
172 IVBSAXContentHandler IVBSAXContentHandler_iface;
173 IVBSAXDTDHandler IVBSAXDTDHandler_iface;
174 IVBSAXErrorHandler IVBSAXErrorHandler_iface;
176 LONG ref;
177 MSXML_VERSION class_version;
179 VARIANT_BOOL props[MXWriter_LastProp];
180 BOOL prop_changed;
181 BOOL cdata;
183 BOOL text; /* last node was text node, so we shouldn't indent next node */
184 BOOL newline; /* newline was already added as a part of previous call */
185 UINT indent; /* indentation level for next node */
187 BSTR version;
189 BSTR encoding; /* exact property value */
190 xml_encoding xml_enc;
192 /* contains a pending (or not closed yet) element name or NULL if
193 we don't have to close */
194 BSTR element;
196 IStream *dest;
198 output_buffer buffer;
199 } mxwriter;
201 typedef struct
203 BSTR qname;
204 BSTR local;
205 BSTR uri;
206 BSTR type;
207 BSTR value;
208 } mxattribute;
210 typedef struct
212 DispatchEx dispex;
213 IMXAttributes IMXAttributes_iface;
214 ISAXAttributes ISAXAttributes_iface;
215 IVBSAXAttributes IVBSAXAttributes_iface;
216 LONG ref;
218 MSXML_VERSION class_version;
220 mxattribute *attr;
221 int length;
222 int allocated;
223 } mxattributes;
225 static inline mxattributes *impl_from_IMXAttributes( IMXAttributes *iface )
227 return CONTAINING_RECORD(iface, mxattributes, IMXAttributes_iface);
230 static inline mxattributes *impl_from_ISAXAttributes( ISAXAttributes *iface )
232 return CONTAINING_RECORD(iface, mxattributes, ISAXAttributes_iface);
235 static inline mxattributes *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
237 return CONTAINING_RECORD(iface, mxattributes, IVBSAXAttributes_iface);
240 static HRESULT mxattributes_grow(mxattributes *This)
242 if (This->length < This->allocated) return S_OK;
244 This->allocated *= 2;
245 This->attr = heap_realloc(This->attr, This->allocated*sizeof(mxattribute));
247 return This->attr ? S_OK : E_OUTOFMEMORY;
250 static xml_encoding parse_encoding_name(const WCHAR *encoding)
252 int min, max, n, c;
254 min = 0;
255 max = ARRAY_SIZE(xml_encoding_map) - 1;
257 while (min <= max)
259 n = (min+max)/2;
261 c = strcmpiW(xml_encoding_map[n].encoding, encoding);
262 if (!c)
263 return xml_encoding_map[n].enc;
265 if (c > 0)
266 max = n-1;
267 else
268 min = n+1;
271 return XmlEncoding_Unknown;
274 static HRESULT init_encoded_buffer(encoded_buffer *buffer)
276 const int initial_len = 0x1000;
277 buffer->data = heap_alloc(initial_len);
278 if (!buffer->data) return E_OUTOFMEMORY;
280 memset(buffer->data, 0, 4);
281 buffer->allocated = initial_len;
282 buffer->written = 0;
284 return S_OK;
287 static void free_encoded_buffer(encoded_buffer *buffer)
289 heap_free(buffer->data);
292 static HRESULT get_code_page(xml_encoding encoding, UINT *cp)
294 const struct xml_encoding_data *data;
296 if (encoding == XmlEncoding_Unknown)
298 FIXME("unsupported encoding %d\n", encoding);
299 return E_NOTIMPL;
302 data = &xml_encoding_map[encoding];
303 *cp = data->cp;
305 return S_OK;
308 static HRESULT init_output_buffer(xml_encoding encoding, output_buffer *buffer)
310 HRESULT hr;
312 hr = get_code_page(encoding, &buffer->code_page);
313 if (hr != S_OK)
314 return hr;
316 hr = init_encoded_buffer(&buffer->encoded);
317 if (hr != S_OK)
318 return hr;
320 list_init(&buffer->blocks);
321 buffer->utf16_total = 0;
323 return S_OK;
326 static void free_output_buffer(output_buffer *buffer)
328 encoded_buffer *cur, *cur2;
330 free_encoded_buffer(&buffer->encoded);
332 LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &buffer->blocks, encoded_buffer, entry)
334 list_remove(&cur->entry);
335 free_encoded_buffer(cur);
336 heap_free(cur);
340 static HRESULT write_output_buffer(mxwriter *writer, const WCHAR *data, int len)
342 output_buffer *buffer = &writer->buffer;
343 encoded_buffer *buff;
344 unsigned int written;
345 int src_len;
347 if (!len || !*data)
348 return S_OK;
350 src_len = len == -1 ? strlenW(data) : len;
351 if (writer->dest)
353 buff = &buffer->encoded;
355 if (buffer->code_page == ~0)
357 unsigned int avail = buff->allocated - buff->written;
359 src_len *= sizeof(WCHAR);
360 written = min(avail, src_len);
362 /* fill internal buffer first */
363 if (avail)
365 memcpy(buff->data + buff->written, data, written);
366 data += written / sizeof(WCHAR);
367 buff->written += written;
368 avail -= written;
369 src_len -= written;
372 if (!avail)
374 IStream_Write(writer->dest, buff->data, buff->written, &written);
375 buff->written = 0;
376 if (src_len >= buff->allocated)
377 IStream_Write(writer->dest, data, src_len, &written);
378 else if (src_len)
380 memcpy(buff->data, data, src_len);
381 buff->written += src_len;
385 else
387 unsigned int avail = buff->allocated - buff->written;
388 int length;
390 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, NULL, 0, NULL, NULL);
391 if (avail >= length)
393 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, buff->data + buff->written, length, NULL, NULL);
394 buff->written += length;
396 else
398 /* drain what we go so far */
399 if (buff->written)
401 IStream_Write(writer->dest, buff->data, buff->written, &written);
402 buff->written = 0;
403 avail = buff->allocated;
406 if (avail >= length)
408 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, buff->data + buff->written, length, NULL, NULL);
409 buff->written += length;
411 else
413 char *mb;
415 /* if current chunk is larger than total buffer size, convert it at once using temporary allocated buffer */
416 mb = heap_alloc(length);
417 if (!mb)
418 return E_OUTOFMEMORY;
420 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, mb, length, NULL, NULL);
421 IStream_Write(writer->dest, mb, length, &written);
422 heap_free(mb);
427 /* When writer has no output set we have to accumulate everything to return it later in a form of BSTR.
428 To achieve that:
430 - fill a buffer already allocated as part of output buffer;
431 - when current buffer is full, allocate another one and switch to it; buffers themselves never grow,
432 but are linked together, with head pointing to first allocated buffer after initial one got filled;
433 - later during get_output() contents are concatenated by copying one after another to destination BSTR buffer,
434 that's returned to the client. */
435 else
437 /* select last used block */
438 if (list_empty(&buffer->blocks))
439 buff = &buffer->encoded;
440 else
441 buff = LIST_ENTRY(list_tail(&buffer->blocks), encoded_buffer, entry);
443 src_len *= sizeof(WCHAR);
444 while (src_len)
446 unsigned int avail = buff->allocated - buff->written;
447 unsigned int written = min(avail, src_len);
449 if (avail)
451 memcpy(buff->data + buff->written, data, written);
452 buff->written += written;
453 buffer->utf16_total += written;
454 src_len -= written;
457 /* alloc new block if needed and retry */
458 if (src_len)
460 encoded_buffer *next = heap_alloc(sizeof(*next));
461 HRESULT hr;
463 if (FAILED(hr = init_encoded_buffer(next))) {
464 heap_free(next);
465 return hr;
468 list_add_tail(&buffer->blocks, &next->entry);
469 buff = next;
474 return S_OK;
477 static HRESULT write_output_buffer_quoted(mxwriter *writer, const WCHAR *data, int len)
479 write_output_buffer(writer, quotW, 1);
480 write_output_buffer(writer, data, len);
481 write_output_buffer(writer, quotW, 1);
483 return S_OK;
486 /* frees buffer data, reallocates with a default lengths */
487 static void close_output_buffer(mxwriter *writer)
489 encoded_buffer *cur, *cur2;
491 heap_free(writer->buffer.encoded.data);
493 LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &writer->buffer.blocks, encoded_buffer, entry)
495 list_remove(&cur->entry);
496 free_encoded_buffer(cur);
497 heap_free(cur);
500 init_encoded_buffer(&writer->buffer.encoded);
501 get_code_page(writer->xml_enc, &writer->buffer.code_page);
502 writer->buffer.utf16_total = 0;
503 list_init(&writer->buffer.blocks);
506 /* Escapes special characters like:
507 '<' -> "&lt;"
508 '&' -> "&amp;"
509 '"' -> "&quot;"
510 '>' -> "&gt;"
512 On call 'len' contains a length of 'str' in chars or -1 if it's null terminated.
513 After a call it's updated with actual new length if it wasn't -1 initially.
515 static WCHAR *get_escaped_string(const WCHAR *str, escape_mode mode, int *len)
517 static const WCHAR ltW[] = {'&','l','t',';'};
518 static const WCHAR ampW[] = {'&','a','m','p',';'};
519 static const WCHAR equotW[] = {'&','q','u','o','t',';'};
520 static const WCHAR gtW[] = {'&','g','t',';'};
522 const int default_alloc = 100;
523 const int grow_thresh = 10;
524 int p = *len, conv_len;
525 WCHAR *ptr, *ret;
527 /* default buffer size to something if length is unknown */
528 conv_len = max(2**len, default_alloc);
529 ptr = ret = heap_alloc(conv_len*sizeof(WCHAR));
531 while (p)
533 if (ptr - ret > conv_len - grow_thresh)
535 int written = ptr - ret;
536 conv_len *= 2;
537 ptr = ret = heap_realloc(ret, conv_len*sizeof(WCHAR));
538 ptr += written;
541 switch (*str)
543 case '<':
544 memcpy(ptr, ltW, sizeof(ltW));
545 ptr += ARRAY_SIZE(ltW);
546 break;
547 case '&':
548 memcpy(ptr, ampW, sizeof(ampW));
549 ptr += ARRAY_SIZE(ampW);
550 break;
551 case '>':
552 memcpy(ptr, gtW, sizeof(gtW));
553 ptr += ARRAY_SIZE(gtW);
554 break;
555 case '"':
556 if (mode == EscapeValue)
558 memcpy(ptr, equotW, sizeof(equotW));
559 ptr += ARRAY_SIZE(equotW);
560 break;
562 /* fallthrough for text mode */
563 default:
564 *ptr++ = *str;
565 break;
568 str++;
569 p--;
572 *len = ptr-ret;
573 *++ptr = 0;
575 return ret;
578 static void write_prolog_buffer(mxwriter *writer)
580 static const WCHAR versionW[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','='};
581 static const WCHAR encodingW[] = {' ','e','n','c','o','d','i','n','g','=','\"'};
582 static const WCHAR standaloneW[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
583 static const WCHAR yesW[] = {'y','e','s','\"','?','>'};
584 static const WCHAR noW[] = {'n','o','\"','?','>'};
586 /* version */
587 write_output_buffer(writer, versionW, ARRAY_SIZE(versionW));
588 write_output_buffer_quoted(writer, writer->version, -1);
590 /* encoding */
591 write_output_buffer(writer, encodingW, ARRAY_SIZE(encodingW));
593 if (writer->dest)
594 write_output_buffer(writer, writer->encoding, -1);
595 else
596 write_output_buffer(writer, utf16W, ARRAY_SIZE(utf16W) - 1);
597 write_output_buffer(writer, quotW, 1);
599 /* standalone */
600 write_output_buffer(writer, standaloneW, ARRAY_SIZE(standaloneW));
601 if (writer->props[MXWriter_Standalone] == VARIANT_TRUE)
602 write_output_buffer(writer, yesW, ARRAY_SIZE(yesW));
603 else
604 write_output_buffer(writer, noW, ARRAY_SIZE(noW));
606 write_output_buffer(writer, crlfW, ARRAY_SIZE(crlfW));
607 writer->newline = TRUE;
610 /* Attempts to the write data from the mxwriter's buffer to
611 * the destination stream (if there is one).
613 static HRESULT write_data_to_stream(mxwriter *writer)
615 encoded_buffer *buffer = &writer->buffer.encoded;
616 ULONG written = 0;
618 if (!writer->dest)
619 return S_OK;
621 if (buffer->written == 0)
623 if (writer->xml_enc == XmlEncoding_UTF8)
624 IStream_Write(writer->dest, buffer->data, 0, &written);
626 else
628 IStream_Write(writer->dest, buffer->data, buffer->written, &written);
629 buffer->written = 0;
632 return S_OK;
635 /* Newly added element start tag left unclosed cause for empty elements
636 we have to close it differently. */
637 static void close_element_starttag(mxwriter *writer)
639 static const WCHAR gtW[] = {'>'};
640 if (!writer->element) return;
641 write_output_buffer(writer, gtW, 1);
644 static void write_node_indent(mxwriter *writer)
646 static const WCHAR tabW[] = {'\t'};
647 int indent = writer->indent;
649 if (!writer->props[MXWriter_Indent] || writer->text)
651 writer->text = FALSE;
652 return;
655 /* This is to workaround PI output logic that always puts newline chars,
656 document prolog PI does that too. */
657 if (!writer->newline)
658 write_output_buffer(writer, crlfW, ARRAY_SIZE(crlfW));
659 while (indent--)
660 write_output_buffer(writer, tabW, 1);
662 writer->newline = FALSE;
663 writer->text = FALSE;
666 static inline void writer_inc_indent(mxwriter *This)
668 This->indent++;
671 static inline void writer_dec_indent(mxwriter *This)
673 if (This->indent) This->indent--;
674 /* depth is decreased only when element is closed, meaning it's not a text node
675 at this point */
676 This->text = FALSE;
679 static void set_element_name(mxwriter *This, const WCHAR *name, int len)
681 SysFreeString(This->element);
682 if (name)
683 This->element = len != -1 ? SysAllocStringLen(name, len) : SysAllocString(name);
684 else
685 This->element = NULL;
688 static inline HRESULT flush_output_buffer(mxwriter *This)
690 close_element_starttag(This);
691 set_element_name(This, NULL, 0);
692 This->cdata = FALSE;
693 return write_data_to_stream(This);
696 static HRESULT writer_set_property(mxwriter *writer, mxwriter_prop property, VARIANT_BOOL value)
698 writer->props[property] = value;
699 writer->prop_changed = TRUE;
700 return S_OK;
703 static HRESULT writer_get_property(const mxwriter *writer, mxwriter_prop property, VARIANT_BOOL *value)
705 if (!value) return E_POINTER;
706 *value = writer->props[property];
707 return S_OK;
710 static inline mxwriter *impl_from_IMXWriter(IMXWriter *iface)
712 return CONTAINING_RECORD(iface, mxwriter, IMXWriter_iface);
715 static inline mxwriter *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
717 return CONTAINING_RECORD(iface, mxwriter, ISAXContentHandler_iface);
720 static inline mxwriter *impl_from_IVBSAXContentHandler(IVBSAXContentHandler *iface)
722 return CONTAINING_RECORD(iface, mxwriter, IVBSAXContentHandler_iface);
725 static inline mxwriter *impl_from_ISAXLexicalHandler(ISAXLexicalHandler *iface)
727 return CONTAINING_RECORD(iface, mxwriter, ISAXLexicalHandler_iface);
730 static inline mxwriter *impl_from_IVBSAXLexicalHandler(IVBSAXLexicalHandler *iface)
732 return CONTAINING_RECORD(iface, mxwriter, IVBSAXLexicalHandler_iface);
735 static inline mxwriter *impl_from_ISAXDeclHandler(ISAXDeclHandler *iface)
737 return CONTAINING_RECORD(iface, mxwriter, ISAXDeclHandler_iface);
740 static inline mxwriter *impl_from_IVBSAXDeclHandler(IVBSAXDeclHandler *iface)
742 return CONTAINING_RECORD(iface, mxwriter, IVBSAXDeclHandler_iface);
745 static inline mxwriter *impl_from_ISAXDTDHandler(ISAXDTDHandler *iface)
747 return CONTAINING_RECORD(iface, mxwriter, ISAXDTDHandler_iface);
750 static inline mxwriter *impl_from_IVBSAXDTDHandler(IVBSAXDTDHandler *iface)
752 return CONTAINING_RECORD(iface, mxwriter, IVBSAXDTDHandler_iface);
755 static inline mxwriter *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
757 return CONTAINING_RECORD(iface, mxwriter, ISAXErrorHandler_iface);
760 static inline mxwriter *impl_from_IVBSAXErrorHandler(IVBSAXErrorHandler *iface)
762 return CONTAINING_RECORD(iface, mxwriter, IVBSAXErrorHandler_iface);
765 static HRESULT WINAPI mxwriter_QueryInterface(IMXWriter *iface, REFIID riid, void **obj)
767 mxwriter *This = impl_from_IMXWriter( iface );
769 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
771 *obj = NULL;
773 if ( IsEqualGUID( riid, &IID_IMXWriter ) ||
774 IsEqualGUID( riid, &IID_IDispatch ) ||
775 IsEqualGUID( riid, &IID_IUnknown ) )
777 *obj = &This->IMXWriter_iface;
779 else if ( IsEqualGUID( riid, &IID_ISAXContentHandler ) )
781 *obj = &This->ISAXContentHandler_iface;
783 else if ( IsEqualGUID( riid, &IID_ISAXLexicalHandler ) )
785 *obj = &This->ISAXLexicalHandler_iface;
787 else if ( IsEqualGUID( riid, &IID_ISAXDeclHandler ) )
789 *obj = &This->ISAXDeclHandler_iface;
791 else if ( IsEqualGUID( riid, &IID_ISAXDTDHandler ) )
793 *obj = &This->ISAXDTDHandler_iface;
795 else if ( IsEqualGUID( riid, &IID_ISAXErrorHandler ) )
797 *obj = &This->ISAXErrorHandler_iface;
799 else if ( IsEqualGUID( riid, &IID_IVBSAXDeclHandler ) )
801 *obj = &This->IVBSAXDeclHandler_iface;
803 else if ( IsEqualGUID( riid, &IID_IVBSAXLexicalHandler ) )
805 *obj = &This->IVBSAXLexicalHandler_iface;
807 else if ( IsEqualGUID( riid, &IID_IVBSAXContentHandler ) )
809 *obj = &This->IVBSAXContentHandler_iface;
811 else if ( IsEqualGUID( riid, &IID_IVBSAXDTDHandler ) )
813 *obj = &This->IVBSAXDTDHandler_iface;
815 else if ( IsEqualGUID( riid, &IID_IVBSAXErrorHandler ) )
817 *obj = &This->IVBSAXErrorHandler_iface;
819 else if (dispex_query_interface(&This->dispex, riid, obj))
821 return *obj ? S_OK : E_NOINTERFACE;
823 else
825 ERR("interface %s not implemented\n", debugstr_guid(riid));
826 *obj = NULL;
827 return E_NOINTERFACE;
830 IMXWriter_AddRef(iface);
831 return S_OK;
834 static ULONG WINAPI mxwriter_AddRef(IMXWriter *iface)
836 mxwriter *This = impl_from_IMXWriter( iface );
837 LONG ref = InterlockedIncrement(&This->ref);
839 TRACE("(%p)->(%d)\n", This, ref);
841 return ref;
844 static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
846 mxwriter *This = impl_from_IMXWriter( iface );
847 ULONG ref = InterlockedDecrement(&This->ref);
849 TRACE("(%p)->(%d)\n", This, ref);
851 if(!ref)
853 /* Windows flushes the buffer when the interface is destroyed. */
854 flush_output_buffer(This);
855 free_output_buffer(&This->buffer);
857 if (This->dest) IStream_Release(This->dest);
858 SysFreeString(This->version);
859 SysFreeString(This->encoding);
861 SysFreeString(This->element);
862 heap_free(This);
865 return ref;
868 static HRESULT WINAPI mxwriter_GetTypeInfoCount(IMXWriter *iface, UINT* pctinfo)
870 mxwriter *This = impl_from_IMXWriter( iface );
871 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
874 static HRESULT WINAPI mxwriter_GetTypeInfo(
875 IMXWriter *iface,
876 UINT iTInfo, LCID lcid,
877 ITypeInfo** ppTInfo )
879 mxwriter *This = impl_from_IMXWriter( iface );
880 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
881 iTInfo, lcid, ppTInfo);
884 static HRESULT WINAPI mxwriter_GetIDsOfNames(
885 IMXWriter *iface,
886 REFIID riid, LPOLESTR* rgszNames,
887 UINT cNames, LCID lcid, DISPID* rgDispId )
889 mxwriter *This = impl_from_IMXWriter( iface );
890 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
891 riid, rgszNames, cNames, lcid, rgDispId);
894 static HRESULT WINAPI mxwriter_Invoke(
895 IMXWriter *iface,
896 DISPID dispIdMember, REFIID riid, LCID lcid,
897 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
898 EXCEPINFO* pExcepInfo, UINT* puArgErr )
900 mxwriter *This = impl_from_IMXWriter( iface );
901 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
902 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
905 static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
907 mxwriter *This = impl_from_IMXWriter( iface );
908 HRESULT hr;
910 TRACE("(%p)->(%s)\n", This, debugstr_variant(&dest));
912 hr = flush_output_buffer(This);
913 if (FAILED(hr))
914 return hr;
916 switch (V_VT(&dest))
918 case VT_EMPTY:
920 if (This->dest) IStream_Release(This->dest);
921 This->dest = NULL;
922 close_output_buffer(This);
923 break;
925 case VT_UNKNOWN:
927 IStream *stream;
929 hr = IUnknown_QueryInterface(V_UNKNOWN(&dest), &IID_IStream, (void**)&stream);
930 if (hr == S_OK)
932 /* Recreate the output buffer to make sure it's using the correct encoding. */
933 close_output_buffer(This);
935 if (This->dest) IStream_Release(This->dest);
936 This->dest = stream;
937 break;
940 FIXME("unhandled interface type for VT_UNKNOWN destination\n");
941 return E_NOTIMPL;
943 default:
944 FIXME("unhandled destination type %s\n", debugstr_variant(&dest));
945 return E_NOTIMPL;
948 return S_OK;
951 static HRESULT WINAPI mxwriter_get_output(IMXWriter *iface, VARIANT *dest)
953 mxwriter *This = impl_from_IMXWriter( iface );
955 TRACE("(%p)->(%p)\n", This, dest);
957 if (!dest) return E_POINTER;
959 if (This->dest)
961 /* we only support IStream output so far */
962 V_VT(dest) = VT_UNKNOWN;
963 V_UNKNOWN(dest) = (IUnknown*)This->dest;
964 IStream_AddRef(This->dest);
966 else
968 encoded_buffer *buff;
969 char *dest_ptr;
970 HRESULT hr;
972 hr = flush_output_buffer(This);
973 if (FAILED(hr))
974 return hr;
976 V_VT(dest) = VT_BSTR;
977 V_BSTR(dest) = SysAllocStringLen(NULL, This->buffer.utf16_total / sizeof(WCHAR));
978 if (!V_BSTR(dest))
979 return E_OUTOFMEMORY;
981 dest_ptr = (char*)V_BSTR(dest);
982 buff = &This->buffer.encoded;
984 if (buff->written)
986 memcpy(dest_ptr, buff->data, buff->written);
987 dest_ptr += buff->written;
990 LIST_FOR_EACH_ENTRY(buff, &This->buffer.blocks, encoded_buffer, entry)
992 memcpy(dest_ptr, buff->data, buff->written);
993 dest_ptr += buff->written;
997 return S_OK;
1000 static HRESULT WINAPI mxwriter_put_encoding(IMXWriter *iface, BSTR encoding)
1002 mxwriter *This = impl_from_IMXWriter( iface );
1003 xml_encoding enc;
1004 HRESULT hr;
1006 TRACE("(%p)->(%s)\n", This, debugstr_w(encoding));
1008 enc = parse_encoding_name(encoding);
1009 if (enc == XmlEncoding_Unknown)
1011 FIXME("unsupported encoding %s\n", debugstr_w(encoding));
1012 return E_INVALIDARG;
1015 hr = flush_output_buffer(This);
1016 if (FAILED(hr))
1017 return hr;
1019 SysReAllocString(&This->encoding, encoding);
1020 This->xml_enc = enc;
1022 TRACE("got encoding %d\n", This->xml_enc);
1023 close_output_buffer(This);
1024 return S_OK;
1027 static HRESULT WINAPI mxwriter_get_encoding(IMXWriter *iface, BSTR *encoding)
1029 mxwriter *This = impl_from_IMXWriter( iface );
1031 TRACE("(%p)->(%p)\n", This, encoding);
1033 if (!encoding) return E_POINTER;
1035 *encoding = SysAllocString(This->encoding);
1036 if (!*encoding) return E_OUTOFMEMORY;
1038 return S_OK;
1041 static HRESULT WINAPI mxwriter_put_byteOrderMark(IMXWriter *iface, VARIANT_BOOL value)
1043 mxwriter *This = impl_from_IMXWriter( iface );
1045 TRACE("(%p)->(%d)\n", This, value);
1046 return writer_set_property(This, MXWriter_BOM, value);
1049 static HRESULT WINAPI mxwriter_get_byteOrderMark(IMXWriter *iface, VARIANT_BOOL *value)
1051 mxwriter *This = impl_from_IMXWriter( iface );
1053 TRACE("(%p)->(%p)\n", This, value);
1054 return writer_get_property(This, MXWriter_BOM, value);
1057 static HRESULT WINAPI mxwriter_put_indent(IMXWriter *iface, VARIANT_BOOL value)
1059 mxwriter *This = impl_from_IMXWriter( iface );
1061 TRACE("(%p)->(%d)\n", This, value);
1062 return writer_set_property(This, MXWriter_Indent, value);
1065 static HRESULT WINAPI mxwriter_get_indent(IMXWriter *iface, VARIANT_BOOL *value)
1067 mxwriter *This = impl_from_IMXWriter( iface );
1069 TRACE("(%p)->(%p)\n", This, value);
1070 return writer_get_property(This, MXWriter_Indent, value);
1073 static HRESULT WINAPI mxwriter_put_standalone(IMXWriter *iface, VARIANT_BOOL value)
1075 mxwriter *This = impl_from_IMXWriter( iface );
1077 TRACE("(%p)->(%d)\n", This, value);
1078 return writer_set_property(This, MXWriter_Standalone, value);
1081 static HRESULT WINAPI mxwriter_get_standalone(IMXWriter *iface, VARIANT_BOOL *value)
1083 mxwriter *This = impl_from_IMXWriter( iface );
1085 TRACE("(%p)->(%p)\n", This, value);
1086 return writer_get_property(This, MXWriter_Standalone, value);
1089 static HRESULT WINAPI mxwriter_put_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL value)
1091 mxwriter *This = impl_from_IMXWriter( iface );
1093 TRACE("(%p)->(%d)\n", This, value);
1094 return writer_set_property(This, MXWriter_OmitXmlDecl, value);
1097 static HRESULT WINAPI mxwriter_get_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL *value)
1099 mxwriter *This = impl_from_IMXWriter( iface );
1101 TRACE("(%p)->(%p)\n", This, value);
1102 return writer_get_property(This, MXWriter_OmitXmlDecl, value);
1105 static HRESULT WINAPI mxwriter_put_version(IMXWriter *iface, BSTR version)
1107 mxwriter *This = impl_from_IMXWriter( iface );
1109 TRACE("(%p)->(%s)\n", This, debugstr_w(version));
1111 if (!version) return E_INVALIDARG;
1113 SysFreeString(This->version);
1114 This->version = SysAllocString(version);
1116 return S_OK;
1119 static HRESULT WINAPI mxwriter_get_version(IMXWriter *iface, BSTR *version)
1121 mxwriter *This = impl_from_IMXWriter( iface );
1123 TRACE("(%p)->(%p)\n", This, version);
1125 if (!version) return E_POINTER;
1127 return return_bstr(This->version, version);
1130 static HRESULT WINAPI mxwriter_put_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL value)
1132 mxwriter *This = impl_from_IMXWriter( iface );
1134 TRACE("(%p)->(%d)\n", This, value);
1135 return writer_set_property(This, MXWriter_DisableEscaping, value);
1138 static HRESULT WINAPI mxwriter_get_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL *value)
1140 mxwriter *This = impl_from_IMXWriter( iface );
1142 TRACE("(%p)->(%p)\n", This, value);
1143 return writer_get_property(This, MXWriter_DisableEscaping, value);
1146 static HRESULT WINAPI mxwriter_flush(IMXWriter *iface)
1148 mxwriter *This = impl_from_IMXWriter( iface );
1149 TRACE("(%p)\n", This);
1150 return flush_output_buffer(This);
1153 static const struct IMXWriterVtbl MXWriterVtbl =
1155 mxwriter_QueryInterface,
1156 mxwriter_AddRef,
1157 mxwriter_Release,
1158 mxwriter_GetTypeInfoCount,
1159 mxwriter_GetTypeInfo,
1160 mxwriter_GetIDsOfNames,
1161 mxwriter_Invoke,
1162 mxwriter_put_output,
1163 mxwriter_get_output,
1164 mxwriter_put_encoding,
1165 mxwriter_get_encoding,
1166 mxwriter_put_byteOrderMark,
1167 mxwriter_get_byteOrderMark,
1168 mxwriter_put_indent,
1169 mxwriter_get_indent,
1170 mxwriter_put_standalone,
1171 mxwriter_get_standalone,
1172 mxwriter_put_omitXMLDeclaration,
1173 mxwriter_get_omitXMLDeclaration,
1174 mxwriter_put_version,
1175 mxwriter_get_version,
1176 mxwriter_put_disableOutputEscaping,
1177 mxwriter_get_disableOutputEscaping,
1178 mxwriter_flush
1181 /*** ISAXContentHandler ***/
1182 static HRESULT WINAPI SAXContentHandler_QueryInterface(
1183 ISAXContentHandler *iface,
1184 REFIID riid,
1185 void **obj)
1187 mxwriter *This = impl_from_ISAXContentHandler( iface );
1188 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1191 static ULONG WINAPI SAXContentHandler_AddRef(ISAXContentHandler *iface)
1193 mxwriter *This = impl_from_ISAXContentHandler( iface );
1194 return IMXWriter_AddRef(&This->IMXWriter_iface);
1197 static ULONG WINAPI SAXContentHandler_Release(ISAXContentHandler *iface)
1199 mxwriter *This = impl_from_ISAXContentHandler( iface );
1200 return IMXWriter_Release(&This->IMXWriter_iface);
1203 static HRESULT WINAPI SAXContentHandler_putDocumentLocator(
1204 ISAXContentHandler *iface,
1205 ISAXLocator *locator)
1207 mxwriter *This = impl_from_ISAXContentHandler( iface );
1208 FIXME("(%p)->(%p)\n", This, locator);
1209 return E_NOTIMPL;
1212 static HRESULT WINAPI SAXContentHandler_startDocument(ISAXContentHandler *iface)
1214 mxwriter *This = impl_from_ISAXContentHandler( iface );
1216 TRACE("(%p)\n", This);
1218 /* If properties have been changed since the last "endDocument" call
1219 * we need to reset the output buffer. If we don't the output buffer
1220 * could end up with multiple XML documents in it, plus this seems to
1221 * be how Windows works.
1223 if (This->prop_changed) {
1224 close_output_buffer(This);
1225 This->prop_changed = FALSE;
1228 if (This->props[MXWriter_OmitXmlDecl] == VARIANT_TRUE) return S_OK;
1230 write_prolog_buffer(This);
1232 if (This->dest && This->xml_enc == XmlEncoding_UTF16) {
1233 static const char utf16BOM[] = {0xff,0xfe};
1235 if (This->props[MXWriter_BOM] == VARIANT_TRUE)
1236 /* Windows passes a NULL pointer as the pcbWritten parameter and
1237 * ignores any error codes returned from this Write call.
1239 IStream_Write(This->dest, utf16BOM, sizeof(utf16BOM), NULL);
1242 return S_OK;
1245 static HRESULT WINAPI SAXContentHandler_endDocument(ISAXContentHandler *iface)
1247 mxwriter *This = impl_from_ISAXContentHandler( iface );
1248 TRACE("(%p)\n", This);
1249 This->prop_changed = FALSE;
1250 return flush_output_buffer(This);
1253 static HRESULT WINAPI SAXContentHandler_startPrefixMapping(
1254 ISAXContentHandler *iface,
1255 const WCHAR *prefix,
1256 int nprefix,
1257 const WCHAR *uri,
1258 int nuri)
1260 mxwriter *This = impl_from_ISAXContentHandler( iface );
1261 TRACE("(%p)->(%s %s)\n", This, debugstr_wn(prefix, nprefix), debugstr_wn(uri, nuri));
1262 return S_OK;
1265 static HRESULT WINAPI SAXContentHandler_endPrefixMapping(
1266 ISAXContentHandler *iface,
1267 const WCHAR *prefix,
1268 int nprefix)
1270 mxwriter *This = impl_from_ISAXContentHandler( iface );
1271 TRACE("(%p)->(%s)\n", This, debugstr_wn(prefix, nprefix));
1272 return S_OK;
1275 static void mxwriter_write_attribute(mxwriter *writer, const WCHAR *qname, int qname_len,
1276 const WCHAR *value, int value_len, BOOL escape)
1278 static const WCHAR eqW[] = {'='};
1280 /* space separator in front of every attribute */
1281 write_output_buffer(writer, spaceW, 1);
1282 write_output_buffer(writer, qname, qname_len);
1283 write_output_buffer(writer, eqW, 1);
1285 if (escape)
1287 WCHAR *escaped = get_escaped_string(value, EscapeValue, &value_len);
1288 write_output_buffer_quoted(writer, escaped, value_len);
1289 heap_free(escaped);
1291 else
1292 write_output_buffer_quoted(writer, value, value_len);
1295 static void mxwriter_write_starttag(mxwriter *writer, const WCHAR *qname, int len)
1297 static const WCHAR ltW[] = {'<'};
1299 close_element_starttag(writer);
1300 set_element_name(writer, qname ? qname : emptyW, qname ? len : 0);
1302 write_node_indent(writer);
1304 write_output_buffer(writer, ltW, 1);
1305 write_output_buffer(writer, qname ? qname : emptyW, qname ? len : 0);
1306 writer_inc_indent(writer);
1309 static HRESULT WINAPI SAXContentHandler_startElement(
1310 ISAXContentHandler *iface,
1311 const WCHAR *namespaceUri,
1312 int nnamespaceUri,
1313 const WCHAR *local_name,
1314 int nlocal_name,
1315 const WCHAR *QName,
1316 int nQName,
1317 ISAXAttributes *attr)
1319 mxwriter *This = impl_from_ISAXContentHandler( iface );
1321 TRACE("(%p)->(%s %s %s %p)\n", This, debugstr_wn(namespaceUri, nnamespaceUri),
1322 debugstr_wn(local_name, nlocal_name), debugstr_wn(QName, nQName), attr);
1324 if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1325 (nQName == -1 && This->class_version == MSXML6))
1326 return E_INVALIDARG;
1328 mxwriter_write_starttag(This, QName, nQName);
1330 if (attr)
1332 int length, i, escape;
1333 HRESULT hr;
1335 hr = ISAXAttributes_getLength(attr, &length);
1336 if (FAILED(hr)) return hr;
1338 escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
1339 (This->class_version == MSXML4 || This->class_version == MSXML6);
1341 for (i = 0; i < length; i++)
1343 int qname_len = 0, value_len = 0;
1344 const WCHAR *qname, *value;
1346 hr = ISAXAttributes_getQName(attr, i, &qname, &qname_len);
1347 if (FAILED(hr)) return hr;
1349 hr = ISAXAttributes_getValue(attr, i, &value, &value_len);
1350 if (FAILED(hr)) return hr;
1352 mxwriter_write_attribute(This, qname, qname_len, value, value_len, escape);
1356 return S_OK;
1359 static HRESULT WINAPI SAXContentHandler_endElement(
1360 ISAXContentHandler *iface,
1361 const WCHAR *namespaceUri,
1362 int nnamespaceUri,
1363 const WCHAR * local_name,
1364 int nlocal_name,
1365 const WCHAR *QName,
1366 int nQName)
1368 mxwriter *This = impl_from_ISAXContentHandler( iface );
1370 TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(namespaceUri, nnamespaceUri), nnamespaceUri,
1371 debugstr_wn(local_name, nlocal_name), nlocal_name, debugstr_wn(QName, nQName), nQName);
1373 if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1374 (nQName == -1 && This->class_version == MSXML6))
1375 return E_INVALIDARG;
1377 writer_dec_indent(This);
1379 if (This->element)
1381 static const WCHAR closeW[] = {'/','>'};
1382 write_output_buffer(This, closeW, 2);
1384 else
1386 static const WCHAR closetagW[] = {'<','/'};
1387 static const WCHAR gtW[] = {'>'};
1389 write_node_indent(This);
1390 write_output_buffer(This, closetagW, 2);
1391 write_output_buffer(This, QName, nQName);
1392 write_output_buffer(This, gtW, 1);
1395 set_element_name(This, NULL, 0);
1397 return S_OK;
1400 static HRESULT WINAPI SAXContentHandler_characters(
1401 ISAXContentHandler *iface,
1402 const WCHAR *chars,
1403 int nchars)
1405 mxwriter *This = impl_from_ISAXContentHandler( iface );
1407 TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1409 if (!chars) return E_INVALIDARG;
1411 close_element_starttag(This);
1412 set_element_name(This, NULL, 0);
1414 if (!This->cdata)
1415 This->text = TRUE;
1417 if (nchars)
1419 if (This->cdata || This->props[MXWriter_DisableEscaping] == VARIANT_TRUE)
1420 write_output_buffer(This, chars, nchars);
1421 else
1423 int len = nchars;
1424 WCHAR *escaped;
1426 escaped = get_escaped_string(chars, EscapeText, &len);
1427 write_output_buffer(This, escaped, len);
1428 heap_free(escaped);
1432 return S_OK;
1435 static HRESULT WINAPI SAXContentHandler_ignorableWhitespace(
1436 ISAXContentHandler *iface,
1437 const WCHAR *chars,
1438 int nchars)
1440 mxwriter *This = impl_from_ISAXContentHandler( iface );
1442 TRACE("(%p)->(%s)\n", This, debugstr_wn(chars, nchars));
1444 if (!chars) return E_INVALIDARG;
1446 write_output_buffer(This, chars, nchars);
1448 return S_OK;
1451 static HRESULT WINAPI SAXContentHandler_processingInstruction(
1452 ISAXContentHandler *iface,
1453 const WCHAR *target,
1454 int ntarget,
1455 const WCHAR *data,
1456 int ndata)
1458 mxwriter *This = impl_from_ISAXContentHandler( iface );
1459 static const WCHAR openpiW[] = {'<','?'};
1460 static const WCHAR closepiW[] = {'?','>','\r','\n'};
1462 TRACE("(%p)->(%s %s)\n", This, debugstr_wn(target, ntarget), debugstr_wn(data, ndata));
1464 if (!target) return E_INVALIDARG;
1466 write_node_indent(This);
1467 write_output_buffer(This, openpiW, ARRAY_SIZE(openpiW));
1469 if (*target)
1470 write_output_buffer(This, target, ntarget);
1472 if (data && *data && ndata)
1474 write_output_buffer(This, spaceW, 1);
1475 write_output_buffer(This, data, ndata);
1478 write_output_buffer(This, closepiW, ARRAY_SIZE(closepiW));
1479 This->newline = TRUE;
1481 return S_OK;
1484 static HRESULT WINAPI SAXContentHandler_skippedEntity(
1485 ISAXContentHandler *iface,
1486 const WCHAR *name,
1487 int nname)
1489 mxwriter *This = impl_from_ISAXContentHandler( iface );
1490 FIXME("(%p)->(%s)\n", This, debugstr_wn(name, nname));
1491 return E_NOTIMPL;
1494 static const struct ISAXContentHandlerVtbl SAXContentHandlerVtbl =
1496 SAXContentHandler_QueryInterface,
1497 SAXContentHandler_AddRef,
1498 SAXContentHandler_Release,
1499 SAXContentHandler_putDocumentLocator,
1500 SAXContentHandler_startDocument,
1501 SAXContentHandler_endDocument,
1502 SAXContentHandler_startPrefixMapping,
1503 SAXContentHandler_endPrefixMapping,
1504 SAXContentHandler_startElement,
1505 SAXContentHandler_endElement,
1506 SAXContentHandler_characters,
1507 SAXContentHandler_ignorableWhitespace,
1508 SAXContentHandler_processingInstruction,
1509 SAXContentHandler_skippedEntity
1512 /*** ISAXLexicalHandler ***/
1513 static HRESULT WINAPI SAXLexicalHandler_QueryInterface(ISAXLexicalHandler *iface,
1514 REFIID riid, void **obj)
1516 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1517 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1520 static ULONG WINAPI SAXLexicalHandler_AddRef(ISAXLexicalHandler *iface)
1522 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1523 return IMXWriter_AddRef(&This->IMXWriter_iface);
1526 static ULONG WINAPI SAXLexicalHandler_Release(ISAXLexicalHandler *iface)
1528 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1529 return IMXWriter_Release(&This->IMXWriter_iface);
1532 static HRESULT WINAPI SAXLexicalHandler_startDTD(ISAXLexicalHandler *iface,
1533 const WCHAR *name, int name_len, const WCHAR *publicId, int publicId_len,
1534 const WCHAR *systemId, int systemId_len)
1536 static const WCHAR doctypeW[] = {'<','!','D','O','C','T','Y','P','E',' '};
1537 static const WCHAR openintW[] = {'[','\r','\n'};
1539 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1541 TRACE("(%p)->(%s %s %s)\n", This, debugstr_wn(name, name_len), debugstr_wn(publicId, publicId_len),
1542 debugstr_wn(systemId, systemId_len));
1544 if (!name) return E_INVALIDARG;
1546 write_output_buffer(This, doctypeW, ARRAY_SIZE(doctypeW));
1548 if (*name)
1550 write_output_buffer(This, name, name_len);
1551 write_output_buffer(This, spaceW, 1);
1554 if (publicId)
1556 write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
1557 write_output_buffer_quoted(This, publicId, publicId_len);
1559 if (!systemId) return E_INVALIDARG;
1561 if (*publicId)
1562 write_output_buffer(This, spaceW, 1);
1564 write_output_buffer_quoted(This, systemId, systemId_len);
1566 if (*systemId)
1567 write_output_buffer(This, spaceW, 1);
1569 else if (systemId)
1571 write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
1572 write_output_buffer_quoted(This, systemId, systemId_len);
1573 if (*systemId)
1574 write_output_buffer(This, spaceW, 1);
1577 write_output_buffer(This, openintW, ARRAY_SIZE(openintW));
1579 return S_OK;
1582 static HRESULT WINAPI SAXLexicalHandler_endDTD(ISAXLexicalHandler *iface)
1584 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1585 static const WCHAR closedtdW[] = {']','>','\r','\n'};
1587 TRACE("(%p)\n", This);
1589 write_output_buffer(This, closedtdW, ARRAY_SIZE(closedtdW));
1591 return S_OK;
1594 static HRESULT WINAPI SAXLexicalHandler_startEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1596 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1597 FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1598 return E_NOTIMPL;
1601 static HRESULT WINAPI SAXLexicalHandler_endEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1603 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1604 FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1605 return E_NOTIMPL;
1608 static HRESULT WINAPI SAXLexicalHandler_startCDATA(ISAXLexicalHandler *iface)
1610 static const WCHAR scdataW[] = {'<','!','[','C','D','A','T','A','['};
1611 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1613 TRACE("(%p)\n", This);
1615 write_node_indent(This);
1616 write_output_buffer(This, scdataW, ARRAY_SIZE(scdataW));
1617 This->cdata = TRUE;
1619 return S_OK;
1622 static HRESULT WINAPI SAXLexicalHandler_endCDATA(ISAXLexicalHandler *iface)
1624 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1625 static const WCHAR ecdataW[] = {']',']','>'};
1627 TRACE("(%p)\n", This);
1629 write_output_buffer(This, ecdataW, ARRAY_SIZE(ecdataW));
1630 This->cdata = FALSE;
1632 return S_OK;
1635 static HRESULT WINAPI SAXLexicalHandler_comment(ISAXLexicalHandler *iface, const WCHAR *chars, int nchars)
1637 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1638 static const WCHAR copenW[] = {'<','!','-','-'};
1639 static const WCHAR ccloseW[] = {'-','-','>','\r','\n'};
1641 TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1643 if (!chars) return E_INVALIDARG;
1645 close_element_starttag(This);
1646 write_node_indent(This);
1648 write_output_buffer(This, copenW, ARRAY_SIZE(copenW));
1649 if (nchars)
1650 write_output_buffer(This, chars, nchars);
1651 write_output_buffer(This, ccloseW, ARRAY_SIZE(ccloseW));
1653 return S_OK;
1656 static const struct ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl =
1658 SAXLexicalHandler_QueryInterface,
1659 SAXLexicalHandler_AddRef,
1660 SAXLexicalHandler_Release,
1661 SAXLexicalHandler_startDTD,
1662 SAXLexicalHandler_endDTD,
1663 SAXLexicalHandler_startEntity,
1664 SAXLexicalHandler_endEntity,
1665 SAXLexicalHandler_startCDATA,
1666 SAXLexicalHandler_endCDATA,
1667 SAXLexicalHandler_comment
1670 /*** ISAXDeclHandler ***/
1671 static HRESULT WINAPI SAXDeclHandler_QueryInterface(ISAXDeclHandler *iface,
1672 REFIID riid, void **obj)
1674 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1675 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1678 static ULONG WINAPI SAXDeclHandler_AddRef(ISAXDeclHandler *iface)
1680 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1681 return IMXWriter_AddRef(&This->IMXWriter_iface);
1684 static ULONG WINAPI SAXDeclHandler_Release(ISAXDeclHandler *iface)
1686 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1687 return IMXWriter_Release(&This->IMXWriter_iface);
1690 static HRESULT WINAPI SAXDeclHandler_elementDecl(ISAXDeclHandler *iface,
1691 const WCHAR *name, int n_name, const WCHAR *model, int n_model)
1693 static const WCHAR elementW[] = {'<','!','E','L','E','M','E','N','T',' '};
1694 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1696 TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1697 debugstr_wn(model, n_model), n_model);
1699 if (!name || !model) return E_INVALIDARG;
1701 write_output_buffer(This, elementW, ARRAY_SIZE(elementW));
1702 if (n_name) {
1703 write_output_buffer(This, name, n_name);
1704 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1706 if (n_model)
1707 write_output_buffer(This, model, n_model);
1708 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1710 return S_OK;
1713 static HRESULT WINAPI SAXDeclHandler_attributeDecl(ISAXDeclHandler *iface,
1714 const WCHAR *element, int n_element, const WCHAR *attr, int n_attr,
1715 const WCHAR *type, int n_type, const WCHAR *Default, int n_default,
1716 const WCHAR *value, int n_value)
1718 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1719 static const WCHAR attlistW[] = {'<','!','A','T','T','L','I','S','T',' '};
1720 static const WCHAR closetagW[] = {'>','\r','\n'};
1722 TRACE("(%p)->(%s:%d %s:%d %s:%d %s:%d %s:%d)\n", This, debugstr_wn(element, n_element), n_element,
1723 debugstr_wn(attr, n_attr), n_attr, debugstr_wn(type, n_type), n_type, debugstr_wn(Default, n_default), n_default,
1724 debugstr_wn(value, n_value), n_value);
1726 write_output_buffer(This, attlistW, ARRAY_SIZE(attlistW));
1727 if (n_element) {
1728 write_output_buffer(This, element, n_element);
1729 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1732 if (n_attr) {
1733 write_output_buffer(This, attr, n_attr);
1734 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1737 if (n_type) {
1738 write_output_buffer(This, type, n_type);
1739 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1742 if (n_default) {
1743 write_output_buffer(This, Default, n_default);
1744 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1747 if (n_value)
1748 write_output_buffer_quoted(This, value, n_value);
1750 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1752 return S_OK;
1755 static HRESULT WINAPI SAXDeclHandler_internalEntityDecl(ISAXDeclHandler *iface,
1756 const WCHAR *name, int n_name, const WCHAR *value, int n_value)
1758 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1760 TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1761 debugstr_wn(value, n_value), n_value);
1763 if (!name || !value) return E_INVALIDARG;
1765 write_output_buffer(This, entityW, ARRAY_SIZE(entityW));
1766 if (n_name) {
1767 write_output_buffer(This, name, n_name);
1768 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1771 if (n_value)
1772 write_output_buffer_quoted(This, value, n_value);
1774 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1776 return S_OK;
1779 static HRESULT WINAPI SAXDeclHandler_externalEntityDecl(ISAXDeclHandler *iface,
1780 const WCHAR *name, int n_name, const WCHAR *publicId, int n_publicId,
1781 const WCHAR *systemId, int n_systemId)
1783 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1785 TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1786 debugstr_wn(publicId, n_publicId), n_publicId, debugstr_wn(systemId, n_systemId), n_systemId);
1788 if (!name || !systemId) return E_INVALIDARG;
1790 write_output_buffer(This, entityW, ARRAY_SIZE(entityW));
1791 if (n_name) {
1792 write_output_buffer(This, name, n_name);
1793 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1796 if (publicId)
1798 write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
1799 write_output_buffer_quoted(This, publicId, n_publicId);
1800 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1801 write_output_buffer_quoted(This, systemId, n_systemId);
1803 else
1805 write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
1806 write_output_buffer_quoted(This, systemId, n_systemId);
1809 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1811 return S_OK;
1814 static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl = {
1815 SAXDeclHandler_QueryInterface,
1816 SAXDeclHandler_AddRef,
1817 SAXDeclHandler_Release,
1818 SAXDeclHandler_elementDecl,
1819 SAXDeclHandler_attributeDecl,
1820 SAXDeclHandler_internalEntityDecl,
1821 SAXDeclHandler_externalEntityDecl
1824 /*** IVBSAXDeclHandler ***/
1825 static HRESULT WINAPI VBSAXDeclHandler_QueryInterface(IVBSAXDeclHandler *iface,
1826 REFIID riid, void **obj)
1828 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1829 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1832 static ULONG WINAPI VBSAXDeclHandler_AddRef(IVBSAXDeclHandler *iface)
1834 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1835 return IMXWriter_AddRef(&This->IMXWriter_iface);
1838 static ULONG WINAPI VBSAXDeclHandler_Release(IVBSAXDeclHandler *iface)
1840 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1841 return IMXWriter_Release(&This->IMXWriter_iface);
1844 static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfoCount(IVBSAXDeclHandler *iface, UINT* pctinfo)
1846 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1847 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1850 static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfo(IVBSAXDeclHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1852 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1853 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1856 static HRESULT WINAPI VBSAXDeclHandler_GetIDsOfNames(IVBSAXDeclHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1857 UINT cNames, LCID lcid, DISPID* rgDispId )
1859 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1860 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1863 static HRESULT WINAPI VBSAXDeclHandler_Invoke(IVBSAXDeclHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1864 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1866 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1867 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1868 pExcepInfo, puArgErr);
1871 static HRESULT WINAPI VBSAXDeclHandler_elementDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *model)
1873 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1875 TRACE("(%p)->(%p %p)\n", This, name, model);
1877 if (!name || !model)
1878 return E_POINTER;
1880 return ISAXDeclHandler_elementDecl(&This->ISAXDeclHandler_iface, *name, -1, *model, -1);
1883 static HRESULT WINAPI VBSAXDeclHandler_attributeDecl(IVBSAXDeclHandler *iface,
1884 BSTR *element, BSTR *attr, BSTR *type, BSTR *default_value, BSTR *value)
1886 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1888 TRACE("(%p)->(%p %p %p %p %p)\n", This, element, attr, type, default_value, value);
1890 if (!element || !attr || !type || !default_value || !value)
1891 return E_POINTER;
1893 return ISAXDeclHandler_attributeDecl(&This->ISAXDeclHandler_iface, *element, -1, *attr, -1, *type, -1,
1894 *default_value, -1, *value, -1);
1897 static HRESULT WINAPI VBSAXDeclHandler_internalEntityDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *value)
1899 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1901 TRACE("(%p)->(%p %p)\n", This, name, value);
1903 if (!name || !value)
1904 return E_POINTER;
1906 return ISAXDeclHandler_internalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *value, -1);
1909 static HRESULT WINAPI VBSAXDeclHandler_externalEntityDecl(IVBSAXDeclHandler *iface,
1910 BSTR *name, BSTR *publicid, BSTR *systemid)
1912 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1914 TRACE("(%p)->(%p %p %p)\n", This, name, publicid, systemid);
1916 if (!name || !publicid || !systemid)
1917 return E_POINTER;
1919 return ISAXDeclHandler_externalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *publicid, -1, *systemid, -1);
1922 static const IVBSAXDeclHandlerVtbl VBSAXDeclHandlerVtbl = {
1923 VBSAXDeclHandler_QueryInterface,
1924 VBSAXDeclHandler_AddRef,
1925 VBSAXDeclHandler_Release,
1926 VBSAXDeclHandler_GetTypeInfoCount,
1927 VBSAXDeclHandler_GetTypeInfo,
1928 VBSAXDeclHandler_GetIDsOfNames,
1929 VBSAXDeclHandler_Invoke,
1930 VBSAXDeclHandler_elementDecl,
1931 VBSAXDeclHandler_attributeDecl,
1932 VBSAXDeclHandler_internalEntityDecl,
1933 VBSAXDeclHandler_externalEntityDecl
1936 /*** IVBSAXLexicalHandler ***/
1937 static HRESULT WINAPI VBSAXLexicalHandler_QueryInterface(IVBSAXLexicalHandler *iface,
1938 REFIID riid, void **obj)
1940 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1941 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1944 static ULONG WINAPI VBSAXLexicalHandler_AddRef(IVBSAXLexicalHandler *iface)
1946 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1947 return IMXWriter_AddRef(&This->IMXWriter_iface);
1950 static ULONG WINAPI VBSAXLexicalHandler_Release(IVBSAXLexicalHandler *iface)
1952 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1953 return IMXWriter_Release(&This->IMXWriter_iface);
1956 static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfoCount(IVBSAXLexicalHandler *iface, UINT* pctinfo)
1958 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1959 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1962 static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfo(IVBSAXLexicalHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1964 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1965 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1968 static HRESULT WINAPI VBSAXLexicalHandler_GetIDsOfNames(IVBSAXLexicalHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1969 UINT cNames, LCID lcid, DISPID* rgDispId )
1971 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1972 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1975 static HRESULT WINAPI VBSAXLexicalHandler_Invoke(IVBSAXLexicalHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1976 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1978 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1979 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1980 pExcepInfo, puArgErr);
1983 static HRESULT WINAPI VBSAXLexicalHandler_startDTD(IVBSAXLexicalHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
1985 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1987 TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
1989 if (!name || !publicId || !systemId)
1990 return E_POINTER;
1992 return ISAXLexicalHandler_startDTD(&This->ISAXLexicalHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
1995 static HRESULT WINAPI VBSAXLexicalHandler_endDTD(IVBSAXLexicalHandler *iface)
1997 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1998 return ISAXLexicalHandler_endDTD(&This->ISAXLexicalHandler_iface);
2001 static HRESULT WINAPI VBSAXLexicalHandler_startEntity(IVBSAXLexicalHandler *iface, BSTR *name)
2003 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2005 TRACE("(%p)->(%p)\n", This, name);
2007 if (!name)
2008 return E_POINTER;
2010 return ISAXLexicalHandler_startEntity(&This->ISAXLexicalHandler_iface, *name, -1);
2013 static HRESULT WINAPI VBSAXLexicalHandler_endEntity(IVBSAXLexicalHandler *iface, BSTR *name)
2015 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2017 TRACE("(%p)->(%p)\n", This, name);
2019 if (!name)
2020 return E_POINTER;
2022 return ISAXLexicalHandler_endEntity(&This->ISAXLexicalHandler_iface, *name, -1);
2025 static HRESULT WINAPI VBSAXLexicalHandler_startCDATA(IVBSAXLexicalHandler *iface)
2027 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2028 return ISAXLexicalHandler_startCDATA(&This->ISAXLexicalHandler_iface);
2031 static HRESULT WINAPI VBSAXLexicalHandler_endCDATA(IVBSAXLexicalHandler *iface)
2033 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2034 return ISAXLexicalHandler_endCDATA(&This->ISAXLexicalHandler_iface);
2037 static HRESULT WINAPI VBSAXLexicalHandler_comment(IVBSAXLexicalHandler *iface, BSTR *chars)
2039 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2041 TRACE("(%p)->(%p)\n", This, chars);
2043 if (!chars)
2044 return E_POINTER;
2046 return ISAXLexicalHandler_comment(&This->ISAXLexicalHandler_iface, *chars, -1);
2049 static const IVBSAXLexicalHandlerVtbl VBSAXLexicalHandlerVtbl = {
2050 VBSAXLexicalHandler_QueryInterface,
2051 VBSAXLexicalHandler_AddRef,
2052 VBSAXLexicalHandler_Release,
2053 VBSAXLexicalHandler_GetTypeInfoCount,
2054 VBSAXLexicalHandler_GetTypeInfo,
2055 VBSAXLexicalHandler_GetIDsOfNames,
2056 VBSAXLexicalHandler_Invoke,
2057 VBSAXLexicalHandler_startDTD,
2058 VBSAXLexicalHandler_endDTD,
2059 VBSAXLexicalHandler_startEntity,
2060 VBSAXLexicalHandler_endEntity,
2061 VBSAXLexicalHandler_startCDATA,
2062 VBSAXLexicalHandler_endCDATA,
2063 VBSAXLexicalHandler_comment
2066 /*** IVBSAXContentHandler ***/
2067 static HRESULT WINAPI VBSAXContentHandler_QueryInterface(IVBSAXContentHandler *iface, REFIID riid, void **obj)
2069 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2070 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2073 static ULONG WINAPI VBSAXContentHandler_AddRef(IVBSAXContentHandler *iface)
2075 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2076 return IMXWriter_AddRef(&This->IMXWriter_iface);
2079 static ULONG WINAPI VBSAXContentHandler_Release(IVBSAXContentHandler *iface)
2081 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2082 return IMXWriter_Release(&This->IMXWriter_iface);
2085 static HRESULT WINAPI VBSAXContentHandler_GetTypeInfoCount(IVBSAXContentHandler *iface, UINT* pctinfo)
2087 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2088 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2091 static HRESULT WINAPI VBSAXContentHandler_GetTypeInfo(IVBSAXContentHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2093 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2094 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2097 static HRESULT WINAPI VBSAXContentHandler_GetIDsOfNames(IVBSAXContentHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2098 UINT cNames, LCID lcid, DISPID* rgDispId )
2100 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2101 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2104 static HRESULT WINAPI VBSAXContentHandler_Invoke(IVBSAXContentHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2105 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2107 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2108 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2109 pExcepInfo, puArgErr);
2112 static HRESULT WINAPI VBSAXContentHandler_putref_documentLocator(IVBSAXContentHandler *iface, IVBSAXLocator *locator)
2114 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2115 TRACE("(%p)->(%p)\n", This, locator);
2116 return S_OK;
2119 static HRESULT WINAPI VBSAXContentHandler_startDocument(IVBSAXContentHandler *iface)
2121 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2122 return ISAXContentHandler_startDocument(&This->ISAXContentHandler_iface);
2125 static HRESULT WINAPI VBSAXContentHandler_endDocument(IVBSAXContentHandler *iface)
2127 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2128 return ISAXContentHandler_endDocument(&This->ISAXContentHandler_iface);
2131 static HRESULT WINAPI VBSAXContentHandler_startPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix, BSTR *uri)
2133 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2135 TRACE("(%p)->(%p %p)\n", This, prefix, uri);
2137 if (!prefix || !uri)
2138 return E_POINTER;
2140 return ISAXContentHandler_startPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1, *uri, -1);
2143 static HRESULT WINAPI VBSAXContentHandler_endPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix)
2145 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2147 TRACE("(%p)->(%p)\n", This, prefix);
2149 if (!prefix)
2150 return E_POINTER;
2152 return ISAXContentHandler_endPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1);
2155 static HRESULT WINAPI VBSAXContentHandler_startElement(IVBSAXContentHandler *iface,
2156 BSTR *namespaceURI, BSTR *localName, BSTR *QName, IVBSAXAttributes *attrs)
2158 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2160 TRACE("(%p)->(%p %p %p %p)\n", This, namespaceURI, localName, QName, attrs);
2162 if (!namespaceURI || !localName || !QName)
2163 return E_POINTER;
2165 TRACE("(%s %s %s)\n", debugstr_w(*namespaceURI), debugstr_w(*localName), debugstr_w(*QName));
2167 mxwriter_write_starttag(This, *QName, SysStringLen(*QName));
2169 if (attrs)
2171 int length, i, escape;
2172 HRESULT hr;
2174 hr = IVBSAXAttributes_get_length(attrs, &length);
2175 if (FAILED(hr)) return hr;
2177 escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
2178 (This->class_version == MSXML4 || This->class_version == MSXML6);
2180 for (i = 0; i < length; i++)
2182 BSTR qname, value;
2184 hr = IVBSAXAttributes_getQName(attrs, i, &qname);
2185 if (FAILED(hr)) return hr;
2187 hr = IVBSAXAttributes_getValue(attrs, i, &value);
2188 if (FAILED(hr))
2190 SysFreeString(qname);
2191 return hr;
2194 mxwriter_write_attribute(This, qname, SysStringLen(qname), value, SysStringLen(value), escape);
2195 SysFreeString(qname);
2196 SysFreeString(value);
2200 return S_OK;
2203 static HRESULT WINAPI VBSAXContentHandler_endElement(IVBSAXContentHandler *iface, BSTR *namespaceURI,
2204 BSTR *localName, BSTR *QName)
2206 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2208 TRACE("(%p)->(%p %p %p)\n", This, namespaceURI, localName, QName);
2210 if (!namespaceURI || !localName || !QName)
2211 return E_POINTER;
2213 return ISAXContentHandler_endElement(&This->ISAXContentHandler_iface,
2214 *namespaceURI, SysStringLen(*namespaceURI),
2215 *localName, SysStringLen(*localName),
2216 *QName, SysStringLen(*QName));
2219 static HRESULT WINAPI VBSAXContentHandler_characters(IVBSAXContentHandler *iface, BSTR *chars)
2221 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2223 TRACE("(%p)->(%p)\n", This, chars);
2225 if (!chars)
2226 return E_POINTER;
2228 return ISAXContentHandler_characters(&This->ISAXContentHandler_iface, *chars, SysStringLen(*chars));
2231 static HRESULT WINAPI VBSAXContentHandler_ignorableWhitespace(IVBSAXContentHandler *iface, BSTR *chars)
2233 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2235 TRACE("(%p)->(%p)\n", This, chars);
2237 if (!chars)
2238 return E_POINTER;
2240 return ISAXContentHandler_ignorableWhitespace(&This->ISAXContentHandler_iface, *chars, -1);
2243 static HRESULT WINAPI VBSAXContentHandler_processingInstruction(IVBSAXContentHandler *iface,
2244 BSTR *target, BSTR *data)
2246 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2248 TRACE("(%p)->(%p %p)\n", This, target, data);
2250 if (!target || !data)
2251 return E_POINTER;
2253 return ISAXContentHandler_processingInstruction(&This->ISAXContentHandler_iface, *target, -1, *data, -1);
2256 static HRESULT WINAPI VBSAXContentHandler_skippedEntity(IVBSAXContentHandler *iface, BSTR *name)
2258 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2260 TRACE("(%p)->(%p)\n", This, name);
2262 if (!name)
2263 return E_POINTER;
2265 return ISAXContentHandler_skippedEntity(&This->ISAXContentHandler_iface, *name, -1);
2268 static const IVBSAXContentHandlerVtbl VBSAXContentHandlerVtbl = {
2269 VBSAXContentHandler_QueryInterface,
2270 VBSAXContentHandler_AddRef,
2271 VBSAXContentHandler_Release,
2272 VBSAXContentHandler_GetTypeInfoCount,
2273 VBSAXContentHandler_GetTypeInfo,
2274 VBSAXContentHandler_GetIDsOfNames,
2275 VBSAXContentHandler_Invoke,
2276 VBSAXContentHandler_putref_documentLocator,
2277 VBSAXContentHandler_startDocument,
2278 VBSAXContentHandler_endDocument,
2279 VBSAXContentHandler_startPrefixMapping,
2280 VBSAXContentHandler_endPrefixMapping,
2281 VBSAXContentHandler_startElement,
2282 VBSAXContentHandler_endElement,
2283 VBSAXContentHandler_characters,
2284 VBSAXContentHandler_ignorableWhitespace,
2285 VBSAXContentHandler_processingInstruction,
2286 VBSAXContentHandler_skippedEntity
2289 static HRESULT WINAPI SAXDTDHandler_QueryInterface(ISAXDTDHandler *iface, REFIID riid, void **obj)
2291 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2292 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2295 static ULONG WINAPI SAXDTDHandler_AddRef(ISAXDTDHandler *iface)
2297 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2298 return IMXWriter_AddRef(&This->IMXWriter_iface);
2301 static ULONG WINAPI SAXDTDHandler_Release(ISAXDTDHandler *iface)
2303 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2304 return IMXWriter_Release(&This->IMXWriter_iface);
2307 static HRESULT WINAPI SAXDTDHandler_notationDecl(ISAXDTDHandler *iface,
2308 const WCHAR *name, INT n_name,
2309 const WCHAR *publicid, INT n_publicid,
2310 const WCHAR *systemid, INT n_systemid)
2312 static const WCHAR notationW[] = {'<','!','N','O','T','A','T','I','O','N',' '};
2313 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2315 TRACE("(%p)->(%s:%d, %s:%d, %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
2316 debugstr_wn(publicid, n_publicid), n_publicid, debugstr_wn(systemid, n_systemid), n_systemid);
2318 if (!name || !n_name)
2319 return E_INVALIDARG;
2321 write_output_buffer(This, notationW, ARRAY_SIZE(notationW));
2322 write_output_buffer(This, name, n_name);
2324 if (!publicid && !systemid)
2325 return E_INVALIDARG;
2327 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
2328 if (publicid)
2330 write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
2331 write_output_buffer_quoted(This, publicid, n_publicid);
2332 if (systemid)
2334 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
2335 write_output_buffer_quoted(This, systemid, n_systemid);
2338 else
2340 write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
2341 write_output_buffer_quoted(This, systemid, n_systemid);
2344 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
2346 return S_OK;
2349 static HRESULT WINAPI SAXDTDHandler_unparsedEntityDecl(ISAXDTDHandler *iface,
2350 const WCHAR *name, INT nname,
2351 const WCHAR *publicid, INT npublicid,
2352 const WCHAR *systemid, INT nsystemid,
2353 const WCHAR *notation, INT nnotation)
2355 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2356 FIXME("(%p)->(%s:%d, %s:%d, %s:%d, %s:%d): stub\n", This, debugstr_wn(name, nname), nname,
2357 debugstr_wn(publicid, npublicid), npublicid, debugstr_wn(systemid, nsystemid), nsystemid,
2358 debugstr_wn(notation, nnotation), nnotation);
2359 return E_NOTIMPL;
2362 static const ISAXDTDHandlerVtbl SAXDTDHandlerVtbl = {
2363 SAXDTDHandler_QueryInterface,
2364 SAXDTDHandler_AddRef,
2365 SAXDTDHandler_Release,
2366 SAXDTDHandler_notationDecl,
2367 SAXDTDHandler_unparsedEntityDecl
2370 /*** IVBSAXDTDHandler ***/
2371 static HRESULT WINAPI VBSAXDTDHandler_QueryInterface(IVBSAXDTDHandler *iface, REFIID riid, void **obj)
2373 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2374 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2377 static ULONG WINAPI VBSAXDTDHandler_AddRef(IVBSAXDTDHandler *iface)
2379 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2380 return IMXWriter_AddRef(&This->IMXWriter_iface);
2383 static ULONG WINAPI VBSAXDTDHandler_Release(IVBSAXDTDHandler *iface)
2385 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2386 return IMXWriter_Release(&This->IMXWriter_iface);
2389 static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfoCount(IVBSAXDTDHandler *iface, UINT* pctinfo)
2391 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2392 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2395 static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfo(IVBSAXDTDHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2397 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2398 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2401 static HRESULT WINAPI VBSAXDTDHandler_GetIDsOfNames(IVBSAXDTDHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2402 UINT cNames, LCID lcid, DISPID* rgDispId )
2404 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2405 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2408 static HRESULT WINAPI VBSAXDTDHandler_Invoke(IVBSAXDTDHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2409 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2411 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2412 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2413 pExcepInfo, puArgErr);
2416 static HRESULT WINAPI VBSAXDTDHandler_notationDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
2418 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2420 TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
2422 if (!name || !publicId || !systemId)
2423 return E_POINTER;
2425 return ISAXDTDHandler_notationDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
2428 static HRESULT WINAPI VBSAXDTDHandler_unparsedEntityDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId,
2429 BSTR *systemId, BSTR *notation)
2431 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2433 TRACE("(%p)->(%p %p %p %p)\n", This, name, publicId, systemId, notation);
2435 if (!name || !publicId || !systemId || !notation)
2436 return E_POINTER;
2438 return ISAXDTDHandler_unparsedEntityDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1,
2439 *systemId, -1, *notation, -1);
2442 static const IVBSAXDTDHandlerVtbl VBSAXDTDHandlerVtbl = {
2443 VBSAXDTDHandler_QueryInterface,
2444 VBSAXDTDHandler_AddRef,
2445 VBSAXDTDHandler_Release,
2446 VBSAXDTDHandler_GetTypeInfoCount,
2447 VBSAXDTDHandler_GetTypeInfo,
2448 VBSAXDTDHandler_GetIDsOfNames,
2449 VBSAXDTDHandler_Invoke,
2450 VBSAXDTDHandler_notationDecl,
2451 VBSAXDTDHandler_unparsedEntityDecl
2454 /* ISAXErrorHandler */
2455 static HRESULT WINAPI SAXErrorHandler_QueryInterface(ISAXErrorHandler *iface, REFIID riid, void **obj)
2457 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2458 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2461 static ULONG WINAPI SAXErrorHandler_AddRef(ISAXErrorHandler *iface)
2463 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2464 return IMXWriter_AddRef(&This->IMXWriter_iface);
2467 static ULONG WINAPI SAXErrorHandler_Release(ISAXErrorHandler *iface)
2469 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2470 return IMXWriter_Release(&This->IMXWriter_iface);
2473 static HRESULT WINAPI SAXErrorHandler_error(ISAXErrorHandler *iface,
2474 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2476 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2478 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2480 return E_NOTIMPL;
2483 static HRESULT WINAPI SAXErrorHandler_fatalError(ISAXErrorHandler *iface,
2484 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2486 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2488 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2490 return E_NOTIMPL;
2493 static HRESULT WINAPI SAXErrorHandler_ignorableWarning(ISAXErrorHandler *iface,
2494 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2496 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2498 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2500 return E_NOTIMPL;
2503 static const ISAXErrorHandlerVtbl SAXErrorHandlerVtbl = {
2504 SAXErrorHandler_QueryInterface,
2505 SAXErrorHandler_AddRef,
2506 SAXErrorHandler_Release,
2507 SAXErrorHandler_error,
2508 SAXErrorHandler_fatalError,
2509 SAXErrorHandler_ignorableWarning
2512 /*** IVBSAXErrorHandler ***/
2513 static HRESULT WINAPI VBSAXErrorHandler_QueryInterface(IVBSAXErrorHandler *iface, REFIID riid, void **obj)
2515 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2516 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2519 static ULONG WINAPI VBSAXErrorHandler_AddRef(IVBSAXErrorHandler *iface)
2521 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2522 return IMXWriter_AddRef(&This->IMXWriter_iface);
2525 static ULONG WINAPI VBSAXErrorHandler_Release(IVBSAXErrorHandler *iface)
2527 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2528 return IMXWriter_Release(&This->IMXWriter_iface);
2531 static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfoCount(IVBSAXErrorHandler *iface, UINT* pctinfo)
2533 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2534 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2537 static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfo(IVBSAXErrorHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2539 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2540 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2543 static HRESULT WINAPI VBSAXErrorHandler_GetIDsOfNames(IVBSAXErrorHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2544 UINT cNames, LCID lcid, DISPID* rgDispId )
2546 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2547 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2550 static HRESULT WINAPI VBSAXErrorHandler_Invoke(IVBSAXErrorHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2551 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2553 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2554 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2555 pExcepInfo, puArgErr);
2558 static HRESULT WINAPI VBSAXErrorHandler_error(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2560 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2561 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2562 return E_NOTIMPL;
2565 static HRESULT WINAPI VBSAXErrorHandler_fatalError(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2567 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2568 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2569 return E_NOTIMPL;
2572 static HRESULT WINAPI VBSAXErrorHandler_ignorableWarning(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2574 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2575 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2576 return E_NOTIMPL;
2579 static const IVBSAXErrorHandlerVtbl VBSAXErrorHandlerVtbl = {
2580 VBSAXErrorHandler_QueryInterface,
2581 VBSAXErrorHandler_AddRef,
2582 VBSAXErrorHandler_Release,
2583 VBSAXErrorHandler_GetTypeInfoCount,
2584 VBSAXErrorHandler_GetTypeInfo,
2585 VBSAXErrorHandler_GetIDsOfNames,
2586 VBSAXErrorHandler_Invoke,
2587 VBSAXErrorHandler_error,
2588 VBSAXErrorHandler_fatalError,
2589 VBSAXErrorHandler_ignorableWarning
2592 static const tid_t mxwriter_iface_tids[] = {
2593 IMXWriter_tid,
2597 static dispex_static_data_t mxwriter_dispex = {
2598 NULL,
2599 IMXWriter_tid,
2600 NULL,
2601 mxwriter_iface_tids
2604 HRESULT MXWriter_create(MSXML_VERSION version, void **ppObj)
2606 static const WCHAR version10W[] = {'1','.','0',0};
2607 mxwriter *This;
2608 HRESULT hr;
2610 TRACE("(%p)\n", ppObj);
2612 This = heap_alloc( sizeof (*This) );
2613 if(!This)
2614 return E_OUTOFMEMORY;
2616 This->IMXWriter_iface.lpVtbl = &MXWriterVtbl;
2617 This->ISAXContentHandler_iface.lpVtbl = &SAXContentHandlerVtbl;
2618 This->ISAXLexicalHandler_iface.lpVtbl = &SAXLexicalHandlerVtbl;
2619 This->ISAXDeclHandler_iface.lpVtbl = &SAXDeclHandlerVtbl;
2620 This->ISAXDTDHandler_iface.lpVtbl = &SAXDTDHandlerVtbl;
2621 This->ISAXErrorHandler_iface.lpVtbl = &SAXErrorHandlerVtbl;
2622 This->IVBSAXDeclHandler_iface.lpVtbl = &VBSAXDeclHandlerVtbl;
2623 This->IVBSAXLexicalHandler_iface.lpVtbl = &VBSAXLexicalHandlerVtbl;
2624 This->IVBSAXContentHandler_iface.lpVtbl = &VBSAXContentHandlerVtbl;
2625 This->IVBSAXDTDHandler_iface.lpVtbl = &VBSAXDTDHandlerVtbl;
2626 This->IVBSAXErrorHandler_iface.lpVtbl = &VBSAXErrorHandlerVtbl;
2627 This->ref = 1;
2628 This->class_version = version;
2630 This->props[MXWriter_BOM] = VARIANT_TRUE;
2631 This->props[MXWriter_DisableEscaping] = VARIANT_FALSE;
2632 This->props[MXWriter_Indent] = VARIANT_FALSE;
2633 This->props[MXWriter_OmitXmlDecl] = VARIANT_FALSE;
2634 This->props[MXWriter_Standalone] = VARIANT_FALSE;
2635 This->prop_changed = FALSE;
2636 This->encoding = SysAllocString(utf16W);
2637 This->version = SysAllocString(version10W);
2638 This->xml_enc = XmlEncoding_UTF16;
2640 This->element = NULL;
2641 This->cdata = FALSE;
2642 This->indent = 0;
2643 This->text = FALSE;
2644 This->newline = FALSE;
2646 This->dest = NULL;
2648 hr = init_output_buffer(This->xml_enc, &This->buffer);
2649 if (hr != S_OK) {
2650 SysFreeString(This->encoding);
2651 SysFreeString(This->version);
2652 heap_free(This);
2653 return hr;
2656 init_dispex(&This->dispex, (IUnknown*)&This->IMXWriter_iface, &mxwriter_dispex);
2658 *ppObj = &This->IMXWriter_iface;
2660 TRACE("returning iface %p\n", *ppObj);
2662 return S_OK;
2665 static HRESULT WINAPI MXAttributes_QueryInterface(IMXAttributes *iface, REFIID riid, void **ppObj)
2667 mxattributes *This = impl_from_IMXAttributes( iface );
2669 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppObj);
2671 *ppObj = NULL;
2673 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2674 IsEqualGUID( riid, &IID_IDispatch ) ||
2675 IsEqualGUID( riid, &IID_IMXAttributes ))
2677 *ppObj = iface;
2679 else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
2681 *ppObj = &This->ISAXAttributes_iface;
2683 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
2685 *ppObj = &This->IVBSAXAttributes_iface;
2687 else if (dispex_query_interface(&This->dispex, riid, ppObj))
2689 return *ppObj ? S_OK : E_NOINTERFACE;
2691 else
2693 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2694 return E_NOINTERFACE;
2697 IMXAttributes_AddRef( iface );
2699 return S_OK;
2702 static ULONG WINAPI MXAttributes_AddRef(IMXAttributes *iface)
2704 mxattributes *This = impl_from_IMXAttributes( iface );
2705 ULONG ref = InterlockedIncrement( &This->ref );
2706 TRACE("(%p)->(%d)\n", This, ref );
2707 return ref;
2710 static ULONG WINAPI MXAttributes_Release(IMXAttributes *iface)
2712 mxattributes *This = impl_from_IMXAttributes( iface );
2713 LONG ref = InterlockedDecrement( &This->ref );
2715 TRACE("(%p)->(%d)\n", This, ref);
2717 if (ref == 0)
2719 int i;
2721 for (i = 0; i < This->length; i++)
2723 SysFreeString(This->attr[i].qname);
2724 SysFreeString(This->attr[i].local);
2725 SysFreeString(This->attr[i].uri);
2726 SysFreeString(This->attr[i].type);
2727 SysFreeString(This->attr[i].value);
2730 heap_free(This->attr);
2731 heap_free(This);
2734 return ref;
2737 static HRESULT WINAPI MXAttributes_GetTypeInfoCount(IMXAttributes *iface, UINT* pctinfo)
2739 mxattributes *This = impl_from_IMXAttributes( iface );
2740 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2743 static HRESULT WINAPI MXAttributes_GetTypeInfo(IMXAttributes *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2745 mxattributes *This = impl_from_IMXAttributes( iface );
2746 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2749 static HRESULT WINAPI MXAttributes_GetIDsOfNames(
2750 IMXAttributes *iface,
2751 REFIID riid,
2752 LPOLESTR* rgszNames,
2753 UINT cNames,
2754 LCID lcid,
2755 DISPID* rgDispId)
2757 mxattributes *This = impl_from_IMXAttributes( iface );
2758 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2759 riid, rgszNames, cNames, lcid, rgDispId);
2762 static HRESULT WINAPI MXAttributes_Invoke(
2763 IMXAttributes *iface,
2764 DISPID dispIdMember,
2765 REFIID riid,
2766 LCID lcid,
2767 WORD wFlags,
2768 DISPPARAMS* pDispParams,
2769 VARIANT* pVarResult,
2770 EXCEPINFO* pExcepInfo,
2771 UINT* puArgErr)
2773 mxattributes *This = impl_from_IMXAttributes( iface );
2774 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
2775 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2778 static HRESULT WINAPI MXAttributes_addAttribute(IMXAttributes *iface,
2779 BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2781 mxattributes *This = impl_from_IMXAttributes( iface );
2782 mxattribute *attr;
2783 HRESULT hr;
2785 TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(uri), debugstr_w(localName),
2786 debugstr_w(QName), debugstr_w(type), debugstr_w(value));
2788 if ((!uri || !localName || !QName || !type || !value) && This->class_version != MSXML6)
2789 return E_INVALIDARG;
2791 /* ensure array is large enough */
2792 hr = mxattributes_grow(This);
2793 if (hr != S_OK) return hr;
2795 attr = &This->attr[This->length];
2797 attr->qname = SysAllocString(QName);
2798 attr->local = SysAllocString(localName);
2799 attr->uri = SysAllocString(uri);
2800 attr->type = SysAllocString(type ? type : emptyW);
2801 attr->value = SysAllocString(value);
2802 This->length++;
2804 return S_OK;
2807 static HRESULT WINAPI MXAttributes_addAttributeFromIndex(IMXAttributes *iface,
2808 VARIANT atts, int index)
2810 mxattributes *This = impl_from_IMXAttributes( iface );
2811 FIXME("(%p)->(%s %d): stub\n", This, debugstr_variant(&atts), index);
2812 return E_NOTIMPL;
2815 static HRESULT WINAPI MXAttributes_clear(IMXAttributes *iface)
2817 mxattributes *This = impl_from_IMXAttributes( iface );
2818 int i;
2820 TRACE("(%p)\n", This);
2822 for (i = 0; i < This->length; i++)
2824 SysFreeString(This->attr[i].qname);
2825 SysFreeString(This->attr[i].local);
2826 SysFreeString(This->attr[i].uri);
2827 SysFreeString(This->attr[i].type);
2828 SysFreeString(This->attr[i].value);
2829 memset(&This->attr[i], 0, sizeof(mxattribute));
2832 This->length = 0;
2834 return S_OK;
2837 static mxattribute *get_attribute_byindex(mxattributes *attrs, int index)
2839 if (index < 0 || index >= attrs->length) return NULL;
2840 return &attrs->attr[index];
2843 static HRESULT WINAPI MXAttributes_removeAttribute(IMXAttributes *iface, int index)
2845 mxattributes *This = impl_from_IMXAttributes( iface );
2846 mxattribute *dst;
2848 TRACE("(%p)->(%d)\n", This, index);
2850 if (!(dst = get_attribute_byindex(This, index))) return E_INVALIDARG;
2852 /* no need to remove last attribute, just make it inaccessible */
2853 if (index + 1 == This->length)
2855 This->length--;
2856 return S_OK;
2859 memmove(dst, dst + 1, (This->length-index-1)*sizeof(*dst));
2860 This->length--;
2862 return S_OK;
2865 static HRESULT WINAPI MXAttributes_setAttribute(IMXAttributes *iface, int index,
2866 BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2868 mxattributes *This = impl_from_IMXAttributes( iface );
2869 FIXME("(%p)->(%d %s %s %s %s %s): stub\n", This, index, debugstr_w(uri),
2870 debugstr_w(localName), debugstr_w(QName), debugstr_w(type), debugstr_w(value));
2871 return E_NOTIMPL;
2874 static HRESULT WINAPI MXAttributes_setAttributes(IMXAttributes *iface, VARIANT atts)
2876 mxattributes *This = impl_from_IMXAttributes( iface );
2877 FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&atts));
2878 return E_NOTIMPL;
2881 static HRESULT WINAPI MXAttributes_setLocalName(IMXAttributes *iface, int index,
2882 BSTR localName)
2884 mxattributes *This = impl_from_IMXAttributes( iface );
2885 mxattribute *attr;
2887 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(localName));
2889 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2891 SysFreeString(attr->local);
2892 attr->local = SysAllocString(localName);
2894 return S_OK;
2897 static HRESULT WINAPI MXAttributes_setQName(IMXAttributes *iface, int index, BSTR QName)
2899 mxattributes *This = impl_from_IMXAttributes( iface );
2900 mxattribute *attr;
2902 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(QName));
2904 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2906 SysFreeString(attr->qname);
2907 attr->qname = SysAllocString(QName);
2909 return S_OK;
2912 static HRESULT WINAPI MXAttributes_setURI(IMXAttributes *iface, int index, BSTR uri)
2914 mxattributes *This = impl_from_IMXAttributes( iface );
2915 mxattribute *attr;
2917 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(uri));
2919 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2921 SysFreeString(attr->uri);
2922 attr->uri = SysAllocString(uri);
2924 return S_OK;
2927 static HRESULT WINAPI MXAttributes_setValue(IMXAttributes *iface, int index, BSTR value)
2929 mxattributes *This = impl_from_IMXAttributes( iface );
2930 mxattribute *attr;
2932 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(value));
2934 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2936 SysFreeString(attr->value);
2937 attr->value = SysAllocString(value);
2939 return S_OK;
2942 static const IMXAttributesVtbl MXAttributesVtbl = {
2943 MXAttributes_QueryInterface,
2944 MXAttributes_AddRef,
2945 MXAttributes_Release,
2946 MXAttributes_GetTypeInfoCount,
2947 MXAttributes_GetTypeInfo,
2948 MXAttributes_GetIDsOfNames,
2949 MXAttributes_Invoke,
2950 MXAttributes_addAttribute,
2951 MXAttributes_addAttributeFromIndex,
2952 MXAttributes_clear,
2953 MXAttributes_removeAttribute,
2954 MXAttributes_setAttribute,
2955 MXAttributes_setAttributes,
2956 MXAttributes_setLocalName,
2957 MXAttributes_setQName,
2958 MXAttributes_setURI,
2959 MXAttributes_setValue
2962 static HRESULT WINAPI SAXAttributes_QueryInterface(ISAXAttributes *iface, REFIID riid, void **ppObj)
2964 mxattributes *This = impl_from_ISAXAttributes( iface );
2965 return IMXAttributes_QueryInterface(&This->IMXAttributes_iface, riid, ppObj);
2968 static ULONG WINAPI SAXAttributes_AddRef(ISAXAttributes *iface)
2970 mxattributes *This = impl_from_ISAXAttributes( iface );
2971 return IMXAttributes_AddRef(&This->IMXAttributes_iface);
2974 static ULONG WINAPI SAXAttributes_Release(ISAXAttributes *iface)
2976 mxattributes *This = impl_from_ISAXAttributes( iface );
2977 return IMXAttributes_Release(&This->IMXAttributes_iface);
2980 static HRESULT WINAPI SAXAttributes_getLength(ISAXAttributes *iface, int *length)
2982 mxattributes *This = impl_from_ISAXAttributes( iface );
2983 TRACE("(%p)->(%p)\n", This, length);
2985 if (!length && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
2986 return E_POINTER;
2988 *length = This->length;
2990 return S_OK;
2993 static HRESULT WINAPI SAXAttributes_getURI(ISAXAttributes *iface, int index, const WCHAR **uri,
2994 int *len)
2996 mxattributes *This = impl_from_ISAXAttributes( iface );
2998 TRACE("(%p)->(%d %p %p)\n", This, index, uri, len);
3000 if (index >= This->length || index < 0) return E_INVALIDARG;
3001 if (!uri || !len) return E_POINTER;
3003 *len = SysStringLen(This->attr[index].uri);
3004 *uri = This->attr[index].uri;
3006 return S_OK;
3009 static HRESULT WINAPI SAXAttributes_getLocalName(ISAXAttributes *iface, int index, const WCHAR **name,
3010 int *len)
3012 mxattributes *This = impl_from_ISAXAttributes( iface );
3014 TRACE("(%p)->(%d %p %p)\n", This, index, name, len);
3016 if (index >= This->length || index < 0) return E_INVALIDARG;
3017 if (!name || !len) return E_POINTER;
3019 *len = SysStringLen(This->attr[index].local);
3020 *name = This->attr[index].local;
3022 return S_OK;
3025 static HRESULT WINAPI SAXAttributes_getQName(ISAXAttributes *iface, int index, const WCHAR **qname, int *length)
3027 mxattributes *This = impl_from_ISAXAttributes( iface );
3029 TRACE("(%p)->(%d %p %p)\n", This, index, qname, length);
3031 if (index >= This->length) return E_INVALIDARG;
3032 if (!qname || !length) return E_POINTER;
3034 *qname = This->attr[index].qname;
3035 *length = SysStringLen(This->attr[index].qname);
3037 return S_OK;
3040 static HRESULT WINAPI SAXAttributes_getName(ISAXAttributes *iface, int index, const WCHAR **uri, int *uri_len,
3041 const WCHAR **local, int *local_len, const WCHAR **qname, int *qname_len)
3043 mxattributes *This = impl_from_ISAXAttributes( iface );
3045 TRACE("(%p)->(%d %p %p %p %p %p %p)\n", This, index, uri, uri_len, local, local_len, qname, qname_len);
3047 if (index >= This->length || index < 0)
3048 return E_INVALIDARG;
3050 if (!uri || !uri_len || !local || !local_len || !qname || !qname_len)
3051 return E_POINTER;
3053 *uri_len = SysStringLen(This->attr[index].uri);
3054 *uri = This->attr[index].uri;
3056 *local_len = SysStringLen(This->attr[index].local);
3057 *local = This->attr[index].local;
3059 *qname_len = SysStringLen(This->attr[index].qname);
3060 *qname = This->attr[index].qname;
3062 TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*local), debugstr_w(*qname));
3064 return S_OK;
3067 static HRESULT WINAPI SAXAttributes_getIndexFromName(ISAXAttributes *iface, const WCHAR *uri, int uri_len,
3068 const WCHAR *name, int len, int *index)
3070 mxattributes *This = impl_from_ISAXAttributes( iface );
3071 int i;
3073 TRACE("(%p)->(%s:%d %s:%d %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
3074 debugstr_wn(name, len), len, index);
3076 if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3077 return E_POINTER;
3079 if (!uri || !name || !index) return E_INVALIDARG;
3081 for (i = 0; i < This->length; i++)
3083 if (uri_len != SysStringLen(This->attr[i].uri)) continue;
3084 if (strncmpW(uri, This->attr[i].uri, uri_len)) continue;
3086 if (len != SysStringLen(This->attr[i].local)) continue;
3087 if (strncmpW(name, This->attr[i].local, len)) continue;
3089 *index = i;
3090 return S_OK;
3093 return E_INVALIDARG;
3096 static HRESULT WINAPI SAXAttributes_getIndexFromQName(ISAXAttributes *iface, const WCHAR *qname,
3097 int len, int *index)
3099 mxattributes *This = impl_from_ISAXAttributes( iface );
3100 int i;
3102 TRACE("(%p)->(%s:%d %p)\n", This, debugstr_wn(qname, len), len, index);
3104 if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3105 return E_POINTER;
3107 if (!qname || !index || !len) return E_INVALIDARG;
3109 for (i = 0; i < This->length; i++)
3111 if (len != SysStringLen(This->attr[i].qname)) continue;
3112 if (strncmpW(qname, This->attr[i].qname, len)) continue;
3114 *index = i;
3115 return S_OK;
3118 return E_INVALIDARG;
3121 static HRESULT WINAPI SAXAttributes_getType(ISAXAttributes *iface, int index, const WCHAR **type,
3122 int *len)
3124 mxattributes *This = impl_from_ISAXAttributes( iface );
3126 TRACE("(%p)->(%d %p %p)\n", This, index, type, len);
3128 if (index >= This->length) return E_INVALIDARG;
3130 if ((!type || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3131 return E_POINTER;
3133 *type = This->attr[index].type;
3134 *len = SysStringLen(This->attr[index].type);
3136 return S_OK;
3139 static HRESULT WINAPI SAXAttributes_getTypeFromName(ISAXAttributes *iface, const WCHAR * pUri, int nUri,
3140 const WCHAR * pLocalName, int nLocalName, const WCHAR ** pType, int * nType)
3142 mxattributes *This = impl_from_ISAXAttributes( iface );
3143 FIXME("(%p)->(%s:%d %s:%d %p %p): stub\n", This, debugstr_wn(pUri, nUri), nUri,
3144 debugstr_wn(pLocalName, nLocalName), nLocalName, pType, nType);
3145 return E_NOTIMPL;
3148 static HRESULT WINAPI SAXAttributes_getTypeFromQName(ISAXAttributes *iface, const WCHAR * pQName,
3149 int nQName, const WCHAR ** pType, int * nType)
3151 mxattributes *This = impl_from_ISAXAttributes( iface );
3152 FIXME("(%p)->(%s:%d %p %p): stub\n", This, debugstr_wn(pQName, nQName), nQName, pType, nType);
3153 return E_NOTIMPL;
3156 static HRESULT WINAPI SAXAttributes_getValue(ISAXAttributes *iface, int index, const WCHAR **value,
3157 int *len)
3159 mxattributes *This = impl_from_ISAXAttributes( iface );
3161 TRACE("(%p)->(%d %p %p)\n", This, index, value, len);
3163 if (index >= This->length) return E_INVALIDARG;
3165 if ((!value || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3166 return E_POINTER;
3168 *value = This->attr[index].value;
3169 *len = SysStringLen(This->attr[index].value);
3171 return S_OK;
3174 static HRESULT WINAPI SAXAttributes_getValueFromName(ISAXAttributes *iface, const WCHAR *uri,
3175 int uri_len, const WCHAR *name, int name_len, const WCHAR **value, int *value_len)
3177 mxattributes *This = impl_from_ISAXAttributes( iface );
3178 HRESULT hr;
3179 int index;
3181 TRACE("(%p)->(%s:%d %s:%d %p %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
3182 debugstr_wn(name, name_len), name_len, value, value_len);
3184 if (!uri || !name || !value || !value_len)
3185 return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3187 hr = ISAXAttributes_getIndexFromName(iface, uri, uri_len, name, name_len, &index);
3188 if (hr == S_OK)
3189 hr = ISAXAttributes_getValue(iface, index, value, value_len);
3191 return hr;
3194 static HRESULT WINAPI SAXAttributes_getValueFromQName(ISAXAttributes *iface, const WCHAR *qname,
3195 int qname_len, const WCHAR **value, int *value_len)
3197 mxattributes *This = impl_from_ISAXAttributes( iface );
3198 HRESULT hr;
3199 int index;
3201 TRACE("(%p)->(%s:%d %p %p)\n", This, debugstr_wn(qname, qname_len), qname_len, value, value_len);
3203 if (!qname || !value || !value_len)
3204 return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3206 hr = ISAXAttributes_getIndexFromQName(iface, qname, qname_len, &index);
3207 if (hr == S_OK)
3208 hr = ISAXAttributes_getValue(iface, index, value, value_len);
3210 return hr;
3213 static const ISAXAttributesVtbl SAXAttributesVtbl = {
3214 SAXAttributes_QueryInterface,
3215 SAXAttributes_AddRef,
3216 SAXAttributes_Release,
3217 SAXAttributes_getLength,
3218 SAXAttributes_getURI,
3219 SAXAttributes_getLocalName,
3220 SAXAttributes_getQName,
3221 SAXAttributes_getName,
3222 SAXAttributes_getIndexFromName,
3223 SAXAttributes_getIndexFromQName,
3224 SAXAttributes_getType,
3225 SAXAttributes_getTypeFromName,
3226 SAXAttributes_getTypeFromQName,
3227 SAXAttributes_getValue,
3228 SAXAttributes_getValueFromName,
3229 SAXAttributes_getValueFromQName
3232 static HRESULT WINAPI VBSAXAttributes_QueryInterface(
3233 IVBSAXAttributes* iface,
3234 REFIID riid,
3235 void **ppvObject)
3237 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3238 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
3239 return ISAXAttributes_QueryInterface(&This->ISAXAttributes_iface, riid, ppvObject);
3242 static ULONG WINAPI VBSAXAttributes_AddRef(IVBSAXAttributes* iface)
3244 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3245 return ISAXAttributes_AddRef(&This->ISAXAttributes_iface);
3248 static ULONG WINAPI VBSAXAttributes_Release(IVBSAXAttributes* iface)
3250 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3251 return ISAXAttributes_Release(&This->ISAXAttributes_iface);
3254 static HRESULT WINAPI VBSAXAttributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
3256 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3258 TRACE("(%p)->(%p)\n", This, pctinfo);
3260 *pctinfo = 1;
3262 return S_OK;
3265 static HRESULT WINAPI VBSAXAttributes_GetTypeInfo(
3266 IVBSAXAttributes *iface,
3267 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
3269 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3270 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
3271 return get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
3274 static HRESULT WINAPI VBSAXAttributes_GetIDsOfNames(
3275 IVBSAXAttributes *iface,
3276 REFIID riid,
3277 LPOLESTR* rgszNames,
3278 UINT cNames,
3279 LCID lcid,
3280 DISPID* rgDispId)
3282 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3283 ITypeInfo *typeinfo;
3284 HRESULT hr;
3286 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
3287 lcid, rgDispId);
3289 if(!rgszNames || cNames == 0 || !rgDispId)
3290 return E_INVALIDARG;
3292 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
3293 if(SUCCEEDED(hr))
3295 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
3296 ITypeInfo_Release(typeinfo);
3299 return hr;
3302 static HRESULT WINAPI VBSAXAttributes_Invoke(
3303 IVBSAXAttributes *iface,
3304 DISPID dispIdMember,
3305 REFIID riid,
3306 LCID lcid,
3307 WORD wFlags,
3308 DISPPARAMS* pDispParams,
3309 VARIANT* pVarResult,
3310 EXCEPINFO* pExcepInfo,
3311 UINT* puArgErr)
3313 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3314 ITypeInfo *typeinfo;
3315 HRESULT hr;
3317 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
3318 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3320 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
3321 if(SUCCEEDED(hr))
3323 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
3324 pDispParams, pVarResult, pExcepInfo, puArgErr);
3325 ITypeInfo_Release(typeinfo);
3328 return hr;
3331 static HRESULT WINAPI VBSAXAttributes_get_length(IVBSAXAttributes* iface, int *len)
3333 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3334 return ISAXAttributes_getLength(&This->ISAXAttributes_iface, len);
3337 static HRESULT WINAPI VBSAXAttributes_getURI(IVBSAXAttributes* iface, int index, BSTR *uri)
3339 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3340 const WCHAR *uriW;
3341 HRESULT hr;
3342 int len;
3344 TRACE("(%p)->(%d %p)\n", This, index, uri);
3346 if (!uri)
3347 return E_POINTER;
3349 *uri = NULL;
3350 hr = ISAXAttributes_getURI(&This->ISAXAttributes_iface, index, &uriW, &len);
3351 if (FAILED(hr))
3352 return hr;
3354 return return_bstrn(uriW, len, uri);
3357 static HRESULT WINAPI VBSAXAttributes_getLocalName(IVBSAXAttributes* iface, int index, BSTR *name)
3359 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3360 const WCHAR *nameW;
3361 HRESULT hr;
3362 int len;
3364 TRACE("(%p)->(%d %p)\n", This, index, name);
3366 if (!name)
3367 return E_POINTER;
3369 *name = NULL;
3370 hr = ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, index, &nameW, &len);
3371 if (FAILED(hr))
3372 return hr;
3374 return return_bstrn(nameW, len, name);
3377 static HRESULT WINAPI VBSAXAttributes_getQName(IVBSAXAttributes* iface, int index, BSTR *qname)
3379 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3380 const WCHAR *qnameW;
3381 HRESULT hr;
3382 int len;
3384 TRACE("(%p)->(%d %p)\n", This, index, qname);
3386 if (!qname)
3387 return E_POINTER;
3389 *qname = NULL;
3390 hr = ISAXAttributes_getQName(&This->ISAXAttributes_iface, index, &qnameW, &len);
3391 if (FAILED(hr))
3392 return hr;
3394 return return_bstrn(qnameW, len, qname);
3397 static HRESULT WINAPI VBSAXAttributes_getIndexFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name, int *index)
3399 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3400 return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3401 name, SysStringLen(name), index);
3404 static HRESULT WINAPI VBSAXAttributes_getIndexFromQName(IVBSAXAttributes* iface, BSTR qname, int *index)
3406 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3407 return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, qname,
3408 SysStringLen(qname), index);
3411 static HRESULT WINAPI VBSAXAttributes_getType(IVBSAXAttributes* iface, int index, BSTR *type)
3413 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3414 const WCHAR *typeW;
3415 HRESULT hr;
3416 int len;
3418 TRACE("(%p)->(%d %p)\n", This, index, type);
3420 if (!type)
3421 return E_POINTER;
3423 *type = NULL;
3424 hr = ISAXAttributes_getType(&This->ISAXAttributes_iface, index, &typeW, &len);
3425 if (FAILED(hr))
3426 return hr;
3428 return return_bstrn(typeW, len, type);
3431 static HRESULT WINAPI VBSAXAttributes_getTypeFromName(IVBSAXAttributes* iface, BSTR uri,
3432 BSTR name, BSTR *type)
3434 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3435 const WCHAR *typeW;
3436 HRESULT hr;
3437 int len;
3439 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), type);
3441 if (!type)
3442 return E_POINTER;
3444 *type = NULL;
3445 hr = ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3446 name, SysStringLen(name), &typeW, &len);
3447 if (FAILED(hr))
3448 return hr;
3450 return return_bstrn(typeW, len, type);
3453 static HRESULT WINAPI VBSAXAttributes_getTypeFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *type)
3455 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3456 const WCHAR *typeW;
3457 HRESULT hr;
3458 int len;
3460 TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), type);
3462 if (!type)
3463 return E_POINTER;
3465 *type = NULL;
3466 hr = ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3467 &typeW, &len);
3468 if (FAILED(hr))
3469 return hr;
3471 return return_bstrn(typeW, len, type);
3474 static HRESULT WINAPI VBSAXAttributes_getValue(IVBSAXAttributes* iface, int index, BSTR *value)
3476 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3477 const WCHAR *valueW;
3478 HRESULT hr;
3479 int len;
3481 TRACE("(%p)->(%d %p)\n", This, index, value);
3483 if (!value)
3484 return E_POINTER;
3486 *value = NULL;
3487 hr = ISAXAttributes_getValue(&This->ISAXAttributes_iface, index, &valueW, &len);
3488 if (FAILED(hr))
3489 return hr;
3491 return return_bstrn(valueW, len, value);
3494 static HRESULT WINAPI VBSAXAttributes_getValueFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name,
3495 BSTR *value)
3497 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3498 const WCHAR *valueW;
3499 HRESULT hr;
3500 int len;
3502 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), value);
3504 if (!value)
3505 return E_POINTER;
3507 *value = NULL;
3508 hr = ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3509 name, SysStringLen(name), &valueW, &len);
3510 if (FAILED(hr))
3511 return hr;
3513 return return_bstrn(valueW, len, value);
3516 static HRESULT WINAPI VBSAXAttributes_getValueFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *value)
3518 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3519 const WCHAR *valueW;
3520 HRESULT hr;
3521 int len;
3523 TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), value);
3525 if (!value)
3526 return E_POINTER;
3528 *value = NULL;
3529 hr = ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3530 &valueW, &len);
3531 if (FAILED(hr))
3532 return hr;
3534 return return_bstrn(valueW, len, value);
3537 static const struct IVBSAXAttributesVtbl VBSAXAttributesVtbl =
3539 VBSAXAttributes_QueryInterface,
3540 VBSAXAttributes_AddRef,
3541 VBSAXAttributes_Release,
3542 VBSAXAttributes_GetTypeInfoCount,
3543 VBSAXAttributes_GetTypeInfo,
3544 VBSAXAttributes_GetIDsOfNames,
3545 VBSAXAttributes_Invoke,
3546 VBSAXAttributes_get_length,
3547 VBSAXAttributes_getURI,
3548 VBSAXAttributes_getLocalName,
3549 VBSAXAttributes_getQName,
3550 VBSAXAttributes_getIndexFromName,
3551 VBSAXAttributes_getIndexFromQName,
3552 VBSAXAttributes_getType,
3553 VBSAXAttributes_getTypeFromName,
3554 VBSAXAttributes_getTypeFromQName,
3555 VBSAXAttributes_getValue,
3556 VBSAXAttributes_getValueFromName,
3557 VBSAXAttributes_getValueFromQName
3560 static const tid_t mxattrs_iface_tids[] = {
3561 IMXAttributes_tid,
3565 static dispex_static_data_t mxattrs_dispex = {
3566 NULL,
3567 IMXAttributes_tid,
3568 NULL,
3569 mxattrs_iface_tids
3572 HRESULT SAXAttributes_create(MSXML_VERSION version, void **ppObj)
3574 static const int default_count = 10;
3575 mxattributes *This;
3577 TRACE("(%p)\n", ppObj);
3579 This = heap_alloc( sizeof (*This) );
3580 if( !This )
3581 return E_OUTOFMEMORY;
3583 This->IMXAttributes_iface.lpVtbl = &MXAttributesVtbl;
3584 This->ISAXAttributes_iface.lpVtbl = &SAXAttributesVtbl;
3585 This->IVBSAXAttributes_iface.lpVtbl = &VBSAXAttributesVtbl;
3586 This->ref = 1;
3588 This->class_version = version;
3590 This->attr = heap_alloc(default_count*sizeof(mxattribute));
3591 This->length = 0;
3592 This->allocated = default_count;
3594 *ppObj = &This->IMXAttributes_iface;
3596 init_dispex(&This->dispex, (IUnknown*)&This->IMXAttributes_iface, &mxattrs_dispex);
3598 TRACE("returning iface %p\n", *ppObj);
3600 return S_OK;