ReactOS 0.4.15-dev-8102-g108db8f
mxwriter.c
Go to the documentation of this file.
1/*
2 * MXWriter implementation
3 *
4 * Copyright 2011-2014, 2016 Nikolay Sivov for CodeWeavers
5 * Copyright 2011 Thomas Mullaly
6 *
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.
11 *
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.
16 *
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
20 */
21
22#define COBJMACROS
23#include "config.h"
24
25#include <stdarg.h>
26#ifdef HAVE_LIBXML2
27# include <libxml/parser.h>
28#endif
29
30#include "windef.h"
31#include "winbase.h"
32#include "ole2.h"
33
34#include "msxml6.h"
35
36#include "wine/debug.h"
37#include "wine/list.h"
38
39#include "msxml_private.h"
40
42
43static const WCHAR emptyW[] = {0};
44static const WCHAR spaceW[] = {' '};
45static const WCHAR quotW[] = {'\"'};
46static const WCHAR closetagW[] = {'>','\r','\n'};
47static const WCHAR crlfW[] = {'\r','\n'};
48static const WCHAR entityW[] = {'<','!','E','N','T','I','T','Y',' '};
49static const WCHAR publicW[] = {'P','U','B','L','I','C',' '};
50static const WCHAR systemW[] = {'S','Y','S','T','E','M',' '};
51
52/* should be ordered as encoding names are sorted */
53typedef enum
54{
68
70{
74};
75
76static const WCHAR iso_8859_1W[] = {'i','s','o','-','8','8','5','9','-','1',0};
77static const WCHAR iso_8859_2W[] = {'i','s','o','-','8','8','5','9','-','2',0};
78static const WCHAR iso_8859_3W[] = {'i','s','o','-','8','8','5','9','-','3',0};
79static const WCHAR iso_8859_4W[] = {'i','s','o','-','8','8','5','9','-','4',0};
80static const WCHAR iso_8859_5W[] = {'i','s','o','-','8','8','5','9','-','5',0};
81static const WCHAR iso_8859_7W[] = {'i','s','o','-','8','8','5','9','-','7',0};
82static const WCHAR iso_8859_9W[] = {'i','s','o','-','8','8','5','9','-','9',0};
83static const WCHAR iso_8859_13W[] = {'i','s','o','-','8','8','5','9','-','1','3',0};
84static const WCHAR iso_8859_15W[] = {'i','s','o','-','8','8','5','9','-','1','5',0};
85static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
86static const WCHAR utf8W[] = {'U','T','F','-','8',0};
87
88static const struct xml_encoding_data xml_encoding_map[] = {
100};
101
102typedef enum
103{
111
112typedef enum
113{
117
118typedef struct
119{
120 struct list entry;
121 char *data;
122 unsigned int allocated;
123 unsigned int written;
125
126typedef struct
127{
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 */
133
134typedef struct
135{
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;
148
151
155
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 */
159
161
162 BSTR encoding; /* exact property value */
164
165 /* contains a pending (or not closed yet) element name or NULL if
166 we don't have to close */
168
170
172} mxwriter;
173
174typedef struct
175{
182
183typedef struct
184{
186 IMXAttributes IMXAttributes_iface;
187 ISAXAttributes ISAXAttributes_iface;
188 IVBSAXAttributes IVBSAXAttributes_iface;
190
192
197
198static inline mxattributes *impl_from_IMXAttributes( IMXAttributes *iface )
199{
200 return CONTAINING_RECORD(iface, mxattributes, IMXAttributes_iface);
201}
202
203static inline mxattributes *impl_from_ISAXAttributes( ISAXAttributes *iface )
204{
205 return CONTAINING_RECORD(iface, mxattributes, ISAXAttributes_iface);
206}
207
208static inline mxattributes *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
209{
210 return CONTAINING_RECORD(iface, mxattributes, IVBSAXAttributes_iface);
211}
212
214{
215 if (This->length < This->allocated) return S_OK;
216
217 This->allocated *= 2;
218 This->attr = heap_realloc(This->attr, This->allocated*sizeof(mxattribute));
219
220 return This->attr ? S_OK : E_OUTOFMEMORY;
221}
222
224{
225 int min, max, n, c;
226
227 min = 0;
229
230 while (min <= max)
231 {
232 n = (min+max)/2;
233
235 if (!c)
236 return xml_encoding_map[n].enc;
237
238 if (c > 0)
239 max = n-1;
240 else
241 min = n+1;
242 }
243
244 return XmlEncoding_Unknown;
245}
246
248{
249 const int initial_len = 0x1000;
250 buffer->data = heap_alloc(initial_len);
251 if (!buffer->data) return E_OUTOFMEMORY;
252
253 memset(buffer->data, 0, 4);
254 buffer->allocated = initial_len;
255 buffer->written = 0;
256
257 return S_OK;
258}
259
261{
262 heap_free(buffer->data);
263}
264
266{
267 const struct xml_encoding_data *data;
268
270 {
271 FIXME("unsupported encoding %d\n", encoding);
272 return E_NOTIMPL;
273 }
274
276 *cp = data->cp;
277
278 return S_OK;
279}
280
282{
283 HRESULT hr;
284
285 hr = get_code_page(encoding, &buffer->code_page);
286 if (hr != S_OK)
287 return hr;
288
289 hr = init_encoded_buffer(&buffer->encoded);
290 if (hr != S_OK)
291 return hr;
292
293 list_init(&buffer->blocks);
294 buffer->utf16_total = 0;
295
296 return S_OK;
297}
298
300{
301 encoded_buffer *cur, *cur2;
302
303 free_encoded_buffer(&buffer->encoded);
304
306 {
307 list_remove(&cur->entry);
309 heap_free(cur);
310 }
311}
312
313static HRESULT write_output_buffer(mxwriter *writer, const WCHAR *data, int len)
314{
315 output_buffer *buffer = &writer->buffer;
317 unsigned int written;
318 int src_len;
319
320 if (!len || !*data)
321 return S_OK;
322
323 src_len = len == -1 ? strlenW(data) : len;
324 if (writer->dest)
325 {
326 buff = &buffer->encoded;
327
328 if (buffer->code_page == ~0)
329 {
330 unsigned int avail = buff->allocated - buff->written;
331
332 src_len *= sizeof(WCHAR);
333 written = min(avail, src_len);
334
335 /* fill internal buffer first */
336 if (avail)
337 {
338 memcpy(buff->data + buff->written, data, written);
339 data += written / sizeof(WCHAR);
340 buff->written += written;
341 avail -= written;
342 src_len -= written;
343 }
344
345 if (!avail)
346 {
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)
352 {
353 memcpy(buff->data, data, src_len);
354 buff->written += src_len;
355 }
356 }
357 }
358 else
359 {
360 unsigned int avail = buff->allocated - buff->written;
361 int length;
362
363 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, NULL, 0, NULL, NULL);
364 if (avail >= length)
365 {
366 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, buff->data + buff->written, length, NULL, NULL);
367 buff->written += length;
368 }
369 else
370 {
371 /* drain what we go so far */
372 if (buff->written)
373 {
374 IStream_Write(writer->dest, buff->data, buff->written, &written);
375 buff->written = 0;
376 avail = buff->allocated;
377 }
378
379 if (avail >= length)
380 {
381 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, buff->data + buff->written, length, NULL, NULL);
382 buff->written += length;
383 }
384 else
385 {
386 char *mb;
387
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;
392
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);
396 }
397 }
398 }
399 }
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:
402
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
409 {
410 /* select last used block */
411 if (list_empty(&buffer->blocks))
412 buff = &buffer->encoded;
413 else
415
416 src_len *= sizeof(WCHAR);
417 while (src_len)
418 {
419 unsigned int avail = buff->allocated - buff->written;
420 unsigned int written = min(avail, src_len);
421
422 if (avail)
423 {
424 memcpy(buff->data + buff->written, data, written);
425 buff->written += written;
426 buffer->utf16_total += written;
427 src_len -= written;
428 }
429
430 /* alloc new block if needed and retry */
431 if (src_len)
432 {
433 encoded_buffer *next = heap_alloc(sizeof(*next));
434 HRESULT hr;
435
438 return hr;
439 }
440
441 list_add_tail(&buffer->blocks, &next->entry);
442 buff = next;
443 }
444 }
445 }
446
447 return S_OK;
448}
449
451{
452 write_output_buffer(writer, quotW, 1);
453 write_output_buffer(writer, data, len);
454 write_output_buffer(writer, quotW, 1);
455
456 return S_OK;
457}
458
459/* frees buffer data, reallocates with a default lengths */
460static void close_output_buffer(mxwriter *writer)
461{
462 encoded_buffer *cur, *cur2;
463
464 heap_free(writer->buffer.encoded.data);
465
467 {
468 list_remove(&cur->entry);
470 heap_free(cur);
471 }
472
474 get_code_page(writer->xml_enc, &writer->buffer.code_page);
475 writer->buffer.utf16_total = 0;
476 list_init(&writer->buffer.blocks);
477}
478
479/* Escapes special characters like:
480 '<' -> "&lt;"
481 '&' -> "&amp;"
482 '"' -> "&quot;"
483 '>' -> "&gt;"
484
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.
487*/
489{
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',';'};
494
495 const int default_alloc = 100;
496 const int grow_thresh = 10;
497 int p = *len, conv_len;
498 WCHAR *ptr, *ret;
499
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));
503
504 while (p)
505 {
506 if (ptr - ret > conv_len - grow_thresh)
507 {
508 int written = ptr - ret;
509 conv_len *= 2;
510 ptr = ret = heap_realloc(ret, conv_len*sizeof(WCHAR));
511 ptr += written;
512 }
513
514 switch (*str)
515 {
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)
530 {
531 memcpy(ptr, equotW, sizeof(equotW));
532 ptr += ARRAY_SIZE(equotW);
533 break;
534 }
535 /* fallthrough for text mode */
536 default:
537 *ptr++ = *str;
538 break;
539 }
540
541 str++;
542 p--;
543 }
544
545 *len = ptr-ret;
546 *++ptr = 0;
547
548 return ret;
549}
550
551static void write_prolog_buffer(mxwriter *writer)
552{
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','\"','?','>'};
558
559 /* version */
561 write_output_buffer_quoted(writer, writer->version, -1);
562
563 /* encoding */
564 write_output_buffer(writer, encodingW, ARRAY_SIZE(encodingW));
565
566 if (writer->dest)
567 write_output_buffer(writer, writer->encoding, -1);
568 else
570 write_output_buffer(writer, quotW, 1);
571
572 /* standalone */
573 write_output_buffer(writer, standaloneW, ARRAY_SIZE(standaloneW));
574 if (writer->props[MXWriter_Standalone] == VARIANT_TRUE)
576 else
578
580 writer->newline = TRUE;
581}
582
583/* Attempts to the write data from the mxwriter's buffer to
584 * the destination stream (if there is one).
585 */
587{
589 ULONG written = 0;
590
591 if (!writer->dest)
592 return S_OK;
593
594 if (buffer->written == 0)
595 {
596 if (writer->xml_enc == XmlEncoding_UTF8)
597 IStream_Write(writer->dest, buffer->data, 0, &written);
598 }
599 else
600 {
601 IStream_Write(writer->dest, buffer->data, buffer->written, &written);
602 buffer->written = 0;
603 }
604
605 return S_OK;
606}
607
608/* Newly added element start tag left unclosed cause for empty elements
609 we have to close it differently. */
611{
612 static const WCHAR gtW[] = {'>'};
613 if (!writer->element) return;
614 write_output_buffer(writer, gtW, 1);
615}
616
617static void write_node_indent(mxwriter *writer)
618{
619 static const WCHAR tabW[] = {'\t'};
620 int indent = writer->indent;
621
622 if (!writer->props[MXWriter_Indent] || writer->text)
623 {
624 writer->text = FALSE;
625 return;
626 }
627
628 /* This is to workaround PI output logic that always puts newline chars,
629 document prolog PI does that too. */
630 if (!writer->newline)
632 while (indent--)
633 write_output_buffer(writer, tabW, 1);
634
635 writer->newline = FALSE;
636 writer->text = FALSE;
637}
638
639static inline void writer_inc_indent(mxwriter *This)
640{
641 This->indent++;
642}
643
644static inline void writer_dec_indent(mxwriter *This)
645{
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;
650}
651
652static void set_element_name(mxwriter *This, const WCHAR *name, int len)
653{
654 SysFreeString(This->element);
655 if (name)
656 This->element = len != -1 ? SysAllocStringLen(name, len) : SysAllocString(name);
657 else
658 This->element = NULL;
659}
660
662{
665 This->cdata = FALSE;
667}
668
669/* Resets the mxwriter's output buffer by closing it, then creating a new
670 * output buffer using the given encoding.
671 */
673{
675}
676
678{
679 writer->props[property] = value;
680 writer->prop_changed = TRUE;
681 return S_OK;
682}
683
685{
686 if (!value) return E_POINTER;
687 *value = writer->props[property];
688 return S_OK;
689}
690
691static inline mxwriter *impl_from_IMXWriter(IMXWriter *iface)
692{
693 return CONTAINING_RECORD(iface, mxwriter, IMXWriter_iface);
694}
695
696static inline mxwriter *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
697{
698 return CONTAINING_RECORD(iface, mxwriter, ISAXContentHandler_iface);
699}
700
701static inline mxwriter *impl_from_IVBSAXContentHandler(IVBSAXContentHandler *iface)
702{
703 return CONTAINING_RECORD(iface, mxwriter, IVBSAXContentHandler_iface);
704}
705
706static inline mxwriter *impl_from_ISAXLexicalHandler(ISAXLexicalHandler *iface)
707{
708 return CONTAINING_RECORD(iface, mxwriter, ISAXLexicalHandler_iface);
709}
710
711static inline mxwriter *impl_from_IVBSAXLexicalHandler(IVBSAXLexicalHandler *iface)
712{
713 return CONTAINING_RECORD(iface, mxwriter, IVBSAXLexicalHandler_iface);
714}
715
716static inline mxwriter *impl_from_ISAXDeclHandler(ISAXDeclHandler *iface)
717{
718 return CONTAINING_RECORD(iface, mxwriter, ISAXDeclHandler_iface);
719}
720
721static inline mxwriter *impl_from_IVBSAXDeclHandler(IVBSAXDeclHandler *iface)
722{
723 return CONTAINING_RECORD(iface, mxwriter, IVBSAXDeclHandler_iface);
724}
725
726static inline mxwriter *impl_from_ISAXDTDHandler(ISAXDTDHandler *iface)
727{
728 return CONTAINING_RECORD(iface, mxwriter, ISAXDTDHandler_iface);
729}
730
731static inline mxwriter *impl_from_IVBSAXDTDHandler(IVBSAXDTDHandler *iface)
732{
733 return CONTAINING_RECORD(iface, mxwriter, IVBSAXDTDHandler_iface);
734}
735
736static inline mxwriter *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
737{
738 return CONTAINING_RECORD(iface, mxwriter, ISAXErrorHandler_iface);
739}
740
741static inline mxwriter *impl_from_IVBSAXErrorHandler(IVBSAXErrorHandler *iface)
742{
743 return CONTAINING_RECORD(iface, mxwriter, IVBSAXErrorHandler_iface);
744}
745
746static HRESULT WINAPI mxwriter_QueryInterface(IMXWriter *iface, REFIID riid, void **obj)
747{
749
750 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
751
752 *obj = NULL;
753
754 if ( IsEqualGUID( riid, &IID_IMXWriter ) ||
757 {
758 *obj = &This->IMXWriter_iface;
759 }
760 else if ( IsEqualGUID( riid, &IID_ISAXContentHandler ) )
761 {
762 *obj = &This->ISAXContentHandler_iface;
763 }
764 else if ( IsEqualGUID( riid, &IID_ISAXLexicalHandler ) )
765 {
766 *obj = &This->ISAXLexicalHandler_iface;
767 }
768 else if ( IsEqualGUID( riid, &IID_ISAXDeclHandler ) )
769 {
770 *obj = &This->ISAXDeclHandler_iface;
771 }
772 else if ( IsEqualGUID( riid, &IID_ISAXDTDHandler ) )
773 {
774 *obj = &This->ISAXDTDHandler_iface;
775 }
776 else if ( IsEqualGUID( riid, &IID_ISAXErrorHandler ) )
777 {
778 *obj = &This->ISAXErrorHandler_iface;
779 }
780 else if ( IsEqualGUID( riid, &IID_IVBSAXDeclHandler ) )
781 {
782 *obj = &This->IVBSAXDeclHandler_iface;
783 }
784 else if ( IsEqualGUID( riid, &IID_IVBSAXLexicalHandler ) )
785 {
786 *obj = &This->IVBSAXLexicalHandler_iface;
787 }
788 else if ( IsEqualGUID( riid, &IID_IVBSAXContentHandler ) )
789 {
790 *obj = &This->IVBSAXContentHandler_iface;
791 }
792 else if ( IsEqualGUID( riid, &IID_IVBSAXDTDHandler ) )
793 {
794 *obj = &This->IVBSAXDTDHandler_iface;
795 }
796 else if ( IsEqualGUID( riid, &IID_IVBSAXErrorHandler ) )
797 {
798 *obj = &This->IVBSAXErrorHandler_iface;
799 }
800 else if (dispex_query_interface(&This->dispex, riid, obj))
801 {
802 return *obj ? S_OK : E_NOINTERFACE;
803 }
804 else
805 {
806 ERR("interface %s not implemented\n", debugstr_guid(riid));
807 *obj = NULL;
808 return E_NOINTERFACE;
809 }
810
811 IMXWriter_AddRef(iface);
812 return S_OK;
813}
814
815static ULONG WINAPI mxwriter_AddRef(IMXWriter *iface)
816{
819
820 TRACE("(%p)->(%d)\n", This, ref);
821
822 return ref;
823}
824
825static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
826{
829
830 TRACE("(%p)->(%d)\n", This, ref);
831
832 if(!ref)
833 {
834 /* Windows flushes the buffer when the interface is destroyed. */
836 free_output_buffer(&This->buffer);
837
838 if (This->dest) IStream_Release(This->dest);
839 SysFreeString(This->version);
840 SysFreeString(This->encoding);
841
842 SysFreeString(This->element);
844 }
845
846 return ref;
847}
848
849static HRESULT WINAPI mxwriter_GetTypeInfoCount(IMXWriter *iface, UINT* pctinfo)
850{
852 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
853}
854
856 IMXWriter *iface,
857 UINT iTInfo, LCID lcid,
858 ITypeInfo** ppTInfo )
859{
861 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
862 iTInfo, lcid, ppTInfo);
863}
864
866 IMXWriter *iface,
867 REFIID riid, LPOLESTR* rgszNames,
868 UINT cNames, LCID lcid, DISPID* rgDispId )
869{
871 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
872 riid, rgszNames, cNames, lcid, rgDispId);
873}
874
876 IMXWriter *iface,
877 DISPID dispIdMember, REFIID riid, LCID lcid,
878 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
879 EXCEPINFO* pExcepInfo, UINT* puArgErr )
880{
882 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
883 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
884}
885
887{
889 HRESULT hr;
890
891 TRACE("(%p)->(%s)\n", This, debugstr_variant(&dest));
892
894 if (FAILED(hr))
895 return hr;
896
897 switch (V_VT(&dest))
898 {
899 case VT_EMPTY:
900 {
901 if (This->dest) IStream_Release(This->dest);
902 This->dest = NULL;
904 break;
905 }
906 case VT_UNKNOWN:
907 {
909
910 hr = IUnknown_QueryInterface(V_UNKNOWN(&dest), &IID_IStream, (void**)&stream);
911 if (hr == S_OK)
912 {
913 /* Recreate the output buffer to make sure it's using the correct encoding. */
915
916 if (This->dest) IStream_Release(This->dest);
917 This->dest = stream;
918 break;
919 }
920
921 FIXME("unhandled interface type for VT_UNKNOWN destination\n");
922 return E_NOTIMPL;
923 }
924 default:
925 FIXME("unhandled destination type %s\n", debugstr_variant(&dest));
926 return E_NOTIMPL;
927 }
928
929 return S_OK;
930}
931
933{
935
936 TRACE("(%p)->(%p)\n", This, dest);
937
938 if (!dest) return E_POINTER;
939
940 if (This->dest)
941 {
942 /* we only support IStream output so far */
944 V_UNKNOWN(dest) = (IUnknown*)This->dest;
945 IStream_AddRef(This->dest);
946 }
947 else
948 {
950 char *dest_ptr;
951 HRESULT hr;
952
954 if (FAILED(hr))
955 return hr;
956
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;
961
962 dest_ptr = (char*)V_BSTR(dest);
963 buff = &This->buffer.encoded;
964
965 if (buff->written)
966 {
967 memcpy(dest_ptr, buff->data, buff->written);
968 dest_ptr += buff->written;
969 }
970
972 {
973 memcpy(dest_ptr, buff->data, buff->written);
974 dest_ptr += buff->written;
975 }
976 }
977
978 return S_OK;
979}
980
982{
985 HRESULT hr;
986
987 TRACE("(%p)->(%s)\n", This, debugstr_w(encoding));
988
991 {
992 FIXME("unsupported encoding %s\n", debugstr_w(encoding));
993 return E_INVALIDARG;
994 }
995
997 if (FAILED(hr))
998 return hr;
999
1000 SysReAllocString(&This->encoding, encoding);
1001 This->xml_enc = enc;
1002
1003 TRACE("got encoding %d\n", This->xml_enc);
1005 return S_OK;
1006}
1007
1009{
1010 mxwriter *This = impl_from_IMXWriter( iface );
1011
1012 TRACE("(%p)->(%p)\n", This, encoding);
1013
1014 if (!encoding) return E_POINTER;
1015
1016 *encoding = SysAllocString(This->encoding);
1017 if (!*encoding) return E_OUTOFMEMORY;
1018
1019 return S_OK;
1020}
1021
1023{
1024 mxwriter *This = impl_from_IMXWriter( iface );
1025
1026 TRACE("(%p)->(%d)\n", This, value);
1028}
1029
1031{
1032 mxwriter *This = impl_from_IMXWriter( iface );
1033
1034 TRACE("(%p)->(%p)\n", This, value);
1036}
1037
1039{
1040 mxwriter *This = impl_from_IMXWriter( iface );
1041
1042 TRACE("(%p)->(%d)\n", This, value);
1044}
1045
1047{
1048 mxwriter *This = impl_from_IMXWriter( iface );
1049
1050 TRACE("(%p)->(%p)\n", This, value);
1052}
1053
1055{
1056 mxwriter *This = impl_from_IMXWriter( iface );
1057
1058 TRACE("(%p)->(%d)\n", This, value);
1060}
1061
1063{
1064 mxwriter *This = impl_from_IMXWriter( iface );
1065
1066 TRACE("(%p)->(%p)\n", This, value);
1068}
1069
1071{
1072 mxwriter *This = impl_from_IMXWriter( iface );
1073
1074 TRACE("(%p)->(%d)\n", This, value);
1076}
1077
1079{
1080 mxwriter *This = impl_from_IMXWriter( iface );
1081
1082 TRACE("(%p)->(%p)\n", This, value);
1084}
1085
1087{
1088 mxwriter *This = impl_from_IMXWriter( iface );
1089
1090 TRACE("(%p)->(%s)\n", This, debugstr_w(version));
1091
1092 if (!version) return E_INVALIDARG;
1093
1094 SysFreeString(This->version);
1095 This->version = SysAllocString(version);
1096
1097 return S_OK;
1098}
1099
1101{
1102 mxwriter *This = impl_from_IMXWriter( iface );
1103
1104 TRACE("(%p)->(%p)\n", This, version);
1105
1106 if (!version) return E_POINTER;
1107
1108 return return_bstr(This->version, version);
1109}
1110
1112{
1113 mxwriter *This = impl_from_IMXWriter( iface );
1114
1115 TRACE("(%p)->(%d)\n", This, value);
1117}
1118
1120{
1121 mxwriter *This = impl_from_IMXWriter( iface );
1122
1123 TRACE("(%p)->(%p)\n", This, value);
1125}
1126
1127static HRESULT WINAPI mxwriter_flush(IMXWriter *iface)
1128{
1129 mxwriter *This = impl_from_IMXWriter( iface );
1130 TRACE("(%p)\n", This);
1131 return flush_output_buffer(This);
1132}
1133
1134static const struct IMXWriterVtbl MXWriterVtbl =
1135{
1160};
1161
1162/*** ISAXContentHandler ***/
1164 ISAXContentHandler *iface,
1165 REFIID riid,
1166 void **obj)
1167{
1169 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1170}
1171
1172static ULONG WINAPI SAXContentHandler_AddRef(ISAXContentHandler *iface)
1173{
1175 return IMXWriter_AddRef(&This->IMXWriter_iface);
1176}
1177
1178static ULONG WINAPI SAXContentHandler_Release(ISAXContentHandler *iface)
1179{
1181 return IMXWriter_Release(&This->IMXWriter_iface);
1182}
1183
1185 ISAXContentHandler *iface,
1186 ISAXLocator *locator)
1187{
1189 FIXME("(%p)->(%p)\n", This, locator);
1190 return E_NOTIMPL;
1191}
1192
1193static HRESULT WINAPI SAXContentHandler_startDocument(ISAXContentHandler *iface)
1194{
1196
1197 TRACE("(%p)\n", This);
1198
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.
1203 */
1204 if (This->prop_changed) {
1206 This->prop_changed = FALSE;
1207 }
1208
1209 if (This->props[MXWriter_OmitXmlDecl] == VARIANT_TRUE) return S_OK;
1210
1212
1213 if (This->dest && This->xml_enc == XmlEncoding_UTF16) {
1214 static const char utf16BOM[] = {0xff,0xfe};
1215
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.
1219 */
1220 IStream_Write(This->dest, utf16BOM, sizeof(utf16BOM), NULL);
1221 }
1222
1223 return S_OK;
1224}
1225
1226static HRESULT WINAPI SAXContentHandler_endDocument(ISAXContentHandler *iface)
1227{
1229 TRACE("(%p)\n", This);
1230 This->prop_changed = FALSE;
1231 return flush_output_buffer(This);
1232}
1233
1235 ISAXContentHandler *iface,
1236 const WCHAR *prefix,
1237 int nprefix,
1238 const WCHAR *uri,
1239 int nuri)
1240{
1242 TRACE("(%p)->(%s %s)\n", This, debugstr_wn(prefix, nprefix), debugstr_wn(uri, nuri));
1243 return S_OK;
1244}
1245
1247 ISAXContentHandler *iface,
1248 const WCHAR *prefix,
1249 int nprefix)
1250{
1252 TRACE("(%p)->(%s)\n", This, debugstr_wn(prefix, nprefix));
1253 return S_OK;
1254}
1255
1256static void mxwriter_write_attribute(mxwriter *writer, const WCHAR *qname, int qname_len,
1257 const WCHAR *value, int value_len, BOOL escape)
1258{
1259 static const WCHAR eqW[] = {'='};
1260
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);
1265
1266 if (escape)
1267 {
1268 WCHAR *escaped = get_escaped_string(value, EscapeValue, &value_len);
1269 write_output_buffer_quoted(writer, escaped, value_len);
1270 heap_free(escaped);
1271 }
1272 else
1273 write_output_buffer_quoted(writer, value, value_len);
1274}
1275
1276static void mxwriter_write_starttag(mxwriter *writer, const WCHAR *qname, int len)
1277{
1278 static const WCHAR ltW[] = {'<'};
1279
1280 close_element_starttag(writer);
1281 set_element_name(writer, qname ? qname : emptyW, qname ? len : 0);
1282
1283 write_node_indent(writer);
1284
1285 write_output_buffer(writer, ltW, 1);
1286 write_output_buffer(writer, qname ? qname : emptyW, qname ? len : 0);
1287 writer_inc_indent(writer);
1288}
1289
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)
1299{
1301
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);
1304
1305 if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1306 (nQName == -1 && This->class_version == MSXML6))
1307 return E_INVALIDARG;
1308
1309 mxwriter_write_starttag(This, QName, nQName);
1310
1311 if (attr)
1312 {
1313 int length, i, escape;
1314 HRESULT hr;
1315
1316 hr = ISAXAttributes_getLength(attr, &length);
1317 if (FAILED(hr)) return hr;
1318
1319 escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
1320 (This->class_version == MSXML4 || This->class_version == MSXML6);
1321
1322 for (i = 0; i < length; i++)
1323 {
1324 int qname_len = 0, value_len = 0;
1325 const WCHAR *qname, *value;
1326
1327 hr = ISAXAttributes_getQName(attr, i, &qname, &qname_len);
1328 if (FAILED(hr)) return hr;
1329
1330 hr = ISAXAttributes_getValue(attr, i, &value, &value_len);
1331 if (FAILED(hr)) return hr;
1332
1333 mxwriter_write_attribute(This, qname, qname_len, value, value_len, escape);
1334 }
1335 }
1336
1337 return S_OK;
1338}
1339
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)
1348{
1350
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);
1353
1354 if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1355 (nQName == -1 && This->class_version == MSXML6))
1356 return E_INVALIDARG;
1357
1359
1360 if (This->element)
1361 {
1362 static const WCHAR closeW[] = {'/','>'};
1363 write_output_buffer(This, closeW, 2);
1364 }
1365 else
1366 {
1367 static const WCHAR closetagW[] = {'<','/'};
1368 static const WCHAR gtW[] = {'>'};
1369
1372 write_output_buffer(This, QName, nQName);
1374 }
1375
1377
1378 return S_OK;
1379}
1380
1382 ISAXContentHandler *iface,
1383 const WCHAR *chars,
1384 int nchars)
1385{
1387
1388 TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1389
1390 if (!chars) return E_INVALIDARG;
1391
1394
1395 if (!This->cdata)
1396 This->text = TRUE;
1397
1398 if (nchars)
1399 {
1400 if (This->cdata || This->props[MXWriter_DisableEscaping] == VARIANT_TRUE)
1401 write_output_buffer(This, chars, nchars);
1402 else
1403 {
1404 int len = nchars;
1405 WCHAR *escaped;
1406
1407 escaped = get_escaped_string(chars, EscapeText, &len);
1408 write_output_buffer(This, escaped, len);
1409 heap_free(escaped);
1410 }
1411 }
1412
1413 return S_OK;
1414}
1415
1417 ISAXContentHandler *iface,
1418 const WCHAR *chars,
1419 int nchars)
1420{
1422
1423 TRACE("(%p)->(%s)\n", This, debugstr_wn(chars, nchars));
1424
1425 if (!chars) return E_INVALIDARG;
1426
1427 write_output_buffer(This, chars, nchars);
1428
1429 return S_OK;
1430}
1431
1433 ISAXContentHandler *iface,
1434 const WCHAR *target,
1435 int ntarget,
1436 const WCHAR *data,
1437 int ndata)
1438{
1440 static const WCHAR openpiW[] = {'<','?'};
1441 static const WCHAR closepiW[] = {'?','>','\r','\n'};
1442
1443 TRACE("(%p)->(%s %s)\n", This, debugstr_wn(target, ntarget), debugstr_wn(data, ndata));
1444
1445 if (!target) return E_INVALIDARG;
1446
1448 write_output_buffer(This, openpiW, ARRAY_SIZE(openpiW));
1449
1450 if (*target)
1451 write_output_buffer(This, target, ntarget);
1452
1453 if (data && *data && ndata)
1454 {
1456 write_output_buffer(This, data, ndata);
1457 }
1458
1460 This->newline = TRUE;
1461
1462 return S_OK;
1463}
1464
1466 ISAXContentHandler *iface,
1467 const WCHAR *name,
1468 int nname)
1469{
1471 FIXME("(%p)->(%s)\n", This, debugstr_wn(name, nname));
1472 return E_NOTIMPL;
1473}
1474
1475static const struct ISAXContentHandlerVtbl SAXContentHandlerVtbl =
1476{
1491};
1492
1493/*** ISAXLexicalHandler ***/
1494static HRESULT WINAPI SAXLexicalHandler_QueryInterface(ISAXLexicalHandler *iface,
1495 REFIID riid, void **obj)
1496{
1498 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1499}
1500
1501static ULONG WINAPI SAXLexicalHandler_AddRef(ISAXLexicalHandler *iface)
1502{
1504 return IMXWriter_AddRef(&This->IMXWriter_iface);
1505}
1506
1507static ULONG WINAPI SAXLexicalHandler_Release(ISAXLexicalHandler *iface)
1508{
1510 return IMXWriter_Release(&This->IMXWriter_iface);
1511}
1512
1513static 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)
1516{
1517 static const WCHAR doctypeW[] = {'<','!','D','O','C','T','Y','P','E',' '};
1518 static const WCHAR openintW[] = {'[','\r','\n'};
1519
1521
1522 TRACE("(%p)->(%s %s %s)\n", This, debugstr_wn(name, name_len), debugstr_wn(publicId, publicId_len),
1523 debugstr_wn(systemId, systemId_len));
1524
1525 if (!name) return E_INVALIDARG;
1526
1527 write_output_buffer(This, doctypeW, ARRAY_SIZE(doctypeW));
1528
1529 if (*name)
1530 {
1531 write_output_buffer(This, name, name_len);
1533 }
1534
1535 if (publicId)
1536 {
1538 write_output_buffer_quoted(This, publicId, publicId_len);
1539
1540 if (!systemId) return E_INVALIDARG;
1541
1542 if (*publicId)
1544
1545 write_output_buffer_quoted(This, systemId, systemId_len);
1546
1547 if (*systemId)
1549 }
1550 else if (systemId)
1551 {
1553 write_output_buffer_quoted(This, systemId, systemId_len);
1554 if (*systemId)
1556 }
1557
1558 write_output_buffer(This, openintW, ARRAY_SIZE(openintW));
1559
1560 return S_OK;
1561}
1562
1563static HRESULT WINAPI SAXLexicalHandler_endDTD(ISAXLexicalHandler *iface)
1564{
1566 static const WCHAR closedtdW[] = {']','>','\r','\n'};
1567
1568 TRACE("(%p)\n", This);
1569
1570 write_output_buffer(This, closedtdW, ARRAY_SIZE(closedtdW));
1571
1572 return S_OK;
1573}
1574
1575static HRESULT WINAPI SAXLexicalHandler_startEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1576{
1578 FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1579 return E_NOTIMPL;
1580}
1581
1582static HRESULT WINAPI SAXLexicalHandler_endEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1583{
1585 FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1586 return E_NOTIMPL;
1587}
1588
1589static HRESULT WINAPI SAXLexicalHandler_startCDATA(ISAXLexicalHandler *iface)
1590{
1591 static const WCHAR scdataW[] = {'<','!','[','C','D','A','T','A','['};
1593
1594 TRACE("(%p)\n", This);
1595
1597 write_output_buffer(This, scdataW, ARRAY_SIZE(scdataW));
1598 This->cdata = TRUE;
1599
1600 return S_OK;
1601}
1602
1603static HRESULT WINAPI SAXLexicalHandler_endCDATA(ISAXLexicalHandler *iface)
1604{
1606 static const WCHAR ecdataW[] = {']',']','>'};
1607
1608 TRACE("(%p)\n", This);
1609
1610 write_output_buffer(This, ecdataW, ARRAY_SIZE(ecdataW));
1611 This->cdata = FALSE;
1612
1613 return S_OK;
1614}
1615
1616static HRESULT WINAPI SAXLexicalHandler_comment(ISAXLexicalHandler *iface, const WCHAR *chars, int nchars)
1617{
1619 static const WCHAR copenW[] = {'<','!','-','-'};
1620 static const WCHAR ccloseW[] = {'-','-','>','\r','\n'};
1621
1622 TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1623
1624 if (!chars) return E_INVALIDARG;
1625
1628
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));
1633
1634 return S_OK;
1635}
1636
1637static const struct ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl =
1638{
1649};
1650
1651/*** ISAXDeclHandler ***/
1652static HRESULT WINAPI SAXDeclHandler_QueryInterface(ISAXDeclHandler *iface,
1653 REFIID riid, void **obj)
1654{
1656 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1657}
1658
1659static ULONG WINAPI SAXDeclHandler_AddRef(ISAXDeclHandler *iface)
1660{
1662 return IMXWriter_AddRef(&This->IMXWriter_iface);
1663}
1664
1665static ULONG WINAPI SAXDeclHandler_Release(ISAXDeclHandler *iface)
1666{
1668 return IMXWriter_Release(&This->IMXWriter_iface);
1669}
1670
1671static HRESULT WINAPI SAXDeclHandler_elementDecl(ISAXDeclHandler *iface,
1672 const WCHAR *name, int n_name, const WCHAR *model, int n_model)
1673{
1674 static const WCHAR elementW[] = {'<','!','E','L','E','M','E','N','T',' '};
1676
1677 TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1678 debugstr_wn(model, n_model), n_model);
1679
1680 if (!name || !model) return E_INVALIDARG;
1681
1682 write_output_buffer(This, elementW, ARRAY_SIZE(elementW));
1683 if (n_name) {
1684 write_output_buffer(This, name, n_name);
1686 }
1687 if (n_model)
1688 write_output_buffer(This, model, n_model);
1690
1691 return S_OK;
1692}
1693
1694static 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)
1698{
1700 static const WCHAR attlistW[] = {'<','!','A','T','T','L','I','S','T',' '};
1701 static const WCHAR closetagW[] = {'>','\r','\n'};
1702
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);
1706
1707 write_output_buffer(This, attlistW, ARRAY_SIZE(attlistW));
1708 if (n_element) {
1709 write_output_buffer(This, element, n_element);
1711 }
1712
1713 if (n_attr) {
1714 write_output_buffer(This, attr, n_attr);
1716 }
1717
1718 if (n_type) {
1719 write_output_buffer(This, type, n_type);
1721 }
1722
1723 if (n_default) {
1724 write_output_buffer(This, Default, n_default);
1726 }
1727
1728 if (n_value)
1730
1732
1733 return S_OK;
1734}
1735
1737 const WCHAR *name, int n_name, const WCHAR *value, int n_value)
1738{
1740
1741 TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1742 debugstr_wn(value, n_value), n_value);
1743
1744 if (!name || !value) return E_INVALIDARG;
1745
1747 if (n_name) {
1748 write_output_buffer(This, name, n_name);
1750 }
1751
1752 if (n_value)
1754
1756
1757 return S_OK;
1758}
1759
1761 const WCHAR *name, int n_name, const WCHAR *publicId, int n_publicId,
1762 const WCHAR *systemId, int n_systemId)
1763{
1765
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);
1768
1769 if (!name || !systemId) return E_INVALIDARG;
1770
1772 if (n_name) {
1773 write_output_buffer(This, name, n_name);
1775 }
1776
1777 if (publicId)
1778 {
1780 write_output_buffer_quoted(This, publicId, n_publicId);
1782 write_output_buffer_quoted(This, systemId, n_systemId);
1783 }
1784 else
1785 {
1787 write_output_buffer_quoted(This, systemId, n_systemId);
1788 }
1789
1791
1792 return S_OK;
1793}
1794
1795static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl = {
1803};
1804
1805/*** IVBSAXDeclHandler ***/
1806static HRESULT WINAPI VBSAXDeclHandler_QueryInterface(IVBSAXDeclHandler *iface,
1807 REFIID riid, void **obj)
1808{
1810 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1811}
1812
1813static ULONG WINAPI VBSAXDeclHandler_AddRef(IVBSAXDeclHandler *iface)
1814{
1816 return IMXWriter_AddRef(&This->IMXWriter_iface);
1817}
1818
1819static ULONG WINAPI VBSAXDeclHandler_Release(IVBSAXDeclHandler *iface)
1820{
1822 return IMXWriter_Release(&This->IMXWriter_iface);
1823}
1824
1825static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfoCount(IVBSAXDeclHandler *iface, UINT* pctinfo)
1826{
1828 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1829}
1830
1831static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfo(IVBSAXDeclHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1832{
1834 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1835}
1836
1837static HRESULT WINAPI VBSAXDeclHandler_GetIDsOfNames(IVBSAXDeclHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1838 UINT cNames, LCID lcid, DISPID* rgDispId )
1839{
1841 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1842}
1843
1844static HRESULT WINAPI VBSAXDeclHandler_Invoke(IVBSAXDeclHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1845 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1846{
1848 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1849 pExcepInfo, puArgErr);
1850}
1851
1852static HRESULT WINAPI VBSAXDeclHandler_elementDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *model)
1853{
1855
1856 TRACE("(%p)->(%p %p)\n", This, name, model);
1857
1858 if (!name || !model)
1859 return E_POINTER;
1860
1861 return ISAXDeclHandler_elementDecl(&This->ISAXDeclHandler_iface, *name, -1, *model, -1);
1862}
1863
1864static HRESULT WINAPI VBSAXDeclHandler_attributeDecl(IVBSAXDeclHandler *iface,
1865 BSTR *element, BSTR *attr, BSTR *type, BSTR *default_value, BSTR *value)
1866{
1868
1869 TRACE("(%p)->(%p %p %p %p %p)\n", This, element, attr, type, default_value, value);
1870
1871 if (!element || !attr || !type || !default_value || !value)
1872 return E_POINTER;
1873
1874 return ISAXDeclHandler_attributeDecl(&This->ISAXDeclHandler_iface, *element, -1, *attr, -1, *type, -1,
1875 *default_value, -1, *value, -1);
1876}
1877
1879{
1881
1882 TRACE("(%p)->(%p %p)\n", This, name, value);
1883
1884 if (!name || !value)
1885 return E_POINTER;
1886
1887 return ISAXDeclHandler_internalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *value, -1);
1888}
1889
1891 BSTR *name, BSTR *publicid, BSTR *systemid)
1892{
1894
1895 TRACE("(%p)->(%p %p %p)\n", This, name, publicid, systemid);
1896
1897 if (!name || !publicid || !systemid)
1898 return E_POINTER;
1899
1900 return ISAXDeclHandler_externalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *publicid, -1, *systemid, -1);
1901}
1902
1903static const IVBSAXDeclHandlerVtbl VBSAXDeclHandlerVtbl = {
1915};
1916
1917/*** IVBSAXLexicalHandler ***/
1918static HRESULT WINAPI VBSAXLexicalHandler_QueryInterface(IVBSAXLexicalHandler *iface,
1919 REFIID riid, void **obj)
1920{
1922 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1923}
1924
1925static ULONG WINAPI VBSAXLexicalHandler_AddRef(IVBSAXLexicalHandler *iface)
1926{
1928 return IMXWriter_AddRef(&This->IMXWriter_iface);
1929}
1930
1931static ULONG WINAPI VBSAXLexicalHandler_Release(IVBSAXLexicalHandler *iface)
1932{
1934 return IMXWriter_Release(&This->IMXWriter_iface);
1935}
1936
1937static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfoCount(IVBSAXLexicalHandler *iface, UINT* pctinfo)
1938{
1940 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1941}
1942
1943static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfo(IVBSAXLexicalHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1944{
1946 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1947}
1948
1949static HRESULT WINAPI VBSAXLexicalHandler_GetIDsOfNames(IVBSAXLexicalHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1950 UINT cNames, LCID lcid, DISPID* rgDispId )
1951{
1953 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1954}
1955
1956static HRESULT WINAPI VBSAXLexicalHandler_Invoke(IVBSAXLexicalHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1957 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1958{
1960 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1961 pExcepInfo, puArgErr);
1962}
1963
1964static HRESULT WINAPI VBSAXLexicalHandler_startDTD(IVBSAXLexicalHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
1965{
1967
1968 TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
1969
1970 if (!name || !publicId || !systemId)
1971 return E_POINTER;
1972
1973 return ISAXLexicalHandler_startDTD(&This->ISAXLexicalHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
1974}
1975
1976static HRESULT WINAPI VBSAXLexicalHandler_endDTD(IVBSAXLexicalHandler *iface)
1977{
1979 return ISAXLexicalHandler_endDTD(&This->ISAXLexicalHandler_iface);
1980}
1981
1982static HRESULT WINAPI VBSAXLexicalHandler_startEntity(IVBSAXLexicalHandler *iface, BSTR *name)
1983{
1985
1986 TRACE("(%p)->(%p)\n", This, name);
1987
1988 if (!name)
1989 return E_POINTER;
1990
1991 return ISAXLexicalHandler_startEntity(&This->ISAXLexicalHandler_iface, *name, -1);
1992}
1993
1994static HRESULT WINAPI VBSAXLexicalHandler_endEntity(IVBSAXLexicalHandler *iface, BSTR *name)
1995{
1997
1998 TRACE("(%p)->(%p)\n", This, name);
1999
2000 if (!name)
2001 return E_POINTER;
2002
2003 return ISAXLexicalHandler_endEntity(&This->ISAXLexicalHandler_iface, *name, -1);
2004}
2005
2006static HRESULT WINAPI VBSAXLexicalHandler_startCDATA(IVBSAXLexicalHandler *iface)
2007{
2009 return ISAXLexicalHandler_startCDATA(&This->ISAXLexicalHandler_iface);
2010}
2011
2012static HRESULT WINAPI VBSAXLexicalHandler_endCDATA(IVBSAXLexicalHandler *iface)
2013{
2015 return ISAXLexicalHandler_endCDATA(&This->ISAXLexicalHandler_iface);
2016}
2017
2018static HRESULT WINAPI VBSAXLexicalHandler_comment(IVBSAXLexicalHandler *iface, BSTR *chars)
2019{
2021
2022 TRACE("(%p)->(%p)\n", This, chars);
2023
2024 if (!chars)
2025 return E_POINTER;
2026
2027 return ISAXLexicalHandler_comment(&This->ISAXLexicalHandler_iface, *chars, -1);
2028}
2029
2030static const IVBSAXLexicalHandlerVtbl VBSAXLexicalHandlerVtbl = {
2045};
2046
2047/*** IVBSAXContentHandler ***/
2048static HRESULT WINAPI VBSAXContentHandler_QueryInterface(IVBSAXContentHandler *iface, REFIID riid, void **obj)
2049{
2051 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2052}
2053
2054static ULONG WINAPI VBSAXContentHandler_AddRef(IVBSAXContentHandler *iface)
2055{
2057 return IMXWriter_AddRef(&This->IMXWriter_iface);
2058}
2059
2060static ULONG WINAPI VBSAXContentHandler_Release(IVBSAXContentHandler *iface)
2061{
2063 return IMXWriter_Release(&This->IMXWriter_iface);
2064}
2065
2066static HRESULT WINAPI VBSAXContentHandler_GetTypeInfoCount(IVBSAXContentHandler *iface, UINT* pctinfo)
2067{
2069 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2070}
2071
2072static HRESULT WINAPI VBSAXContentHandler_GetTypeInfo(IVBSAXContentHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2073{
2075 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2076}
2077
2078static HRESULT WINAPI VBSAXContentHandler_GetIDsOfNames(IVBSAXContentHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2079 UINT cNames, LCID lcid, DISPID* rgDispId )
2080{
2082 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2083}
2084
2085static HRESULT WINAPI VBSAXContentHandler_Invoke(IVBSAXContentHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2086 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2087{
2089 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2090 pExcepInfo, puArgErr);
2091}
2092
2093static HRESULT WINAPI VBSAXContentHandler_putref_documentLocator(IVBSAXContentHandler *iface, IVBSAXLocator *locator)
2094{
2096 TRACE("(%p)->(%p)\n", This, locator);
2097 return S_OK;
2098}
2099
2100static HRESULT WINAPI VBSAXContentHandler_startDocument(IVBSAXContentHandler *iface)
2101{
2103 return ISAXContentHandler_startDocument(&This->ISAXContentHandler_iface);
2104}
2105
2106static HRESULT WINAPI VBSAXContentHandler_endDocument(IVBSAXContentHandler *iface)
2107{
2109 return ISAXContentHandler_endDocument(&This->ISAXContentHandler_iface);
2110}
2111
2112static HRESULT WINAPI VBSAXContentHandler_startPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix, BSTR *uri)
2113{
2115
2116 TRACE("(%p)->(%p %p)\n", This, prefix, uri);
2117
2118 if (!prefix || !uri)
2119 return E_POINTER;
2120
2121 return ISAXContentHandler_startPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1, *uri, -1);
2122}
2123
2124static HRESULT WINAPI VBSAXContentHandler_endPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix)
2125{
2127
2128 TRACE("(%p)->(%p)\n", This, prefix);
2129
2130 if (!prefix)
2131 return E_POINTER;
2132
2133 return ISAXContentHandler_endPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1);
2134}
2135
2136static HRESULT WINAPI VBSAXContentHandler_startElement(IVBSAXContentHandler *iface,
2137 BSTR *namespaceURI, BSTR *localName, BSTR *QName, IVBSAXAttributes *attrs)
2138{
2140
2141 TRACE("(%p)->(%p %p %p %p)\n", This, namespaceURI, localName, QName, attrs);
2142
2143 if (!namespaceURI || !localName || !QName)
2144 return E_POINTER;
2145
2146 TRACE("(%s %s %s)\n", debugstr_w(*namespaceURI), debugstr_w(*localName), debugstr_w(*QName));
2147
2148 mxwriter_write_starttag(This, *QName, SysStringLen(*QName));
2149
2150 if (attrs)
2151 {
2152 int length, i, escape;
2153 HRESULT hr;
2154
2155 hr = IVBSAXAttributes_get_length(attrs, &length);
2156 if (FAILED(hr)) return hr;
2157
2158 escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
2159 (This->class_version == MSXML4 || This->class_version == MSXML6);
2160
2161 for (i = 0; i < length; i++)
2162 {
2163 BSTR qname, value;
2164
2165 hr = IVBSAXAttributes_getQName(attrs, i, &qname);
2166 if (FAILED(hr)) return hr;
2167
2168 hr = IVBSAXAttributes_getValue(attrs, i, &value);
2169 if (FAILED(hr))
2170 {
2171 SysFreeString(qname);
2172 return hr;
2173 }
2174
2176 SysFreeString(qname);
2178 }
2179 }
2180
2181 return S_OK;
2182}
2183
2184static HRESULT WINAPI VBSAXContentHandler_endElement(IVBSAXContentHandler *iface, BSTR *namespaceURI,
2185 BSTR *localName, BSTR *QName)
2186{
2188
2189 TRACE("(%p)->(%p %p %p)\n", This, namespaceURI, localName, QName);
2190
2191 if (!namespaceURI || !localName || !QName)
2192 return E_POINTER;
2193
2194 return ISAXContentHandler_endElement(&This->ISAXContentHandler_iface,
2195 *namespaceURI, SysStringLen(*namespaceURI),
2196 *localName, SysStringLen(*localName),
2197 *QName, SysStringLen(*QName));
2198}
2199
2200static HRESULT WINAPI VBSAXContentHandler_characters(IVBSAXContentHandler *iface, BSTR *chars)
2201{
2203
2204 TRACE("(%p)->(%p)\n", This, chars);
2205
2206 if (!chars)
2207 return E_POINTER;
2208
2209 return ISAXContentHandler_characters(&This->ISAXContentHandler_iface, *chars, SysStringLen(*chars));
2210}
2211
2212static HRESULT WINAPI VBSAXContentHandler_ignorableWhitespace(IVBSAXContentHandler *iface, BSTR *chars)
2213{
2215
2216 TRACE("(%p)->(%p)\n", This, chars);
2217
2218 if (!chars)
2219 return E_POINTER;
2220
2221 return ISAXContentHandler_ignorableWhitespace(&This->ISAXContentHandler_iface, *chars, -1);
2222}
2223
2225 BSTR *target, BSTR *data)
2226{
2228
2229 TRACE("(%p)->(%p %p)\n", This, target, data);
2230
2231 if (!target || !data)
2232 return E_POINTER;
2233
2234 return ISAXContentHandler_processingInstruction(&This->ISAXContentHandler_iface, *target, -1, *data, -1);
2235}
2236
2237static HRESULT WINAPI VBSAXContentHandler_skippedEntity(IVBSAXContentHandler *iface, BSTR *name)
2238{
2240
2241 TRACE("(%p)->(%p)\n", This, name);
2242
2243 if (!name)
2244 return E_POINTER;
2245
2246 return ISAXContentHandler_skippedEntity(&This->ISAXContentHandler_iface, *name, -1);
2247}
2248
2249static const IVBSAXContentHandlerVtbl VBSAXContentHandlerVtbl = {
2268};
2269
2270static HRESULT WINAPI SAXDTDHandler_QueryInterface(ISAXDTDHandler *iface, REFIID riid, void **obj)
2271{
2273 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2274}
2275
2276static ULONG WINAPI SAXDTDHandler_AddRef(ISAXDTDHandler *iface)
2277{
2279 return IMXWriter_AddRef(&This->IMXWriter_iface);
2280}
2281
2282static ULONG WINAPI SAXDTDHandler_Release(ISAXDTDHandler *iface)
2283{
2285 return IMXWriter_Release(&This->IMXWriter_iface);
2286}
2287
2288static 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)
2292{
2293 static const WCHAR notationW[] = {'<','!','N','O','T','A','T','I','O','N',' '};
2295
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);
2298
2299 if (!name || !n_name)
2300 return E_INVALIDARG;
2301
2302 write_output_buffer(This, notationW, ARRAY_SIZE(notationW));
2303 write_output_buffer(This, name, n_name);
2304
2305 if (!publicid && !systemid)
2306 return E_INVALIDARG;
2307
2309 if (publicid)
2310 {
2312 write_output_buffer_quoted(This, publicid, n_publicid);
2313 if (systemid)
2314 {
2316 write_output_buffer_quoted(This, systemid, n_systemid);
2317 }
2318 }
2319 else
2320 {
2322 write_output_buffer_quoted(This, systemid, n_systemid);
2323 }
2324
2326
2327 return S_OK;
2328}
2329
2331 const WCHAR *name, INT nname,
2332 const WCHAR *publicid, INT npublicid,
2333 const WCHAR *systemid, INT nsystemid,
2334 const WCHAR *notation, INT nnotation)
2335{
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;
2341}
2342
2343static const ISAXDTDHandlerVtbl SAXDTDHandlerVtbl = {
2349};
2350
2351/*** IVBSAXDTDHandler ***/
2352static HRESULT WINAPI VBSAXDTDHandler_QueryInterface(IVBSAXDTDHandler *iface, REFIID riid, void **obj)
2353{
2355 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2356}
2357
2358static ULONG WINAPI VBSAXDTDHandler_AddRef(IVBSAXDTDHandler *iface)
2359{
2361 return IMXWriter_AddRef(&This->IMXWriter_iface);
2362}
2363
2364static ULONG WINAPI VBSAXDTDHandler_Release(IVBSAXDTDHandler *iface)
2365{
2367 return IMXWriter_Release(&This->IMXWriter_iface);
2368}
2369
2370static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfoCount(IVBSAXDTDHandler *iface, UINT* pctinfo)
2371{
2373 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2374}
2375
2376static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfo(IVBSAXDTDHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2377{
2379 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2380}
2381
2382static HRESULT WINAPI VBSAXDTDHandler_GetIDsOfNames(IVBSAXDTDHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2383 UINT cNames, LCID lcid, DISPID* rgDispId )
2384{
2386 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2387}
2388
2389static HRESULT WINAPI VBSAXDTDHandler_Invoke(IVBSAXDTDHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2390 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2391{
2393 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2394 pExcepInfo, puArgErr);
2395}
2396
2397static HRESULT WINAPI VBSAXDTDHandler_notationDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
2398{
2400
2401 TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
2402
2403 if (!name || !publicId || !systemId)
2404 return E_POINTER;
2405
2406 return ISAXDTDHandler_notationDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
2407}
2408
2409static HRESULT WINAPI VBSAXDTDHandler_unparsedEntityDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId,
2410 BSTR *systemId, BSTR *notation)
2411{
2413
2414 TRACE("(%p)->(%p %p %p %p)\n", This, name, publicId, systemId, notation);
2415
2416 if (!name || !publicId || !systemId || !notation)
2417 return E_POINTER;
2418
2419 return ISAXDTDHandler_unparsedEntityDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1,
2420 *systemId, -1, *notation, -1);
2421}
2422
2423static const IVBSAXDTDHandlerVtbl VBSAXDTDHandlerVtbl = {
2433};
2434
2435/* ISAXErrorHandler */
2436static HRESULT WINAPI SAXErrorHandler_QueryInterface(ISAXErrorHandler *iface, REFIID riid, void **obj)
2437{
2439 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2440}
2441
2442static ULONG WINAPI SAXErrorHandler_AddRef(ISAXErrorHandler *iface)
2443{
2445 return IMXWriter_AddRef(&This->IMXWriter_iface);
2446}
2447
2448static ULONG WINAPI SAXErrorHandler_Release(ISAXErrorHandler *iface)
2449{
2451 return IMXWriter_Release(&This->IMXWriter_iface);
2452}
2453
2454static HRESULT WINAPI SAXErrorHandler_error(ISAXErrorHandler *iface,
2455 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2456{
2458
2459 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2460
2461 return E_NOTIMPL;
2462}
2463
2464static HRESULT WINAPI SAXErrorHandler_fatalError(ISAXErrorHandler *iface,
2465 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2466{
2468
2469 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2470
2471 return E_NOTIMPL;
2472}
2473
2474static HRESULT WINAPI SAXErrorHandler_ignorableWarning(ISAXErrorHandler *iface,
2475 ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2476{
2478
2479 FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2480
2481 return E_NOTIMPL;
2482}
2483
2484static const ISAXErrorHandlerVtbl SAXErrorHandlerVtbl = {
2491};
2492
2493/*** IVBSAXErrorHandler ***/
2494static HRESULT WINAPI VBSAXErrorHandler_QueryInterface(IVBSAXErrorHandler *iface, REFIID riid, void **obj)
2495{
2497 return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2498}
2499
2500static ULONG WINAPI VBSAXErrorHandler_AddRef(IVBSAXErrorHandler *iface)
2501{
2503 return IMXWriter_AddRef(&This->IMXWriter_iface);
2504}
2505
2506static ULONG WINAPI VBSAXErrorHandler_Release(IVBSAXErrorHandler *iface)
2507{
2509 return IMXWriter_Release(&This->IMXWriter_iface);
2510}
2511
2512static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfoCount(IVBSAXErrorHandler *iface, UINT* pctinfo)
2513{
2515 return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2516}
2517
2518static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfo(IVBSAXErrorHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2519{
2521 return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2522}
2523
2524static HRESULT WINAPI VBSAXErrorHandler_GetIDsOfNames(IVBSAXErrorHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2525 UINT cNames, LCID lcid, DISPID* rgDispId )
2526{
2528 return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2529}
2530
2531static HRESULT WINAPI VBSAXErrorHandler_Invoke(IVBSAXErrorHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2532 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2533{
2535 return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2536 pExcepInfo, puArgErr);
2537}
2538
2539static HRESULT WINAPI VBSAXErrorHandler_error(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2540{
2542 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2543 return E_NOTIMPL;
2544}
2545
2546static HRESULT WINAPI VBSAXErrorHandler_fatalError(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2547{
2549 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2550 return E_NOTIMPL;
2551}
2552
2553static HRESULT WINAPI VBSAXErrorHandler_ignorableWarning(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2554{
2556 FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2557 return E_NOTIMPL;
2558}
2559
2560static const IVBSAXErrorHandlerVtbl VBSAXErrorHandlerVtbl = {
2571};
2572
2573static const tid_t mxwriter_iface_tids[] = {
2575 0
2576};
2577
2579 NULL,
2581 NULL,
2583};
2584
2586{
2587 static const WCHAR version10W[] = {'1','.','0',0};
2588 mxwriter *This;
2589 HRESULT hr;
2590
2591 TRACE("(%p)\n", ppObj);
2592
2593 This = heap_alloc( sizeof (*This) );
2594 if(!This)
2595 return E_OUTOFMEMORY;
2596
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;
2610
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;
2620
2621 This->element = NULL;
2622 This->cdata = FALSE;
2623 This->indent = 0;
2624 This->text = FALSE;
2625 This->newline = FALSE;
2626
2627 This->dest = NULL;
2628
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;
2635 }
2636
2637 init_dispex(&This->dispex, (IUnknown*)&This->IMXWriter_iface, &mxwriter_dispex);
2638
2639 *ppObj = &This->IMXWriter_iface;
2640
2641 TRACE("returning iface %p\n", *ppObj);
2642
2643 return S_OK;
2644}
2645
2646static HRESULT WINAPI MXAttributes_QueryInterface(IMXAttributes *iface, REFIID riid, void **ppObj)
2647{
2649
2650 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppObj);
2651
2652 *ppObj = NULL;
2653
2654 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2656 IsEqualGUID( riid, &IID_IMXAttributes ))
2657 {
2658 *ppObj = iface;
2659 }
2660 else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
2661 {
2662 *ppObj = &This->ISAXAttributes_iface;
2663 }
2664 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
2665 {
2666 *ppObj = &This->IVBSAXAttributes_iface;
2667 }
2668 else if (dispex_query_interface(&This->dispex, riid, ppObj))
2669 {
2670 return *ppObj ? S_OK : E_NOINTERFACE;
2671 }
2672 else
2673 {
2674 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2675 return E_NOINTERFACE;
2676 }
2677
2678 IMXAttributes_AddRef( iface );
2679
2680 return S_OK;
2681}
2682
2683static ULONG WINAPI MXAttributes_AddRef(IMXAttributes *iface)
2684{
2687 TRACE("(%p)->(%d)\n", This, ref );
2688 return ref;
2689}
2690
2691static ULONG WINAPI MXAttributes_Release(IMXAttributes *iface)
2692{
2694 LONG ref = InterlockedDecrement( &This->ref );
2695
2696 TRACE("(%p)->(%d)\n", This, ref);
2697
2698 if (ref == 0)
2699 {
2700 int i;
2701
2702 for (i = 0; i < This->length; i++)
2703 {
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);
2709 }
2710
2711 heap_free(This->attr);
2712 heap_free(This);
2713 }
2714
2715 return ref;
2716}
2717
2718static HRESULT WINAPI MXAttributes_GetTypeInfoCount(IMXAttributes *iface, UINT* pctinfo)
2719{
2721 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2722}
2723
2724static HRESULT WINAPI MXAttributes_GetTypeInfo(IMXAttributes *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2725{
2727 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2728}
2729
2731 IMXAttributes *iface,
2732 REFIID riid,
2733 LPOLESTR* rgszNames,
2734 UINT cNames,
2735 LCID lcid,
2736 DISPID* rgDispId)
2737{
2739 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2740 riid, rgszNames, cNames, lcid, rgDispId);
2741}
2742
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)
2753{
2755 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
2756 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2757}
2758
2759static HRESULT WINAPI MXAttributes_addAttribute(IMXAttributes *iface,
2760 BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2761{
2764 HRESULT hr;
2765
2766 TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(uri), debugstr_w(localName),
2768
2769 if ((!uri || !localName || !QName || !type || !value) && This->class_version != MSXML6)
2770 return E_INVALIDARG;
2771
2772 /* ensure array is large enough */
2774 if (hr != S_OK) return hr;
2775
2776 attr = &This->attr[This->length];
2777
2778 attr->qname = SysAllocString(QName);
2779 attr->local = SysAllocString(localName);
2780 attr->uri = SysAllocString(uri);
2781 attr->type = SysAllocString(type ? type : emptyW);
2783 This->length++;
2784
2785 return S_OK;
2786}
2787
2789 VARIANT atts, int index)
2790{
2792 FIXME("(%p)->(%s %d): stub\n", This, debugstr_variant(&atts), index);
2793 return E_NOTIMPL;
2794}
2795
2796static HRESULT WINAPI MXAttributes_clear(IMXAttributes *iface)
2797{
2799 int i;
2800
2801 TRACE("(%p)\n", This);
2802
2803 for (i = 0; i < This->length; i++)
2804 {
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));
2811 }
2812
2813 This->length = 0;
2814
2815 return S_OK;
2816}
2817
2819{
2820 if (index < 0 || index >= attrs->length) return NULL;
2821 return &attrs->attr[index];
2822}
2823
2824static HRESULT WINAPI MXAttributes_removeAttribute(IMXAttributes *iface, int index)
2825{
2828
2829 TRACE("(%p)->(%d)\n", This, index);
2830
2831 if (!(dst = get_attribute_byindex(This, index))) return E_INVALIDARG;
2832
2833 /* no need to remove last attribute, just make it inaccessible */
2834 if (index + 1 == This->length)
2835 {
2836 This->length--;
2837 return S_OK;
2838 }
2839
2840 memmove(dst, dst + 1, (This->length-index-1)*sizeof(*dst));
2841 This->length--;
2842
2843 return S_OK;
2844}
2845
2846static HRESULT WINAPI MXAttributes_setAttribute(IMXAttributes *iface, int index,
2847 BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2848{
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;
2853}
2854
2856{
2858 FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&atts));
2859 return E_NOTIMPL;
2860}
2861
2862static HRESULT WINAPI MXAttributes_setLocalName(IMXAttributes *iface, int index,
2863 BSTR localName)
2864{
2867
2868 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(localName));
2869
2871
2872 SysFreeString(attr->local);
2873 attr->local = SysAllocString(localName);
2874
2875 return S_OK;
2876}
2877
2878static HRESULT WINAPI MXAttributes_setQName(IMXAttributes *iface, int index, BSTR QName)
2879{
2882
2883 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(QName));
2884
2886
2887 SysFreeString(attr->qname);
2888 attr->qname = SysAllocString(QName);
2889
2890 return S_OK;
2891}
2892
2893static HRESULT WINAPI MXAttributes_setURI(IMXAttributes *iface, int index, BSTR uri)
2894{
2897
2898 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(uri));
2899
2901
2902 SysFreeString(attr->uri);
2903 attr->uri = SysAllocString(uri);
2904
2905 return S_OK;
2906}
2907
2908static HRESULT WINAPI MXAttributes_setValue(IMXAttributes *iface, int index, BSTR value)
2909{
2912
2913 TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(value));
2914
2916
2919
2920 return S_OK;
2921}
2922
2923static const IMXAttributesVtbl MXAttributesVtbl = {
2941};
2942
2943static HRESULT WINAPI SAXAttributes_QueryInterface(ISAXAttributes *iface, REFIID riid, void **ppObj)
2944{
2946 return IMXAttributes_QueryInterface(&This->IMXAttributes_iface, riid, ppObj);
2947}
2948
2949static ULONG WINAPI SAXAttributes_AddRef(ISAXAttributes *iface)
2950{
2952 return IMXAttributes_AddRef(&This->IMXAttributes_iface);
2953}
2954
2955static ULONG WINAPI SAXAttributes_Release(ISAXAttributes *iface)
2956{
2958 return IMXAttributes_Release(&This->IMXAttributes_iface);
2959}
2960
2961static HRESULT WINAPI SAXAttributes_getLength(ISAXAttributes *iface, int *length)
2962{
2964 TRACE("(%p)->(%p)\n", This, length);
2965
2966 if (!length && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
2967 return E_POINTER;
2968
2969 *length = This->length;
2970
2971 return S_OK;
2972}
2973
2974static HRESULT WINAPI SAXAttributes_getURI(ISAXAttributes *iface, int index, const WCHAR **uri,
2975 int *len)
2976{
2978
2979 TRACE("(%p)->(%d %p %p)\n", This, index, uri, len);
2980
2981 if (index >= This->length || index < 0) return E_INVALIDARG;
2982 if (!uri || !len) return E_POINTER;
2983
2984 *len = SysStringLen(This->attr[index].uri);
2985 *uri = This->attr[index].uri;
2986
2987 return S_OK;
2988}
2989
2990static HRESULT WINAPI SAXAttributes_getLocalName(ISAXAttributes *iface, int index, const WCHAR **name,
2991 int *len)
2992{
2994
2995 TRACE("(%p)->(%d %p %p)\n", This, index, name, len);
2996
2997 if (index >= This->length || index < 0) return E_INVALIDARG;
2998 if (!name || !len) return E_POINTER;
2999
3000 *len = SysStringLen(This->attr[index].local);
3001 *name = This->attr[index].local;
3002
3003 return S_OK;
3004}
3005
3006static HRESULT WINAPI SAXAttributes_getQName(ISAXAttributes *iface, int index, const WCHAR **qname, int *length)
3007{
3009
3010 TRACE("(%p)->(%d %p %p)\n", This, index, qname, length);
3011
3012 if (index >= This->length) return E_INVALIDARG;
3013 if (!qname || !length) return E_POINTER;
3014
3015 *qname = This->attr[index].qname;
3016 *length = SysStringLen(This->attr[index].qname);
3017
3018 return S_OK;
3019}
3020
3021static 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)
3023{
3025
3026 TRACE("(%p)->(%d %p %p %p %p %p %p)\n", This, index, uri, uri_len, local, local_len, qname, qname_len);
3027
3028 if (index >= This->length || index < 0)
3029 return E_INVALIDARG;
3030
3031 if (!uri || !uri_len || !local || !local_len || !qname || !qname_len)
3032 return E_POINTER;
3033
3034 *uri_len = SysStringLen(This->attr[index].uri);
3035 *uri = This->attr[index].uri;
3036
3037 *local_len = SysStringLen(This->attr[index].local);
3038 *local = This->attr[index].local;
3039
3040 *qname_len = SysStringLen(This->attr[index].qname);
3041 *qname = This->attr[index].qname;
3042
3043 TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*local), debugstr_w(*qname));
3044
3045 return S_OK;
3046}
3047
3048static HRESULT WINAPI SAXAttributes_getIndexFromName(ISAXAttributes *iface, const WCHAR *uri, int uri_len,
3049 const WCHAR *name, int len, int *index)
3050{
3052 int i;
3053
3054 TRACE("(%p)->(%s:%d %s:%d %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
3056
3057 if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3058 return E_POINTER;
3059
3060 if (!uri || !name || !index) return E_INVALIDARG;
3061
3062 for (i = 0; i < This->length; i++)
3063 {
3064 if (uri_len != SysStringLen(This->attr[i].uri)) continue;
3065 if (strncmpW(uri, This->attr[i].uri, uri_len)) continue;
3066
3067 if (len != SysStringLen(This->attr[i].local)) continue;
3068 if (strncmpW(name, This->attr[i].local, len)) continue;
3069
3070 *index = i;
3071 return S_OK;
3072 }
3073
3074 return E_INVALIDARG;
3075}
3076
3077static HRESULT WINAPI SAXAttributes_getIndexFromQName(ISAXAttributes *iface, const WCHAR *qname,
3078 int len, int *index)
3079{
3081 int i;
3082
3083 TRACE("(%p)->(%s:%d %p)\n", This, debugstr_wn(qname, len), len, index);
3084
3085 if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3086 return E_POINTER;
3087
3088 if (!qname || !index || !len) return E_INVALIDARG;
3089
3090 for (i = 0; i < This->length; i++)
3091 {
3092 if (len != SysStringLen(This->attr[i].qname)) continue;
3093 if (strncmpW(qname, This->attr[i].qname, len)) continue;
3094
3095 *index = i;
3096 return S_OK;
3097 }
3098
3099 return E_INVALIDARG;
3100}
3101
3102static HRESULT WINAPI SAXAttributes_getType(ISAXAttributes *iface, int index, const WCHAR **type,
3103 int *len)
3104{
3106
3107 TRACE("(%p)->(%d %p %p)\n", This, index, type, len);
3108
3109 if (index >= This->length) return E_INVALIDARG;
3110
3111 if ((!type || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3112 return E_POINTER;
3113
3114 *type = This->attr[index].type;
3115 *len = SysStringLen(This->attr[index].type);
3116
3117 return S_OK;
3118}
3119
3120static HRESULT WINAPI SAXAttributes_getTypeFromName(ISAXAttributes *iface, const WCHAR * pUri, int nUri,
3121 const WCHAR * pLocalName, int nLocalName, const WCHAR ** pType, int * nType)
3122{
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;
3127}
3128
3129static HRESULT WINAPI SAXAttributes_getTypeFromQName(ISAXAttributes *iface, const WCHAR * pQName,
3130 int nQName, const WCHAR ** pType, int * nType)
3131{
3133 FIXME("(%p)->(%s:%d %p %p): stub\n", This, debugstr_wn(pQName, nQName), nQName, pType, nType);
3134 return E_NOTIMPL;
3135}
3136
3137static HRESULT WINAPI SAXAttributes_getValue(ISAXAttributes *iface, int index, const WCHAR **value,
3138 int *len)
3139{
3141
3142 TRACE("(%p)->(%d %p %p)\n", This, index, value, len);
3143
3144 if (index >= This->length) return E_INVALIDARG;
3145
3146 if ((!value || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3147 return E_POINTER;
3148
3149 *value = This->attr[index].value;
3150 *len = SysStringLen(This->attr[index].value);
3151
3152 return S_OK;
3153}
3154
3155static 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)
3157{
3159 HRESULT hr;
3160 int index;
3161
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);
3164
3165 if (!uri || !name || !value || !value_len)
3166 return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3167
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);
3171
3172 return hr;
3173}
3174
3175static HRESULT WINAPI SAXAttributes_getValueFromQName(ISAXAttributes *iface, const WCHAR *qname,
3176 int qname_len, const WCHAR **value, int *value_len)
3177{
3179 HRESULT hr;
3180 int index;
3181
3182 TRACE("(%p)->(%s:%d %p %p)\n", This, debugstr_wn(qname, qname_len), qname_len, value, value_len);
3183
3184 if (!qname || !value || !value_len)
3185 return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3186
3187 hr = ISAXAttributes_getIndexFromQName(iface, qname, qname_len, &index);
3188 if (hr == S_OK)
3189 hr = ISAXAttributes_getValue(iface, index, value, value_len);
3190
3191 return hr;
3192}
3193
3194static const ISAXAttributesVtbl SAXAttributesVtbl = {
3211};
3212
3214 IVBSAXAttributes* iface,
3215 REFIID riid,
3216 void **ppvObject)
3217{
3219 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
3220 return ISAXAttributes_QueryInterface(&This->ISAXAttributes_iface, riid, ppvObject);
3221}
3222
3223static ULONG WINAPI VBSAXAttributes_AddRef(IVBSAXAttributes* iface)
3224{
3226 return ISAXAttributes_AddRef(&This->ISAXAttributes_iface);
3227}
3228
3229static ULONG WINAPI VBSAXAttributes_Release(IVBSAXAttributes* iface)
3230{
3232 return ISAXAttributes_Release(&This->ISAXAttributes_iface);
3233}
3234
3235static HRESULT WINAPI VBSAXAttributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
3236{
3238
3239 TRACE("(%p)->(%p)\n", This, pctinfo);
3240
3241 *pctinfo = 1;
3242
3243 return S_OK;
3244}
3245
3247 IVBSAXAttributes *iface,
3248 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
3249{
3251 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
3252 return get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
3253}
3254
3256 IVBSAXAttributes *iface,
3257 REFIID riid,
3258 LPOLESTR* rgszNames,
3259 UINT cNames,
3260 LCID lcid,
3261 DISPID* rgDispId)
3262{
3265 HRESULT hr;
3266
3267 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
3268 lcid, rgDispId);
3269
3270 if(!rgszNames || cNames == 0 || !rgDispId)
3271 return E_INVALIDARG;
3272
3274 if(SUCCEEDED(hr))
3275 {
3276 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
3277 ITypeInfo_Release(typeinfo);
3278 }
3279
3280 return hr;
3281}
3282
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)
3293{
3296 HRESULT hr;
3297
3298 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
3299 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3300
3302 if(SUCCEEDED(hr))
3303 {
3304 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
3305 pDispParams, pVarResult, pExcepInfo, puArgErr);
3306 ITypeInfo_Release(typeinfo);
3307 }
3308
3309 return hr;
3310}
3311
3312static HRESULT WINAPI VBSAXAttributes_get_length(IVBSAXAttributes* iface, int *len)
3313{
3315 return ISAXAttributes_getLength(&This->ISAXAttributes_iface, len);
3316}
3317
3318static HRESULT WINAPI VBSAXAttributes_getURI(IVBSAXAttributes* iface, int index, BSTR *uri)
3319{
3321 const WCHAR *uriW;
3322 HRESULT hr;
3323 int len;
3324
3325 TRACE("(%p)->(%d %p)\n", This, index, uri);
3326
3327 if (!uri)
3328 return E_POINTER;
3329
3330 *uri = NULL;
3331 hr = ISAXAttributes_getURI(&This->ISAXAttributes_iface, index, &uriW, &len);
3332 if (FAILED(hr))
3333 return hr;
3334
3335 return return_bstrn(uriW, len, uri);
3336}
3337
3338static HRESULT WINAPI VBSAXAttributes_getLocalName(IVBSAXAttributes* iface, int index, BSTR *name)
3339{
3341 const WCHAR *nameW;
3342 HRESULT hr;
3343 int len;
3344
3345 TRACE("(%p)->(%d %p)\n", This, index, name);
3346
3347 if (!name)
3348 return E_POINTER;
3349
3350 *name = NULL;
3351 hr = ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, index, &nameW, &len);
3352 if (FAILED(hr))
3353 return hr;
3354
3355 return return_bstrn(nameW, len, name);
3356}
3357
3358static HRESULT WINAPI VBSAXAttributes_getQName(IVBSAXAttributes* iface, int index, BSTR *qname)
3359{
3361 const WCHAR *qnameW;
3362 HRESULT hr;
3363 int len;
3364
3365 TRACE("(%p)->(%d %p)\n", This, index, qname);
3366
3367 if (!qname)
3368 return E_POINTER;
3369
3370 *qname = NULL;
3371 hr = ISAXAttributes_getQName(&This->ISAXAttributes_iface, index, &qnameW, &len);
3372 if (FAILED(hr))
3373 return hr;
3374
3375 return return_bstrn(qnameW, len, qname);
3376}
3377
3378static HRESULT WINAPI VBSAXAttributes_getIndexFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name, int *index)
3379{
3381 return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3383}
3384
3385static HRESULT WINAPI VBSAXAttributes_getIndexFromQName(IVBSAXAttributes* iface, BSTR qname, int *index)
3386{
3388 return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, qname,
3389 SysStringLen(qname), index);
3390}
3391
3392static HRESULT WINAPI VBSAXAttributes_getType(IVBSAXAttributes* iface, int index, BSTR *type)
3393{
3395 const WCHAR *typeW;
3396 HRESULT hr;
3397 int len;
3398
3399 TRACE("(%p)->(%d %p)\n", This, index, type);
3400
3401 if (!type)
3402 return E_POINTER;
3403
3404 *type = NULL;
3405 hr = ISAXAttributes_getType(&This->ISAXAttributes_iface, index, &typeW, &len);
3406 if (FAILED(hr))
3407 return hr;
3408
3409 return return_bstrn(typeW, len, type);
3410}
3411
3413 BSTR name, BSTR *type)
3414{
3416 const WCHAR *typeW;
3417 HRESULT hr;
3418 int len;
3419
3420 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), type);
3421
3422 if (!type)
3423 return E_POINTER;
3424
3425 *type = NULL;
3426 hr = ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3428 if (FAILED(hr))
3429 return hr;
3430
3431 return return_bstrn(typeW, len, type);
3432}
3433
3434static HRESULT WINAPI VBSAXAttributes_getTypeFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *type)
3435{
3437 const WCHAR *typeW;
3438 HRESULT hr;
3439 int len;
3440
3441 TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), type);
3442
3443 if (!type)
3444 return E_POINTER;
3445
3446 *type = NULL;
3447 hr = ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3448 &typeW, &len);
3449 if (FAILED(hr))
3450 return hr;
3451
3452 return return_bstrn(typeW, len, type);
3453}
3454
3455static HRESULT WINAPI VBSAXAttributes_getValue(IVBSAXAttributes* iface, int index, BSTR *value)
3456{
3458 const WCHAR *valueW;
3459 HRESULT hr;
3460 int len;
3461
3462 TRACE("(%p)->(%d %p)\n", This, index, value);
3463
3464 if (!value)
3465 return E_POINTER;
3466
3467 *value = NULL;
3468 hr = ISAXAttributes_getValue(&This->ISAXAttributes_iface, index, &valueW, &len);
3469 if (FAILED(hr))
3470 return hr;
3471
3472 return return_bstrn(valueW, len, value);
3473}
3474
3476 BSTR *value)
3477{
3479 const WCHAR *valueW;
3480 HRESULT hr;
3481 int len;
3482
3483 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), value);
3484
3485 if (!value)
3486 return E_POINTER;
3487
3488 *value = NULL;
3489 hr = ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3491 if (FAILED(hr))
3492 return hr;
3493
3494 return return_bstrn(valueW, len, value);
3495}
3496
3497static HRESULT WINAPI VBSAXAttributes_getValueFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *value)
3498{
3500 const WCHAR *valueW;
3501 HRESULT hr;
3502 int len;
3503
3504 TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), value);
3505
3506 if (!value)
3507 return E_POINTER;
3508
3509 *value = NULL;
3510 hr = ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3511 &valueW, &len);
3512 if (FAILED(hr))
3513 return hr;
3514
3515 return return_bstrn(valueW, len, value);
3516}
3517
3518static const struct IVBSAXAttributesVtbl VBSAXAttributesVtbl =
3519{
3539};
3540
3541static const tid_t mxattrs_iface_tids[] = {
3543 0
3544};
3545
3547 NULL,
3549 NULL,
3551};
3552
3554{
3555 static const int default_count = 10;
3557
3558 TRACE("(%p)\n", ppObj);
3559
3560 This = heap_alloc( sizeof (*This) );
3561 if( !This )
3562 return E_OUTOFMEMORY;
3563
3564 This->IMXAttributes_iface.lpVtbl = &MXAttributesVtbl;
3565 This->ISAXAttributes_iface.lpVtbl = &SAXAttributesVtbl;
3566 This->IVBSAXAttributes_iface.lpVtbl = &VBSAXAttributesVtbl;
3567 This->ref = 1;
3568
3569 This->class_version = version;
3570
3571 This->attr = heap_alloc(default_count*sizeof(mxattribute));
3572 This->length = 0;
3573 This->allocated = default_count;
3574
3575 *ppObj = &This->IMXAttributes_iface;
3576
3577 init_dispex(&This->dispex, (IUnknown*)&This->IMXAttributes_iface, &mxattrs_dispex);
3578
3579 TRACE("returning iface %p\n", *ppObj);
3580
3581 return S_OK;
3582}
static int avail
Definition: adh-main.c:39
HRESULT get_typeinfo(enum type_id tid, ITypeInfo **ret)
Definition: apps.c:124
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static const WCHAR nameW[]
Definition: main.c:46
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:33
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:114
#define ERR(fmt,...)
Definition: debug.h:113
_In_ uint16_t _Out_ ULONG * atts
Definition: btrfs_drv.h:1107
Definition: list.h:37
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR indent[]
Definition: object.c:1156
OLECHAR * BSTR
Definition: compat.h:2293
#define WideCharToMultiByte
Definition: compat.h:111
short VARIANT_BOOL
Definition: compat.h:2290
@ VT_BSTR
Definition: compat.h:2303
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_EMPTY
Definition: compat.h:2295
static const WCHAR version[]
Definition: asmname.c:66
static const WCHAR valueW[]
Definition: object.c:48
static const WCHAR typeW[]
Definition: name.c:51
static const WCHAR versionW[]
Definition: name.c:52
static const WCHAR gtW[]
Definition: reader.c:96
static const WCHAR ltW[]
Definition: reader.c:95
static const WCHAR closepiW[]
Definition: writer.c:47
static BSTR local_name(call_frame_t *frame, int ref)
Definition: engine.c:187
static unsigned char buff[32768]
Definition: fatten.c:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned short WORD
Definition: ntddk_ex.h:93
#define local
Definition: zutil.h:30
FxCollectionEntry * cur
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLenum mode
Definition: glext.h:6217
GLenum GLenum dst
Definition: glext.h:6340
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLenum target
Definition: glext.h:7315
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static const WCHAR yesW[]
Definition: htmlbody.c:594
static const WCHAR noW[]
Definition: htmlbody.c:595
tid_t
Definition: ieframe.h:311
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:919
#define c
Definition: ke_i.h:80
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
POINT cp
Definition: magnifier.c:59
static int blocks
Definition: mkdosfs.c:527
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static PVOID ptr
Definition: dispmode.c:27
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
static char * dest
Definition: rtl.c:135
static LPOLESTR
Definition: stg_prop.c:27
static VARIANTARG static DISPID
Definition: ordinal.c:52
const char * uri
Definition: sec_mgr.c:1588
static WCHAR escape[]
Definition: url.c:36
#define min(a, b)
Definition: monoChain.cc:55
BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv)
Definition: dispex.c:1656
MSXML_VERSION
Definition: msxml_private.h:34
@ MSXML_DEFAULT
Definition: msxml_private.h:35
@ MSXML4
Definition: msxml_private.h:39
@ MSXML6
Definition: msxml_private.h:40
@ MSXML3
Definition: msxml_private.h:38
@ IMXWriter_tid
Definition: msxml_private.h:83
@ IMXAttributes_tid
Definition: msxml_private.h:81
@ IVBSAXAttributes_tid
Definition: msxml_private.h:71
static HRESULT return_bstrn(const WCHAR *value, int len, BSTR *p)
static HRESULT return_bstr(const WCHAR *value, BSTR *p)
static HRESULT WINAPI SAXErrorHandler_fatalError(ISAXErrorHandler *iface, ISAXLocator *locator, const WCHAR *message, HRESULT hr)
Definition: mxwriter.c:2464
static ULONG WINAPI SAXDeclHandler_Release(ISAXDeclHandler *iface)
Definition: mxwriter.c:1665
static HRESULT WINAPI SAXLexicalHandler_comment(ISAXLexicalHandler *iface, const WCHAR *chars, int nchars)
Definition: mxwriter.c:1616
static HRESULT WINAPI mxwriter_get_indent(IMXWriter *iface, VARIANT_BOOL *value)
Definition: mxwriter.c:1046
static HRESULT WINAPI SAXAttributes_getValue(ISAXAttributes *iface, int index, const WCHAR **value, int *len)
Definition: mxwriter.c:3137
static HRESULT WINAPI MXAttributes_GetTypeInfoCount(IMXAttributes *iface, UINT *pctinfo)
Definition: mxwriter.c:2718
static const IVBSAXErrorHandlerVtbl VBSAXErrorHandlerVtbl
Definition: mxwriter.c:2560
static HRESULT WINAPI SAXContentHandler_endElement(ISAXContentHandler *iface, const WCHAR *namespaceUri, int nnamespaceUri, const WCHAR *local_name, int nlocal_name, const WCHAR *QName, int nQName)
Definition: mxwriter.c:1340
static const WCHAR iso_8859_9W[]
Definition: mxwriter.c:82
static ULONG WINAPI SAXAttributes_AddRef(ISAXAttributes *iface)
Definition: mxwriter.c:2949
static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfo(IVBSAXErrorHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: mxwriter.c:2518
static HRESULT WINAPI VBSAXAttributes_getIndexFromQName(IVBSAXAttributes *iface, BSTR qname, int *index)
Definition: mxwriter.c:3385
static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfoCount(IVBSAXLexicalHandler *iface, UINT *pctinfo)
Definition: mxwriter.c:1937
static HRESULT WINAPI VBSAXAttributes_QueryInterface(IVBSAXAttributes *iface, REFIID riid, void **ppvObject)
Definition: mxwriter.c:3213
static HRESULT WINAPI mxwriter_GetIDsOfNames(IMXWriter *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
Definition: mxwriter.c:865
static ULONG WINAPI VBSAXLexicalHandler_AddRef(IVBSAXLexicalHandler *iface)
Definition: mxwriter.c:1925
static HRESULT WINAPI VBSAXContentHandler_ignorableWhitespace(IVBSAXContentHandler *iface, BSTR *chars)
Definition: mxwriter.c:2212
static const IVBSAXDeclHandlerVtbl VBSAXDeclHandlerVtbl
Definition: mxwriter.c:1903
static HRESULT WINAPI VBSAXLexicalHandler_endDTD(IVBSAXLexicalHandler *iface)
Definition: mxwriter.c:1976
static HRESULT WINAPI VBSAXContentHandler_GetTypeInfoCount(IVBSAXContentHandler *iface, UINT *pctinfo)
Definition: mxwriter.c:2066
static HRESULT WINAPI VBSAXAttributes_getQName(IVBSAXAttributes *iface, int index, BSTR *qname)
Definition: mxwriter.c:3358
static void write_node_indent(mxwriter *writer)
Definition: mxwriter.c:617
static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfo(IVBSAXLexicalHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: mxwriter.c:1943
static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfoCount(IVBSAXErrorHandler *iface, UINT *pctinfo)
Definition: mxwriter.c:2512
static HRESULT WINAPI VBSAXContentHandler_endPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix)
Definition: mxwriter.c:2124
static HRESULT WINAPI SAXDeclHandler_internalEntityDecl(ISAXDeclHandler *iface, const WCHAR *name, int n_name, const WCHAR *value, int n_value)
Definition: mxwriter.c:1736
static HRESULT WINAPI SAXAttributes_getName(ISAXAttributes *iface, int index, const WCHAR **uri, int *uri_len, const WCHAR **local, int *local_len, const WCHAR **qname, int *qname_len)
Definition: mxwriter.c:3021
static const IVBSAXDTDHandlerVtbl VBSAXDTDHandlerVtbl
Definition: mxwriter.c:2423
static HRESULT WINAPI mxwriter_get_standalone(IMXWriter *iface, VARIANT_BOOL *value)
Definition: mxwriter.c:1062
static ULONG WINAPI VBSAXErrorHandler_AddRef(IVBSAXErrorHandler *iface)
Definition: mxwriter.c:2500
static HRESULT WINAPI SAXAttributes_getIndexFromQName(ISAXAttributes *iface, const WCHAR *qname, int len, int *index)
Definition: mxwriter.c:3077
static const struct IVBSAXAttributesVtbl VBSAXAttributesVtbl
Definition: mxwriter.c:3518