ReactOS 0.4.17-dev-966-gf06eace
writer.c
Go to the documentation of this file.
1/*
2 * IXmlWriter implementation
3 *
4 * Copyright 2011 Alistair Leslie-Hughes
5 * Copyright 2014-2018 Nikolay Sivov for CodeWeavers
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#define COBJMACROS
22
23#include <assert.h>
24#include <stdarg.h>
25
26#include "windef.h"
27#include "winbase.h"
28#include "objbase.h"
29#include "xmllite.h"
30#include "xmllite_private.h"
31#ifdef __REACTOS__
32#include <wchar.h>
33#include <winnls.h>
34#endif
35#include "initguid.h"
36
37#include "wine/debug.h"
38#include "wine/list.h"
39
41
42/* not defined in public headers */
43DEFINE_GUID(IID_IXmlWriterOutput, 0xc1131708, 0x0f59, 0x477f, 0x93, 0x59, 0x7d, 0x33, 0x24, 0x51, 0xbc, 0x1a);
44
45static const WCHAR xmlnsuriW[] = L"http://www.w3.org/2000/xmlns/";
46
47struct output_buffer
48{
49 char *data;
50 unsigned int allocated;
51 unsigned int written;
53};
54
55typedef enum
56{
57 XmlWriterState_Initial, /* output is not set yet */
58 XmlWriterState_Ready, /* SetOutput() was called, ready to start */
59 XmlWriterState_InvalidEncoding, /* SetOutput() was called, but output had invalid encoding */
60 XmlWriterState_PIDocStarted, /* document was started with manually added 'xml' PI */
61 XmlWriterState_DocStarted, /* document was started with WriteStartDocument() */
62 XmlWriterState_ElemStarted, /* writing element */
63 XmlWriterState_Content, /* content is accepted at this point */
64 XmlWriterState_DocClosed /* WriteEndDocument was called */
66
67typedef struct
68{
75 WCHAR *encoding_name; /* exactly as specified on output creation */
79
80static const struct IUnknownVtbl xmlwriteroutputvtbl;
81
82struct element
83{
84 struct list entry;
86 unsigned int len; /* qname length in chars */
87 struct list ns;
88};
89
90struct ns
91{
92 struct list entry;
97 struct element *element;
98};
99
100typedef struct _xmlwriter
101{
106 unsigned int indent_level;
117
119{
120 return CONTAINING_RECORD(iface, xmlwriter, IXmlWriter_iface);
121}
122
124{
125 return CONTAINING_RECORD(iface, xmlwriteroutput, IXmlWriterOutput_iface);
126}
127
129{
130 static const char * const prop_names[] =
131 {
132 "MultiLanguage",
133 "Indent",
134 "ByteOrderMark",
135 "OmitXmlDeclaration",
136 "ConformanceLevel"
137 };
138
139 if (prop > _XmlWriterProperty_Last)
140 return wine_dbg_sprintf("unknown property=%d", prop);
141
142 return prop_names[prop];
143}
144
146 const WCHAR *encoding_name, xmlwriteroutput **out);
147
148/* writer output memory allocation functions */
149static inline void *writeroutput_alloc(xmlwriteroutput *output, size_t len)
150{
151 return m_alloc(output->imalloc, len);
152}
153
154static inline void writeroutput_free(xmlwriteroutput *output, void *mem)
155{
156 m_free(output->imalloc, mem);
157}
158
159static inline void *writeroutput_realloc(xmlwriteroutput *output, void *mem, size_t len)
160{
161 return m_realloc(output->imalloc, mem, len);
162}
163
164/* writer memory allocation functions */
165static inline void *writer_alloc(const xmlwriter *writer, size_t len)
166{
167 return m_alloc(writer->imalloc, len);
168}
169
170static inline void writer_free(const xmlwriter *writer, void *mem)
171{
172 m_free(writer->imalloc, mem);
173}
174
176{
177 return !str || !*str;
178}
179
180static struct element *alloc_element(xmlwriter *writer, const WCHAR *prefix, const WCHAR *local)
181{
182 struct element *ret;
183 int len;
184
185 ret = writer_alloc(writer, sizeof(*ret));
186 if (!ret) return ret;
187
188 len = is_empty_string(prefix) ? 0 : lstrlenW(prefix) + 1 /* ':' */;
189 len += lstrlenW(local);
190
191 ret->qname = writer_alloc(writer, (len + 1)*sizeof(WCHAR));
192
193 if (!ret->qname)
194 {
195 writer_free(writer, ret);
196 return NULL;
197 }
198
199 ret->len = len;
201 ret->qname[0] = 0;
202 else
203 {
204 lstrcpyW(ret->qname, prefix);
205 lstrcatW(ret->qname, L":");
206 }
207 lstrcatW(ret->qname, local);
208 list_init(&ret->ns);
209
210 return ret;
211}
212
213static void writer_free_element(xmlwriter *writer, struct element *element)
214{
215 struct ns *ns, *ns2;
216
217 LIST_FOR_EACH_ENTRY_SAFE(ns, ns2, &element->ns, struct ns, entry)
218 {
220 writer_free(writer, ns->prefix);
221 writer_free(writer, ns->uri);
222 writer_free(writer, ns);
223 }
224
225 writer_free(writer, element->qname);
226 writer_free(writer, element);
227}
228
230{
231 struct element *element, *element2;
232
233 LIST_FOR_EACH_ENTRY_SAFE(element, element2, &writer->elements, struct element, entry)
234 {
237 }
238}
239
240static void writer_push_element(xmlwriter *writer, struct element *element)
241{
242 list_add_head(&writer->elements, &element->entry);
243}
244
245static struct element *pop_element(xmlwriter *writer)
246{
247 struct element *element = LIST_ENTRY(list_head(&writer->elements), struct element, entry);
248
249 if (element)
251
252 return element;
253}
254
255static WCHAR *writer_strndupW(const xmlwriter *writer, const WCHAR *str, int len)
256{
257 WCHAR *ret;
258
259 if (!str)
260 return NULL;
261
262 if (len == -1)
263 len = lstrlenW(str);
264
265 ret = writer_alloc(writer, (len + 1) * sizeof(WCHAR));
266 if (ret)
267 {
268 memcpy(ret, str, len * sizeof(WCHAR));
269 ret[len] = 0;
270 }
271
272 return ret;
273}
274
275static WCHAR *writer_strdupW(const xmlwriter *writer, const WCHAR *str)
276{
277 return writer_strndupW(writer, str, -1);
278}
279
280static struct ns *writer_push_ns(xmlwriter *writer, const WCHAR *prefix, int prefix_len, const WCHAR *uri)
281{
282 struct element *element;
283 struct ns *ns;
284
285 element = LIST_ENTRY(list_head(&writer->elements), struct element, entry);
286 if (!element)
287 return NULL;
288
289 if ((ns = writer_alloc(writer, sizeof(*ns))))
290 {
293 ns->uri = writer_strdupW(writer, uri);
294 ns->emitted = FALSE;
295 ns->element = element;
297 }
298
299 return ns;
300}
301
302static struct ns *writer_find_ns_current(const xmlwriter *writer, const WCHAR *prefix, const WCHAR *uri)
303{
304 struct element *element;
305 struct ns *ns;
306
308 return NULL;
309
310 element = LIST_ENTRY(list_head(&writer->elements), struct element, entry);
311
313 {
314 if (!wcscmp(uri, ns->uri) && !wcscmp(prefix, ns->prefix))
315 return ns;
316 }
317
318 return NULL;
319}
320
321static struct ns *writer_find_ns(const xmlwriter *writer, const WCHAR *prefix, const WCHAR *uri)
322{
323 struct element *element;
324 struct ns *ns;
325
327 return NULL;
328
330 {
332 {
333 if (!uri)
334 {
335 if (!ns->prefix) continue;
336 if (!wcscmp(ns->prefix, prefix))
337 return ns;
338 }
339 else if (!wcscmp(uri, ns->uri))
340 {
341 if (prefix && !*prefix)
342 return NULL;
343 if (!prefix || !wcscmp(prefix, ns->prefix))
344 return ns;
345 }
346 }
347 }
348
349 return NULL;
350}
351
352static HRESULT is_valid_ncname(const WCHAR *str, int *out)
353{
354 int len = 0;
355
356 *out = 0;
357
358 if (!str || !*str)
359 return S_OK;
360
361 while (*str)
362 {
363 if (!is_ncnamechar(*str))
364 return WC_E_NAMECHARACTER;
365 len++;
366 str++;
367 }
368
369 *out = len;
370 return S_OK;
371}
372
373static HRESULT is_valid_name(const WCHAR *str, unsigned int *out)
374{
375 unsigned int len = 1;
376
377 *out = 0;
378
379 if (!str || !*str)
380 return S_OK;
381
382 if (!is_namestartchar(*str++))
383 return WC_E_NAMECHARACTER;
384
385 while (*str)
386 {
387 if (!is_namechar(*str))
388 return WC_E_NAMECHARACTER;
389 len++;
390 str++;
391 }
392
393 *out = len;
394 return S_OK;
395}
396
397static HRESULT is_valid_pubid(const WCHAR *str, unsigned int *out)
398{
399 unsigned int len = 0;
400
401 *out = 0;
402
403 if (!str || !*str)
404 return S_OK;
405
406 while (*str)
407 {
408 if (!is_pubchar(*str++))
409 return WC_E_PUBLICID;
410 len++;
411 }
412
413 *out = len;
414
415 return S_OK;
416}
417
419{
420 struct output_buffer *buffer = &output->buffer;
421 const int initial_len = 0x2000;
422 UINT cp = ~0u;
423 HRESULT hr;
424
425 if (FAILED(hr = get_code_page(output->encoding, &cp)))
426 WARN("Failed to get code page for specified encoding.\n");
427
428 buffer->data = writeroutput_alloc(output, initial_len);
429 if (!buffer->data) return E_OUTOFMEMORY;
430
431 memset(buffer->data, 0, 4);
432 buffer->allocated = initial_len;
433 buffer->written = 0;
434 buffer->codepage = cp;
435
436 return S_OK;
437}
438
440{
441 struct output_buffer *buffer = &output->buffer;
442 writeroutput_free(output, buffer->data);
443 buffer->data = NULL;
444 buffer->allocated = 0;
445 buffer->written = 0;
446}
447
449{
450 struct output_buffer *buffer = &output->buffer;
451 /* grow if needed, plus 4 bytes to be sure null terminator will fit in */
452 if (buffer->allocated < buffer->written + length + 4) {
453 int grown_size = max(2*buffer->allocated, buffer->allocated + length);
454 char *ptr = writeroutput_realloc(output, buffer->data, grown_size);
455 if (!ptr) return E_OUTOFMEMORY;
456 buffer->data = ptr;
457 buffer->allocated = grown_size;
458 }
459
460 return S_OK;
461}
462
464{
465 struct output_buffer *buffer = &output->buffer;
466 int length;
467 HRESULT hr;
468 char *ptr;
469
470 if (buffer->codepage == 1200) {
471 /* For UTF-16 encoding just copy. */
472 length = len == -1 ? lstrlenW(data) : len;
473 if (length) {
474 length *= sizeof(WCHAR);
475
476 hr = grow_output_buffer(output, length);
477 if (FAILED(hr)) return hr;
478 ptr = buffer->data + buffer->written;
479
481 buffer->written += length;
482 ptr += length;
483 /* null termination */
484 *(WCHAR*)ptr = 0;
485 }
486 }
487 else {
488 length = WideCharToMultiByte(buffer->codepage, 0, data, len, NULL, 0, NULL, NULL);
489 hr = grow_output_buffer(output, length);
490 if (FAILED(hr)) return hr;
491 ptr = buffer->data + buffer->written;
493 buffer->written += len == -1 ? length-1 : length;
494 }
495 output->written = length != 0;
496
497 return S_OK;
498}
499
501{
502 return write_output_buffer(output, &ch, 1);
503}
504
506{
507 write_output_buffer_char(output, '"');
508 if (!is_empty_string(data))
509 write_output_buffer(output, data, len);
510 write_output_buffer_char(output, '"');
511 return S_OK;
512}
513
514/* TODO: test if we need to validate char range */
515static HRESULT write_output_qname(xmlwriteroutput *output, const WCHAR *prefix, int prefix_len,
516 const WCHAR *local_name, int local_len)
517{
518 assert(prefix_len >= 0 && local_len >= 0);
519
520 if (prefix_len)
521 write_output_buffer(output, prefix, prefix_len);
522
523 if (prefix_len && local_len)
524 write_output_buffer_char(output, ':');
525
526 write_output_buffer(output, local_name, local_len);
527
528 return S_OK;
529}
530
532{
533 if (writeroutput->stream) {
534 ISequentialStream_Release(writeroutput->stream);
535 writeroutput->stream = NULL;
536 }
537}
538
540{
541 HRESULT hr;
542
543 writeroutput_release_stream(writeroutput);
544 hr = IUnknown_QueryInterface(writeroutput->output, &IID_IStream, (void**)&writeroutput->stream);
545 if (hr != S_OK)
546 hr = IUnknown_QueryInterface(writeroutput->output, &IID_ISequentialStream, (void**)&writeroutput->stream);
547
548 return hr;
549}
550
552{
553 struct output_buffer *buffer;
554 ULONG written, offset = 0;
555 HRESULT hr;
556
557 if (!output || !output->stream)
558 return S_OK;
559
560 buffer = &output->buffer;
561
562 /* It will loop forever until everything is written or an error occurred. */
563 do {
564 written = 0;
565 hr = ISequentialStream_Write(output->stream, buffer->data + offset, buffer->written, &written);
566 if (FAILED(hr)) {
567 WARN("write to stream failed %#lx.\n", hr);
568 buffer->written = 0;
569 return hr;
570 }
571
572 offset += written;
573 buffer->written -= written;
574 } while (buffer->written > 0);
575
576 return S_OK;
577}
578
580{
581 if (!writer->bom || writer->bomwritten) return S_OK;
582
583 if (writer->output->encoding == XmlEncoding_UTF16) {
584 static const char utf16bom[] = {0xff, 0xfe};
585 struct output_buffer *buffer = &writer->output->buffer;
586 int len = sizeof(utf16bom);
587 HRESULT hr;
588
589 hr = grow_output_buffer(writer->output, len);
590 if (FAILED(hr)) return hr;
591 memcpy(buffer->data + buffer->written, utf16bom, len);
592 buffer->written += len;
593 }
594
595 writer->bomwritten = TRUE;
596 return S_OK;
597}
598
600{
601 if (output->encoding_name)
602 return output->encoding_name;
603
604 return get_encoding_name(output->encoding);
605}
606
607static HRESULT write_xmldecl(xmlwriter *writer, XmlStandalone standalone)
608{
609 write_encoding_bom(writer);
611 if (writer->omitxmldecl) return S_OK;
612
613 /* version */
614 write_output_buffer(writer->output, L"<?xml version=\"1.0\"", 19);
615
616 /* encoding */
617 write_output_buffer(writer->output, L" encoding=", 10);
619
620 /* standalone */
621 if (standalone == XmlStandalone_Omit)
622 write_output_buffer(writer->output, L"?>", 2);
623 else
624 {
625 write_output_buffer(writer->output, L" standalone=\"", 13);
626 if (standalone == XmlStandalone_Yes)
627 write_output_buffer(writer->output, L"yes\"?>", 6);
628 else
629 write_output_buffer(writer->output, L"no\"?>", 5);
630 }
631
632 return S_OK;
633}
634
635static void writer_output_ns(xmlwriter *writer, struct element *element)
636{
637 struct ns *ns;
638
640 {
641 if (ns->emitted)
642 continue;
643
644 write_output_qname(writer->output, L" xmlns", 6, ns->prefix, ns->prefix_len);
645 write_output_buffer_char(writer->output, '=');
647 }
648}
649
651{
652 HRESULT hr;
653
654 if (!writer->starttagopen) return S_OK;
655
656 writer_output_ns(writer, LIST_ENTRY(list_head(&writer->elements), struct element, entry));
657 hr = write_output_buffer_char(writer->output, '>');
658 writer->starttagopen = 0;
659 return hr;
660}
661
662static void writer_inc_indent(xmlwriter *writer)
663{
664 writer->indent_level++;
665}
666
667static void writer_dec_indent(xmlwriter *writer)
668{
669 if (writer->indent_level)
670 writer->indent_level--;
671}
672
673static void write_node_indent(xmlwriter *writer)
674{
675 unsigned int indent_level = writer->indent_level;
676
677 if (!writer->indent || writer->textnode)
678 {
679 writer->textnode = 0;
680 return;
681 }
682
683 /* Do state check to prevent newline inserted after BOM. It is assumed that
684 state does not change between writing BOM and inserting indentation. */
685 if (writer->output->written && writer->state != XmlWriterState_Ready)
686 write_output_buffer(writer->output, L"\r\n", 2);
687 while (indent_level--)
688 write_output_buffer(writer->output, L" ", 2);
689
690 writer->textnode = 0;
691}
692
694{
696
697 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
698
699 if (IsEqualGUID(riid, &IID_IXmlWriter) ||
701 {
702 *ppvObject = iface;
703 }
704 else
705 {
706 FIXME("interface %s is not supported\n", debugstr_guid(riid));
707 *ppvObject = NULL;
708 return E_NOINTERFACE;
709 }
710
711 IXmlWriter_AddRef(iface);
712
713 return S_OK;
714}
715
717{
718 xmlwriter *writer = impl_from_IXmlWriter(iface);
719 ULONG ref = InterlockedIncrement(&writer->ref);
720 TRACE("%p, refcount %lu.\n", iface, ref);
721 return ref;
722}
723
725{
726 xmlwriter *writer = impl_from_IXmlWriter(iface);
727 ULONG ref = InterlockedDecrement(&writer->ref);
728
729 TRACE("%p, refcount %lu.\n", iface, ref);
730
731 if (!ref)
732 {
733 IMalloc *imalloc = writer->imalloc;
734
736 if (writer->output)
737 IUnknown_Release(&writer->output->IXmlWriterOutput_iface);
738
740
741 writer_free(writer, writer);
742 if (imalloc) IMalloc_Release(imalloc);
743 }
744
745 return ref;
746}
747
748/*** IXmlWriter methods ***/
750{
752 IXmlWriterOutput *writeroutput;
753 HRESULT hr;
754
755 TRACE("(%p)->(%p)\n", This, output);
756
757 if (This->output) {
759 IUnknown_Release(&This->output->IXmlWriterOutput_iface);
760 This->output = NULL;
761 This->bomwritten = 0;
762 This->textnode = 0;
763 This->indent_level = 0;
765 }
766
767 /* just reset current output */
768 if (!output) {
770 return S_OK;
771 }
772
773 /* now try IXmlWriterOutput, ISequentialStream, IStream */
774 hr = IUnknown_QueryInterface(output, &IID_IXmlWriterOutput, (void**)&writeroutput);
775 if (hr == S_OK) {
776 if (writeroutput->lpVtbl == &xmlwriteroutputvtbl)
777 This->output = impl_from_IXmlWriterOutput(writeroutput);
778 else {
779 ERR("got external IXmlWriterOutput implementation: %p, vtbl=%p\n",
780 writeroutput, writeroutput->lpVtbl);
781 IUnknown_Release(writeroutput);
782 return E_FAIL;
783 }
784 }
785
786 if (hr != S_OK || !writeroutput) {
787 /* Create output for given stream. */
788 hr = create_writer_output(output, This->imalloc, XmlEncoding_UTF8, NULL, &This->output);
789 if (hr != S_OK)
790 return hr;
791 }
792
793 if (This->output->encoding == XmlEncoding_Unknown)
795 else
796 This->state = XmlWriterState_Ready;
797 return writeroutput_query_for_stream(This->output);
798}
799
801{
803
804 TRACE("(%p)->(%s %p)\n", This, debugstr_writer_prop(property), value);
805
806 if (!value) return E_INVALIDARG;
807
808 switch (property)
809 {
811 *value = This->indent;
812 break;
814 *value = This->bom;
815 break;
817 *value = This->omitxmldecl;
818 break;
820 *value = This->conformance;
821 break;
822 default:
823 FIXME("Unimplemented property (%u)\n", property);
824 return E_NOTIMPL;
825 }
826
827 return S_OK;
828}
829
831{
832 xmlwriter *writer = impl_from_IXmlWriter(iface);
833
834 TRACE("%p, %s, %Id.\n", iface, debugstr_writer_prop(property), value);
835
836 switch (property)
837 {
839 writer->indent = !!value;
840 break;
842 writer->bom = !!value;
843 break;
845 writer->omitxmldecl = !!value;
846 break;
847 default:
848 FIXME("Unimplemented property (%u)\n", property);
849 return E_NOTIMPL;
850 }
851
852 return S_OK;
853}
854
855static HRESULT writer_write_attribute(IXmlWriter *writer, IXmlReader *reader, BOOL write_default_attributes)
856{
857 const WCHAR *prefix, *local, *uri, *value;
858 HRESULT hr;
859
860 if (IXmlReader_IsDefault(reader) && !write_default_attributes)
861 return S_OK;
862
863 if (FAILED(hr = IXmlReader_GetPrefix(reader, &prefix, NULL))) return hr;
864 if (FAILED(hr = IXmlReader_GetLocalName(reader, &local, NULL))) return hr;
865 if (FAILED(hr = IXmlReader_GetNamespaceUri(reader, &uri, NULL))) return hr;
866 if (FAILED(hr = IXmlReader_GetValue(reader, &value, NULL))) return hr;
867 return IXmlWriter_WriteAttributeString(writer, prefix, local, uri, value);
868}
869
870static HRESULT WINAPI xmlwriter_WriteAttributes(IXmlWriter *iface, IXmlReader *reader, BOOL write_default_attributes)
871{
872 XmlNodeType node_type;
873 HRESULT hr = S_OK;
874
875 TRACE("%p, %p, %d.\n", iface, reader, write_default_attributes);
876
877 if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr;
878
879 switch (node_type)
880 {
884 if (node_type != XmlNodeType_Attribute)
885 {
886 if (FAILED(hr = IXmlReader_MoveToFirstAttribute(reader))) return hr;
887 if (hr == S_FALSE) return S_OK;
888 }
889 if (FAILED(hr = writer_write_attribute(iface, reader, write_default_attributes))) return hr;
890 while (IXmlReader_MoveToNextAttribute(reader) == S_OK)
891 {
892 if (FAILED(hr = writer_write_attribute(iface, reader, write_default_attributes))) break;
893 }
894 if (node_type != XmlNodeType_Attribute && SUCCEEDED(hr))
895 hr = IXmlReader_MoveToElement(reader);
896 break;
897 default:
898 WARN("Unexpected node type %d.\n", node_type);
899 return E_UNEXPECTED;
900 }
901
902 return hr;
903}
904
905static void write_output_attribute(xmlwriter *writer, const WCHAR *prefix, int prefix_len,
906 const WCHAR *local, int local_len, const WCHAR *value)
907{
908 write_output_buffer_char(writer->output, ' ');
909 write_output_qname(writer->output, prefix, prefix_len, local, local_len);
910 write_output_buffer_char(writer->output, '=');
912}
913
915{
916 return value && (!wcscmp(value, L"preserve") || !wcscmp(value, L"default"));
917}
918
921{
922 xmlwriter *writer = impl_from_IXmlWriter(iface);
923 BOOL is_xmlns_prefix, is_xmlns_local;
924 int prefix_len, local_len;
925 struct ns *ns;
926 HRESULT hr;
927
928 TRACE("%p, %s, %s, %s, %s.\n", iface, debugstr_w(prefix), debugstr_w(local), debugstr_w(uri), debugstr_w(value));
929
930 switch (writer->state)
931 {
933 return E_UNEXPECTED;
937 return WR_E_INVALIDACTION;
939 return MX_E_ENCODING;
940 default:
941 ;
942 }
943
944 /* Prefix "xmlns" */
945 is_xmlns_prefix = prefix && !wcscmp(prefix, L"xmlns");
946 if (is_xmlns_prefix && is_empty_string(uri) && is_empty_string(local))
948
950 return E_INVALIDARG;
951
952 /* Validate prefix and local name */
954 return hr;
955
956 if (FAILED(hr = is_valid_ncname(local, &local_len)))
957 return hr;
958
959 is_xmlns_local = !wcscmp(local, L"xmlns");
960
961 /* Trivial case, no prefix. */
962 if (prefix_len == 0 && is_empty_string(uri))
963 {
964 write_output_attribute(writer, prefix, prefix_len, local, local_len, value);
965 return S_OK;
966 }
967
968 /* Predefined "xml" prefix. */
969 if (prefix_len && !wcscmp(prefix, L"xml"))
970 {
971 /* Valid "space" value is enforced. */
972 if (!wcscmp(local, L"space") && !is_valid_xml_space_value(value))
974
975 /* Redefinition is not allowed. */
976 if (!is_empty_string(uri))
978
979 write_output_attribute(writer, prefix, prefix_len, local, local_len, value);
980
981 return S_OK;
982 }
983
984 if (is_xmlns_prefix || (prefix_len == 0 && uri && !wcscmp(uri, xmlnsuriW)))
985 {
988
989 /* Look for exact match defined in current element, and write it out. */
990 if (!(ns = writer_find_ns_current(writer, prefix, value)))
991 ns = writer_push_ns(writer, local, local_len, value);
992 ns->emitted = TRUE;
993
994 write_output_attribute(writer, L"xmlns", 5, local, local_len, value);
995
996 return S_OK;
997 }
998
999 /* Ignore prefix if URI wasn't specified. */
1000 if (is_xmlns_local && is_empty_string(uri))
1001 {
1002 write_output_attribute(writer, NULL, 0, L"xmlns", 5, value);
1003 return S_OK;
1004 }
1005
1006 if (!(ns = writer_find_ns(writer, prefix, uri)))
1007 {
1009 {
1010 FIXME("Prefix autogeneration is not implemented.\n");
1011 return E_NOTIMPL;
1012 }
1013 if (!is_empty_string(uri))
1014 ns = writer_push_ns(writer, prefix, prefix_len, uri);
1015 }
1016
1017 if (ns)
1018 write_output_attribute(writer, ns->prefix, ns->prefix_len, local, local_len, value);
1019 else
1020 write_output_attribute(writer, prefix, prefix_len, local, local_len, value);
1021
1022 return S_OK;
1023}
1024
1025static void write_cdata_section(xmlwriteroutput *output, const WCHAR *data, int len)
1026{
1027 write_output_buffer(output, L"<![CDATA[", 9);
1028 if (data)
1029 write_output_buffer(output, data, len);
1030 write_output_buffer(output, L"]]>", 3);
1031}
1032
1034{
1036 int len;
1037
1038 TRACE("%p %s\n", This, debugstr_w(data));
1039
1040 switch (This->state)
1041 {
1043 return E_UNEXPECTED;
1046 break;
1050 return WR_E_INVALIDACTION;
1052 return MX_E_ENCODING;
1053 default:
1054 ;
1055 }
1056
1057 len = data ? lstrlenW(data) : 0;
1058
1060 if (!len)
1061 write_cdata_section(This->output, NULL, 0);
1062 else
1063 {
1064 while (len)
1065 {
1066 const WCHAR *str = wcsstr(data, L"]]>");
1067 if (str) {
1068 str += 2;
1069 write_cdata_section(This->output, data, str - data);
1070 len -= str - data;
1071 data = str;
1072 }
1073 else {
1074 write_cdata_section(This->output, data, len);
1075 break;
1076 }
1077 }
1078 }
1079
1080 return S_OK;
1081}
1082
1084{
1086 WCHAR bufW[16];
1087
1088 TRACE("%p %#x\n", This, ch);
1089
1090 switch (This->state)
1091 {
1093 return E_UNEXPECTED;
1095 return MX_E_ENCODING;
1098 break;
1100 return WR_E_INVALIDACTION;
1101 default:
1102 ;
1103 }
1104
1105 swprintf(bufW, ARRAY_SIZE(bufW), L"&#x%x;", ch);
1106 write_output_buffer(This->output, bufW, -1);
1107
1108 return S_OK;
1109}
1110
1111static HRESULT writer_get_next_write_count(const WCHAR *str, unsigned int length, unsigned int *count)
1112{
1113 if (!is_char(*str)) return WC_E_XMLCHARACTER;
1114
1115 if (IS_HIGH_SURROGATE(*str))
1116 {
1117 if (length < 2 || !IS_LOW_SURROGATE(*(str + 1)))
1119
1120 *count = 2;
1121 }
1122 else if (IS_LOW_SURROGATE(*str))
1124 else
1125 *count = 1;
1126
1127 return S_OK;
1128}
1129
1130static HRESULT write_escaped_char(xmlwriter *writer, const WCHAR *string, unsigned int count)
1131{
1132 HRESULT hr;
1133
1134 switch (*string)
1135 {
1136 case '<':
1137 hr = write_output_buffer(writer->output, L"&lt;", 4);
1138 break;
1139 case '&':
1140 hr = write_output_buffer(writer->output, L"&amp;", 5);
1141 break;
1142 case '>':
1143 hr = write_output_buffer(writer->output, L"&gt;", 4);
1144 break;
1145 default:
1146 hr = write_output_buffer(writer->output, string, count);
1147 }
1148
1149 return hr;
1150}
1151
1152static HRESULT write_escaped_string(xmlwriter *writer, const WCHAR *string, unsigned int length)
1153{
1154 unsigned int count;
1155 HRESULT hr = S_OK;
1156
1157 if (length == ~0u)
1158 {
1159 while (*string)
1160 {
1161 if (FAILED(hr = writer_get_next_write_count(string, ~0u, &count))) return hr;
1162 if (FAILED(hr = write_escaped_char(writer, string, count))) return hr;
1163
1164 string += count;
1165 }
1166 }
1167 else
1168 {
1169 while (length)
1170 {
1171 if (FAILED(hr = writer_get_next_write_count(string, length, &count))) return hr;
1172 if (FAILED(hr = write_escaped_char(writer, string, count))) return hr;
1173
1174 string += count;
1175 length -= count;
1176 }
1177 }
1178
1179 return hr;
1180}
1181
1183{
1184 xmlwriter *writer = impl_from_IXmlWriter(iface);
1185
1186 TRACE("%p, %s, %d.\n", iface, debugstr_wn(characters, length), length);
1187
1188 if ((characters == NULL && length != 0))
1189 return E_INVALIDARG;
1190
1191 if (length == 0)
1192 return S_OK;
1193
1194 switch (writer->state)
1195 {
1197 return E_UNEXPECTED;
1199 return MX_E_ENCODING;
1201 writer_close_starttag(writer);
1202 break;
1206 return WR_E_INVALIDACTION;
1207 default:
1208 ;
1209 }
1210
1211 writer->textnode = 1;
1212 return write_escaped_string(writer, characters, length);
1213}
1214
1216{
1218
1219 TRACE("%p %s\n", This, debugstr_w(comment));
1220
1221 switch (This->state)
1222 {
1224 return E_UNEXPECTED;
1226 return MX_E_ENCODING;
1229 break;
1231 return WR_E_INVALIDACTION;
1232 default:
1233 ;
1234 }
1235
1237 write_output_buffer(This->output, L"<!--", 4);
1238 if (comment) {
1239 int len = lstrlenW(comment), i;
1240
1241 /* Make sure there's no two hyphen sequences in a string, space is used as a separator to produce compliant
1242 comment string */
1243 if (len > 1) {
1244 for (i = 0; i < len; i++) {
1245 write_output_buffer(This->output, comment + i, 1);
1246 if (comment[i] == '-' && (i + 1 < len) && comment[i+1] == '-')
1247 write_output_buffer_char(This->output, ' ');
1248 }
1249 }
1250 else
1252
1253 if (len && comment[len-1] == '-')
1254 write_output_buffer_char(This->output, ' ');
1255 }
1256 write_output_buffer(This->output, L"-->", 3);
1257
1258 return S_OK;
1259}
1260
1262 LPCWSTR sysid, LPCWSTR subset)
1263{
1265 unsigned int name_len, pubid_len;
1266 HRESULT hr;
1267
1268 TRACE("(%p)->(%s %s %s %s)\n", This, wine_dbgstr_w(name), wine_dbgstr_w(pubid), wine_dbgstr_w(sysid),
1269 wine_dbgstr_w(subset));
1270
1271 switch (This->state)
1272 {
1274 return E_UNEXPECTED;
1276 return MX_E_ENCODING;
1279 return WR_E_INVALIDACTION;
1280 default:
1281 ;
1282 }
1283
1284 if (is_empty_string(name))
1285 return E_INVALIDARG;
1286
1287 if (FAILED(hr = is_valid_name(name, &name_len)))
1288 return hr;
1289
1290 if (FAILED(hr = is_valid_pubid(pubid, &pubid_len)))
1291 return hr;
1292
1293 write_output_buffer(This->output, L"<!DOCTYPE ", 10);
1294 write_output_buffer(This->output, name, name_len);
1295
1296 if (pubid)
1297 {
1298 write_output_buffer(This->output, L" PUBLIC ", 8);
1299 write_output_buffer_quoted(This->output, pubid, pubid_len);
1300 write_output_buffer_char(This->output, ' ');
1301 write_output_buffer_quoted(This->output, sysid, -1);
1302 }
1303 else if (sysid)
1304 {
1305 write_output_buffer(This->output, L" SYSTEM ", 8);
1306 write_output_buffer_quoted(This->output, sysid, -1);
1307 }
1308
1309 if (subset)
1310 {
1311 write_output_buffer_char(This->output, ' ');
1312 write_output_buffer_char(This->output, '[');
1313 write_output_buffer(This->output, subset, -1);
1314 write_output_buffer_char(This->output, ']');
1315 }
1316 write_output_buffer_char(This->output, '>');
1317
1319
1320 return S_OK;
1321}
1322
1325{
1327 int prefix_len, local_len;
1328 struct ns *ns;
1329 HRESULT hr;
1330
1331 TRACE("(%p)->(%s %s %s %s)\n", This, wine_dbgstr_w(prefix), wine_dbgstr_w(local_name),
1333
1334 switch (This->state)
1335 {
1337 return E_UNEXPECTED;
1339 return MX_E_ENCODING;
1342 break;
1344 return WR_E_INVALIDACTION;
1345 default:
1346 ;
1347 }
1348
1349 if (!local_name)
1350 return E_INVALIDARG;
1351
1352 /* Validate prefix and local name */
1354 return hr;
1355
1356 if (FAILED(hr = is_valid_ncname(local_name, &local_len)))
1357 return hr;
1358
1362
1363 if (uri && !wcscmp(uri, xmlnsuriW))
1364 {
1365 if (!prefix)
1367
1368 if (!is_empty_string(prefix))
1370 }
1371
1374
1375 write_output_buffer_char(This->output, '<');
1376 if (ns)
1377 write_output_qname(This->output, ns->prefix, ns->prefix_len, local_name, local_len);
1378 else
1379 write_output_qname(This->output, prefix, prefix_len, local_name, local_len);
1380
1381 if (!ns && (prefix_len || !is_empty_string(uri)))
1382 {
1383 write_output_qname(This->output, L" xmlns", 6, prefix, prefix_len);
1384 write_output_buffer_char(This->output, '=');
1385 write_output_buffer_quoted(This->output, uri, -1);
1386 }
1387
1388 if (value)
1389 {
1390 write_output_buffer_char(This->output, '>');
1391 write_output_buffer(This->output, value, -1);
1392 write_output_buffer(This->output, L"</", 2);
1393 write_output_qname(This->output, prefix, prefix_len, local_name, local_len);
1394 write_output_buffer_char(This->output, '>');
1395 }
1396 else
1397 write_output_buffer(This->output, L" />", 3);
1398
1400
1401 return S_OK;
1402}
1403
1405{
1407
1408 TRACE("%p\n", This);
1409
1410 switch (This->state)
1411 {
1413 return E_UNEXPECTED;
1417 return WR_E_INVALIDACTION;
1419 return MX_E_ENCODING;
1420 default:
1421 ;
1422 }
1423
1424 /* empty element stack */
1425 while (IXmlWriter_WriteEndElement(iface) == S_OK)
1426 ;
1427
1429 return S_OK;
1430}
1431
1433{
1435 struct element *element;
1436
1437 TRACE("%p\n", This);
1438
1439 switch (This->state)
1440 {
1442 return E_UNEXPECTED;
1446 return WR_E_INVALIDACTION;
1448 return MX_E_ENCODING;
1449 default:
1450 ;
1451 }
1452
1454 if (!element)
1455 return WR_E_INVALIDACTION;
1456
1458
1459 if (This->starttagopen)
1460 {
1462 write_output_buffer(This->output, L" />", 3);
1463 This->starttagopen = 0;
1464 }
1465 else
1466 {
1467 /* Write full end tag. */
1469 write_output_buffer(This->output, L"</", 2);
1471 write_output_buffer_char(This->output, '>');
1472 }
1474
1475 return S_OK;
1476}
1477
1479{
1481
1482 FIXME("%p %s\n", This, wine_dbgstr_w(pwszName));
1483
1484 switch (This->state)
1485 {
1487 return E_UNEXPECTED;
1489 return MX_E_ENCODING;
1491 return WR_E_INVALIDACTION;
1492 default:
1493 ;
1494 }
1495
1496 return E_NOTIMPL;
1497}
1498
1500{
1502 struct element *element;
1503
1504 TRACE("%p\n", This);
1505
1506 switch (This->state)
1507 {
1509 return E_UNEXPECTED;
1513 return WR_E_INVALIDACTION;
1515 return MX_E_ENCODING;
1518 break;
1519 default:
1520 ;
1521 }
1522
1524 if (!element)
1525 return WR_E_INVALIDACTION;
1526
1528
1529 /* don't force full end tag to the next line */
1530 if (This->state == XmlWriterState_ElemStarted)
1531 {
1533 This->textnode = 0;
1534 }
1535 else
1537
1538 /* write full end tag */
1539 write_output_buffer(This->output, L"</", 2);
1541 write_output_buffer_char(This->output, '>');
1542
1544
1545 return S_OK;
1546}
1547
1549{
1551
1552 FIXME("%p %s\n", This, wine_dbgstr_w(pwszName));
1553
1554 switch (This->state)
1555 {
1557 return E_UNEXPECTED;
1561 return WR_E_INVALIDACTION;
1563 return MX_E_ENCODING;
1564 default:
1565 ;
1566 }
1567
1568 return E_NOTIMPL;
1569}
1570
1572{
1574
1575 FIXME("%p %s\n", This, wine_dbgstr_w(pwszNmToken));
1576
1577 switch (This->state)
1578 {
1580 return E_UNEXPECTED;
1584 return WR_E_INVALIDACTION;
1586 return MX_E_ENCODING;
1587 default:
1588 ;
1589 }
1590
1591 return E_NOTIMPL;
1592}
1593
1594static HRESULT writer_write_node(IXmlWriter *writer, IXmlReader *reader, BOOL shallow, BOOL write_default_attributes)
1595{
1596 XmlStandalone standalone = XmlStandalone_Omit;
1597 const WCHAR *name, *value, *prefix, *uri;
1598 unsigned int start_depth = 0, depth;
1599 XmlNodeType node_type;
1600 HRESULT hr;
1601
1602 if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr;
1603
1604 switch (node_type)
1605 {
1606 case XmlNodeType_None:
1607 if (shallow) return S_OK;
1608 while ((hr = IXmlReader_Read(reader, NULL)) == S_OK)
1609 {
1610 if (FAILED(hr = writer_write_node(writer, reader, FALSE, write_default_attributes))) return hr;
1611 }
1612 break;
1614 if (FAILED(hr = IXmlReader_GetPrefix(reader, &prefix, NULL))) return hr;
1615 if (FAILED(hr = IXmlReader_GetLocalName(reader, &name, NULL))) return hr;
1616 if (FAILED(hr = IXmlReader_GetNamespaceUri(reader, &uri, NULL))) return hr;
1617 if (FAILED(hr = IXmlWriter_WriteStartElement(writer, prefix, name, uri))) return hr;
1618 if (FAILED(hr = IXmlWriter_WriteAttributes(writer, reader, write_default_attributes))) return hr;
1619 if (IXmlReader_IsEmptyElement(reader))
1620 {
1621 hr = IXmlWriter_WriteEndElement(writer);
1622 }
1623 else
1624 {
1625 if (shallow) return S_OK;
1626 if (FAILED(hr = IXmlReader_MoveToElement(reader))) return hr;
1627 if (FAILED(hr = IXmlReader_GetDepth(reader, &start_depth))) return hr;
1628 while ((hr = IXmlReader_Read(reader, &node_type)) == S_OK)
1629 {
1630 if (FAILED(hr = writer_write_node(writer, reader, FALSE, write_default_attributes))) return hr;
1631 if (FAILED(hr = IXmlReader_MoveToElement(reader))) return hr;
1632
1633 depth = 0;
1634 if (FAILED(hr = IXmlReader_GetDepth(reader, &depth))) return hr;
1635 if (node_type == XmlNodeType_EndElement && (start_depth == depth - 1)) break;
1636 }
1637 }
1638 break;
1640 break;
1641 case XmlNodeType_Text:
1642 if (FAILED(hr = IXmlReader_GetValue(reader, &value, NULL))) return hr;
1643 hr = IXmlWriter_WriteRaw(writer, value);
1644 break;
1645 case XmlNodeType_CDATA:
1646 if (FAILED(hr = IXmlReader_GetValue(reader, &value, NULL))) return hr;
1647 hr = IXmlWriter_WriteCData(writer, value);
1648 break;
1650 if (FAILED(hr = IXmlReader_GetLocalName(reader, &name, NULL))) return hr;
1651 if (FAILED(hr = IXmlReader_GetValue(reader, &value, NULL))) return hr;
1652 hr = IXmlWriter_WriteProcessingInstruction(writer, name, value);
1653 break;
1655 if (FAILED(hr = IXmlReader_GetValue(reader, &value, NULL))) return hr;
1656 hr = IXmlWriter_WriteComment(writer, value);
1657 break;
1659 if (FAILED(hr = IXmlReader_GetValue(reader, &value, NULL))) return hr;
1660 hr = IXmlWriter_WriteWhitespace(writer, value);
1661 break;
1663 hr = IXmlWriter_WriteFullEndElement(writer);
1664 break;
1666 while ((hr = IXmlReader_MoveToNextAttribute(reader)) == S_OK)
1667 {
1668 if (FAILED(hr = IXmlReader_GetLocalName(reader, &name, NULL))) return hr;
1669 if (!wcscmp(name, L"standalone"))
1670 {
1671 if (FAILED(hr = IXmlReader_GetValue(reader, &value, NULL))) return hr;
1672 standalone = !wcscmp(value, L"yes") ? XmlStandalone_Yes : XmlStandalone_No;
1673 }
1674 }
1675 if (SUCCEEDED(hr))
1676 hr = IXmlWriter_WriteStartDocument(writer, standalone);
1677 break;
1678 default:
1679 WARN("Unknown node type %d.\n", node_type);
1680 return E_UNEXPECTED;
1681 }
1682
1683 return hr;
1684}
1685
1686static HRESULT WINAPI xmlwriter_WriteNode(IXmlWriter *iface, IXmlReader *reader, BOOL write_default_attributes)
1687{
1688 HRESULT hr;
1689
1690 TRACE("%p, %p, %d.\n", iface, reader, write_default_attributes);
1691
1692 if (!reader)
1693 return E_INVALIDARG;
1694
1695 if (SUCCEEDED(hr = writer_write_node(iface, reader, FALSE, write_default_attributes)))
1696 hr = IXmlReader_Read(reader, NULL);
1697
1698 return hr;
1699}
1700
1702{
1703 TRACE("%p, %p, %d.\n", iface, reader, write_default_attributes);
1704
1705 if (!reader)
1706 return E_INVALIDARG;
1707
1708 return writer_write_node(iface, reader, TRUE, write_default_attributes);
1709}
1710
1712 LPCWSTR text)
1713{
1715
1716 TRACE("(%p)->(%s %s)\n", This, wine_dbgstr_w(name), wine_dbgstr_w(text));
1717
1718 switch (This->state)
1719 {
1721 return E_UNEXPECTED;
1723 return MX_E_ENCODING;
1725 if (!wcscmp(name, L"xml"))
1726 return WR_E_INVALIDACTION;
1727 break;
1730 break;
1732 return WR_E_INVALIDACTION;
1733 default:
1734 ;
1735 }
1736
1739 write_output_buffer(This->output, L"<?", 2);
1740 write_output_buffer(This->output, name, -1);
1741 write_output_buffer_char(This->output, ' ');
1742 write_output_buffer(This->output, text, -1);
1743 write_output_buffer(This->output, L"?>", 2);
1744
1745 if (!wcscmp(name, L"xml"))
1747
1748 return S_OK;
1749}
1750
1752 LPCWSTR pwszNamespaceUri)
1753{
1755
1756 FIXME("%p %s %s\n", This, wine_dbgstr_w(pwszLocalName), wine_dbgstr_w(pwszNamespaceUri));
1757
1758 switch (This->state)
1759 {
1761 return E_UNEXPECTED;
1763 return MX_E_ENCODING;
1765 return WR_E_INVALIDACTION;
1766 default:
1767 ;
1768 }
1769
1770 return E_NOTIMPL;
1771}
1772
1774{
1776 unsigned int count;
1777 HRESULT hr = S_OK;
1778
1779 TRACE("%p %s\n", This, debugstr_w(data));
1780
1781 if (!data)
1782 return S_OK;
1783
1784 switch (This->state)
1785 {
1787 return E_UNEXPECTED;
1790 /* fallthrough */
1793 break;
1795 return MX_E_ENCODING;
1798 break;
1799 default:
1801 return WR_E_INVALIDACTION;
1802 }
1803
1804 while (*data)
1805 {
1806 if (FAILED(hr = writer_get_next_write_count(data, ~0u, &count))) return hr;
1807 if (FAILED(hr = write_output_buffer(This->output, data, count))) return hr;
1808
1809 data += count;
1810 }
1811
1812 return hr;
1813}
1814
1816{
1817 xmlwriter *writer = impl_from_IXmlWriter(iface);
1818 HRESULT hr = S_OK;
1819 unsigned int count;
1820
1821 TRACE("%p, %s, %d.\n", iface, debugstr_wn(characters, length), length);
1822
1823 if ((characters == NULL && length != 0))
1824 return E_INVALIDARG;
1825
1826 if (length == 0)
1827 return S_OK;
1828
1829 switch (writer->state)
1830 {
1832 return E_UNEXPECTED;
1834 return MX_E_ENCODING;
1836 return WR_E_INVALIDACTION;
1839 break;
1841 writer_close_starttag(writer);
1842 default:
1843 ;
1844 }
1845
1846 while (length)
1847 {
1848 if (FAILED(hr = writer_get_next_write_count(characters, length, &count))) return hr;
1849 if (FAILED(hr = write_output_buffer(writer->output, characters, count))) return hr;
1850
1851 characters += count;
1852 length -= count;
1853 }
1854
1855 return hr;
1856}
1857
1859{
1861
1862 TRACE("(%p)->(%d)\n", This, standalone);
1863
1864 switch (This->state)
1865 {
1867 return E_UNEXPECTED;
1870 return S_OK;
1872 break;
1874 return MX_E_ENCODING;
1875 default:
1877 return WR_E_INVALIDACTION;
1878 }
1879
1880 return write_xmldecl(This, standalone);
1881}
1882
1884{
1886 int prefix_len, local_len;
1887 struct element *element;
1888 struct ns *ns;
1889 HRESULT hr;
1890
1892
1893 if (!local_name)
1894 return E_INVALIDARG;
1895
1896 switch (This->state)
1897 {
1899 return E_UNEXPECTED;
1901 return MX_E_ENCODING;
1903 return WR_E_INVALIDACTION;
1906 break;
1907 default:
1908 ;
1909 }
1910
1911 /* Validate prefix and local name */
1913 return hr;
1914
1915 if (FAILED(hr = is_valid_ncname(local_name, &local_len)))
1916 return hr;
1917
1918 if (uri && !wcscmp(uri, xmlnsuriW))
1919 {
1920 if (!prefix)
1922
1923 if (!is_empty_string(prefix))
1925 }
1926
1928
1930 if (!element)
1931 return E_OUTOFMEMORY;
1932
1935
1937 This->starttagopen = 1;
1938
1940
1941 if (!ns && !is_empty_string(uri))
1943
1944 write_output_buffer_char(This->output, '<');
1945 if (ns)
1946 write_output_qname(This->output, ns->prefix, ns->prefix_len, local_name, local_len);
1947 else
1948 write_output_qname(This->output, prefix, prefix_len, local_name, local_len);
1950
1951 return S_OK;
1952}
1953
1955{
1957
1958 TRACE("%p %s\n", This, debugstr_w(string));
1959
1960 if (!string)
1961 return S_OK;
1962
1963 switch (This->state)
1964 {
1966 return E_UNEXPECTED;
1969 break;
1973 return WR_E_INVALIDACTION;
1975 return MX_E_ENCODING;
1976 default:
1977 ;
1978 }
1979
1980 This->textnode = 1;
1981 return write_escaped_string(This, string, ~0u);
1982}
1983
1985{
1986 xmlwriter *writer = impl_from_IXmlWriter(iface);
1987 int codepoint;
1988 WCHAR bufW[16];
1989
1990 TRACE("%p, %d, %d.\n", iface, wchLow, wchHigh);
1991
1992 if (!IS_SURROGATE_PAIR(wchHigh, wchLow))
1993 return WC_E_XMLCHARACTER;
1994
1995 switch (writer->state)
1996 {
1998 return E_UNEXPECTED;
2000 return MX_E_ENCODING;
2002 writer_close_starttag(writer);
2003 break;
2005 return WR_E_INVALIDACTION;
2006 default:
2007 ;
2008 }
2009
2010 codepoint = ((wchHigh - 0xd800) * 0x400) + (wchLow - 0xdc00) + 0x10000;
2011 swprintf(bufW, ARRAY_SIZE(bufW), L"&#x%X;", codepoint);
2012 write_output_buffer(writer->output, bufW, -1);
2013
2014 return S_OK;
2015}
2016
2018{
2019 xmlwriter *writer = impl_from_IXmlWriter(iface);
2020 size_t length = 0;
2021
2022 TRACE("%p, %s.\n", iface, wine_dbgstr_w(text));
2023
2024 switch (writer->state)
2025 {
2027 return E_UNEXPECTED;
2029 writer_close_starttag(writer);
2030 break;
2032 return MX_E_ENCODING;
2034 break;
2035 default:
2036 return WR_E_INVALIDACTION;
2037 }
2038
2039 while (text[length])
2040 {
2042 length++;
2043 }
2044
2046 return S_OK;
2047}
2048
2050{
2052
2053 TRACE("%p\n", This);
2054
2055 return writeroutput_flush_stream(This->output);
2056}
2057
2058static const struct IXmlWriterVtbl xmlwriter_vtbl =
2059{
2092};
2093
2096{
2098
2099 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
2100
2101 if (IsEqualGUID(riid, &IID_IXmlWriterOutput) ||
2103 {
2104 *ppvObject = iface;
2105 }
2106 else
2107 {
2108 WARN("interface %s not implemented\n", debugstr_guid(riid));
2109 *ppvObject = NULL;
2110 return E_NOINTERFACE;
2111 }
2112
2113 IUnknown_AddRef(iface);
2114
2115 return S_OK;
2116}
2117
2119{
2121 ULONG ref = InterlockedIncrement(&output->ref);
2122 TRACE("%p, refcount %ld.\n", iface, ref);
2123 return ref;
2124}
2125
2127{
2130
2131 TRACE("%p, refcount %ld.\n", iface, ref);
2132
2133 if (ref == 0)
2134 {
2135 IMalloc *imalloc = This->imalloc;
2136 if (This->output) IUnknown_Release(This->output);
2137 if (This->stream) ISequentialStream_Release(This->stream);
2139 writeroutput_free(This, This->encoding_name);
2141 if (imalloc) IMalloc_Release(imalloc);
2142 }
2143
2144 return ref;
2145}
2146
2147static const struct IUnknownVtbl xmlwriteroutputvtbl =
2148{
2152};
2153
2155{
2156 xmlwriter *writer;
2157 HRESULT hr;
2158
2159 TRACE("(%s, %p, %p)\n", wine_dbgstr_guid(riid), obj, imalloc);
2160
2161 if (!(writer = m_alloc(imalloc, sizeof(*writer))))
2162 return E_OUTOFMEMORY;
2163 memset(writer, 0, sizeof(*writer));
2164
2165 writer->IXmlWriter_iface.lpVtbl = &xmlwriter_vtbl;
2166 writer->ref = 1;
2167 writer->imalloc = imalloc;
2168 if (imalloc) IMalloc_AddRef(imalloc);
2169 writer->bom = TRUE;
2171 writer->state = XmlWriterState_Initial;
2172 list_init(&writer->elements);
2173
2174 hr = IXmlWriter_QueryInterface(&writer->IXmlWriter_iface, riid, obj);
2175 IXmlWriter_Release(&writer->IXmlWriter_iface);
2176
2177 TRACE("returning iface %p, hr %#lx.\n", *obj, hr);
2178
2179 return hr;
2180}
2181
2183 const WCHAR *encoding_name, xmlwriteroutput **out)
2184{
2185 xmlwriteroutput *writeroutput;
2186 HRESULT hr;
2187
2188 *out = NULL;
2189
2190 if (!(writeroutput = m_alloc(imalloc, sizeof(*writeroutput))))
2191 return E_OUTOFMEMORY;
2192 memset(writeroutput, 0, sizeof(*writeroutput));
2193
2194 writeroutput->IXmlWriterOutput_iface.lpVtbl = &xmlwriteroutputvtbl;
2195 writeroutput->ref = 1;
2196 writeroutput->imalloc = imalloc;
2197 if (imalloc)
2198 IMalloc_AddRef(imalloc);
2199 writeroutput->encoding = encoding;
2200 hr = init_output_buffer(writeroutput);
2201 if (FAILED(hr)) {
2202 IUnknown_Release(&writeroutput->IXmlWriterOutput_iface);
2203 return hr;
2204 }
2205
2206 if (encoding_name)
2207 {
2208 unsigned int size = (lstrlenW(encoding_name) + 1) * sizeof(WCHAR);
2209 writeroutput->encoding_name = writeroutput_alloc(writeroutput, size);
2210 memcpy(writeroutput->encoding_name, encoding_name, size);
2211 }
2212
2213 IUnknown_QueryInterface(stream, &IID_IUnknown, (void**)&writeroutput->output);
2214
2215 *out = writeroutput;
2216
2217 TRACE("Created writer output %p\n", *out);
2218
2219 return S_OK;
2220}
2221
2224{
2225 xmlwriteroutput *output;
2226 xml_encoding xml_enc;
2227 HRESULT hr;
2228
2229 TRACE("%p %p %s %p\n", stream, imalloc, debugstr_w(encoding), out);
2230
2231 if (!stream || !out)
2232 return E_INVALIDARG;
2233
2234 *out = NULL;
2235
2236 xml_enc = encoding ? parse_encoding_name(encoding, -1) : XmlEncoding_UTF8;
2237 if (SUCCEEDED(hr = create_writer_output(stream, imalloc, xml_enc, encoding, &output)))
2238 *out = &output->IXmlWriterOutput_iface;
2239
2240 return hr;
2241}
2242
2245{
2246 xmlwriteroutput *output;
2247 xml_encoding xml_enc;
2248 HRESULT hr;
2249
2250 TRACE("%p %p %u %p\n", stream, imalloc, codepage, out);
2251
2252 if (!stream || !out)
2253 return E_INVALIDARG;
2254
2255 *out = NULL;
2256
2258 if (SUCCEEDED(hr = create_writer_output(stream, imalloc, xml_enc, NULL, &output)))
2259 *out = &output->IXmlWriterOutput_iface;
2260
2261 return hr;
2262}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
BOOL is_char(const WCHAR s, const WCHAR c)
Definition: reg.c:267
#define ARRAY_SIZE(A)
Definition: main.h:20
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
Definition: list.h:39
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define lstrlenW
Definition: compat.h:750
const WCHAR * text
Definition: package.c:1826
unsigned char ch[4][2]
Definition: console.c:118
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
_ACRTIMP wchar_t *__cdecl wcsstr(const wchar_t *, const wchar_t *)
Definition: wcs.c:2998
#define swprintf
Definition: precomp.h:40
BOOL is_namechar(WCHAR ch)
Definition: reader.c:1530
BOOL is_namestartchar(WCHAR ch)
Definition: reader.c:1486
const WCHAR * get_encoding_name(xml_encoding encoding)
Definition: reader.c:155
xml_encoding get_encoding_from_codepage(UINT codepage)
Definition: reader.c:160
BOOL is_pubchar(WCHAR ch)
Definition: reader.c:1473
BOOL is_ncnamechar(WCHAR ch)
Definition: reader.c:1506
static HRESULT WINAPI xmlwriter_SetOutput(IXmlWriter *iface, IUnknown *output)
Definition: writer.c:749
static HRESULT WINAPI xmlwriter_WriteElementString(IXmlWriter *iface, LPCWSTR prefix, LPCWSTR local_name, LPCWSTR uri, LPCWSTR value)
Definition: writer.c:1323
static HRESULT write_xmldecl(xmlwriter *writer, XmlStandalone standalone)
Definition: writer.c:607
static BOOL is_empty_string(const WCHAR *str)
Definition: writer.c:175
static HRESULT WINAPI xmlwriter_WriteDocType(IXmlWriter *iface, LPCWSTR name, LPCWSTR pubid, LPCWSTR sysid, LPCWSTR subset)
Definition: writer.c:1261
static HRESULT WINAPI xmlwriter_WriteRaw(IXmlWriter *iface, LPCWSTR data)
Definition: writer.c:1773
static HRESULT WINAPI xmlwriter_WriteProcessingInstruction(IXmlWriter *iface, LPCWSTR name, LPCWSTR text)
Definition: writer.c:1711
static HRESULT WINAPI xmlwriter_WriteCData(IXmlWriter *iface, LPCWSTR data)
Definition: writer.c:1033
static HRESULT WINAPI xmlwriter_WriteChars(IXmlWriter *iface, const WCHAR *characters, UINT length)
Definition: writer.c:1182
static HRESULT WINAPI xmlwriter_WriteRawChars(IXmlWriter *iface, const WCHAR *characters, UINT length)
Definition: writer.c:1815
HRESULT WINAPI CreateXmlWriter(REFIID riid, void **obj, IMalloc *imalloc)
Definition: writer.c:2154
static ULONG WINAPI xmlwriter_AddRef(IXmlWriter *iface)
Definition: writer.c:716
static struct element * alloc_element(xmlwriter *writer, const WCHAR *prefix, const WCHAR *local)
Definition: writer.c:180
static ULONG WINAPI xmlwriteroutput_Release(IXmlWriterOutput *iface)
Definition: writer.c:2126
struct _xmlwriter xmlwriter
static xmlwriter * impl_from_IXmlWriter(IXmlWriter *iface)
Definition: writer.c:118
static HRESULT writer_get_next_write_count(const WCHAR *str, unsigned int length, unsigned int *count)
Definition: writer.c:1111
static HRESULT WINAPI xmlwriter_WriteEndDocument(IXmlWriter *iface)
Definition: writer.c:1404
static void write_output_attribute(xmlwriter *writer, const WCHAR *prefix, int prefix_len, const WCHAR *local, int local_len, const WCHAR *value)
Definition: writer.c:905
static WCHAR * writer_strndupW(const xmlwriter *writer, const WCHAR *str, int len)
Definition: writer.c:255
static HRESULT WINAPI xmlwriter_WriteSurrogateCharEntity(IXmlWriter *iface, WCHAR wchLow, WCHAR wchHigh)
Definition: writer.c:1984
static HRESULT WINAPI xmlwriter_WriteCharEntity(IXmlWriter *iface, WCHAR ch)
Definition: writer.c:1083
static HRESULT grow_output_buffer(xmlwriteroutput *output, int length)
Definition: writer.c:448
static struct ns * writer_find_ns_current(const xmlwriter *writer, const WCHAR *prefix, const WCHAR *uri)
Definition: writer.c:302
static HRESULT is_valid_ncname(const WCHAR *str, int *out)
Definition: writer.c:352
static HRESULT write_encoding_bom(xmlwriter *writer)
Definition: writer.c:579
static struct element * pop_element(xmlwriter *writer)
Definition: writer.c:245
static BOOL is_valid_xml_space_value(const WCHAR *value)
Definition: writer.c:914
static HRESULT WINAPI xmlwriter_WriteQualifiedName(IXmlWriter *iface, LPCWSTR pwszLocalName, LPCWSTR pwszNamespaceUri)
Definition: writer.c:1751
static HRESULT writeroutput_query_for_stream(xmlwriteroutput *writeroutput)
Definition: writer.c:539
static HRESULT is_valid_name(const WCHAR *str, unsigned int *out)
Definition: writer.c:373
static HRESULT WINAPI xmlwriter_WriteString(IXmlWriter *iface, const WCHAR *string)
Definition: writer.c:1954
static HRESULT write_output_buffer_char(xmlwriteroutput *output, WCHAR ch)
Definition: writer.c:500
static HRESULT WINAPI xmlwriter_WriteEntityRef(IXmlWriter *iface, LPCWSTR pwszName)
Definition: writer.c:1478
static HRESULT WINAPI xmlwriter_WriteAttributeString(IXmlWriter *iface, LPCWSTR prefix, LPCWSTR local, LPCWSTR uri, LPCWSTR value)
Definition: writer.c:919
static const WCHAR * get_output_encoding_name(xmlwriteroutput *output)
Definition: writer.c:599
static HRESULT writer_write_attribute(IXmlWriter *writer, IXmlReader *reader, BOOL write_default_attributes)
Definition: writer.c:855
static struct ns * writer_find_ns(const xmlwriter *writer, const WCHAR *prefix, const WCHAR *uri)
Definition: writer.c:321
static HRESULT create_writer_output(IUnknown *stream, IMalloc *imalloc, xml_encoding encoding, const WCHAR *encoding_name, xmlwriteroutput **out)
Definition: writer.c:2182
static const struct IXmlWriterVtbl xmlwriter_vtbl
Definition: writer.c:2058
static HRESULT write_escaped_char(xmlwriter *writer, const WCHAR *string, unsigned int count)
Definition: writer.c:1130
static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR prefix, LPCWSTR local_name, LPCWSTR uri)
Definition: writer.c:1883
static HRESULT WINAPI xmlwriter_WriteAttributes(IXmlWriter *iface, IXmlReader *reader, BOOL write_default_attributes)
Definition: writer.c:870
static HRESULT WINAPI xmlwriter_GetProperty(IXmlWriter *iface, UINT property, LONG_PTR *value)
Definition: writer.c:800
static const WCHAR xmlnsuriW[]
Definition: writer.c:45
static HRESULT WINAPI xmlwriter_WriteNodeShallow(IXmlWriter *iface, IXmlReader *reader, BOOL write_default_attributes)
Definition: writer.c:1701
static HRESULT writer_close_starttag(xmlwriter *writer)
Definition: writer.c:650
static void free_output_buffer(xmlwriteroutput *output)
Definition: writer.c:439
static void * writeroutput_alloc(xmlwriteroutput *output, size_t len)
Definition: writer.c:149
static void writeroutput_free(xmlwriteroutput *output, void *mem)
Definition: writer.c:154
static HRESULT write_output_qname(xmlwriteroutput *output, const WCHAR *prefix, int prefix_len, const WCHAR *local_name, int local_len)
Definition: writer.c:515
static void write_cdata_section(xmlwriteroutput *output, const WCHAR *data, int len)
Definition: writer.c:1025
HRESULT WINAPI CreateXmlWriterOutputWithEncodingCodePage(IUnknown *stream, IMalloc *imalloc, UINT codepage, IXmlWriterOutput **out)
Definition: writer.c:2243
static HRESULT write_output_buffer_quoted(xmlwriteroutput *output, const WCHAR *data, int len)
Definition: writer.c:505
static const char * debugstr_writer_prop(XmlWriterProperty prop)
Definition: writer.c:128
static HRESULT writeroutput_flush_stream(xmlwriteroutput *output)
Definition: writer.c:551
static HRESULT is_valid_pubid(const WCHAR *str, unsigned int *out)
Definition: writer.c:397
static void writer_push_element(xmlwriter *writer, struct element *element)
Definition: writer.c:240
static void writeroutput_release_stream(xmlwriteroutput *writeroutput)
Definition: writer.c:531
static ULONG WINAPI xmlwriter_Release(IXmlWriter *iface)
Definition: writer.c:724
static HRESULT WINAPI xmlwriter_WriteNmToken(IXmlWriter *iface, LPCWSTR pwszNmToken)
Definition: writer.c:1571
static HRESULT WINAPI xmlwriter_Flush(IXmlWriter *iface)
Definition: writer.c:2049
static HRESULT writer_write_node(IXmlWriter *writer, IXmlReader *reader, BOOL shallow, BOOL write_default_attributes)
Definition: writer.c:1594
XmlWriterState
Definition: writer.c:56
@ XmlWriterState_InvalidEncoding
Definition: writer.c:59
@ XmlWriterState_Initial
Definition: writer.c:57
@ XmlWriterState_DocStarted
Definition: writer.c:61
@ XmlWriterState_Ready
Definition: writer.c:58
@ XmlWriterState_Content
Definition: writer.c:63
@ XmlWriterState_ElemStarted
Definition: writer.c:62
@ XmlWriterState_DocClosed
Definition: writer.c:64
@ XmlWriterState_PIDocStarted
Definition: writer.c:60
static void writer_inc_indent(xmlwriter *writer)
Definition: writer.c:662
static struct ns * writer_push_ns(xmlwriter *writer, const WCHAR *prefix, int prefix_len, const WCHAR *uri)
Definition: writer.c:280
static HRESULT WINAPI xmlwriter_WriteNode(IXmlWriter *iface, IXmlReader *reader, BOOL write_default_attributes)
Definition: writer.c:1686
static void write_node_indent(xmlwriter *writer)
Definition: writer.c:673
static HRESULT WINAPI xmlwriter_WriteWhitespace(IXmlWriter *iface, LPCWSTR text)
Definition: writer.c:2017
static HRESULT WINAPI xmlwriter_WriteStartDocument(IXmlWriter *iface, XmlStandalone standalone)
Definition: writer.c:1858
static HRESULT WINAPI xmlwriter_WriteName(IXmlWriter *iface, LPCWSTR pwszName)
Definition: writer.c:1548
static void writer_free_element_stack(xmlwriter *writer)
Definition: writer.c:229
static void writer_free_element(xmlwriter *writer, struct element *element)
Definition: writer.c:213
static HRESULT WINAPI xmlwriter_WriteFullEndElement(IXmlWriter *iface)
Definition: writer.c:1499
static const struct IUnknownVtbl xmlwriteroutputvtbl
Definition: writer.c:80
static void * writer_alloc(const xmlwriter *writer, size_t len)
Definition: writer.c:165
static xmlwriteroutput * impl_from_IXmlWriterOutput(IXmlWriterOutput *iface)
Definition: writer.c:123
static void writer_output_ns(xmlwriter *writer, struct element *element)
Definition: writer.c:635
static ULONG WINAPI xmlwriteroutput_AddRef(IXmlWriterOutput *iface)
Definition: writer.c:2118
static HRESULT WINAPI xmlwriteroutput_QueryInterface(IXmlWriterOutput *iface, REFIID riid, void **ppvObject)
Definition: writer.c:2095
static void * writeroutput_realloc(xmlwriteroutput *output, void *mem, size_t len)
Definition: writer.c:159
static HRESULT WINAPI xmlwriter_WriteEndElement(IXmlWriter *iface)
Definition: writer.c:1432
static void writer_dec_indent(xmlwriter *writer)
Definition: writer.c:667
static HRESULT write_escaped_string(xmlwriter *writer, const WCHAR *string, unsigned int length)
Definition: writer.c:1152
static HRESULT WINAPI xmlwriter_WriteComment(IXmlWriter *iface, LPCWSTR comment)
Definition: writer.c:1215
HRESULT WINAPI CreateXmlWriterOutputWithEncodingName(IUnknown *stream, IMalloc *imalloc, const WCHAR *encoding, IXmlWriterOutput **out)
Definition: writer.c:2222
static HRESULT WINAPI xmlwriter_SetProperty(IXmlWriter *iface, UINT property, LONG_PTR value)
Definition: writer.c:830
static void writer_free(const xmlwriter *writer, void *mem)
Definition: writer.c:170
static HRESULT WINAPI xmlwriter_QueryInterface(IXmlWriter *iface, REFIID riid, void **ppvObject)
Definition: writer.c:693
static HRESULT write_output_buffer(xmlwriteroutput *output, const WCHAR *data, int len)
Definition: writer.c:463
static WCHAR * writer_strdupW(const xmlwriter *writer, const WCHAR *str)
Definition: writer.c:275
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
static BSTR local_name(call_frame_t *frame, int ref)
Definition: engine.c:164
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define local
Definition: zutil.h:30
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
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
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 * u
Definition: glfuncs.h:240
unsigned int UINT
Definition: sysinfo.c:13
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
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
POINT cp
Definition: magnifier.c:59
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
#define comment(fmt, arg1)
Definition: rebar.c:847
static const char utf16bom[]
Definition: filesystem.c:50
const WCHAR * uri
Definition: sec_mgr.c:1564
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
static HRESULT get_code_page(xml_encoding encoding, UINT *cp)
Definition: mxwriter.c:287
static xml_encoding parse_encoding_name(const WCHAR *encoding)
Definition: mxwriter.c:245
xml_encoding
Definition: mxwriter.c:49
@ XmlEncoding_UTF8
Definition: mxwriter.c:60
@ XmlEncoding_Unknown
Definition: mxwriter.c:70
@ XmlEncoding_UTF16
Definition: mxwriter.c:59
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: guiddef.h:68
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
const WCHAR * str
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
#define memset(x, y, z)
Definition: compat.h:39
static void init_output_buffer(void)
Definition: tools.h:791
#define TRACE(s)
Definition: solgame.cpp:4
xmlwriteroutput * output
Definition: writer.c:105
unsigned int indent_level
Definition: writer.c:106
DWORD starttagopen
Definition: writer.c:114
BOOL omitxmldecl
Definition: writer.c:109
struct list elements
Definition: writer.c:112
IXmlWriter IXmlWriter_iface
Definition: writer.c:102
LONG ref
Definition: writer.c:103
XmlWriterState state
Definition: writer.c:111
XmlConformanceLevel conformance
Definition: writer.c:110
BOOL bom
Definition: writer.c:108
DWORD textnode
Definition: writer.c:115
DWORD bomwritten
Definition: writer.c:113
IMalloc * imalloc
Definition: writer.c:104
BOOL indent
Definition: writer.c:107
struct list ns
Definition: writer.c:87
WCHAR * qname
Definition: writer.c:85
strval qname
Definition: reader.c:251
unsigned int len
Definition: writer.c:86
struct list entry
Definition: reader.c:248
Definition: list.h:15
Definition: mem.c:349
Definition: name.c:39
Definition: mxnamespace.c:38
struct element * element
Definition: reader.c:260
int prefix_len
Definition: writer.c:94
WCHAR * prefix
Definition: writer.c:93
WCHAR * uri
Definition: writer.c:95
struct list entry
Definition: reader.c:257
BSTR prefix
Definition: mxnamespace.c:39
BSTR uri
Definition: mxnamespace.c:40
BOOL emitted
Definition: writer.c:96
char * data
Definition: writer.c:49
UINT codepage
Definition: writer.c:52
unsigned int written
Definition: writer.c:51
unsigned int allocated
Definition: writer.c:50
Definition: reader.h:84
Definition: send.c:48
Definition: parse.h:23
IXmlWriterOutput IXmlWriterOutput_iface
Definition: writer.c:69
struct output_buffer buffer
Definition: writer.c:76
IUnknown * output
Definition: writer.c:71
ISequentialStream * stream
Definition: writer.c:72
DWORD written
Definition: writer.c:77
WCHAR * encoding_name
Definition: writer.c:75
xml_encoding encoding
Definition: writer.c:74
IMalloc * imalloc
Definition: writer.c:73
#define max(a, b)
Definition: svc.c:63
#define LIST_ENTRY(type)
Definition: queue.h:175
Character const *const prefix
Definition: tempnam.cpp:195
const uint16_t * LPCWSTR
Definition: typedefs.h:57
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:64
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
int codepage
Definition: win_iconv.c:156
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_UNEXPECTED
Definition: winerror.h:3528
#define IS_SURROGATE_PAIR(high, low)
Definition: winnls.h:765
#define IS_HIGH_SURROGATE(ch)
Definition: winnls.h:763
#define IS_LOW_SURROGATE(ch)
Definition: winnls.h:764
@ MX_E_ENCODING
Definition: xmllite.idl:142
@ WR_E_XMLPREFIXDECLARATION
Definition: xmllite.idl:214
@ WR_E_INVALIDXMLSPACE
Definition: xmllite.idl:218
@ WR_E_NONWHITESPACE
Definition: xmllite.idl:209
@ WR_E_NSPREFIXDECLARED
Definition: xmllite.idl:210
@ WC_E_NAMECHARACTER
Definition: xmllite.idl:157
@ WR_E_XMLNSURIDECLARATION
Definition: xmllite.idl:216
@ WC_E_XMLCHARACTER
Definition: xmllite.idl:156
@ WR_E_INVALIDSURROGATEPAIR
Definition: xmllite.idl:220
@ WR_E_XMLNSPREFIXDECLARATION
Definition: xmllite.idl:213
@ WR_E_NSPREFIXWITHEMPTYNSURI
Definition: xmllite.idl:211
@ WC_E_PUBLICID
Definition: xmllite.idl:179
@ WR_E_INVALIDACTION
Definition: xmllite.idl:219
XmlWriterProperty
Definition: xmllite.idl:246
@ XmlWriterProperty_ConformanceLevel
Definition: xmllite.idl:251
@ XmlWriterProperty_OmitXmlDeclaration
Definition: xmllite.idl:250
@ XmlWriterProperty_ByteOrderMark
Definition: xmllite.idl:249
@ XmlWriterProperty_Indent
Definition: xmllite.idl:248
@ _XmlWriterProperty_Last
Definition: xmllite.idl:252
XmlConformanceLevel
Definition: xmllite.idl:108
@ XmlConformanceLevel_Document
Definition: xmllite.idl:111
XmlNodeType
Definition: xmllite.idl:23
@ XmlNodeType_Whitespace
Definition: xmllite.idl:32
@ XmlNodeType_EndElement
Definition: xmllite.idl:33
@ XmlNodeType_ProcessingInstruction
Definition: xmllite.idl:29
@ XmlNodeType_Attribute
Definition: xmllite.idl:26
@ XmlNodeType_CDATA
Definition: xmllite.idl:28
@ XmlNodeType_XmlDeclaration
Definition: xmllite.idl:34
@ XmlNodeType_Comment
Definition: xmllite.idl:30
@ XmlNodeType_None
Definition: xmllite.idl:24
@ XmlNodeType_Element
Definition: xmllite.idl:25
@ XmlNodeType_Text
Definition: xmllite.idl:27
XmlStandalone
Definition: xmllite.idl:238
@ XmlStandalone_No
Definition: xmllite.idl:241
@ XmlStandalone_Omit
Definition: xmllite.idl:239
@ XmlStandalone_Yes
Definition: xmllite.idl:240
static void * m_alloc(IMalloc *imalloc, size_t len)
static BOOL is_wchar_space(WCHAR ch)
static void m_free(IMalloc *imalloc, void *mem)
static void * m_realloc(IMalloc *imalloc, void *mem, size_t len)