ReactOS  0.4.14-dev-843-g15bc263
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 */
43 DEFINE_GUID(IID_IXmlWriterOutput, 0xc1131708, 0x0f59, 0x477f, 0x93, 0x59, 0x7d, 0x33, 0x24, 0x51, 0xbc, 0x1a);
44 
45 static const WCHAR closeelementW[] = {'<','/'};
46 static const WCHAR closetagW[] = {' ','/','>'};
47 static const WCHAR closepiW[] = {'?','>'};
48 static const WCHAR xmlnsW[] = {' ','x','m','l','n','s'};
49 static 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 
51 struct output_buffer
52 {
53  char *data;
54  unsigned int allocated;
55  unsigned int written;
57 };
58 
59 typedef 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 
71 typedef struct
72 {
79  WCHAR *encoding_name; /* exactly as specified on output creation */
83 
84 static const struct IUnknownVtbl xmlwriteroutputvtbl;
85 
86 struct element
87 {
88  struct list entry;
90  unsigned int len; /* qname length in chars */
91  struct list ns;
92 };
93 
94 struct ns
95 {
96  struct list entry;
101  struct element *element;
102 };
103 
104 typedef struct _xmlwriter
105 {
110  unsigned int indent_level;
116  struct list elements;
120 } xmlwriter;
121 
123 {
124  return CONTAINING_RECORD(iface, xmlwriter, IXmlWriter_iface);
125 }
126 
128 {
129  return CONTAINING_RECORD(iface, xmlwriteroutput, IXmlWriterOutput_iface);
130 }
131 
132 static const char *debugstr_writer_prop(XmlWriterProperty prop)
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 */
153 static inline void *writeroutput_alloc(xmlwriteroutput *output, size_t len)
154 {
155  return m_alloc(output->imalloc, len);
156 }
157 
158 static inline void writeroutput_free(xmlwriteroutput *output, void *mem)
159 {
160  m_free(output->imalloc, mem);
161 }
162 
163 static 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 */
169 static inline void *writer_alloc(const xmlwriter *writer, size_t len)
170 {
171  return m_alloc(writer->imalloc, len);
172 }
173 
174 static inline void writer_free(const xmlwriter *writer, void *mem)
175 {
176  m_free(writer->imalloc, mem);
177 }
178 
179 static 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 
205 static 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  {
211  list_remove(&ns->entry);
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  {
228  writer_free_element(writer, element);
229  }
230 }
231 
232 static void writer_push_element(xmlwriter *writer, struct element *element)
233 {
234  list_add_head(&writer->elements, &element->entry);
235 }
236 
237 static 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 
247 static 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 
264 static WCHAR *writer_strdupW(const xmlwriter *writer, const WCHAR *str)
265 {
266  return writer_strndupW(writer, str, -1);
267 }
268 
269 static 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 
296 static 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 
306  LIST_FOR_EACH_ENTRY(ns, &element->ns, struct ns, entry)
307  {
308  if (!wcscmp(uri, ns->uri) && !wcscmp(prefix, ns->prefix))
309  return ns;
310  }
311 
312  return NULL;
313 }
314 
315 static 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 
323  LIST_FOR_EACH_ENTRY(element, &writer->elements, struct element, entry)
324  {
325  LIST_FOR_EACH_ENTRY(ns, &element->ns, struct ns, entry)
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 
346 static 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 
367 static 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 
390 static 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;
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 
470  if (FAILED(hr)) return hr;
471  ptr = buffer->data + buffer->written;
472 
473  memcpy(ptr, data, length);
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);
483  if (FAILED(hr)) return hr;
484  ptr = buffer->data + buffer->written;
485  length = WideCharToMultiByte(buffer->codepage, 0, data, len, ptr, length, NULL, NULL);
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 {
501  if (!is_empty_string(data))
504  return S_OK;
505 }
506 
507 /* TODO: test if we need to validate char range */
508 static 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)
518 
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 
600 static 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 
634 static void writer_output_ns(xmlwriter *writer, struct element *element)
635 {
636  struct ns *ns;
637 
638  LIST_FOR_EACH_ENTRY(ns, &element->ns, struct ns, entry)
639  {
640  if (ns->emitted)
641  continue;
642 
644  write_output_buffer_char(writer->output, '=');
645  write_output_buffer_quoted(writer->output, ns->uri, -1);
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 
661 static void writer_inc_indent(xmlwriter *writer)
662 {
663  writer->indent_level++;
664 }
665 
666 static void writer_dec_indent(xmlwriter *writer)
667 {
668  if (writer->indent_level)
669  writer->indent_level--;
670 }
671 
672 static 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) {
768  This->state = XmlWriterState_Initial;
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 
864 static 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 
896  TRACE("%p %s %s %s %s\n", This, debugstr_w(prefix), debugstr_w(local), debugstr_w(uri), debugstr_w(value));
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))
915  return WR_E_NSPREFIXDECLARED;
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))
941  return WR_E_INVALIDXMLSPACE;
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  {
954  if (prefix_len && !is_empty_string(uri))
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 
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)
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;
1017  case XmlWriterState_Ready:
1019  This->state = XmlWriterState_DocClosed;
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 
1081 static 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
1141  write_output_buffer(This->output, comment, len);
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 
1211  This->state = XmlWriterState_Content;
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))
1262  return WR_E_XMLNSURIDECLARATION;
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 
1292  This->state = XmlWriterState_Content;
1293 
1294  return S_OK;
1295 }
1296 
1298 {
1300 
1301  TRACE("%p\n", This);
1302 
1303  switch (This->state)
1304  {
1306  return E_UNEXPECTED;
1307  case XmlWriterState_Ready:
1309  This->state = XmlWriterState_DocClosed;
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 
1321  This->state = XmlWriterState_DocClosed;
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;
1336  case XmlWriterState_Ready:
1338  This->state = XmlWriterState_DocClosed;
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;
1403  case XmlWriterState_Ready:
1405  This->state = XmlWriterState_DocClosed;
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  {
1425  This->state = XmlWriterState_Content;
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;
1451  case XmlWriterState_Ready:
1453  This->state = XmlWriterState_DocClosed;
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;
1474  case XmlWriterState_Ready:
1476  This->state = XmlWriterState_DocClosed;
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;
1582  case XmlWriterState_Ready:
1584  /* fallthrough */
1587  break;
1589  return MX_E_ENCODING;
1590  default:
1591  This->state = XmlWriterState_DocClosed;
1592  return WR_E_INVALIDACTION;
1593  }
1594 
1595  write_output_buffer(This->output, data, -1);
1596  return S_OK;
1597 }
1598 
1599 static HRESULT WINAPI xmlwriter_WriteRawChars(IXmlWriter *iface, const WCHAR *pwch, UINT cwch)
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;
1633  case XmlWriterState_Ready:
1634  break;
1636  return MX_E_ENCODING;
1637  default:
1638  This->state = XmlWriterState_DocClosed;
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 
1653  TRACE("(%p)->(%s %s %s)\n", This, wine_dbgstr_w(prefix), wine_dbgstr_w(local_name), wine_dbgstr_w(uri));
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))
1686  return WR_E_XMLNSURIDECLARATION;
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 
1716 static 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 
1743 static HRESULT WINAPI xmlwriter_WriteString(IXmlWriter *iface, const WCHAR *string)
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;
1759  case XmlWriterState_Ready:
1761  This->state = XmlWriterState_DocClosed;
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 
1801 static 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 {
1872  LONG ref = InterlockedDecrement(&This->ref);
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 
1890 static 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 {
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 {
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 }
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 xmlnsuriW[]
Definition: writer.c:49
DWORD textnode
Definition: writer.c:119
WCHAR * encoding_name
Definition: writer.c:79
HRESULT WINAPI CreateXmlWriterOutputWithEncodingName(IUnknown *stream, IMalloc *imalloc, const WCHAR *encoding, IXmlWriterOutput **out)
Definition: writer.c:1976
#define max(a, b)
Definition: svc.c:63
static void * writer_alloc(const xmlwriter *writer, size_t len)
Definition: writer.c:169
static HRESULT WINAPI xmlwriter_WriteElementString(IXmlWriter *iface, LPCWSTR prefix, LPCWSTR local_name, LPCWSTR uri, LPCWSTR value)
Definition: writer.c:1216
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
#define E_NOINTERFACE
Definition: winerror.h:2364
static struct ns * writer_find_ns(const xmlwriter *writer, const WCHAR *prefix, const WCHAR *uri)
Definition: writer.c:315
static HRESULT WINAPI xmlwriter_WriteSurrogateCharEntity(IXmlWriter *iface, WCHAR wchLow, WCHAR wchHigh)
Definition: writer.c:1774
static void writer_dec_indent(xmlwriter *writer)
Definition: writer.c:666
#define WideCharToMultiByte
Definition: compat.h:101
HRESULT hr
Definition: shlfolder.c:183
static void writer_inc_indent(xmlwriter *writer)
Definition: writer.c:661
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static struct ns * writer_find_ns_current(const xmlwriter *writer, const WCHAR *prefix, const WCHAR *uri)
Definition: writer.c:296
BSTR uri
Definition: mxnamespace.c:47
BOOL bom
Definition: writer.c:112
static HRESULT WINAPI xmlwriter_SetOutput(IXmlWriter *iface, IUnknown *output)
Definition: writer.c:748
static ULONG WINAPI xmlwriter_Release(IXmlWriter *iface)
Definition: writer.c:725
static HRESULT writer_close_starttag(xmlwriter *writer)
Definition: writer.c:649
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
const char * uri
Definition: sec_mgr.c:1594
REFIID riid
Definition: precomp.h:44
static HRESULT WINAPI xmlwriter_SetProperty(IXmlWriter *iface, UINT property, LONG_PTR value)
Definition: writer.c:829
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
static const struct IUnknownVtbl xmlwriteroutputvtbl
Definition: writer.c:84
const WCHAR * text
Definition: package.c:1827
XmlWriterProperty
Definition: xmllite.idl:243
static void * writeroutput_alloc(xmlwriteroutput *output, size_t len)
Definition: writer.c:153
static BOOL is_empty_string(const WCHAR *str)
Definition: writer.c:291
#define WARN(fmt,...)
Definition: debug.h:111
static const WCHAR defaultW[]
Definition: lex.c:42
BOOL is_pubchar(WCHAR ch)
Definition: reader.c:1496
XmlStandalone
Definition: xmllite.idl:235
static HRESULT WINAPI xmlwriter_WriteQualifiedName(IXmlWriter *iface, LPCWSTR pwszLocalName, LPCWSTR pwszNamespaceUri)
Definition: writer.c:1547
static const WCHAR closeelementW[]
Definition: writer.c:45
GLintptr offset
Definition: glext.h:5920
static struct ns * writer_push_ns(xmlwriter *writer, const WCHAR *prefix, int prefix_len, const WCHAR *uri)
Definition: writer.c:269
__WINE_SERVER_LIST_INLINE void list_add_head(struct list *list, struct list *elem)
Definition: list.h:96
static struct element * pop_element(xmlwriter *writer)
Definition: writer.c:237
const char * wine_dbgstr_guid(const GUID *guid)
#define assert(x)
Definition: debug.h:53
unsigned int allocated
Definition: writer.c:54
static const WCHAR * get_output_encoding_name(xmlwriteroutput *output)
Definition: writer.c:592
GLuint buffer
Definition: glext.h:5915
static HRESULT WINAPI xmlwriter_WriteFullEndElement(IXmlWriter *iface)
Definition: writer.c:1392
static void writer_free(const xmlwriter *writer, void *mem)
Definition: writer.c:174
BOOL omitxmldecl
Definition: writer.c:113
#define lstrlenW
Definition: compat.h:415
#define E_FAIL
Definition: ddrawi.h:102
static void * writeroutput_realloc(xmlwriteroutput *output, void *mem, size_t len)
Definition: writer.c:163
static const WCHAR utf16bom
Definition: filesystem.c:46
int prefix_len
Definition: writer.c:98
Definition: send.c:47
static HRESULT is_valid_pubid(const WCHAR *str, unsigned int *out)
Definition: writer.c:390
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
WINE_DEFAULT_DEBUG_CHANNEL(richedit)
static HRESULT write_output_buffer_char(xmlwriteroutput *output, WCHAR ch)
Definition: writer.c:493
__WINE_SERVER_LIST_INLINE struct list * list_head(const struct list *list)
Definition: list.h:131
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:271
static const WCHAR crlfW[]
Definition: mxwriter.c:47
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
IUnknown * output
Definition: writer.c:75
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static const WCHAR ltW[]
Definition: reader.c:95
static const WCHAR xmlnsW[]
Definition: writer.c:48
static HRESULT WINAPI xmlwriter_WriteAttributes(IXmlWriter *iface, IXmlReader *pReader, BOOL fWriteDefaultAttributes)
Definition: writer.c:854
char * data
Definition: writer.c:53
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static HRESULT WINAPI xmlwriter_WriteAttributeString(IXmlWriter *iface, LPCWSTR prefix, LPCWSTR local, LPCWSTR uri, LPCWSTR value)
Definition: writer.c:884
XmlConformanceLevel
Definition: xmllite.idl:107
#define debugstr_w
Definition: kernel32.h:32
static void writeroutput_free(xmlwriteroutput *output, void *mem)
Definition: writer.c:158
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
struct output_buffer buffer
Definition: writer.c:80
DWORD written
Definition: writer.c:81
unsigned int written
Definition: writer.c:55
static PVOID ptr
Definition: dispmode.c:27
static HRESULT writeroutput_query_for_stream(xmlwriteroutput *writeroutput)
Definition: writer.c:532
int codepage
Definition: win_iconv.c:156
#define E_INVALIDARG
Definition: ddrawi.h:101
const WCHAR * str
XmlWriterState state
Definition: writer.c:115
static const WCHAR yesW[]
Definition: htmlbody.c:594
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR xmlW[]
Definition: mxnamespace.c:61
xmlwriteroutput * output
Definition: writer.c:109
static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR prefix, LPCWSTR local_name, LPCWSTR uri)
Definition: writer.c:1645
static const char * debugstr_writer_prop(XmlWriterProperty prop)
Definition: writer.c:132
static HRESULT WINAPI xmlwriter_WriteEntityRef(IXmlWriter *iface, LPCWSTR pwszName)
Definition: writer.c:1371
static ULONG WINAPI xmlwriter_AddRef(IXmlWriter *iface)
Definition: writer.c:717
struct _xmlwriter xmlwriter
BOOL is_namechar(WCHAR ch)
Definition: reader.c:1553
static HRESULT WINAPI xmlwriter_WriteStartDocument(IXmlWriter *iface, XmlStandalone standalone)
Definition: writer.c:1620
#define debugstr_guid
Definition: kernel32.h:35
strval prefix
Definition: reader.c:259
static HRESULT WINAPI xmlwriter_WriteRawChars(IXmlWriter *iface, const WCHAR *pwch, UINT cwch)
Definition: writer.c:1599
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
static void writer_output_ns(xmlwriter *writer, struct element *element)
Definition: writer.c:634
static HRESULT WINAPI xmlwriter_WriteCData(IXmlWriter *iface, LPCWSTR data)
Definition: writer.c:1003
static HRESULT WINAPI xmlwriter_WriteWhitespace(IXmlWriter *iface, LPCWSTR pwszWhitespace)
Definition: writer.c:1783
static void write_cdata_section(xmlwriteroutput *output, const WCHAR *data, int len)
Definition: writer.c:993
static HRESULT WINAPI xmlwriter_WriteCharEntity(IXmlWriter *iface, WCHAR ch)
Definition: writer.c:1052
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
static void * m_alloc(IMalloc *imalloc, size_t len)
static xmlwriteroutput * impl_from_IXmlWriterOutput(IXmlWriterOutput *iface)
Definition: writer.c:127
IMalloc * imalloc
Definition: writer.c:108
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
static HRESULT WINAPI xmlwriter_WriteComment(IXmlWriter *iface, LPCWSTR comment)
Definition: writer.c:1103
static const WCHAR noW[]
Definition: htmlbody.c:595
static HRESULT get_code_page(xml_encoding encoding, UINT *cp)
Definition: mxwriter.c:265
__wchar_t WCHAR
Definition: xmlstorage.h:180
static xml_encoding parse_encoding_name(const WCHAR *encoding)
Definition: mxwriter.c:223
LONG HRESULT
Definition: typedefs.h:77
static const WCHAR closepiW[]
Definition: writer.c:47
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static HRESULT is_valid_ncname(const WCHAR *str, int *out)
Definition: writer.c:346
unsigned int len
Definition: writer.c:90
static BOOL is_valid_xml_space_value(const WCHAR *value)
Definition: writer.c:873
UINT codepage
Definition: writer.c:56
static WCHAR * writer_strdupW(const xmlwriter *writer, const WCHAR *str)
Definition: writer.c:264
const GUID IID_IUnknown
static HRESULT write_encoding_bom(xmlwriter *writer)
Definition: writer.c:572
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define WINAPI
Definition: msvc.h:6
static void writer_free_element_stack(xmlwriter *writer)
Definition: writer.c:221
static HRESULT WINAPI xmlwriter_GetProperty(IXmlWriter *iface, UINT property, LONG_PTR *value)
Definition: writer.c:799
static FILE * out
Definition: regtests2xml.c:44
IMalloc * imalloc
Definition: writer.c:77
unsigned long DWORD
Definition: ntddk_ex.h:95
struct list entry
Definition: reader.c:258
static HRESULT WINAPI xmlwriter_WriteProcessingInstruction(IXmlWriter *iface, LPCWSTR name, LPCWSTR text)
Definition: writer.c:1507
HRESULT WINAPI CreateXmlWriterOutputWithEncodingCodePage(IUnknown *stream, IMalloc *imalloc, UINT codepage, IXmlWriterOutput **out)
Definition: writer.c:1997
static HRESULT grow_output_buffer(xmlwriteroutput *output, int length)
Definition: writer.c:441
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
BOOL indent
Definition: writer.c:111
DWORD starttagopen
Definition: writer.c:118
static const WCHAR gtW[]
Definition: reader.c:96
static HRESULT WINAPI xmlwriter_WriteDocType(IXmlWriter *iface, LPCWSTR name, LPCWSTR pubid, LPCWSTR sysid, LPCWSTR subset)
Definition: writer.c:1151
xml_encoding encoding
Definition: writer.c:78
BOOL is_ncnamechar(WCHAR ch)
Definition: reader.c:1529
static void free_output_buffer(xmlwriteroutput *output)
Definition: writer.c:432
int ret
static void * m_realloc(IMalloc *imalloc, void *mem, size_t len)
static HRESULT write_output_buffer(xmlwriteroutput *output, const WCHAR *data, int len)
Definition: writer.c:456
Definition: mxnamespace.c:44
#define InterlockedDecrement
Definition: armddk.h:52
Definition: parse.h:22
static HRESULT WINAPI xmlwriter_WriteNodeShallow(IXmlWriter *iface, IXmlReader *pReader, BOOL fWriteDefaultAttributes)
Definition: writer.c:1497
Definition: id3.c:18
struct list elements
Definition: writer.c:116
uint32_t entry
Definition: isohybrid.c:63
static HRESULT write_xmldecl(xmlwriter *writer, XmlStandalone standalone)
Definition: writer.c:600
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
Definition: _list.h:228
REFIID LPVOID * ppvObject
Definition: precomp.h:44
static HRESULT write_output_qname(xmlwriteroutput *output, const WCHAR *prefix, int prefix_len, const WCHAR *local_name, int local_len)
Definition: writer.c:508
IXmlWriterOutput IXmlWriterOutput_iface
Definition: writer.c:73
static HRESULT WINAPI xmlwriter_WriteEndElement(IXmlWriter *iface)
Definition: writer.c:1325
GLsizei const GLfloat * value
Definition: glext.h:6069
xml_encoding get_encoding_from_codepage(UINT codepage)
Definition: reader.c:170
BSTR prefix
Definition: mxnamespace.c:46
static void m_free(IMalloc *imalloc, void *mem)
static xmlwriter * impl_from_IXmlWriter(IXmlWriter *iface)
Definition: writer.c:122
ed encoding
Definition: write.c:2839
static HRESULT write_output_buffer_quoted(xmlwriteroutput *output, const WCHAR *data, int len)
Definition: writer.c:498
#define local
Definition: zutil.h:30
#define ERR(fmt,...)
Definition: debug.h:109
static void writer_push_element(xmlwriter *writer, struct element *element)
Definition: writer.c:232
static const WCHAR publicW[]
Definition: mxwriter.c:49
static HRESULT writeroutput_flush_stream(xmlwriteroutput *output)
Definition: writer.c:544
static void write_escaped_string(xmlwriter *writer, const WCHAR *string)
Definition: writer.c:1716
struct list entry
Definition: reader.c:267
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define S_OK
Definition: intsafe.h:59
static const WCHAR closetagW[]
Definition: writer.c:46
static HRESULT is_valid_name(const WCHAR *str, unsigned int *out)
Definition: writer.c:367
const WCHAR * get_encoding_name(xml_encoding encoding)
Definition: reader.c:165
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
#define InterlockedIncrement
Definition: armddk.h:53
static const struct IXmlWriterVtbl xmlwriter_vtbl
Definition: writer.c:1801
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
#define lstrcpyW
Definition: compat.h:414
static HRESULT init_output_buffer(xmlwriteroutput *output)
Definition: writer.c:411
XmlWriterState
Definition: writer.c:59
WCHAR * prefix
Definition: writer.c:97
#define ARRAY_SIZE(a)
Definition: main.h:24
#define E_NOTIMPL
Definition: ddrawi.h:99
WCHAR * uri
Definition: writer.c:99
struct list ns
Definition: writer.c:91
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
strval qname
Definition: reader.c:261
static void writer_free_element(xmlwriter *writer, struct element *element)
Definition: writer.c:205
static void write_node_indent(xmlwriter *writer)
Definition: writer.c:672
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
static HRESULT WINAPI xmlwriteroutput_QueryInterface(IXmlWriterOutput *iface, REFIID riid, void **ppvObject)
Definition: writer.c:1838
ISequentialStream * stream
Definition: writer.c:76
static HRESULT WINAPI xmlwriter_WriteName(IXmlWriter *iface, LPCWSTR pwszName)
Definition: writer.c:1441
static ULONG WINAPI xmlwriteroutput_Release(IXmlWriterOutput *iface)
Definition: writer.c:1869
HRESULT WINAPI CreateXmlWriter(REFIID riid, void **obj, IMalloc *imalloc)
Definition: writer.c:1897
#define E_UNEXPECTED
Definition: winerror.h:2456
static HRESULT WINAPI xmlwriter_QueryInterface(IXmlWriter *iface, REFIID riid, void **ppvObject)
Definition: writer.c:694
static HRESULT WINAPI xmlwriter_WriteNode(IXmlWriter *iface, IXmlReader *pReader, BOOL fWriteDefaultAttributes)
Definition: writer.c:1487
static HRESULT WINAPI xmlwriter_WriteNmToken(IXmlWriter *iface, LPCWSTR pwszNmToken)
Definition: writer.c:1464
static HRESULT WINAPI xmlwriter_WriteChars(IXmlWriter *iface, const WCHAR *pwch, UINT cwch)
Definition: writer.c:1081
Definition: mem.c:156
POINT cp
Definition: magnifier.c:59
Definition: name.c:38
WCHAR * qname
Definition: writer.c:89
static HRESULT WINAPI xmlwriter_WriteEndDocument(IXmlWriter *iface)
Definition: writer.c:1297
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
unsigned int ULONG
Definition: retypes.h:1
static const WCHAR systemW[]
Definition: mxwriter.c:50
static HRESULT create_writer_output(IUnknown *stream, IMalloc *imalloc, xml_encoding encoding, const WCHAR *encoding_name, xmlwriteroutput **out)
Definition: writer.c:1930
struct element * element
Definition: reader.c:270
static void writeroutput_release_stream(xmlwriteroutput *writeroutput)
Definition: writer.c:524
static ULONG WINAPI xmlwriteroutput_AddRef(IXmlWriterOutput *iface)
Definition: writer.c:1861
unsigned int indent_level
Definition: writer.c:110
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
static HRESULT WINAPI xmlwriter_Flush(IXmlWriter *iface)
Definition: writer.c:1792
LONG ref
Definition: writer.c:107
static HRESULT WINAPI xmlwriter_WriteRaw(IXmlWriter *iface, LPCWSTR data)
Definition: writer.c:1569
xml_encoding
Definition: mxwriter.c:53
#define LIST_ENTRY(type)
Definition: queue.h:175
BOOL is_namestartchar(WCHAR ch)
Definition: reader.c:1509
XmlConformanceLevel conformance
Definition: writer.c:114
#define memset(x, y, z)
Definition: compat.h:39
static const WCHAR versionW[]
Definition: name.c:52
static BSTR local_name(call_frame_t *frame, int ref)
Definition: engine.c:187
IXmlWriter IXmlWriter_iface
Definition: writer.c:106
DWORD bomwritten
Definition: writer.c:117
BOOL emitted
Definition: writer.c:100
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static struct element * alloc_element(xmlwriter *writer, const WCHAR *prefix, const WCHAR *local)
Definition: writer.c:179
static HRESULT WINAPI xmlwriter_WriteString(IXmlWriter *iface, const WCHAR *string)
Definition: writer.c:1743
DEFINE_GUID(IID_IXmlWriterOutput, 0xc1131708, 0x0f59, 0x477f, 0x93, 0x59, 0x7d, 0x33, 0x24, 0x51, 0xbc, 0x1a)
static WCHAR * writer_strndupW(const xmlwriter *writer, const WCHAR *str, int len)
Definition: writer.c:247