2 * XMLLite IXmlWriter tests
4 * Copyright 2011 (C) Alistair Leslie-Hughes
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.
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.
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
34 #include "wine/test.h"
37 DEFINE_GUID(IID_IXmlWriterOutput
, 0xc1131708, 0x0f59, 0x477f, 0x93, 0x59, 0x7d, 0x33, 0x24, 0x51, 0xbc, 0x1a);
39 static const WCHAR aW
[] = {'a',0};
41 #define EXPECT_REF(obj, ref) _expect_ref((IUnknown *)obj, ref, __LINE__)
42 static void _expect_ref(IUnknown
*obj
, ULONG ref
, int line
)
46 refcount
= IUnknown_Release(obj
);
47 ok_(__FILE__
, line
)(refcount
== ref
, "expected refcount %d, got %d\n", ref
, refcount
);
50 static void check_output_raw(IStream
*stream
, const void *expected
, SIZE_T size
, int line
)
57 hr
= GetHGlobalFromStream(stream
, &hglobal
);
58 ok_(__FILE__
, line
)(hr
== S_OK
, "Failed to get the stream handle, hr %#x.\n", hr
);
60 content_size
= GlobalSize(hglobal
);
61 ok_(__FILE__
, line
)(size
<= content_size
, "Unexpected test output size.\n");
62 ptr
= GlobalLock(hglobal
);
63 if (size
<= content_size
)
64 ok_(__FILE__
, line
)(!memcmp(expected
, ptr
, size
), "Unexpected output content.\n");
66 GlobalUnlock(hglobal
);
69 static void check_output(IStream
*stream
, const char *expected
, BOOL todo
, int line
)
71 int len
= strlen(expected
), size
;
76 hr
= GetHGlobalFromStream(stream
, &hglobal
);
77 ok_(__FILE__
, line
)(hr
== S_OK
, "got 0x%08x\n", hr
);
79 size
= GlobalSize(hglobal
);
80 ptr
= GlobalLock(hglobal
);
85 ok_(__FILE__
, line
)(0, "data size mismatch, expected %u, got %u\n", len
, size
);
86 ok_(__FILE__
, line
)(0, "got |%s|, expected |%s|\n", ptr
, expected
);
89 ok_(__FILE__
, line
)(!strncmp(ptr
, expected
, len
), "got |%s|, expected |%s|\n", ptr
, expected
);
91 GlobalUnlock(hglobal
);
93 #define CHECK_OUTPUT(stream, expected) check_output(stream, expected, FALSE, __LINE__)
94 #define CHECK_OUTPUT_TODO(stream, expected) check_output(stream, expected, TRUE, __LINE__)
95 #define CHECK_OUTPUT_RAW(stream, expected, size) check_output_raw(stream, expected, size, __LINE__)
97 static void writer_set_property(IXmlWriter
*writer
, XmlWriterProperty property
)
101 hr
= IXmlWriter_SetProperty(writer
, property
, TRUE
);
102 ok(hr
== S_OK
, "Failed to set writer property, hr %#x.\n", hr
);
105 /* used to test all Write* methods for consistent error state */
106 static void check_writer_state(IXmlWriter
*writer
, HRESULT exp_hr
)
108 static const WCHAR aW
[] = {'a',0};
111 /* FIXME: add WriteAttributes */
113 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, aW
, NULL
, aW
);
114 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
116 hr
= IXmlWriter_WriteCData(writer
, aW
);
117 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
119 hr
= IXmlWriter_WriteCharEntity(writer
, aW
[0]);
120 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
122 hr
= IXmlWriter_WriteChars(writer
, aW
, 1);
123 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
125 hr
= IXmlWriter_WriteComment(writer
, aW
);
126 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
128 /* FIXME: add WriteDocType */
130 hr
= IXmlWriter_WriteElementString(writer
, NULL
, aW
, NULL
, aW
);
131 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
133 hr
= IXmlWriter_WriteEndDocument(writer
);
134 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
136 hr
= IXmlWriter_WriteEndElement(writer
);
137 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
139 hr
= IXmlWriter_WriteEntityRef(writer
, aW
);
140 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
142 hr
= IXmlWriter_WriteFullEndElement(writer
);
143 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
145 hr
= IXmlWriter_WriteName(writer
, aW
);
146 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
148 hr
= IXmlWriter_WriteNmToken(writer
, aW
);
149 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
151 /* FIXME: add WriteNode */
152 /* FIXME: add WriteNodeShallow */
154 hr
= IXmlWriter_WriteProcessingInstruction(writer
, aW
, aW
);
155 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
157 hr
= IXmlWriter_WriteQualifiedName(writer
, aW
, NULL
);
158 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
160 hr
= IXmlWriter_WriteRaw(writer
, aW
);
161 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
163 hr
= IXmlWriter_WriteRawChars(writer
, aW
, 1);
164 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
166 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
167 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
169 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
170 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
172 hr
= IXmlWriter_WriteString(writer
, aW
);
173 ok(hr
== exp_hr
, "got 0x%08x, expected 0x%08x\n", hr
, exp_hr
);
175 /* FIXME: add WriteSurrogateCharEntity */
176 /* FIXME: add WriteWhitespace */
179 static IStream
*writer_set_output(IXmlWriter
*writer
)
184 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
185 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
187 hr
= IXmlWriter_SetOutput(writer
, (IUnknown
*)stream
);
188 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
193 static HRESULT WINAPI
testoutput_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
195 if (IsEqualGUID(riid
, &IID_IUnknown
)) {
200 ok(0, "unknown riid=%s\n", wine_dbgstr_guid(riid
));
201 return E_NOINTERFACE
;
205 static ULONG WINAPI
testoutput_AddRef(IUnknown
*iface
)
210 static ULONG WINAPI
testoutput_Release(IUnknown
*iface
)
215 static const IUnknownVtbl testoutputvtbl
= {
216 testoutput_QueryInterface
,
221 static IUnknown testoutput
= { &testoutputvtbl
};
223 static HRESULT WINAPI
teststream_QueryInterface(ISequentialStream
*iface
, REFIID riid
, void **obj
)
225 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_ISequentialStream
))
232 return E_NOINTERFACE
;
235 static ULONG WINAPI
teststream_AddRef(ISequentialStream
*iface
)
240 static ULONG WINAPI
teststream_Release(ISequentialStream
*iface
)
245 static HRESULT WINAPI
teststream_Read(ISequentialStream
*iface
, void *pv
, ULONG cb
, ULONG
*pread
)
247 ok(0, "unexpected call\n");
251 static ULONG g_write_len
;
252 static HRESULT WINAPI
teststream_Write(ISequentialStream
*iface
, const void *pv
, ULONG cb
, ULONG
*written
)
259 static const ISequentialStreamVtbl teststreamvtbl
=
261 teststream_QueryInterface
,
268 static ISequentialStream teststream
= { &teststreamvtbl
};
270 static void test_writer_create(void)
280 CreateXmlWriter(&IID_IXmlWriter
, NULL
, NULL
);
281 CreateXmlWriter(NULL
, (void**)&writer
, NULL
);
284 hr
= CreateXmlWriter(&IID_IStream
, (void **)&unk
, NULL
);
285 ok(hr
== E_NOINTERFACE
, "got %08x\n", hr
);
287 hr
= CreateXmlWriter(&IID_IUnknown
, (void **)&unk
, NULL
);
288 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
289 hr
= IUnknown_QueryInterface(unk
, &IID_IXmlWriter
, (void **)&writer
);
290 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
291 ok(unk
== (IUnknown
*)writer
, "unexpected interface pointer\n");
292 IUnknown_Release(unk
);
293 IXmlWriter_Release(writer
);
295 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
296 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
298 /* check default properties values */
300 hr
= IXmlWriter_GetProperty(writer
, XmlWriterProperty_ByteOrderMark
, &value
);
301 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
302 ok(value
== TRUE
, "got %ld\n", value
);
305 hr
= IXmlWriter_GetProperty(writer
, XmlWriterProperty_Indent
, &value
);
306 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
307 ok(value
== FALSE
, "got %ld\n", value
);
310 hr
= IXmlWriter_GetProperty(writer
, XmlWriterProperty_OmitXmlDeclaration
, &value
);
311 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
312 ok(value
== FALSE
, "got %ld\n", value
);
314 value
= XmlConformanceLevel_Auto
;
315 hr
= IXmlWriter_GetProperty(writer
, XmlWriterProperty_ConformanceLevel
, &value
);
316 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
317 ok(value
== XmlConformanceLevel_Document
, "got %ld\n", value
);
319 IXmlWriter_Release(writer
);
322 static void test_invalid_output_encoding(IXmlWriter
*writer
, IUnknown
*output
)
326 hr
= IXmlWriter_SetOutput(writer
, output
);
327 ok(hr
== S_OK
, "Failed to set output, hr %#x.\n", hr
);
329 /* TODO: WriteAttributes */
331 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, aW
, NULL
, aW
);
332 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
334 hr
= IXmlWriter_WriteCData(writer
, aW
);
335 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
337 hr
= IXmlWriter_WriteCharEntity(writer
, 0x100);
338 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
340 hr
= IXmlWriter_WriteChars(writer
, aW
, 1);
341 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
343 hr
= IXmlWriter_WriteComment(writer
, aW
);
344 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
346 /* TODO: WriteDocType */
348 hr
= IXmlWriter_WriteElementString(writer
, NULL
, aW
, NULL
, NULL
);
349 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
351 hr
= IXmlWriter_WriteEndDocument(writer
);
352 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
354 hr
= IXmlWriter_WriteEndElement(writer
);
355 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
357 hr
= IXmlWriter_WriteEntityRef(writer
, aW
);
358 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
360 hr
= IXmlWriter_WriteFullEndElement(writer
);
361 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
363 hr
= IXmlWriter_WriteName(writer
, aW
);
364 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
366 hr
= IXmlWriter_WriteNmToken(writer
, aW
);
367 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
369 /* TODO: WriteNode */
370 /* TODO: WriteNodeShallow */
372 hr
= IXmlWriter_WriteProcessingInstruction(writer
, aW
, aW
);
373 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
375 hr
= IXmlWriter_WriteQualifiedName(writer
, aW
, NULL
);
376 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
378 hr
= IXmlWriter_WriteRaw(writer
, aW
);
379 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
381 hr
= IXmlWriter_WriteRawChars(writer
, aW
, 1);
382 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
384 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
385 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
387 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
388 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
390 hr
= IXmlWriter_WriteString(writer
, aW
);
391 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#x.\n", hr
);
393 /* TODO: WriteSurrogateCharEntity */
394 /* ًُُTODO: WriteWhitespace */
396 hr
= IXmlWriter_Flush(writer
);
397 ok(hr
== S_OK
, "Failed to flush, hr %#x.\n", hr
);
400 static void test_writeroutput(void)
402 static const WCHAR utf16W
[] = {'u','t','f','-','1','6',0};
403 static const WCHAR usasciiW
[] = {'u','s','-','a','s','c','i','i',0};
404 static const WCHAR dummyW
[] = {'d','u','m','m','y',0};
405 static const WCHAR utf16_outputW
[] = {0xfeff,'<','a'};
406 IXmlWriterOutput
*output
;
413 hr
= CreateXmlWriterOutputWithEncodingName(&testoutput
, NULL
, NULL
, &output
);
414 ok(hr
== S_OK
, "got %08x\n", hr
);
415 EXPECT_REF(output
, 1);
416 IUnknown_Release(output
);
418 hr
= CreateXmlWriterOutputWithEncodingName(&testoutput
, NULL
, utf16W
, &output
);
419 ok(hr
== S_OK
, "got %08x\n", hr
);
421 hr
= IUnknown_QueryInterface(output
, &IID_IXmlWriterOutput
, (void**)&unk
);
422 ok(hr
== S_OK
, "got %08x\n", hr
);
424 ok(unk
!= NULL
&& unk
!= output
, "got %p, output %p\n", unk
, output
);
425 EXPECT_REF(output
, 2);
426 /* releasing 'unk' crashes on native */
427 IUnknown_Release(output
);
428 EXPECT_REF(output
, 1);
429 IUnknown_Release(output
);
432 hr
= CreateXmlWriterOutputWithEncodingCodePage(&testoutput
, NULL
, ~0u, &output
);
433 ok(hr
== S_OK
, "got %08x\n", hr
);
434 IUnknown_Release(output
);
436 hr
= CreateXmlWriterOutputWithEncodingCodePage(&testoutput
, NULL
, CP_UTF8
, &output
);
437 ok(hr
== S_OK
, "got %08x\n", hr
);
439 hr
= IUnknown_QueryInterface(output
, &IID_IXmlWriterOutput
, (void**)&unk
);
440 ok(hr
== S_OK
, "got %08x\n", hr
);
441 ok(unk
!= NULL
, "got %p\n", unk
);
442 /* releasing 'unk' crashes on native */
443 IUnknown_Release(output
);
444 IUnknown_Release(output
);
446 /* create with us-ascii */
448 hr
= CreateXmlWriterOutputWithEncodingName(&testoutput
, NULL
, usasciiW
, &output
);
449 ok(hr
== S_OK
, "got %08x\n", hr
);
450 IUnknown_Release(output
);
452 /* Output with codepage 1200. */
453 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
454 ok(hr
== S_OK
, "Failed to create writer, hr %#x.\n", hr
);
456 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
457 ok(hr
== S_OK
, "Failed to create stream, hr %#x.\n", hr
);
459 hr
= CreateXmlWriterOutputWithEncodingCodePage((IUnknown
*)stream
, NULL
, 1200, &output
);
460 ok(hr
== S_OK
, "Failed to create writer output, hr %#x.\n", hr
);
462 hr
= IXmlWriter_SetOutput(writer
, output
);
463 ok(hr
== S_OK
, "Failed to set writer output, hr %#x.\n", hr
);
465 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
466 ok(hr
== S_OK
, "Write failed, hr %#x.\n", hr
);
468 hr
= IXmlWriter_Flush(writer
);
469 ok(hr
== S_OK
, "Failed to flush, hr %#x.\n", hr
);
471 CHECK_OUTPUT_RAW(stream
, utf16_outputW
, sizeof(utf16_outputW
));
473 IStream_Release(stream
);
475 /* Create output with meaningless code page value. */
476 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
477 ok(hr
== S_OK
, "Failed to create stream, hr %#x.\n", hr
);
480 hr
= CreateXmlWriterOutputWithEncodingCodePage((IUnknown
*)stream
, NULL
, ~0u, &output
);
481 ok(hr
== S_OK
, "Failed to create writer output, hr %#x.\n", hr
);
483 test_invalid_output_encoding(writer
, output
);
484 CHECK_OUTPUT(stream
, "");
486 IStream_Release(stream
);
487 IUnknown_Release(output
);
489 /* Same, with invalid encoding name. */
490 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
491 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
494 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, dummyW
, &output
);
495 ok(hr
== S_OK
, "got %08x\n", hr
);
497 test_invalid_output_encoding(writer
, output
);
498 CHECK_OUTPUT(stream
, "");
500 IStream_Release(stream
);
501 IUnknown_Release(output
);
503 IXmlWriter_Release(writer
);
506 static void test_writestartdocument(void)
508 static const char fullprolog
[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
509 static const char *prologversion2
= "<?xml version=\"1.0\" encoding=\"uS-asCii\"?>";
510 static const char prologversion
[] = "<?xml version=\"1.0\"?>";
511 static const WCHAR versionW
[] = {'v','e','r','s','i','o','n','=','"','1','.','0','"',0};
512 static const WCHAR usasciiW
[] = {'u','S','-','a','s','C','i','i',0};
513 static const WCHAR xmlW
[] = {'x','m','l',0};
514 IXmlWriterOutput
*output
;
519 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
520 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
523 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
524 ok(hr
== E_UNEXPECTED
, "got 0x%08x\n", hr
);
526 hr
= IXmlWriter_WriteProcessingInstruction(writer
, xmlW
, versionW
);
527 ok(hr
== E_UNEXPECTED
, "got 0x%08x\n", hr
);
529 hr
= IXmlWriter_Flush(writer
);
530 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
532 stream
= writer_set_output(writer
);
534 /* nothing written yet */
535 hr
= IXmlWriter_Flush(writer
);
536 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
538 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
539 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
541 hr
= IXmlWriter_Flush(writer
);
542 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
544 CHECK_OUTPUT(stream
, fullprolog
);
547 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
548 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
549 IStream_Release(stream
);
551 /* now add PI manually, and try to start a document */
552 stream
= writer_set_output(writer
);
554 hr
= IXmlWriter_WriteProcessingInstruction(writer
, xmlW
, versionW
);
555 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
557 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
558 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
560 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
561 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
563 /* another attempt to add 'xml' PI */
564 hr
= IXmlWriter_WriteProcessingInstruction(writer
, xmlW
, versionW
);
565 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
567 hr
= IXmlWriter_Flush(writer
);
568 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
570 CHECK_OUTPUT(stream
, prologversion
);
572 IStream_Release(stream
);
573 IXmlWriter_Release(writer
);
575 /* create with us-ascii */
576 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
577 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
580 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, usasciiW
, &output
);
581 ok(hr
== S_OK
, "got %08x\n", hr
);
583 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
584 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
586 hr
= IXmlWriter_SetOutput(writer
, output
);
587 ok(hr
== S_OK
, "got %08x\n", hr
);
589 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
590 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
592 hr
= IXmlWriter_Flush(writer
);
593 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
595 CHECK_OUTPUT(stream
, prologversion2
);
597 IStream_Release(stream
);
598 IXmlWriter_Release(writer
);
599 IUnknown_Release(output
);
602 static void test_flush(void)
607 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
608 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
610 hr
= IXmlWriter_SetOutput(writer
, (IUnknown
*)&teststream
);
611 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
613 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
614 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
617 hr
= IXmlWriter_Flush(writer
);
618 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
619 ok(g_write_len
> 0, "got %d\n", g_write_len
);
622 hr
= IXmlWriter_Flush(writer
);
623 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
624 ok(g_write_len
== 0, "got %d\n", g_write_len
);
626 /* Release() flushes too */
628 IXmlWriter_Release(writer
);
629 ok(g_write_len
== 0, "got %d\n", g_write_len
);
632 static void test_omitxmldeclaration(void)
634 static const char prologversion
[] = "<?xml version=\"1.0\"?>";
635 static const WCHAR versionW
[] = {'v','e','r','s','i','o','n','=','"','1','.','0','"',0};
636 static const WCHAR xmlW
[] = {'x','m','l',0};
643 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
644 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
646 stream
= writer_set_output(writer
);
648 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
650 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
651 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
653 hr
= IXmlWriter_Flush(writer
);
654 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
656 hr
= GetHGlobalFromStream(stream
, &hglobal
);
657 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
659 ptr
= GlobalLock(hglobal
);
660 ok(!ptr
, "got %p\n", ptr
);
661 GlobalUnlock(hglobal
);
664 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
665 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
667 IStream_Release(stream
);
669 /* now add PI manually, and try to start a document */
670 stream
= writer_set_output(writer
);
672 hr
= IXmlWriter_WriteProcessingInstruction(writer
, xmlW
, versionW
);
673 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
675 hr
= IXmlWriter_Flush(writer
);
676 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
678 CHECK_OUTPUT(stream
, prologversion
);
680 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
681 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
683 hr
= IXmlWriter_Flush(writer
);
684 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
686 CHECK_OUTPUT(stream
, prologversion
);
688 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
689 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
691 hr
= IXmlWriter_Flush(writer
);
692 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
694 CHECK_OUTPUT(stream
, prologversion
);
696 /* another attempt to add 'xml' PI */
697 hr
= IXmlWriter_WriteProcessingInstruction(writer
, xmlW
, versionW
);
698 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
700 hr
= IXmlWriter_Flush(writer
);
701 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
703 IStream_Release(stream
);
704 IXmlWriter_Release(writer
);
707 static void test_bom(void)
709 static const WCHAR versionW
[] = {'v','e','r','s','i','o','n','=','"','1','.','0','"',0};
710 static const WCHAR utf16W
[] = {'u','t','f','-','1','6',0};
711 static const WCHAR xmlW
[] = {'x','m','l',0};
712 IXmlWriterOutput
*output
;
719 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
720 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
722 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, utf16W
, &output
);
723 ok(hr
== S_OK
, "got %08x\n", hr
);
725 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
726 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
728 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
730 hr
= IXmlWriter_SetOutput(writer
, output
);
731 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
733 /* BOM is on by default */
734 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
735 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
737 hr
= IXmlWriter_Flush(writer
);
738 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
740 hr
= GetHGlobalFromStream(stream
, &hglobal
);
741 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
743 ptr
= GlobalLock(hglobal
);
744 ok(ptr
[0] == 0xff && ptr
[1] == 0xfe, "got %x,%x\n", ptr
[0], ptr
[1]);
745 GlobalUnlock(hglobal
);
747 IStream_Release(stream
);
748 IUnknown_Release(output
);
751 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
752 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
754 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, utf16W
, &output
);
755 ok(hr
== S_OK
, "got %08x\n", hr
);
757 hr
= IXmlWriter_SetOutput(writer
, output
);
758 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
760 hr
= IXmlWriter_WriteProcessingInstruction(writer
, xmlW
, versionW
);
761 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
763 hr
= IXmlWriter_Flush(writer
);
764 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
766 hr
= GetHGlobalFromStream(stream
, &hglobal
);
767 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
769 ptr
= GlobalLock(hglobal
);
770 ok(ptr
[0] == 0xff && ptr
[1] == 0xfe, "got %x,%x\n", ptr
[0], ptr
[1]);
771 GlobalUnlock(hglobal
);
773 IUnknown_Release(output
);
774 IStream_Release(stream
);
776 /* start with element */
777 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
778 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
780 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, utf16W
, &output
);
781 ok(hr
== S_OK
, "got %08x\n", hr
);
783 hr
= IXmlWriter_SetOutput(writer
, output
);
784 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
786 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
787 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
789 hr
= IXmlWriter_Flush(writer
);
790 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
792 hr
= GetHGlobalFromStream(stream
, &hglobal
);
793 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
795 ptr
= GlobalLock(hglobal
);
796 ok(ptr
[0] == 0xff && ptr
[1] == 0xfe, "got %x,%x\n", ptr
[0], ptr
[1]);
797 GlobalUnlock(hglobal
);
799 IUnknown_Release(output
);
800 IStream_Release(stream
);
802 /* WriteElementString */
803 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
804 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
806 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, utf16W
, &output
);
807 ok(hr
== S_OK
, "got %08x\n", hr
);
809 hr
= IXmlWriter_SetOutput(writer
, output
);
810 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
812 writer_set_property(writer
, XmlWriterProperty_Indent
);
814 hr
= IXmlWriter_WriteElementString(writer
, NULL
, aW
, NULL
, NULL
);
815 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
817 hr
= IXmlWriter_Flush(writer
);
818 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
820 hr
= GetHGlobalFromStream(stream
, &hglobal
);
821 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
823 ptr
= GlobalLock(hglobal
);
824 ok(ptr
[0] == 0xff && ptr
[1] == 0xfe && ptr
[2] == '<', "Unexpected output: %#x,%#x,%#x\n",
825 ptr
[0], ptr
[1], ptr
[2]);
826 GlobalUnlock(hglobal
);
828 IUnknown_Release(output
);
829 IStream_Release(stream
);
831 IXmlWriter_Release(writer
);
834 static void test_writestartelement(void)
836 static const WCHAR valueW
[] = {'v','a','l','u','e',0};
837 static const WCHAR aW
[] = {'a',0};
838 static const WCHAR bW
[] = {'b',0};
843 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
844 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
846 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
847 ok(hr
== E_UNEXPECTED
, "got 0x%08x\n", hr
);
849 stream
= writer_set_output(writer
);
851 hr
= IXmlWriter_WriteStartElement(writer
, aW
, NULL
, NULL
);
852 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
854 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, NULL
, NULL
);
855 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
857 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, NULL
, aW
);
858 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
860 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
861 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
863 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
864 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
866 hr
= IXmlWriter_Flush(writer
);
867 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
869 CHECK_OUTPUT(stream
, "<a");
871 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
872 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
874 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, NULL
, NULL
);
875 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
877 hr
= IXmlWriter_WriteProcessingInstruction(writer
, aW
, aW
);
878 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
880 IStream_Release(stream
);
881 IXmlWriter_Release(writer
);
883 /* WriteElementString */
884 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
885 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
887 hr
= IXmlWriter_WriteElementString(writer
, NULL
, bW
, NULL
, valueW
);
888 ok(hr
== E_UNEXPECTED
, "got 0x%08x\n", hr
);
890 stream
= writer_set_output(writer
);
892 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
893 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
895 hr
= IXmlWriter_WriteElementString(writer
, NULL
, bW
, NULL
, valueW
);
896 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
898 hr
= IXmlWriter_WriteElementString(writer
, NULL
, bW
, NULL
, NULL
);
899 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
901 hr
= IXmlWriter_Flush(writer
);
902 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
905 "<a><b>value</b><b />");
907 IStream_Release(stream
);
908 IXmlWriter_Release(writer
);
911 static void test_writeendelement(void)
913 static const WCHAR aW
[] = {'a',0};
914 static const WCHAR bW
[] = {'b',0};
919 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
920 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
922 stream
= writer_set_output(writer
);
924 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
925 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
927 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, bW
, NULL
);
928 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
930 hr
= IXmlWriter_WriteEndElement(writer
);
931 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
933 hr
= IXmlWriter_WriteEndElement(writer
);
934 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
936 hr
= IXmlWriter_Flush(writer
);
937 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
939 CHECK_OUTPUT(stream
, "<a><b /></a>");
941 IXmlWriter_Release(writer
);
942 IStream_Release(stream
);
945 static void test_writeenddocument(void)
947 static const WCHAR aW
[] = {'a',0};
948 static const WCHAR bW
[] = {'b',0};
955 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
956 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
958 hr
= IXmlWriter_WriteEndDocument(writer
);
959 ok(hr
== E_UNEXPECTED
, "got 0x%08x\n", hr
);
961 stream
= writer_set_output(writer
);
963 /* WriteEndDocument resets it to initial state */
964 hr
= IXmlWriter_WriteEndDocument(writer
);
965 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
967 hr
= IXmlWriter_WriteEndDocument(writer
);
968 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
970 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
971 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
973 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
974 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
976 hr
= IXmlWriter_SetOutput(writer
, (IUnknown
*)stream
);
977 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
979 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
980 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
982 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, bW
, NULL
);
983 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
985 hr
= IXmlWriter_WriteEndDocument(writer
);
986 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
988 hr
= GetHGlobalFromStream(stream
, &hglobal
);
989 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
991 ptr
= GlobalLock(hglobal
);
992 ok(ptr
== NULL
, "got %p\n", ptr
);
994 /* we still need to flush manually, WriteEndDocument doesn't do that */
995 hr
= IXmlWriter_Flush(writer
);
996 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
998 CHECK_OUTPUT(stream
, "<a><b /></a>");
1000 IXmlWriter_Release(writer
);
1001 IStream_Release(stream
);
1004 static void test_WriteComment(void)
1006 static const WCHAR closeW
[] = {'-','-','>',0};
1007 static const WCHAR aW
[] = {'a',0};
1008 static const WCHAR bW
[] = {'b',0};
1013 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1014 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1016 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1018 hr
= IXmlWriter_WriteComment(writer
, aW
);
1019 ok(hr
== E_UNEXPECTED
, "got 0x%08x\n", hr
);
1021 stream
= writer_set_output(writer
);
1023 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1024 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1026 hr
= IXmlWriter_WriteComment(writer
, aW
);
1027 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1029 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, bW
, NULL
);
1030 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1032 hr
= IXmlWriter_WriteComment(writer
, aW
);
1033 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1035 hr
= IXmlWriter_WriteComment(writer
, NULL
);
1036 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1038 hr
= IXmlWriter_WriteComment(writer
, closeW
);
1039 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1041 hr
= IXmlWriter_Flush(writer
);
1042 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1044 CHECK_OUTPUT(stream
, "<!--a--><b><!--a--><!----><!--- ->-->");
1046 IXmlWriter_Release(writer
);
1047 IStream_Release(stream
);
1050 static void test_WriteCData(void)
1052 static const WCHAR closeW
[] = {']',']','>',0};
1053 static const WCHAR close2W
[] = {'a',']',']','>','b',0};
1054 static const WCHAR aW
[] = {'a',0};
1055 static const WCHAR bW
[] = {'b',0};
1060 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1061 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1063 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1065 hr
= IXmlWriter_WriteCData(writer
, aW
);
1066 ok(hr
== E_UNEXPECTED
, "got 0x%08x\n", hr
);
1068 stream
= writer_set_output(writer
);
1070 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, bW
, NULL
);
1071 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1073 hr
= IXmlWriter_WriteCData(writer
, aW
);
1074 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1076 hr
= IXmlWriter_WriteCData(writer
, NULL
);
1077 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1079 hr
= IXmlWriter_WriteCData(writer
, closeW
);
1080 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1082 hr
= IXmlWriter_WriteCData(writer
, close2W
);
1083 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1085 hr
= IXmlWriter_Flush(writer
);
1086 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1088 CHECK_OUTPUT(stream
,
1097 IXmlWriter_Release(writer
);
1098 IStream_Release(stream
);
1101 static void test_WriteRaw(void)
1103 static const WCHAR rawW
[] = {'a','<',':',0};
1104 static const WCHAR aW
[] = {'a',0};
1109 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1110 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1112 hr
= IXmlWriter_WriteRaw(writer
, NULL
);
1113 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1115 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1116 ok(hr
== E_UNEXPECTED
, "got 0x%08x\n", hr
);
1118 stream
= writer_set_output(writer
);
1120 hr
= IXmlWriter_WriteRaw(writer
, NULL
);
1121 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1123 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1124 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1126 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1127 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1129 hr
= IXmlWriter_WriteComment(writer
, rawW
);
1130 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1132 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1133 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1135 hr
= IXmlWriter_WriteElementString(writer
, NULL
, aW
, NULL
, aW
);
1136 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1138 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
1139 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
1141 hr
= IXmlWriter_WriteComment(writer
, rawW
);
1142 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
1144 hr
= IXmlWriter_WriteEndDocument(writer
);
1145 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
1147 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1148 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
1150 hr
= IXmlWriter_Flush(writer
);
1151 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1153 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>a<:a<:<!--a<:-->a<:<a>a</a>");
1155 IXmlWriter_Release(writer
);
1156 IStream_Release(stream
);
1159 static void test_writer_state(void)
1161 static const WCHAR aW
[] = {'a',0};
1166 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1167 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1170 check_writer_state(writer
, E_UNEXPECTED
);
1172 /* set output and call 'wrong' method, WriteEndElement */
1173 stream
= writer_set_output(writer
);
1175 hr
= IXmlWriter_WriteEndElement(writer
);
1176 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
1178 check_writer_state(writer
, WR_E_INVALIDACTION
);
1179 IStream_Release(stream
);
1181 /* WriteAttributeString */
1182 stream
= writer_set_output(writer
);
1184 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, aW
, NULL
, aW
);
1185 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
1187 check_writer_state(writer
, WR_E_INVALIDACTION
);
1188 IStream_Release(stream
);
1190 /* WriteEndDocument */
1191 stream
= writer_set_output(writer
);
1193 hr
= IXmlWriter_WriteEndDocument(writer
);
1194 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
1196 check_writer_state(writer
, WR_E_INVALIDACTION
);
1197 IStream_Release(stream
);
1199 /* WriteFullEndElement */
1200 stream
= writer_set_output(writer
);
1202 hr
= IXmlWriter_WriteFullEndElement(writer
);
1203 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
1205 check_writer_state(writer
, WR_E_INVALIDACTION
);
1206 IStream_Release(stream
);
1209 stream
= writer_set_output(writer
);
1211 hr
= IXmlWriter_WriteCData(writer
, aW
);
1212 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
1214 check_writer_state(writer
, WR_E_INVALIDACTION
);
1215 IStream_Release(stream
);
1218 stream
= writer_set_output(writer
);
1220 hr
= IXmlWriter_WriteName(writer
, aW
);
1221 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
1223 check_writer_state(writer
, WR_E_INVALIDACTION
);
1224 IStream_Release(stream
);
1227 stream
= writer_set_output(writer
);
1229 hr
= IXmlWriter_WriteNmToken(writer
, aW
);
1230 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
1232 check_writer_state(writer
, WR_E_INVALIDACTION
);
1233 IStream_Release(stream
);
1236 stream
= writer_set_output(writer
);
1238 hr
= IXmlWriter_WriteString(writer
, aW
);
1239 ok(hr
== WR_E_INVALIDACTION
, "got 0x%08x\n", hr
);
1241 check_writer_state(writer
, WR_E_INVALIDACTION
);
1242 IStream_Release(stream
);
1244 IXmlWriter_Release(writer
);
1247 static void test_indentation(void)
1249 static const WCHAR commentW
[] = {'c','o','m','m','e','n','t',0};
1250 static const WCHAR aW
[] = {'a',0};
1251 static const WCHAR bW
[] = {'b',0};
1256 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1257 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1259 stream
= writer_set_output(writer
);
1261 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1262 writer_set_property(writer
, XmlWriterProperty_Indent
);
1264 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1265 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1267 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
1268 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1270 hr
= IXmlWriter_WriteComment(writer
, commentW
);
1271 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1273 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, bW
, NULL
);
1274 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1276 hr
= IXmlWriter_WriteEndDocument(writer
);
1277 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1279 hr
= IXmlWriter_Flush(writer
);
1280 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1282 CHECK_OUTPUT(stream
,
1284 " <!--comment-->\r\n"
1288 IStream_Release(stream
);
1290 /* WriteElementString */
1291 stream
= writer_set_output(writer
);
1293 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
1294 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1296 hr
= IXmlWriter_WriteElementString(writer
, NULL
, bW
, NULL
, NULL
);
1297 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1299 hr
= IXmlWriter_WriteElementString(writer
, NULL
, bW
, NULL
, NULL
);
1300 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1302 hr
= IXmlWriter_WriteEndElement(writer
);
1303 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1305 hr
= IXmlWriter_Flush(writer
);
1306 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1308 CHECK_OUTPUT(stream
,
1314 IStream_Release(stream
);
1316 IXmlWriter_Release(writer
);
1319 static void test_WriteAttributeString(void)
1321 static const WCHAR prefixW
[] = {'p','r','e','f','i','x',0};
1322 static const WCHAR localW
[] = {'l','o','c','a','l',0};
1323 static const WCHAR uriW
[] = {'u','r','i',0};
1324 static const WCHAR uri2W
[] = {'u','r','i','2',0};
1325 static const WCHAR xmlnsW
[] = {'x','m','l','n','s',0};
1326 static const WCHAR aW
[] = {'a',0};
1327 static const WCHAR bW
[] = {'b',0};
1332 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1333 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1335 stream
= writer_set_output(writer
);
1337 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1339 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1340 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1342 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
1343 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1345 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, aW
, NULL
, bW
);
1346 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1348 hr
= IXmlWriter_WriteEndDocument(writer
);
1349 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1351 hr
= IXmlWriter_Flush(writer
);
1352 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1354 CHECK_OUTPUT(stream
,
1356 IStream_Release(stream
);
1358 /* with namespaces */
1359 stream
= writer_set_output(writer
);
1361 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1362 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1364 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
1365 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1367 hr
= IXmlWriter_WriteAttributeString(writer
, aW
, NULL
, NULL
, bW
);
1369 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1371 hr
= IXmlWriter_WriteAttributeString(writer
, prefixW
, localW
, uriW
, bW
);
1373 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1375 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, aW
, NULL
, bW
);
1376 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1378 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, xmlnsW
, uri2W
, NULL
);
1380 ok(hr
== WR_E_XMLNSPREFIXDECLARATION
, "got 0x%08x\n", hr
);
1382 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, xmlnsW
, NULL
, uri2W
);
1384 ok(hr
== WR_E_NSPREFIXDECLARED
, "got 0x%08x\n", hr
);
1386 hr
= IXmlWriter_WriteAttributeString(writer
, prefixW
, localW
, NULL
, bW
);
1388 ok(hr
== WR_E_DUPLICATEATTRIBUTE
, "got 0x%08x\n", hr
);
1390 hr
= IXmlWriter_WriteEndDocument(writer
);
1391 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1393 hr
= IXmlWriter_Flush(writer
);
1394 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1396 CHECK_OUTPUT_TODO(stream
,
1397 "<a prefix:local=\"b\" a=\"b\" xmlns:prefix=\"uri\" />");
1399 IXmlWriter_Release(writer
);
1400 IStream_Release(stream
);
1403 static void test_WriteFullEndElement(void)
1405 static const WCHAR aW
[] = {'a',0};
1410 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1411 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1413 /* standalone element */
1414 stream
= writer_set_output(writer
);
1416 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1417 writer_set_property(writer
, XmlWriterProperty_Indent
);
1419 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1420 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1422 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
1423 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1425 hr
= IXmlWriter_WriteFullEndElement(writer
);
1426 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1428 hr
= IXmlWriter_WriteEndDocument(writer
);
1429 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1431 hr
= IXmlWriter_Flush(writer
);
1432 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1434 CHECK_OUTPUT(stream
,
1436 IStream_Release(stream
);
1438 /* nested elements */
1439 stream
= writer_set_output(writer
);
1441 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1442 writer_set_property(writer
, XmlWriterProperty_Indent
);
1444 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1445 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1447 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
1448 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1450 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
1451 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1453 hr
= IXmlWriter_WriteFullEndElement(writer
);
1454 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1456 hr
= IXmlWriter_WriteEndDocument(writer
);
1457 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1459 hr
= IXmlWriter_Flush(writer
);
1460 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1462 CHECK_OUTPUT(stream
,
1467 IXmlWriter_Release(writer
);
1468 IStream_Release(stream
);
1471 static void test_WriteCharEntity(void)
1473 static const WCHAR aW
[] = {'a',0};
1478 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1479 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1481 /* without indentation */
1482 stream
= writer_set_output(writer
);
1484 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1486 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1487 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1489 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
1490 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1492 hr
= IXmlWriter_WriteCharEntity(writer
, 0x100);
1493 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1495 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, aW
, NULL
);
1496 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1498 hr
= IXmlWriter_WriteEndDocument(writer
);
1499 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1501 hr
= IXmlWriter_Flush(writer
);
1502 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1504 CHECK_OUTPUT(stream
,
1505 "<a>Ā<a /></a>");
1507 IXmlWriter_Release(writer
);
1508 IStream_Release(stream
);
1511 static void test_WriteString(void)
1513 static const WCHAR markupW
[] = {'<','&','"','>','=',0};
1514 static const WCHAR aW
[] = {'a',0};
1515 static const WCHAR bW
[] = {'b',0};
1516 static const WCHAR emptyW
[] = {0};
1521 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1522 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1524 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1526 hr
= IXmlWriter_WriteString(writer
, aW
);
1527 ok(hr
== E_UNEXPECTED
, "got 0x%08x\n", hr
);
1529 hr
= IXmlWriter_WriteString(writer
, NULL
);
1530 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1532 hr
= IXmlWriter_WriteString(writer
, emptyW
);
1533 ok(hr
== E_UNEXPECTED
, "got 0x%08x\n", hr
);
1535 stream
= writer_set_output(writer
);
1537 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, bW
, NULL
);
1538 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1540 hr
= IXmlWriter_WriteString(writer
, NULL
);
1541 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1543 hr
= IXmlWriter_WriteString(writer
, emptyW
);
1544 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1546 hr
= IXmlWriter_WriteString(writer
, aW
);
1547 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1549 /* WriteString automatically escapes markup characters */
1550 hr
= IXmlWriter_WriteString(writer
, markupW
);
1551 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1553 hr
= IXmlWriter_Flush(writer
);
1554 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1556 CHECK_OUTPUT(stream
,
1557 "<b>a<&\">=");
1558 IStream_Release(stream
);
1560 stream
= writer_set_output(writer
);
1562 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, bW
, NULL
);
1563 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1565 hr
= IXmlWriter_WriteString(writer
, NULL
);
1566 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1568 hr
= IXmlWriter_Flush(writer
);
1569 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1571 CHECK_OUTPUT(stream
,
1574 hr
= IXmlWriter_WriteString(writer
, emptyW
);
1575 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1577 hr
= IXmlWriter_Flush(writer
);
1578 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1580 CHECK_OUTPUT(stream
,
1583 IXmlWriter_Release(writer
);
1584 IStream_Release(stream
);
1589 test_writer_create();
1590 test_writer_state();
1591 test_writeroutput();
1592 test_writestartdocument();
1593 test_writestartelement();
1594 test_writeendelement();
1596 test_omitxmldeclaration();
1598 test_writeenddocument();
1599 test_WriteComment();
1603 test_WriteAttributeString();
1604 test_WriteFullEndElement();
1605 test_WriteCharEntity();