ReactOS 0.4.15-dev-7788-g1ad9096
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 closeelementW[] = {'<','/'};
46static const WCHAR closetagW[] = {' ','/','>'};
47static const WCHAR closepiW[] = {'?','>'};
48static const WCHAR xmlnsW[] = {' ','x','m','l','n','s'};
49static const WCHAR xmlnsuriW[] = {'h','t','t','p',':','/','/','w','w','w','.','w','3','.','o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0};
50
51struct output_buffer
52{
53 char *data;
54 unsigned int allocated;
55 unsigned int written;
57};
58
59typedef enum
60{
61 XmlWriterState_Initial, /* output is not set yet */
62 XmlWriterState_Ready, /* SetOutput() was called, ready to start */
63 XmlWriterState_InvalidEncoding, /* SetOutput() was called, but output had invalid encoding */
64 XmlWriterState_PIDocStarted, /* document was started with manually added 'xml' PI */
65 XmlWriterState_DocStarted, /* document was started with WriteStartDocument() */
66 XmlWriterState_ElemStarted, /* writing element */
67 XmlWriterState_Content, /* content is accepted at this point */
68 XmlWriterState_DocClosed /* WriteEndDocument was called */
70
71typedef struct
72{
79 WCHAR *encoding_name; /* exactly as specified on output creation */
83
84static const struct IUnknownVtbl xmlwriteroutputvtbl;
85
86struct element
87{
88 struct list entry;
90 unsigned int len; /* qname length in chars */
91 struct list ns;
92};
93
94struct ns
95{
96 struct list entry;
101 struct element *element;
102};
103
104typedef struct _xmlwriter
105{
110 unsigned int indent_level;
121
123{
124 return CONTAINING_RECORD(iface, xmlwriter, IXmlWriter_iface);
125}
126
128{
129 return CONTAINING_RECORD(iface, xmlwriteroutput, IXmlWriterOutput_iface);
130}
131
133{
134 static const char * const prop_names[] =
135 {
136 "MultiLanguage",
137 "Indent",
138 "ByteOrderMark",
139 "OmitXmlDeclaration",
140 "ConformanceLevel"
141 };
142
143 if (prop > _XmlWriterProperty_Last)
144 return wine_dbg_sprintf("unknown property=%d", prop);
145
146 return prop_names[prop];
147}
148
150 const WCHAR *encoding_name, xmlwriteroutput **out);
151
152/* writer output memory allocation functions */
153static inline void *writeroutput_alloc(xmlwriteroutput *output, size_t len)
154{
155 return m_alloc(output->imalloc, len);
156}
157
158static inline void writeroutput_free(xmlwriteroutput *output, void *mem)
159{
160 m_free(output->imalloc, mem);
161}
162
163static inline void *writeroutput_realloc(xmlwriteroutput *output, void *mem, size_t len)
164{
165 return m_realloc(output->imalloc, mem, len);
166}
167
168/* writer memory allocation functions */
169static inline void *writer_alloc(const xmlwriter *writer, size_t len)
170{
171 return m_alloc(writer->imalloc, len);
172}
173
174static inline void writer_free(const xmlwriter *writer, void *mem)
175{
176 m_free(writer->imalloc, mem);
177}
178
179static struct element *alloc_element(xmlwriter *writer, const WCHAR *prefix, const WCHAR *local)
180{
181 struct element *ret;
182 int len;
183
184 ret = writer_alloc(writer, sizeof(*ret));
185 if (!ret) return ret;
186
187 len = prefix ? lstrlenW(prefix) + 1 /* ':' */ : 0;
188 len += lstrlenW(local);
189
190 ret->qname = writer_alloc(writer, (len + 1)*sizeof(WCHAR));
191 ret->len = len;
192 if (prefix) {
193 static const WCHAR colonW[] = {':',0};
194 lstrcpyW(ret->qname, prefix);
195 lstrcatW(ret->qname, colonW);
196 }
197 else
198 ret->qname[0] = 0;
199 lstrcatW(ret->qname, local);
200 list_init(&ret->ns);
201
202 return ret;
203}
204
205static void writer_free_element(xmlwriter *writer, struct element *element)
206{
207 struct ns *ns, *ns2;
208
209 LIST_FOR_EACH_ENTRY_SAFE(ns, ns2, &element->ns, struct ns, entry)
210 {
212 writer_free(writer, ns->prefix);
213 writer_free(writer, ns->uri);
214 writer_free(writer, ns);
215 }
216
217 writer_free(writer, element->qname);
218 writer_free(writer, element);
219}
220
222{
223 struct element *element, *element2;
224
225 LIST_FOR_EACH_ENTRY_SAFE(element, element2, &writer->elements, struct element, entry)
226 {
229 }
230}
231
232static void writer_push_element(xmlwriter *writer, struct element *element)
233{
234 list_add_head(&writer->elements, &element->entry);
235}
236
237static struct element *pop_element(xmlwriter *writer)
238{
239 struct element *element = LIST_ENTRY(list_head(&writer->elements), struct element, entry);
240
241 if (element)
243
244 return element;
245}
246
247static WCHAR *writer_strndupW(const xmlwriter *writer, const WCHAR *str, int len)
248{
249 size_t size;
250 WCHAR *ret;
251
252 if (!str)
253 return NULL;
254
255 if (len == -1)
256 len = lstrlenW(str);
257
258 size = (len + 1) * sizeof(WCHAR);
259 ret = writer_alloc(writer, size);
260 memcpy(ret, str, size);
261 return ret;
262}
263
264static WCHAR *writer_strdupW(const xmlwriter *writer, const WCHAR *str)
265{
266 return writer_strndupW(writer, str, -1);
267}
268
269static struct ns *writer_push_ns(xmlwriter *writer, const WCHAR *prefix, int prefix_len, const WCHAR *uri)
270{
271 struct element *element;
272 struct ns *ns;
273
274 element = LIST_ENTRY(list_head(&writer->elements), struct element, entry);
275 if (!element)
276 return NULL;
277
278 if ((ns = writer_alloc(writer, sizeof(*ns))))
279 {
282 ns->uri = writer_strdupW(writer, uri);
283 ns->emitted = FALSE;
284 ns->element = element;
286 }
287
288 return ns;
289}
290
292{
293 return !str || !*str;
294}
295
296static struct ns *writer_find_ns_current(const xmlwriter *writer, const WCHAR *prefix, const WCHAR *uri)
297{
298 struct element *element;
299 struct ns *ns;
300
302 return NULL;
303
304 element = LIST_ENTRY(list_head(&writer->elements), struct element, entry);
305
307 {
308 if (!wcscmp(uri, ns->uri) && !wcscmp(prefix, ns->prefix))
309 return ns;
310 }
311
312 return NULL;
313}
314
315static struct ns *writer_find_ns(const xmlwriter *writer, const WCHAR *prefix, const WCHAR *uri)
316{
317 struct element *element;
318 struct ns *ns;
319
321 return NULL;
322
324 {
326 {
327 if (!uri)
328 {
329 if (!ns->prefix) continue;
330 if (!wcscmp(ns->prefix, prefix))
331 return ns;
332 }
333 else if (!wcscmp(uri, ns->uri))
334 {
335 if (prefix && !*prefix)
336 return NULL;
337 if (!prefix || !wcscmp(prefix, ns->prefix))
338 return ns;
339 }
340 }
341 }
342
343 return NULL;
344}
345
346static HRESULT is_valid_ncname(const WCHAR *str, int *out)
347{
348 int len = 0;
349
350 *out = 0;
351
352 if (!str || !*str)
353 return S_OK;
354
355 while (*str)
356 {
357 if (!is_ncnamechar(*str))
358 return WC_E_NAMECHARACTER;
359 len++;
360 str++;
361 }
362
363 *out = len;
364 return S_OK;
365}
366
367static HRESULT is_valid_name(const WCHAR *str, unsigned int *out)
368{
369 unsigned int len = 1;
370
371 *out = 0;
372
373 if (!str || !*str)
374 return S_OK;
375
376 if (!is_namestartchar(*str++))
377 return WC_E_NAMECHARACTER;
378
379 while (*str++)
380 {
381 if (!is_namechar(*str))
382 return WC_E_NAMECHARACTER;
383 len++;
384 }
385
386 *out = len;
387 return S_OK;
388}
389
390static HRESULT is_valid_pubid(const WCHAR *str, unsigned int *out)
391{
392 unsigned int len = 0;
393
394 *out = 0;
395
396 if (!str || !*str)
397 return S_OK;
398
399 while (*str)
400 {
401 if (!is_pubchar(*str++))
402 return WC_E_PUBLICID;
403 len++;
404 }
405
406 *out = len;
407
408 return S_OK;
409}
410
412{
413 struct output_buffer *buffer = &output->buffer;
414 const int initial_len = 0x2000;
415 UINT cp = ~0u;
416 HRESULT hr;
417
418 if (FAILED(hr = get_code_page(output->encoding, &cp)))
419 WARN("Failed to get code page for specified encoding.\n");
420
421 buffer->data = writeroutput_alloc(output, initial_len);
422 if (!buffer->data) return E_OUTOFMEMORY;
423
424 memset(buffer->data, 0, 4);
425 buffer->allocated = initial_len;
426 buffer->written = 0;
427 buffer->codepage = cp;
428
429 return S_OK;
430}
431
433{
434 struct output_buffer *buffer = &output->buffer;
435 writeroutput_free(output, buffer->data);
436 buffer->data = NULL;
437 buffer->allocated = 0;
438 buffer->written = 0;
439}
440
442{
443 struct output_buffer *buffer = &output->buffer;
444 /* grow if needed, plus 4 bytes to be sure null terminator will fit in */
445 if (buffer->allocated < buffer->written + length + 4) {
446 int grown_size = max(2*buffer->allocated, buffer->allocated + length);
447 char *ptr = writeroutput_realloc(output, buffer->data, grown_size);
448 if (!ptr) return E_OUTOFMEMORY;
449 buffer->data = ptr;
450 buffer->allocated = grown_size;
451 }
452
453 return S_OK;
454}
455
457{
458 struct output_buffer *buffer = &output->buffer;
459 int length;
460 HRESULT hr;
461 char *ptr;
462
463 if (buffer->codepage == 1200) {
464 /* For UTF-16 encoding just copy. */
465 length = len == -1 ? lstrlenW(data) : len;
466 if (length) {
467 length *= sizeof(WCHAR);
468
469 hr = grow_output_buffer(output, length);
470 if (FAILED(hr)) return hr;
471 ptr = buffer->data + buffer->written;
472
474 buffer->written += length;
475 ptr += length;
476 /* null termination */
477 *(WCHAR*)ptr = 0;
478 }
479 }
480 else {
481 length = WideCharToMultiByte(buffer->codepage, 0, data, len, NULL, 0, NULL, NULL);
482 hr = grow_output_buffer(output, length);
483 if (FAILED(hr)) return hr;
484 ptr = buffer->data + buffer->written;
486 buffer->written += len == -1 ? length-1 : length;
487 }
488 output->written = length != 0;
489
490 return S_OK;
491}
492
494{
495 return write_output_buffer(output, &ch, 1);
496}
497
499{
500 write_output_buffer_char(output, '"');
501 if (!is_empty_string(data))
502 write_output_buffer(output, data, len);
503 write_output_buffer_char(output, '"');
504 return S_OK;
505}
506
507/* TODO: test if we need to validate char range */
508static HRESULT write_output_qname(xmlwriteroutput *output, const WCHAR *prefix, int prefix_len,
509 const WCHAR *local_name, int local_len)
510{
511 assert(prefix_len >= 0 && local_len >= 0);
512
513 if (prefix_len)
514 write_output_buffer(output, prefix, prefix_len);
515
516 if (prefix_len && local_len)
517 write_output_buffer_char(output, ':');
518
519 write_output_buffer(output, local_name, local_len);
520
521 return S_OK;
522}
523
525{
526 if (writeroutput->stream) {
527 ISequentialStream_Release(writeroutput->stream);
528 writeroutput->stream = NULL;
529 }
530}
531
533{
534 HRESULT hr;
535
536 writeroutput_release_stream(writeroutput);
537 hr = IUnknown_QueryInterface(writeroutput->output, &IID_IStream, (void**)&writeroutput->stream);
538 if (hr != S_OK)
539 hr = IUnknown_QueryInterface(writeroutput->output, &IID_ISequentialStream, (void**)&writeroutput->stream);
540
541 return hr;
542}
543
545{
546 struct output_buffer *buffer;
547 ULONG written, offset = 0;
548 HRESULT hr;
549
550 if (!output || !output->stream)
551 return S_OK;
552
553 buffer = &output->buffer;
554
555 /* It will loop forever until everything is written or an error occurred. */
556 do {
557 written = 0;
558 hr = ISequentialStream_Write(output->stream, buffer->data + offset, buffer->written, &written);
559 if (FAILED(hr)) {
560 WARN("write to stream failed (0x%08x)\n", hr);
561 buffer->written = 0;
562 return hr;
563 }
564
565 offset += written;
566 buffer->written -= written;
567 } while (buffer->written > 0);
568
569 return S_OK;
570}
571
573{
574 if (!writer->bom || writer->bomwritten) return S_OK;
575
576 if (writer->output->encoding == XmlEncoding_UTF16) {
577 static const char utf16bom[] = {0xff, 0xfe};
578 struct output_buffer *buffer = &writer->output->buffer;
579 int len = sizeof(utf16bom);
580 HRESULT hr;
581
582 hr = grow_output_buffer(writer->output, len);
583 if (FAILED(hr)) return hr;
584 memcpy(buffer->data + buffer->written, utf16bom, len);
585 buffer->written += len;
586 }
587
588 writer->bomwritten = TRUE;
589 return S_OK;
590}
591
593{
594 if (output->encoding_name)
595 return output->encoding_name;
596
597 return get_encoding_name(output->encoding);
598}
599
600static HRESULT write_xmldecl(xmlwriter *writer, XmlStandalone standalone)
601{
602 static const WCHAR versionW[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"'};
603 static const WCHAR encodingW[] = {' ','e','n','c','o','d','i','n','g','='};
604
605 write_encoding_bom(writer);
607 if (writer->omitxmldecl) return S_OK;
608
609 /* version */
611
612 /* encoding */
613 write_output_buffer(writer->output, encodingW, ARRAY_SIZE(encodingW));
615
616 /* standalone */
617 if (standalone == XmlStandalone_Omit)
619 else {
620 static const WCHAR standaloneW[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
621 static const WCHAR yesW[] = {'y','e','s','\"','?','>'};
622 static const WCHAR noW[] = {'n','o','\"','?','>'};
623
624 write_output_buffer(writer->output, standaloneW, ARRAY_SIZE(standaloneW));
625 if (standalone == XmlStandalone_Yes)
627 else
629 }
630
631 return S_OK;
632}
633
634static void writer_output_ns(xmlwriter *writer, struct element *element)
635{
636 struct ns *ns;
637
639 {
640 if (ns->emitted)
641 continue;
642
644 write_output_buffer_char(writer->output, '=');
646 }
647}
648
650{
651 HRESULT hr;
652
653 if (!writer->starttagopen) return S_OK;
654
655 writer_output_ns(writer, LIST_ENTRY(list_head(&writer->elements), struct element, entry));
656 hr = write_output_buffer_char(writer->output, '>');
657 writer->starttagopen = 0;
658 return hr;
659}
660
661static void writer_inc_indent(xmlwriter *writer)
662{
663 writer->indent_level++;
664}
665
666static void writer_dec_indent(xmlwriter *writer)
667{
668 if (writer->indent_level)
669 writer->indent_level--;
670}
671
672static void write_node_indent(xmlwriter *writer)
673{
674 static const WCHAR dblspaceW[] = {' ',' '};
675 static const WCHAR crlfW[] = {'\r','\n'};
676 unsigned int indent_level = writer->indent_level;
677
678 if (!writer->indent || writer->textnode)
679 {
680 writer->textnode = 0;
681 return;
682 }
683
684 /* Do state check to prevent newline inserted after BOM. It is assumed that
685 state does not change between writing BOM and inserting indentation. */
686 if (writer->output->written && writer->state != XmlWriterState_Ready)
688 while (indent_level--)
689 write_output_buffer(writer->output, dblspaceW, ARRAY_SIZE(dblspaceW));
690
691 writer->textnode = 0;
692}
693
695{
697
698 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
699
700 if (IsEqualGUID(riid, &IID_IXmlWriter) ||
702 {
703 *ppvObject = iface;
704 }
705 else
706 {
707 FIXME("interface %s is not supported\n", debugstr_guid(riid));
708 *ppvObject = NULL;
709 return E_NOINTERFACE;
710 }
711
712 IXmlWriter_AddRef(iface);
713
714 return S_OK;
715}
716
718{
721 TRACE("(%p)->(%u)\n", This, ref);
722 return ref;
723}
724
726{
729
730 TRACE("(%p)->(%u)\n", This, ref);
731
732 if (ref == 0) {
733 IMalloc *imalloc = This->imalloc;
734
736 if (This->output) IUnknown_Release(&This->output->IXmlWriterOutput_iface);
737
739
741 if (imalloc) IMalloc_Release(imalloc);
742 }
743
744 return ref;
745}
746
747/*** IXmlWriter methods ***/
749{
751 IXmlWriterOutput *writeroutput;
752 HRESULT hr;
753
754 TRACE("(%p)->(%p)\n", This, output);
755
756 if (This->output) {
758 IUnknown_Release(&This->output->IXmlWriterOutput_iface);
759 This->output = NULL;
760 This->bomwritten = 0;
761 This->textnode = 0;
762 This->indent_level = 0;
764 }
765
766 /* just reset current output */
767 if (!output) {
769 return S_OK;
770 }
771
772 /* now try IXmlWriterOutput, ISequentialStream, IStream */
773 hr = IUnknown_QueryInterface(output, &IID_IXmlWriterOutput, (void**)&writeroutput);
774 if (hr == S_OK) {
775 if (writeroutput->lpVtbl == &xmlwriteroutputvtbl)
776 This->output = impl_from_IXmlWriterOutput(writeroutput);
777 else {
778 ERR("got external IXmlWriterOutput implementation: %p, vtbl=%p\n",
779 writeroutput, writeroutput->lpVtbl);
780 IUnknown_Release(writeroutput);
781 return E_FAIL;
782 }
783 }
784
785 if (hr != S_OK || !writeroutput) {
786 /* Create output for given stream. */
787 hr = create_writer_output(output, This->imalloc, XmlEncoding_UTF8, NULL, &This->output);
788 if (hr != S_OK)
789 return hr;
790 }
791
792 if (This->output->encoding == XmlEncoding_Unknown)
794 else
795 This->state = XmlWriterState_Ready;
796 return writeroutput_query_for_stream(This->output);
797}
798
800{
802
803 TRACE("(%p)->(%s %p)\n", This, debugstr_writer_prop(property), value);
804
805 if (!value) return E_INVALIDARG;
806
807 switch (property)
808 {
810 *value = This->indent;
811 break;
813 *value = This->bom;
814 break;
816 *value = This->omitxmldecl;
817 break;
819 *value = This->conformance;
820 break;
821 default:
822 FIXME("Unimplemented property (%u)\n", property);
823 return E_NOTIMPL;
824 }
825
826 return S_OK;
827}
828
830{
832
833 TRACE("(%p)->(%s %lu)\n", This, debugstr_writer_prop(property), value);
834
835 switch (property)
836 {
838 This->indent = !!value;
839 break;
841 This->bom = !!value;
842 break;
844 This->omitxmldecl = !!value;
845 break;
846 default:
847 FIXME("Unimplemented property (%u)\n", property);
848 return E_NOTIMPL;
849 }
850
851 return S_OK;
852}
853
855 BOOL fWriteDefaultAttributes)
856{
858
859 FIXME("%p %p %d\n", This, pReader, fWriteDefaultAttributes);
860
861 return E_NOTIMPL;
862}
863
864static void write_output_attribute(xmlwriter *writer, const WCHAR *prefix, int prefix_len,
865 const WCHAR *local, int local_len, const WCHAR *value)
866{
867 write_output_buffer_char(writer->output, ' ');
868 write_output_qname(writer->output, prefix, prefix_len, local, local_len);
869 write_output_buffer_char(writer->output, '=');
871}
872
874{
875 static const WCHAR preserveW[] = {'p','r','e','s','e','r','v','e',0};
876 static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
877
878 if (!value)
879 return FALSE;
880
881 return !wcscmp(value, preserveW) || !wcscmp(value, defaultW);
882}
883
886{
887 static const WCHAR spaceattrW[] = {'s','p','a','c','e',0};
888 static const WCHAR xmlnsW[] = {'x','m','l','n','s',0};
889 static const WCHAR xmlW[] = {'x','m','l',0};
891 BOOL is_xmlns_prefix, is_xmlns_local;
892 int prefix_len, local_len;
893 struct ns *ns;
894 HRESULT hr;
895
897
898 switch (This->state)
899 {
901 return E_UNEXPECTED;
905 return WR_E_INVALIDACTION;
907 return MX_E_ENCODING;
908 default:
909 ;
910 }
911
912 /* Prefix "xmlns" */
913 is_xmlns_prefix = prefix && !wcscmp(prefix, xmlnsW);
914 if (is_xmlns_prefix && is_empty_string(uri) && is_empty_string(local))
916
917 if (!local)
918 return E_INVALIDARG;
919
920 /* Validate prefix and local name */
922 return hr;
923
924 if (FAILED(hr = is_valid_ncname(local, &local_len)))
925 return hr;
926
927 is_xmlns_local = !wcscmp(local, xmlnsW);
928
929 /* Trivial case, no prefix. */
930 if (prefix_len == 0 && is_empty_string(uri))
931 {
933 return S_OK;
934 }
935
936 /* Predefined "xml" prefix. */
937 if (prefix_len && !wcscmp(prefix, xmlW))
938 {
939 /* Valid "space" value is enforced. */
940 if (!wcscmp(local, spaceattrW) && !is_valid_xml_space_value(value))
942
943 /* Redefinition is not allowed. */
944 if (!is_empty_string(uri))
946
948
949 return S_OK;
950 }
951
952 if (is_xmlns_prefix || (prefix_len == 0 && uri && !wcscmp(uri, xmlnsuriW)))
953 {
956
957 /* Look for exact match defined in current element, and write it out. */
959 ns = writer_push_ns(This, local, local_len, value);
960 ns->emitted = TRUE;
961
963
964 return S_OK;
965 }
966
967 /* Ignore prefix is URI wasn't specified. */
968 if (is_xmlns_local && is_empty_string(uri))
969 {
971 return S_OK;
972 }
973
974 if (!(ns = writer_find_ns(This, prefix, uri)))
975 {
977 {
978 FIXME("Prefix autogeneration is not implemented.\n");
979 return E_NOTIMPL;
980 }
981 if (!is_empty_string(uri))
983 }
984
985 if (ns)
987 else
989
990 return S_OK;
991}
992
993static void write_cdata_section(xmlwriteroutput *output, const WCHAR *data, int len)
994{
995 static const WCHAR cdataopenW[] = {'<','!','[','C','D','A','T','A','['};
996 static const WCHAR cdatacloseW[] = {']',']','>'};
997 write_output_buffer(output, cdataopenW, ARRAY_SIZE(cdataopenW));
998 if (data)
999 write_output_buffer(output, data, len);
1000 write_output_buffer(output, cdatacloseW, ARRAY_SIZE(cdatacloseW));
1001}
1002
1004{
1006 int len;
1007
1008 TRACE("%p %s\n", This, debugstr_w(data));
1009
1010 switch (This->state)
1011 {
1013 return E_UNEXPECTED;
1016 break;
1020 return WR_E_INVALIDACTION;
1022 return MX_E_ENCODING;
1023 default:
1024 ;
1025 }
1026
1027 len = data ? lstrlenW(data) : 0;
1028
1030 if (!len)
1031 write_cdata_section(This->output, NULL, 0);
1032 else {
1033 static const WCHAR cdatacloseW[] = {']',']','>',0};
1034 while (len) {
1035 const WCHAR *str = wcsstr(data, cdatacloseW);
1036 if (str) {
1037 str += 2;
1038 write_cdata_section(This->output, data, str - data);
1039 len -= str - data;
1040 data = str;
1041 }
1042 else {
1043 write_cdata_section(This->output, data, len);
1044 break;
1045 }
1046 }
1047 }
1048
1049 return S_OK;
1050}
1051
1053{
1054 static const WCHAR fmtW[] = {'&','#','x','%','x',';',0};
1056 WCHAR bufW[16];
1057
1058 TRACE("%p %#x\n", This, ch);
1059
1060 switch (This->state)
1061 {
1063 return E_UNEXPECTED;
1065 return MX_E_ENCODING;
1068 break;
1070 return WR_E_INVALIDACTION;
1071 default:
1072 ;
1073 }
1074
1075 swprintf(bufW, fmtW, ch);
1076 write_output_buffer(This->output, bufW, -1);
1077
1078 return S_OK;
1079}
1080
1081static HRESULT WINAPI xmlwriter_WriteChars(IXmlWriter *iface, const WCHAR *pwch, UINT cwch)
1082{
1084
1085 FIXME("%p %s %d\n", This, wine_dbgstr_w(pwch), cwch);
1086
1087 switch (This->state)
1088 {
1090 return E_UNEXPECTED;
1092 return MX_E_ENCODING;
1094 return WR_E_INVALIDACTION;
1095 default:
1096 ;
1097 }
1098
1099 return E_NOTIMPL;
1100}
1101
1102
1104{
1105 static const WCHAR copenW[] = {'<','!','-','-'};
1106 static const WCHAR ccloseW[] = {'-','-','>'};
1108
1109 TRACE("%p %s\n", This, debugstr_w(comment));
1110
1111 switch (This->state)
1112 {
1114 return E_UNEXPECTED;
1116 return MX_E_ENCODING;
1119 break;
1121 return WR_E_INVALIDACTION;
1122 default:
1123 ;
1124 }
1125
1127 write_output_buffer(This->output, copenW, ARRAY_SIZE(copenW));
1128 if (comment) {
1129 int len = lstrlenW(comment), i;
1130
1131 /* Make sure there's no two hyphen sequences in a string, space is used as a separator to produce compliant
1132 comment string */
1133 if (len > 1) {
1134 for (i = 0; i < len; i++) {
1135 write_output_buffer(This->output, comment + i, 1);
1136 if (comment[i] == '-' && (i + 1 < len) && comment[i+1] == '-')
1137 write_output_buffer_char(This->output, ' ');
1138 }
1139 }
1140 else
1142
1143 if (len && comment[len-1] == '-')
1144 write_output_buffer_char(This->output, ' ');
1145 }
1146 write_output_buffer(This->output, ccloseW, ARRAY_SIZE(ccloseW));
1147
1148 return S_OK;
1149}
1150
1152 LPCWSTR sysid, LPCWSTR subset)
1153{
1154 static const WCHAR doctypeW[] = {'<','!','D','O','C','T','Y','P','E',' '};
1155 static const WCHAR publicW[] = {' ','P','U','B','L','I','C',' '};
1156 static const WCHAR systemW[] = {' ','S','Y','S','T','E','M',' '};
1158 unsigned int name_len, pubid_len;
1159 HRESULT hr;
1160
1161 TRACE("(%p)->(%s %s %s %s)\n", This, wine_dbgstr_w(name), wine_dbgstr_w(pubid), wine_dbgstr_w(sysid),
1162 wine_dbgstr_w(subset));
1163
1164 switch (This->state)
1165 {
1167 return E_UNEXPECTED;
1169 return MX_E_ENCODING;
1172 return WR_E_INVALIDACTION;
1173 default:
1174 ;
1175 }
1176
1177 if (is_empty_string(name))
1178 return E_INVALIDARG;
1179
1180 if (FAILED(hr = is_valid_name(name, &name_len)))
1181 return hr;
1182
1183 if (FAILED(hr = is_valid_pubid(pubid, &pubid_len)))
1184 return hr;
1185
1186 write_output_buffer(This->output, doctypeW, ARRAY_SIZE(doctypeW));
1187 write_output_buffer(This->output, name, name_len);
1188
1189 if (pubid)
1190 {
1192 write_output_buffer_quoted(This->output, pubid, pubid_len);
1193 write_output_buffer_char(This->output, ' ');
1194 write_output_buffer_quoted(This->output, sysid, -1);
1195 }
1196 else if (sysid)
1197 {
1199 write_output_buffer_quoted(This->output, sysid, -1);
1200 }
1201
1202 if (subset)
1203 {
1204 write_output_buffer_char(This->output, ' ');
1205 write_output_buffer_char(This->output, '[');
1206 write_output_buffer(This->output, subset, -1);
1207 write_output_buffer_char(This->output, ']');
1208 }
1209 write_output_buffer_char(This->output, '>');
1210
1212
1213 return S_OK;
1214}
1215
1218{
1220 int prefix_len, local_len;
1221 struct ns *ns;
1222 HRESULT hr;
1223
1224 TRACE("(%p)->(%s %s %s %s)\n", This, wine_dbgstr_w(prefix), wine_dbgstr_w(local_name),
1226
1227 switch (This->state)
1228 {
1230 return E_UNEXPECTED;
1232 return MX_E_ENCODING;
1235 break;
1237 return WR_E_INVALIDACTION;
1238 default:
1239 ;
1240 }
1241
1242 if (!local_name)
1243 return E_INVALIDARG;
1244
1245 /* Validate prefix and local name */
1247 return hr;
1248
1249 if (FAILED(hr = is_valid_ncname(local_name, &local_len)))
1250 return hr;
1251
1255
1256 if (uri && !wcscmp(uri, xmlnsuriW))
1257 {
1258 if (!prefix)
1260
1261 if (!is_empty_string(prefix))
1263 }
1264
1267
1268 write_output_buffer_char(This->output, '<');
1269 if (ns)
1270 write_output_qname(This->output, ns->prefix, ns->prefix_len, local_name, local_len);
1271 else
1272 write_output_qname(This->output, prefix, prefix_len, local_name, local_len);
1273
1274 if (!ns && (prefix_len || !is_empty_string(uri)))
1275 {
1277 write_output_buffer_char(This->output, '=');
1278 write_output_buffer_quoted(This->output, uri, -1);
1279 }
1280
1281 if (value)
1282 {
1283 write_output_buffer_char(This->output, '>');
1284 write_output_buffer(This->output, value, -1);
1286 write_output_qname(This->output, prefix, prefix_len, local_name, local_len);
1287 write_output_buffer_char(This->output, '>');
1288 }
1289 else
1291
1293
1294 return S_OK;
1295}
1296
1298{
1300
1301 TRACE("%p\n", This);
1302
1303 switch (This->state)
1304 {
1306 return E_UNEXPECTED;
1310 return WR_E_INVALIDACTION;
1312 return MX_E_ENCODING;
1313 default:
1314 ;
1315 }
1316
1317 /* empty element stack */
1318 while (IXmlWriter_WriteEndElement(iface) == S_OK)
1319 ;
1320
1322 return S_OK;
1323}
1324
1326{
1328 struct element *element;
1329
1330 TRACE("%p\n", This);
1331
1332 switch (This->state)
1333 {
1335 return E_UNEXPECTED;
1339 return WR_E_INVALIDACTION;
1341 return MX_E_ENCODING;
1342 default:
1343 ;
1344 }
1345
1347 if (!element)
1348 return WR_E_INVALIDACTION;
1349
1351
1352 if (This->starttagopen)
1353 {
1356 This->starttagopen = 0;
1357 }
1358 else
1359 {
1360 /* Write full end tag. */
1364 write_output_buffer_char(This->output, '>');
1365 }
1367
1368 return S_OK;
1369}
1370
1372{
1374
1375 FIXME("%p %s\n", This, wine_dbgstr_w(pwszName));
1376
1377 switch (This->state)
1378 {
1380 return E_UNEXPECTED;
1382 return MX_E_ENCODING;
1384 return WR_E_INVALIDACTION;
1385 default:
1386 ;
1387 }
1388
1389 return E_NOTIMPL;
1390}
1391
1393{
1395 struct element *element;
1396
1397 TRACE("%p\n", This);
1398
1399 switch (This->state)
1400 {
1402 return E_UNEXPECTED;
1406 return WR_E_INVALIDACTION;
1408 return MX_E_ENCODING;
1411 break;
1412 default:
1413 ;
1414 }
1415
1417 if (!element)
1418 return WR_E_INVALIDACTION;
1419
1421
1422 /* don't force full end tag to the next line */
1423 if (This->state == XmlWriterState_ElemStarted)
1424 {
1426 This->textnode = 0;
1427 }
1428 else
1430
1431 /* write full end tag */
1434 write_output_buffer_char(This->output, '>');
1435
1437
1438 return S_OK;
1439}
1440
1442{
1444
1445 FIXME("%p %s\n", This, wine_dbgstr_w(pwszName));
1446
1447 switch (This->state)
1448 {
1450 return E_UNEXPECTED;
1454 return WR_E_INVALIDACTION;
1456 return MX_E_ENCODING;
1457 default:
1458 ;
1459 }
1460
1461 return E_NOTIMPL;
1462}
1463
1465{
1467
1468 FIXME("%p %s\n", This, wine_dbgstr_w(pwszNmToken));
1469
1470 switch (This->state)
1471 {
1473 return E_UNEXPECTED;
1477 return WR_E_INVALIDACTION;
1479 return MX_E_ENCODING;
1480 default:
1481 ;
1482 }
1483
1484 return E_NOTIMPL;
1485}
1486
1488 BOOL fWriteDefaultAttributes)
1489{
1491
1492 FIXME("%p %p %d\n", This, pReader, fWriteDefaultAttributes);
1493
1494 return E_NOTIMPL;
1495}
1496
1498 BOOL fWriteDefaultAttributes)
1499{
1501
1502 FIXME("%p %p %d\n", This, pReader, fWriteDefaultAttributes);
1503
1504 return E_NOTIMPL;
1505}
1506
1508 LPCWSTR text)
1509{
1511 static const WCHAR xmlW[] = {'x','m','l',0};
1512 static const WCHAR openpiW[] = {'<','?'};
1513
1514 TRACE("(%p)->(%s %s)\n", This, wine_dbgstr_w(name), wine_dbgstr_w(text));
1515
1516 switch (This->state)
1517 {
1519 return E_UNEXPECTED;
1521 return MX_E_ENCODING;
1523 if (!wcscmp(name, xmlW))
1524 return WR_E_INVALIDACTION;
1525 break;
1528 return WR_E_INVALIDACTION;
1529 default:
1530 ;
1531 }
1532
1535 write_output_buffer(This->output, openpiW, ARRAY_SIZE(openpiW));
1536 write_output_buffer(This->output, name, -1);
1537 write_output_buffer_char(This->output, ' ');
1538 write_output_buffer(This->output, text, -1);
1540
1541 if (!wcscmp(name, xmlW))
1543
1544 return S_OK;
1545}
1546
1548 LPCWSTR pwszNamespaceUri)
1549{
1551
1552 FIXME("%p %s %s\n", This, wine_dbgstr_w(pwszLocalName), wine_dbgstr_w(pwszNamespaceUri));
1553
1554 switch (This->state)
1555 {
1557 return E_UNEXPECTED;
1559 return MX_E_ENCODING;
1561 return WR_E_INVALIDACTION;
1562 default:
1563 ;
1564 }
1565
1566 return E_NOTIMPL;
1567}
1568
1570{
1572
1573 TRACE("%p %s\n", This, debugstr_w(data));
1574
1575 if (!data)
1576 return S_OK;
1577
1578 switch (This->state)
1579 {
1581 return E_UNEXPECTED;
1584 /* fallthrough */
1587 break;
1589 return MX_E_ENCODING;
1590 default:
1592 return WR_E_INVALIDACTION;
1593 }
1594
1595 write_output_buffer(This->output, data, -1);
1596 return S_OK;
1597}
1598
1600{
1602
1603 FIXME("%p %s %d\n", This, wine_dbgstr_w(pwch), cwch);
1604
1605 switch (This->state)
1606 {
1608 return E_UNEXPECTED;
1610 return MX_E_ENCODING;
1612 return WR_E_INVALIDACTION;
1613 default:
1614 ;
1615 }
1616
1617 return E_NOTIMPL;
1618}
1619
1621{
1623
1624 TRACE("(%p)->(%d)\n", This, standalone);
1625
1626 switch (This->state)
1627 {
1629 return E_UNEXPECTED;
1632 return S_OK;
1634 break;
1636 return MX_E_ENCODING;
1637 default:
1639 return WR_E_INVALIDACTION;
1640 }
1641
1642 return write_xmldecl(This, standalone);
1643}
1644
1646{
1648 int prefix_len, local_len;
1649 struct element *element;
1650 struct ns *ns;
1651 HRESULT hr;
1652
1654
1655 if (!local_name)
1656 return E_INVALIDARG;
1657
1658 switch (This->state)
1659 {
1661 return E_UNEXPECTED;
1663 return MX_E_ENCODING;
1665 return WR_E_INVALIDACTION;
1668 break;
1669 default:
1670 ;
1671 }
1672
1673 /* Validate prefix and local name */
1675 return hr;
1676
1677 if (FAILED(hr = is_valid_ncname(local_name, &local_len)))
1678 return hr;
1679
1680 if (uri && !wcscmp(uri, xmlnsuriW))
1681 {
1682 if (!prefix)
1684
1685 if (!is_empty_string(prefix))
1687 }
1688
1690
1692 if (!element)
1693 return E_OUTOFMEMORY;
1694
1697
1699 This->starttagopen = 1;
1700
1702
1703 if (!ns && uri)
1705
1706 write_output_buffer_char(This->output, '<');
1707 if (ns)
1708 write_output_qname(This->output, ns->prefix, ns->prefix_len, local_name, local_len);
1709 else
1710 write_output_qname(This->output, prefix, prefix_len, local_name, local_len);
1712
1713 return S_OK;
1714}
1715
1716static void write_escaped_string(xmlwriter *writer, const WCHAR *string)
1717{
1718 static const WCHAR ampW[] = {'&','a','m','p',';'};
1719 static const WCHAR ltW[] = {'&','l','t',';'};
1720 static const WCHAR gtW[] = {'&','g','t',';'};
1721
1722 while (*string)
1723 {
1724 switch (*string)
1725 {
1726 case '<':
1728 break;
1729 case '&':
1730 write_output_buffer(writer->output, ampW, ARRAY_SIZE(ampW));
1731 break;
1732 case '>':
1734 break;
1735 default:
1736 write_output_buffer(writer->output, string, 1);
1737 }
1738
1739 string++;
1740 }
1741}
1742
1744{
1746
1747 TRACE("%p %s\n", This, debugstr_w(string));
1748
1749 if (!string)
1750 return S_OK;
1751
1752 switch (This->state)
1753 {
1755 return E_UNEXPECTED;
1758 break;
1762 return WR_E_INVALIDACTION;
1764 return MX_E_ENCODING;
1765 default:
1766 ;
1767 }
1768
1769 This->textnode = 1;
1770 write_escaped_string(This, string);
1771 return S_OK;
1772}
1773
1775{
1777
1778 FIXME("%p %d %d\n", This, wchLow, wchHigh);
1779
1780 return E_NOTIMPL;
1781}
1782
1784{
1786
1787 FIXME("%p %s\n", This, wine_dbgstr_w(pwszWhitespace));
1788
1789 return E_NOTIMPL;
1790}
1791
1793{
1795
1796 TRACE("%p\n", This);
1797
1798 return writeroutput_flush_stream(This->output);
1799}
1800
1801static const struct IXmlWriterVtbl xmlwriter_vtbl =
1802{
1835};
1836
1839{
1841
1842 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
1843
1844 if (IsEqualGUID(riid, &IID_IXmlWriterOutput) ||
1846 {
1847 *ppvObject = iface;
1848 }
1849 else
1850 {
1851 WARN("interface %s not implemented\n", debugstr_guid(riid));
1852 *ppvObject = NULL;
1853 return E_NOINTERFACE;
1854 }
1855
1856 IUnknown_AddRef(iface);
1857
1858 return S_OK;
1859}
1860
1862{
1865 TRACE("(%p)->(%d)\n", This, ref);
1866 return ref;
1867}
1868
1870{
1873
1874 TRACE("(%p)->(%d)\n", This, ref);
1875
1876 if (ref == 0)
1877 {
1878 IMalloc *imalloc = This->imalloc;
1879 if (This->output) IUnknown_Release(This->output);
1880 if (This->stream) ISequentialStream_Release(This->stream);
1882 writeroutput_free(This, This->encoding_name);
1884 if (imalloc) IMalloc_Release(imalloc);
1885 }
1886
1887 return ref;
1888}
1889
1890static const struct IUnknownVtbl xmlwriteroutputvtbl =
1891{
1895};
1896
1898{
1899 xmlwriter *writer;
1900 HRESULT hr;
1901
1902 TRACE("(%s, %p, %p)\n", wine_dbgstr_guid(riid), obj, imalloc);
1903
1904 if (imalloc)
1905 writer = IMalloc_Alloc(imalloc, sizeof(*writer));
1906 else
1907 writer = heap_alloc(sizeof(*writer));
1908 if (!writer)
1909 return E_OUTOFMEMORY;
1910
1911 memset(writer, 0, sizeof(*writer));
1912
1913 writer->IXmlWriter_iface.lpVtbl = &xmlwriter_vtbl;
1914 writer->ref = 1;
1915 writer->imalloc = imalloc;
1916 if (imalloc) IMalloc_AddRef(imalloc);
1917 writer->bom = TRUE;
1919 writer->state = XmlWriterState_Initial;
1920 list_init(&writer->elements);
1921
1922 hr = IXmlWriter_QueryInterface(&writer->IXmlWriter_iface, riid, obj);
1923 IXmlWriter_Release(&writer->IXmlWriter_iface);
1924
1925 TRACE("returning iface %p, hr %#x\n", *obj, hr);
1926
1927 return hr;
1928}
1929
1931 const WCHAR *encoding_name, xmlwriteroutput **out)
1932{
1933 xmlwriteroutput *writeroutput;
1934 HRESULT hr;
1935
1936 *out = NULL;
1937
1938 if (imalloc)
1939 writeroutput = IMalloc_Alloc(imalloc, sizeof(*writeroutput));
1940 else
1941 writeroutput = heap_alloc(sizeof(*writeroutput));
1942 if (!writeroutput)
1943 return E_OUTOFMEMORY;
1944
1945 writeroutput->IXmlWriterOutput_iface.lpVtbl = &xmlwriteroutputvtbl;
1946 writeroutput->ref = 1;
1947 writeroutput->imalloc = imalloc;
1948 if (imalloc)
1949 IMalloc_AddRef(imalloc);
1950 writeroutput->encoding = encoding;
1951 writeroutput->stream = NULL;
1952 hr = init_output_buffer(writeroutput);
1953 if (FAILED(hr)) {
1954 IUnknown_Release(&writeroutput->IXmlWriterOutput_iface);
1955 return hr;
1956 }
1957
1958 if (encoding_name) {
1959 unsigned int size = (lstrlenW(encoding_name) + 1) * sizeof(WCHAR);
1960 writeroutput->encoding_name = writeroutput_alloc(writeroutput, size);
1961 memcpy(writeroutput->encoding_name, encoding_name, size);
1962 }
1963 else
1964 writeroutput->encoding_name = NULL;
1965 writeroutput->written = 0;
1966
1967 IUnknown_QueryInterface(stream, &IID_IUnknown, (void**)&writeroutput->output);
1968
1969 *out = writeroutput;
1970
1971 TRACE("Created writer output %p\n", *out);
1972
1973 return S_OK;
1974}
1975
1978{
1979 xmlwriteroutput *output;
1980 xml_encoding xml_enc;
1981 HRESULT hr;
1982
1983 TRACE("%p %p %s %p\n", stream, imalloc, debugstr_w(encoding), out);
1984
1985 if (!stream || !out)
1986 return E_INVALIDARG;
1987
1988 *out = NULL;
1989
1991 if (SUCCEEDED(hr = create_writer_output(stream, imalloc, xml_enc, encoding, &output)))
1992 *out = &output->IXmlWriterOutput_iface;
1993
1994 return hr;
1995}
1996
1999{
2000 xmlwriteroutput *output;
2001 xml_encoding xml_enc;
2002 HRESULT hr;
2003
2004 TRACE("%p %p %u %p\n", stream, imalloc, codepage, out);
2005
2006 if (!stream || !out)
2007 return E_INVALIDARG;
2008
2009 *out = NULL;
2010
2012 if (SUCCEEDED(hr = create_writer_output(stream, imalloc, xml_enc, NULL, &output)))
2013 *out = &output->IXmlWriterOutput_iface;
2014
2015 return hr;
2016}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:33
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
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
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 E_FAIL
Definition: ddrawi.h:102
#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:1799
static const WCHAR utf16bom
Definition: filesystem.c:46
static const WCHAR versionW[]
Definition: name.c:52
#define swprintf
Definition: precomp.h:40
#define assert(x)
Definition: debug.h:53
BOOL is_namechar(WCHAR ch)
Definition: reader.c:1553
static const WCHAR gtW[]
Definition: reader.c:96
BOOL is_namestartchar(WCHAR ch)
Definition: reader.c:1509
const WCHAR * get_encoding_name(xml_encoding encoding)
Definition: reader.c:165
static const WCHAR ltW[]
Definition: reader.c:95
xml_encoding get_encoding_from_codepage(UINT codepage)
Definition: reader.c:170
BOOL is_pubchar(WCHAR ch)
Definition: reader.c:1496
BOOL is_ncnamechar(WCHAR ch)
Definition: reader.c:1529
static HRESULT WINAPI xmlwriter_SetOutput(IXmlWriter *iface, IUnknown *output)
Definition: writer.c:748
static HRESULT WINAPI xmlwriter_WriteElementString(IXmlWriter *iface, LPCWSTR prefix, LPCWSTR local_name, LPCWSTR uri, LPCWSTR value)
Definition: writer.c:1216
static HRESULT write_xmldecl(xmlwriter *writer, XmlStandalone standalone)
Definition: writer.c:600
static const WCHAR closeelementW[]
Definition: writer.c:45
static BOOL is_empty_string(const WCHAR *str)
Definition: writer.c:291
static HRESULT WINAPI xmlwriter_WriteDocType(IXmlWriter *iface, LPCWSTR name, LPCWSTR pubid, LPCWSTR sysid, LPCWSTR subset)
Definition: writer.c:1151
static HRESULT WINAPI xmlwriter_WriteRaw(IXmlWriter *iface, LPCWSTR data)
Definition: writer.c:1569
static HRESULT WINAPI xmlwriter_WriteProcessingInstruction(IXmlWriter *iface, LPCWSTR name, LPCWSTR text)
Definition: writer.c:1507
static HRESULT WINAPI xmlwriter_WriteRawChars(IXmlWriter *iface, const WCHAR *pwch, UINT cwch)
Definition: writer.c:1599
static HRESULT WINAPI xmlwriter_WriteCData(IXmlWriter *iface, LPCWSTR data)
Definition: writer.c:1003
HRESULT WINAPI CreateXmlWriter(REFIID riid, void **obj, IMalloc *imalloc)
Definition: writer.c:1897
static ULONG WINAPI xmlwriter_AddRef(IXmlWriter *iface)
Definition: writer.c:717
static struct element * alloc_element(xmlwriter *writer, const WCHAR *prefix, const WCHAR *local)
Definition: writer.c:179
static ULONG WINAPI xmlwriteroutput_Release(IXmlWriterOutput *iface)
Definition: writer.c:1869
struct _xmlwriter xmlwriter
static xmlwriter * impl_from_IXmlWriter(IXmlWriter *iface)
Definition: writer.c:122
static HRESULT WINAPI xmlwriter_WriteEndDocument(IXmlWriter *iface)
Definition: writer.c:1297
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:864
static WCHAR * writer_strndupW(const xmlwriter *writer, const WCHAR *str, int len)
Definition: writer.c:247
static HRESULT WINAPI xmlwriter_WriteSurrogateCharEntity(IXmlWriter *iface, WCHAR wchLow, WCHAR wchHigh)
Definition: writer.c:1774
static HRESULT WINAPI xmlwriter_WriteAttributes(IXmlWriter *iface, IXmlReader *pReader, BOOL fWriteDefaultAttributes)
Definition: writer.c:854
static HRESULT WINAPI xmlwriter_WriteCharEntity(IXmlWriter *iface, WCHAR ch)
Definition: writer.c:1052
static HRESULT grow_output_buffer(xmlwriteroutput *output, int length)
Definition: writer.c:441
static struct ns * writer_find_ns_current(const xmlwriter *writer, const WCHAR *prefix, const WCHAR *uri)
Definition: writer.c:296
static HRESULT is_valid_ncname(const WCHAR *str, int *out)
Definition: writer.c:346
static HRESULT write_encoding_bom(xmlwriter *writer)
Definition: writer.c:572
static struct element * pop_element(xmlwriter *writer)
Definition: writer.c:237
static BOOL is_valid_xml_space_value(const WCHAR *value)
Definition: writer.c:873
static HRESULT WINAPI xmlwriter_WriteQualifiedName(IXmlWriter *iface, LPCWSTR pwszLocalName, LPCWSTR pwszNamespaceUri)
Definition: writer.c:1547
static HRESULT writeroutput_query_for_stream(xmlwriteroutput *writeroutput)
Definition: writer.c:532
static HRESULT WINAPI xmlwriter_WriteWhitespace(IXmlWriter *iface, LPCWSTR pwszWhitespace)
Definition: writer.c:1783
static HRESULT is_valid_name(const WCHAR *str, unsigned int *out)
Definition: writer.c:367
static HRESULT WINAPI xmlwriter_WriteString(IXmlWriter *iface, const WCHAR *string)
Definition: writer.c:1743
static HRESULT write_output_buffer_char(xmlwriteroutput *output, WCHAR ch)
Definition: writer.c:493
static HRESULT WINAPI xmlwriter_WriteEntityRef(IXmlWriter *iface, LPCWSTR pwszName)
Definition: writer.c:1371
static HRESULT WINAPI xmlwriter_WriteAttributeString(IXmlWriter *iface, LPCWSTR prefix, LPCWSTR local, LPCWSTR uri, LPCWSTR value)
Definition: writer.c:884
static const WCHAR xmlnsW[]
Definition: writer.c:48
static const WCHAR * get_output_encoding_name(xmlwriteroutput *output)
Definition: writer.c:592
static struct ns * writer_find_ns(const xmlwriter *writer, const WCHAR *prefix, const WCHAR *uri)
Definition: writer.c:315
static HRESULT create_writer_output(IUnknown *stream, IMalloc *imalloc, xml_encoding encoding, const WCHAR *encoding_name, xmlwriteroutput **out)
Definition: writer.c:1930
static const struct IXmlWriterVtbl xmlwriter_vtbl
Definition: writer.c:1801
static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR prefix, LPCWSTR local_name, LPCWSTR uri)
Definition: writer.c:1645
static HRESULT WINAPI xmlwriter_GetProperty(IXmlWriter *iface, UINT property, LONG_PTR *value)
Definition: writer.c:799
static const WCHAR xmlnsuriW[]
Definition: writer.c:49
static HRESULT writer_close_starttag(xmlwriter *writer)
Definition: writer.c:649
static void free_output_buffer(xmlwriteroutput *output)
Definition: writer.c:432
static HRESULT WINAPI xmlwriter_WriteChars(IXmlWriter *iface, const WCHAR *pwch, UINT cwch)
Definition: writer.c:1081
static void * writeroutput_alloc(xmlwriteroutput *output, size_t len)
Definition: writer.c:153
static void writeroutput_free(xmlwriteroutput *output, void *mem)
Definition: writer.c:158
static HRESULT WINAPI xmlwriter_WriteNodeShallow(IXmlWriter *iface, IXmlReader *pReader, BOOL fWriteDefaultAttributes)
Definition: writer.c:1497
static HRESULT write_output_qname(xmlwriteroutput *output, const WCHAR *prefix, int prefix_len, const WCHAR *local_name, int local_len)
Definition: writer.c:508
static void write_cdata_section(xmlwriteroutput *output, const WCHAR *data, int len)
Definition: writer.c:993
HRESULT WINAPI CreateXmlWriterOutputWithEncodingCodePage(IUnknown *stream, IMalloc *imalloc, UINT codepage, IXmlWriterOutput **out)
Definition: writer.c:1997
static void write_escaped_string(xmlwriter *writer, const WCHAR *string)
Definition: writer.c:1716
static HRESULT write_output_buffer_quoted(xmlwriteroutput *output, const WCHAR *data, int len)
Definition: writer.c:498
static const char * debugstr_writer_prop(XmlWriterProperty prop)
Definition: writer.c:132
static HRESULT writeroutput_flush_stream(xmlwriteroutput *output)
Definition: writer.c:544
static HRESULT is_valid_pubid(const WCHAR *str, unsigned int *out)
Definition: writer.c:390
static void writer_push_element(xmlwriter *writer, struct element *element)
Definition: writer.c:232
static void writeroutput_release_stream(xmlwriteroutput *writeroutput)
Definition: writer.c:524
static ULONG WINAPI xmlwriter_Release(IXmlWriter *iface)
Definition: writer.c:725
static HRESULT WINAPI xmlwriter_WriteNmToken(IXmlWriter *iface, LPCWSTR pwszNmToken)
Definition: writer.c:1464
static HRESULT WINAPI xmlwriter_Flush(IXmlWriter *iface)
Definition: writer.c:1792
static HRESULT WINAPI xmlwriter_WriteNode(IXmlWriter *iface, IXmlReader *pReader, BOOL fWriteDefaultAttributes)
Definition: writer.c:1487
XmlWriterState
Definition: writer.c:60
@ XmlWriterState_InvalidEncoding
Definition: writer.c:63
@ XmlWriterState_Initial
Definition: writer.c:61
@ XmlWriterState_DocStarted
Definition: writer.c:65
@ XmlWriterState_Ready
Definition: writer.c:62
@ XmlWriterState_Content
Definition: writer.c:67
@ XmlWriterState_ElemStarted
Definition: writer.c:66
@ XmlWriterState_DocClosed
Definition: writer.c:68
@ XmlWriterState_PIDocStarted
Definition: writer.c:64
static void writer_inc_indent(xmlwriter *writer)
Definition: writer.c:661
static struct ns * writer_push_ns(xmlwriter *writer, const WCHAR *prefix, int prefix_len, const WCHAR *uri)
Definition: writer.c:269
static void write_node_indent(xmlwriter *writer)
Definition: writer.c:672
static HRESULT WINAPI xmlwriter_WriteStartDocument(IXmlWriter *iface, XmlStandalone standalone)
Definition: writer.c:1620
static HRESULT WINAPI xmlwriter_WriteName(IXmlWriter *iface, LPCWSTR pwszName)
Definition: writer.c:1441
static const WCHAR closepiW[]
Definition: writer.c:47
static void writer_free_element_stack(xmlwriter *writer)
Definition: writer.c:221
static void writer_free_element(xmlwriter *writer, struct element *element)
Definition: writer.c:205
static const WCHAR closetagW[]
Definition: writer.c:46
static HRESULT WINAPI xmlwriter_WriteFullEndElement(IXmlWriter *iface)
Definition: writer.c:1392
static const struct IUnknownVtbl xmlwriteroutputvtbl
Definition: writer.c:84
static void * writer_alloc(const xmlwriter *writer, size_t len)
Definition: writer.c:169
static xmlwriteroutput * impl_from_IXmlWriterOutput(IXmlWriterOutput *iface)
Definition: writer.c:127
static void writer_output_ns(xmlwriter *writer, struct element *element)
Definition: writer.c:634
static ULONG WINAPI xmlwriteroutput_AddRef(IXmlWriterOutput *iface)
Definition: writer.c:1861
static HRESULT WINAPI xmlwriteroutput_QueryInterface(IXmlWriterOutput *iface, REFIID riid, void **ppvObject)
Definition: writer.c:1838
static void * writeroutput_realloc(xmlwriteroutput *output, void *mem, size_t len)
Definition: writer.c:163
static HRESULT WINAPI xmlwriter_WriteEndElement(IXmlWriter *iface)
Definition: writer.c:1325
static void writer_dec_indent(xmlwriter *writer)
Definition: writer.c:666
static HRESULT WINAPI xmlwriter_WriteComment(IXmlWriter *iface, LPCWSTR comment)
Definition: writer.c:1103
HRESULT WINAPI CreateXmlWriterOutputWithEncodingName(IUnknown *stream, IMalloc *imalloc, const WCHAR *encoding, IXmlWriterOutput **out)
Definition: writer.c:1976
static HRESULT WINAPI xmlwriter_SetProperty(IXmlWriter *iface, UINT property, LONG_PTR value)
Definition: writer.c:829
static void writer_free(const xmlwriter *writer, void *mem)
Definition: writer.c:174
static HRESULT WINAPI xmlwriter_QueryInterface(IXmlWriter *iface, REFIID riid, void **ppvObject)
Definition: writer.c:694
static HRESULT write_output_buffer(xmlwriteroutput *output, const WCHAR *data, int len)
Definition: writer.c:456
static WCHAR * writer_strdupW(const xmlwriter *writer, const WCHAR *str)
Definition: writer.c:264
static BSTR local_name(call_frame_t *frame, int ref)
Definition: engine.c:187
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define local
Definition: zutil.h:30
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
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
static const WCHAR yesW[]
Definition: htmlbody.c:594
static const WCHAR noW[]
Definition: htmlbody.c:595
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
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_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:820
const char * uri
Definition: sec_mgr.c:1588
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
static const WCHAR xmlW[]
Definition: mxnamespace.c:61
static const WCHAR crlfW[]
Definition: mxwriter.c:47
static HRESULT get_code_page(xml_encoding encoding, UINT *cp)
Definition: mxwriter.c:265
static xml_encoding parse_encoding_name(const WCHAR *encoding)
Definition: mxwriter.c:223
static const WCHAR publicW[]
Definition: mxwriter.c:49
static const WCHAR systemW[]
Definition: mxwriter.c:50
xml_encoding
Definition: mxwriter.c:54
@ XmlEncoding_UTF8
Definition: mxwriter.c:65
@ XmlEncoding_Unknown
Definition: mxwriter.c:66
@ XmlEncoding_UTF16
Definition: mxwriter.c:64
unsigned int UINT
Definition: ndis.h:50
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
static FILE * out
Definition: regtests2xml.c:44
const WCHAR * str
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
#define memset(x, y, z)
Definition: compat.h:39
void init_output_buffer(void)
Definition: utils.c:272
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
xmlwriteroutput * output
Definition: writer.c:109
unsigned int indent_level
Definition: writer.c:110
DWORD starttagopen
Definition: writer.c:118
BOOL omitxmldecl
Definition: writer.c:113
struct list elements
Definition: writer.c:116
IXmlWriter IXmlWriter_iface
Definition: writer.c:106
LONG ref
Definition: writer.c:107
XmlWriterState state
Definition: writer.c:115
XmlConformanceLevel conformance
Definition: writer.c:114
BOOL bom
Definition: writer.c:112
DWORD textnode
Definition: writer.c:119
DWORD bomwritten
Definition: writer.c:117
IMalloc * imalloc
Definition: writer.c:108
BOOL indent
Definition: writer.c:111
struct list ns
Definition: writer.c:91
strval prefix
Definition: reader.c:259
WCHAR * qname
Definition: writer.c:89
strval qname
Definition: reader.c:261
unsigned int len
Definition: writer.c:90
struct list entry
Definition: reader.c:258
Definition: list.h:15
Definition: mem.c:156
Definition: name.c:39
Definition: mxnamespace.c:45
struct element * element
Definition: reader.c:270
int prefix_len
Definition: writer.c:98
WCHAR * prefix
Definition: writer.c:97
WCHAR * uri
Definition: writer.c:99
struct list entry
Definition: reader.c:267
BSTR prefix
Definition: mxnamespace.c:46
BSTR uri
Definition: mxnamespace.c:47
BOOL emitted
Definition: writer.c:100
char * data
Definition: writer.c:53
UINT codepage
Definition: writer.c:56
unsigned int written
Definition: writer.c:55
unsigned int allocated
Definition: writer.c:54
Definition: send.c:48
Definition: parse.h:23
IXmlWriterOutput IXmlWriterOutput_iface
Definition: writer.c:73
struct output_buffer buffer
Definition: writer.c:80
IUnknown * output
Definition: writer.c:75
ISequentialStream * stream
Definition: writer.c:76
DWORD written
Definition: writer.c:81
WCHAR * encoding_name
Definition: writer.c:79
xml_encoding encoding
Definition: writer.c:78
IMalloc * imalloc
Definition: writer.c:77
#define max(a, b)
Definition: svc.c:63
#define LIST_ENTRY(type)
Definition: queue.h:175
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:94
static const WCHAR defaultW[]
Definition: lex.c:42
int ret
int codepage
Definition: win_iconv.c:156
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_UNEXPECTED
Definition: winerror.h:2456
static char * encoding
Definition: xmllint.c:155
@ MX_E_ENCODING
Definition: xmllite.idl:142
@ WR_E_XMLPREFIXDECLARATION
Definition: xmllite.idl:214
@ WR_E_INVALIDXMLSPACE
Definition: xmllite.idl:218
@ WR_E_NSPREFIXDECLARED
Definition: xmllite.idl:210
@ WC_E_NAMECHARACTER
Definition: xmllite.idl:157
@ WR_E_XMLNSURIDECLARATION
Definition: xmllite.idl:216
@ 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:244
@ XmlWriterProperty_ConformanceLevel
Definition: xmllite.idl:249
@ XmlWriterProperty_OmitXmlDeclaration
Definition: xmllite.idl:248
@ XmlWriterProperty_ByteOrderMark
Definition: xmllite.idl:247
@ XmlWriterProperty_Indent
Definition: xmllite.idl:246
@ _XmlWriterProperty_Last
Definition: xmllite.idl:250
XmlConformanceLevel
Definition: xmllite.idl:108
@ XmlConformanceLevel_Document
Definition: xmllite.idl:111
XmlStandalone
Definition: xmllite.idl:236
@ XmlStandalone_Omit
Definition: xmllite.idl:237
@ XmlStandalone_Yes
Definition: xmllite.idl:238
static void * m_alloc(IMalloc *imalloc, size_t len)
static void m_free(IMalloc *imalloc, void *mem)
static void * m_realloc(IMalloc *imalloc, void *mem, size_t len)
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185