ReactOS 0.4.15-dev-5865-g640e228
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/heap.h"
36#include "wine/test.h"
37
38#include "initguid.h"
39DEFINE_GUID(IID_IXmlWriterOutput, 0xc1131708, 0x0f59, 0x477f, 0x93, 0x59, 0x7d, 0x33, 0x24, 0x51, 0xbc, 0x1a);
40
41static const WCHAR aW[] = {'a',0};
42
43#define EXPECT_REF(obj, ref) _expect_ref((IUnknown *)obj, ref, __LINE__)
44static void _expect_ref(IUnknown *obj, ULONG ref, int line)
45{
46 ULONG refcount;
47 IUnknown_AddRef(obj);
48 refcount = IUnknown_Release(obj);
49 ok_(__FILE__, line)(refcount == ref, "expected refcount %d, got %d\n", ref, refcount);
50}
51
52static void check_output_raw(IStream *stream, const void *expected, SIZE_T size, int line)
53{
54 SIZE_T content_size;
55 HGLOBAL hglobal;
56 HRESULT hr;
57 WCHAR *ptr;
58
59 hr = GetHGlobalFromStream(stream, &hglobal);
60 ok_(__FILE__, line)(hr == S_OK, "Failed to get the stream handle, hr %#x.\n", hr);
61
62 content_size = GlobalSize(hglobal);
63 ok_(__FILE__, line)(size == content_size, "Unexpected test output size %ld.\n", content_size);
64 ptr = GlobalLock(hglobal);
65 if (size <= content_size)
66 ok_(__FILE__, line)(!memcmp(expected, ptr, size), "Unexpected output content.\n");
67 if (size != content_size && *ptr == 0xfeff)
68 ok_(__FILE__, line)(0, "Content: %s.\n", wine_dbgstr_wn(ptr, content_size / sizeof(WCHAR)));
69
70 GlobalUnlock(hglobal);
71}
72
73static void check_output(IStream *stream, const char *expected, BOOL todo, int line)
74{
75 int len = strlen(expected), size;
76 HGLOBAL hglobal;
77 HRESULT hr;
78 char *ptr;
79
80 hr = GetHGlobalFromStream(stream, &hglobal);
81 ok_(__FILE__, line)(hr == S_OK, "got 0x%08x\n", hr);
82
83 size = GlobalSize(hglobal);
84 ptr = GlobalLock(hglobal);
86 {
87 if (size != len)
88 {
89 ok_(__FILE__, line)(0, "data size mismatch, expected %u, got %u\n", len, size);
90 ok_(__FILE__, line)(0, "got |%s|, expected |%s|\n", ptr, expected);
91 }
92 else
93 ok_(__FILE__, line)(!strncmp(ptr, expected, len), "got |%s|, expected |%s|\n", ptr, expected);
94 }
95 GlobalUnlock(hglobal);
96}
97#define CHECK_OUTPUT(stream, expected) check_output(stream, expected, FALSE, __LINE__)
98#define CHECK_OUTPUT_TODO(stream, expected) check_output(stream, expected, TRUE, __LINE__)
99#define CHECK_OUTPUT_RAW(stream, expected, size) check_output_raw(stream, expected, size, __LINE__)
100
101static WCHAR *strdupAtoW(const char *str)
102{
103 WCHAR *ret = NULL;
104 DWORD len;
105
106 if (!str) return ret;
107 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
108 ret = heap_alloc(len * sizeof(WCHAR));
109 if (ret)
111 return ret;
112}
113
115{
116 HRESULT hr;
117
118 hr = IXmlWriter_SetProperty(writer, property, TRUE);
119 ok(hr == S_OK, "Failed to set writer property, hr %#x.\n", hr);
120}
121
122/* used to test all Write* methods for consistent error state */
123static void check_writer_state(IXmlWriter *writer, HRESULT exp_hr)
124{
125 static const WCHAR aW[] = {'a',0};
126 HRESULT hr;
127
128 /* FIXME: add WriteAttributes */
129
130 hr = IXmlWriter_WriteAttributeString(writer, NULL, aW, NULL, aW);
131 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
132
133 hr = IXmlWriter_WriteCData(writer, aW);
134 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
135
136 hr = IXmlWriter_WriteCharEntity(writer, aW[0]);
137 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
138
139 hr = IXmlWriter_WriteChars(writer, aW, 1);
140 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
141
142 hr = IXmlWriter_WriteComment(writer, aW);
143 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
144
145 hr = IXmlWriter_WriteDocType(writer, aW, NULL, NULL, NULL);
146 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
147
148 hr = IXmlWriter_WriteElementString(writer, NULL, aW, NULL, aW);
149 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
150
151 hr = IXmlWriter_WriteEndDocument(writer);
152 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
153
154 hr = IXmlWriter_WriteEndElement(writer);
155 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
156
157 hr = IXmlWriter_WriteEntityRef(writer, aW);
158 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
159
160 hr = IXmlWriter_WriteFullEndElement(writer);
161 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
162
163 hr = IXmlWriter_WriteName(writer, aW);
164 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
165
166 hr = IXmlWriter_WriteNmToken(writer, aW);
167 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
168
169 /* FIXME: add WriteNode */
170 /* FIXME: add WriteNodeShallow */
171
172 hr = IXmlWriter_WriteProcessingInstruction(writer, aW, aW);
173 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
174
175 hr = IXmlWriter_WriteQualifiedName(writer, aW, NULL);
176 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
177
178 hr = IXmlWriter_WriteRaw(writer, aW);
179 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
180
181 hr = IXmlWriter_WriteRawChars(writer, aW, 1);
182 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
183
184 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
185 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
186
187 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
188 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
189
190 hr = IXmlWriter_WriteString(writer, aW);
191 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
192
193 /* FIXME: add WriteSurrogateCharEntity */
194 /* FIXME: add WriteWhitespace */
195}
196
198{
200 HRESULT hr;
201
203 ok(hr == S_OK, "got 0x%08x\n", hr);
204
205 hr = IXmlWriter_SetOutput(writer, (IUnknown*)stream);
206 ok(hr == S_OK, "got 0x%08x\n", hr);
207
208 return stream;
209}
210
212{
214 *obj = iface;
215 return S_OK;
216 }
217 else {
218 ok(0, "unknown riid=%s\n", wine_dbgstr_guid(riid));
219 return E_NOINTERFACE;
220 }
221}
222
224{
225 return 2;
226}
227
229{
230 return 1;
231}
232
233static const IUnknownVtbl testoutputvtbl = {
237};
238
240
242{
243 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_ISequentialStream))
244 {
245 *obj = iface;
246 return S_OK;
247 }
248
249 *obj = NULL;
250 return E_NOINTERFACE;
251}
252
254{
255 return 2;
256}
257
259{
260 return 1;
261}
262
264{
265 ok(0, "unexpected call\n");
266 return E_NOTIMPL;
267}
268
270static HRESULT WINAPI teststream_Write(ISequentialStream *iface, const void *pv, ULONG cb, ULONG *written)
271{
272 g_write_len = cb;
273 *written = cb;
274 return S_OK;
275}
276
277static const ISequentialStreamVtbl teststreamvtbl =
278{
284};
285
287
288static void test_writer_create(void)
289{
290 HRESULT hr;
291 IXmlWriter *writer;
293 IUnknown *unk;
294
295 /* crashes native */
296 if (0)
297 {
298 CreateXmlWriter(&IID_IXmlWriter, NULL, NULL);
299 CreateXmlWriter(NULL, (void**)&writer, NULL);
300 }
301
302 hr = CreateXmlWriter(&IID_IStream, (void **)&unk, NULL);
303 ok(hr == E_NOINTERFACE, "got %08x\n", hr);
304
305 hr = CreateXmlWriter(&IID_IUnknown, (void **)&unk, NULL);
306 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
307 hr = IUnknown_QueryInterface(unk, &IID_IXmlWriter, (void **)&writer);
308 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
309 ok(unk == (IUnknown *)writer, "unexpected interface pointer\n");
310 IUnknown_Release(unk);
311 IXmlWriter_Release(writer);
312
313 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
314 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
315
316 /* check default properties values */
317 value = 0;
318 hr = IXmlWriter_GetProperty(writer, XmlWriterProperty_ByteOrderMark, &value);
319 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
320 ok(value == TRUE, "got %ld\n", value);
321
322 value = TRUE;
323 hr = IXmlWriter_GetProperty(writer, XmlWriterProperty_Indent, &value);
324 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
325 ok(value == FALSE, "got %ld\n", value);
326
327 value = TRUE;
328 hr = IXmlWriter_GetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, &value);
329 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
330 ok(value == FALSE, "got %ld\n", value);
331
333 hr = IXmlWriter_GetProperty(writer, XmlWriterProperty_ConformanceLevel, &value);
334 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
335 ok(value == XmlConformanceLevel_Document, "got %ld\n", value);
336
337 IXmlWriter_Release(writer);
338}
339
341{
342 HRESULT hr;
343
344 hr = IXmlWriter_SetOutput(writer, output);
345 ok(hr == S_OK, "Failed to set output, hr %#x.\n", hr);
346
347 /* TODO: WriteAttributes */
348
349 hr = IXmlWriter_WriteAttributeString(writer, NULL, aW, NULL, aW);
350 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
351
352 hr = IXmlWriter_WriteCData(writer, aW);
353 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
354
355 hr = IXmlWriter_WriteCharEntity(writer, 0x100);
356 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
357
358 hr = IXmlWriter_WriteChars(writer, aW, 1);
359 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
360
361 hr = IXmlWriter_WriteComment(writer, aW);
362 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
363
364 hr = IXmlWriter_WriteDocType(writer, aW, NULL, NULL, NULL);
365 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
366
367 hr = IXmlWriter_WriteElementString(writer, NULL, aW, NULL, NULL);
368 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
369
370 hr = IXmlWriter_WriteEndDocument(writer);
371 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
372
373 hr = IXmlWriter_WriteEndElement(writer);
374 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
375
376 hr = IXmlWriter_WriteEntityRef(writer, aW);
377 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
378
379 hr = IXmlWriter_WriteFullEndElement(writer);
380 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
381
382 hr = IXmlWriter_WriteName(writer, aW);
383 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
384
385 hr = IXmlWriter_WriteNmToken(writer, aW);
386 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
387
388 /* TODO: WriteNode */
389 /* TODO: WriteNodeShallow */
390
391 hr = IXmlWriter_WriteProcessingInstruction(writer, aW, aW);
392 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
393
394 hr = IXmlWriter_WriteQualifiedName(writer, aW, NULL);
395 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
396
397 hr = IXmlWriter_WriteRaw(writer, aW);
398 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
399
400 hr = IXmlWriter_WriteRawChars(writer, aW, 1);
401 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
402
403 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
404 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
405
406 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
407 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
408
409 hr = IXmlWriter_WriteString(writer, aW);
410 ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
411
412 /* TODO: WriteSurrogateCharEntity */
413 /* ًُُTODO: WriteWhitespace */
414
415 hr = IXmlWriter_Flush(writer);
416 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
417}
418
419static void test_writeroutput(void)
420{
421 static const WCHAR utf16W[] = {'u','t','f','-','1','6',0};
422 static const WCHAR usasciiW[] = {'u','s','-','a','s','c','i','i',0};
423 static const WCHAR dummyW[] = {'d','u','m','m','y',0};
424 static const WCHAR utf16_outputW[] = {0xfeff,'<','a'};
425 IXmlWriterOutput *output;
426 IXmlWriter *writer;
428 IUnknown *unk;
429 HRESULT hr;
430
431 output = NULL;
433 ok(hr == S_OK, "got %08x\n", hr);
434 EXPECT_REF(output, 1);
435 IUnknown_Release(output);
436
438 ok(hr == S_OK, "got %08x\n", hr);
439 unk = NULL;
440 hr = IUnknown_QueryInterface(output, &IID_IXmlWriterOutput, (void**)&unk);
441 ok(hr == S_OK, "got %08x\n", hr);
443 ok(unk != NULL && unk != output, "got %p, output %p\n", unk, output);
444 EXPECT_REF(output, 2);
445 /* releasing 'unk' crashes on native */
446 IUnknown_Release(output);
447 EXPECT_REF(output, 1);
448 IUnknown_Release(output);
449
450 output = NULL;
452 ok(hr == S_OK, "got %08x\n", hr);
453 IUnknown_Release(output);
454
456 ok(hr == S_OK, "got %08x\n", hr);
457 unk = NULL;
458 hr = IUnknown_QueryInterface(output, &IID_IXmlWriterOutput, (void**)&unk);
459 ok(hr == S_OK, "got %08x\n", hr);
460 ok(unk != NULL, "got %p\n", unk);
461 /* releasing 'unk' crashes on native */
462 IUnknown_Release(output);
463 IUnknown_Release(output);
464
465 /* create with us-ascii */
466 output = NULL;
468 ok(hr == S_OK, "got %08x\n", hr);
469 IUnknown_Release(output);
470
471 /* Output with codepage 1200. */
472 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
473 ok(hr == S_OK, "Failed to create writer, hr %#x.\n", hr);
474
476 ok(hr == S_OK, "Failed to create stream, hr %#x.\n", hr);
477
479 ok(hr == S_OK, "Failed to create writer output, hr %#x.\n", hr);
480
481 hr = IXmlWriter_SetOutput(writer, output);
482 ok(hr == S_OK, "Failed to set writer output, hr %#x.\n", hr);
483
484 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
485 ok(hr == S_OK, "Write failed, hr %#x.\n", hr);
486
487 hr = IXmlWriter_Flush(writer);
488 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
489
490 CHECK_OUTPUT_RAW(stream, utf16_outputW, sizeof(utf16_outputW));
491
492 IStream_Release(stream);
493 IUnknown_Release(output);
494
495 /* Create output with meaningless code page value. */
497 ok(hr == S_OK, "Failed to create stream, hr %#x.\n", hr);
498
499 output = NULL;
501 ok(hr == S_OK, "Failed to create writer output, hr %#x.\n", hr);
502
503 test_invalid_output_encoding(writer, output);
504 CHECK_OUTPUT(stream, "");
505
506 IStream_Release(stream);
507 IUnknown_Release(output);
508
509 /* Same, with invalid encoding name. */
511 ok(hr == S_OK, "got 0x%08x\n", hr);
512
513 output = NULL;
515 ok(hr == S_OK, "got %08x\n", hr);
516
517 test_invalid_output_encoding(writer, output);
518 CHECK_OUTPUT(stream, "");
519
520 IStream_Release(stream);
521 IUnknown_Release(output);
522
523 IXmlWriter_Release(writer);
524}
525
526static void test_writestartdocument(void)
527{
528 static const char fullprolog[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
529 static const char *prologversion2 = "<?xml version=\"1.0\" encoding=\"uS-asCii\"?>";
530 static const char prologversion[] = "<?xml version=\"1.0\"?>";
531 static const WCHAR versionW[] = {'v','e','r','s','i','o','n','=','"','1','.','0','"',0};
532 static const WCHAR usasciiW[] = {'u','S','-','a','s','C','i','i',0};
533 static const WCHAR xmlW[] = {'x','m','l',0};
534 IXmlWriterOutput *output;
535 IXmlWriter *writer;
537 HRESULT hr;
538
539 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
540 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
541
542 /* output not set */
543 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
544 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
545
546 hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
547 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
548
549 hr = IXmlWriter_Flush(writer);
550 ok(hr == S_OK, "got 0x%08x\n", hr);
551
552 stream = writer_set_output(writer);
553
554 /* nothing written yet */
555 hr = IXmlWriter_Flush(writer);
556 ok(hr == S_OK, "got 0x%08x\n", hr);
557
558 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
559 ok(hr == S_OK, "got 0x%08x\n", hr);
560
561 hr = IXmlWriter_Flush(writer);
562 ok(hr == S_OK, "got 0x%08x\n", hr);
563
564 CHECK_OUTPUT(stream, fullprolog);
565
566 /* one more time */
567 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
568 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
569 IStream_Release(stream);
570
571 /* now add PI manually, and try to start a document */
572 stream = writer_set_output(writer);
573
574 hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
575 ok(hr == S_OK, "got 0x%08x\n", hr);
576
577 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
578 ok(hr == S_OK, "got 0x%08x\n", hr);
579
580 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
581 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
582
583 /* another attempt to add 'xml' PI */
584 hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
585 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
586
587 hr = IXmlWriter_Flush(writer);
588 ok(hr == S_OK, "got 0x%08x\n", hr);
589
590 CHECK_OUTPUT(stream, prologversion);
591
592 IStream_Release(stream);
593 IXmlWriter_Release(writer);
594
595 /* create with us-ascii */
597 ok(hr == S_OK, "got 0x%08x\n", hr);
598
599 output = NULL;
601 ok(hr == S_OK, "got %08x\n", hr);
602
603 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
604 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
605
606 hr = IXmlWriter_SetOutput(writer, output);
607 ok(hr == S_OK, "got %08x\n", hr);
608
609 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
610 ok(hr == S_OK, "got 0x%08x\n", hr);
611
612 hr = IXmlWriter_Flush(writer);
613 ok(hr == S_OK, "got 0x%08x\n", hr);
614
615 CHECK_OUTPUT(stream, prologversion2);
616
617 IStream_Release(stream);
618 IXmlWriter_Release(writer);
619 IUnknown_Release(output);
620}
621
622static void test_flush(void)
623{
624 IXmlWriter *writer;
625 HRESULT hr;
626
627 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
628 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
629
630 hr = IXmlWriter_SetOutput(writer, (IUnknown*)&teststream);
631 ok(hr == S_OK, "got 0x%08x\n", hr);
632
633 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
634 ok(hr == S_OK, "got 0x%08x\n", hr);
635
636 g_write_len = 0;
637 hr = IXmlWriter_Flush(writer);
638 ok(hr == S_OK, "got 0x%08x\n", hr);
639 ok(g_write_len > 0, "got %d\n", g_write_len);
640
641 g_write_len = 1;
642 hr = IXmlWriter_Flush(writer);
643 ok(hr == S_OK, "got 0x%08x\n", hr);
644 ok(g_write_len == 0, "got %d\n", g_write_len);
645
646 /* Release() flushes too */
647 g_write_len = 1;
648 IXmlWriter_Release(writer);
649 ok(g_write_len == 0, "got %d\n", g_write_len);
650}
651
652static void test_omitxmldeclaration(void)
653{
654 static const char prologversion[] = "<?xml version=\"1.0\"?>";
655 static const WCHAR versionW[] = {'v','e','r','s','i','o','n','=','"','1','.','0','"',0};
656 static const WCHAR xmlW[] = {'x','m','l',0};
657 IXmlWriter *writer;
658 HGLOBAL hglobal;
660 HRESULT hr;
661 char *ptr;
662
663 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
664 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
665
666 stream = writer_set_output(writer);
667
669
670 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
671 ok(hr == S_OK, "got 0x%08x\n", hr);
672
673 hr = IXmlWriter_Flush(writer);
674 ok(hr == S_OK, "got 0x%08x\n", hr);
675
676 hr = GetHGlobalFromStream(stream, &hglobal);
677 ok(hr == S_OK, "got 0x%08x\n", hr);
678
679 ptr = GlobalLock(hglobal);
680 ok(!ptr, "got %p\n", ptr);
681 GlobalUnlock(hglobal);
682
683 /* one more time */
684 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
685 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
686
687 IStream_Release(stream);
688
689 /* now add PI manually, and try to start a document */
690 stream = writer_set_output(writer);
691
692 hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
693 ok(hr == S_OK, "got 0x%08x\n", hr);
694
695 hr = IXmlWriter_Flush(writer);
696 ok(hr == S_OK, "got 0x%08x\n", hr);
697
698 CHECK_OUTPUT(stream, prologversion);
699
700 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
701 ok(hr == S_OK, "got 0x%08x\n", hr);
702
703 hr = IXmlWriter_Flush(writer);
704 ok(hr == S_OK, "got 0x%08x\n", hr);
705
706 CHECK_OUTPUT(stream, prologversion);
707
708 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
709 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
710
711 hr = IXmlWriter_Flush(writer);
712 ok(hr == S_OK, "got 0x%08x\n", hr);
713
714 CHECK_OUTPUT(stream, prologversion);
715
716 /* another attempt to add 'xml' PI */
717 hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
718 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
719
720 hr = IXmlWriter_Flush(writer);
721 ok(hr == S_OK, "got 0x%08x\n", hr);
722
723 IStream_Release(stream);
724 IXmlWriter_Release(writer);
725}
726
727static void test_bom(void)
728{
729 static const WCHAR piW[] = {0xfeff,'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"','?','>'};
730 static const WCHAR aopenW[] = {0xfeff,'<','a'};
731 static const WCHAR afullW[] = {0xfeff,'<','a',' ','/','>'};
732 static const WCHAR versionW[] = {'v','e','r','s','i','o','n','=','"','1','.','0','"',0};
733 static const WCHAR utf16W[] = {'u','t','f','-','1','6',0};
734 static const WCHAR xmlW[] = {'x','m','l',0};
735 static const WCHAR bomW[] = {0xfeff};
736 IXmlWriterOutput *output;
737 IXmlWriter *writer;
739 HGLOBAL hglobal;
740 HRESULT hr;
741
743 ok(hr == S_OK, "got 0x%08x\n", hr);
744
746 ok(hr == S_OK, "got %08x\n", hr);
747
748 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
749 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
750
752
753 hr = IXmlWriter_SetOutput(writer, output);
754 ok(hr == S_OK, "got 0x%08x\n", hr);
755
756 /* BOM is on by default */
757 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
758 ok(hr == S_OK, "got 0x%08x\n", hr);
759
760 hr = IXmlWriter_Flush(writer);
761 ok(hr == S_OK, "got 0x%08x\n", hr);
762
763 CHECK_OUTPUT_RAW(stream, bomW, sizeof(bomW));
764
765 IStream_Release(stream);
766 IUnknown_Release(output);
767
768 /* start with PI */
770 ok(hr == S_OK, "got 0x%08x\n", hr);
771
773 ok(hr == S_OK, "got %08x\n", hr);
774
775 hr = IXmlWriter_SetOutput(writer, output);
776 ok(hr == S_OK, "got 0x%08x\n", hr);
777
778 hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
779 ok(hr == S_OK, "got 0x%08x\n", hr);
780
781 hr = IXmlWriter_Flush(writer);
782 ok(hr == S_OK, "got 0x%08x\n", hr);
783
784 CHECK_OUTPUT_RAW(stream, piW, sizeof(piW));
785
786 IUnknown_Release(output);
787 IStream_Release(stream);
788
789 /* start with element */
791 ok(hr == S_OK, "got 0x%08x\n", hr);
792
794 ok(hr == S_OK, "got %08x\n", hr);
795
796 hr = IXmlWriter_SetOutput(writer, output);
797 ok(hr == S_OK, "got 0x%08x\n", hr);
798
799 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
800 ok(hr == S_OK, "got 0x%08x\n", hr);
801
802 hr = IXmlWriter_Flush(writer);
803 ok(hr == S_OK, "got 0x%08x\n", hr);
804
805 CHECK_OUTPUT_RAW(stream, aopenW, sizeof(aopenW));
806
807 IUnknown_Release(output);
808 IStream_Release(stream);
809
810 /* WriteElementString */
812 ok(hr == S_OK, "got 0x%08x\n", hr);
813
815 ok(hr == S_OK, "got %08x\n", hr);
816
817 hr = IXmlWriter_SetOutput(writer, output);
818 ok(hr == S_OK, "got 0x%08x\n", hr);
819
821
822 hr = IXmlWriter_WriteElementString(writer, NULL, aW, NULL, NULL);
823 ok(hr == S_OK, "got 0x%08x\n", hr);
824
825 hr = IXmlWriter_Flush(writer);
826 ok(hr == S_OK, "got 0x%08x\n", hr);
827
828 hr = GetHGlobalFromStream(stream, &hglobal);
829 ok(hr == S_OK, "got 0x%08x\n", hr);
830
831 CHECK_OUTPUT_RAW(stream, afullW, sizeof(afullW));
832
833 IUnknown_Release(output);
834 IStream_Release(stream);
835
836 IXmlWriter_Release(writer);
837}
838
839static HRESULT write_start_element(IXmlWriter *writer, const char *prefix, const char *local,
840 const char *uri)
841{
842 WCHAR *prefixW, *localW, *uriW;
843 HRESULT hr;
844
845 prefixW = strdupAtoW(prefix);
846 localW = strdupAtoW(local);
847 uriW = strdupAtoW(uri);
848
849 hr = IXmlWriter_WriteStartElement(writer, prefixW, localW, uriW);
850
851 heap_free(prefixW);
852 heap_free(localW);
853 heap_free(uriW);
854
855 return hr;
856}
857
858static HRESULT write_element_string(IXmlWriter *writer, const char *prefix, const char *local,
859 const char *uri, const char *value)
860{
861 WCHAR *prefixW, *localW, *uriW, *valueW;
862 HRESULT hr;
863
864 prefixW = strdupAtoW(prefix);
865 localW = strdupAtoW(local);
866 uriW = strdupAtoW(uri);
868
869 hr = IXmlWriter_WriteElementString(writer, prefixW, localW, uriW, valueW);
870
871 heap_free(prefixW);
872 heap_free(localW);
873 heap_free(uriW);
875
876 return hr;
877}
878
879static HRESULT write_string(IXmlWriter *writer, const char *str)
880{
881 WCHAR *strW;
882 HRESULT hr;
883
885
886 hr = IXmlWriter_WriteString(writer, strW);
887
889
890 return hr;
891}
892
893static void test_WriteStartElement(void)
894{
895 static const struct
896 {
897 const char *prefix;
898 const char *local;
899 const char *uri;
900 const char *output;
901 const char *output_partial;
902 HRESULT hr;
903 int todo;
904 int todo_partial;
905 }
906 start_element_tests[] =
907 {
908 { "prefix", "local", "uri", "<prefix:local xmlns:prefix=\"uri\" />", "<prefix:local" },
909 { NULL, "local", "uri", "<local xmlns=\"uri\" />", "<local" },
910 { "", "local", "uri", "<local xmlns=\"uri\" />", "<local" },
911 { "", "local", "uri", "<local xmlns=\"uri\" />", "<local" },
912
913 { "prefix", NULL, NULL, NULL, NULL, E_INVALIDARG },
914 { NULL, NULL, "uri", NULL, NULL, E_INVALIDARG },
916 { NULL, "prefix:local", "uri", NULL, NULL, WC_E_NAMECHARACTER },
917 { "pre:fix", "local", "uri", NULL, NULL, WC_E_NAMECHARACTER },
918 { NULL, ":local", "uri", NULL, NULL, WC_E_NAMECHARACTER },
919 { ":", "local", "uri", NULL, NULL, WC_E_NAMECHARACTER },
920 { NULL, "local", "http://www.w3.org/2000/xmlns/", NULL, NULL, WR_E_XMLNSPREFIXDECLARATION },
921 { "prefix", "local", "http://www.w3.org/2000/xmlns/", NULL, NULL, WR_E_XMLNSURIDECLARATION },
922 };
923 static const WCHAR aW[] = {'a',0};
924 IXmlWriter *writer;
926 unsigned int i;
927 HRESULT hr;
928
929 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
930 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
931
932 hr = write_start_element(writer, NULL, "a", NULL);
933 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
934
935 stream = writer_set_output(writer);
936
937 hr = write_start_element(writer, NULL, "a", NULL);
938 ok(hr == S_OK, "got 0x%08x\n", hr);
939
940 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
941 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
942
943 hr = IXmlWriter_Flush(writer);
944 ok(hr == S_OK, "got 0x%08x\n", hr);
945
946 CHECK_OUTPUT(stream, "<a");
947
948 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
949 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
950
951 hr = IXmlWriter_WriteStartElement(writer, NULL, NULL, NULL);
952 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
953
954 hr = IXmlWriter_WriteProcessingInstruction(writer, aW, aW);
955 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
956
957 IStream_Release(stream);
958 IXmlWriter_Release(writer);
959
960 /* WriteElementString */
961 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
962 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
963
964 hr = write_element_string(writer, NULL, "b", NULL, "value");
965 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
966
967 stream = writer_set_output(writer);
968
969 hr = write_start_element(writer, "prefix", "a", "uri");
970 ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr);
971
972 hr = write_element_string(writer, NULL, "b", NULL, "value");
973 ok(hr == S_OK, "Failed to write element string, hr %#x.\n", hr);
974
975 hr = write_element_string(writer, NULL, "c", NULL, NULL);
976 ok(hr == S_OK, "Failed to write element string, hr %#x.\n", hr);
977
978 hr = write_start_element(writer, NULL, "d", "uri");
979 ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr);
980
981 hr = write_start_element(writer, "", "e", "uri");
982 ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr);
983
984 hr = write_start_element(writer, "prefix2", "f", "uri");
985 ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr);
986
987 hr = IXmlWriter_Flush(writer);
988 ok(hr == S_OK, "got 0x%08x\n", hr);
989
991 "<prefix:a xmlns:prefix=\"uri\">"
992 "<b>value</b>"
993 "<c />"
994 "<prefix:d>"
995 "<e xmlns=\"uri\">"
996 "<prefix2:f");
997
998 IStream_Release(stream);
999
1000 /* WriteStartElement */
1001 for (i = 0; i < ARRAY_SIZE(start_element_tests); ++i)
1002 {
1003 stream = writer_set_output(writer);
1004
1006
1007 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1008 ok(hr == S_OK, "Failed to start document, hr %#x.\n", hr);
1009
1010 hr = write_start_element(writer, start_element_tests[i].prefix, start_element_tests[i].local,
1011 start_element_tests[i].uri);
1012 ok(hr == start_element_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
1013
1014 if (SUCCEEDED(start_element_tests[i].hr))
1015 {
1016 hr = IXmlWriter_Flush(writer);
1017 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
1018
1019 check_output(stream, start_element_tests[i].output_partial, start_element_tests[i].todo_partial, __LINE__);
1020
1021 hr = IXmlWriter_WriteEndDocument(writer);
1022 ok(hr == S_OK, "Failed to end document, hr %#x.\n", hr);
1023
1024 hr = IXmlWriter_Flush(writer);
1025 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
1026
1027 check_output(stream, start_element_tests[i].output, start_element_tests[i].todo, __LINE__);
1028 }
1029
1030 IStream_Release(stream);
1031 }
1032
1033 IXmlWriter_Release(writer);
1034}
1035
1037{
1038 static const struct
1039 {
1040 const char *prefix;
1041 const char *local;
1042 const char *uri;
1043 const char *value;
1044 const char *output;
1045 HRESULT hr;
1046 int todo;
1047 }
1048 element_string_tests[] =
1049 {
1050 { "prefix", "local", "uri", "value", "<prefix:local xmlns:prefix=\"uri\">value</prefix:local>" },
1051 { NULL, "local", "uri", "value", "<local xmlns=\"uri\">value</local>" },
1052 { "", "local", "uri", "value", "<local xmlns=\"uri\">value</local>" },
1053 { "prefix", "local", "uri", NULL, "<prefix:local xmlns:prefix=\"uri\" />" },
1054 { NULL, "local", "uri", NULL, "<local xmlns=\"uri\" />" },
1055 { "", "local", "uri", NULL, "<local xmlns=\"uri\" />" },
1056 { NULL, "local", NULL, NULL, "<local />" },
1057 { "prefix", "local", "uri", "", "<prefix:local xmlns:prefix=\"uri\"></prefix:local>" },
1058 { NULL, "local", "uri", "", "<local xmlns=\"uri\"></local>" },
1059 { "", "local", "uri", "", "<local xmlns=\"uri\"></local>" },
1060 { NULL, "local", NULL, "", "<local></local>" },
1061 { "", "local", "http://www.w3.org/2000/xmlns/", NULL, "<local xmlns=\"http://www.w3.org/2000/xmlns/\" />" },
1062
1063 { "prefix", NULL, NULL, "value", NULL, E_INVALIDARG },
1064 { NULL, NULL, "uri", "value", NULL, E_INVALIDARG },
1065 { NULL, NULL, NULL, "value", NULL, E_INVALIDARG },
1066 { NULL, "prefix:local", "uri", "value", NULL, WC_E_NAMECHARACTER },
1067 { NULL, ":local", "uri", "value", NULL, WC_E_NAMECHARACTER },
1068 { ":", "local", "uri", "value", NULL, WC_E_NAMECHARACTER },
1069 { "prefix", "local", NULL, "value", NULL, WR_E_NSPREFIXWITHEMPTYNSURI },
1070 { "prefix", "local", "", "value", NULL, WR_E_NSPREFIXWITHEMPTYNSURI },
1071 { NULL, "local", "http://www.w3.org/2000/xmlns/", "value", NULL, WR_E_XMLNSPREFIXDECLARATION },
1072 { "prefix", "local", "http://www.w3.org/2000/xmlns/", "value", NULL, WR_E_XMLNSURIDECLARATION },
1073 };
1074 IXmlWriter *writer;
1075 IStream *stream;
1076 unsigned int i;
1077 HRESULT hr;
1078
1079 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1080 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1081
1082 hr = write_element_string(writer, NULL, "b", NULL, "value");
1083 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
1084
1085 stream = writer_set_output(writer);
1086
1087 hr = write_start_element(writer, NULL, "a", NULL);
1088 ok(hr == S_OK, "got 0x%08x\n", hr);
1089
1090 hr = write_element_string(writer, NULL, "b", NULL, "value");
1091 ok(hr == S_OK, "got 0x%08x\n", hr);
1092
1093 hr = write_element_string(writer, NULL, "b", NULL, NULL);
1094 ok(hr == S_OK, "got 0x%08x\n", hr);
1095
1096 hr = write_element_string(writer, "prefix", "b", "uri", NULL);
1097 ok(hr == S_OK, "got 0x%08x\n", hr);
1098
1099 hr = write_start_element(writer, "prefix", "c", "uri");
1100 ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr);
1101
1102 hr = write_element_string(writer, "prefix", "d", NULL, NULL);
1103 ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr);
1104
1105 hr = write_element_string(writer, "prefix2", "d", "uri", NULL);
1106 ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr);
1107
1108 hr = write_element_string(writer, NULL, "e", "uri", NULL);
1109 ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr);
1110
1111 hr = write_element_string(writer, "prefix", "f", "uri2", NULL);
1112 ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr);
1113
1114 hr = write_element_string(writer, NULL, "g", "uri3", NULL);
1115 ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr);
1116
1117 hr = write_element_string(writer, "prefix", "h", NULL, NULL);
1118 ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr);
1119
1120 hr = write_element_string(writer, "prefix_i", "i", NULL, NULL);
1121 ok(hr == WR_E_NSPREFIXWITHEMPTYNSURI, "Failed to write element, hr %#x.\n", hr);
1122
1123 hr = write_element_string(writer, "", "j", "uri", NULL);
1124 ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr);
1125
1126 hr = IXmlWriter_Flush(writer);
1127 ok(hr == S_OK, "got 0x%08x\n", hr);
1128
1130 "<a><b>value</b><b />"
1131 "<prefix:b xmlns:prefix=\"uri\" />"
1132 "<prefix:c xmlns:prefix=\"uri\">"
1133 "<prefix:d />"
1134 "<prefix2:d xmlns:prefix2=\"uri\" />"
1135 "<prefix:e />"
1136 "<prefix:f xmlns:prefix=\"uri2\" />"
1137 "<g xmlns=\"uri3\" />"
1138 "<prefix:h />"
1139 "<j xmlns=\"uri\" />");
1140
1141 IStream_Release(stream);
1142
1143 for (i = 0; i < ARRAY_SIZE(element_string_tests); ++i)
1144 {
1145 stream = writer_set_output(writer);
1146
1148
1149 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1150 ok(hr == S_OK, "Failed to start document, hr %#x.\n", hr);
1151
1152 hr = write_element_string(writer, element_string_tests[i].prefix, element_string_tests[i].local,
1153 element_string_tests[i].uri, element_string_tests[i].value);
1154 ok(hr == element_string_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
1155
1156 if (SUCCEEDED(element_string_tests[i].hr))
1157 {
1158 hr = IXmlWriter_Flush(writer);
1159 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
1160
1161 check_output(stream, element_string_tests[i].output, element_string_tests[i].todo, __LINE__);
1162
1163 hr = IXmlWriter_WriteEndDocument(writer);
1164 ok(hr == S_OK, "Failed to end document, hr %#x.\n", hr);
1165
1166 hr = IXmlWriter_Flush(writer);
1167 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
1168
1169 check_output(stream, element_string_tests[i].output, element_string_tests[i].todo, __LINE__);
1170 }
1171
1172 IStream_Release(stream);
1173 }
1174
1175 IXmlWriter_Release(writer);
1176}
1177
1178static void test_WriteEndElement(void)
1179{
1180 IXmlWriter *writer;
1181 IStream *stream;
1182 HRESULT hr;
1183
1184 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1185 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1186
1187 stream = writer_set_output(writer);
1188
1189 hr = write_start_element(writer, NULL, "a", NULL);
1190 ok(hr == S_OK, "got 0x%08x\n", hr);
1191
1192 hr = write_start_element(writer, NULL, "b", NULL);
1193 ok(hr == S_OK, "got 0x%08x\n", hr);
1194
1195 hr = IXmlWriter_WriteEndElement(writer);
1196 ok(hr == S_OK, "got 0x%08x\n", hr);
1197
1198 hr = IXmlWriter_WriteEndElement(writer);
1199 ok(hr == S_OK, "got 0x%08x\n", hr);
1200
1201 hr = IXmlWriter_Flush(writer);
1202 ok(hr == S_OK, "got 0x%08x\n", hr);
1203
1204 CHECK_OUTPUT(stream, "<a><b /></a>");
1205
1206 IXmlWriter_Release(writer);
1207 IStream_Release(stream);
1208}
1209
1210static void test_writeenddocument(void)
1211{
1212 static const WCHAR aW[] = {'a',0};
1213 static const WCHAR bW[] = {'b',0};
1214 IXmlWriter *writer;
1215 IStream *stream;
1216 HGLOBAL hglobal;
1217 HRESULT hr;
1218 char *ptr;
1219
1220 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1221 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1222
1223 hr = IXmlWriter_WriteEndDocument(writer);
1224 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
1225
1226 stream = writer_set_output(writer);
1227
1228 /* WriteEndDocument resets it to initial state */
1229 hr = IXmlWriter_WriteEndDocument(writer);
1230 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1231
1232 hr = IXmlWriter_WriteEndDocument(writer);
1233 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1234
1235 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1236 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1237
1238 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1239 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1240
1241 hr = IXmlWriter_SetOutput(writer, (IUnknown*)stream);
1242 ok(hr == S_OK, "got 0x%08x\n", hr);
1243
1244 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1245 ok(hr == S_OK, "got 0x%08x\n", hr);
1246
1247 hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL);
1248 ok(hr == S_OK, "got 0x%08x\n", hr);
1249
1250 hr = IXmlWriter_WriteEndDocument(writer);
1251 ok(hr == S_OK, "got 0x%08x\n", hr);
1252
1253 hr = GetHGlobalFromStream(stream, &hglobal);
1254 ok(hr == S_OK, "got 0x%08x\n", hr);
1255
1256 ptr = GlobalLock(hglobal);
1257 ok(ptr == NULL, "got %p\n", ptr);
1258
1259 /* we still need to flush manually, WriteEndDocument doesn't do that */
1260 hr = IXmlWriter_Flush(writer);
1261 ok(hr == S_OK, "got 0x%08x\n", hr);
1262
1263 CHECK_OUTPUT(stream, "<a><b /></a>");
1264
1265 IXmlWriter_Release(writer);
1266 IStream_Release(stream);
1267}
1268
1269static void test_WriteComment(void)
1270{
1271 static const WCHAR closeW[] = {'-','-','>',0};
1272 static const WCHAR aW[] = {'a',0};
1273 static const WCHAR bW[] = {'b',0};
1274 IXmlWriter *writer;
1275 IStream *stream;
1276 HRESULT hr;
1277
1278 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1279 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1280
1282
1283 hr = IXmlWriter_WriteComment(writer, aW);
1284 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
1285
1286 stream = writer_set_output(writer);
1287
1288 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1289 ok(hr == S_OK, "got 0x%08x\n", hr);
1290
1291 hr = IXmlWriter_WriteComment(writer, aW);
1292 ok(hr == S_OK, "got 0x%08x\n", hr);
1293
1294 hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL);
1295 ok(hr == S_OK, "got 0x%08x\n", hr);
1296
1297 hr = IXmlWriter_WriteComment(writer, aW);
1298 ok(hr == S_OK, "got 0x%08x\n", hr);
1299
1300 hr = IXmlWriter_WriteComment(writer, NULL);
1301 ok(hr == S_OK, "got 0x%08x\n", hr);
1302
1303 hr = IXmlWriter_WriteComment(writer, closeW);
1304 ok(hr == S_OK, "got 0x%08x\n", hr);
1305
1306 hr = IXmlWriter_Flush(writer);
1307 ok(hr == S_OK, "got 0x%08x\n", hr);
1308
1309 CHECK_OUTPUT(stream, "<!--a--><b><!--a--><!----><!--- ->-->");
1310
1311 IXmlWriter_Release(writer);
1312 IStream_Release(stream);
1313}
1314
1315static void test_WriteCData(void)
1316{
1317 static const WCHAR closeW[] = {']',']','>',0};
1318 static const WCHAR close2W[] = {'a',']',']','>','b',0};
1319 static const WCHAR aW[] = {'a',0};
1320 static const WCHAR bW[] = {'b',0};
1321 IXmlWriter *writer;
1322 IStream *stream;
1323 HRESULT hr;
1324
1325 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1326 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1327
1329
1330 hr = IXmlWriter_WriteCData(writer, aW);
1331 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
1332
1333 stream = writer_set_output(writer);
1334
1335 hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL);
1336 ok(hr == S_OK, "got 0x%08x\n", hr);
1337
1338 hr = IXmlWriter_WriteCData(writer, aW);
1339 ok(hr == S_OK, "got 0x%08x\n", hr);
1340
1341 hr = IXmlWriter_WriteCData(writer, NULL);
1342 ok(hr == S_OK, "got 0x%08x\n", hr);
1343
1344 hr = IXmlWriter_WriteCData(writer, closeW);
1345 ok(hr == S_OK, "got 0x%08x\n", hr);
1346
1347 hr = IXmlWriter_WriteCData(writer, close2W);
1348 ok(hr == S_OK, "got 0x%08x\n", hr);
1349
1350 hr = IXmlWriter_Flush(writer);
1351 ok(hr == S_OK, "got 0x%08x\n", hr);
1352
1354 "<b>"
1355 "<![CDATA[a]]>"
1356 "<![CDATA[]]>"
1357 "<![CDATA[]]]]>"
1358 "<![CDATA[>]]>"
1359 "<![CDATA[a]]]]>"
1360 "<![CDATA[>b]]>");
1361
1362 IXmlWriter_Release(writer);
1363 IStream_Release(stream);
1364}
1365
1366static void test_WriteRaw(void)
1367{
1368 static const WCHAR rawW[] = {'a','<',':',0};
1369 static const WCHAR aW[] = {'a',0};
1370 IXmlWriter *writer;
1371 IStream *stream;
1372 HRESULT hr;
1373
1374 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1375 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1376
1377 hr = IXmlWriter_WriteRaw(writer, NULL);
1378 ok(hr == S_OK, "got 0x%08x\n", hr);
1379
1380 hr = IXmlWriter_WriteRaw(writer, rawW);
1381 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
1382
1383 stream = writer_set_output(writer);
1384
1385 hr = IXmlWriter_WriteRaw(writer, NULL);
1386 ok(hr == S_OK, "got 0x%08x\n", hr);
1387
1388 hr = IXmlWriter_WriteRaw(writer, rawW);
1389 ok(hr == S_OK, "got 0x%08x\n", hr);
1390
1391 hr = IXmlWriter_WriteRaw(writer, rawW);
1392 ok(hr == S_OK, "got 0x%08x\n", hr);
1393
1394 hr = IXmlWriter_WriteComment(writer, rawW);
1395 ok(hr == S_OK, "got 0x%08x\n", hr);
1396
1397 hr = IXmlWriter_WriteRaw(writer, rawW);
1398 ok(hr == S_OK, "got 0x%08x\n", hr);
1399
1400 hr = IXmlWriter_WriteElementString(writer, NULL, aW, NULL, aW);
1401 ok(hr == S_OK, "got 0x%08x\n", hr);
1402
1403 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
1404 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1405
1406 hr = IXmlWriter_WriteComment(writer, rawW);
1407 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1408
1409 hr = IXmlWriter_WriteEndDocument(writer);
1410 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1411
1412 hr = IXmlWriter_WriteRaw(writer, rawW);
1413 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1414
1415 hr = IXmlWriter_Flush(writer);
1416 ok(hr == S_OK, "got 0x%08x\n", hr);
1417
1418 CHECK_OUTPUT(stream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>a<:a<:<!--a<:-->a<:<a>a</a>");
1419
1420 IXmlWriter_Release(writer);
1421 IStream_Release(stream);
1422}
1423
1424static void test_writer_state(void)
1425{
1426 static const WCHAR aW[] = {'a',0};
1427 IXmlWriter *writer;
1428 IStream *stream;
1429 HRESULT hr;
1430
1431 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1432 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1433
1434 /* initial state */
1436
1437 /* set output and call 'wrong' method, WriteEndElement */
1438 stream = writer_set_output(writer);
1439
1440 hr = IXmlWriter_WriteEndElement(writer);
1441 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1442
1444 IStream_Release(stream);
1445
1446 /* WriteAttributeString */
1447 stream = writer_set_output(writer);
1448
1449 hr = IXmlWriter_WriteAttributeString(writer, NULL, aW, NULL, aW);
1450 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1451
1453 IStream_Release(stream);
1454
1455 /* WriteEndDocument */
1456 stream = writer_set_output(writer);
1457
1458 hr = IXmlWriter_WriteEndDocument(writer);
1459 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1460
1462 IStream_Release(stream);
1463
1464 /* WriteFullEndElement */
1465 stream = writer_set_output(writer);
1466
1467 hr = IXmlWriter_WriteFullEndElement(writer);
1468 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1469
1471 IStream_Release(stream);
1472
1473 /* WriteCData */
1474 stream = writer_set_output(writer);
1475
1476 hr = IXmlWriter_WriteCData(writer, aW);
1477 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1478
1480 IStream_Release(stream);
1481
1482 /* WriteName */
1483 stream = writer_set_output(writer);
1484
1485 hr = IXmlWriter_WriteName(writer, aW);
1486 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1487
1489 IStream_Release(stream);
1490
1491 /* WriteNmToken */
1492 stream = writer_set_output(writer);
1493
1494 hr = IXmlWriter_WriteNmToken(writer, aW);
1495 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1496
1498 IStream_Release(stream);
1499
1500 /* WriteString */
1501 stream = writer_set_output(writer);
1502
1503 hr = IXmlWriter_WriteString(writer, aW);
1504 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1505
1507 IStream_Release(stream);
1508
1509 IXmlWriter_Release(writer);
1510}
1511
1512static void test_indentation(void)
1513{
1514 static const WCHAR commentW[] = {'c','o','m','m','e','n','t',0};
1515 static const WCHAR aW[] = {'a',0};
1516 static const WCHAR bW[] = {'b',0};
1517 IXmlWriter *writer;
1518 IStream *stream;
1519 HRESULT hr;
1520
1521 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1522 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1523
1524 stream = writer_set_output(writer);
1525
1528
1529 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1530 ok(hr == S_OK, "got 0x%08x\n", hr);
1531
1532 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1533 ok(hr == S_OK, "got 0x%08x\n", hr);
1534
1535 hr = IXmlWriter_WriteComment(writer, commentW);
1536 ok(hr == S_OK, "got 0x%08x\n", hr);
1537
1538 hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL);
1539 ok(hr == S_OK, "got 0x%08x\n", hr);
1540
1541 hr = IXmlWriter_WriteEndDocument(writer);
1542 ok(hr == S_OK, "got 0x%08x\n", hr);
1543
1544 hr = IXmlWriter_Flush(writer);
1545 ok(hr == S_OK, "got 0x%08x\n", hr);
1546
1548 "<a>\r\n"
1549 " <!--comment-->\r\n"
1550 " <b />\r\n"
1551 "</a>");
1552
1553 IStream_Release(stream);
1554
1555 /* WriteElementString */
1556 stream = writer_set_output(writer);
1557
1558 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1559 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1560
1561 hr = IXmlWriter_WriteElementString(writer, NULL, bW, NULL, NULL);
1562 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1563
1564 hr = IXmlWriter_WriteElementString(writer, NULL, bW, NULL, NULL);
1565 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1566
1567 hr = IXmlWriter_WriteEndElement(writer);
1568 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1569
1570 hr = IXmlWriter_Flush(writer);
1571 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1572
1574 "<a>\r\n"
1575 " <b />\r\n"
1576 " <b />\r\n"
1577 "</a>");
1578
1579 IStream_Release(stream);
1580
1581 IXmlWriter_Release(writer);
1582}
1583
1584static HRESULT write_attribute_string(IXmlWriter *writer, const char *prefix, const char *local,
1585 const char *uri, const char *value)
1586{
1587 WCHAR *prefixW, *localW, *uriW, *valueW;
1588 HRESULT hr;
1589
1590 prefixW = strdupAtoW(prefix);
1591 localW = strdupAtoW(local);
1592 uriW = strdupAtoW(uri);
1594
1595 hr = IXmlWriter_WriteAttributeString(writer, prefixW, localW, uriW, valueW);
1596
1597 heap_free(prefixW);
1598 heap_free(localW);
1599 heap_free(uriW);
1601
1602 return hr;
1603}
1604
1606{
1607 static const struct
1608 {
1609 const char *prefix;
1610 const char *local;
1611 const char *uri;
1612 const char *value;
1613 const char *output;
1614 const char *output_partial;
1615 HRESULT hr;
1616 int todo;
1617 int todo_partial;
1618 int todo_hr;
1619 }
1620 attribute_tests[] =
1621 {
1622 { NULL, "a", NULL, "b", "<e a=\"b\" />", "<e a=\"b\"" },
1623 { "", "a", NULL, "b", "<e a=\"b\" />", "<e a=\"b\"" },
1624 { NULL, "a", "", "b", "<e a=\"b\" />", "<e a=\"b\"" },
1625 { "", "a", "", "b", "<e a=\"b\" />", "<e a=\"b\"" },
1626 { "prefix", "local", "uri", "b", "<e prefix:local=\"b\" xmlns:prefix=\"uri\" />", "<e prefix:local=\"b\"" },
1627 { NULL, "a", "http://www.w3.org/2000/xmlns/", "defuri", "<e xmlns:a=\"defuri\" />", "<e xmlns:a=\"defuri\"" },
1628 { "xmlns", "a", NULL, "uri", "<e xmlns:a=\"uri\" />", "<e xmlns:a=\"uri\"" },
1629 { "xmlns", "a", "", "uri", "<e xmlns:a=\"uri\" />", "<e xmlns:a=\"uri\"" },
1630 { "prefix", "xmlns", "uri", "value", "<e prefix:xmlns=\"value\" xmlns:prefix=\"uri\" />", "<e prefix:xmlns=\"value\"" },
1631 { "prefix", "xmlns", "uri", NULL, "<e prefix:xmlns=\"\" xmlns:prefix=\"uri\" />", "<e prefix:xmlns=\"\"" },
1632 { "prefix", "xmlns", "uri", "", "<e prefix:xmlns=\"\" xmlns:prefix=\"uri\" />", "<e prefix:xmlns=\"\"" },
1633 { "prefix", "xmlns", NULL, "uri", "<e xmlns=\"uri\" />", "<e xmlns=\"uri\"" },
1634 { "prefix", "xmlns", "", "uri", "<e xmlns=\"uri\" />", "<e xmlns=\"uri\"" },
1635 { "xml", "space", NULL, "preserve", "<e xml:space=\"preserve\" />", "<e xml:space=\"preserve\"" },
1636 { "xml", "space", "", "preserve", "<e xml:space=\"preserve\" />", "<e xml:space=\"preserve\"" },
1637 { "xml", "space", NULL, "default", "<e xml:space=\"default\" />", "<e xml:space=\"default\"" },
1638 { "xml", "space", "", "default", "<e xml:space=\"default\" />", "<e xml:space=\"default\"" },
1639 { "xml", "a", NULL, "value", "<e xml:a=\"value\" />", "<e xml:a=\"value\"" },
1640 { "xml", "a", "", "value", "<e xml:a=\"value\" />", "<e xml:a=\"value\"" },
1641
1642 /* Autogenerated prefix names. */
1643 { NULL, "a", "defuri", NULL, "<e p1:a=\"\" xmlns:p1=\"defuri\" />", "<e p1:a=\"\"", S_OK, 1, 1, 1 },
1644 { NULL, "a", "defuri", "b", "<e p1:a=\"b\" xmlns:p1=\"defuri\" />", "<e p1:a=\"b\"", S_OK, 1, 1, 1 },
1645 { "", "a", "defuri", NULL, "<e p1:a=\"\" xmlns:p1=\"defuri\" />", "<e p1:a=\"\"", S_OK, 1, 1, 1 },
1646 { NULL, "a", "defuri", "", "<e p1:a=\"\" xmlns:p1=\"defuri\" />", "<e p1:a=\"\"", S_OK, 1, 1, 1 },
1647 { "", "a", "defuri", "b", "<e p1:a=\"b\" xmlns:p1=\"defuri\" />", "<e p1:a=\"b\"", S_OK, 1, 1, 1 },
1648
1649 /* Failing cases. */
1650 { NULL, NULL, "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", E_INVALIDARG },
1651 { "", "a", "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION, 1, 1, 1 },
1652 { "", NULL, "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", E_INVALIDARG },
1653 { "", "", "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", E_INVALIDARG, 1, 1, 1 },
1654 { NULL, "", "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", E_INVALIDARG, 1, 1, 1 },
1655 { "prefix", "a", "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", WR_E_XMLNSURIDECLARATION, 1, 1, 1 },
1656 { "prefix", NULL, "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", E_INVALIDARG },
1657 { "prefix", NULL, NULL, "b", "<e />", "<e", E_INVALIDARG },
1658 { "prefix", NULL, "uri", NULL, "<e />", "<e", E_INVALIDARG },
1659 { "xml", NULL, NULL, "value", "<e />", "<e", E_INVALIDARG },
1660 { "xmlns", "a", "defuri", NULL, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION },
1661 { "xmlns", "a", "b", "uri", "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION },
1662 { NULL, "xmlns", "uri", NULL, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION, 0, 0, 1 },
1663 { "xmlns", NULL, "uri", NULL, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION, 0, 0, 1 },
1664 { "pre:fix", "local", "uri", "b", "<e />", "<e", WC_E_NAMECHARACTER },
1665 { "pre:fix", NULL, "uri", "b", "<e />", "<e", E_INVALIDARG },
1666 { "prefix", "lo:cal", "uri", "b", "<e />", "<e", WC_E_NAMECHARACTER },
1667 { "xmlns", NULL, NULL, "uri", "<e />", "<e", WR_E_NSPREFIXDECLARED },
1668 { "xmlns", NULL, "", "uri", "<e />", "<e", WR_E_NSPREFIXDECLARED },
1669 { "xmlns", "", NULL, "uri", "<e />", "<e", WR_E_NSPREFIXDECLARED },
1670 { "xmlns", "", "", "uri", "<e />", "<e", WR_E_NSPREFIXDECLARED },
1671 { "xml", "space", "", "value", "<e />", "<e", WR_E_INVALIDXMLSPACE },
1672 { "xml", "space", NULL, "value", "<e />", "<e", WR_E_INVALIDXMLSPACE },
1673 { "xml", "a", "uri", "value", "<e />", "<e", WR_E_XMLPREFIXDECLARATION },
1674 { "xml", "space", NULL, "preServe", "<e />", "<e", WR_E_INVALIDXMLSPACE },
1675 { "xml", "space", NULL, "defAult", "<e />", "<e", WR_E_INVALIDXMLSPACE },
1676 { "xml", "space", NULL, NULL, "<e />", "<e", WR_E_INVALIDXMLSPACE },
1677 { "xml", "space", NULL, "", "<e />", "<e", WR_E_INVALIDXMLSPACE },
1678 };
1679
1680 IXmlWriter *writer;
1681 IStream *stream;
1682 unsigned int i;
1683 HRESULT hr;
1684
1685 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1686 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1687
1689
1690 for (i = 0; i < ARRAY_SIZE(attribute_tests); ++i)
1691 {
1692 stream = writer_set_output(writer);
1693
1694 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1695 ok(hr == S_OK, "Failed to start document, hr %#x.\n", hr);
1696
1697 hr = write_start_element(writer, NULL, "e", NULL);
1698 ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr);
1699
1700 hr = write_attribute_string(writer, attribute_tests[i].prefix, attribute_tests[i].local,
1701 attribute_tests[i].uri, attribute_tests[i].value);
1702 todo_wine_if(attribute_tests[i].todo_hr)
1703 ok(hr == attribute_tests[i].hr, "%u: unexpected hr %#x, expected %#x.\n", i, hr, attribute_tests[i].hr);
1704
1705 hr = IXmlWriter_Flush(writer);
1706 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
1707
1708 check_output(stream, attribute_tests[i].output_partial, attribute_tests[i].todo_partial, __LINE__);
1709
1710 hr = IXmlWriter_WriteEndDocument(writer);
1711 ok(hr == S_OK, "Failed to end document, hr %#x.\n", hr);
1712
1713 hr = IXmlWriter_Flush(writer);
1714 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
1715
1716 check_output(stream, attribute_tests[i].output, attribute_tests[i].todo, __LINE__);
1717 IStream_Release(stream);
1718 }
1719
1720 /* With namespaces */
1721 stream = writer_set_output(writer);
1722
1723 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1724 ok(hr == S_OK, "got 0x%08x\n", hr);
1725
1726 hr = write_start_element(writer, "p", "a", "outeruri");
1727 ok(hr == S_OK, "got 0x%08x\n", hr);
1728
1729 hr = write_attribute_string(writer, "prefix", "local", "uri", "b");
1730 ok(hr == S_OK, "got 0x%08x\n", hr);
1731
1732 hr = write_attribute_string(writer, NULL, "a", NULL, "b");
1733 ok(hr == S_OK, "got 0x%08x\n", hr);
1734
1735 hr = write_attribute_string(writer, "xmlns", "prefix", NULL, "uri");
1736 ok(hr == S_OK, "got 0x%08x\n", hr);
1737
1738 hr = write_attribute_string(writer, "p", "attr", NULL, "value");
1739 ok(hr == S_OK, "Failed to write attribute string, hr %#x.\n", hr);
1740
1741 hr = write_attribute_string(writer, "prefix", "local", NULL, "b");
1743 ok(hr == WR_E_DUPLICATEATTRIBUTE, "got 0x%08x\n", hr);
1744
1745 hr = write_start_element(writer, NULL, "b", NULL);
1746 ok(hr == S_OK, "got 0x%08x\n", hr);
1747
1748 hr = write_attribute_string(writer, NULL, "attr2", "outeruri", "value");
1749 ok(hr == S_OK, "Failed to write attribute string, hr %#x.\n", hr);
1750
1751 hr = write_attribute_string(writer, "pr", "attr3", "outeruri", "value");
1752 ok(hr == S_OK, "Failed to write attribute string, hr %#x.\n", hr);
1753
1754 hr = IXmlWriter_WriteEndDocument(writer);
1755 ok(hr == S_OK, "got 0x%08x\n", hr);
1756
1757 hr = IXmlWriter_Flush(writer);
1758 ok(hr == S_OK, "got 0x%08x\n", hr);
1759
1761 "<p:a prefix:local=\"b\" a=\"b\" xmlns:prefix=\"uri\" p:attr=\"value\" xmlns:p=\"outeruri\">"
1762 "<b p:attr2=\"value\" pr:attr3=\"value\" xmlns:pr=\"outeruri\" />"
1763 "</p:a>");
1764
1765 IStream_Release(stream);
1766
1767 /* Define prefix, write attribute with it. */
1768 stream = writer_set_output(writer);
1769
1770 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1771 ok(hr == S_OK, "got 0x%08x\n", hr);
1772
1773 hr = write_start_element(writer, NULL, "e", NULL);
1774 ok(hr == S_OK, "got 0x%08x\n", hr);
1775
1776 hr = write_attribute_string(writer, "xmlns", "prefix", NULL, "uri");
1777 ok(hr == S_OK, "got 0x%08x\n", hr);
1778
1779 hr = write_attribute_string(writer, "prefix", "attr", NULL, "value");
1780 ok(hr == S_OK, "got 0x%08x\n", hr);
1781
1782 hr = IXmlWriter_WriteEndDocument(writer);
1783 ok(hr == S_OK, "got 0x%08x\n", hr);
1784
1785 hr = IXmlWriter_Flush(writer);
1786 ok(hr == S_OK, "got 0x%08x\n", hr);
1787
1789 "<e xmlns:prefix=\"uri\" prefix:attr=\"value\" />");
1790
1791 IStream_Release(stream);
1792
1793 IXmlWriter_Release(writer);
1794}
1795
1797{
1798 static const WCHAR aW[] = {'a',0};
1799 IXmlWriter *writer;
1800 IStream *stream;
1801 HRESULT hr;
1802
1803 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1804 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1805
1806 /* standalone element */
1807 stream = writer_set_output(writer);
1808
1811
1812 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1813 ok(hr == S_OK, "got 0x%08x\n", hr);
1814
1815 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1816 ok(hr == S_OK, "got 0x%08x\n", hr);
1817
1818 hr = IXmlWriter_WriteFullEndElement(writer);
1819 ok(hr == S_OK, "got 0x%08x\n", hr);
1820
1821 hr = IXmlWriter_WriteEndDocument(writer);
1822 ok(hr == S_OK, "got 0x%08x\n", hr);
1823
1824 hr = IXmlWriter_Flush(writer);
1825 ok(hr == S_OK, "got 0x%08x\n", hr);
1826
1828 "<a></a>");
1829 IStream_Release(stream);
1830
1831 /* nested elements */
1832 stream = writer_set_output(writer);
1833
1836
1837 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1838 ok(hr == S_OK, "got 0x%08x\n", hr);
1839
1840 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1841 ok(hr == S_OK, "got 0x%08x\n", hr);
1842
1843 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1844 ok(hr == S_OK, "got 0x%08x\n", hr);
1845
1846 hr = IXmlWriter_WriteFullEndElement(writer);
1847 ok(hr == S_OK, "got 0x%08x\n", hr);
1848
1849 hr = IXmlWriter_WriteEndDocument(writer);
1850 ok(hr == S_OK, "got 0x%08x\n", hr);
1851
1852 hr = IXmlWriter_Flush(writer);
1853 ok(hr == S_OK, "got 0x%08x\n", hr);
1854
1856 "<a>\r\n"
1857 " <a></a>\r\n"
1858 "</a>");
1859
1860 IXmlWriter_Release(writer);
1861 IStream_Release(stream);
1862}
1863
1864static void test_WriteCharEntity(void)
1865{
1866 static const WCHAR aW[] = {'a',0};
1867 IXmlWriter *writer;
1868 IStream *stream;
1869 HRESULT hr;
1870
1871 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1872 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1873
1874 /* without indentation */
1875 stream = writer_set_output(writer);
1876
1878
1879 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1880 ok(hr == S_OK, "got 0x%08x\n", hr);
1881
1882 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1883 ok(hr == S_OK, "got 0x%08x\n", hr);
1884
1885 hr = IXmlWriter_WriteCharEntity(writer, 0x100);
1886 ok(hr == S_OK, "got 0x%08x\n", hr);
1887
1888 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1889 ok(hr == S_OK, "got 0x%08x\n", hr);
1890
1891 hr = IXmlWriter_WriteEndDocument(writer);
1892 ok(hr == S_OK, "got 0x%08x\n", hr);
1893
1894 hr = IXmlWriter_Flush(writer);
1895 ok(hr == S_OK, "got 0x%08x\n", hr);
1896
1898 "<a>&#x100;<a /></a>");
1899
1900 IXmlWriter_Release(writer);
1901 IStream_Release(stream);
1902}
1903
1904static void test_WriteString(void)
1905{
1906 IXmlWriter *writer;
1907 IStream *stream;
1908 HRESULT hr;
1909
1910 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1911 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1912
1914
1915 hr = write_string(writer, "a");
1916 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
1917
1918 hr = write_string(writer, NULL);
1919 ok(hr == S_OK, "got 0x%08x\n", hr);
1920
1921 hr = write_string(writer, "");
1922 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
1923
1924 stream = writer_set_output(writer);
1925
1926 hr = write_start_element(writer, NULL, "b", NULL);
1927 ok(hr == S_OK, "got 0x%08x\n", hr);
1928
1929 hr = write_string(writer, NULL);
1930 ok(hr == S_OK, "got 0x%08x\n", hr);
1931
1932 hr = write_string(writer, "");
1933 ok(hr == S_OK, "got 0x%08x\n", hr);
1934
1935 hr = write_string(writer, "a");
1936 ok(hr == S_OK, "got 0x%08x\n", hr);
1937
1938 /* WriteString automatically escapes markup characters */
1939 hr = write_string(writer, "<&\">=");
1940 ok(hr == S_OK, "got 0x%08x\n", hr);
1941
1942 hr = IXmlWriter_Flush(writer);
1943 ok(hr == S_OK, "got 0x%08x\n", hr);
1944
1946 "<b>a&lt;&amp;\"&gt;=");
1947 IStream_Release(stream);
1948
1949 stream = writer_set_output(writer);
1950
1951 hr = write_start_element(writer, NULL, "b", NULL);
1952 ok(hr == S_OK, "got 0x%08x\n", hr);
1953
1954 hr = write_string(writer, NULL);
1955 ok(hr == S_OK, "got 0x%08x\n", hr);
1956
1957 hr = IXmlWriter_Flush(writer);
1958 ok(hr == S_OK, "got 0x%08x\n", hr);
1959
1961 "<b");
1962
1963 hr = write_string(writer, "");
1964 ok(hr == S_OK, "got 0x%08x\n", hr);
1965
1966 hr = IXmlWriter_Flush(writer);
1967 ok(hr == S_OK, "got 0x%08x\n", hr);
1968
1970 "<b>");
1971
1972 IStream_Release(stream);
1973 IXmlWriter_Release(writer);
1974
1975 /* With indentation */
1976 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
1977 ok(hr == S_OK, "Failed to create a writer, hr %#x.\n", hr);
1978
1979 stream = writer_set_output(writer);
1980
1982
1983 hr = write_start_element(writer, NULL, "a", NULL);
1984 ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr);
1985
1986 hr = write_start_element(writer, NULL, "b", NULL);
1987 ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr);
1988
1989 hr = write_string(writer, "text");
1990 ok(hr == S_OK, "Failed to write a string, hr %#x.\n", hr);
1991
1992 hr = IXmlWriter_Flush(writer);
1993 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
1994
1996 "<a>\r\n"
1997 " <b>text");
1998
1999 hr = IXmlWriter_WriteFullEndElement(writer);
2000 ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr);
2001
2002 hr = IXmlWriter_Flush(writer);
2003 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
2004
2006 "<a>\r\n"
2007 " <b>text</b>");
2008
2009 hr = IXmlWriter_WriteFullEndElement(writer);
2010 ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr);
2011
2012 hr = IXmlWriter_Flush(writer);
2013 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
2014
2016 "<a>\r\n"
2017 " <b>text</b>\r\n"
2018 "</a>");
2019
2020 IStream_Release(stream);
2021
2022 stream = writer_set_output(writer);
2023
2024 hr = write_start_element(writer, NULL, "a", NULL);
2025 ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr);
2026
2027 hr = write_start_element(writer, NULL, "b", NULL);
2028 ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr);
2029
2030 hr = IXmlWriter_WriteEndElement(writer);
2031 ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr);
2032
2033 hr = IXmlWriter_Flush(writer);
2034 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
2035
2037 "<a>\r\n"
2038 " <b />");
2039
2040 hr = write_start_element(writer, NULL, "c", NULL);
2041 ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr);
2042
2043 hr = write_attribute_string(writer, NULL, "attr", NULL, "value");
2044 ok(hr == S_OK, "Failed to write attribute string, hr %#x.\n", hr);
2045
2046 hr = IXmlWriter_Flush(writer);
2047 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
2048
2050 "<a>\r\n"
2051 " <b />\r\n"
2052 " <c attr=\"value\"");
2053
2054 hr = write_string(writer, "text");
2055 ok(hr == S_OK, "Failed to write a string, hr %#x.\n", hr);
2056
2057 hr = IXmlWriter_Flush(writer);
2058 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
2059
2061 "<a>\r\n"
2062 " <b />\r\n"
2063 " <c attr=\"value\">text");
2064
2065 hr = IXmlWriter_WriteEndElement(writer);
2066 ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr);
2067
2068 hr = IXmlWriter_Flush(writer);
2069 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
2070
2072 "<a>\r\n"
2073 " <b />\r\n"
2074 " <c attr=\"value\">text</c>");
2075
2076 hr = write_start_element(writer, NULL, "d", NULL);
2077 ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr);
2078
2079 hr = write_string(writer, "");
2080 ok(hr == S_OK, "Failed to write a string, hr %#x.\n", hr);
2081
2082 hr = IXmlWriter_WriteEndElement(writer);
2083 ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr);
2084
2085 hr = IXmlWriter_Flush(writer);
2086 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
2087
2089 "<a>\r\n"
2090 " <b />\r\n"
2091 " <c attr=\"value\">text</c>\r\n"
2092 " <d></d>");
2093
2094 hr = IXmlWriter_WriteEndElement(writer);
2095 ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr);
2096
2097 hr = IXmlWriter_Flush(writer);
2098 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
2099
2101 "<a>\r\n"
2102 " <b />\r\n"
2103 " <c attr=\"value\">text</c>\r\n"
2104 " <d></d>\r\n"
2105 "</a>");
2106
2107 IXmlWriter_Release(writer);
2108 IStream_Release(stream);
2109}
2110
2111static HRESULT write_doctype(IXmlWriter *writer, const char *name, const char *pubid, const char *sysid,
2112 const char *subset)
2113{
2114 WCHAR *nameW, *pubidW, *sysidW, *subsetW;
2115 HRESULT hr;
2116
2118 pubidW = strdupAtoW(pubid);
2119 sysidW = strdupAtoW(sysid);
2120 subsetW = strdupAtoW(subset);
2121
2122 hr = IXmlWriter_WriteDocType(writer, nameW, pubidW, sysidW, subsetW);
2123
2125 heap_free(pubidW);
2126 heap_free(sysidW);
2127 heap_free(subsetW);
2128
2129 return hr;
2130}
2131
2132static void test_WriteDocType(void)
2133{
2134 static const struct
2135 {
2136 const char *name;
2137 const char *pubid;
2138 const char *sysid;
2139 const char *subset;
2140 const char *output;
2141 }
2142 doctype_tests[] =
2143 {
2144 { "a", "", NULL, NULL, "<!DOCTYPE a PUBLIC \"\" \"\">" },
2145 { "a", NULL, NULL, NULL, "<!DOCTYPE a>" },
2146 { "a", NULL, "", NULL, "<!DOCTYPE a SYSTEM \"\">" },
2147 { "a", "", "", NULL, "<!DOCTYPE a PUBLIC \"\" \"\">" },
2148 { "a", "pubid", "", NULL, "<!DOCTYPE a PUBLIC \"pubid\" \"\">" },
2149 { "a", "pubid", NULL, NULL, "<!DOCTYPE a PUBLIC \"pubid\" \"\">" },
2150 { "a", "", "sysid", NULL, "<!DOCTYPE a PUBLIC \"\" \"sysid\">" },
2151 { "a", NULL, NULL, "", "<!DOCTYPE a []>" },
2152 { "a", NULL, NULL, "subset", "<!DOCTYPE a [subset]>" },
2153 { "a", "", NULL, "subset", "<!DOCTYPE a PUBLIC \"\" \"\" [subset]>" },
2154 { "a", NULL, "", "subset", "<!DOCTYPE a SYSTEM \"\" [subset]>" },
2155 { "a", "", "", "subset", "<!DOCTYPE a PUBLIC \"\" \"\" [subset]>" },
2156 { "a", "pubid", NULL, "subset", "<!DOCTYPE a PUBLIC \"pubid\" \"\" [subset]>" },
2157 { "a", "pubid", "", "subset", "<!DOCTYPE a PUBLIC \"pubid\" \"\" [subset]>" },
2158 { "a", NULL, "sysid", "subset", "<!DOCTYPE a SYSTEM \"sysid\" [subset]>" },
2159 { "a", "", "sysid", "subset", "<!DOCTYPE a PUBLIC \"\" \"sysid\" [subset]>" },
2160 { "a", "pubid", "sysid", "subset", "<!DOCTYPE a PUBLIC \"pubid\" \"sysid\" [subset]>" },
2161 };
2162 static const WCHAR pubidW[] = {'p',0x100,'i','d',0};
2163 static const WCHAR nameW[] = {'-','a',0};
2164 static const WCHAR emptyW[] = { 0 };
2165 IXmlWriter *writer;
2166 IStream *stream;
2167 unsigned int i;
2168 HRESULT hr;
2169
2170 hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
2171 ok(hr == S_OK, "Failed to create writer instance, hr %#x.\n", hr);
2172
2173 stream = writer_set_output(writer);
2174
2175 hr = IXmlWriter_WriteDocType(writer, NULL, NULL, NULL, NULL);
2176 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2177
2178 hr = IXmlWriter_WriteDocType(writer, emptyW, NULL, NULL, NULL);
2179 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2180
2181 /* Name validation. */
2182 hr = IXmlWriter_WriteDocType(writer, nameW, NULL, NULL, NULL);
2183 ok(hr == WC_E_NAMECHARACTER, "Unexpected hr %#x.\n", hr);
2184
2185 /* Pubid validation. */
2186 hr = IXmlWriter_WriteDocType(writer, aW, pubidW, NULL, NULL);
2187 ok(hr == WC_E_PUBLICID, "Unexpected hr %#x.\n", hr);
2188
2189 IStream_Release(stream);
2190
2191 for (i = 0; i < ARRAY_SIZE(doctype_tests); i++)
2192 {
2193 stream = writer_set_output(writer);
2194
2195 hr = write_doctype(writer, doctype_tests[i].name, doctype_tests[i].pubid, doctype_tests[i].sysid,
2196 doctype_tests[i].subset);
2197 ok(hr == S_OK, "%u: failed to write doctype, hr %#x.\n", i, hr);
2198
2199 hr = IXmlWriter_Flush(writer);
2200 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
2201
2202 CHECK_OUTPUT(stream, doctype_tests[i].output);
2203
2204 hr = write_doctype(writer, doctype_tests[i].name, doctype_tests[i].pubid, doctype_tests[i].sysid,
2205 doctype_tests[i].subset);
2206 ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#x.\n", hr);
2207
2208 IStream_Release(stream);
2209 }
2210
2211 IXmlWriter_Release(writer);
2212}
2213
2215{
2223 test_flush();
2225 test_bom();
2229 test_WriteRaw();
2236}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
static const WCHAR nameW[]
Definition: main.c:46
#define ARRAY_SIZE(A)
Definition: main.h:33
const GUID IID_IUnknown
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
const char * wine_dbgstr_wn(const WCHAR *str, int n)
Definition: compat.c:367
#define CP_ACP
Definition: compat.h:109
#define MultiByteToWideChar
Definition: compat.h:110
static const WCHAR valueW[]
Definition: object.c:48
HRESULT WINAPI GetHGlobalFromStream(IStream *pstm, HGLOBAL *phglobal)
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
static const WCHAR versionW[]
Definition: name.c:52
static const WCHAR piW[]
Definition: reader.c:98
static const WCHAR commentW[]
Definition: reader.c:97
static const WCHAR usasciiW[]
Definition: reader.c:89
HRESULT WINAPI CreateXmlWriter(REFIID riid, void **obj, IMalloc *imalloc)
Definition: writer.c:1897
HRESULT WINAPI CreateXmlWriterOutputWithEncodingCodePage(IUnknown *stream, IMalloc *imalloc, UINT codepage, IXmlWriterOutput **out)
Definition: writer.c:1997
HRESULT WINAPI CreateXmlWriterOutputWithEncodingName(IUnknown *stream, IMalloc *imalloc, const WCHAR *encoding, IXmlWriterOutput **out)
Definition: writer.c:1976
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define local
Definition: zutil.h:30
GLsizeiptr size
Definition: glext.h:5919
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
static const WCHAR emptyW[]
Definition: navigate.c:40
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
static PVOID ptr
Definition: dispmode.c:27
BOOL todo
Definition: filedlg.c:313
BOOL expected
Definition: store.c:2063
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
#define todo_wine_if(is_todo)
Definition: custom.c:76
#define todo_wine
Definition: custom.c:79
static const WCHAR dummyW[]
Definition: directory.c:79
const char * uri
Definition: sec_mgr.c:1588
WCHAR strW[12]
Definition: clipboard.c:2029
ssize_t pread(int fd, void *buf, size_t count, off_t offset)
static HRESULT write_element_string(IXmlWriter *writer, const char *prefix, const char *local, const char *uri, const char *value)
Definition: writer.c:858
static void test_writer_state(void)
Definition: writer.c:1424
static void test_writeroutput(void)
Definition: writer.c:419
static HRESULT WINAPI teststream_QueryInterface(ISequentialStream *iface, REFIID riid, void **obj)
Definition: writer.c:241
static void test_WriteStartElement(void)
Definition: writer.c:893
static HRESULT write_start_element(IXmlWriter *writer, const char *prefix, const char *local, const char *uri)
Definition: writer.c:839
static void check_output_raw(IStream *stream, const void *expected, SIZE_T size, int line)
Definition: writer.c:52
static void test_indentation(void)
Definition: writer.c:1512
static HRESULT WINAPI teststream_Write(ISequentialStream *iface, const void *pv, ULONG cb, ULONG *written)
Definition: writer.c:270
static void test_writestartdocument(void)
Definition: writer.c:526
static void test_writeenddocument(void)
Definition: writer.c:1210
static ISequentialStream teststream
Definition: writer.c:286
static HRESULT write_doctype(IXmlWriter *writer, const char *name, const char *pubid, const char *sysid, const char *subset)
Definition: writer.c:2111
static ULONG WINAPI teststream_AddRef(ISequentialStream *iface)
Definition: writer.c:253
static const IUnknownVtbl testoutputvtbl
Definition: writer.c:233
static IUnknown testoutput
Definition: writer.c:239
static void _expect_ref(IUnknown *obj, ULONG ref, int line)
Definition: writer.c:44
static HRESULT write_attribute_string(IXmlWriter *writer, const char *prefix, const char *local, const char *uri, const char *value)
Definition: writer.c:1584
static HRESULT write_string(IXmlWriter *writer, const char *str)
Definition: writer.c:879
static void check_output(IStream *stream, const char *expected, BOOL todo, int line)
Definition: writer.c:73
static void test_WriteComment(void)
Definition: writer.c:1269
static void test_omitxmldeclaration(void)
Definition: writer.c:652
static void test_invalid_output_encoding(IXmlWriter *writer, IUnknown *output)
Definition: writer.c:340
#define CHECK_OUTPUT_TODO(stream, expected)
Definition: writer.c:98
static void test_WriteRaw(void)
Definition: writer.c:1366
static ULONG WINAPI testoutput_Release(IUnknown *iface)
Definition: writer.c:228
static const ISequentialStreamVtbl teststreamvtbl
Definition: writer.c:277
static void test_bom(void)
Definition: writer.c:727
static IStream * writer_set_output(IXmlWriter *writer)
Definition: writer.c:197
static void test_flush(void)
Definition: writer.c:622
static void test_WriteDocType(void)
Definition: writer.c:2132
static void test_WriteString(void)
Definition: writer.c:1904
#define CHECK_OUTPUT_RAW(stream, expected, size)
Definition: writer.c:99
static ULONG WINAPI teststream_Release(ISequentialStream *iface)
Definition: writer.c:258
static void test_WriteElementString(void)
Definition: writer.c:1036
static HRESULT WINAPI teststream_Read(ISequentialStream *iface, void *pv, ULONG cb, ULONG *pread)
Definition: writer.c:263
#define EXPECT_REF(obj, ref)
Definition: writer.c:43
#define CHECK_OUTPUT(stream, expected)
Definition: writer.c:97
static void test_WriteCData(void)
Definition: writer.c:1315
static const WCHAR aW[]
Definition: writer.c:41
static ULONG WINAPI testoutput_AddRef(IUnknown *iface)
Definition: writer.c:223
static void test_WriteFullEndElement(void)
Definition: writer.c:1796
static WCHAR * strdupAtoW(const char *str)
Definition: writer.c:101
static ULONG g_write_len
Definition: writer.c:269
static void check_writer_state(IXmlWriter *writer, HRESULT exp_hr)
Definition: writer.c:123
static void test_WriteAttributeString(void)
Definition: writer.c:1605
static void writer_set_property(IXmlWriter *writer, XmlWriterProperty property)
Definition: writer.c:114
static void test_WriteCharEntity(void)
Definition: writer.c:1864
static HRESULT WINAPI testoutput_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
Definition: writer.c:211
static void test_WriteEndElement(void)
Definition: writer.c:1178
static void test_writer_create(void)
Definition: writer.c:288
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
static const WCHAR xmlW[]
Definition: mxnamespace.c:61
static const WCHAR utf16W[]
Definition: mxwriter.c:85
#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
const WCHAR * str
#define CP_UTF8
Definition: nls.h:20
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
HRESULT hr
Definition: shlfolder.c:183
Definition: parser.c:49
Definition: name.c:39
Definition: send.c:48
Definition: parse.h:23
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:94
int ret
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_UNEXPECTED
Definition: winerror.h:2456
@ MX_E_ENCODING
Definition: xmllite.idl:142
@ WR_E_XMLPREFIXDECLARATION
Definition: xmllite.idl:214
@ WR_E_INVALIDXMLSPACE
Definition: xmllite.idl:218
@ 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
@ WR_E_XMLNSPREFIXDECLARATION
Definition: xmllite.idl:213
@ WR_E_NSPREFIXWITHEMPTYNSURI
Definition: xmllite.idl:211
@ WC_E_PUBLICID
Definition: xmllite.idl:179
@ WR_E_INVALIDACTION
Definition: xmllite.idl:219
XmlWriterProperty
Definition: xmllite.idl:244
@ XmlWriterProperty_ConformanceLevel
Definition: xmllite.idl:249
@ XmlWriterProperty_OmitXmlDeclaration
Definition: xmllite.idl:248
@ XmlWriterProperty_ByteOrderMark
Definition: xmllite.idl:247
@ XmlWriterProperty_Indent
Definition: xmllite.idl:246
@ XmlConformanceLevel_Document
Definition: xmllite.idl:111
@ XmlConformanceLevel_Auto
Definition: xmllite.idl:109
@ XmlStandalone_Omit
Definition: xmllite.idl:237
@ XmlStandalone_Yes
Definition: xmllite.idl:238
__wchar_t WCHAR
Definition: xmlstorage.h:180