ReactOS 0.4.17-dev-966-gf06eace
writer.c
Go to the documentation of this file.
1/*
2 * XMLLite IXmlWriter tests
3 *
4 * Copyright 2011 (C) Alistair Leslie-Hughes
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#ifdef __REACTOS__
22#define CONST_VTABLE
23#endif
24
25#define COBJMACROS
26
27#include <stdarg.h>
28#include <stdio.h>
29
30#include "windef.h"
31#include "winbase.h"
32#include "ole2.h"
33#include "xmllite.h"
34
35#include "wine/test.h"
36
37#include "initguid.h"
38DEFINE_GUID(IID_IXmlWriterOutput, 0xc1131708, 0x0f59, 0x477f, 0x93, 0x59, 0x7d, 0x33, 0x24, 0x51, 0xbc, 0x1a);
39
40static IStream *create_stream_on_data(const void *data, unsigned int size)
41{
43 HGLOBAL hglobal;
44 void *ptr;
45 HRESULT hr;
46
47 hglobal = GlobalAlloc(GHND, size);
48 ptr = GlobalLock(hglobal);
49
51
52 hr = CreateStreamOnHGlobal(hglobal, TRUE, &stream);
53 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
54 ok(stream != NULL, "Expected non-NULL stream\n");
55
56 GlobalUnlock(hglobal);
57
58 return stream;
59}
60
61#define reader_set_input(a, b) _reader_set_input(__LINE__, a, b)
62static void _reader_set_input(unsigned line, IXmlReader *reader, const char *xml)
63{
65 HRESULT hr;
66
68
69 hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
70 ok_(__FILE__,line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
71
72 IStream_Release(stream);
73}
74
75#define EXPECT_REF(obj, ref) _expect_ref((IUnknown *)obj, ref, __LINE__)
76static void _expect_ref(IUnknown *obj, ULONG ref, int line)
77{
78 ULONG refcount;
79 IUnknown_AddRef(obj);
80 refcount = IUnknown_Release(obj);
81 ok_(__FILE__, line)(refcount == ref, "expected refcount %lu, got %lu.\n", ref, refcount);
82}
83
84static void check_output_raw(IStream *stream, const void *expected, SIZE_T size, int line)
85{
86 SIZE_T content_size;
87 HGLOBAL hglobal;
88 HRESULT hr;
89 WCHAR *ptr;
90
91 hr = GetHGlobalFromStream(stream, &hglobal);
92 ok_(__FILE__, line)(hr == S_OK, "Failed to get the stream handle, hr %#lx.\n", hr);
93
94 content_size = GlobalSize(hglobal);
95 ok_(__FILE__, line)(size == content_size, "Unexpected test output size %Id.\n", content_size);
96 ptr = GlobalLock(hglobal);
97 if (size <= content_size)
98 ok_(__FILE__, line)(!memcmp(expected, ptr, size), "Unexpected output content.\n");
99 if (size != content_size && *ptr == 0xfeff)
100 ok_(__FILE__, line)(0, "Content: %s.\n", wine_dbgstr_wn(ptr, content_size / sizeof(WCHAR)));
101
102 GlobalUnlock(hglobal);
103}
104
105static void check_output(IStream *stream, const char *expected, BOOL todo, int line)
106{
107 int len = strlen(expected), size;
108 HGLOBAL hglobal;
109 HRESULT hr;
110 char *ptr;
111
112 hr = GetHGlobalFromStream(stream, &hglobal);
113 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
114
115 size = GlobalSize(hglobal);
116 ptr = GlobalLock(hglobal);
118 {
119 if (size != len)
120 {
121 ok_(__FILE__, line)(0, "data size mismatch, expected %u, got %u\n", len, size);
122 ok_(__FILE__, line)(0, "got |%s|, expected |%s|\n", ptr, expected);
123 }
124 else
125 ok_(__FILE__, line)(!strncmp(ptr, expected, len), "got |%s|, expected |%s|\n", ptr, expected);
126 }
127 GlobalUnlock(hglobal);
128}
129#define CHECK_OUTPUT(stream, expected) check_output(stream, expected, FALSE, __LINE__)
130#define CHECK_OUTPUT_TODO(stream, expected) check_output(stream, expected, TRUE, __LINE__)
131#define CHECK_OUTPUT_RAW(stream, expected, size) check_output_raw(stream, expected, size, __LINE__)
132
134{
135 HRESULT hr;
136
137 hr = IXmlWriter_SetProperty(writer, property, TRUE);
138 ok(hr == S_OK, "Failed to set writer property, hr %#lx.\n", hr);
139}
140
141/* used to test all Write* methods for consistent error state */
142static void check_writer_state(IXmlWriter *writer, HRESULT exp_hr)
143{
145 HRESULT hr;
146 WCHAR low = 0xdcef;
147 WCHAR high = 0xdaff;
148
149 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
150 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
151
152 /* FIXME: add WriteAttributes */
153
154 hr = IXmlWriter_WriteAttributeString(writer, NULL, L"a", NULL, L"a");
155 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
156
157 hr = IXmlWriter_WriteCData(writer, L"a");
158 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
159
160 hr = IXmlWriter_WriteCharEntity(writer, 'a');
161 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
162
163 hr = IXmlWriter_WriteChars(writer, L"a", 1);
164 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
165
166 hr = IXmlWriter_WriteComment(writer, L"a");
167 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
168
169 hr = IXmlWriter_WriteDocType(writer, L"a", NULL, NULL, NULL);
170 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
171
172 hr = IXmlWriter_WriteElementString(writer, NULL, L"a", NULL, L"a");
173 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
174
175 hr = IXmlWriter_WriteEndDocument(writer);
176 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
177
178 hr = IXmlWriter_WriteEndElement(writer);
179 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
180
181 hr = IXmlWriter_WriteEntityRef(writer, L"a");
182 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
183
184 hr = IXmlWriter_WriteFullEndElement(writer);
185 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
186
187 hr = IXmlWriter_WriteName(writer, L"a");
188 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
189
190 hr = IXmlWriter_WriteNmToken(writer, L"a");
191 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
192
193 hr = IXmlWriter_WriteNode(writer, NULL, FALSE);
194 ok(hr == E_INVALIDARG, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
195
196 reader_set_input(reader, "<a/>");
197 hr = IXmlWriter_WriteNode(writer, reader, FALSE);
198 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
199
200 reader_set_input(reader, "<a/>");
201 hr = IXmlReader_Read(reader, NULL);
202 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
203 hr = IXmlWriter_WriteNodeShallow(writer, reader, FALSE);
204 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
205
206 hr = IXmlWriter_WriteProcessingInstruction(writer, L"a", L"a");
207 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
208
209 hr = IXmlWriter_WriteQualifiedName(writer, L"a", NULL);
210 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
211
212 hr = IXmlWriter_WriteRaw(writer, L"a");
213 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
214
215 hr = IXmlWriter_WriteRawChars(writer, L"a", 1);
216 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
217
218 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
219 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
220
221 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
222 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
223
224 hr = IXmlWriter_WriteString(writer, L"a");
225 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
226
227 hr = IXmlWriter_WriteSurrogateCharEntity(writer, low, high);
228 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
229
230 hr = IXmlWriter_WriteWhitespace(writer, L" ");
231 ok(hr == exp_hr, "Unexpected hr %#lx, expected %#lx.\n", hr, exp_hr);
232
233 IXmlReader_Release(reader);
234}
235
237{
239 HRESULT hr;
240
242 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
243
244 hr = IXmlWriter_SetOutput(writer, (IUnknown*)stream);
245 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
246
247 return stream;
248}
249
251{
253 *obj = iface;
254 return S_OK;
255 }
256 else {
257 ok(0, "unknown riid=%s\n", wine_dbgstr_guid(riid));
258 return E_NOINTERFACE;
259 }
260}
261
263{
264 return 2;
265}
266
268{
269 return 1;
270}
271
272static const IUnknownVtbl testoutputvtbl = {
276};
277
279
281{
282 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_ISequentialStream))
283 {
284 *obj = iface;
285 return S_OK;
286 }
287
288 *obj = NULL;
289 return E_NOINTERFACE;
290}
291
293{
294 return 2;
295}
296
298{
299 return 1;
300}
301
303{
304 ok(0, "unexpected call\n");
305 return E_NOTIMPL;
306}
307
309static HRESULT WINAPI teststream_Write(ISequentialStream *iface, const void *pv, ULONG cb, ULONG *written)
310{
311 g_write_len = cb;
312 *written = cb;
313 return S_OK;
314}
315
316static const ISequentialStreamVtbl teststreamvtbl =
317{
323};
324
326
327static void test_writer_create(void)
328{
329 HRESULT hr;
330 IXmlWriter *writer;
332 IUnknown *unk;
333
334 /* crashes native */
335 if (0)
336 {
337 CreateXmlWriter(&IID_IXmlWriter, NULL, NULL);
338 CreateXmlWriter(NULL, (void**)&writer, NULL);
339 }
340
341 hr = CreateXmlWriter(&IID_IStream, (void **)&unk, NULL);
342 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
343
344 hr = CreateXmlWriter(&IID_IUnknown, (void **)&unk, NULL);
345 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
346 hr = IUnknown_QueryInterface(unk, &IID_IXmlWriter, (void **)&writer);
347 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
348 ok(unk == (IUnknown *)writer, "unexpected interface pointer\n");
349 IUnknown_Release(unk);
350 IXmlWriter_Release(writer);
351
352 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
353 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
354
355 /* check default properties values */
356 value = 0;
357 hr = IXmlWriter_GetProperty(writer, XmlWriterProperty_ByteOrderMark, &value);
358 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
359 ok(value == TRUE, "got %Id.\n", value);
360
361 value = TRUE;
362 hr = IXmlWriter_GetProperty(writer, XmlWriterProperty_Indent, &value);
363 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
364 ok(value == FALSE, "got %Id.\n", value);
365
366 value = TRUE;
367 hr = IXmlWriter_GetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, &value);
368 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
369 ok(value == FALSE, "got %Id.\n", value);
370
372 hr = IXmlWriter_GetProperty(writer, XmlWriterProperty_ConformanceLevel, &value);
373 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
374 ok(value == XmlConformanceLevel_Document, "got %Id.\n", value);
375
376 IXmlWriter_Release(writer);
377}
378
380{
382 HRESULT hr;
383 WCHAR low = 0xdcef;
384 WCHAR high = 0xdaff;
385
386 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
387 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
388
389 hr = IXmlWriter_SetOutput(writer, output);
390 ok(hr == S_OK, "Failed to set output, hr %#lx.\n", hr);
391
392 /* TODO: WriteAttributes */
393
394 hr = IXmlWriter_WriteAttributeString(writer, NULL, L"a", NULL, L"a");
395 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
396
397 hr = IXmlWriter_WriteCData(writer, L"a");
398 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
399
400 hr = IXmlWriter_WriteCharEntity(writer, 0x100);
401 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
402
403 hr = IXmlWriter_WriteChars(writer, L"a", 1);
404 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
405
406 hr = IXmlWriter_WriteComment(writer, L"a");
407 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
408
409 hr = IXmlWriter_WriteDocType(writer, L"a", NULL, NULL, NULL);
410 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
411
412 hr = IXmlWriter_WriteElementString(writer, NULL, L"a", NULL, NULL);
413 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
414
415 hr = IXmlWriter_WriteEndDocument(writer);
416 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
417
418 hr = IXmlWriter_WriteEndElement(writer);
419 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
420
421 hr = IXmlWriter_WriteEntityRef(writer, L"a");
422 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
423
424 hr = IXmlWriter_WriteFullEndElement(writer);
425 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
426
427 hr = IXmlWriter_WriteName(writer, L"a");
428 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
429
430 hr = IXmlWriter_WriteNmToken(writer, L"a");
431 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
432
433 reader_set_input(reader, "<a/>");
434 hr = IXmlWriter_WriteNode(writer, reader, FALSE);
435 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
436
437 hr = IXmlWriter_WriteNodeShallow(writer, reader, FALSE);
438 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
439
440 hr = IXmlWriter_WriteProcessingInstruction(writer, L"a", L"a");
441 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
442
443 hr = IXmlWriter_WriteQualifiedName(writer, L"a", NULL);
444 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
445
446 hr = IXmlWriter_WriteRaw(writer, L"a");
447 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
448
449 hr = IXmlWriter_WriteRawChars(writer, L"a", 1);
450 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
451
452 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
453 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
454
455 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
456 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
457
458 hr = IXmlWriter_WriteString(writer, L"a");
459 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
460
461 hr = IXmlWriter_WriteSurrogateCharEntity(writer, low, high);
462 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
463
464 hr = IXmlWriter_WriteWhitespace(writer, L" ");
465 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
466
467 hr = IXmlWriter_WriteChars(writer, L"a", 1);
468 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
469
470 hr = IXmlWriter_WriteRawChars(writer, L"a", 1);
471 ok(hr == MX_E_ENCODING, "Unexpected hr %#lx.\n", hr);
472
473 hr = IXmlWriter_Flush(writer);
474 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
475
476 IXmlReader_Release(reader);
477}
478
479static void test_writeroutput(void)
480{
481 static const WCHAR utf16_outputW[] = {0xfeff,'<','a'};
482 IXmlWriterOutput *output;
483 IXmlWriter *writer;
485 IUnknown *unk;
486 HRESULT hr;
487
488 output = NULL;
490 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
491 EXPECT_REF(output, 1);
492 IUnknown_Release(output);
493
495 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
496 unk = NULL;
497 hr = IUnknown_QueryInterface(output, &IID_IXmlWriterOutput, (void**)&unk);
498 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
500 ok(unk != NULL && unk != output, "got %p, output %p\n", unk, output);
501 EXPECT_REF(output, 2);
502 /* releasing 'unk' crashes on native */
503 IUnknown_Release(output);
504 EXPECT_REF(output, 1);
505 IUnknown_Release(output);
506
507 output = NULL;
509 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
510 IUnknown_Release(output);
511
513 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
514 unk = NULL;
515 hr = IUnknown_QueryInterface(output, &IID_IXmlWriterOutput, (void**)&unk);
516 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
517 ok(unk != NULL, "got %p\n", unk);
518 /* releasing 'unk' crashes on native */
519 IUnknown_Release(output);
520 IUnknown_Release(output);
521
522 /* create with us-ascii */
523 output = NULL;
525 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
526 IUnknown_Release(output);
527
528 /* Output with codepage 1200. */
529 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
530 ok(hr == S_OK, "Failed to create writer, hr %#lx.\n", hr);
531
533 ok(hr == S_OK, "Failed to create stream, hr %#lx.\n", hr);
534
536 ok(hr == S_OK, "Failed to create writer output, hr %#lx.\n", hr);
537
538 hr = IXmlWriter_SetOutput(writer, output);
539 ok(hr == S_OK, "Failed to set writer output, hr %#lx.\n", hr);
540
541 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
542 ok(hr == S_OK, "Write failed, hr %#lx.\n", hr);
543
544 hr = IXmlWriter_Flush(writer);
545 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
546
547 CHECK_OUTPUT_RAW(stream, utf16_outputW, sizeof(utf16_outputW));
548
549 IStream_Release(stream);
550 IUnknown_Release(output);
551
552 /* Create output with meaningless code page value. */
554 ok(hr == S_OK, "Failed to create stream, hr %#lx.\n", hr);
555
556 output = NULL;
558 ok(hr == S_OK, "Failed to create writer output, hr %#lx.\n", hr);
559
560 test_invalid_output_encoding(writer, output);
561 CHECK_OUTPUT(stream, "");
562
563 IStream_Release(stream);
564 IUnknown_Release(output);
565
566 /* Same, with invalid encoding name. */
568 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
569
570 output = NULL;
572 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
573
574 test_invalid_output_encoding(writer, output);
575 CHECK_OUTPUT(stream, "");
576
577 IStream_Release(stream);
578 IUnknown_Release(output);
579
580 IXmlWriter_Release(writer);
581}
582
583static void test_writestartdocument(void)
584{
585 static const char fullprolog[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
586 static const char *prologversion2 = "<?xml version=\"1.0\" encoding=\"uS-asCii\"?>";
587 static const char prologversion[] = "<?xml version=\"1.0\"?>";
588 IXmlWriterOutput *output;
589 IXmlWriter *writer;
591 HRESULT hr;
592
593 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
594 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
595
596 /* output not set */
597 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
598 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
599
600 hr = IXmlWriter_WriteProcessingInstruction(writer, L"xml", L"version=\"1.0\"");
601 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
602
603 hr = IXmlWriter_Flush(writer);
604 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
605
606 stream = writer_set_output(writer);
607
608 /* nothing written yet */
609 hr = IXmlWriter_Flush(writer);
610 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
611
612 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
613 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
614
615 hr = IXmlWriter_Flush(writer);
616 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
617
618 CHECK_OUTPUT(stream, fullprolog);
619
620 /* one more time */
621 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
622 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
623 IStream_Release(stream);
624
625 /* now add PI manually, and try to start a document */
626 stream = writer_set_output(writer);
627
628 hr = IXmlWriter_WriteProcessingInstruction(writer, L"xml", L"version=\"1.0\"");
629 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
630
631 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
632 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
633
634 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
635 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
636
637 /* another attempt to add 'xml' PI */
638 hr = IXmlWriter_WriteProcessingInstruction(writer, L"xml", L"version=\"1.0\"");
639 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
640
641 hr = IXmlWriter_Flush(writer);
642 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
643
644 CHECK_OUTPUT(stream, prologversion);
645
646 IStream_Release(stream);
647 IXmlWriter_Release(writer);
648
649 /* create with us-ascii */
651 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
652
653 output = NULL;
655 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
656
657 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
658 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
659
660 hr = IXmlWriter_SetOutput(writer, output);
661 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
662
663 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
664 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
665
666 hr = IXmlWriter_Flush(writer);
667 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
668
669 CHECK_OUTPUT(stream, prologversion2);
670
671 IStream_Release(stream);
672 IXmlWriter_Release(writer);
673 IUnknown_Release(output);
674}
675
676static void test_flush(void)
677{
678 IXmlWriter *writer;
679 HRESULT hr;
680
681 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
682 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
683
684 hr = IXmlWriter_SetOutput(writer, (IUnknown*)&teststream);
685 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
686
687 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
688 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
689
690 g_write_len = 0;
691 hr = IXmlWriter_Flush(writer);
692 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
693 ok(g_write_len > 0, "Unexpected length %lu.\n", g_write_len);
694
695 g_write_len = 1;
696 hr = IXmlWriter_Flush(writer);
697 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
698 ok(g_write_len == 0, "Unexpected length %lu.\n", g_write_len);
699
700 /* Release() flushes too */
701 g_write_len = 1;
702 IXmlWriter_Release(writer);
703 ok(g_write_len == 0, "Unexpected length %lu.\n", g_write_len);
704}
705
706static void test_omitxmldeclaration(void)
707{
708 static const char prologversion[] = "<?xml version=\"1.0\"?>";
709 IXmlWriter *writer;
710 HGLOBAL hglobal;
712 HRESULT hr;
713 char *ptr;
714
715 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
716 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
717
718 stream = writer_set_output(writer);
719
721
722 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
723 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
724
725 hr = IXmlWriter_Flush(writer);
726 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
727
728 hr = GetHGlobalFromStream(stream, &hglobal);
729 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
730
731 ptr = GlobalLock(hglobal);
732 ok(!ptr, "got %p\n", ptr);
733 GlobalUnlock(hglobal);
734
735 /* one more time */
736 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
737 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
738
739 IStream_Release(stream);
740
741 /* now add PI manually, and try to start a document */
742 stream = writer_set_output(writer);
743
744 hr = IXmlWriter_WriteProcessingInstruction(writer, L"xml", L"version=\"1.0\"");
745 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
746
747 hr = IXmlWriter_Flush(writer);
748 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
749
750 CHECK_OUTPUT(stream, prologversion);
751
752 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
753 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
754
755 hr = IXmlWriter_Flush(writer);
756 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
757
758 CHECK_OUTPUT(stream, prologversion);
759
760 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
761 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
762
763 hr = IXmlWriter_Flush(writer);
764 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
765
766 CHECK_OUTPUT(stream, prologversion);
767
768 /* another attempt to add 'xml' PI */
769 hr = IXmlWriter_WriteProcessingInstruction(writer, L"xml", L"version=\"1.0\"");
770 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
771
772 hr = IXmlWriter_Flush(writer);
773 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
774
775 IStream_Release(stream);
776 IXmlWriter_Release(writer);
777}
778
779static void test_bom(void)
780{
781 static const WCHAR piW[] = {0xfeff,'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"','?','>'};
782 static const WCHAR aopenW[] = {0xfeff,'<','a'};
783 static const WCHAR afullW[] = {0xfeff,'<','a',' ','/','>'};
784 static const WCHAR bomW[] = {0xfeff};
785 IXmlWriterOutput *output;
786 IXmlWriter *writer;
788 HGLOBAL hglobal;
789 HRESULT hr;
790
792 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
793
795 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
796
797 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
798 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
799
801
802 hr = IXmlWriter_SetOutput(writer, output);
803 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
804
805 /* BOM is on by default */
806 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
807 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
808
809 hr = IXmlWriter_Flush(writer);
810 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
811
812 CHECK_OUTPUT_RAW(stream, bomW, sizeof(bomW));
813
814 IStream_Release(stream);
815 IUnknown_Release(output);
816
817 /* start with PI */
819 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
820
822 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
823
824 hr = IXmlWriter_SetOutput(writer, output);
825 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
826
827 hr = IXmlWriter_WriteProcessingInstruction(writer, L"xml", L"version=\"1.0\"");
828 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
829
830 hr = IXmlWriter_Flush(writer);
831 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
832
833 CHECK_OUTPUT_RAW(stream, piW, sizeof(piW));
834
835 IUnknown_Release(output);
836 IStream_Release(stream);
837
838 /* start with element */
840 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
841
843 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
844
845 hr = IXmlWriter_SetOutput(writer, output);
846 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
847
848 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
849 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
850
851 hr = IXmlWriter_Flush(writer);
852 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
853
854 CHECK_OUTPUT_RAW(stream, aopenW, sizeof(aopenW));
855
856 IUnknown_Release(output);
857 IStream_Release(stream);
858
859 /* WriteElementString */
861 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
862
864 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
865
866 hr = IXmlWriter_SetOutput(writer, output);
867 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
868
870
871 hr = IXmlWriter_WriteElementString(writer, NULL, L"a", NULL, NULL);
872 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
873
874 hr = IXmlWriter_Flush(writer);
875 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
876
877 hr = GetHGlobalFromStream(stream, &hglobal);
878 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
879
880 CHECK_OUTPUT_RAW(stream, afullW, sizeof(afullW));
881
882 IUnknown_Release(output);
883 IStream_Release(stream);
884
885 IXmlWriter_Release(writer);
886}
887
888static void test_WriteStartElement(void)
889{
890 static const struct
891 {
892 const WCHAR *prefix;
893 const WCHAR *local;
894 const WCHAR *uri;
895 const char *output;
896 const char *output_partial;
897 HRESULT hr;
898 int todo;
899 int todo_partial;
900 }
901 start_element_tests[] =
902 {
903 { L"prefix", L"local", L"uri", "<prefix:local xmlns:prefix=\"uri\" />", "<prefix:local" },
904 { NULL, L"local", L"uri", "<local xmlns=\"uri\" />", "<local" },
905 { L"", L"local", L"uri", "<local xmlns=\"uri\" />", "<local" },
906 { L"", L"local", L"uri", "<local xmlns=\"uri\" />", "<local" },
907 { NULL, L"local", NULL, "<local />", "<local" },
908 { NULL, L"local", L"", "<local />", "<local" },
909
910 { L"prefix", NULL, NULL, NULL, NULL, E_INVALIDARG },
911 { NULL, NULL, L"uri", NULL, NULL, E_INVALIDARG },
913 { NULL, L"prefix:local", L"uri", NULL, NULL, WC_E_NAMECHARACTER },
914 { L"pre:fix", L"local", L"uri", NULL, NULL, WC_E_NAMECHARACTER },
915 { NULL, L":local", L"uri", NULL, NULL, WC_E_NAMECHARACTER },
916 { L":", L"local", L"uri", NULL, NULL, WC_E_NAMECHARACTER },
917 { NULL, L"local", L"http://www.w3.org/2000/xmlns/", NULL, NULL, WR_E_XMLNSPREFIXDECLARATION },
918 { L"prefix", L"local", L"http://www.w3.org/2000/xmlns/", NULL, NULL, WR_E_XMLNSURIDECLARATION },
919 };
920 IXmlWriter *writer;
922 unsigned int i;
923 HRESULT hr;
924
925 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
926 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
927
928 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
929 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
930
931 stream = writer_set_output(writer);
932
933 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
934 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
935
936 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
937 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
938
939 hr = IXmlWriter_Flush(writer);
940 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
941
942 CHECK_OUTPUT(stream, "<a");
943
944 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
945 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
946
947 hr = IXmlWriter_WriteStartElement(writer, NULL, NULL, NULL);
948 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
949
950 hr = IXmlWriter_WriteProcessingInstruction(writer, L"a", L"a");
951 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
952
953 IStream_Release(stream);
954 IXmlWriter_Release(writer);
955
956 /* WriteElementString */
957 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
958 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
959
960 hr = IXmlWriter_WriteElementString(writer, NULL, L"b", NULL, L"value");
961 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
962
963 stream = writer_set_output(writer);
964
965 hr = IXmlWriter_WriteStartElement(writer, L"prefix", L"a", L"uri");
966 ok(hr == S_OK, "Failed to start element, hr %#lx.\n", hr);
967
968 hr = IXmlWriter_WriteElementString(writer, NULL, L"b", NULL, L"value");
969 ok(hr == S_OK, "Failed to write element string, hr %#lx.\n", hr);
970
971 hr = IXmlWriter_WriteElementString(writer, NULL, L"c", NULL, NULL);
972 ok(hr == S_OK, "Failed to write element string, hr %#lx.\n", hr);
973
974 hr = IXmlWriter_WriteStartElement(writer, NULL, L"d", L"uri");
975 ok(hr == S_OK, "Failed to start element, hr %#lx.\n", hr);
976
977 hr = IXmlWriter_WriteStartElement(writer, L"", L"e", L"uri");
978 ok(hr == S_OK, "Failed to start element, hr %#lx.\n", hr);
979
980 hr = IXmlWriter_WriteStartElement(writer, L"prefix2", L"f", L"uri");
981 ok(hr == S_OK, "Failed to start element, hr %#lx.\n", hr);
982
983 hr = IXmlWriter_Flush(writer);
984 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
985
987 "<prefix:a xmlns:prefix=\"uri\">"
988 "<b>value</b>"
989 "<c />"
990 "<prefix:d>"
991 "<e xmlns=\"uri\">"
992 "<prefix2:f");
993
994 IStream_Release(stream);
995
996 /* WriteStartElement */
997 for (i = 0; i < ARRAY_SIZE(start_element_tests); ++i)
998 {
999 stream = writer_set_output(writer);
1000
1002
1003 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1004 ok(hr == S_OK, "Failed to start document, hr %#lx.\n", hr);
1005
1006 hr = IXmlWriter_WriteStartElement(writer, start_element_tests[i].prefix, start_element_tests[i].local,
1007 start_element_tests[i].uri);
1008 ok(hr == start_element_tests[i].hr, "%u: unexpected hr %#lx.\n", i, hr);
1009
1010 if (SUCCEEDED(start_element_tests[i].hr))
1011 {
1012 hr = IXmlWriter_Flush(writer);
1013 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
1014
1015 check_output(stream, start_element_tests[i].output_partial, start_element_tests[i].todo_partial, __LINE__);
1016
1017 hr = IXmlWriter_WriteEndDocument(writer);
1018 ok(hr == S_OK, "Failed to end document, hr %#lx.\n", hr);
1019
1020 hr = IXmlWriter_Flush(writer);
1021 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
1022
1023 check_output(stream, start_element_tests[i].output, start_element_tests[i].todo, __LINE__);
1024 }
1025
1026 IStream_Release(stream);
1027 }
1028
1029 IXmlWriter_Release(writer);
1030}
1031
1033{
1034 static const struct
1035 {
1036 const WCHAR *prefix;
1037 const WCHAR *local;
1038 const WCHAR *uri;
1039 const WCHAR *value;
1040 const char *output;
1041 HRESULT hr;
1042 int todo;
1043 }
1044 element_string_tests[] =
1045 {
1046 { L"prefix", L"local", L"uri", L"value", "<prefix:local xmlns:prefix=\"uri\">value</prefix:local>" },
1047 { NULL, L"local", L"uri", L"value", "<local xmlns=\"uri\">value</local>" },
1048 { L"", L"local", L"uri", L"value", "<local xmlns=\"uri\">value</local>" },
1049 { L"prefix", L"local", L"uri", NULL, "<prefix:local xmlns:prefix=\"uri\" />" },
1050 { NULL, L"local", L"uri", NULL, "<local xmlns=\"uri\" />" },
1051 { L"", L"local", L"uri", NULL, "<local xmlns=\"uri\" />" },
1052 { NULL, L"local", NULL, NULL, "<local />" },
1053 { L"prefix", L"local", L"uri", L"", "<prefix:local xmlns:prefix=\"uri\"></prefix:local>" },
1054 { NULL, L"local", L"uri", L"", "<local xmlns=\"uri\"></local>" },
1055 { L"", L"local", L"uri", L"", "<local xmlns=\"uri\"></local>" },
1056 { NULL, L"local", NULL, L"", "<local></local>" },
1057 { L"", L"local", L"http://www.w3.org/2000/xmlns/", NULL, "<local xmlns=\"http://www.w3.org/2000/xmlns/\" />" },
1058
1059 { L"prefix", NULL, NULL, L"value", NULL, E_INVALIDARG },
1060 { NULL, NULL, L"uri", L"value", NULL, E_INVALIDARG },
1061 { NULL, NULL, NULL, L"value", NULL, E_INVALIDARG },
1062 { NULL, L"prefix:local", L"uri", L"value", NULL, WC_E_NAMECHARACTER },
1063 { NULL, L":local", L"uri", L"value", NULL, WC_E_NAMECHARACTER },
1064 { L":", L"local", L"uri", L"value", NULL, WC_E_NAMECHARACTER },
1065 { L"prefix", L"local", NULL, L"value", NULL, WR_E_NSPREFIXWITHEMPTYNSURI },
1066 { L"prefix", L"local", L"", L"value", NULL, WR_E_NSPREFIXWITHEMPTYNSURI },
1067 { NULL, L"local", L"http://www.w3.org/2000/xmlns/", L"value", NULL, WR_E_XMLNSPREFIXDECLARATION },
1068 { L"prefix", L"local", L"http://www.w3.org/2000/xmlns/", L"value", NULL, WR_E_XMLNSURIDECLARATION },
1069 };
1070 IXmlWriter *writer;
1071 IStream *stream;
1072 unsigned int i;
1073 HRESULT hr;
1074
1075 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1076 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1077
1078 hr = IXmlWriter_WriteElementString(writer, NULL, L"b", NULL, L"value");
1079 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
1080
1081 stream = writer_set_output(writer);
1082
1083 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
1084 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1085
1086 hr = IXmlWriter_WriteElementString(writer, NULL, L"b", NULL, L"value");
1087 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1088
1089 hr = IXmlWriter_WriteElementString(writer, NULL, L"b", NULL, NULL);
1090 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1091
1092 hr = IXmlWriter_WriteElementString(writer, L"prefix", L"b", L"uri", NULL);
1093 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1094
1095 hr = IXmlWriter_WriteStartElement(writer, L"prefix", L"c", L"uri");
1096 ok(hr == S_OK, "Failed to start element, hr %#lx.\n", hr);
1097
1098 hr = IXmlWriter_WriteElementString(writer, L"prefix", L"d", NULL, NULL);
1099 ok(hr == S_OK, "Failed to write element, hr %#lx.\n", hr);
1100
1101 hr = IXmlWriter_WriteElementString(writer, L"prefix2", L"d", L"uri", NULL);
1102 ok(hr == S_OK, "Failed to write element, hr %#lx.\n", hr);
1103
1104 hr = IXmlWriter_WriteElementString(writer, NULL, L"e", L"uri", NULL);
1105 ok(hr == S_OK, "Failed to write element, hr %#lx.\n", hr);
1106
1107 hr = IXmlWriter_WriteElementString(writer, L"prefix", L"f", L"uri2", NULL);
1108 ok(hr == S_OK, "Failed to write element, hr %#lx.\n", hr);
1109
1110 hr = IXmlWriter_WriteElementString(writer, NULL, L"g", L"uri3", NULL);
1111 ok(hr == S_OK, "Failed to write element, hr %#lx.\n", hr);
1112
1113 hr = IXmlWriter_WriteElementString(writer, L"prefix", L"h", NULL, NULL);
1114 ok(hr == S_OK, "Failed to write element, hr %#lx.\n", hr);
1115
1116 hr = IXmlWriter_WriteElementString(writer, L"prefix_i", L"i", NULL, NULL);
1117 ok(hr == WR_E_NSPREFIXWITHEMPTYNSURI, "Failed to write element, hr %#lx.\n", hr);
1118
1119 hr = IXmlWriter_WriteElementString(writer, L"", L"j", L"uri", NULL);
1120 ok(hr == S_OK, "Failed to write element, hr %#lx.\n", hr);
1121
1122 hr = IXmlWriter_Flush(writer);
1123 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1124
1126 "<a><b>value</b><b />"
1127 "<prefix:b xmlns:prefix=\"uri\" />"
1128 "<prefix:c xmlns:prefix=\"uri\">"
1129 "<prefix:d />"
1130 "<prefix2:d xmlns:prefix2=\"uri\" />"
1131 "<prefix:e />"
1132 "<prefix:f xmlns:prefix=\"uri2\" />"
1133 "<g xmlns=\"uri3\" />"
1134 "<prefix:h />"
1135 "<j xmlns=\"uri\" />");
1136
1137 IStream_Release(stream);
1138
1139 for (i = 0; i < ARRAY_SIZE(element_string_tests); ++i)
1140 {
1141 stream = writer_set_output(writer);
1142
1144
1145 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1146 ok(hr == S_OK, "Failed to start document, hr %#lx.\n", hr);
1147
1148 hr = IXmlWriter_WriteElementString(writer, element_string_tests[i].prefix, element_string_tests[i].local,
1149 element_string_tests[i].uri, element_string_tests[i].value);
1150 ok(hr == element_string_tests[i].hr, "%u: unexpected hr %#lx.\n", i, hr);
1151
1152 if (SUCCEEDED(element_string_tests[i].hr))
1153 {
1154 hr = IXmlWriter_Flush(writer);
1155 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
1156
1157 check_output(stream, element_string_tests[i].output, element_string_tests[i].todo, __LINE__);
1158
1159 hr = IXmlWriter_WriteEndDocument(writer);
1160 ok(hr == S_OK, "Failed to end document, hr %#lx.\n", hr);
1161
1162 hr = IXmlWriter_Flush(writer);
1163 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
1164
1165 check_output(stream, element_string_tests[i].output, element_string_tests[i].todo, __LINE__);
1166 }
1167
1168 IStream_Release(stream);
1169 }
1170
1171 IXmlWriter_Release(writer);
1172}
1173
1174static void test_WriteEndElement(void)
1175{
1176 IXmlWriter *writer;
1177 IStream *stream;
1178 HRESULT hr;
1179
1180 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1181 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1182
1183 stream = writer_set_output(writer);
1184
1185 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
1186 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1187
1188 hr = IXmlWriter_WriteStartElement(writer, NULL, L"b", NULL);
1189 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1190
1191 hr = IXmlWriter_WriteEndElement(writer);
1192 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1193
1194 hr = IXmlWriter_WriteEndElement(writer);
1195 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1196
1197 hr = IXmlWriter_Flush(writer);
1198 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1199
1200 CHECK_OUTPUT(stream, "<a><b /></a>");
1201
1202 IXmlWriter_Release(writer);
1203 IStream_Release(stream);
1204}
1205
1206static void test_writeenddocument(void)
1207{
1208 IXmlWriter *writer;
1209 IStream *stream;
1210 HGLOBAL hglobal;
1211 HRESULT hr;
1212 char *ptr;
1213
1214 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1215 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1216
1217 hr = IXmlWriter_WriteEndDocument(writer);
1218 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
1219
1220 stream = writer_set_output(writer);
1221
1222 /* WriteEndDocument resets it to initial state */
1223 hr = IXmlWriter_WriteEndDocument(writer);
1224 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1225
1226 hr = IXmlWriter_WriteEndDocument(writer);
1227 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1228
1229 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1230 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1231
1232 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
1233 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1234
1235 hr = IXmlWriter_SetOutput(writer, (IUnknown*)stream);
1236 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1237
1238 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
1239 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1240
1241 hr = IXmlWriter_WriteStartElement(writer, NULL, L"b", NULL);
1242 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1243
1244 hr = IXmlWriter_WriteEndDocument(writer);
1245 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1246
1247 hr = GetHGlobalFromStream(stream, &hglobal);
1248 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1249
1250 ptr = GlobalLock(hglobal);
1251 ok(ptr == NULL, "got %p\n", ptr);
1252
1253 /* we still need to flush manually, WriteEndDocument doesn't do that */
1254 hr = IXmlWriter_Flush(writer);
1255 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1256
1257 CHECK_OUTPUT(stream, "<a><b /></a>");
1258
1259 IXmlWriter_Release(writer);
1260 IStream_Release(stream);
1261}
1262
1263static void test_WriteComment(void)
1264{
1265 IXmlWriter *writer;
1266 IStream *stream;
1267 HRESULT hr;
1268
1269 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1270 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1271
1273
1274 hr = IXmlWriter_WriteComment(writer, L"a");
1275 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
1276
1277 stream = writer_set_output(writer);
1278
1279 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1280 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1281
1282 hr = IXmlWriter_WriteComment(writer, L"a");
1283 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1284
1285 hr = IXmlWriter_WriteStartElement(writer, NULL, L"b", NULL);
1286 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1287
1288 hr = IXmlWriter_WriteComment(writer, L"a");
1289 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1290
1291 hr = IXmlWriter_WriteComment(writer, NULL);
1292 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1293
1294 hr = IXmlWriter_WriteComment(writer, L"-->");
1295 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1296
1297 hr = IXmlWriter_Flush(writer);
1298 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1299
1300 CHECK_OUTPUT(stream, "<!--a--><b><!--a--><!----><!--- ->-->");
1301
1302 IXmlWriter_Release(writer);
1303 IStream_Release(stream);
1304}
1305
1306static void test_WriteCData(void)
1307{
1308 IXmlWriter *writer;
1309 IStream *stream;
1310 HRESULT hr;
1311
1312 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1313 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1314
1316
1317 hr = IXmlWriter_WriteCData(writer, L"a");
1318 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
1319
1320 stream = writer_set_output(writer);
1321
1322 hr = IXmlWriter_WriteStartElement(writer, NULL, L"b", NULL);
1323 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1324
1325 hr = IXmlWriter_WriteCData(writer, L"a");
1326 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1327
1328 hr = IXmlWriter_WriteCData(writer, NULL);
1329 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1330
1331 hr = IXmlWriter_WriteCData(writer, L"]]>");
1332 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1333
1334 hr = IXmlWriter_WriteCData(writer, L"a]]>b");
1335 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1336
1337 hr = IXmlWriter_Flush(writer);
1338 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1339
1341 "<b>"
1342 "<![CDATA[a]]>"
1343 "<![CDATA[]]>"
1344 "<![CDATA[]]]]>"
1345 "<![CDATA[>]]>"
1346 "<![CDATA[a]]]]>"
1347 "<![CDATA[>b]]>");
1348
1349 IXmlWriter_Release(writer);
1350 IStream_Release(stream);
1351}
1352
1353static void test_WriteRaw(void)
1354{
1355 static const WCHAR surrogates[] = {0xdc00, 0xd800, '\0'};
1356 static const WCHAR invalid[] = {0x8, '\0'};
1357 static const WCHAR rawW[] = L"a<:";
1358 IXmlWriter *writer;
1359 IStream *stream;
1360 HRESULT hr;
1361
1362 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1363 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1364
1365 hr = IXmlWriter_WriteRaw(writer, NULL);
1366 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1367
1368 hr = IXmlWriter_WriteRaw(writer, rawW);
1369 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
1370
1371 stream = writer_set_output(writer);
1372
1373 hr = IXmlWriter_WriteRaw(writer, surrogates);
1374 ok(hr == WR_E_INVALIDSURROGATEPAIR, "Unexpected hr %#lx.\n", hr);
1375
1376 hr = IXmlWriter_WriteRaw(writer, L"\uffff");
1377 ok(hr == WC_E_XMLCHARACTER, "Unexpected hr %#lx.\n", hr);
1378
1379 hr = IXmlWriter_WriteRaw(writer, invalid);
1380 ok(hr == WC_E_XMLCHARACTER, "Unexpected hr %#lx.\n", hr);
1381
1382 hr = IXmlWriter_WriteRaw(writer, NULL);
1383 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1384
1385 hr = IXmlWriter_WriteRaw(writer, rawW);
1386 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1387
1388 hr = IXmlWriter_WriteRaw(writer, rawW);
1389 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1390
1391 hr = IXmlWriter_WriteComment(writer, rawW);
1392 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1393
1394 hr = IXmlWriter_WriteRaw(writer, rawW);
1395 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1396
1397 hr = IXmlWriter_WriteElementString(writer, NULL, L"a", NULL, L"a");
1398 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1399
1400 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
1401 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1402
1403 hr = IXmlWriter_WriteComment(writer, rawW);
1404 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1405
1406 hr = IXmlWriter_WriteEndDocument(writer);
1407 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1408
1409 hr = IXmlWriter_WriteRaw(writer, rawW);
1410 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1411
1412 hr = IXmlWriter_Flush(writer);
1413 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1414 CHECK_OUTPUT(stream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>a<:a<:<!--a<:-->a<:<a>a</a>");
1415 IStream_Release(stream);
1416
1417 /* With open element. */
1418 stream = writer_set_output(writer);
1419
1420 hr = IXmlWriter_WriteStartElement(writer, NULL, L"w", NULL);
1421 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1422 hr = IXmlWriter_WriteRaw(writer, L"text");
1423 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1424
1425 hr = IXmlWriter_Flush(writer);
1426 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1427 CHECK_OUTPUT(stream, "<w>text");
1428 IStream_Release(stream);
1429
1430 IXmlWriter_Release(writer);
1431}
1432
1433static void test_writer_state(void)
1434{
1435 IXmlWriter *writer;
1436 IStream *stream;
1437 HRESULT hr;
1438
1439 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1440 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1441
1442 /* initial state */
1444
1445 /* set output and call 'wrong' method, WriteEndElement */
1446 stream = writer_set_output(writer);
1447
1448 hr = IXmlWriter_WriteEndElement(writer);
1449 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1450
1452 IStream_Release(stream);
1453
1454 /* WriteAttributeString */
1455 stream = writer_set_output(writer);
1456
1457 hr = IXmlWriter_WriteAttributeString(writer, NULL, L"a", NULL, L"a");
1458 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1459
1461 IStream_Release(stream);
1462
1463 /* WriteEndDocument */
1464 stream = writer_set_output(writer);
1465
1466 hr = IXmlWriter_WriteEndDocument(writer);
1467 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1468
1470 IStream_Release(stream);
1471
1472 /* WriteFullEndElement */
1473 stream = writer_set_output(writer);
1474
1475 hr = IXmlWriter_WriteFullEndElement(writer);
1476 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1477
1479 IStream_Release(stream);
1480
1481 /* WriteCData */
1482 stream = writer_set_output(writer);
1483
1484 hr = IXmlWriter_WriteCData(writer, L"a");
1485 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1486
1488 IStream_Release(stream);
1489
1490 /* WriteName */
1491 stream = writer_set_output(writer);
1492
1493 hr = IXmlWriter_WriteName(writer, L"a");
1494 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1495
1497 IStream_Release(stream);
1498
1499 /* WriteNmToken */
1500 stream = writer_set_output(writer);
1501
1502 hr = IXmlWriter_WriteNmToken(writer, L"a");
1503 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1504
1506 IStream_Release(stream);
1507
1508 /* WriteString */
1509 stream = writer_set_output(writer);
1510
1511 hr = IXmlWriter_WriteString(writer, L"a");
1512 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1513
1515 IStream_Release(stream);
1516
1517 /* WriteChars */
1518 stream = writer_set_output(writer);
1519
1520 hr = IXmlWriter_WriteChars(writer, L"a", 1);
1521 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
1522
1524
1525 IStream_Release(stream);
1526 IXmlWriter_Release(writer);
1527}
1528
1529static void test_indentation(void)
1530{
1531 IXmlWriter *writer;
1532 IStream *stream;
1533 HRESULT hr;
1534
1535 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1536 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1537
1538 stream = writer_set_output(writer);
1539
1542
1543 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1544 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1545
1546 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
1547 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1548
1549 hr = IXmlWriter_WriteComment(writer, L"comment");
1550 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1551
1552 hr = IXmlWriter_WriteStartElement(writer, NULL, L"b", NULL);
1553 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1554
1555 hr = IXmlWriter_WriteEndDocument(writer);
1556 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1557
1558 hr = IXmlWriter_Flush(writer);
1559 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1560
1562 "<a>\r\n"
1563 " <!--comment-->\r\n"
1564 " <b />\r\n"
1565 "</a>");
1566
1567 IStream_Release(stream);
1568
1569 /* WriteElementString */
1570 stream = writer_set_output(writer);
1571
1572 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
1573 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1574
1575 hr = IXmlWriter_WriteElementString(writer, NULL, L"b", NULL, NULL);
1576 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1577
1578 hr = IXmlWriter_WriteElementString(writer, NULL, L"b", NULL, NULL);
1579 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1580
1581 hr = IXmlWriter_WriteEndElement(writer);
1582 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1583
1584 hr = IXmlWriter_Flush(writer);
1585 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1586
1588 "<a>\r\n"
1589 " <b />\r\n"
1590 " <b />\r\n"
1591 "</a>");
1592
1593 IStream_Release(stream);
1594
1595 IXmlWriter_Release(writer);
1596}
1597
1599{
1600 static const struct
1601 {
1602 const WCHAR *prefix;
1603 const WCHAR *local;
1604 const WCHAR *uri;
1605 const WCHAR *value;
1606 const char *output;
1607 const char *output_partial;
1608 HRESULT hr;
1609 int todo;
1610 int todo_partial;
1611 int todo_hr;
1612 }
1613 attribute_tests[] =
1614 {
1615 { NULL, L"a", NULL, L"b", "<e a=\"b\" />", "<e a=\"b\"" },
1616 { L"", L"a", NULL, L"b", "<e a=\"b\" />", "<e a=\"b\"" },
1617 { NULL, L"a", L"", L"b", "<e a=\"b\" />", "<e a=\"b\"" },
1618 { L"", L"a", L"", L"b", "<e a=\"b\" />", "<e a=\"b\"" },
1619 { L"prefix", L"local", L"uri", L"b", "<e prefix:local=\"b\" xmlns:prefix=\"uri\" />", "<e prefix:local=\"b\"" },
1620 { NULL, L"a", L"http://www.w3.org/2000/xmlns/", L"defuri", "<e xmlns:a=\"defuri\" />", "<e xmlns:a=\"defuri\"" },
1621 { L"xmlns", L"a", NULL, L"uri", "<e xmlns:a=\"uri\" />", "<e xmlns:a=\"uri\"" },
1622 { L"xmlns", L"a", L"", L"uri", "<e xmlns:a=\"uri\" />", "<e xmlns:a=\"uri\"" },
1623 { L"prefix", L"xmlns", L"uri", L"value", "<e prefix:xmlns=\"value\" xmlns:prefix=\"uri\" />", "<e prefix:xmlns=\"value\"" },
1624 { L"prefix", L"xmlns", L"uri", NULL, "<e prefix:xmlns=\"\" xmlns:prefix=\"uri\" />", "<e prefix:xmlns=\"\"" },
1625 { L"prefix", L"xmlns", L"uri", L"", "<e prefix:xmlns=\"\" xmlns:prefix=\"uri\" />", "<e prefix:xmlns=\"\"" },
1626 { L"prefix", L"xmlns", NULL, L"uri", "<e xmlns=\"uri\" />", "<e xmlns=\"uri\"" },
1627 { L"prefix", L"xmlns", L"", L"uri", "<e xmlns=\"uri\" />", "<e xmlns=\"uri\"" },
1628 { L"xml", L"space", NULL, L"preserve", "<e xml:space=\"preserve\" />", "<e xml:space=\"preserve\"" },
1629 { L"xml", L"space", L"", L"preserve", "<e xml:space=\"preserve\" />", "<e xml:space=\"preserve\"" },
1630 { L"xml", L"space", NULL, L"default", "<e xml:space=\"default\" />", "<e xml:space=\"default\"" },
1631 { L"xml", L"space", L"", L"default", "<e xml:space=\"default\" />", "<e xml:space=\"default\"" },
1632 { L"xml", L"a", NULL, L"value", "<e xml:a=\"value\" />", "<e xml:a=\"value\"" },
1633 { L"xml", L"a", L"", L"value", "<e xml:a=\"value\" />", "<e xml:a=\"value\"" },
1634
1635 /* Autogenerated prefix names. */
1636 { NULL, L"a", L"defuri", NULL, "<e p1:a=\"\" xmlns:p1=\"defuri\" />", "<e p1:a=\"\"", S_OK, 1, 1, 1 },
1637 { NULL, L"a", L"defuri", L"b", "<e p1:a=\"b\" xmlns:p1=\"defuri\" />", "<e p1:a=\"b\"", S_OK, 1, 1, 1 },
1638 { L"", L"a", L"defuri", NULL, "<e p1:a=\"\" xmlns:p1=\"defuri\" />", "<e p1:a=\"\"", S_OK, 1, 1, 1 },
1639 { NULL, L"a", L"defuri", L"", "<e p1:a=\"\" xmlns:p1=\"defuri\" />", "<e p1:a=\"\"", S_OK, 1, 1, 1 },
1640 { L"", L"a", L"defuri", L"b", "<e p1:a=\"b\" xmlns:p1=\"defuri\" />", "<e p1:a=\"b\"", S_OK, 1, 1, 1 },
1641
1642 /* Failing cases. */
1643 { NULL, NULL, L"http://www.w3.org/2000/xmlns/", L"defuri", "<e />", "<e", E_INVALIDARG },
1644 { L"", L"a", L"http://www.w3.org/2000/xmlns/", L"defuri", "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION, 1, 1, 1 },
1645 { L"", NULL, L"http://www.w3.org/2000/xmlns/", L"defuri", "<e />", "<e", E_INVALIDARG },
1646 { L"", L"", L"http://www.w3.org/2000/xmlns/", L"defuri", "<e />", "<e", E_INVALIDARG },
1647 { NULL, L"", L"http://www.w3.org/2000/xmlns/", L"defuri", "<e />", "<e", E_INVALIDARG },
1648 { L"prefix", L"a", L"http://www.w3.org/2000/xmlns/", L"defuri", "<e />", "<e", WR_E_XMLNSURIDECLARATION, 1, 1, 1 },
1649 { L"prefix", NULL, L"http://www.w3.org/2000/xmlns/", L"defuri", "<e />", "<e", E_INVALIDARG },
1650 { L"prefix", NULL, NULL, L"b", "<e />", "<e", E_INVALIDARG },
1651 { L"prefix", NULL, L"uri", NULL, "<e />", "<e", E_INVALIDARG },
1652 { L"xml", NULL, NULL, L"value", "<e />", "<e", E_INVALIDARG },
1653 { L"xmlns", L"a", L"defuri", NULL, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION },
1654 { L"xmlns", L"a", L"b", L"uri", "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION },
1655 { NULL, L"xmlns", L"uri", NULL, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION, 0, 0, 1 },
1656 { L"xmlns", NULL, L"uri", NULL, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION, 0, 0, 1 },
1657 { L"pre:fix", L"local", L"uri", L"b", "<e />", "<e", WC_E_NAMECHARACTER },
1658 { L"pre:fix", NULL, L"uri", L"b", "<e />", "<e", E_INVALIDARG },
1659 { L"prefix", L"lo:cal", L"uri", L"b", "<e />", "<e", WC_E_NAMECHARACTER },
1660 { L"xmlns", NULL, NULL, L"uri", "<e />", "<e", WR_E_NSPREFIXDECLARED },
1661 { L"xmlns", NULL, L"", L"uri", "<e />", "<e", WR_E_NSPREFIXDECLARED },
1662 { L"xmlns", L"", NULL, L"uri", "<e />", "<e", WR_E_NSPREFIXDECLARED },
1663 { L"xmlns", L"", L"", L"uri", "<e />", "<e", WR_E_NSPREFIXDECLARED },
1664 { L"xml", L"space", L"", L"value", "<e />", "<e", WR_E_INVALIDXMLSPACE },
1665 { L"xml", L"space", NULL, L"value", "<e />", "<e", WR_E_INVALIDXMLSPACE },
1666 { L"xml", L"a", L"uri", L"value", "<e />", "<e", WR_E_XMLPREFIXDECLARATION },
1667 { L"xml", L"space", NULL, L"preServe", "<e />", "<e", WR_E_INVALIDXMLSPACE },
1668 { L"xml", L"space", NULL, L"defAult", "<e />", "<e", WR_E_INVALIDXMLSPACE },
1669 { L"xml", L"space", NULL, NULL, "<e />", "<e", WR_E_INVALIDXMLSPACE },
1670 { L"xml", L"space", NULL, L"", "<e />", "<e", WR_E_INVALIDXMLSPACE },
1671 };
1672
1673 IXmlWriter *writer;
1674 IStream *stream;
1675 unsigned int i;
1676 HRESULT hr;
1677
1678 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1679 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1680
1682
1683 for (i = 0; i < ARRAY_SIZE(attribute_tests); ++i)
1684 {
1685 winetest_push_context("Test %u", i);
1686
1687 stream = writer_set_output(writer);
1688
1689 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1690 ok(hr == S_OK, "Failed to start document, hr %#lx.\n", hr);
1691
1692 hr = IXmlWriter_WriteStartElement(writer, NULL, L"e", NULL);
1693 ok(hr == S_OK, "Failed to start element, hr %#lx.\n", hr);
1694
1695 hr = IXmlWriter_WriteAttributeString(writer, attribute_tests[i].prefix, attribute_tests[i].local,
1696 attribute_tests[i].uri, attribute_tests[i].value);
1697 todo_wine_if(attribute_tests[i].todo_hr)
1698 ok(hr == attribute_tests[i].hr, "Unexpected hr %#lx, expected %#lx.\n", hr, attribute_tests[i].hr);
1699
1700 hr = IXmlWriter_Flush(writer);
1701 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
1702
1703 check_output(stream, attribute_tests[i].output_partial, attribute_tests[i].todo_partial, __LINE__);
1704
1705 hr = IXmlWriter_WriteEndDocument(writer);
1706 ok(hr == S_OK, "Failed to end document, hr %#lx.\n", hr);
1707
1708 hr = IXmlWriter_Flush(writer);
1709 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
1710
1711 check_output(stream, attribute_tests[i].output, attribute_tests[i].todo, __LINE__);
1712 IStream_Release(stream);
1713
1715 }
1716
1717 /* With namespaces */
1718 stream = writer_set_output(writer);
1719
1720 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1721 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1722
1723 hr = IXmlWriter_WriteStartElement(writer, L"p", L"a", L"outeruri");
1724 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1725
1726 hr = IXmlWriter_WriteAttributeString(writer, L"prefix", L"local", L"uri", L"b");
1727 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1728
1729 hr = IXmlWriter_WriteAttributeString(writer, NULL, L"a", NULL, L"b");
1730 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1731
1732 hr = IXmlWriter_WriteAttributeString(writer, L"xmlns", L"prefix", NULL, L"uri");
1733 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1734
1735 hr = IXmlWriter_WriteAttributeString(writer, L"p", L"attr", NULL, L"value");
1736 ok(hr == S_OK, "Failed to write attribute string, hr %#lx.\n", hr);
1737
1738 hr = IXmlWriter_WriteAttributeString(writer, L"prefix", L"local", NULL, L"b");
1739 todo_wine
1740 ok(hr == WR_E_DUPLICATEATTRIBUTE, "Unexpected hr %#lx.\n", hr);
1741
1742 hr = IXmlWriter_WriteStartElement(writer, NULL, L"b", NULL);
1743 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1744
1745 hr = IXmlWriter_WriteAttributeString(writer, NULL, L"attr2", L"outeruri", L"value");
1746 ok(hr == S_OK, "Failed to write attribute string, hr %#lx.\n", hr);
1747
1748 hr = IXmlWriter_WriteAttributeString(writer, L"pr", L"attr3", L"outeruri", L"value");
1749 ok(hr == S_OK, "Failed to write attribute string, hr %#lx.\n", hr);
1750
1751 hr = IXmlWriter_WriteEndDocument(writer);
1752 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1753
1754 hr = IXmlWriter_Flush(writer);
1755 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1756
1758 "<p:a prefix:local=\"b\" a=\"b\" xmlns:prefix=\"uri\" p:attr=\"value\" xmlns:p=\"outeruri\">"
1759 "<b p:attr2=\"value\" pr:attr3=\"value\" xmlns:pr=\"outeruri\" />"
1760 "</p:a>");
1761
1762 IStream_Release(stream);
1763
1764 /* Define prefix, write attribute with it. */
1765 stream = writer_set_output(writer);
1766
1767 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1768 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1769
1770 hr = IXmlWriter_WriteStartElement(writer, NULL, L"e", NULL);
1771 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1772
1773 hr = IXmlWriter_WriteAttributeString(writer, L"xmlns", L"prefix", NULL, L"uri");
1774 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1775
1776 hr = IXmlWriter_WriteAttributeString(writer, L"prefix", L"attr", NULL, L"value");
1777 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1778
1779 hr = IXmlWriter_WriteEndDocument(writer);
1780 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1781
1782 hr = IXmlWriter_Flush(writer);
1783 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1784
1786 "<e xmlns:prefix=\"uri\" prefix:attr=\"value\" />");
1787
1788 IStream_Release(stream);
1789
1790 IXmlWriter_Release(writer);
1791}
1792
1794{
1795 IXmlWriter *writer;
1796 IStream *stream;
1797 HRESULT hr;
1798
1799 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1800 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1801
1802 /* standalone element */
1803 stream = writer_set_output(writer);
1804
1807
1808 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1809 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1810
1811 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
1812 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1813
1814 hr = IXmlWriter_WriteFullEndElement(writer);
1815 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1816
1817 hr = IXmlWriter_WriteEndDocument(writer);
1818 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1819
1820 hr = IXmlWriter_Flush(writer);
1821 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1822
1824 "<a></a>");
1825 IStream_Release(stream);
1826
1827 /* nested elements */
1828 stream = writer_set_output(writer);
1829
1832
1833 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1834 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1835
1836 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
1837 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1838
1839 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
1840 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1841
1842 hr = IXmlWriter_WriteFullEndElement(writer);
1843 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1844
1845 hr = IXmlWriter_WriteEndDocument(writer);
1846 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1847
1848 hr = IXmlWriter_Flush(writer);
1849 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1850
1852 "<a>\r\n"
1853 " <a></a>\r\n"
1854 "</a>");
1855 IStream_Release(stream);
1856
1857 /* Empty strings for prefix and uri. */
1858 stream = writer_set_output(writer);
1859
1860 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_Indent, FALSE);
1861 ok(hr == S_OK, "Failed to set property, hr %#lx.\n", hr);
1862
1863 hr = IXmlWriter_WriteStartElement(writer, L"", L"a", NULL);
1864 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1865 hr = IXmlWriter_WriteStartElement(writer, NULL, L"b", L"");
1866 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1867 hr = IXmlWriter_WriteStartElement(writer, L"", L"c", L"");
1868 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1869 hr = IXmlWriter_WriteFullEndElement(writer);
1870 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1871 hr = IXmlWriter_WriteFullEndElement(writer);
1872 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1873 hr = IXmlWriter_WriteFullEndElement(writer);
1874 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1875
1876 hr = IXmlWriter_Flush(writer);
1877 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1878 CHECK_OUTPUT(stream, "<a><b><c></c></b></a>");
1879 IStream_Release(stream);
1880
1881 IXmlWriter_Release(writer);
1882}
1883
1884static void test_WriteCharEntity(void)
1885{
1886 IXmlWriter *writer;
1887 IStream *stream;
1888 HRESULT hr;
1889
1890 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1891 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1892
1893 /* without indentation */
1894 stream = writer_set_output(writer);
1895
1897
1898 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1899 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1900
1901 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
1902 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1903
1904 hr = IXmlWriter_WriteCharEntity(writer, 0x100);
1905 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1906
1907 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
1908 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1909
1910 hr = IXmlWriter_WriteEndDocument(writer);
1911 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1912
1913 hr = IXmlWriter_Flush(writer);
1914 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1915
1917 "<a>&#x100;<a /></a>");
1918
1919 IXmlWriter_Release(writer);
1920 IStream_Release(stream);
1921}
1922
1923static void test_WriteRawChars(void)
1924{
1925 IXmlWriter *writer;
1926 IStream *stream;
1927 HRESULT hr;
1928 static WCHAR surrogates[] = {0xd800, 0xdc00, 0};
1929
1930 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1931 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1932
1933 hr = IXmlWriter_WriteRawChars(writer, NULL, 0);
1934 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1935
1936 hr = IXmlWriter_WriteRawChars(writer, L"", 0);
1937 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1938
1939 hr = IXmlWriter_WriteRawChars(writer, NULL, 5);
1940 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1941
1942 hr = IXmlWriter_WriteRawChars(writer, L"", 6);
1943 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
1944
1945 stream = writer_set_output(writer);
1946
1947 hr = IXmlWriter_WriteStartElement(writer, NULL, L"sub", NULL);
1948 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1949
1950 hr = IXmlWriter_WriteRawChars(writer, L"<rawChars>", 5);
1951 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1952
1953 hr = IXmlWriter_Flush(writer);
1954 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1955
1956 CHECK_OUTPUT(stream, "<sub><rawC");
1957 IStream_Release(stream);
1958
1959 stream = writer_set_output(writer);
1960
1961 hr = IXmlWriter_WriteRawChars(writer, L"a", 1);
1962 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1963
1964 hr = IXmlWriter_WriteStartElement(writer, NULL, L"sub", NULL);
1965 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1966
1967 hr = IXmlWriter_WriteRawChars(writer, L"<;;>", 10);
1968 ok(hr == WC_E_XMLCHARACTER, "Unexpected hr %#lx.\n", hr);
1969
1970 hr = IXmlWriter_Flush(writer);
1971 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1972
1973 CHECK_OUTPUT(stream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>a<sub><;;>");
1974 IStream_Release(stream);
1975
1976 stream = writer_set_output(writer);
1977
1978 hr = IXmlWriter_WriteStartElement(writer, NULL, L"sub", NULL);
1979 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1980
1981 hr = IXmlWriter_WriteRawChars(writer, surrogates, 1);
1982 ok(hr == WR_E_INVALIDSURROGATEPAIR, "Unexpected hr %#lx.\n", hr);
1983
1984 hr = IXmlWriter_WriteRawChars(writer, surrogates, 2);
1985 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1986
1987 hr = IXmlWriter_Flush(writer);
1988 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1989
1990 CHECK_OUTPUT(stream, "<sub>\U00010000");
1991 IStream_Release(stream);
1992
1993 stream = writer_set_output(writer);
1994
1995 hr = IXmlWriter_WriteStartElement(writer, NULL, L"sub", NULL);
1996 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1997
1998 hr = IXmlWriter_WriteRawChars(writer, L"", 5);
1999 ok(hr == WC_E_XMLCHARACTER, "Unexpected hr %#lx.\n", hr);
2000
2001 hr = IXmlWriter_Flush(writer);
2002 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2003
2004 CHECK_OUTPUT(stream, "<sub>");
2005 IStream_Release(stream);
2006
2007 stream = writer_set_output(writer);
2008
2009 hr = IXmlWriter_WriteStartElement(writer, NULL, L"sub", NULL);
2010 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2011
2012 hr = IXmlWriter_WriteRawChars(writer, L"", 0);
2013 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2014
2015 hr = IXmlWriter_Flush(writer);
2016 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2017
2018 CHECK_OUTPUT(stream, "<sub");
2019
2020 IStream_Release(stream);
2021
2022 stream = writer_set_output(writer);
2023
2024 /* Force document close */
2025 hr = IXmlWriter_WriteEndElement(writer);
2026 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
2027
2028 hr = IXmlWriter_WriteRawChars(writer, L"a", 1);
2029 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
2030
2031 IStream_Release(stream);
2032 IXmlWriter_Release(writer);
2033}
2034
2036{
2037 IXmlWriter *writer;
2038 IStream *stream;
2039 HRESULT hr;
2040 WCHAR low = 0xdcef;
2041 WCHAR high = 0xdaff;
2042
2043 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
2044 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2045
2046 hr = IXmlWriter_WriteSurrogateCharEntity(writer, high, low);
2047 ok(hr == WC_E_XMLCHARACTER, "Unexpected hr %#lx.\n", hr);
2048
2049 hr = IXmlWriter_WriteSurrogateCharEntity(writer, low, high);
2050 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
2051
2052 stream = writer_set_output(writer);
2053
2054 hr = IXmlWriter_WriteStartElement(writer, NULL, L"root", NULL);
2055 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2056
2057 hr = IXmlWriter_WriteSurrogateCharEntity(writer, high, low);
2058 ok(hr == WC_E_XMLCHARACTER, "Unexpected hr %#lx.\n", hr);
2059
2060 hr = IXmlWriter_Flush(writer);
2061 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2062
2063 CHECK_OUTPUT(stream, "<root");
2064
2065 hr = IXmlWriter_WriteSurrogateCharEntity(writer, low, high);
2066 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2067
2068 hr = IXmlWriter_WriteFullEndElement(writer);
2069 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2070
2071 hr = IXmlWriter_Flush(writer);
2072 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2073
2074 CHECK_OUTPUT(stream, "<root>&#xCFCEF;</root>");
2075 IStream_Release(stream);
2076
2077 stream = writer_set_output(writer);
2078
2079 hr = IXmlWriter_WriteEndElement(writer);
2080 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
2081
2082 hr = IXmlWriter_WriteSurrogateCharEntity(writer, low, high);
2083 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
2084
2085 IXmlWriter_Release(writer);
2086 IStream_Release(stream);
2087}
2088
2089static void test_WriteString(void)
2090{
2091 static const WCHAR surrogates[] = {0xd800, 0xdc00, 'x', 'y', '\0'};
2092 IXmlWriter *writer;
2093 IStream *stream;
2094 HRESULT hr;
2095
2096 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
2097 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2098
2100
2101 hr = IXmlWriter_WriteString(writer, L"a");
2102 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
2103
2104 hr = IXmlWriter_WriteString(writer, NULL);
2105 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2106
2107 hr = IXmlWriter_WriteString(writer, L"");
2108 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
2109
2110 stream = writer_set_output(writer);
2111
2112 hr = IXmlWriter_WriteStartElement(writer, NULL, L"sub", NULL);
2113 ok(hr == S_OK, "Unexpected hr #%lx.\n", hr);
2114
2115 hr = IXmlWriter_WriteString(writer, L"\v");
2116 ok(hr == WC_E_XMLCHARACTER, "Unexpected hr %#lx.\n", hr);
2117
2118 hr = IXmlWriter_WriteString(writer, L"\ufffe");
2119 ok(hr == WC_E_XMLCHARACTER, "Unexpected hr %#lx.\n", hr);
2120
2121 hr = IXmlWriter_WriteString(writer, surrogates);
2122 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2123
2124 hr = IXmlWriter_Flush(writer);
2125 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2126
2128 "<sub>\U00010000xy");
2129 IStream_Release(stream);
2130
2131 stream = writer_set_output(writer);
2132
2133 hr = IXmlWriter_WriteStartElement(writer, NULL, L"b", NULL);
2134 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2135
2136 hr = IXmlWriter_WriteString(writer, NULL);
2137 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2138
2139 hr = IXmlWriter_WriteString(writer, L"");
2140 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2141
2142 hr = IXmlWriter_WriteString(writer, L"a");
2143 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2144
2145 /* WriteString automatically escapes markup characters */
2146 hr = IXmlWriter_WriteString(writer, L"<&\">=");
2147 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2148
2149 hr = IXmlWriter_Flush(writer);
2150 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2151
2153 "<b>a&lt;&amp;\"&gt;=");
2154 IStream_Release(stream);
2155
2156 stream = writer_set_output(writer);
2157
2158 hr = IXmlWriter_WriteStartElement(writer, NULL, L"b", NULL);
2159 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2160
2161 hr = IXmlWriter_WriteString(writer, NULL);
2162 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2163
2164 hr = IXmlWriter_Flush(writer);
2165 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2166
2168 "<b");
2169
2170 hr = IXmlWriter_WriteString(writer, L"");
2171 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2172
2173 hr = IXmlWriter_Flush(writer);
2174 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2175
2177 "<b>");
2178
2179 IStream_Release(stream);
2180 IXmlWriter_Release(writer);
2181
2182 /* With indentation */
2183 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
2184 ok(hr == S_OK, "Failed to create a writer, hr %#lx.\n", hr);
2185
2186 stream = writer_set_output(writer);
2187
2189
2190 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
2191 ok(hr == S_OK, "Failed to start element, hr %#lx.\n", hr);
2192
2193 hr = IXmlWriter_WriteStartElement(writer, NULL, L"b", NULL);
2194 ok(hr == S_OK, "Failed to start element, hr %#lx.\n", hr);
2195
2196 hr = IXmlWriter_WriteString(writer, L"text");
2197 ok(hr == S_OK, "Failed to write a string, hr %#lx.\n", hr);
2198
2199 hr = IXmlWriter_Flush(writer);
2200 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2201
2203 "<a>\r\n"
2204 " <b>text");
2205
2206 hr = IXmlWriter_WriteFullEndElement(writer);
2207 ok(hr == S_OK, "Failed to end element, hr %#lx.\n", hr);
2208
2209 hr = IXmlWriter_Flush(writer);
2210 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2211
2213 "<a>\r\n"
2214 " <b>text</b>");
2215
2216 hr = IXmlWriter_WriteFullEndElement(writer);
2217 ok(hr == S_OK, "Failed to end element, hr %#lx.\n", hr);
2218
2219 hr = IXmlWriter_Flush(writer);
2220 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2221
2223 "<a>\r\n"
2224 " <b>text</b>\r\n"
2225 "</a>");
2226
2227 IStream_Release(stream);
2228
2229 stream = writer_set_output(writer);
2230
2231 hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL);
2232 ok(hr == S_OK, "Failed to start element, hr %#lx.\n", hr);
2233
2234 hr = IXmlWriter_WriteStartElement(writer, NULL, L"b", NULL);
2235 ok(hr == S_OK, "Failed to start element, hr %#lx.\n", hr);
2236
2237 hr = IXmlWriter_WriteEndElement(writer);
2238 ok(hr == S_OK, "Failed to end element, hr %#lx.\n", hr);
2239
2240 hr = IXmlWriter_Flush(writer);
2241 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2242
2244 "<a>\r\n"
2245 " <b />");
2246
2247 hr = IXmlWriter_WriteStartElement(writer, NULL, L"c", NULL);
2248 ok(hr == S_OK, "Failed to start element, hr %#lx.\n", hr);
2249
2250 hr = IXmlWriter_WriteAttributeString(writer, NULL, L"attr", NULL, L"value");
2251 ok(hr == S_OK, "Failed to write attribute string, hr %#lx.\n", hr);
2252
2253 hr = IXmlWriter_Flush(writer);
2254 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2255
2257 "<a>\r\n"
2258 " <b />\r\n"
2259 " <c attr=\"value\"");
2260
2261 hr = IXmlWriter_WriteString(writer, L"text");
2262 ok(hr == S_OK, "Failed to write a string, hr %#lx.\n", hr);
2263
2264 hr = IXmlWriter_Flush(writer);
2265 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2266
2268 "<a>\r\n"
2269 " <b />\r\n"
2270 " <c attr=\"value\">text");
2271
2272 hr = IXmlWriter_WriteEndElement(writer);
2273 ok(hr == S_OK, "Failed to end element, hr %#lx.\n", hr);
2274
2275 hr = IXmlWriter_Flush(writer);
2276 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2277
2279 "<a>\r\n"
2280 " <b />\r\n"
2281 " <c attr=\"value\">text</c>");
2282
2283 hr = IXmlWriter_WriteStartElement(writer, NULL, L"d", NULL);
2284 ok(hr == S_OK, "Failed to start element, hr %#lx.\n", hr);
2285
2286 hr = IXmlWriter_WriteString(writer, L"");
2287 ok(hr == S_OK, "Failed to write a string, hr %#lx.\n", hr);
2288
2289 hr = IXmlWriter_WriteEndElement(writer);
2290 ok(hr == S_OK, "Failed to end element, hr %#lx.\n", hr);
2291
2292 hr = IXmlWriter_Flush(writer);
2293 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2294
2296 "<a>\r\n"
2297 " <b />\r\n"
2298 " <c attr=\"value\">text</c>\r\n"
2299 " <d></d>");
2300
2301 hr = IXmlWriter_WriteEndElement(writer);
2302 ok(hr == S_OK, "Failed to end element, hr %#lx.\n", hr);
2303
2304 hr = IXmlWriter_Flush(writer);
2305 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2306
2308 "<a>\r\n"
2309 " <b />\r\n"
2310 " <c attr=\"value\">text</c>\r\n"
2311 " <d></d>\r\n"
2312 "</a>");
2313
2314 IXmlWriter_Release(writer);
2315 IStream_Release(stream);
2316}
2317
2318static void test_WriteChars(void)
2319{
2320 IXmlWriter *writer;
2321 IStream *stream;
2322 HRESULT hr;
2323 static WCHAR raw[] = {'s', 'a', 'm', 0xd800, 0xdc00, 'p', 'l', 'e', 0};
2324
2325 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
2326 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2327
2328 hr = IXmlWriter_WriteChars(writer, NULL, 0);
2329 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2330
2331 hr = IXmlWriter_WriteChars(writer, NULL, 5);
2332 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2333
2334 hr = IXmlWriter_WriteChars(writer, L"", 0);
2335 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2336
2337 hr = IXmlWriter_WriteChars(writer, L"", 5);
2338 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
2339
2340 stream = writer_set_output(writer);
2341
2342 hr = IXmlWriter_WriteChars(writer, L"a", 1);
2343 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
2344
2345 hr = IXmlWriter_WriteStartElement(writer, NULL, L"chars", NULL);
2346 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
2347
2348 IStream_Release(stream);
2349
2350 stream = writer_set_output(writer);
2351
2352 hr = IXmlWriter_WriteStartElement(writer, NULL, L"chars", NULL);
2353 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2354
2355 hr = IXmlWriter_WriteChars(writer, NULL, 5);
2356 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2357
2358 hr = IXmlWriter_WriteChars(writer, L"<chars>", 20);
2359 ok(hr == WC_E_XMLCHARACTER, "Unexpected hr %#lx.\n", hr);
2360
2361 hr = IXmlWriter_WriteChars(writer, L"<chars>", 7);
2362 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2363
2364 hr = IXmlWriter_Flush(writer);
2365 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2366
2368 "<chars>&lt;chars&gt;&lt;chars&gt;");
2369 IStream_Release(stream);
2370
2371 stream = writer_set_output(writer);
2372
2373 hr = IXmlWriter_WriteStartElement(writer, NULL, L"chars", NULL);
2374 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2375
2376 hr = IXmlWriter_WriteChars(writer, raw, 8);
2377 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2378
2379 raw[3] = 0xdc00;
2380 raw[4] = 0xd800;
2381 hr = IXmlWriter_WriteChars(writer, raw, 8);
2382 ok(hr == WR_E_INVALIDSURROGATEPAIR, "Unexpected hr %#lx.\n", hr);
2383
2384 hr = IXmlWriter_Flush(writer);
2385 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2386
2387 CHECK_OUTPUT(stream, "<chars>sam\U00010000plesam");
2388 IStream_Release(stream);
2389
2390 stream = writer_set_output(writer);
2391
2392 hr = IXmlWriter_WriteStartElement(writer, NULL, L"chars", NULL);
2393 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2394
2395 hr = IXmlWriter_WriteChars(writer, NULL, 0);
2396 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2397
2398 hr = IXmlWriter_WriteFullEndElement(writer);
2399 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2400
2401 hr = IXmlWriter_Flush(writer);
2402 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2403
2405 "<chars></chars>");
2406 IStream_Release(stream);
2407
2408 stream = writer_set_output(writer);
2409
2410 hr = IXmlWriter_WriteStartElement(writer, NULL, L"chars", NULL);
2411 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2412
2413 hr = IXmlWriter_WriteChars(writer, L"", 0);
2414 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2415
2416 hr = IXmlWriter_Flush(writer);
2417 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2418
2420 "<chars");
2421
2422 IStream_Release(stream);
2423
2424 stream = writer_set_output(writer);
2425
2426 hr = IXmlWriter_WriteStartElement(writer, NULL, L"c", NULL);
2427 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2428
2429 hr = IXmlWriter_WriteChars(writer, L"", 5);
2430 ok(hr == WC_E_XMLCHARACTER, "Unexpected hr %#lx.\n", hr);
2431
2432 hr = IXmlWriter_Flush(writer);
2433 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2434
2436 "<c>");
2437
2438 IXmlWriter_Release(writer);
2439 IStream_Release(stream);
2440}
2441
2442static void test_WriteDocType(void)
2443{
2444 static const struct
2445 {
2446 const WCHAR *name;
2447 const WCHAR *pubid;
2448 const WCHAR *sysid;
2449 const WCHAR *subset;
2450 const char *output;
2451 }
2452 doctype_tests[] =
2453 {
2454 { L"a", L"", NULL, NULL, "<!DOCTYPE a PUBLIC \"\" \"\">" },
2455 { L"a", NULL, NULL, NULL, "<!DOCTYPE a>" },
2456 { L"a", NULL, L"", NULL, "<!DOCTYPE a SYSTEM \"\">" },
2457 { L"a", L"", L"", NULL, "<!DOCTYPE a PUBLIC \"\" \"\">" },
2458 { L"a", L"pubid", L"", NULL, "<!DOCTYPE a PUBLIC \"pubid\" \"\">" },
2459 { L"a", L"pubid", NULL, NULL, "<!DOCTYPE a PUBLIC \"pubid\" \"\">" },
2460 { L"a", L"", L"sysid", NULL, "<!DOCTYPE a PUBLIC \"\" \"sysid\">" },
2461 { L"a", NULL, NULL, L"", "<!DOCTYPE a []>" },
2462 { L"a", NULL, NULL, L"subset", "<!DOCTYPE a [subset]>" },
2463 { L"a", L"", NULL, L"subset", "<!DOCTYPE a PUBLIC \"\" \"\" [subset]>" },
2464 { L"a", NULL, L"", L"subset", "<!DOCTYPE a SYSTEM \"\" [subset]>" },
2465 { L"a", L"", L"", L"subset", "<!DOCTYPE a PUBLIC \"\" \"\" [subset]>" },
2466 { L"a", L"pubid", NULL, L"subset", "<!DOCTYPE a PUBLIC \"pubid\" \"\" [subset]>" },
2467 { L"a", L"pubid", L"", L"subset", "<!DOCTYPE a PUBLIC \"pubid\" \"\" [subset]>" },
2468 { L"a", NULL, L"sysid", L"subset", "<!DOCTYPE a SYSTEM \"sysid\" [subset]>" },
2469 { L"a", L"", L"sysid", L"subset", "<!DOCTYPE a PUBLIC \"\" \"sysid\" [subset]>" },
2470 { L"a", L"pubid", L"sysid", L"subset", "<!DOCTYPE a PUBLIC \"pubid\" \"sysid\" [subset]>" },
2471 };
2472 static const WCHAR pubidW[] = {'p',0x100,'i','d',0};
2473 IXmlWriter *writer;
2474 IStream *stream;
2475 unsigned int i;
2476 HRESULT hr;
2477
2478 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
2479 ok(hr == S_OK, "Failed to create writer instance, hr %#lx.\n", hr);
2480
2481 stream = writer_set_output(writer);
2482
2483 hr = IXmlWriter_WriteDocType(writer, NULL, NULL, NULL, NULL);
2484 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2485
2486 hr = IXmlWriter_WriteDocType(writer, L"", NULL, NULL, NULL);
2487 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2488
2489 /* Name validation. */
2490 hr = IXmlWriter_WriteDocType(writer, L"-a", NULL, NULL, NULL);
2491 ok(hr == WC_E_NAMECHARACTER, "Unexpected hr %#lx.\n", hr);
2492
2493 /* Pubid validation. */
2494 hr = IXmlWriter_WriteDocType(writer, L"a", pubidW, NULL, NULL);
2495 ok(hr == WC_E_PUBLICID, "Unexpected hr %#lx.\n", hr);
2496
2497 /* Invalid multi-character string */
2498 hr = IXmlWriter_WriteDocType(writer, L":ax>m", NULL, NULL, NULL);
2499 ok(hr == WC_E_NAMECHARACTER, "Unexpected hr %#lx.\n", hr);
2500
2501 /* Valid multi-character string */
2502 hr = IXmlWriter_WriteDocType(writer, L"root", NULL, NULL, NULL);
2503 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2504
2505 IStream_Release(stream);
2506
2507 for (i = 0; i < ARRAY_SIZE(doctype_tests); i++)
2508 {
2509 stream = writer_set_output(writer);
2510
2511 hr = IXmlWriter_WriteDocType(writer, doctype_tests[i].name, doctype_tests[i].pubid, doctype_tests[i].sysid,
2512 doctype_tests[i].subset);
2513 ok(hr == S_OK, "%u: failed to write doctype, hr %#lx.\n", i, hr);
2514
2515 hr = IXmlWriter_Flush(writer);
2516 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2517
2518 CHECK_OUTPUT(stream, doctype_tests[i].output);
2519
2520 hr = IXmlWriter_WriteDocType(writer, doctype_tests[i].name, doctype_tests[i].pubid, doctype_tests[i].sysid,
2521 doctype_tests[i].subset);
2522 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr);
2523
2524 IStream_Release(stream);
2525 }
2526
2527 IXmlWriter_Release(writer);
2528}
2529
2530static void test_WriteWhitespace(void)
2531{
2532 IXmlWriter *writer;
2533 IStream *stream;
2534 HRESULT hr;
2535
2536 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
2537 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2538
2539 stream = writer_set_output(writer);
2540
2541 hr = IXmlWriter_WriteWhitespace(writer, L" ");
2542 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2543 hr = IXmlWriter_WriteWhitespace(writer, L"ab");
2544 ok(hr == WR_E_NONWHITESPACE, "Unexpected hr %#lx.\n", hr);
2545 hr = IXmlWriter_WriteStartElement(writer, NULL, L"w", NULL);
2546 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2547 hr = IXmlWriter_WriteWhitespace(writer, L"\t");
2548 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2549
2550 hr = IXmlWriter_Flush(writer);
2551 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2552 CHECK_OUTPUT(stream, " <w>\t");
2553 IStream_Release(stream);
2554
2555 IXmlWriter_Release(writer);
2556}
2557
2559{
2560 IXmlWriter *writer;
2561 IStream *stream;
2562 HRESULT hr;
2563
2564 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
2565 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2566
2567 stream = writer_set_output(writer);
2568
2569 hr = IXmlWriter_WriteStartElement(writer, NULL, L"w", NULL);
2570 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2571 hr = IXmlWriter_WriteProcessingInstruction(writer, L"pi", L"content");
2572 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2573
2574 hr = IXmlWriter_Flush(writer);
2575 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2576 CHECK_OUTPUT(stream, "<w><?pi content?>");
2577 IStream_Release(stream);
2578
2579 IXmlWriter_Release(writer);
2580}
2581
2582static void test_WriteAttributes(void)
2583{
2584 XmlNodeType node_type;
2585 IXmlWriter *writer;
2587 const WCHAR *name;
2588 IStream *stream;
2589 HRESULT hr;
2590
2591 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
2592 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2593
2594 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
2595 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2596
2597 /* No attributes. */
2598 reader_set_input(reader, "<a/>");
2599 stream = writer_set_output(writer);
2600 hr = IXmlWriter_WriteAttributes(writer, reader, FALSE);
2601 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
2602 hr = IXmlReader_Read(reader, NULL);
2603 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2604 hr = IXmlWriter_WriteAttributes(writer, reader, FALSE);
2605 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2606 hr = IXmlWriter_Flush(writer);
2607 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2608 CHECK_OUTPUT(stream, "");
2609 IStream_Release(stream);
2610
2611 /* Position on element with attributes. */
2612 reader_set_input(reader, "<a attr1=\'b\' attr2=\'c\' attr3=\'d\' />");
2613 stream = writer_set_output(writer);
2614 hr = IXmlReader_Read(reader, NULL);
2615 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2616 hr = IXmlWriter_WriteStartElement(writer, NULL, L"w", NULL);
2617 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2618 hr = IXmlWriter_WriteAttributes(writer, reader, FALSE);
2619 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2620 hr = IXmlReader_GetNodeType(reader, &node_type);
2621 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2622 ok(node_type == XmlNodeType_Element, "Unexpected node type %d.\n", node_type);
2623 hr = IXmlWriter_Flush(writer);
2624 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2625 CHECK_OUTPUT(stream, "<w attr1=\"b\" attr2=\"c\" attr3=\"d\"");
2626 IStream_Release(stream);
2627
2628 /* Position on second attribute. */
2629 hr = IXmlReader_MoveToAttributeByName(reader, L"attr2", NULL);
2630 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2631 stream = writer_set_output(writer);
2632 hr = IXmlWriter_WriteStartElement(writer, NULL, L"w", NULL);
2633 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2634 hr = IXmlWriter_WriteAttributes(writer, reader, FALSE);
2635 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2636 hr = IXmlReader_GetNodeType(reader, &node_type);
2637 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2638 ok(node_type == XmlNodeType_Attribute, "Unexpected node type %d.\n", node_type);
2639 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2640 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2641 ok(!wcscmp(name, L"attr3"), "Unexpected node %s.\n", debugstr_w(name));
2642 hr = IXmlWriter_Flush(writer);
2643 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2644 CHECK_OUTPUT(stream, "<w attr2=\"c\" attr3=\"d\"");
2645 IStream_Release(stream);
2646
2647 IXmlWriter_Release(writer);
2648 IXmlReader_Release(reader);
2649}
2650
2651static void test_WriteNode(void)
2652{
2653 static const struct
2654 {
2655 const char *input;
2656 const char *output;
2657 XmlNodeType node_type;
2658 }
2659 write_node_tests[] =
2660 {
2661 { "<r><!-- comment --></r>", "<w><!-- comment -->", XmlNodeType_Comment },
2662 { "<r>text</r>", "<w>text", XmlNodeType_Text },
2663 { "<r> </r>", "<w> ", XmlNodeType_Whitespace },
2664 { "<r><![CDATA[ cdata ]]></r>", "<w><![CDATA[ cdata ]]>", XmlNodeType_CDATA },
2665 { "<r><?pi pidata ?></r>", "<w><?pi pidata ?>", XmlNodeType_ProcessingInstruction },
2666 { "<r><e1><e2 attr1=\'a\'/></e1></r>", "<w><e1><e2 attr1=\"a\" /></e1>", XmlNodeType_Element },
2667 { "<r><e1/></r>", "<w><e1 />", XmlNodeType_Element },
2668 { "<r></r>", "<w></w>", XmlNodeType_EndElement },
2669 };
2670 XmlNodeType node_type;
2671 IXmlWriter *writer;
2673 const WCHAR *name;
2674 IStream *stream;
2675 unsigned int i;
2676 HRESULT hr;
2677
2678 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
2679 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2680
2681 hr = IXmlWriter_WriteNode(writer, NULL, FALSE);
2682 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2683
2684 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
2685 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2686
2687 for (i = 0; i < ARRAY_SIZE(write_node_tests); ++i)
2688 {
2689 winetest_push_context("Test %s", debugstr_a(write_node_tests[i].input));
2690
2691 stream = writer_set_output(writer);
2692 reader_set_input(reader, write_node_tests[i].input);
2693
2694 /* Skip top level element. */
2695 hr = IXmlReader_Read(reader, &node_type);
2696 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2697
2698 hr = IXmlReader_Read(reader, &node_type);
2699 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2700 ok(node_type == write_node_tests[i].node_type, "Unexpected node type %d.\n", node_type);
2701
2702 /* Always write a root node to give a valid context for following nodes. */
2703 hr = IXmlWriter_WriteStartElement(writer, NULL, L"w", NULL);
2704 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2705 hr = IXmlWriter_WriteNode(writer, reader, FALSE);
2706 ok(SUCCEEDED(hr), "Failed to write a node, hr %#lx.\n", hr);
2707
2708 if (hr == S_OK)
2709 {
2710 hr = IXmlReader_GetNodeType(reader, &node_type);
2711 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2712 ok(node_type == XmlNodeType_EndElement, "Unexpected node type on return %d.\n", node_type);
2713 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2714 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2715 ok(!wcscmp(name, L"r"), "Unexpected node name %s.\n", debugstr_w(name));
2716 }
2717
2718 hr = IXmlWriter_Flush(writer);
2719 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2720
2721 CHECK_OUTPUT(stream, write_node_tests[i].output);
2722
2723 IStream_Release(stream);
2724
2726 }
2727
2728 /* Current node is an attribute. */
2729 reader_set_input(reader, "<a attr=\'b\' ></a>");
2730 hr = IXmlReader_Read(reader, &node_type);
2731 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2732 ok(node_type == XmlNodeType_Element, "Unexpected node type on return %d.\n", node_type);
2733 hr = IXmlReader_MoveToFirstAttribute(reader);
2734 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2735
2736 stream = writer_set_output(writer);
2737 hr = IXmlWriter_WriteNode(writer, reader, FALSE);
2738 ok(hr == S_OK, "Failed to write a node, hr %#lx.\n", hr);
2739 hr = IXmlReader_GetNodeType(reader, &node_type);
2740 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2741 ok(node_type == XmlNodeType_EndElement, "Unexpected node type on return %d.\n", node_type);
2742 hr = IXmlWriter_Flush(writer);
2743 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2744 CHECK_OUTPUT(stream, "");
2745 IStream_Release(stream);
2746
2747 /* Xml declaration node. */
2748 reader_set_input(reader, "<?xml version=\"1.0\" ?><a/>");
2749 hr = IXmlReader_Read(reader, &node_type);
2750 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2751 ok(node_type == XmlNodeType_XmlDeclaration, "Unexpected node type on return %d.\n", node_type);
2752
2753 stream = writer_set_output(writer);
2754 hr = IXmlWriter_WriteNode(writer, reader, FALSE);
2755 ok(hr == S_OK, "Failed to write a node, hr %#lx.\n", hr);
2756 hr = IXmlReader_GetNodeType(reader, &node_type);
2757 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2758 ok(node_type == XmlNodeType_Element, "Unexpected node type on return %d.\n", node_type);
2759 hr = IXmlWriter_Flush(writer);
2760 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2761 CHECK_OUTPUT(stream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
2762 IStream_Release(stream);
2763
2764 /* With standalone attribute. */
2765 reader_set_input(reader, "<?xml version=\"1.0\" standalone=\'yes\'?><a/>");
2766 hr = IXmlReader_Read(reader, &node_type);
2767 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2768 ok(node_type == XmlNodeType_XmlDeclaration, "Unexpected node type on return %d.\n", node_type);
2769
2770 stream = writer_set_output(writer);
2771 hr = IXmlWriter_WriteNode(writer, reader, FALSE);
2772 ok(hr == S_OK, "Failed to write a node, hr %#lx.\n", hr);
2773 hr = IXmlReader_GetNodeType(reader, &node_type);
2774 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2775 ok(node_type == XmlNodeType_Element, "Unexpected node type on return %d.\n", node_type);
2776 hr = IXmlWriter_Flush(writer);
2777 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2778 CHECK_OUTPUT(stream, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
2779 IStream_Release(stream);
2780
2781 /* Initial state. */
2782 reader_set_input(reader, "<?xml version=\"1.0\" ?><a><b/></a>");
2783 hr = IXmlReader_GetNodeType(reader, &node_type);
2784 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2785 ok(node_type == XmlNodeType_None, "Unexpected node type on return %d.\n", node_type);
2786 stream = writer_set_output(writer);
2787 hr = IXmlWriter_WriteNode(writer, reader, FALSE);
2788 ok(hr == S_FALSE, "Failed to write a node, hr %#lx.\n", hr);
2789 node_type = XmlNodeType_Element;
2790 hr = IXmlReader_GetNodeType(reader, &node_type);
2791 todo_wine
2792 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
2793 ok(node_type == XmlNodeType_None, "Unexpected node type on return %d.\n", node_type);
2794 hr = IXmlWriter_Flush(writer);
2795 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2796 CHECK_OUTPUT(stream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><a><b /></a>");
2797 IStream_Release(stream);
2798
2799 IXmlReader_Release(reader);
2800 IXmlWriter_Release(writer);
2801}
2802
2803static void test_WriteNodeShallow(void)
2804{
2805 static const struct
2806 {
2807 const char *input;
2808 const char *output;
2809 XmlNodeType node_type;
2810 }
2811 write_node_tests[] =
2812 {
2813 { "<r><!-- comment --></r>", "<w><!-- comment -->", XmlNodeType_Comment },
2814 { "<r>text</r>", "<w>text", XmlNodeType_Text },
2815 { "<r> </r>", "<w> ", XmlNodeType_Whitespace },
2816 { "<r><![CDATA[ cdata ]]></r>", "<w><![CDATA[ cdata ]]>", XmlNodeType_CDATA },
2817 { "<r><?pi pidata ?></r>", "<w><?pi pidata ?>", XmlNodeType_ProcessingInstruction },
2818 { "<r><e1><e2 attr1=\'a\'/></e1></r>", "<w><e1", XmlNodeType_Element },
2819 { "<r><e1/></r>", "<w><e1 />", XmlNodeType_Element },
2820 { "<r><e1 attr1=\'a\'/></r>", "<w><e1 attr1=\"a\" />", XmlNodeType_Element },
2821 { "<r><e1 attr1=\'a\'></e1></r>", "<w><e1 attr1=\"a\"", XmlNodeType_Element },
2822 { "<r></r>", "<w></w>", XmlNodeType_EndElement },
2823 };
2824 XmlNodeType node_type;
2825 IXmlWriter *writer;
2827 IStream *stream;
2828 unsigned int i;
2829 HRESULT hr;
2830
2831 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
2832 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2833
2834 hr = IXmlWriter_WriteNodeShallow(writer, NULL, FALSE);
2835 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2836
2837 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
2838 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2839
2840 for (i = 0; i < ARRAY_SIZE(write_node_tests); ++i)
2841 {
2842 winetest_push_context("Test %s", debugstr_a(write_node_tests[i].input));
2843
2844 stream = writer_set_output(writer);
2845 reader_set_input(reader, write_node_tests[i].input);
2846
2847 /* Skip top level element. */
2848 hr = IXmlReader_Read(reader, &node_type);
2849 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2850
2851 hr = IXmlReader_Read(reader, &node_type);
2852 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2853 ok(node_type == write_node_tests[i].node_type, "Unexpected node type %d.\n", node_type);
2854
2855 /* Always write a root node to give a valid context for following nodes. */
2856 hr = IXmlWriter_WriteStartElement(writer, NULL, L"w", NULL);
2857 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2858 hr = IXmlWriter_WriteNodeShallow(writer, reader, FALSE);
2859 ok(hr == S_OK, "Failed to write a node, hr %#lx.\n", hr);
2860
2861 hr = IXmlReader_GetNodeType(reader, &node_type);
2862 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2863 ok(node_type == write_node_tests[i].node_type, "Unexpected node type on return %d.\n", node_type);
2864
2865 hr = IXmlWriter_Flush(writer);
2866 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2867
2868 CHECK_OUTPUT(stream, write_node_tests[i].output);
2869
2870 IStream_Release(stream);
2871
2873 }
2874
2875 /* Current node is an attribute. */
2876 reader_set_input(reader, "<a attr=\'b\' ></a>");
2877 hr = IXmlReader_Read(reader, &node_type);
2878 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2879 ok(node_type == XmlNodeType_Element, "Unexpected node type on return %d.\n", node_type);
2880 hr = IXmlReader_MoveToFirstAttribute(reader);
2881 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2882
2883 stream = writer_set_output(writer);
2884 hr = IXmlWriter_WriteNodeShallow(writer, reader, FALSE);
2885 ok(hr == S_OK, "Failed to write a node, hr %#lx.\n", hr);
2886 hr = IXmlReader_GetNodeType(reader, &node_type);
2887 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2888 ok(node_type == XmlNodeType_Attribute, "Unexpected node type on return %d.\n", node_type);
2889 hr = IXmlWriter_Flush(writer);
2890 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2891 CHECK_OUTPUT(stream, "");
2892 IStream_Release(stream);
2893
2894 /* Xml declaration node. */
2895 reader_set_input(reader, "<?xml version=\"1.0\" ?><a/>");
2896 hr = IXmlReader_Read(reader, &node_type);
2897 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2898 ok(node_type == XmlNodeType_XmlDeclaration, "Unexpected node type on return %d.\n", node_type);
2899
2900 stream = writer_set_output(writer);
2901 hr = IXmlWriter_WriteNodeShallow(writer, reader, FALSE);
2902 ok(hr == S_OK, "Failed to write a node, hr %#lx.\n", hr);
2903 hr = IXmlReader_GetNodeType(reader, &node_type);
2904 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2905 ok(node_type == XmlNodeType_Attribute, "Unexpected node type on return %d.\n", node_type);
2906 hr = IXmlWriter_Flush(writer);
2907 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2908 CHECK_OUTPUT(stream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
2909 IStream_Release(stream);
2910
2911 /* With standalone attribute. */
2912 reader_set_input(reader, "<?xml version=\"1.0\" standalone=\'yes\'?><a/>");
2913 hr = IXmlReader_Read(reader, &node_type);
2914 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2915 ok(node_type == XmlNodeType_XmlDeclaration, "Unexpected node type on return %d.\n", node_type);
2916
2917 stream = writer_set_output(writer);
2918 hr = IXmlWriter_WriteNodeShallow(writer, reader, FALSE);
2919 ok(hr == S_OK, "Failed to write a node, hr %#lx.\n", hr);
2920 hr = IXmlReader_GetNodeType(reader, &node_type);
2921 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2922 ok(node_type == XmlNodeType_Attribute, "Unexpected node type on return %d.\n", node_type);
2923 hr = IXmlWriter_Flush(writer);
2924 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2925 CHECK_OUTPUT(stream, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
2926 IStream_Release(stream);
2927
2928 /* Initial state. */
2929 reader_set_input(reader, "<?xml version=\"1.0\" ?><a><b/></a>");
2930 hr = IXmlReader_GetNodeType(reader, &node_type);
2931 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2932 ok(node_type == XmlNodeType_None, "Unexpected node type on return %d.\n", node_type);
2933 stream = writer_set_output(writer);
2934 hr = IXmlWriter_WriteNodeShallow(writer, reader, FALSE);
2935 ok(hr == S_OK, "Failed to write a node, hr %#lx.\n", hr);
2936 node_type = XmlNodeType_Element;
2937 hr = IXmlReader_GetNodeType(reader, &node_type);
2938 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2939 ok(node_type == XmlNodeType_None, "Unexpected node type on return %d.\n", node_type);
2940 hr = IXmlWriter_Flush(writer);
2941 ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
2942 CHECK_OUTPUT(stream, "");
2943 IStream_Release(stream);
2944
2945 IXmlReader_Release(reader);
2946 IXmlWriter_Release(writer);
2947}
2948
2950{
2958 test_flush();
2960 test_bom();
2964 test_WriteRaw();
2979}
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define ARRAY_SIZE(A)
Definition: main.h:20
const GUID IID_IUnknown
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI GetHGlobalFromStream(IStream *stream, HGLOBAL *phglobal)
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL delete_on_release, IStream **stream)
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
_ACRTIMP int __cdecl strncmp(const char *, const char *, size_t)
Definition: string.c:3335
HRESULT WINAPI CreateXmlReader(REFIID riid, void **obj, IMalloc *imalloc)
Definition: reader.c:3616
HRESULT WINAPI CreateXmlWriter(REFIID riid, void **obj, IMalloc *imalloc)
Definition: writer.c:2154
HRESULT WINAPI CreateXmlWriterOutputWithEncodingCodePage(IUnknown *stream, IMalloc *imalloc, UINT codepage, IXmlWriterOutput **out)
Definition: writer.c:2243
HRESULT WINAPI CreateXmlWriterOutputWithEncodingName(IUnknown *stream, IMalloc *imalloc, const WCHAR *encoding, IXmlWriterOutput **out)
Definition: writer.c:2222
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
#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
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
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
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
static ERESOURCE GlobalLock
Definition: sys_arch.c:8
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define todo_wine_if(is_todo)
Definition: minitest.h:81
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:539
#define todo_wine
Definition: minitest.h:80
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
BOOL todo
Definition: filedlg.c:313
BOOL expected
Definition: store.c:2000
const WCHAR * uri
Definition: sec_mgr.c:1564
ssize_t pread(int fd, void *buf, size_t count, off_t offset)
static void test_writer_state(void)
Definition: writer.c:1433
static void test_writeroutput(void)
Definition: writer.c:479
static HRESULT WINAPI teststream_QueryInterface(ISequentialStream *iface, REFIID riid, void **obj)
Definition: writer.c:280
static void _reader_set_input(unsigned line, IXmlReader *reader, const char *xml)
Definition: writer.c:62
static void test_WriteStartElement(void)
Definition: writer.c:888
static void test_WriteRawChars(void)
Definition: writer.c:1923
static void check_output_raw(IStream *stream, const void *expected, SIZE_T size, int line)
Definition: writer.c:84
static void test_WriteAttributes(void)
Definition: writer.c:2582
static void test_indentation(void)
Definition: writer.c:1529
static HRESULT WINAPI teststream_Write(ISequentialStream *iface, const void *pv, ULONG cb, ULONG *written)
Definition: writer.c:309
static void test_writestartdocument(void)
Definition: writer.c:583
static void test_writeenddocument(void)
Definition: writer.c:1206
static void test_WriteProcessingInstruction(void)
Definition: writer.c:2558
static ULONG WINAPI teststream_AddRef(ISequentialStream *iface)
Definition: writer.c:292
static const IUnknownVtbl testoutputvtbl
Definition: writer.c:272
static IUnknown testoutput
Definition: writer.c:278
#define reader_set_input(a, b)
Definition: writer.c:61
static void _expect_ref(IUnknown *obj, ULONG ref, int line)
Definition: writer.c:76
static void check_output(IStream *stream, const char *expected, BOOL todo, int line)
Definition: writer.c:105
static void test_WriteComment(void)
Definition: writer.c:1263
static void test_WriteSurrogateCharEntity(void)
Definition: writer.c:2035
static void test_omitxmldeclaration(void)
Definition: writer.c:706
static void test_invalid_output_encoding(IXmlWriter *writer, IUnknown *output)
Definition: writer.c:379
#define CHECK_OUTPUT_TODO(stream, expected)
Definition: writer.c:130
static void test_WriteRaw(void)
Definition: writer.c:1353
static ULONG WINAPI testoutput_Release(IUnknown *iface)
Definition: writer.c:267
static const ISequentialStreamVtbl teststreamvtbl
Definition: writer.c:316
static void test_bom(void)
Definition: writer.c:779
static IStream * writer_set_output(IXmlWriter *writer)
Definition: writer.c:236
static IStream * create_stream_on_data(const void *data, unsigned int size)
Definition: writer.c:40
static void test_WriteNodeShallow(void)
Definition: writer.c:2803
static void test_flush(void)
Definition: writer.c:676
static void test_WriteDocType(void)
Definition: writer.c:2442
static void test_WriteString(void)
Definition: writer.c:2089
#define CHECK_OUTPUT_RAW(stream, expected, size)
Definition: writer.c:131
static ULONG WINAPI teststream_Release(ISequentialStream *iface)
Definition: writer.c:297
static void test_WriteElementString(void)
Definition: writer.c:1032
static HRESULT WINAPI teststream_Read(ISequentialStream *iface, void *pv, ULONG cb, ULONG *pread)
Definition: writer.c:302
#define EXPECT_REF(obj, ref)
Definition: writer.c:75
static void test_WriteNode(void)
Definition: writer.c:2651
#define CHECK_OUTPUT(stream, expected)
Definition: writer.c:129
static void test_WriteCData(void)
Definition: writer.c:1306
static ULONG WINAPI testoutput_AddRef(IUnknown *iface)
Definition: writer.c:262
static void test_WriteFullEndElement(void)
Definition: writer.c:1793
static ULONG g_write_len
Definition: writer.c:308
static void check_writer_state(IXmlWriter *writer, HRESULT exp_hr)
Definition: writer.c:142
static void test_WriteWhitespace(void)
Definition: writer.c:2530
static void test_WriteAttributeString(void)
Definition: writer.c:1598
static void writer_set_property(IXmlWriter *writer, XmlWriterProperty property)
Definition: writer.c:133
static void test_WriteChars(void)
Definition: writer.c:2318
static void test_WriteCharEntity(void)
Definition: writer.c:1884
static HRESULT WINAPI testoutput_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
Definition: writer.c:250
static void test_WriteEndElement(void)
Definition: writer.c:1174
static void test_writer_create(void)
Definition: writer.c:327
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
short WCHAR
Definition: pedump.c:58
#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 IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define wine_dbgstr_wn
Definition: testlist.c:2
#define CP_UTF8
Definition: nls.h:20
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
Definition: parser.c:49
Definition: name.c:39
Definition: reader.h:84
Definition: send.c:48
Definition: parse.h:23
Character const *const prefix
Definition: tempnam.cpp:195
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:64
#define GHND
Definition: winbase.h:321
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_UNEXPECTED
Definition: winerror.h:3528
@ MX_E_ENCODING
Definition: xmllite.idl:142
@ WR_E_XMLPREFIXDECLARATION
Definition: xmllite.idl:214
@ WR_E_INVALIDXMLSPACE
Definition: xmllite.idl:218
@ WR_E_NONWHITESPACE
Definition: xmllite.idl:209
@ WR_E_DUPLICATEATTRIBUTE
Definition: xmllite.idl:212
@ WR_E_NSPREFIXDECLARED
Definition: xmllite.idl:210
@ WC_E_NAMECHARACTER
Definition: xmllite.idl:157
@ WR_E_XMLNSURIDECLARATION
Definition: xmllite.idl:216
@ WC_E_XMLCHARACTER
Definition: xmllite.idl:156
@ WR_E_INVALIDSURROGATEPAIR
Definition: xmllite.idl:220
@ WR_E_XMLNSPREFIXDECLARATION
Definition: xmllite.idl:213
@ WR_E_NSPREFIXWITHEMPTYNSURI
Definition: xmllite.idl:211
@ WC_E_PUBLICID
Definition: xmllite.idl:179
@ WR_E_INVALIDACTION
Definition: xmllite.idl:219
XmlWriterProperty
Definition: xmllite.idl:246
@ XmlWriterProperty_ConformanceLevel
Definition: xmllite.idl:251
@ XmlWriterProperty_OmitXmlDeclaration
Definition: xmllite.idl:250
@ XmlWriterProperty_ByteOrderMark
Definition: xmllite.idl:249
@ XmlWriterProperty_Indent
Definition: xmllite.idl:248
@ XmlConformanceLevel_Document
Definition: xmllite.idl:111
@ XmlConformanceLevel_Auto
Definition: xmllite.idl:109
XmlNodeType
Definition: xmllite.idl:23
@ XmlNodeType_Whitespace
Definition: xmllite.idl:32
@ XmlNodeType_EndElement
Definition: xmllite.idl:33
@ XmlNodeType_ProcessingInstruction
Definition: xmllite.idl:29
@ XmlNodeType_Attribute
Definition: xmllite.idl:26
@ XmlNodeType_CDATA
Definition: xmllite.idl:28
@ XmlNodeType_XmlDeclaration
Definition: xmllite.idl:34
@ XmlNodeType_Comment
Definition: xmllite.idl:30
@ XmlNodeType_None
Definition: xmllite.idl:24
@ XmlNodeType_Element
Definition: xmllite.idl:25
@ XmlNodeType_Text
Definition: xmllite.idl:27
@ XmlStandalone_Omit
Definition: xmllite.idl:239
@ XmlStandalone_Yes
Definition: xmllite.idl:240