wined3d: Introduce wined3d_resource_prepare_sysmem().
[wine.git] / dlls / msxml3 / mxwriter.c
bloba5bfdf1e991de46718aeca2d003d5969fd09d63b
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_Unknown
67 } xml_encoding;
69 struct xml_encoding_data
71 const WCHAR *encoding;
72 xml_encoding enc;
73 UINT cp;
76 static const WCHAR iso_8859_1W[] = {'i','s','o','-','8','8','5','9','-','1',0};
77 static const WCHAR iso_8859_2W[] = {'i','s','o','-','8','8','5','9','-','2',0};
78 static const WCHAR iso_8859_3W[] = {'i','s','o','-','8','8','5','9','-','3',0};
79 static const WCHAR iso_8859_4W[] = {'i','s','o','-','8','8','5','9','-','4',0};
80 static const WCHAR iso_8859_5W[] = {'i','s','o','-','8','8','5','9','-','5',0};
81 static const WCHAR iso_8859_7W[] = {'i','s','o','-','8','8','5','9','-','7',0};
82 static const WCHAR iso_8859_9W[] = {'i','s','o','-','8','8','5','9','-','9',0};
83 static const WCHAR iso_8859_13W[] = {'i','s','o','-','8','8','5','9','-','1','3',0};
84 static const WCHAR iso_8859_15W[] = {'i','s','o','-','8','8','5','9','-','1','5',0};
85 static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
86 static const WCHAR utf8W[] = {'U','T','F','-','8',0};
88 static const struct xml_encoding_data xml_encoding_map[] = {
89 { iso_8859_1W, XmlEncoding_ISO_8859_1, 28591 },
90 { iso_8859_13W, XmlEncoding_ISO_8859_13, 28603 },
91 { iso_8859_15W, XmlEncoding_ISO_8859_15, 28605 },
92 { iso_8859_2W, XmlEncoding_ISO_8859_2, 28592 },
93 { iso_8859_3W, XmlEncoding_ISO_8859_3, 28593 },
94 { iso_8859_4W, XmlEncoding_ISO_8859_4, 28594 },
95 { iso_8859_5W, XmlEncoding_ISO_8859_5, 28595 },
96 { iso_8859_7W, XmlEncoding_ISO_8859_7, 28597 },
97 { iso_8859_9W, XmlEncoding_ISO_8859_9, 28599 },
98 { utf16W, XmlEncoding_UTF16, ~0 },
99 { utf8W, XmlEncoding_UTF8, CP_UTF8 }
102 typedef enum
104 MXWriter_BOM = 0,
105 MXWriter_DisableEscaping,
106 MXWriter_Indent,
107 MXWriter_OmitXmlDecl,
108 MXWriter_Standalone,
109 MXWriter_LastProp
110 } mxwriter_prop;
112 typedef enum
114 EscapeValue,
115 EscapeText
116 } escape_mode;
118 typedef struct
120 struct list entry;
121 char *data;
122 unsigned int allocated;
123 unsigned int written;
124 } encoded_buffer;
126 typedef struct
128 encoded_buffer encoded;
129 UINT code_page;
130 UINT utf16_total; /* total number of bytes written since last buffer reinitialization */
131 struct list blocks; /* only used when output was not set, for BSTR case */
132 } output_buffer;
134 typedef struct
136 DispatchEx dispex;
137 IMXWriter IMXWriter_iface;
138 ISAXContentHandler ISAXContentHandler_iface;
139 ISAXLexicalHandler ISAXLexicalHandler_iface;
140 ISAXDeclHandler ISAXDeclHandler_iface;
141 ISAXDTDHandler ISAXDTDHandler_iface;
142 ISAXErrorHandler ISAXErrorHandler_iface;
143 IVBSAXDeclHandler IVBSAXDeclHandler_iface;
144 IVBSAXLexicalHandler IVBSAXLexicalHandler_iface;
145 IVBSAXContentHandler IVBSAXContentHandler_iface;
146 IVBSAXDTDHandler IVBSAXDTDHandler_iface;
147 IVBSAXErrorHandler IVBSAXErrorHandler_iface;
149 LONG ref;
150 MSXML_VERSION class_version;
152 VARIANT_BOOL props[MXWriter_LastProp];
153 BOOL prop_changed;
154 BOOL cdata;
156 BOOL text; /* last node was text node, so we shouldn't indent next node */
157 BOOL newline; /* newline was already added as a part of previous call */
158 UINT indent; /* indentation level for next node */
160 BSTR version;
162 BSTR encoding; /* exact property value */
163 xml_encoding xml_enc;
165 /* contains a pending (or not closed yet) element name or NULL if
166 we don't have to close */
167 BSTR element;
169 IStream *dest;
171 output_buffer buffer;
172 } mxwriter;
174 typedef struct
176 BSTR qname;
177 BSTR local;
178 BSTR uri;
179 BSTR type;
180 BSTR value;
181 } mxattribute;
183 typedef struct
185 DispatchEx dispex;
186 IMXAttributes IMXAttributes_iface;
187 ISAXAttributes ISAXAttributes_iface;
188 IVBSAXAttributes IVBSAXAttributes_iface;
189 LONG ref;
191 MSXML_VERSION class_version;
193 mxattribute *attr;
194 int length;
195 int allocated;
196 } mxattributes;
198 static inline mxattributes *impl_from_IMXAttributes( IMXAttributes *iface )
200 return CONTAINING_RECORD(iface, mxattributes, IMXAttributes_iface);
203 static inline mxattributes *impl_from_ISAXAttributes( ISAXAttributes *iface )
205 return CONTAINING_RECORD(iface, mxattributes, ISAXAttributes_iface);
208 static inline mxattributes *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
210 return CONTAINING_RECORD(iface, mxattributes, IVBSAXAttributes_iface);
213 static HRESULT mxattributes_grow(mxattributes *This)
215 if (This->length < This->allocated) return S_OK;
217 This->allocated *= 2;
218 This->attr = heap_realloc(This->attr, This->allocated*sizeof(mxattribute));
220 return This->attr ? S_OK : E_OUTOFMEMORY;
223 static xml_encoding parse_encoding_name(const WCHAR *encoding)
225 int min, max, n, c;
227 min = 0;
228 max = ARRAY_SIZE(xml_encoding_map) - 1;
230 while (min <= max)
232 n = (min+max)/2;
234 c = strcmpiW(xml_encoding_map[n].encoding, encoding);
235 if (!c)
236 return xml_encoding_map[n].enc;
238 if (c > 0)
239 max = n-1;
240 else
241 min = n+1;
244 return XmlEncoding_Unknown;
247 static HRESULT init_encoded_buffer(encoded_buffer *buffer)
249 const int initial_len = 0x1000;
250 buffer->data = heap_alloc(initial_len);
251 if (!buffer->data) return E_OUTOFMEMORY;
253 memset(buffer->data, 0, 4);
254 buffer->allocated = initial_len;
255 buffer->written = 0;
257 return S_OK;
260 static void free_encoded_buffer(encoded_buffer *buffer)
262 heap_free(buffer->data);
265 static HRESULT get_code_page(xml_encoding encoding, UINT *cp)
267 const struct xml_encoding_data *data;
269 if (encoding == XmlEncoding_Unknown)
271 FIXME("unsupported encoding %d\n", encoding);
272 return E_NOTIMPL;
275 data = &xml_encoding_map[encoding];
276 *cp = data->cp;
278 return S_OK;
281 static HRESULT init_output_buffer(xml_encoding encoding, output_buffer *buffer)
283 HRESULT hr;
285 hr = get_code_page(encoding, &buffer->code_page);
286 if (hr != S_OK)
287 return hr;
289 hr = init_encoded_buffer(&buffer->encoded);
290 if (hr != S_OK)
291 return hr;
293 list_init(&buffer->blocks);
294 buffer->utf16_total = 0;
296 return S_OK;
299 static void free_output_buffer(output_buffer *buffer)
301 encoded_buffer *cur, *cur2;
303 free_encoded_buffer(&buffer->encoded);
305 LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &buffer->blocks, encoded_buffer, entry)
307 list_remove(&cur->entry);
308 free_encoded_buffer(cur);
309 heap_free(cur);
313 static HRESULT write_output_buffer(mxwriter *writer, const WCHAR *data, int len)
315 output_buffer *buffer = &writer->buffer;
316 encoded_buffer *buff;
317 unsigned int written;
318 int src_len;
320 if (!len || !*data)
321 return S_OK;
323 src_len = len == -1 ? strlenW(data) : len;
324 if (writer->dest)
326 buff = &buffer->encoded;
328 if (buffer->code_page == ~0)
330 unsigned int avail = buff->allocated - buff->written;
332 src_len *= sizeof(WCHAR);
333 written = min(avail, src_len);
335 /* fill internal buffer first */
336 if (avail)
338 memcpy(buff->data + buff->written, data, written);
339 data += written / sizeof(WCHAR);
340 buff->written += written;
341 avail -= written;
342 src_len -= written;
345 if (!avail)
347 IStream_Write(writer->dest, buff->data, buff->written, &written);
348 buff->written = 0;
349 if (src_len >= buff->allocated)
350 IStream_Write(writer->dest, data, src_len, &written);
351 else if (src_len)
353 memcpy(buff->data, data, src_len);
354 buff->written += src_len;
358 else
360 unsigned int avail = buff->allocated - buff->written;
361 int length;
363 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, NULL, 0, NULL, NULL);
364 if (avail >= length)
366 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, buff->data + buff->written, length, NULL, NULL);
367 buff->written += length;
369 else
371 /* drain what we go so far */
372 if (buff->written)
374 IStream_Write(writer->dest, buff->data, buff->written, &written);
375 buff->written = 0;
376 avail = buff->allocated;
379 if (avail >= length)
381 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, buff->data + buff->written, length, NULL, NULL);
382 buff->written += length;
384 else
386 char *mb;
388 /* if current chunk is larger than total buffer size, convert it at once using temporary allocated buffer */
389 mb = heap_alloc(length);
390 if (!mb)
391 return E_OUTOFMEMORY;
393 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, mb, length, NULL, NULL);
394 IStream_Write(writer->dest, mb, length, &written);
395 heap_free(mb);
400 /* When writer has no output set we have to accumulate everything to return it later in a form of BSTR.
401 To achieve that:
403 - fill a buffer already allocated as part of output buffer;
404 - when current buffer is full, allocate another one and switch to it; buffers themselves never grow,
405 but are linked together, with head pointing to first allocated buffer after initial one got filled;
406 - later during get_output() contents are concatenated by copying one after another to destination BSTR buffer,
407 that's returned to the client. */
408 else
410 /* select last used block */
411 if (list_empty(&buffer->blocks))
412 buff = &buffer->encoded;
413 else
414 buff = LIST_ENTRY(list_tail(&buffer->blocks), encoded_buffer, entry);
416 src_len *= sizeof(WCHAR);
417 while (src_len)
419 unsigned int avail = buff->allocated - buff->written;
420 unsigned int written = min(avail, src_len);
422 if (avail)
424 memcpy(buff->data + buff->written, data, written);
425 buff->written += written;
426 buffer->utf16_total += written;
427 src_len -= written;
430 /* alloc new block if needed and retry */
431 if (src_len)
433 encoded_buffer *next = heap_alloc(sizeof(*next));
434 HRESULT hr;
436 if (FAILED(hr = init_encoded_buffer(next))) {
437 heap_free(next);
438 return hr;
441 list_add_tail(&buffer->blocks, &next->entry);
442 buff = next;
447 return S_OK;
450 static HRESULT write_output_buffer_quoted(mxwriter *writer, const WCHAR *data, int len)
452 write_output_buffer(writer, quotW, 1);
453 write_output_buffer(writer, data, len);
454 write_output_buffer(writer, quotW, 1);
456 return S_OK;
459 /* frees buffer data, reallocates with a default lengths */
460 static void close_output_buffer(mxwriter *writer)
462 encoded_buffer *cur, *cur2;
464 heap_free(writer->buffer.encoded.data);
466 LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &writer->buffer.blocks, encoded_buffer, entry)
468 list_remove(&cur->entry);
469 free_encoded_buffer(cur);
470 heap_free(cur);
473 init_encoded_buffer(&writer->buffer.encoded);
474 get_code_page(writer->xml_enc, &writer->buffer.code_page);
475 writer->buffer.utf16_total = 0;
476 list_init(&writer->buffer.blocks);
479 /* Escapes special characters like:
480 '<' -> "&lt;"
481 '&' -> "&amp;"
482 '"' -> "&quot;"
483 '>' -> "&gt;"
485 On call 'len' contains a length of 'str' in chars or -1 if it's null terminated.
486 After a call it's updated with actual new length if it wasn't -1 initially.
488 static WCHAR *get_escaped_string(const WCHAR *str, escape_mode mode, int *len)
490 static const WCHAR ltW[] = {'&','l','t',';'};
491 static const WCHAR ampW[] = {'&','a','m','p',';'};
492 static const WCHAR equotW[] = {'&','q','u','o','t',';'};
493 static const WCHAR gtW[] = {'&','g','t',';'};
495 const int default_alloc = 100;
496 const int grow_thresh = 10;
497 int p = *len, conv_len;
498 WCHAR *ptr, *ret;
500 /* default buffer size to something if length is unknown */
501 conv_len = max(2**len, default_alloc);
502 ptr = ret = heap_alloc(conv_len*sizeof(WCHAR));
504 while (p)
506 if (ptr - ret > conv_len - grow_thresh)
508 int written = ptr - ret;
509 conv_len *= 2;
510 ptr = ret = heap_realloc(ret, conv_len*sizeof(WCHAR));
511 ptr += written;
514 switch (*str)
516 case '<':
517 memcpy(ptr, ltW, sizeof(ltW));
518 ptr += ARRAY_SIZE(ltW);
519 break;
520 case '&':
521 memcpy(ptr, ampW, sizeof(ampW));
522 ptr += ARRAY_SIZE(ampW);
523 break;
524 case '>':
525 memcpy(ptr, gtW, sizeof(gtW));
526 ptr += ARRAY_SIZE(gtW);
527 break;
528 case '"':
529 if (mode == EscapeValue)
531 memcpy(ptr, equotW, sizeof(equotW));
532 ptr += ARRAY_SIZE(equotW);
533 break;
535 /* fallthrough for text mode */
536 default:
537 *ptr++ = *str;
538 break;
541 str++;
542 p--;
545 *len = ptr-ret;
546 *++ptr = 0;
548 return ret;
551 static void write_prolog_buffer(mxwriter *writer)
553 static const WCHAR versionW[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','='};
554 static const WCHAR encodingW[] = {' ','e','n','c','o','d','i','n','g','=','\"'};
555 static const WCHAR standaloneW[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
556 static const WCHAR yesW[] = {'y','e','s','\"','?','>'};
557 static const WCHAR noW[] = {'n','o','\"','?','>'};
559 /* version */
560 write_output_buffer(writer, versionW, ARRAY_SIZE(versionW));
561 write_output_buffer_quoted(writer, writer->version, -1);
563 /* encoding */
564 write_output_buffer(writer, encodingW, ARRAY_SIZE(encodingW));
566 if (writer->dest)
567 write_output_buffer(writer, writer->encoding, -1);
568 else
569 write_output_buffer(writer, utf16W, ARRAY_SIZE(utf16W) - 1);
570 write_output_buffer(writer, quotW, 1);
572 /* standalone */
573 write_output_buffer(writer, standaloneW, ARRAY_SIZE(standaloneW));
574 if (writer->props[MXWriter_Standalone] == VARIANT_TRUE)
575 write_output_buffer(writer, yesW, ARRAY_SIZE(yesW));
576 else
577 write_output_buffer(writer, noW, ARRAY_SIZE(noW));
579 write_output_buffer(writer, crlfW, ARRAY_SIZE(crlfW));
580 writer->newline = TRUE;
583 /* Attempts to the write data from the mxwriter's buffer to
584 * the destination stream (if there is one).
586 static HRESULT write_data_to_stream(mxwriter *writer)
588 encoded_buffer *buffer = &writer->buffer.encoded;
589 ULONG written = 0;
591 if (!writer->dest)
592 return S_OK;
594 if (buffer->written == 0)
596 if (writer->xml_enc == XmlEncoding_UTF8)
597 IStream_Write(writer->dest, buffer->data, 0, &written);
599 else
601 IStream_Write(writer->dest, buffer->data, buffer->written, &written);
602 buffer->written = 0;
605 return S_OK;
608 /* Newly added element start tag left unclosed cause for empty elements
609 we have to close it differently. */
610 static void close_element_starttag(mxwriter *writer)
612 static const WCHAR gtW[] = {'>'};
613 if (!writer->element) return;
614 write_output_buffer(writer, gtW, 1);
617 static void write_node_indent(mxwriter *writer)
619 static const WCHAR tabW[] = {'\t'};
620 int indent = writer->indent;
622 if (!writer->props[MXWriter_Indent] || writer->text)
624 writer->text = FALSE;
625 return;
628 /* This is to workaround PI output logic that always puts newline chars,
629 document prolog PI does that too. */
630 if (!writer->newline)
631 write_output_buffer(writer, crlfW, ARRAY_SIZE(crlfW));
632 while (indent--)
633 write_output_buffer(writer, tabW, 1);
635 writer->newline = FALSE;
636 writer->text = FALSE;
639 static inline void writer_inc_indent(mxwriter *This)
641 This->indent++;
644 static inline void writer_dec_indent(mxwriter *This)
646 if (This->indent) This->indent--;
647 /* depth is decreased only when element is closed, meaning it's not a text node
648 at this point */
649 This->text = FALSE;
652 static void set_element_name(mxwriter *This, const WCHAR *name, int len)
654 SysFreeString(This->element);
655 if (name)
656 This->element = len != -1 ? SysAllocStringLen(name, len) : SysAllocString(name);
657 else
658 This->element = NULL;
661 static inline HRESULT flush_output_buffer(mxwriter *This)
663 close_element_starttag(This);
664 set_element_name(This, NULL, 0);
665 This->cdata = FALSE;
666 return write_data_to_stream(This);
669 /* Resets the mxwriter's output buffer by closing it, then creating a new
670 * output buffer using the given encoding.
672 static inline void reset_output_buffer(mxwriter *This)
674 close_output_buffer(This);
677 static HRESULT writer_set_property(mxwriter *writer, mxwriter_prop property, VARIANT_BOOL value)
679 writer->props[property] = value;
680 writer->prop_changed = TRUE;
681 return S_OK;
684 static HRESULT writer_get_property(const mxwriter *writer, mxwriter_prop property, VARIANT_BOOL *value)
686 if (!value) return E_POINTER;
687 *value = writer->props[property];
688 return S_OK;
691 static inline mxwriter *impl_from_IMXWriter(IMXWriter *iface)
693 return CONTAINING_RECORD(iface, mxwriter, IMXWriter_iface);
696 static inline mxwriter *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
698 return CONTAINING_RECORD(iface, mxwriter, ISAXContentHandler_iface);
701 static inline mxwriter *impl_from_IVBSAXContentHandler(IVBSAXContentHandler *iface)
703 return CONTAINING_RECORD(iface, mxwriter, IVBSAXContentHandler_iface);
706 static inline mxwriter *impl_from_ISAXLexicalHandler(ISAXLexicalHandler *iface)
708 return CONTAINING_RECORD(iface, mxwriter, ISAXLexicalHandler_iface);
711 static inline mxwriter *impl_from_IVBSAXLexicalHandler(IVBSAXLexicalHandler *iface)
713 return CONTAINING_RECORD(iface, mxwriter, IVBSAXLexicalHandler_iface);
716 static inline mxwriter *impl_from_ISAXDeclHandler(ISAXDeclHandler *iface)
718 return CONTAINING_RECORD(iface, mxwriter, ISAXDeclHandler_iface);
721 static inline mxwriter *impl_from_IVBSAXDeclHandler(IVBSAXDeclHandler *iface)
723 return CONTAINING_RECORD(iface, mxwriter, IVBSAXDeclHandler_iface);
726 static inline mxwriter *impl_from_ISAXDTDHandler(ISAXDTDHandler *iface)
728 return CONTAINING_RECORD(iface, mxwriter, ISAXDTDHandler_iface);
731 static inline mxwriter *impl_from_IVBSAXDTDHandler(IVBSAXDTDHandler *iface)
733 return CONTAINING_RECORD(iface, mxwriter, IVBSAXDTDHandler_iface);
736 static inline mxwriter *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
738 return CONTAINING_RECORD(iface, mxwriter, ISAXErrorHandler_iface);
741 static inline mxwriter *impl_from_IVBSAXErrorHandler(IVBSAXErrorHandler *iface)
743 return CONTAINING_RECORD(iface, mxwriter, IVBSAXErrorHandler_iface);
746 static HRESULT WINAPI mxwriter_QueryInterface(IMXWriter *iface, REFIID riid, void **obj)
748 mxwriter *This = impl_from_IMXWriter( iface );
750 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
752 *obj = NULL;
754 if ( IsEqualGUID( riid, &IID_IMXWriter ) ||
755 IsEqualGUID( riid, &IID_IDispatch ) ||
756 IsEqualGUID( riid, &IID_IUnknown ) )
758 *obj = &This->IMXWriter_iface;
760 else if ( IsEqualGUID( riid, &IID_ISAXContentHandler ) )
762 *obj = &This->ISAXContentHandler_iface;
764 else if ( IsEqualGUID( riid, &IID_ISAXLexicalHandler ) )
766 *obj = &This->ISAXLexicalHandler_iface;
768 else if ( IsEqualGUID( riid, &IID_ISAXDeclHandler ) )
770 *obj = &This->ISAXDeclHandler_iface;
772 else if ( IsEqualGUID( riid, &IID_ISAXDTDHandler ) )
774 *obj = &This->ISAXDTDHandler_iface;
776 else if ( IsEqualGUID( riid, &IID_ISAXErrorHandler ) )
778 *obj = &This->ISAXErrorHandler_iface;
780 else if ( IsEqualGUID( riid, &IID_IVBSAXDeclHandler ) )
782 *obj = &This->IVBSAXDeclHandler_iface;
784 else if ( IsEqualGUID( riid, &IID_IVBSAXLexicalHandler ) )
786 *obj = &This->IVBSAXLexicalHandler_iface;
788 else if ( IsEqualGUID( riid, &IID_IVBSAXContentHandler ) )
790 *obj = &This->IVBSAXContentHandler_iface;
792 else if ( IsEqualGUID( riid, &IID_IVBSAXDTDHandler ) )
794 *obj = &This->IVBSAXDTDHandler_iface;
796 else if ( IsEqualGUID( riid, &IID_IVBSAXErrorHandler ) )
798 *obj = &This->IVBSAXErrorHandler_iface;
800 else if (dispex_query_interface(&This->dispex, riid, obj))
802 return *obj ? S_OK : E_NOINTERFACE;
804 else
806 ERR("interface %s not implemented\n", debugstr_guid(riid));
807 *obj = NULL;
808 return E_NOINTERFACE;
811 IMXWriter_AddRef(iface);
812 return S_OK;
815 static ULONG WINAPI mxwriter_AddRef(IMXWriter *iface)
817 mxwriter *This = impl_from_IMXWriter( iface );
818 LONG ref = InterlockedIncrement(&This->ref);
820 TRACE("(%p)->(%d)\n", This, ref);
822 return ref;
825 static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
827 mxwriter *This = impl_from_IMXWriter( iface );
828 ULONG ref = InterlockedDecrement(&This->ref);
830 TRACE("(%p)->(%d)\n", This, ref);
832 if(!ref)
834 /* Windows flushes the buffer when the interface is destroyed. */
835 flush_output_buffer(This);
836 free_output_buffer(&This->buffer);
838 if (This->dest) IStream_Release(This->dest);
839 SysFreeString(This->version);
840 SysFreeString(This->encoding);
842 SysFreeString(This->element);
843 heap_free(This);
846 return ref;
849 static HRESULT WINAPI mxwriter_GetTypeInfoCount(IMXWriter *iface, UINT* pctinfo)
851 mxwriter *This = impl_from_IMXWriter( iface );
852 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
855 static HRESULT WINAPI mxwriter_GetTypeInfo(
856 IMXWriter *iface,
857 UINT iTInfo, LCID lcid,
858 ITypeInfo** ppTInfo )
860 mxwriter *This = impl_from_IMXWriter( iface );
861 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
862 iTInfo, lcid, ppTInfo);
865 static HRESULT WINAPI mxwriter_GetIDsOfNames(
866 IMXWriter *iface,
867 REFIID riid, LPOLESTR* rgszNames,
868 UINT cNames, LCID lcid, DISPID* rgDispId )
870 mxwriter *This = impl_from_IMXWriter( iface );
871 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
872 riid, rgszNames, cNames, lcid, rgDispId);
875 static HRESULT WINAPI mxwriter_Invoke(
876 IMXWriter *iface,
877 DISPID dispIdMember, REFIID riid, LCID lcid,
878 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
879 EXCEPINFO* pExcepInfo, UINT* puArgErr )
881 mxwriter *This = impl_from_IMXWriter( iface );
882 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
883 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
886 static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
888 mxwriter *This = impl_from_IMXWriter( iface );
889 HRESULT hr;
891 TRACE("(%p)->(%s)\n", This, debugstr_variant(&dest));
893 hr = flush_output_buffer(This);
894 if (FAILED(hr))
895 return hr;
897 switch (V_VT(&dest))
899 case VT_EMPTY:
901 if (This->dest) IStream_Release(This->dest);
902 This->dest = NULL;
903 reset_output_buffer(This);
904 break;
906 case VT_UNKNOWN:
908 IStream *stream;
910 hr = IUnknown_QueryInterface(V_UNKNOWN(&dest), &IID_IStream, (void**)&stream);
911 if (hr == S_OK)
913 /* Recreate the output buffer to make sure it's using the correct encoding. */
914 reset_output_buffer(This);
916 if (This->dest) IStream_Release(This->dest);
917 This->dest = stream;
918 break;
921 FIXME("unhandled interface type for VT_UNKNOWN destination\n");
922 return E_NOTIMPL;
924 default:
925 FIXME("unhandled destination type %s\n", debugstr_variant(&dest));
926 return E_NOTIMPL;
929 return S_OK;
932 static HRESULT WINAPI mxwriter_get_output(IMXWriter *iface, VARIANT *dest)
934 mxwriter *This = impl_from_IMXWriter( iface );
936 TRACE("(%p)->(%p)\n", This, dest);
938 if (!dest) return E_POINTER;
940 if (This->dest)
942 /* we only support IStream output so far */
943 V_VT(dest) = VT_UNKNOWN;
944 V_UNKNOWN(dest) = (IUnknown*)This->dest;
945 IStream_AddRef(This->dest);
947 else
949 encoded_buffer *buff;
950 char *dest_ptr;
951 HRESULT hr;
953 hr = flush_output_buffer(This);
954 if (FAILED(hr))
955 return hr;
957 V_VT(dest) = VT_BSTR;
958 V_BSTR(dest) = SysAllocStringLen(NULL, This->buffer.utf16_total / sizeof(WCHAR));
959 if (!V_BSTR(dest))
960 return E_OUTOFMEMORY;
962 dest_ptr = (char*)V_BSTR(dest);
963 buff = &This->buffer.encoded;
965 if (buff->written)
967 memcpy(dest_ptr, buff->data, buff->written);
968 dest_ptr += buff->written;
971 LIST_FOR_EACH_ENTRY(buff, &This->buffer.blocks, encoded_buffer, entry)
973 memcpy(dest_ptr, buff->data, buff->written);
974 dest_ptr += buff->written;
978 return S_OK;
981 static HRESULT WINAPI mxwriter_put_encoding(IMXWriter *iface, BSTR encoding)
983 mxwriter *This = impl_from_IMXWriter( iface );
984 xml_encoding enc;
985 HRESULT hr;
987 TRACE("(%p)->(%s)\n", This, debugstr_w(encoding));
989 enc = parse_encoding_name(encoding);
990 if (enc == XmlEncoding_Unknown)
992 FIXME("unsupported encoding %s\n", debugstr_w(encoding));
993 return E_INVALIDARG;
996 hr = flush_output_buffer(This);
997 if (FAILED(hr))
998 return hr;
1000 SysReAllocString(&This->encoding, encoding);
1001 This->xml_enc = enc;
1003 TRACE("got encoding %d\n", This->xml_enc);
1004 reset_output_buffer(This);
1005 return S_OK;
1008 static HRESULT WINAPI mxwriter_get_encoding(IMXWriter *iface, BSTR *encoding)
1010 mxwriter *This = impl_from_IMXWriter( iface );
1012 TRACE("(%p)->(%p)\n", This, encoding);
1014 if (!encoding) return E_POINTER;
1016 *encoding = SysAllocString(This->encoding);
1017 if (!*encoding) return E_OUTOFMEMORY;
1019 return S_OK;
1022 static HRESULT WINAPI mxwriter_put_byteOrderMark(IMXWriter *iface, VARIANT_BOOL value)
1024 mxwriter *This = impl_from_IMXWriter( iface );
1026 TRACE("(%p)->(%d)\n", This, value);
1027 return writer_set_property(This, MXWriter_BOM, value);
1030 static HRESULT WINAPI mxwriter_get_byteOrderMark(IMXWriter *iface, VARIANT_BOOL *value)
1032 mxwriter *This = impl_from_IMXWriter( iface );
1034 TRACE("(%p)->(%p)\n", This, value);
1035 return writer_get_property(This, MXWriter_BOM, value);
1038 static HRESULT WINAPI mxwriter_put_indent(IMXWriter *iface, VARIANT_BOOL value)
1040 mxwriter *This = impl_from_IMXWriter( iface );
1042 TRACE("(%p)->(%d)\n", This, value);
1043 return writer_set_property(This, MXWriter_Indent, value);
1046 static HRESULT WINAPI mxwriter_get_indent(IMXWriter *iface, VARIANT_BOOL *value)
1048 mxwriter *This = impl_from_IMXWriter( iface );
1050 TRACE("(%p)->(%p)\n", This, value);
1051 return writer_get_property(This, MXWriter_Indent, value);
1054 static HRESULT WINAPI mxwriter_put_standalone(IMXWriter *iface, VARIANT_BOOL value)
1056 mxwriter *This = impl_from_IMXWriter( iface );
1058 TRACE("(%p)->(%d)\n", This, value);
1059 return writer_set_property(This, MXWriter_Standalone, value);
1062 static HRESULT WINAPI mxwriter_get_standalone(IMXWriter *iface, VARIANT_BOOL *value)
1064 mxwriter *This = impl_from_IMXWriter( iface );
1066 TRACE("(%p)->(%p)\n", This, value);
1067 return writer_get_property(This, MXWriter_Standalone, value);
1070 static HRESULT WINAPI mxwriter_put_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL value)
1072 mxwriter *This = impl_from_IMXWriter( iface );
1074 TRACE("(%p)->(%d)\n", This, value);
1075 return writer_set_property(This, MXWriter_OmitXmlDecl, value);
1078 static HRESULT WINAPI mxwriter_get_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL *value)
1080 mxwriter *This = impl_from_IMXWriter( iface );
1082 TRACE("(%p)->(%p)\n", This, value);
1083 return writer_get_property(This, MXWriter_OmitXmlDecl, value);
1086 static HRESULT WINAPI mxwriter_put_version(IMXWriter *iface, BSTR version)
1088 mxwriter *This = impl_from_IMXWriter( iface );
1090 TRACE("(%p)->(%s)\n", This, debugstr_w(version));
1092 if (!version) return E_INVALIDARG;
1094 SysFreeString(This->version);
1095 This->version = SysAllocString(version);
1097 return S_OK;
1100 static HRESULT WINAPI mxwriter_get_version(IMXWriter *iface, BSTR *version)
1102 mxwriter *This = impl_from_IMXWriter( iface );
1104 TRACE("(%p)->(%p)\n", This, version);
1106 if (!version) return E_POINTER;
1108 return return_bstr(This->version, version);
1111 static HRESULT WINAPI mxwriter_put_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL value)
1113 mxwriter *This = impl_from_IMXWriter( iface );
1115 TRACE("(%p)->(%d)\n", This, value);
1116 return writer_set_property(This, MXWriter_DisableEscaping, value);
1119 static HRESULT WINAPI mxwriter_get_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL *value)
1121 mxwriter *This = impl_from_IMXWriter( iface );
1123 TRACE("(%p)->(%p)\n", This, value);
1124 return writer_get_property(This, MXWriter_DisableEscaping, value);
1127 static HRESULT WINAPI mxwriter_flush(IMXWriter *iface)
1129 mxwriter *This = impl_from_IMXWriter( iface );
1130 TRACE("(%p)\n", This);
1131 return flush_output_buffer(This);
1134 static const struct IMXWriterVtbl MXWriterVtbl =
1136 mxwriter_QueryInterface,
1137 mxwriter_AddRef,
1138 mxwriter_Release,
1139 mxwriter_GetTypeInfoCount,
1140 mxwriter_GetTypeInfo,
1141 mxwriter_GetIDsOfNames,
1142 mxwriter_Invoke,
1143 mxwriter_put_output,
1144 mxwriter_get_output,
1145 mxwriter_put_encoding,
1146 mxwriter_get_encoding,
1147 mxwriter_put_byteOrderMark,
1148 mxwriter_get_byteOrderMark,
1149 mxwriter_put_indent,
1150 mxwriter_get_indent,
1151 mxwriter_put_standalone,
1152 mxwriter_get_standalone,
1153 mxwriter_put_omitXMLDeclaration,
1154 mxwriter_get_omitXMLDeclaration,
1155 mxwriter_put_version,
1156 mxwriter_get_version,
1157 mxwriter_put_disableOutputEscaping,
1158 mxwriter_get_disableOutputEscaping,
1159 mxwriter_flush
1162 /*** ISAXContentHandler ***/
1163 static HRESULT WINAPI SAXContentHandler_QueryInterface(
1164 ISAXContentHandler *iface,
1165 REFIID riid,
1166 void **obj)
1168 mxwriter *This = impl_from_ISAXContentHandler( iface );
1169 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1172 static ULONG WINAPI SAXContentHandler_AddRef(ISAXContentHandler *iface)
1174 mxwriter *This = impl_from_ISAXContentHandler( iface );
1175 return IMXWriter_AddRef(&This->IMXWriter_iface);
1178 static ULONG WINAPI SAXContentHandler_Release(ISAXContentHandler *iface)
1180 mxwriter *This = impl_from_ISAXContentHandler( iface );
1181 return IMXWriter_Release(&This->IMXWriter_iface);
1184 static HRESULT WINAPI SAXContentHandler_putDocumentLocator(
1185 ISAXContentHandler *iface,
1186 ISAXLocator *locator)
1188 mxwriter *This = impl_from_ISAXContentHandler( iface );
1189 FIXME("(%p)->(%p)\n", This, locator);
1190 return E_NOTIMPL;
1193 static HRESULT WINAPI SAXContentHandler_startDocument(ISAXContentHandler *iface)
1195 mxwriter *This = impl_from_ISAXContentHandler( iface );
1197 TRACE("(%p)\n", This);
1199 /* If properties have been changed since the last "endDocument" call
1200 * we need to reset the output buffer. If we don't the output buffer
1201 * could end up with multiple XML documents in it, plus this seems to
1202 * be how Windows works.
1204 if (This->prop_changed) {
1205 reset_output_buffer(This);
1206 This->prop_changed = FALSE;
1209 if (This->props[MXWriter_OmitXmlDecl] == VARIANT_TRUE) return S_OK;
1211 write_prolog_buffer(This);
1213 if (This->dest && This->xml_enc == XmlEncoding_UTF16) {
1214 static const char utf16BOM[] = {0xff,0xfe};
1216 if (This->props[MXWriter_BOM] == VARIANT_TRUE)
1217 /* Windows passes a NULL pointer as the pcbWritten parameter and
1218 * ignores any error codes returned from this Write call.
1220 IStream_Write(This->dest, utf16BOM, sizeof(utf16BOM), NULL);
1223 return S_OK;
1226 static HRESULT WINAPI SAXContentHandler_endDocument(ISAXContentHandler *iface)
1228 mxwriter *This = impl_from_ISAXContentHandler( iface );
1229 TRACE("(%p)\n", This);
1230 This->prop_changed = FALSE;
1231 return flush_output_buffer(This);
1234 static HRESULT WINAPI SAXContentHandler_startPrefixMapping(
1235 ISAXContentHandler *iface,
1236 const WCHAR *prefix,
1237 int nprefix,
1238 const WCHAR *uri,
1239 int nuri)
1241 mxwriter *This = impl_from_ISAXContentHandler( iface );
1242 TRACE("(%p)->(%s %s)\n", This, debugstr_wn(prefix, nprefix), debugstr_wn(uri, nuri));
1243 return S_OK;
1246 static HRESULT WINAPI SAXContentHandler_endPrefixMapping(
1247 ISAXContentHandler *iface,
1248 const WCHAR *prefix,
1249 int nprefix)
1251 mxwriter *This = impl_from_ISAXContentHandler( iface );
1252 TRACE("(%p)->(%s)\n", This, debugstr_wn(prefix, nprefix));
1253 return S_OK;
1256 static void mxwriter_write_attribute(mxwriter *writer, const WCHAR *qname, int qname_len,
1257 const WCHAR *value, int value_len, BOOL escape)
1259 static const WCHAR eqW[] = {'='};
1261 /* space separator in front of every attribute */
1262 write_output_buffer(writer, spaceW, 1);
1263 write_output_buffer(writer, qname, qname_len);
1264 write_output_buffer(writer, eqW, 1);
1266 if (escape)
1268 WCHAR *escaped = get_escaped_string(value, EscapeValue, &value_len);
1269 write_output_buffer_quoted(writer, escaped, value_len);
1270 heap_free(escaped);
1272 else
1273 write_output_buffer_quoted(writer, value, value_len);
1276 static void mxwriter_write_starttag(mxwriter *writer, const WCHAR *qname, int len)
1278 static const WCHAR ltW[] = {'<'};
1280 close_element_starttag(writer);
1281 set_element_name(writer, qname ? qname : emptyW, qname ? len : 0);
1283 write_node_indent(writer);
1285 write_output_buffer(writer, ltW, 1);
1286 write_output_buffer(writer, qname ? qname : emptyW, qname ? len : 0);
1287 writer_inc_indent(writer);
1290 static HRESULT WINAPI SAXContentHandler_startElement(
1291 ISAXContentHandler *iface,
1292 const WCHAR *namespaceUri,
1293 int nnamespaceUri,
1294 const WCHAR *local_name,
1295 int nlocal_name,
1296 const WCHAR *QName,
1297 int nQName,
1298 ISAXAttributes *attr)
1300 mxwriter *This = impl_from_ISAXContentHandler( iface );
1302 TRACE("(%p)->(%s %s %s %p)\n", This, debugstr_wn(namespaceUri, nnamespaceUri),
1303 debugstr_wn(local_name, nlocal_name), debugstr_wn(QName, nQName), attr);
1305 if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1306 (nQName == -1 && This->class_version == MSXML6))
1307 return E_INVALIDARG;
1309 mxwriter_write_starttag(This, QName, nQName);
1311 if (attr)
1313 int length, i, escape;
1314 HRESULT hr;
1316 hr = ISAXAttributes_getLength(attr, &length);
1317 if (FAILED(hr)) return hr;
1319 escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
1320 (This->class_version == MSXML4 || This->class_version == MSXML6);
1322 for (i = 0; i < length; i++)
1324 int qname_len = 0, value_len = 0;
1325 const WCHAR *qname, *value;
1327 hr = ISAXAttributes_getQName(attr, i, &qname, &qname_len);
1328 if (FAILED(hr)) return hr;
1330 hr = ISAXAttributes_getValue(attr, i, &value, &value_len);
1331 if (FAILED(hr)) return hr;
1333 mxwriter_write_attribute(This, qname, qname_len, value, value_len, escape);
1337 return S_OK;
1340 static HRESULT WINAPI SAXContentHandler_endElement(
1341 ISAXContentHandler *iface,
1342 const WCHAR *namespaceUri,
1343 int nnamespaceUri,
1344 const WCHAR * local_name,
1345 int nlocal_name,
1346 const WCHAR *QName,
1347 int nQName)
1349 mxwriter *This = impl_from_ISAXContentHandler( iface );
1351 TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(namespaceUri, nnamespaceUri), nnamespaceUri,
1352 debugstr_wn(local_name, nlocal_name), nlocal_name, debugstr_wn(QName, nQName), nQName);
1354 if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1355 (nQName == -1 && This->class_version == MSXML6))
1356 return E_INVALIDARG;
1358 writer_dec_indent(This);
1360 if (This->element)
1362 static const WCHAR closeW[] = {'/','>'};
1363 write_output_buffer(This, closeW, 2);
1365 else
1367 static const WCHAR closetagW[] = {'<','/'};
1368 static const WCHAR gtW[] = {'>'};
1370 write_node_indent(This);
1371 write_output_buffer(This, closetagW, 2);
1372 write_output_buffer(This, QName, nQName);
1373 write_output_buffer(This, gtW, 1);
1376 set_element_name(This, NULL, 0);
1378 return S_OK;
1381 static HRESULT WINAPI SAXContentHandler_characters(
1382 ISAXContentHandler *iface,
1383 const WCHAR *chars,
1384 int nchars)
1386 mxwriter *This = impl_from_ISAXContentHandler( iface );
1388 TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1390 if (!chars) return E_INVALIDARG;
1392 close_element_starttag(This);
1393 set_element_name(This, NULL, 0);
1395 if (!This->cdata)
1396 This->text = TRUE;
1398 if (nchars)
1400 if (This->cdata || This->props[MXWriter_DisableEscaping] == VARIANT_TRUE)
1401 write_output_buffer(This, chars, nchars);
1402 else
1404 int len = nchars;
1405 WCHAR *escaped;
1407 escaped = get_escaped_string(chars, EscapeText, &len);
1408 write_output_buffer(This, escaped, len);
1409 heap_free(escaped);
1413 return S_OK;
1416 static HRESULT WINAPI SAXContentHandler_ignorableWhitespace(
1417 ISAXContentHandler *iface,
1418 const WCHAR *chars,
1419 int nchars)
1421 mxwriter *This = impl_from_ISAXContentHandler( iface );
1423 TRACE("(%p)->(%s)\n", This, debugstr_wn(chars, nchars));
1425 if (!chars) return E_INVALIDARG;
1427 write_output_buffer(This, chars, nchars);
1429 return S_OK;
1432 static HRESULT WINAPI SAXContentHandler_processingInstruction(
1433 ISAXContentHandler *iface,
1434 const WCHAR *target,
1435 int ntarget,
1436 const WCHAR *data,
1437 int ndata)
1439 mxwriter *This = impl_from_ISAXContentHandler( iface );
1440 static const WCHAR openpiW[] = {'<','?'};
1441 static const WCHAR closepiW[] = {'?','>','\r','\n'};
1443 TRACE("(%p)->(%s %s)\n", This, debugstr_wn(target, ntarget), debugstr_wn(data, ndata));
1445 if (!target) return E_INVALIDARG;
1447 write_node_indent(This);
1448 write_output_buffer(This, openpiW, ARRAY_SIZE(openpiW));
1450 if (*target)
1451 write_output_buffer(This, target, ntarget);
1453 if (data && *data && ndata)
1455 write_output_buffer(This, spaceW, 1);
1456 write_output_buffer(This, data, ndata);
1459 write_output_buffer(This, closepiW, ARRAY_SIZE(closepiW));
1460 This->newline = TRUE;
1462 return S_OK;
1465 static HRESULT WINAPI SAXContentHandler_skippedEntity(
1466 ISAXContentHandler *iface,
1467 const WCHAR *name,
1468 int nname)
1470 mxwriter *This = impl_from_ISAXContentHandler( iface );
1471 FIXME("(%p)->(%s)\n", This, debugstr_wn(name, nname));
1472 return E_NOTIMPL;
1475 static const struct ISAXContentHandlerVtbl SAXContentHandlerVtbl =
1477 SAXContentHandler_QueryInterface,
1478 SAXContentHandler_AddRef,
1479 SAXContentHandler_Release,
1480 SAXContentHandler_putDocumentLocator,
1481 SAXContentHandler_startDocument,
1482 SAXContentHandler_endDocument,
1483 SAXContentHandler_startPrefixMapping,
1484 SAXContentHandler_endPrefixMapping,
1485 SAXContentHandler_startElement,
1486 SAXContentHandler_endElement,
1487 SAXContentHandler_characters,
1488 SAXContentHandler_ignorableWhitespace,
1489 SAXContentHandler_processingInstruction,
1490 SAXContentHandler_skippedEntity
1493 /*** ISAXLexicalHandler ***/
1494 static HRESULT WINAPI SAXLexicalHandler_QueryInterface(ISAXLexicalHandler *iface,
1495 REFIID riid, void **obj)
1497 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1498 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1501 static ULONG WINAPI SAXLexicalHandler_AddRef(ISAXLexicalHandler *iface)
1503 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1504 return IMXWriter_AddRef(&This->IMXWriter_iface);
1507 static ULONG WINAPI SAXLexicalHandler_Release(ISAXLexicalHandler *iface)
1509 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1510 return IMXWriter_Release(&This->IMXWriter_iface);
1513 static HRESULT WINAPI SAXLexicalHandler_startDTD(ISAXLexicalHandler *iface,
1514 const WCHAR *name, int name_len, const WCHAR *publicId, int publicId_len,
1515 const WCHAR *systemId, int systemId_len)
1517 static const WCHAR doctypeW[] = {'<','!','D','O','C','T','Y','P','E',' '};
1518 static const WCHAR openintW[] = {'[','\r','\n'};
1520 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1522 TRACE("(%p)->(%s %s %s)\n", This, debugstr_wn(name, name_len), debugstr_wn(publicId, publicId_len),
1523 debugstr_wn(systemId, systemId_len));
1525 if (!name) return E_INVALIDARG;
1527 write_output_buffer(This, doctypeW, ARRAY_SIZE(doctypeW));
1529 if (*name)
1531 write_output_buffer(This, name, name_len);
1532 write_output_buffer(This, spaceW, 1);
1535 if (publicId)
1537 write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
1538 write_output_buffer_quoted(This, publicId, publicId_len);
1540 if (!systemId) return E_INVALIDARG;
1542 if (*publicId)
1543 write_output_buffer(This, spaceW, 1);
1545 write_output_buffer_quoted(This, systemId, systemId_len);
1547 if (*systemId)
1548 write_output_buffer(This, spaceW, 1);
1550 else if (systemId)
1552 write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
1553 write_output_buffer_quoted(This, systemId, systemId_len);
1554 if (*systemId)
1555 write_output_buffer(This, spaceW, 1);
1558 write_output_buffer(This, openintW, ARRAY_SIZE(openintW));
1560 return S_OK;
1563 static HRESULT WINAPI SAXLexicalHandler_endDTD(ISAXLexicalHandler *iface)
1565 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1566 static const WCHAR closedtdW[] = {']','>','\r','\n'};
1568 TRACE("(%p)\n", This);
1570 write_output_buffer(This, closedtdW, ARRAY_SIZE(closedtdW));
1572 return S_OK;
1575 static HRESULT WINAPI SAXLexicalHandler_startEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1577 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1578 FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1579 return E_NOTIMPL;
1582 static HRESULT WINAPI SAXLexicalHandler_endEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1584 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1585 FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1586 return E_NOTIMPL;
1589 static HRESULT WINAPI SAXLexicalHandler_startCDATA(ISAXLexicalHandler *iface)
1591 static const WCHAR scdataW[] = {'<','!','[','C','D','A','T','A','['};
1592 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1594 TRACE("(%p)\n", This);
1596 write_node_indent(This);
1597 write_output_buffer(This, scdataW, ARRAY_SIZE(scdataW));
1598 This->cdata = TRUE;
1600 return S_OK;
1603 static HRESULT WINAPI SAXLexicalHandler_endCDATA(ISAXLexicalHandler *iface)
1605 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1606 static const WCHAR ecdataW[] = {']',']','>'};
1608 TRACE("(%p)\n", This);
1610 write_output_buffer(This, ecdataW, ARRAY_SIZE(ecdataW));
1611 This->cdata = FALSE;
1613 return S_OK;
1616 static HRESULT WINAPI SAXLexicalHandler_comment(ISAXLexicalHandler *iface, const WCHAR *chars, int nchars)
1618 mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1619 static const WCHAR copenW[] = {'<','!','-','-'};
1620 static const WCHAR ccloseW[] = {'-','-','>','\r','\n'};
1622 TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1624 if (!chars) return E_INVALIDARG;
1626 close_element_starttag(This);
1627 write_node_indent(This);
1629 write_output_buffer(This, copenW, ARRAY_SIZE(copenW));
1630 if (nchars)
1631 write_output_buffer(This, chars, nchars);
1632 write_output_buffer(This, ccloseW, ARRAY_SIZE(ccloseW));
1634 return S_OK;
1637 static const struct ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl =
1639 SAXLexicalHandler_QueryInterface,
1640 SAXLexicalHandler_AddRef,
1641 SAXLexicalHandler_Release,
1642 SAXLexicalHandler_startDTD,
1643 SAXLexicalHandler_endDTD,
1644 SAXLexicalHandler_startEntity,
1645 SAXLexicalHandler_endEntity,
1646 SAXLexicalHandler_startCDATA,
1647 SAXLexicalHandler_endCDATA,
1648 SAXLexicalHandler_comment
1651 /*** ISAXDeclHandler ***/
1652 static HRESULT WINAPI SAXDeclHandler_QueryInterface(ISAXDeclHandler *iface,
1653 REFIID riid, void **obj)
1655 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1656 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1659 static ULONG WINAPI SAXDeclHandler_AddRef(ISAXDeclHandler *iface)
1661 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1662 return IMXWriter_AddRef(&This->IMXWriter_iface);
1665 static ULONG WINAPI SAXDeclHandler_Release(ISAXDeclHandler *iface)
1667 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1668 return IMXWriter_Release(&This->IMXWriter_iface);
1671 static HRESULT WINAPI SAXDeclHandler_elementDecl(ISAXDeclHandler *iface,
1672 const WCHAR *name, int n_name, const WCHAR *model, int n_model)
1674 static const WCHAR elementW[] = {'<','!','E','L','E','M','E','N','T',' '};
1675 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1677 TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1678 debugstr_wn(model, n_model), n_model);
1680 if (!name || !model) return E_INVALIDARG;
1682 write_output_buffer(This, elementW, ARRAY_SIZE(elementW));
1683 if (n_name) {
1684 write_output_buffer(This, name, n_name);
1685 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1687 if (n_model)
1688 write_output_buffer(This, model, n_model);
1689 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1691 return S_OK;
1694 static HRESULT WINAPI SAXDeclHandler_attributeDecl(ISAXDeclHandler *iface,
1695 const WCHAR *element, int n_element, const WCHAR *attr, int n_attr,
1696 const WCHAR *type, int n_type, const WCHAR *Default, int n_default,
1697 const WCHAR *value, int n_value)
1699 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1700 static const WCHAR attlistW[] = {'<','!','A','T','T','L','I','S','T',' '};
1701 static const WCHAR closetagW[] = {'>','\r','\n'};
1703 TRACE("(%p)->(%s:%d %s:%d %s:%d %s:%d %s:%d)\n", This, debugstr_wn(element, n_element), n_element,
1704 debugstr_wn(attr, n_attr), n_attr, debugstr_wn(type, n_type), n_type, debugstr_wn(Default, n_default), n_default,
1705 debugstr_wn(value, n_value), n_value);
1707 write_output_buffer(This, attlistW, ARRAY_SIZE(attlistW));
1708 if (n_element) {
1709 write_output_buffer(This, element, n_element);
1710 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1713 if (n_attr) {
1714 write_output_buffer(This, attr, n_attr);
1715 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1718 if (n_type) {
1719 write_output_buffer(This, type, n_type);
1720 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1723 if (n_default) {
1724 write_output_buffer(This, Default, n_default);
1725 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1728 if (n_value)
1729 write_output_buffer_quoted(This, value, n_value);
1731 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1733 return S_OK;
1736 static HRESULT WINAPI SAXDeclHandler_internalEntityDecl(ISAXDeclHandler *iface,
1737 const WCHAR *name, int n_name, const WCHAR *value, int n_value)
1739 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1741 TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1742 debugstr_wn(value, n_value), n_value);
1744 if (!name || !value) return E_INVALIDARG;
1746 write_output_buffer(This, entityW, ARRAY_SIZE(entityW));
1747 if (n_name) {
1748 write_output_buffer(This, name, n_name);
1749 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1752 if (n_value)
1753 write_output_buffer_quoted(This, value, n_value);
1755 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1757 return S_OK;
1760 static HRESULT WINAPI SAXDeclHandler_externalEntityDecl(ISAXDeclHandler *iface,
1761 const WCHAR *name, int n_name, const WCHAR *publicId, int n_publicId,
1762 const WCHAR *systemId, int n_systemId)
1764 mxwriter *This = impl_from_ISAXDeclHandler( iface );
1766 TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1767 debugstr_wn(publicId, n_publicId), n_publicId, debugstr_wn(systemId, n_systemId), n_systemId);
1769 if (!name || !systemId) return E_INVALIDARG;
1771 write_output_buffer(This, entityW, ARRAY_SIZE(entityW));
1772 if (n_name) {
1773 write_output_buffer(This, name, n_name);
1774 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1777 if (publicId)
1779 write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
1780 write_output_buffer_quoted(This, publicId, n_publicId);
1781 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1782 write_output_buffer_quoted(This, systemId, n_systemId);
1784 else
1786 write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
1787 write_output_buffer_quoted(This, systemId, n_systemId);
1790 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1792 return S_OK;
1795 static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl = {
1796 SAXDeclHandler_QueryInterface,
1797 SAXDeclHandler_AddRef,
1798 SAXDeclHandler_Release,
1799 SAXDeclHandler_elementDecl,
1800 SAXDeclHandler_attributeDecl,
1801 SAXDeclHandler_internalEntityDecl,
1802 SAXDeclHandler_externalEntityDecl
1805 /*** IVBSAXDeclHandler ***/
1806 static HRESULT WINAPI VBSAXDeclHandler_QueryInterface(IVBSAXDeclHandler *iface,
1807 REFIID riid, void **obj)
1809 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1810 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1813 static ULONG WINAPI VBSAXDeclHandler_AddRef(IVBSAXDeclHandler *iface)
1815 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1816 return IMXWriter_AddRef(&This->IMXWriter_iface);
1819 static ULONG WINAPI VBSAXDeclHandler_Release(IVBSAXDeclHandler *iface)
1821 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1822 return IMXWriter_Release(&This->IMXWriter_iface);
1825 static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfoCount(IVBSAXDeclHandler *iface, UINT* pctinfo)
1827 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1828 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1831 static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfo(IVBSAXDeclHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1833 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1834 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1837 static HRESULT WINAPI VBSAXDeclHandler_GetIDsOfNames(IVBSAXDeclHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1838 UINT cNames, LCID lcid, DISPID* rgDispId )
1840 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1841 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1844 static HRESULT WINAPI VBSAXDeclHandler_Invoke(IVBSAXDeclHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1845 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1847 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1848 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1849 pExcepInfo, puArgErr);
1852 static HRESULT WINAPI VBSAXDeclHandler_elementDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *model)
1854 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1856 TRACE("(%p)->(%p %p)\n", This, name, model);
1858 if (!name || !model)
1859 return E_POINTER;
1861 return ISAXDeclHandler_elementDecl(&This->ISAXDeclHandler_iface, *name, -1, *model, -1);
1864 static HRESULT WINAPI VBSAXDeclHandler_attributeDecl(IVBSAXDeclHandler *iface,
1865 BSTR *element, BSTR *attr, BSTR *type, BSTR *default_value, BSTR *value)
1867 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1869 TRACE("(%p)->(%p %p %p %p %p)\n", This, element, attr, type, default_value, value);
1871 if (!element || !attr || !type || !default_value || !value)
1872 return E_POINTER;
1874 return ISAXDeclHandler_attributeDecl(&This->ISAXDeclHandler_iface, *element, -1, *attr, -1, *type, -1,
1875 *default_value, -1, *value, -1);
1878 static HRESULT WINAPI VBSAXDeclHandler_internalEntityDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *value)
1880 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1882 TRACE("(%p)->(%p %p)\n", This, name, value);
1884 if (!name || !value)
1885 return E_POINTER;
1887 return ISAXDeclHandler_internalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *value, -1);
1890 static HRESULT WINAPI VBSAXDeclHandler_externalEntityDecl(IVBSAXDeclHandler *iface,
1891 BSTR *name, BSTR *publicid, BSTR *systemid)
1893 mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1895 TRACE("(%p)->(%p %p %p)\n", This, name, publicid, systemid);
1897 if (!name || !publicid || !systemid)
1898 return E_POINTER;
1900 return ISAXDeclHandler_externalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *publicid, -1, *systemid, -1);
1903 static const IVBSAXDeclHandlerVtbl VBSAXDeclHandlerVtbl = {
1904 VBSAXDeclHandler_QueryInterface,
1905 VBSAXDeclHandler_AddRef,
1906 VBSAXDeclHandler_Release,
1907 VBSAXDeclHandler_GetTypeInfoCount,
1908 VBSAXDeclHandler_GetTypeInfo,
1909 VBSAXDeclHandler_GetIDsOfNames,
1910 VBSAXDeclHandler_Invoke,
1911 VBSAXDeclHandler_elementDecl,
1912 VBSAXDeclHandler_attributeDecl,
1913 VBSAXDeclHandler_internalEntityDecl,
1914 VBSAXDeclHandler_externalEntityDecl
1917 /*** IVBSAXLexicalHandler ***/
1918 static HRESULT WINAPI VBSAXLexicalHandler_QueryInterface(IVBSAXLexicalHandler *iface,
1919 REFIID riid, void **obj)
1921 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1922 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1925 static ULONG WINAPI VBSAXLexicalHandler_AddRef(IVBSAXLexicalHandler *iface)
1927 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1928 return IMXWriter_AddRef(&This->IMXWriter_iface);
1931 static ULONG WINAPI VBSAXLexicalHandler_Release(IVBSAXLexicalHandler *iface)
1933 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1934 return IMXWriter_Release(&This->IMXWriter_iface);
1937 static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfoCount(IVBSAXLexicalHandler *iface, UINT* pctinfo)
1939 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1940 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1943 static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfo(IVBSAXLexicalHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1945 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1946 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1949 static HRESULT WINAPI VBSAXLexicalHandler_GetIDsOfNames(IVBSAXLexicalHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1950 UINT cNames, LCID lcid, DISPID* rgDispId )
1952 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1953 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1956 static HRESULT WINAPI VBSAXLexicalHandler_Invoke(IVBSAXLexicalHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1957 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1959 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1960 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1961 pExcepInfo, puArgErr);
1964 static HRESULT WINAPI VBSAXLexicalHandler_startDTD(IVBSAXLexicalHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
1966 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1968 TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
1970 if (!name || !publicId || !systemId)
1971 return E_POINTER;
1973 return ISAXLexicalHandler_startDTD(&This->ISAXLexicalHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
1976 static HRESULT WINAPI VBSAXLexicalHandler_endDTD(IVBSAXLexicalHandler *iface)
1978 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1979 return ISAXLexicalHandler_endDTD(&This->ISAXLexicalHandler_iface);
1982 static HRESULT WINAPI VBSAXLexicalHandler_startEntity(IVBSAXLexicalHandler *iface, BSTR *name)
1984 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1986 TRACE("(%p)->(%p)\n", This, name);
1988 if (!name)
1989 return E_POINTER;
1991 return ISAXLexicalHandler_startEntity(&This->ISAXLexicalHandler_iface, *name, -1);
1994 static HRESULT WINAPI VBSAXLexicalHandler_endEntity(IVBSAXLexicalHandler *iface, BSTR *name)
1996 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1998 TRACE("(%p)->(%p)\n", This, name);
2000 if (!name)
2001 return E_POINTER;
2003 return ISAXLexicalHandler_endEntity(&This->ISAXLexicalHandler_iface, *name, -1);
2006 static HRESULT WINAPI VBSAXLexicalHandler_startCDATA(IVBSAXLexicalHandler *iface)
2008 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2009 return ISAXLexicalHandler_startCDATA(&This->ISAXLexicalHandler_iface);
2012 static HRESULT WINAPI VBSAXLexicalHandler_endCDATA(IVBSAXLexicalHandler *iface)
2014 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2015 return ISAXLexicalHandler_endCDATA(&This->ISAXLexicalHandler_iface);
2018 static HRESULT WINAPI VBSAXLexicalHandler_comment(IVBSAXLexicalHandler *iface, BSTR *chars)
2020 mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2022 TRACE("(%p)->(%p)\n", This, chars);
2024 if (!chars)
2025 return E_POINTER;
2027 return ISAXLexicalHandler_comment(&This->ISAXLexicalHandler_iface, *chars, -1);
2030 static const IVBSAXLexicalHandlerVtbl VBSAXLexicalHandlerVtbl = {
2031 VBSAXLexicalHandler_QueryInterface,
2032 VBSAXLexicalHandler_AddRef,
2033 VBSAXLexicalHandler_Release,
2034 VBSAXLexicalHandler_GetTypeInfoCount,
2035 VBSAXLexicalHandler_GetTypeInfo,
2036 VBSAXLexicalHandler_GetIDsOfNames,
2037 VBSAXLexicalHandler_Invoke,
2038 VBSAXLexicalHandler_startDTD,
2039 VBSAXLexicalHandler_endDTD,
2040 VBSAXLexicalHandler_startEntity,
2041 VBSAXLexicalHandler_endEntity,
2042 VBSAXLexicalHandler_startCDATA,
2043 VBSAXLexicalHandler_endCDATA,
2044 VBSAXLexicalHandler_comment
2047 /*** IVBSAXContentHandler ***/
2048 static HRESULT WINAPI VBSAXContentHandler_QueryInterface(IVBSAXContentHandler *iface, REFIID riid, void **obj)
2050 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2051 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2054 static ULONG WINAPI VBSAXContentHandler_AddRef(IVBSAXContentHandler *iface)
2056 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2057 return IMXWriter_AddRef(&This->IMXWriter_iface);
2060 static ULONG WINAPI VBSAXContentHandler_Release(IVBSAXContentHandler *iface)
2062 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2063 return IMXWriter_Release(&This->IMXWriter_iface);
2066 static HRESULT WINAPI VBSAXContentHandler_GetTypeInfoCount(IVBSAXContentHandler *iface, UINT* pctinfo)
2068 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2069 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2072 static HRESULT WINAPI VBSAXContentHandler_GetTypeInfo(IVBSAXContentHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2074 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2075 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2078 static HRESULT WINAPI VBSAXContentHandler_GetIDsOfNames(IVBSAXContentHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2079 UINT cNames, LCID lcid, DISPID* rgDispId )
2081 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2082 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2085 static HRESULT WINAPI VBSAXContentHandler_Invoke(IVBSAXContentHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2086 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2088 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2089 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2090 pExcepInfo, puArgErr);
2093 static HRESULT WINAPI VBSAXContentHandler_putref_documentLocator(IVBSAXContentHandler *iface, IVBSAXLocator *locator)
2095 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2096 TRACE("(%p)->(%p)\n", This, locator);
2097 return S_OK;
2100 static HRESULT WINAPI VBSAXContentHandler_startDocument(IVBSAXContentHandler *iface)
2102 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2103 return ISAXContentHandler_startDocument(&This->ISAXContentHandler_iface);
2106 static HRESULT WINAPI VBSAXContentHandler_endDocument(IVBSAXContentHandler *iface)
2108 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2109 return ISAXContentHandler_endDocument(&This->ISAXContentHandler_iface);
2112 static HRESULT WINAPI VBSAXContentHandler_startPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix, BSTR *uri)
2114 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2116 TRACE("(%p)->(%p %p)\n", This, prefix, uri);
2118 if (!prefix || !uri)
2119 return E_POINTER;
2121 return ISAXContentHandler_startPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1, *uri, -1);
2124 static HRESULT WINAPI VBSAXContentHandler_endPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix)
2126 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2128 TRACE("(%p)->(%p)\n", This, prefix);
2130 if (!prefix)
2131 return E_POINTER;
2133 return ISAXContentHandler_endPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1);
2136 static HRESULT WINAPI VBSAXContentHandler_startElement(IVBSAXContentHandler *iface,
2137 BSTR *namespaceURI, BSTR *localName, BSTR *QName, IVBSAXAttributes *attrs)
2139 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2141 TRACE("(%p)->(%p %p %p %p)\n", This, namespaceURI, localName, QName, attrs);
2143 if (!namespaceURI || !localName || !QName)
2144 return E_POINTER;
2146 TRACE("(%s %s %s)\n", debugstr_w(*namespaceURI), debugstr_w(*localName), debugstr_w(*QName));
2148 mxwriter_write_starttag(This, *QName, SysStringLen(*QName));
2150 if (attrs)
2152 int length, i, escape;
2153 HRESULT hr;
2155 hr = IVBSAXAttributes_get_length(attrs, &length);
2156 if (FAILED(hr)) return hr;
2158 escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
2159 (This->class_version == MSXML4 || This->class_version == MSXML6);
2161 for (i = 0; i < length; i++)
2163 BSTR qname, value;
2165 hr = IVBSAXAttributes_getQName(attrs, i, &qname);
2166 if (FAILED(hr)) return hr;
2168 hr = IVBSAXAttributes_getValue(attrs, i, &value);
2169 if (FAILED(hr))
2171 SysFreeString(qname);
2172 return hr;
2175 mxwriter_write_attribute(This, qname, SysStringLen(qname), value, SysStringLen(value), escape);
2176 SysFreeString(qname);
2177 SysFreeString(value);
2181 return S_OK;
2184 static HRESULT WINAPI VBSAXContentHandler_endElement(IVBSAXContentHandler *iface, BSTR *namespaceURI,
2185 BSTR *localName, BSTR *QName)
2187 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2189 TRACE("(%p)->(%p %p %p)\n", This, namespaceURI, localName, QName);
2191 if (!namespaceURI || !localName || !QName)
2192 return E_POINTER;
2194 return ISAXContentHandler_endElement(&This->ISAXContentHandler_iface,
2195 *namespaceURI, SysStringLen(*namespaceURI),
2196 *localName, SysStringLen(*localName),
2197 *QName, SysStringLen(*QName));
2200 static HRESULT WINAPI VBSAXContentHandler_characters(IVBSAXContentHandler *iface, BSTR *chars)
2202 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2204 TRACE("(%p)->(%p)\n", This, chars);
2206 if (!chars)
2207 return E_POINTER;
2209 return ISAXContentHandler_characters(&This->ISAXContentHandler_iface, *chars, SysStringLen(*chars));
2212 static HRESULT WINAPI VBSAXContentHandler_ignorableWhitespace(IVBSAXContentHandler *iface, BSTR *chars)
2214 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2216 TRACE("(%p)->(%p)\n", This, chars);
2218 if (!chars)
2219 return E_POINTER;
2221 return ISAXContentHandler_ignorableWhitespace(&This->ISAXContentHandler_iface, *chars, -1);
2224 static HRESULT WINAPI VBSAXContentHandler_processingInstruction(IVBSAXContentHandler *iface,
2225 BSTR *target, BSTR *data)
2227 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2229 TRACE("(%p)->(%p %p)\n", This, target, data);
2231 if (!target || !data)
2232 return E_POINTER;
2234 return ISAXContentHandler_processingInstruction(&This->ISAXContentHandler_iface, *target, -1, *data, -1);
2237 static HRESULT WINAPI VBSAXContentHandler_skippedEntity(IVBSAXContentHandler *iface, BSTR *name)
2239 mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2241 TRACE("(%p)->(%p)\n", This, name);
2243 if (!name)
2244 return E_POINTER;
2246 return ISAXContentHandler_skippedEntity(&This->ISAXContentHandler_iface, *name, -1);
2249 static const IVBSAXContentHandlerVtbl VBSAXContentHandlerVtbl = {
2250 VBSAXContentHandler_QueryInterface,
2251 VBSAXContentHandler_AddRef,
2252 VBSAXContentHandler_Release,
2253 VBSAXContentHandler_GetTypeInfoCount,
2254 VBSAXContentHandler_GetTypeInfo,
2255 VBSAXContentHandler_GetIDsOfNames,
2256 VBSAXContentHandler_Invoke,
2257 VBSAXContentHandler_putref_documentLocator,
2258 VBSAXContentHandler_startDocument,
2259 VBSAXContentHandler_endDocument,
2260 VBSAXContentHandler_startPrefixMapping,
2261 VBSAXContentHandler_endPrefixMapping,
2262 VBSAXContentHandler_startElement,
2263 VBSAXContentHandler_endElement,
2264 VBSAXContentHandler_characters,
2265 VBSAXContentHandler_ignorableWhitespace,
2266 VBSAXContentHandler_processingInstruction,
2267 VBSAXContentHandler_skippedEntity
2270 static HRESULT WINAPI SAXDTDHandler_QueryInterface(ISAXDTDHandler *iface, REFIID riid, void **obj)
2272 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2273 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2276 static ULONG WINAPI SAXDTDHandler_AddRef(ISAXDTDHandler *iface)
2278 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2279 return IMXWriter_AddRef(&This->IMXWriter_iface);
2282 static ULONG WINAPI SAXDTDHandler_Release(ISAXDTDHandler *iface)
2284 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2285 return IMXWriter_Release(&This->IMXWriter_iface);
2288 static HRESULT WINAPI SAXDTDHandler_notationDecl(ISAXDTDHandler *iface,
2289 const WCHAR *name, INT n_name,
2290 const WCHAR *publicid, INT n_publicid,
2291 const WCHAR *systemid, INT n_systemid)
2293 static const WCHAR notationW[] = {'<','!','N','O','T','A','T','I','O','N',' '};
2294 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2296 TRACE("(%p)->(%s:%d, %s:%d, %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
2297 debugstr_wn(publicid, n_publicid), n_publicid, debugstr_wn(systemid, n_systemid), n_systemid);
2299 if (!name || !n_name)
2300 return E_INVALIDARG;
2302 write_output_buffer(This, notationW, ARRAY_SIZE(notationW));
2303 write_output_buffer(This, name, n_name);
2305 if (!publicid && !systemid)
2306 return E_INVALIDARG;
2308 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
2309 if (publicid)
2311 write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
2312 write_output_buffer_quoted(This, publicid, n_publicid);
2313 if (systemid)
2315 write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
2316 write_output_buffer_quoted(This, systemid, n_systemid);
2319 else
2321 write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
2322 write_output_buffer_quoted(This, systemid, n_systemid);
2325 write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
2327 return S_OK;
2330 static HRESULT WINAPI SAXDTDHandler_unparsedEntityDecl(ISAXDTDHandler *iface,
2331 const WCHAR *name, INT nname,
2332 const WCHAR *publicid, INT npublicid,
2333 const WCHAR *systemid, INT nsystemid,
2334 const WCHAR *notation, INT nnotation)
2336 mxwriter *This = impl_from_ISAXDTDHandler( iface );
2337 FIXME("(%p)->(%s:%d, %s:%d, %s:%d, %s:%d): stub\n", This, debugstr_wn(name, nname), nname,
2338 debugstr_wn(publicid, npublicid), npublicid, debugstr_wn(systemid, nsystemid), nsystemid,
2339 debugstr_wn(notation, nnotation), nnotation);
2340 return E_NOTIMPL;
2343 static const ISAXDTDHandlerVtbl SAXDTDHandlerVtbl = {
2344 SAXDTDHandler_QueryInterface,
2345 SAXDTDHandler_AddRef,
2346 SAXDTDHandler_Release,
2347 SAXDTDHandler_notationDecl,
2348 SAXDTDHandler_unparsedEntityDecl
2351 /*** IVBSAXDTDHandler ***/
2352 static HRESULT WINAPI VBSAXDTDHandler_QueryInterface(IVBSAXDTDHandler *iface, REFIID riid, void **obj)
2354 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2355 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2358 static ULONG WINAPI VBSAXDTDHandler_AddRef(IVBSAXDTDHandler *iface)
2360 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2361 return IMXWriter_AddRef(&This->IMXWriter_iface);
2364 static ULONG WINAPI VBSAXDTDHandler_Release(IVBSAXDTDHandler *iface)
2366 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2367 return IMXWriter_Release(&This->IMXWriter_iface);
2370 static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfoCount(IVBSAXDTDHandler *iface, UINT* pctinfo)
2372 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2373 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2376 static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfo(IVBSAXDTDHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2378 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2379 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2382 static HRESULT WINAPI VBSAXDTDHandler_GetIDsOfNames(IVBSAXDTDHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2383 UINT cNames, LCID lcid, DISPID* rgDispId )
2385 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2386 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2389 static HRESULT WINAPI VBSAXDTDHandler_Invoke(IVBSAXDTDHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2390 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2392 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2393 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2394 pExcepInfo, puArgErr);
2397 static HRESULT WINAPI VBSAXDTDHandler_notationDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
2399 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2401 TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
2403 if (!name || !publicId || !systemId)
2404 return E_POINTER;
2406 return ISAXDTDHandler_notationDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
2409 static HRESULT WINAPI VBSAXDTDHandler_unparsedEntityDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId,
2410 BSTR *systemId, BSTR *notation)
2412 mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2414 TRACE("(%p)->(%p %p %p %p)\n", This, name, publicId, systemId, notation);
2416 if (!name || !publicId || !systemId || !notation)
2417 return E_POINTER;
2419 return ISAXDTDHandler_unparsedEntityDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1,
2420 *systemId, -1, *notation, -1);
2423 static const IVBSAXDTDHandlerVtbl VBSAXDTDHandlerVtbl = {
2424 VBSAXDTDHandler_QueryInterface,
2425 VBSAXDTDHandler_AddRef,
2426 VBSAXDTDHandler_Release,
2427 VBSAXDTDHandler_GetTypeInfoCount,
2428 VBSAXDTDHandler_GetTypeInfo,
2429 VBSAXDTDHandler_GetIDsOfNames,
2430 VBSAXDTDHandler_Invoke,
2431 VBSAXDTDHandler_notationDecl,
2432 VBSAXDTDHandler_unparsedEntityDecl
2435 /* ISAXErrorHandler */
2436 static HRESULT WINAPI SAXErrorHandler_QueryInterface(ISAXErrorHandler *iface, REFIID riid, void **obj)
2438 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2439 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2442 static ULONG WINAPI SAXErrorHandler_AddRef(ISAXErrorHandler *iface)
2444 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2445 return IMXWriter_AddRef(&This->IMXWriter_iface);
2448 static ULONG WINAPI SAXErrorHandler_Release(ISAXErrorHandler *iface)
2450 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2451 return IMXWriter_Release(&This->IMXWriter_iface);
2454 static HRESULT WINAPI SAXErrorHandler_error(ISAXErrorHandler *iface,
2455 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2457 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2459 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2461 return E_NOTIMPL;
2464 static HRESULT WINAPI SAXErrorHandler_fatalError(ISAXErrorHandler *iface,
2465 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2467 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2469 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2471 return E_NOTIMPL;
2474 static HRESULT WINAPI SAXErrorHandler_ignorableWarning(ISAXErrorHandler *iface,
2475 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2477 mxwriter *This = impl_from_ISAXErrorHandler( iface );
2479 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2481 return E_NOTIMPL;
2484 static const ISAXErrorHandlerVtbl SAXErrorHandlerVtbl = {
2485 SAXErrorHandler_QueryInterface,
2486 SAXErrorHandler_AddRef,
2487 SAXErrorHandler_Release,
2488 SAXErrorHandler_error,
2489 SAXErrorHandler_fatalError,
2490 SAXErrorHandler_ignorableWarning
2493 /*** IVBSAXErrorHandler ***/
2494 static HRESULT WINAPI VBSAXErrorHandler_QueryInterface(IVBSAXErrorHandler *iface, REFIID riid, void **obj)
2496 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2497 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2500 static ULONG WINAPI VBSAXErrorHandler_AddRef(IVBSAXErrorHandler *iface)
2502 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2503 return IMXWriter_AddRef(&This->IMXWriter_iface);
2506 static ULONG WINAPI VBSAXErrorHandler_Release(IVBSAXErrorHandler *iface)
2508 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2509 return IMXWriter_Release(&This->IMXWriter_iface);
2512 static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfoCount(IVBSAXErrorHandler *iface, UINT* pctinfo)
2514 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2515 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2518 static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfo(IVBSAXErrorHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2520 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2521 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2524 static HRESULT WINAPI VBSAXErrorHandler_GetIDsOfNames(IVBSAXErrorHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2525 UINT cNames, LCID lcid, DISPID* rgDispId )
2527 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2528 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2531 static HRESULT WINAPI VBSAXErrorHandler_Invoke(IVBSAXErrorHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2532 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2534 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2535 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2536 pExcepInfo, puArgErr);
2539 static HRESULT WINAPI VBSAXErrorHandler_error(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2541 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2542 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2543 return E_NOTIMPL;
2546 static HRESULT WINAPI VBSAXErrorHandler_fatalError(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2548 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2549 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2550 return E_NOTIMPL;
2553 static HRESULT WINAPI VBSAXErrorHandler_ignorableWarning(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2555 mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2556 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2557 return E_NOTIMPL;
2560 static const IVBSAXErrorHandlerVtbl VBSAXErrorHandlerVtbl = {
2561 VBSAXErrorHandler_QueryInterface,
2562 VBSAXErrorHandler_AddRef,
2563 VBSAXErrorHandler_Release,
2564 VBSAXErrorHandler_GetTypeInfoCount,
2565 VBSAXErrorHandler_GetTypeInfo,
2566 VBSAXErrorHandler_GetIDsOfNames,
2567 VBSAXErrorHandler_Invoke,
2568 VBSAXErrorHandler_error,
2569 VBSAXErrorHandler_fatalError,
2570 VBSAXErrorHandler_ignorableWarning
2573 static const tid_t mxwriter_iface_tids[] = {
2574 IMXWriter_tid,
2578 static dispex_static_data_t mxwriter_dispex = {
2579 NULL,
2580 IMXWriter_tid,
2581 NULL,
2582 mxwriter_iface_tids
2585 HRESULT MXWriter_create(MSXML_VERSION version, void **ppObj)
2587 static const WCHAR version10W[] = {'1','.','0',0};
2588 mxwriter *This;
2589 HRESULT hr;
2591 TRACE("(%p)\n", ppObj);
2593 This = heap_alloc( sizeof (*This) );
2594 if(!This)
2595 return E_OUTOFMEMORY;
2597 This->IMXWriter_iface.lpVtbl = &MXWriterVtbl;
2598 This->ISAXContentHandler_iface.lpVtbl = &SAXContentHandlerVtbl;
2599 This->ISAXLexicalHandler_iface.lpVtbl = &SAXLexicalHandlerVtbl;
2600 This->ISAXDeclHandler_iface.lpVtbl = &SAXDeclHandlerVtbl;
2601 This->ISAXDTDHandler_iface.lpVtbl = &SAXDTDHandlerVtbl;
2602 This->ISAXErrorHandler_iface.lpVtbl = &SAXErrorHandlerVtbl;
2603 This->IVBSAXDeclHandler_iface.lpVtbl = &VBSAXDeclHandlerVtbl;
2604 This->IVBSAXLexicalHandler_iface.lpVtbl = &VBSAXLexicalHandlerVtbl;
2605 This->IVBSAXContentHandler_iface.lpVtbl = &VBSAXContentHandlerVtbl;
2606 This->IVBSAXDTDHandler_iface.lpVtbl = &VBSAXDTDHandlerVtbl;
2607 This->IVBSAXErrorHandler_iface.lpVtbl = &VBSAXErrorHandlerVtbl;
2608 This->ref = 1;
2609 This->class_version = version;
2611 This->props[MXWriter_BOM] = VARIANT_TRUE;
2612 This->props[MXWriter_DisableEscaping] = VARIANT_FALSE;
2613 This->props[MXWriter_Indent] = VARIANT_FALSE;
2614 This->props[MXWriter_OmitXmlDecl] = VARIANT_FALSE;
2615 This->props[MXWriter_Standalone] = VARIANT_FALSE;
2616 This->prop_changed = FALSE;
2617 This->encoding = SysAllocString(utf16W);
2618 This->version = SysAllocString(version10W);
2619 This->xml_enc = XmlEncoding_UTF16;
2621 This->element = NULL;
2622 This->cdata = FALSE;
2623 This->indent = 0;
2624 This->text = FALSE;
2625 This->newline = FALSE;
2627 This->dest = NULL;
2629 hr = init_output_buffer(This->xml_enc, &This->buffer);
2630 if (hr != S_OK) {
2631 SysFreeString(This->encoding);
2632 SysFreeString(This->version);
2633 heap_free(This);
2634 return hr;
2637 init_dispex(&This->dispex, (IUnknown*)&This->IMXWriter_iface, &mxwriter_dispex);
2639 *ppObj = &This->IMXWriter_iface;
2641 TRACE("returning iface %p\n", *ppObj);
2643 return S_OK;
2646 static HRESULT WINAPI MXAttributes_QueryInterface(IMXAttributes *iface, REFIID riid, void **ppObj)
2648 mxattributes *This = impl_from_IMXAttributes( iface );
2650 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppObj);
2652 *ppObj = NULL;
2654 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2655 IsEqualGUID( riid, &IID_IDispatch ) ||
2656 IsEqualGUID( riid, &IID_IMXAttributes ))
2658 *ppObj = iface;
2660 else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
2662 *ppObj = &This->ISAXAttributes_iface;
2664 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
2666 *ppObj = &This->IVBSAXAttributes_iface;
2668 else if (dispex_query_interface(&This->dispex, riid, ppObj))
2670 return *ppObj ? S_OK : E_NOINTERFACE;
2672 else
2674 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2675 return E_NOINTERFACE;
2678 IMXAttributes_AddRef( iface );
2680 return S_OK;
2683 static ULONG WINAPI MXAttributes_AddRef(IMXAttributes *iface)
2685 mxattributes *This = impl_from_IMXAttributes( iface );
2686 ULONG ref = InterlockedIncrement( &This->ref );
2687 TRACE("(%p)->(%d)\n", This, ref );
2688 return ref;
2691 static ULONG WINAPI MXAttributes_Release(IMXAttributes *iface)
2693 mxattributes *This = impl_from_IMXAttributes( iface );
2694 LONG ref = InterlockedDecrement( &This->ref );
2696 TRACE("(%p)->(%d)\n", This, ref);
2698 if (ref == 0)
2700 int i;
2702 for (i = 0; i < This->length; i++)
2704 SysFreeString(This->attr[i].qname);
2705 SysFreeString(This->attr[i].local);
2706 SysFreeString(This->attr[i].uri);
2707 SysFreeString(This->attr[i].type);
2708 SysFreeString(This->attr[i].value);
2711 heap_free(This->attr);
2712 heap_free(This);
2715 return ref;
2718 static HRESULT WINAPI MXAttributes_GetTypeInfoCount(IMXAttributes *iface, UINT* pctinfo)
2720 mxattributes *This = impl_from_IMXAttributes( iface );
2721 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2724 static HRESULT WINAPI MXAttributes_GetTypeInfo(IMXAttributes *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2726 mxattributes *This = impl_from_IMXAttributes( iface );
2727 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2730 static HRESULT WINAPI MXAttributes_GetIDsOfNames(
2731 IMXAttributes *iface,
2732 REFIID riid,
2733 LPOLESTR* rgszNames,
2734 UINT cNames,
2735 LCID lcid,
2736 DISPID* rgDispId)
2738 mxattributes *This = impl_from_IMXAttributes( iface );
2739 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2740 riid, rgszNames, cNames, lcid, rgDispId);
2743 static HRESULT WINAPI MXAttributes_Invoke(
2744 IMXAttributes *iface,
2745 DISPID dispIdMember,
2746 REFIID riid,
2747 LCID lcid,
2748 WORD wFlags,
2749 DISPPARAMS* pDispParams,
2750 VARIANT* pVarResult,
2751 EXCEPINFO* pExcepInfo,
2752 UINT* puArgErr)
2754 mxattributes *This = impl_from_IMXAttributes( iface );
2755 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
2756 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2759 static HRESULT WINAPI MXAttributes_addAttribute(IMXAttributes *iface,
2760 BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2762 mxattributes *This = impl_from_IMXAttributes( iface );
2763 mxattribute *attr;
2764 HRESULT hr;
2766 TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(uri), debugstr_w(localName),
2767 debugstr_w(QName), debugstr_w(type), debugstr_w(value));
2769 if ((!uri || !localName || !QName || !type || !value) && This->class_version != MSXML6)
2770 return E_INVALIDARG;
2772 /* ensure array is large enough */
2773 hr = mxattributes_grow(This);
2774 if (hr != S_OK) return hr;
2776 attr = &This->attr[This->length];
2778 attr->qname = SysAllocString(QName);
2779 attr->local = SysAllocString(localName);
2780 attr->uri = SysAllocString(uri);
2781 attr->type = SysAllocString(type ? type : emptyW);
2782 attr->value = SysAllocString(value);
2783 This->length++;
2785 return S_OK;
2788 static HRESULT WINAPI MXAttributes_addAttributeFromIndex(IMXAttributes *iface,
2789 VARIANT atts, int index)
2791 mxattributes *This = impl_from_IMXAttributes( iface );
2792 FIXME("(%p)->(%s %d): stub\n", This, debugstr_variant(&atts), index);
2793 return E_NOTIMPL;
2796 static HRESULT WINAPI MXAttributes_clear(IMXAttributes *iface)
2798 mxattributes *This = impl_from_IMXAttributes( iface );
2799 int i;
2801 TRACE("(%p)\n", This);
2803 for (i = 0; i < This->length; i++)
2805 SysFreeString(This->attr[i].qname);
2806 SysFreeString(This->attr[i].local);
2807 SysFreeString(This->attr[i].uri);
2808 SysFreeString(This->attr[i].type);
2809 SysFreeString(This->attr[i].value);
2810 memset(&This->attr[i], 0, sizeof(mxattribute));
2813 This->length = 0;
2815 return S_OK;
2818 static mxattribute *get_attribute_byindex(mxattributes *attrs, int index)
2820 if (index < 0 || index >= attrs->length) return NULL;
2821 return &attrs->attr[index];
2824 static HRESULT WINAPI MXAttributes_removeAttribute(IMXAttributes *iface, int index)
2826 mxattributes *This = impl_from_IMXAttributes( iface );
2827 mxattribute *dst;
2829 TRACE("(%p)->(%d)\n", This, index);
2831 if (!(dst = get_attribute_byindex(This, index))) return E_INVALIDARG;
2833 /* no need to remove last attribute, just make it inaccessible */
2834 if (index + 1 == This->length)
2836 This->length--;
2837 return S_OK;
2840 memmove(dst, dst + 1, (This->length-index-1)*sizeof(*dst));
2841 This->length--;
2843 return S_OK;
2846 static HRESULT WINAPI MXAttributes_setAttribute(IMXAttributes *iface, int index,
2847 BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2849 mxattributes *This = impl_from_IMXAttributes( iface );
2850 FIXME("(%p)->(%d %s %s %s %s %s): stub\n", This, index, debugstr_w(uri),
2851 debugstr_w(localName), debugstr_w(QName), debugstr_w(type), debugstr_w(value));
2852 return E_NOTIMPL;
2855 static HRESULT WINAPI MXAttributes_setAttributes(IMXAttributes *iface, VARIANT atts)
2857 mxattributes *This = impl_from_IMXAttributes( iface );
2858 FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&atts));
2859 return E_NOTIMPL;
2862 static HRESULT WINAPI MXAttributes_setLocalName(IMXAttributes *iface, int index,
2863 BSTR localName)
2865 mxattributes *This = impl_from_IMXAttributes( iface );
2866 mxattribute *attr;
2868 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(localName));
2870 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2872 SysFreeString(attr->local);
2873 attr->local = SysAllocString(localName);
2875 return S_OK;
2878 static HRESULT WINAPI MXAttributes_setQName(IMXAttributes *iface, int index, BSTR QName)
2880 mxattributes *This = impl_from_IMXAttributes( iface );
2881 mxattribute *attr;
2883 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(QName));
2885 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2887 SysFreeString(attr->qname);
2888 attr->qname = SysAllocString(QName);
2890 return S_OK;
2893 static HRESULT WINAPI MXAttributes_setURI(IMXAttributes *iface, int index, BSTR uri)
2895 mxattributes *This = impl_from_IMXAttributes( iface );
2896 mxattribute *attr;
2898 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(uri));
2900 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2902 SysFreeString(attr->uri);
2903 attr->uri = SysAllocString(uri);
2905 return S_OK;
2908 static HRESULT WINAPI MXAttributes_setValue(IMXAttributes *iface, int index, BSTR value)
2910 mxattributes *This = impl_from_IMXAttributes( iface );
2911 mxattribute *attr;
2913 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(value));
2915 if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2917 SysFreeString(attr->value);
2918 attr->value = SysAllocString(value);
2920 return S_OK;
2923 static const IMXAttributesVtbl MXAttributesVtbl = {
2924 MXAttributes_QueryInterface,
2925 MXAttributes_AddRef,
2926 MXAttributes_Release,
2927 MXAttributes_GetTypeInfoCount,
2928 MXAttributes_GetTypeInfo,
2929 MXAttributes_GetIDsOfNames,
2930 MXAttributes_Invoke,
2931 MXAttributes_addAttribute,
2932 MXAttributes_addAttributeFromIndex,
2933 MXAttributes_clear,
2934 MXAttributes_removeAttribute,
2935 MXAttributes_setAttribute,
2936 MXAttributes_setAttributes,
2937 MXAttributes_setLocalName,
2938 MXAttributes_setQName,
2939 MXAttributes_setURI,
2940 MXAttributes_setValue
2943 static HRESULT WINAPI SAXAttributes_QueryInterface(ISAXAttributes *iface, REFIID riid, void **ppObj)
2945 mxattributes *This = impl_from_ISAXAttributes( iface );
2946 return IMXAttributes_QueryInterface(&This->IMXAttributes_iface, riid, ppObj);
2949 static ULONG WINAPI SAXAttributes_AddRef(ISAXAttributes *iface)
2951 mxattributes *This = impl_from_ISAXAttributes( iface );
2952 return IMXAttributes_AddRef(&This->IMXAttributes_iface);
2955 static ULONG WINAPI SAXAttributes_Release(ISAXAttributes *iface)
2957 mxattributes *This = impl_from_ISAXAttributes( iface );
2958 return IMXAttributes_Release(&This->IMXAttributes_iface);
2961 static HRESULT WINAPI SAXAttributes_getLength(ISAXAttributes *iface, int *length)
2963 mxattributes *This = impl_from_ISAXAttributes( iface );
2964 TRACE("(%p)->(%p)\n", This, length);
2966 if (!length && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
2967 return E_POINTER;
2969 *length = This->length;
2971 return S_OK;
2974 static HRESULT WINAPI SAXAttributes_getURI(ISAXAttributes *iface, int index, const WCHAR **uri,
2975 int *len)
2977 mxattributes *This = impl_from_ISAXAttributes( iface );
2979 TRACE("(%p)->(%d %p %p)\n", This, index, uri, len);
2981 if (index >= This->length || index < 0) return E_INVALIDARG;
2982 if (!uri || !len) return E_POINTER;
2984 *len = SysStringLen(This->attr[index].uri);
2985 *uri = This->attr[index].uri;
2987 return S_OK;
2990 static HRESULT WINAPI SAXAttributes_getLocalName(ISAXAttributes *iface, int index, const WCHAR **name,
2991 int *len)
2993 mxattributes *This = impl_from_ISAXAttributes( iface );
2995 TRACE("(%p)->(%d %p %p)\n", This, index, name, len);
2997 if (index >= This->length || index < 0) return E_INVALIDARG;
2998 if (!name || !len) return E_POINTER;
3000 *len = SysStringLen(This->attr[index].local);
3001 *name = This->attr[index].local;
3003 return S_OK;
3006 static HRESULT WINAPI SAXAttributes_getQName(ISAXAttributes *iface, int index, const WCHAR **qname, int *length)
3008 mxattributes *This = impl_from_ISAXAttributes( iface );
3010 TRACE("(%p)->(%d %p %p)\n", This, index, qname, length);
3012 if (index >= This->length) return E_INVALIDARG;
3013 if (!qname || !length) return E_POINTER;
3015 *qname = This->attr[index].qname;
3016 *length = SysStringLen(This->attr[index].qname);
3018 return S_OK;
3021 static HRESULT WINAPI SAXAttributes_getName(ISAXAttributes *iface, int index, const WCHAR **uri, int *uri_len,
3022 const WCHAR **local, int *local_len, const WCHAR **qname, int *qname_len)
3024 mxattributes *This = impl_from_ISAXAttributes( iface );
3026 TRACE("(%p)->(%d %p %p %p %p %p %p)\n", This, index, uri, uri_len, local, local_len, qname, qname_len);
3028 if (index >= This->length || index < 0)
3029 return E_INVALIDARG;
3031 if (!uri || !uri_len || !local || !local_len || !qname || !qname_len)
3032 return E_POINTER;
3034 *uri_len = SysStringLen(This->attr[index].uri);
3035 *uri = This->attr[index].uri;
3037 *local_len = SysStringLen(This->attr[index].local);
3038 *local = This->attr[index].local;
3040 *qname_len = SysStringLen(This->attr[index].qname);
3041 *qname = This->attr[index].qname;
3043 TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*local), debugstr_w(*qname));
3045 return S_OK;
3048 static HRESULT WINAPI SAXAttributes_getIndexFromName(ISAXAttributes *iface, const WCHAR *uri, int uri_len,
3049 const WCHAR *name, int len, int *index)
3051 mxattributes *This = impl_from_ISAXAttributes( iface );
3052 int i;
3054 TRACE("(%p)->(%s:%d %s:%d %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
3055 debugstr_wn(name, len), len, index);
3057 if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3058 return E_POINTER;
3060 if (!uri || !name || !index) return E_INVALIDARG;
3062 for (i = 0; i < This->length; i++)
3064 if (uri_len != SysStringLen(This->attr[i].uri)) continue;
3065 if (strncmpW(uri, This->attr[i].uri, uri_len)) continue;
3067 if (len != SysStringLen(This->attr[i].local)) continue;
3068 if (strncmpW(name, This->attr[i].local, len)) continue;
3070 *index = i;
3071 return S_OK;
3074 return E_INVALIDARG;
3077 static HRESULT WINAPI SAXAttributes_getIndexFromQName(ISAXAttributes *iface, const WCHAR *qname,
3078 int len, int *index)
3080 mxattributes *This = impl_from_ISAXAttributes( iface );
3081 int i;
3083 TRACE("(%p)->(%s:%d %p)\n", This, debugstr_wn(qname, len), len, index);
3085 if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3086 return E_POINTER;
3088 if (!qname || !index || !len) return E_INVALIDARG;
3090 for (i = 0; i < This->length; i++)
3092 if (len != SysStringLen(This->attr[i].qname)) continue;
3093 if (strncmpW(qname, This->attr[i].qname, len)) continue;
3095 *index = i;
3096 return S_OK;
3099 return E_INVALIDARG;
3102 static HRESULT WINAPI SAXAttributes_getType(ISAXAttributes *iface, int index, const WCHAR **type,
3103 int *len)
3105 mxattributes *This = impl_from_ISAXAttributes( iface );
3107 TRACE("(%p)->(%d %p %p)\n", This, index, type, len);
3109 if (index >= This->length) return E_INVALIDARG;
3111 if ((!type || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3112 return E_POINTER;
3114 *type = This->attr[index].type;
3115 *len = SysStringLen(This->attr[index].type);
3117 return S_OK;
3120 static HRESULT WINAPI SAXAttributes_getTypeFromName(ISAXAttributes *iface, const WCHAR * pUri, int nUri,
3121 const WCHAR * pLocalName, int nLocalName, const WCHAR ** pType, int * nType)
3123 mxattributes *This = impl_from_ISAXAttributes( iface );
3124 FIXME("(%p)->(%s:%d %s:%d %p %p): stub\n", This, debugstr_wn(pUri, nUri), nUri,
3125 debugstr_wn(pLocalName, nLocalName), nLocalName, pType, nType);
3126 return E_NOTIMPL;
3129 static HRESULT WINAPI SAXAttributes_getTypeFromQName(ISAXAttributes *iface, const WCHAR * pQName,
3130 int nQName, const WCHAR ** pType, int * nType)
3132 mxattributes *This = impl_from_ISAXAttributes( iface );
3133 FIXME("(%p)->(%s:%d %p %p): stub\n", This, debugstr_wn(pQName, nQName), nQName, pType, nType);
3134 return E_NOTIMPL;
3137 static HRESULT WINAPI SAXAttributes_getValue(ISAXAttributes *iface, int index, const WCHAR **value,
3138 int *len)
3140 mxattributes *This = impl_from_ISAXAttributes( iface );
3142 TRACE("(%p)->(%d %p %p)\n", This, index, value, len);
3144 if (index >= This->length) return E_INVALIDARG;
3146 if ((!value || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3147 return E_POINTER;
3149 *value = This->attr[index].value;
3150 *len = SysStringLen(This->attr[index].value);
3152 return S_OK;
3155 static HRESULT WINAPI SAXAttributes_getValueFromName(ISAXAttributes *iface, const WCHAR *uri,
3156 int uri_len, const WCHAR *name, int name_len, const WCHAR **value, int *value_len)
3158 mxattributes *This = impl_from_ISAXAttributes( iface );
3159 HRESULT hr;
3160 int index;
3162 TRACE("(%p)->(%s:%d %s:%d %p %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
3163 debugstr_wn(name, name_len), name_len, value, value_len);
3165 if (!uri || !name || !value || !value_len)
3166 return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3168 hr = ISAXAttributes_getIndexFromName(iface, uri, uri_len, name, name_len, &index);
3169 if (hr == S_OK)
3170 hr = ISAXAttributes_getValue(iface, index, value, value_len);
3172 return hr;
3175 static HRESULT WINAPI SAXAttributes_getValueFromQName(ISAXAttributes *iface, const WCHAR *qname,
3176 int qname_len, const WCHAR **value, int *value_len)
3178 mxattributes *This = impl_from_ISAXAttributes( iface );
3179 HRESULT hr;
3180 int index;
3182 TRACE("(%p)->(%s:%d %p %p)\n", This, debugstr_wn(qname, qname_len), qname_len, value, value_len);
3184 if (!qname || !value || !value_len)
3185 return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3187 hr = ISAXAttributes_getIndexFromQName(iface, qname, qname_len, &index);
3188 if (hr == S_OK)
3189 hr = ISAXAttributes_getValue(iface, index, value, value_len);
3191 return hr;
3194 static const ISAXAttributesVtbl SAXAttributesVtbl = {
3195 SAXAttributes_QueryInterface,
3196 SAXAttributes_AddRef,
3197 SAXAttributes_Release,
3198 SAXAttributes_getLength,
3199 SAXAttributes_getURI,
3200 SAXAttributes_getLocalName,
3201 SAXAttributes_getQName,
3202 SAXAttributes_getName,
3203 SAXAttributes_getIndexFromName,
3204 SAXAttributes_getIndexFromQName,
3205 SAXAttributes_getType,
3206 SAXAttributes_getTypeFromName,
3207 SAXAttributes_getTypeFromQName,
3208 SAXAttributes_getValue,
3209 SAXAttributes_getValueFromName,
3210 SAXAttributes_getValueFromQName
3213 static HRESULT WINAPI VBSAXAttributes_QueryInterface(
3214 IVBSAXAttributes* iface,
3215 REFIID riid,
3216 void **ppvObject)
3218 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3219 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
3220 return ISAXAttributes_QueryInterface(&This->ISAXAttributes_iface, riid, ppvObject);
3223 static ULONG WINAPI VBSAXAttributes_AddRef(IVBSAXAttributes* iface)
3225 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3226 return ISAXAttributes_AddRef(&This->ISAXAttributes_iface);
3229 static ULONG WINAPI VBSAXAttributes_Release(IVBSAXAttributes* iface)
3231 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3232 return ISAXAttributes_Release(&This->ISAXAttributes_iface);
3235 static HRESULT WINAPI VBSAXAttributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
3237 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3239 TRACE("(%p)->(%p)\n", This, pctinfo);
3241 *pctinfo = 1;
3243 return S_OK;
3246 static HRESULT WINAPI VBSAXAttributes_GetTypeInfo(
3247 IVBSAXAttributes *iface,
3248 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
3250 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3251 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
3252 return get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
3255 static HRESULT WINAPI VBSAXAttributes_GetIDsOfNames(
3256 IVBSAXAttributes *iface,
3257 REFIID riid,
3258 LPOLESTR* rgszNames,
3259 UINT cNames,
3260 LCID lcid,
3261 DISPID* rgDispId)
3263 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3264 ITypeInfo *typeinfo;
3265 HRESULT hr;
3267 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
3268 lcid, rgDispId);
3270 if(!rgszNames || cNames == 0 || !rgDispId)
3271 return E_INVALIDARG;
3273 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
3274 if(SUCCEEDED(hr))
3276 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
3277 ITypeInfo_Release(typeinfo);
3280 return hr;
3283 static HRESULT WINAPI VBSAXAttributes_Invoke(
3284 IVBSAXAttributes *iface,
3285 DISPID dispIdMember,
3286 REFIID riid,
3287 LCID lcid,
3288 WORD wFlags,
3289 DISPPARAMS* pDispParams,
3290 VARIANT* pVarResult,
3291 EXCEPINFO* pExcepInfo,
3292 UINT* puArgErr)
3294 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3295 ITypeInfo *typeinfo;
3296 HRESULT hr;
3298 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
3299 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3301 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
3302 if(SUCCEEDED(hr))
3304 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
3305 pDispParams, pVarResult, pExcepInfo, puArgErr);
3306 ITypeInfo_Release(typeinfo);
3309 return hr;
3312 static HRESULT WINAPI VBSAXAttributes_get_length(IVBSAXAttributes* iface, int *len)
3314 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3315 return ISAXAttributes_getLength(&This->ISAXAttributes_iface, len);
3318 static HRESULT WINAPI VBSAXAttributes_getURI(IVBSAXAttributes* iface, int index, BSTR *uri)
3320 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3321 const WCHAR *uriW;
3322 HRESULT hr;
3323 int len;
3325 TRACE("(%p)->(%d %p)\n", This, index, uri);
3327 if (!uri)
3328 return E_POINTER;
3330 *uri = NULL;
3331 hr = ISAXAttributes_getURI(&This->ISAXAttributes_iface, index, &uriW, &len);
3332 if (FAILED(hr))
3333 return hr;
3335 return return_bstrn(uriW, len, uri);
3338 static HRESULT WINAPI VBSAXAttributes_getLocalName(IVBSAXAttributes* iface, int index, BSTR *name)
3340 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3341 const WCHAR *nameW;
3342 HRESULT hr;
3343 int len;
3345 TRACE("(%p)->(%d %p)\n", This, index, name);
3347 if (!name)
3348 return E_POINTER;
3350 *name = NULL;
3351 hr = ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, index, &nameW, &len);
3352 if (FAILED(hr))
3353 return hr;
3355 return return_bstrn(nameW, len, name);
3358 static HRESULT WINAPI VBSAXAttributes_getQName(IVBSAXAttributes* iface, int index, BSTR *qname)
3360 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3361 const WCHAR *qnameW;
3362 HRESULT hr;
3363 int len;
3365 TRACE("(%p)->(%d %p)\n", This, index, qname);
3367 if (!qname)
3368 return E_POINTER;
3370 *qname = NULL;
3371 hr = ISAXAttributes_getQName(&This->ISAXAttributes_iface, index, &qnameW, &len);
3372 if (FAILED(hr))
3373 return hr;
3375 return return_bstrn(qnameW, len, qname);
3378 static HRESULT WINAPI VBSAXAttributes_getIndexFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name, int *index)
3380 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3381 return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3382 name, SysStringLen(name), index);
3385 static HRESULT WINAPI VBSAXAttributes_getIndexFromQName(IVBSAXAttributes* iface, BSTR qname, int *index)
3387 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3388 return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, qname,
3389 SysStringLen(qname), index);
3392 static HRESULT WINAPI VBSAXAttributes_getType(IVBSAXAttributes* iface, int index, BSTR *type)
3394 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3395 const WCHAR *typeW;
3396 HRESULT hr;
3397 int len;
3399 TRACE("(%p)->(%d %p)\n", This, index, type);
3401 if (!type)
3402 return E_POINTER;
3404 *type = NULL;
3405 hr = ISAXAttributes_getType(&This->ISAXAttributes_iface, index, &typeW, &len);
3406 if (FAILED(hr))
3407 return hr;
3409 return return_bstrn(typeW, len, type);
3412 static HRESULT WINAPI VBSAXAttributes_getTypeFromName(IVBSAXAttributes* iface, BSTR uri,
3413 BSTR name, BSTR *type)
3415 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3416 const WCHAR *typeW;
3417 HRESULT hr;
3418 int len;
3420 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), type);
3422 if (!type)
3423 return E_POINTER;
3425 *type = NULL;
3426 hr = ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3427 name, SysStringLen(name), &typeW, &len);
3428 if (FAILED(hr))
3429 return hr;
3431 return return_bstrn(typeW, len, type);
3434 static HRESULT WINAPI VBSAXAttributes_getTypeFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *type)
3436 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3437 const WCHAR *typeW;
3438 HRESULT hr;
3439 int len;
3441 TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), type);
3443 if (!type)
3444 return E_POINTER;
3446 *type = NULL;
3447 hr = ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3448 &typeW, &len);
3449 if (FAILED(hr))
3450 return hr;
3452 return return_bstrn(typeW, len, type);
3455 static HRESULT WINAPI VBSAXAttributes_getValue(IVBSAXAttributes* iface, int index, BSTR *value)
3457 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3458 const WCHAR *valueW;
3459 HRESULT hr;
3460 int len;
3462 TRACE("(%p)->(%d %p)\n", This, index, value);
3464 if (!value)
3465 return E_POINTER;
3467 *value = NULL;
3468 hr = ISAXAttributes_getValue(&This->ISAXAttributes_iface, index, &valueW, &len);
3469 if (FAILED(hr))
3470 return hr;
3472 return return_bstrn(valueW, len, value);
3475 static HRESULT WINAPI VBSAXAttributes_getValueFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name,
3476 BSTR *value)
3478 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3479 const WCHAR *valueW;
3480 HRESULT hr;
3481 int len;
3483 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), value);
3485 if (!value)
3486 return E_POINTER;
3488 *value = NULL;
3489 hr = ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3490 name, SysStringLen(name), &valueW, &len);
3491 if (FAILED(hr))
3492 return hr;
3494 return return_bstrn(valueW, len, value);
3497 static HRESULT WINAPI VBSAXAttributes_getValueFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *value)
3499 mxattributes *This = impl_from_IVBSAXAttributes( iface );
3500 const WCHAR *valueW;
3501 HRESULT hr;
3502 int len;
3504 TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), value);
3506 if (!value)
3507 return E_POINTER;
3509 *value = NULL;
3510 hr = ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3511 &valueW, &len);
3512 if (FAILED(hr))
3513 return hr;
3515 return return_bstrn(valueW, len, value);
3518 static const struct IVBSAXAttributesVtbl VBSAXAttributesVtbl =
3520 VBSAXAttributes_QueryInterface,
3521 VBSAXAttributes_AddRef,
3522 VBSAXAttributes_Release,
3523 VBSAXAttributes_GetTypeInfoCount,
3524 VBSAXAttributes_GetTypeInfo,
3525 VBSAXAttributes_GetIDsOfNames,
3526 VBSAXAttributes_Invoke,
3527 VBSAXAttributes_get_length,
3528 VBSAXAttributes_getURI,
3529 VBSAXAttributes_getLocalName,
3530 VBSAXAttributes_getQName,
3531 VBSAXAttributes_getIndexFromName,
3532 VBSAXAttributes_getIndexFromQName,
3533 VBSAXAttributes_getType,
3534 VBSAXAttributes_getTypeFromName,
3535 VBSAXAttributes_getTypeFromQName,
3536 VBSAXAttributes_getValue,
3537 VBSAXAttributes_getValueFromName,
3538 VBSAXAttributes_getValueFromQName
3541 static const tid_t mxattrs_iface_tids[] = {
3542 IMXAttributes_tid,
3546 static dispex_static_data_t mxattrs_dispex = {
3547 NULL,
3548 IMXAttributes_tid,
3549 NULL,
3550 mxattrs_iface_tids
3553 HRESULT SAXAttributes_create(MSXML_VERSION version, void **ppObj)
3555 static const int default_count = 10;
3556 mxattributes *This;
3558 TRACE("(%p)\n", ppObj);
3560 This = heap_alloc( sizeof (*This) );
3561 if( !This )
3562 return E_OUTOFMEMORY;
3564 This->IMXAttributes_iface.lpVtbl = &MXAttributesVtbl;
3565 This->ISAXAttributes_iface.lpVtbl = &SAXAttributesVtbl;
3566 This->IVBSAXAttributes_iface.lpVtbl = &VBSAXAttributesVtbl;
3567 This->ref = 1;
3569 This->class_version = version;
3571 This->attr = heap_alloc(default_count*sizeof(mxattribute));
3572 This->length = 0;
3573 This->allocated = default_count;
3575 *ppObj = &This->IMXAttributes_iface;
3577 init_dispex(&This->dispex, (IUnknown*)&This->IMXAttributes_iface, &mxattrs_dispex);
3579 TRACE("returning iface %p\n", *ppObj);
3581 return S_OK;