2 * Copyright 2015 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "webservices.h"
22 #include "wine/test.h"
26 static inline float __port_infinity(void)
28 static const unsigned __inf_bytes
= 0x7f800000;
29 return *(const float *)&__inf_bytes
;
31 #define INFINITY __port_infinity()
35 static inline float __port_nan(void)
37 static const unsigned __nan_bytes
= 0x7fc00000;
38 return *(const float *)&__nan_bytes
;
40 #define NAN __port_nan()
43 static HRESULT
set_output( WS_XML_WRITER
*writer
)
45 WS_XML_WRITER_TEXT_ENCODING text
= { {WS_XML_WRITER_ENCODING_TYPE_TEXT
}, WS_CHARSET_UTF8
};
46 WS_XML_WRITER_BUFFER_OUTPUT buf
= { {WS_XML_WRITER_OUTPUT_TYPE_BUFFER
} };
47 return WsSetOutput( writer
, &text
.encoding
, &buf
.output
, NULL
, 0, NULL
);
50 static void test_WsCreateWriter(void)
53 WS_XML_WRITER
*writer
;
54 WS_XML_WRITER_PROPERTY prop
;
55 ULONG size
, max_depth
, max_attrs
, indent
, trim_size
, max_size
, max_ns
;
56 BOOL allow_fragment
, write_decl
, in_attr
;
61 hr
= WsCreateWriter( NULL
, 0, NULL
, NULL
);
62 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
65 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
66 ok( hr
== S_OK
, "got %08x\n", hr
);
67 ok( writer
!= NULL
, "writer not set\n" );
69 /* can't retrieve properties before output is set */
70 max_depth
= 0xdeadbeef;
71 size
= sizeof(max_depth
);
72 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_DEPTH
, &max_depth
, size
, NULL
);
73 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
74 ok( max_depth
== 0xdeadbeef, "max_depth set\n" );
76 hr
= set_output( writer
);
77 ok( hr
== S_OK
, "got %08x\n", hr
);
79 /* check some defaults */
80 max_depth
= 0xdeadbeef;
81 size
= sizeof(max_depth
);
82 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_DEPTH
, &max_depth
, size
, NULL
);
83 ok( hr
== S_OK
, "got %08x\n", hr
);
84 ok( max_depth
== 32, "got %u\n", max_depth
);
86 allow_fragment
= TRUE
;
87 size
= sizeof(allow_fragment
);
88 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_ALLOW_FRAGMENT
, &allow_fragment
, size
, NULL
);
89 ok( hr
== S_OK
, "got %08x\n", hr
);
90 ok( !allow_fragment
, "got %d\n", allow_fragment
);
92 max_attrs
= 0xdeadbeef;
93 size
= sizeof(max_attrs
);
94 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_ATTRIBUTES
, &max_attrs
, size
, NULL
);
95 ok( hr
== S_OK
, "got %08x\n", hr
);
96 ok( max_attrs
== 128, "got %u\n", max_attrs
);
99 size
= sizeof(write_decl
);
100 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_WRITE_DECLARATION
, &write_decl
, size
, NULL
);
101 ok( hr
== S_OK
, "got %08x\n", hr
);
102 ok( !write_decl
, "got %d\n", write_decl
);
105 size
= sizeof(indent
);
106 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_INDENT
, &indent
, size
, NULL
);
107 ok( hr
== S_OK
, "got %08x\n", hr
);
108 ok( !indent
, "got %u\n", indent
);
110 trim_size
= 0xdeadbeef;
111 size
= sizeof(trim_size
);
112 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BUFFER_TRIM_SIZE
, &trim_size
, size
, NULL
);
113 ok( hr
== S_OK
, "got %08x\n", hr
);
114 ok( trim_size
== 4096, "got %u\n", trim_size
);
116 charset
= 0xdeadbeef;
117 size
= sizeof(charset
);
118 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_CHARSET
, &charset
, size
, NULL
);
119 ok( hr
== S_OK
, "got %08x\n", hr
);
120 ok( charset
== WS_CHARSET_UTF8
, "got %u\n", charset
);
122 buffers
.bufferCount
= 0xdeadbeef;
123 buffers
.buffers
= (WS_BYTES
*)0xdeadbeef;
124 size
= sizeof(buffers
);
125 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BUFFERS
, &buffers
, size
, NULL
);
126 ok( hr
== S_OK
, "got %08x\n", hr
);
127 ok( !buffers
.bufferCount
, "got %u\n", buffers
.bufferCount
);
128 ok( !buffers
.buffers
, "got %p\n", buffers
.buffers
);
130 max_size
= 0xdeadbeef;
131 size
= sizeof(max_size
);
132 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BUFFER_MAX_SIZE
, &max_size
, size
, NULL
);
133 ok( hr
== S_OK
, "got %08x\n", hr
);
134 ok( max_size
== 65536, "got %u\n", max_size
);
136 bytes
.length
= 0xdeadbeef;
137 bytes
.bytes
= (BYTE
*)0xdeadbeef;
138 size
= sizeof(buffers
);
139 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
140 ok( hr
== S_OK
, "got %08x\n", hr
);
141 ok( !bytes
.length
, "got %u\n", bytes
.length
);
142 ok( bytes
.bytes
!= NULL
, "got %p\n", bytes
.bytes
);
144 max_size
= 0xdeadbeef;
145 size
= sizeof(max_size
);
146 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_MIME_PARTS_BUFFER_SIZE
, &max_size
, size
, NULL
);
147 ok( hr
== S_OK
, "got %08x\n", hr
);
148 ok( max_size
== 65536, "got %u\n", max_size
);
150 bytes
.length
= 0xdeadbeef;
151 bytes
.bytes
= (BYTE
*)0xdeadbeef;
152 size
= sizeof(bytes
);
153 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_INITIAL_BUFFER
, &bytes
, size
, NULL
);
154 ok( hr
== S_OK
, "got %08x\n", hr
);
155 ok( !bytes
.length
, "got %u\n", bytes
.length
);
156 ok( !bytes
.bytes
, "got %p\n", bytes
.bytes
);
159 size
= sizeof(max_ns
);
160 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_NAMESPACES
, &max_ns
, size
, NULL
);
161 ok( hr
== S_OK
, "got %08x\n", hr
);
162 ok( max_ns
== 32, "got %u\n", max_ns
);
163 WsFreeWriter( writer
);
165 /* change a property */
167 prop
.id
= WS_XML_WRITER_PROPERTY_MAX_DEPTH
;
168 prop
.value
= &max_depth
;
169 prop
.valueSize
= sizeof(max_depth
);
170 hr
= WsCreateWriter( &prop
, 1, &writer
, NULL
);
171 ok( hr
== S_OK
, "got %08x\n", hr
);
173 hr
= set_output( writer
);
174 ok( hr
== S_OK
, "got %08x\n", hr
);
176 max_depth
= 0xdeadbeef;
177 size
= sizeof(max_depth
);
178 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_DEPTH
, &max_depth
, size
, NULL
);
179 ok( hr
== S_OK
, "got %08x\n", hr
);
180 ok( max_depth
== 16, "got %u\n", max_depth
);
181 WsFreeWriter( writer
);
183 /* show that some properties are read-only */
185 prop
.id
= WS_XML_WRITER_PROPERTY_IN_ATTRIBUTE
;
186 prop
.value
= &in_attr
;
187 prop
.valueSize
= sizeof(in_attr
);
188 hr
= WsCreateWriter( &prop
, 1, &writer
, NULL
);
189 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
192 prop
.id
= WS_XML_WRITER_PROPERTY_BYTES_WRITTEN
;
194 prop
.valueSize
= sizeof(size
);
195 hr
= WsCreateWriter( &prop
, 1, &writer
, NULL
);
196 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
199 prop
.id
= WS_XML_WRITER_PROPERTY_BYTES_TO_CLOSE
;
201 prop
.valueSize
= sizeof(size
);
202 hr
= WsCreateWriter( &prop
, 1, &writer
, NULL
);
203 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
206 static void test_WsCreateXmlBuffer(void)
210 WS_XML_WRITER
*writer
;
211 WS_XML_BUFFER
*buffer
;
215 hr
= WsCreateXmlBuffer( NULL
, NULL
, 0, NULL
, NULL
);
216 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
218 hr
= WsCreateXmlBuffer( NULL
, NULL
, 0, &buffer
, NULL
);
219 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
221 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
222 ok( hr
== S_OK
, "got %08x\n", hr
);
224 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, NULL
, NULL
);
225 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
228 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
229 ok( hr
== S_OK
, "got %08x\n", hr
);
230 ok( buffer
!= NULL
, "buffer not set\n" );
232 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
233 ok( hr
== S_OK
, "got %08x\n", hr
);
235 size
= sizeof(bytes
);
236 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
237 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
239 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
240 ok( hr
== S_OK
, "got %08x\n", hr
);
242 size
= sizeof(bytes
);
243 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
244 todo_wine
ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
246 WsFreeWriter( writer
);
250 static void test_WsSetOutput(void)
253 WS_XML_WRITER
*writer
;
254 WS_XML_WRITER_PROPERTY prop
;
255 WS_XML_WRITER_TEXT_ENCODING encoding
;
256 WS_XML_WRITER_BUFFER_OUTPUT output
;
257 ULONG size
, max_depth
;
259 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
260 ok( hr
== S_OK
, "got %08x\n", hr
);
262 hr
= WsSetOutput( NULL
, NULL
, NULL
, NULL
, 0, NULL
);
263 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
265 encoding
.encoding
.encodingType
= WS_XML_WRITER_ENCODING_TYPE_TEXT
;
266 encoding
.charSet
= WS_CHARSET_UTF8
;
268 output
.output
.outputType
= WS_XML_WRITER_OUTPUT_TYPE_BUFFER
;
270 hr
= WsSetOutput( writer
, &encoding
.encoding
, &output
.output
, NULL
, 0, NULL
);
271 ok( hr
== S_OK
, "got %08x\n", hr
);
273 /* multiple calls are allowed */
274 hr
= WsSetOutput( writer
, &encoding
.encoding
, &output
.output
, NULL
, 0, NULL
);
275 ok( hr
== S_OK
, "got %08x\n", hr
);
277 /* writer properties can be set with WsSetOutput */
279 prop
.id
= WS_XML_WRITER_PROPERTY_MAX_DEPTH
;
280 prop
.value
= &max_depth
;
281 prop
.valueSize
= sizeof(max_depth
);
282 hr
= WsSetOutput( writer
, &encoding
.encoding
, &output
.output
, &prop
, 1, NULL
);
283 ok( hr
== S_OK
, "got %08x\n", hr
);
285 max_depth
= 0xdeadbeef;
286 size
= sizeof(max_depth
);
287 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_DEPTH
, &max_depth
, size
, NULL
);
288 ok( hr
== S_OK
, "got %08x\n", hr
);
289 ok( max_depth
== 16, "got %u\n", max_depth
);
290 WsFreeWriter( writer
);
293 static void test_WsSetOutputToBuffer(void)
297 WS_XML_BUFFER
*buffer
;
298 WS_XML_WRITER
*writer
;
299 WS_XML_WRITER_PROPERTY prop
;
300 ULONG size
, max_depth
;
302 hr
= WsSetOutputToBuffer( NULL
, NULL
, NULL
, 0, NULL
);
303 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
305 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
306 ok( hr
== S_OK
, "got %08x\n", hr
);
308 hr
= WsSetOutputToBuffer( writer
, NULL
, NULL
, 0, NULL
);
309 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
311 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
312 ok( hr
== S_OK
, "got %08x\n", hr
);
314 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
315 ok( hr
== S_OK
, "got %08x\n", hr
);
317 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
318 ok( hr
== S_OK
, "got %08x\n", hr
);
320 /* multiple calls are allowed */
321 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
322 ok( hr
== S_OK
, "got %08x\n", hr
);
324 /* writer properties can be set with WsSetOutputToBuffer */
326 prop
.id
= WS_XML_WRITER_PROPERTY_MAX_DEPTH
;
327 prop
.value
= &max_depth
;
328 prop
.valueSize
= sizeof(max_depth
);
329 hr
= WsSetOutputToBuffer( writer
, buffer
, &prop
, 1, NULL
);
330 ok( hr
== S_OK
, "got %08x\n", hr
);
332 max_depth
= 0xdeadbeef;
333 size
= sizeof(max_depth
);
334 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_DEPTH
, &max_depth
, size
, NULL
);
335 ok( hr
== S_OK
, "got %08x\n", hr
);
336 ok( max_depth
== 16, "got %u\n", max_depth
);
338 WsFreeWriter( writer
);
342 static char strbuf
[512];
343 static const char *debugstr_bytes( const BYTE
*bytes
, ULONG len
)
345 const BYTE
*src
= bytes
;
351 if (dst
- strbuf
> sizeof(strbuf
) - 7) break;
354 case '\n': *dst
++ = '\\'; *dst
++ = 'n'; break;
355 case '\r': *dst
++ = '\\'; *dst
++ = 'r'; break;
356 case '\t': *dst
++ = '\\'; *dst
++ = 't'; break;
358 if (c
>= ' ' && c
< 127) *dst
++ = c
;
361 sprintf( dst
, "\\%02x", c
);
377 static void check_output( WS_XML_WRITER
*writer
, const char *expected
, unsigned int line
)
380 ULONG size
= sizeof(bytes
);
381 int len
= strlen( expected
);
384 memset( &bytes
, 0, sizeof(bytes
) );
385 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
386 ok( hr
== S_OK
, "%u: got %08x\n", line
, hr
);
387 ok( bytes
.length
== len
, "%u: got %u expected %u\n", line
, bytes
.length
, len
);
388 if (bytes
.length
!= len
) return;
389 ok( !memcmp( bytes
.bytes
, expected
, len
),
390 "%u: got %s expected %s\n", line
, debugstr_bytes(bytes
.bytes
, bytes
.length
), expected
);
393 static void test_WsWriteStartElement(void)
396 WS_XML_WRITER
*writer
;
397 WS_XML_STRING prefix
= {1, (BYTE
*)"p"}, ns
= {2, (BYTE
*)"ns"}, ns2
= {3, (BYTE
*)"ns2"};
398 WS_XML_STRING localname
= {1, (BYTE
*)"a"}, localname2
= {1, (BYTE
*)"b"}, empty
= {0, NULL
};
400 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
401 ok( hr
== S_OK
, "got %08x\n", hr
);
403 hr
= set_output( writer
);
404 ok( hr
== S_OK
, "got %08x\n", hr
);
406 hr
= WsWriteStartElement( NULL
, &prefix
, &localname
, &ns
, NULL
);
407 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
409 /* first call to WsWriteStartElement doesn't output anything */
410 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
411 ok( hr
== S_OK
, "got %08x\n", hr
);
412 check_output( writer
, "", __LINE__
);
414 /* two ways to close an element */
415 hr
= WsWriteEndStartElement( writer
, NULL
);
416 ok( hr
== S_OK
, "got %08x\n", hr
);
417 check_output( writer
, "<p:a xmlns:p=\"ns\">", __LINE__
);
419 hr
= WsWriteEndElement( writer
, NULL
);
420 ok( hr
== S_OK
, "got %08x\n", hr
);
421 check_output( writer
, "<p:a xmlns:p=\"ns\"></p:a>", __LINE__
);
423 hr
= set_output( writer
);
424 ok( hr
== S_OK
, "got %08x\n", hr
);
426 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
427 ok( hr
== S_OK
, "got %08x\n", hr
);
429 hr
= WsWriteEndElement( writer
, NULL
);
430 ok( hr
== S_OK
, "got %08x\n", hr
);
431 check_output( writer
, "<p:a xmlns:p=\"ns\"/>", __LINE__
);
433 /* nested elements */
434 hr
= set_output( writer
);
435 ok( hr
== S_OK
, "got %08x\n", hr
);
437 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
438 ok( hr
== S_OK
, "got %08x\n", hr
);
439 check_output( writer
, "", __LINE__
);
441 hr
= WsWriteStartElement( writer
, NULL
, &localname2
, &ns
, NULL
);
442 ok( hr
== S_OK
, "got %08x\n", hr
);
443 check_output( writer
, "<p:a xmlns:p=\"ns\">", __LINE__
);
445 hr
= WsWriteEndElement( writer
, NULL
);
446 ok( hr
== S_OK
, "got %08x\n", hr
);
447 check_output( writer
, "<p:a xmlns:p=\"ns\"><p:b/>", __LINE__
);
449 hr
= WsWriteEndElement( writer
, NULL
);
450 ok( hr
== S_OK
, "got %08x\n", hr
);
451 check_output( writer
, "<p:a xmlns:p=\"ns\"><p:b/></p:a>", __LINE__
);
453 hr
= set_output( writer
);
454 ok( hr
== S_OK
, "got %08x\n", hr
);
456 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
457 ok( hr
== S_OK
, "got %08x\n", hr
);
458 check_output( writer
, "", __LINE__
);
460 hr
= WsWriteStartElement( writer
, NULL
, &localname2
, &ns2
, NULL
);
461 ok( hr
== S_OK
, "got %08x\n", hr
);
462 check_output( writer
, "<p:a xmlns:p=\"ns\">", __LINE__
);
464 hr
= WsWriteEndElement( writer
, NULL
);
465 ok( hr
== S_OK
, "got %08x\n", hr
);
466 check_output( writer
, "<p:a xmlns:p=\"ns\"><b xmlns=\"ns2\"/>", __LINE__
);
468 hr
= WsWriteEndElement( writer
, NULL
);
469 ok( hr
== S_OK
, "got %08x\n", hr
);
470 check_output( writer
, "<p:a xmlns:p=\"ns\"><b xmlns=\"ns2\"/></p:a>", __LINE__
);
472 hr
= set_output( writer
);
473 ok( hr
== S_OK
, "got %08x\n", hr
);
475 hr
= WsWriteStartElement( writer
, &empty
, &localname
, &empty
, NULL
);
476 ok( hr
== S_OK
, "got %08x\n", hr
);
477 hr
= WsWriteEndStartElement( writer
, NULL
);
478 ok( hr
== S_OK
, "got %08x\n", hr
);
479 hr
= WsWriteEndElement( writer
, NULL
);
480 ok( hr
== S_OK
, "got %08x\n", hr
);
481 check_output( writer
, "<a></a>", __LINE__
);
483 WsFreeWriter( writer
);
486 static void test_WsWriteStartAttribute(void)
489 WS_XML_WRITER
*writer
;
490 WS_XML_STRING prefix
= {1, (BYTE
*)"p"}, localname
= {3, (BYTE
*)"str"};
491 WS_XML_STRING localname2
= {3, (BYTE
*)"len"}, ns
= {2, (BYTE
*)"ns"}, empty
= {0, NULL
};
492 WS_XML_UTF8_TEXT text
= {{WS_XML_TEXT_TYPE_UTF8
}};
494 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
495 ok( hr
== S_OK
, "got %08x\n", hr
);
497 hr
= set_output( writer
);
498 ok( hr
== S_OK
, "got %08x\n", hr
);
500 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
501 ok( hr
== S_OK
, "got %08x\n", hr
);
503 hr
= WsWriteStartAttribute( NULL
, &prefix
, &localname
, &ns
, FALSE
, NULL
);
504 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
506 /* WsWriteStartAttribute doesn't output anything */
507 hr
= WsWriteStartAttribute( writer
, &prefix
, &localname2
, &ns
, FALSE
, NULL
);
508 ok( hr
== S_OK
, "got %08x\n", hr
);
509 check_output( writer
, "", __LINE__
);
511 text
.value
.length
= 1;
512 text
.value
.bytes
= (BYTE
*)"0";
513 hr
= WsWriteText( writer
, &text
.text
, NULL
);
514 ok( hr
== S_OK
, "got %08x\n", hr
);
515 check_output( writer
, "", __LINE__
);
517 /* WsWriteEndAttribute doesn't output anything */
518 hr
= WsWriteEndAttribute( writer
, NULL
);
519 ok( hr
== S_OK
, "got %08x\n", hr
);
520 check_output( writer
, "", __LINE__
);
522 hr
= WsWriteEndElement( writer
, NULL
);
523 ok( hr
== S_OK
, "got %08x\n", hr
);
524 check_output( writer
, "<p:str p:len=\"0\" xmlns:p=\"ns\"/>", __LINE__
);
526 hr
= set_output( writer
);
527 ok( hr
== S_OK
, "got %08x\n", hr
);
529 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
530 ok( hr
== S_OK
, "got %08x\n", hr
);
532 hr
= WsWriteStartAttribute( writer
, &empty
, &localname2
, &empty
, FALSE
, NULL
);
533 ok( hr
== S_OK
, "got %08x\n", hr
);
534 hr
= WsWriteEndAttribute( writer
, NULL
);
535 ok( hr
== S_OK
, "got %08x\n", hr
);
537 hr
= WsWriteEndElement( writer
, NULL
);
538 ok( hr
== S_OK
, "got %08x\n", hr
);
539 check_output( writer
, "<p:str len=\"\" xmlns:p=\"ns\"/>", __LINE__
);
541 hr
= set_output( writer
);
542 ok( hr
== S_OK
, "got %08x\n", hr
);
544 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
545 ok( hr
== S_OK
, "got %08x\n", hr
);
547 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &empty
, FALSE
, NULL
);
548 ok( hr
== S_OK
, "got %08x\n", hr
);
550 hr
= WsWriteEndAttribute( writer
, NULL
);
551 ok( hr
== S_OK
, "got %08x\n", hr
);
553 hr
= WsWriteStartAttribute( writer
, NULL
, &localname
, &ns
, FALSE
, NULL
);
554 ok( hr
== S_OK
, "got %08x\n", hr
);
556 hr
= WsWriteEndAttribute( writer
, NULL
);
557 ok( hr
== S_OK
, "got %08x\n", hr
);
559 hr
= WsWriteEndElement( writer
, NULL
);
560 ok( hr
== S_OK
, "got %08x\n", hr
);
561 check_output( writer
, "<p:str len=\"\" p:str=\"\" xmlns:p=\"ns\"/>", __LINE__
);
563 WsFreeWriter( writer
);
566 static void test_WsWriteType(void)
568 static const WCHAR testW
[] = {'t','e','s','t',0};
570 WS_XML_WRITER
*writer
;
571 WS_XML_STRING prefix
= {1, (BYTE
*)"p"}, localname
= {3, (BYTE
*)"str"}, ns
= {2, (BYTE
*)"ns"};
572 const WCHAR
*val_str
;
574 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
575 ok( hr
== S_OK
, "got %08x\n", hr
);
577 hr
= set_output( writer
);
578 ok( hr
== S_OK
, "got %08x\n", hr
);
581 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
582 WS_WRITE_REQUIRED_POINTER
, &val_str
, sizeof(val_str
), NULL
);
583 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
585 hr
= set_output( writer
);
586 ok( hr
== S_OK
, "got %08x\n", hr
);
588 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
589 ok( hr
== S_OK
, "got %08x\n", hr
);
592 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
593 WS_WRITE_REQUIRED_VALUE
, NULL
, sizeof(testW
), NULL
);
594 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
596 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
597 WS_WRITE_REQUIRED_VALUE
, testW
, sizeof(testW
), NULL
);
598 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
600 /* required pointer */
601 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
602 WS_WRITE_REQUIRED_POINTER
, NULL
, sizeof(val_str
), NULL
);
603 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
605 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
606 WS_WRITE_REQUIRED_VALUE
, testW
, sizeof(testW
), NULL
);
607 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
609 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
610 WS_WRITE_REQUIRED_POINTER
, &val_str
, sizeof(WCHAR
**), NULL
);
611 ok( hr
== S_OK
, "got %08x\n", hr
);
612 check_output( writer
, "<p:str xmlns:p=\"ns\">test", __LINE__
);
614 hr
= WsWriteEndElement( writer
, NULL
);
615 ok( hr
== S_OK
, "got %08x\n", hr
);
616 check_output( writer
, "<p:str xmlns:p=\"ns\">test</p:str>", __LINE__
);
618 hr
= set_output( writer
);
619 ok( hr
== S_OK
, "got %08x\n", hr
);
621 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
622 ok( hr
== S_OK
, "got %08x\n", hr
);
624 hr
= WsWriteStartAttribute( writer
, NULL
, &localname
, &ns
, FALSE
, NULL
);
625 ok( hr
== S_OK
, "got %08x\n", hr
);
628 hr
= WsWriteType( writer
, WS_ATTRIBUTE_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
629 WS_WRITE_REQUIRED_POINTER
, &val_str
, sizeof(val_str
), NULL
);
630 ok( hr
== S_OK
, "got %08x\n", hr
);
631 check_output( writer
, "", __LINE__
);
633 hr
= WsWriteEndAttribute( writer
, NULL
);
634 ok( hr
== S_OK
, "got %08x\n", hr
);
635 check_output( writer
, "", __LINE__
);
637 hr
= WsWriteEndElement( writer
, NULL
);
638 ok( hr
== S_OK
, "got %08x\n", hr
);
639 check_output( writer
, "<p:str p:str=\"test\" xmlns:p=\"ns\"/>", __LINE__
);
641 hr
= set_output( writer
);
642 ok( hr
== S_OK
, "got %08x\n", hr
);
644 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
645 ok( hr
== S_OK
, "got %08x\n", hr
);
648 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
649 WS_WRITE_REQUIRED_POINTER
, &val_str
, sizeof(val_str
), NULL
);
650 ok( hr
== S_OK
, "got %08x\n", hr
);
651 check_output( writer
, "<p:str xmlns:p=\"ns\">test", __LINE__
);
653 hr
= WsWriteEndElement( writer
, NULL
);
654 ok( hr
== S_OK
, "got %08x\n", hr
);
655 check_output( writer
, "<p:str xmlns:p=\"ns\">test</p:str>", __LINE__
);
657 WsFreeWriter( writer
);
660 static void prepare_basic_type_test( WS_XML_WRITER
*writer
)
662 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
665 hr
= set_output( writer
);
666 ok( hr
== S_OK
, "got %08x\n", hr
);
667 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
668 ok( hr
== S_OK
, "got %08x\n", hr
);
671 static void test_basic_type(void)
673 static WCHAR testW
[] = {'t','e','s','t',0};
675 WS_XML_WRITER
*writer
;
676 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
}, xmlstr
;
692 { WS_BOOL_TYPE
, TRUE
, sizeof(BOOL
), "<t>true</t>", "<t t=\"true\"/>" },
693 { WS_BOOL_TYPE
, FALSE
, sizeof(BOOL
), "<t>false</t>", "<t t=\"false\"/>" },
694 { WS_INT8_TYPE
, -128, sizeof(INT8
), "<t>-128</t>", "<t t=\"-128\"/>" },
695 { WS_INT16_TYPE
, -32768, sizeof(INT16
), "<t>-32768</t>", "<t t=\"-32768\"/>" },
696 { WS_INT32_TYPE
, -2147483647 - 1, sizeof(INT32
), "<t>-2147483648</t>",
697 "<t t=\"-2147483648\"/>" },
698 { WS_INT64_TYPE
, -9223372036854775807 - 1, sizeof(INT64
), "<t>-9223372036854775808</t>",
699 "<t t=\"-9223372036854775808\"/>" },
700 { WS_UINT8_TYPE
, 255, sizeof(UINT8
), "<t>255</t>", "<t t=\"255\"/>" },
701 { WS_UINT16_TYPE
, 65535, sizeof(UINT16
), "<t>65535</t>", "<t t=\"65535\"/>" },
702 { WS_UINT32_TYPE
, ~0u, sizeof(UINT32
), "<t>4294967295</t>", "<t t=\"4294967295\"/>" },
703 { WS_UINT64_TYPE
, ~0, sizeof(UINT64
), "<t>18446744073709551615</t>",
704 "<t t=\"18446744073709551615\"/>" },
707 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
708 ok( hr
== S_OK
, "got %08x\n", hr
);
710 /* element content type mapping */
711 for (i
= 0; i
< sizeof(tests
)/sizeof(tests
[0]); i
++)
713 prepare_basic_type_test( writer
);
714 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, tests
[i
].type
, NULL
,
715 WS_WRITE_REQUIRED_VALUE
, &tests
[i
].val
, tests
[i
].size
, NULL
);
716 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
718 hr
= WsWriteEndElement( writer
, NULL
);
719 ok( hr
== S_OK
, "got %08x\n", hr
);
720 check_output( writer
, tests
[i
].result
, __LINE__
);
723 /* element type mapping is the same as element content type mapping for basic types */
724 for (i
= 0; i
< sizeof(tests
)/sizeof(tests
[0]); i
++)
726 const INT64
*ptr
= &tests
[i
].val
;
728 prepare_basic_type_test( writer
);
729 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, tests
[i
].type
, NULL
,
730 WS_WRITE_REQUIRED_POINTER
, &ptr
, sizeof(ptr
), NULL
);
731 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
733 hr
= WsWriteEndElement( writer
, NULL
);
734 ok( hr
== S_OK
, "got %08x\n", hr
);
735 check_output( writer
, tests
[i
].result
, __LINE__
);
738 /* attribute type mapping */
739 for (i
= 0; i
< sizeof(tests
)/sizeof(tests
[0]); i
++)
741 prepare_basic_type_test( writer
);
742 hr
= WsWriteStartAttribute( writer
, NULL
, &localname
, &ns
, FALSE
, NULL
);
743 ok( hr
== S_OK
, "got %08x\n", hr
);
745 hr
= WsWriteType( writer
, WS_ATTRIBUTE_TYPE_MAPPING
, tests
[i
].type
, NULL
,
746 WS_WRITE_REQUIRED_VALUE
, &tests
[i
].val
, tests
[i
].size
, NULL
);
747 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
749 hr
= WsWriteEndAttribute( writer
, NULL
);
750 ok( hr
== S_OK
, "got %08x\n", hr
);
752 hr
= WsWriteEndElement( writer
, NULL
);
753 ok( hr
== S_OK
, "got %08x\n", hr
);
754 check_output( writer
, tests
[i
].result2
, __LINE__
);
757 prepare_basic_type_test( writer
);
758 memset( &guid
, 0, sizeof(guid
) );
759 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_GUID_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
760 &guid
, sizeof(guid
), NULL
);
761 ok( hr
== S_OK
, "got %08x\n", hr
);
762 hr
= WsWriteEndElement( writer
, NULL
);
763 ok( hr
== S_OK
, "got %08x\n", hr
);
764 check_output( writer
, "<t>00000000-0000-0000-0000-000000000000</t>", __LINE__
);
766 prepare_basic_type_test( writer
);
767 string
.chars
= testW
;
769 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_STRING_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
770 &string
, sizeof(string
), NULL
);
771 ok( hr
== S_OK
, "got %08x\n", hr
);
772 hr
= WsWriteEndElement( writer
, NULL
);
773 ok( hr
== S_OK
, "got %08x\n", hr
);
774 check_output( writer
, "<t>test</t>", __LINE__
);
776 prepare_basic_type_test( writer
);
778 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
, WS_WRITE_REQUIRED_POINTER
,
779 &str
, sizeof(str
), NULL
);
780 ok( hr
== S_OK
, "got %08x\n", hr
);
781 hr
= WsWriteEndElement( writer
, NULL
);
782 ok( hr
== S_OK
, "got %08x\n", hr
);
783 check_output( writer
, "<t>test</t>", __LINE__
);
785 prepare_basic_type_test( writer
);
786 xmlstr
.bytes
= (BYTE
*)"test";
788 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_XML_STRING_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
789 &xmlstr
, sizeof(xmlstr
), NULL
);
790 ok( hr
== S_OK
, "got %08x\n", hr
);
791 hr
= WsWriteEndElement( writer
, NULL
);
792 ok( hr
== S_OK
, "got %08x\n", hr
);
793 check_output( writer
, "<t>test</t>", __LINE__
);
795 prepare_basic_type_test( writer
);
796 bytes
.bytes
= (BYTE
*)"test";
798 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_BYTES_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
799 &bytes
, sizeof(bytes
), NULL
);
800 ok( hr
== S_OK
, "got %08x\n", hr
);
801 hr
= WsWriteEndElement( writer
, NULL
);
802 ok( hr
== S_OK
, "got %08x\n", hr
);
803 check_output( writer
, "<t>dGVzdA==</t>", __LINE__
);
805 prepare_basic_type_test( writer
);
807 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_BYTES_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
808 &bytes
, sizeof(bytes
), NULL
);
809 ok( hr
== S_OK
, "got %08x\n", hr
);
810 hr
= WsWriteEndElement( writer
, NULL
);
811 ok( hr
== S_OK
, "got %08x\n", hr
);
812 check_output( writer
, "<t/>", __LINE__
);
814 prepare_basic_type_test( writer
);
816 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_BYTES_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
817 &bytes
, sizeof(bytes
), NULL
);
818 ok( hr
== S_OK
, "got %08x\n", hr
);
819 hr
= WsWriteEndElement( writer
, NULL
);
820 ok( hr
== S_OK
, "got %08x\n", hr
);
821 check_output( writer
, "<t/>", __LINE__
);
823 prepare_basic_type_test( writer
);
824 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_BYTES_TYPE
, NULL
, WS_WRITE_NILLABLE_VALUE
,
825 &bytes
, sizeof(bytes
), NULL
);
826 ok( hr
== S_OK
, "got %08x\n", hr
);
827 hr
= WsWriteEndElement( writer
, NULL
);
828 ok( hr
== S_OK
, "got %08x\n", hr
);
829 check_output( writer
, "<t a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/>",
832 WsFreeWriter( writer
);
835 static void test_simple_struct_type(void)
837 static const WCHAR valueW
[] = {'v','a','l','u','e',0};
839 WS_XML_WRITER
*writer
;
840 WS_STRUCT_DESCRIPTION s
;
841 WS_FIELD_DESCRIPTION f
, *fields
[1];
842 WS_XML_STRING localname
= {6, (BYTE
*)"struct"}, ns
= {0, NULL
};
848 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
849 ok( hr
== S_OK
, "got %08x\n", hr
);
851 hr
= set_output( writer
);
852 ok( hr
== S_OK
, "got %08x\n", hr
);
854 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
855 ok( hr
== S_OK
, "got %08x\n", hr
);
857 memset( &f
, 0, sizeof(f
) );
858 f
.mapping
= WS_TEXT_FIELD_MAPPING
;
859 f
.type
= WS_WSZ_TYPE
;
862 memset( &s
, 0, sizeof(s
) );
863 s
.size
= sizeof(struct test
);
864 s
.alignment
= TYPE_ALIGNMENT(struct test
);
868 test
= HeapAlloc( GetProcessHeap(), 0, sizeof(*test
) );
869 test
->field
= valueW
;
870 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, NULL
,
871 WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
872 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
874 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, NULL
,
875 WS_WRITE_REQUIRED_VALUE
, test
, sizeof(*test
), NULL
);
876 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
878 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
879 WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
880 ok( hr
== S_OK
, "got %08x\n", hr
);
882 hr
= WsWriteEndElement( writer
, NULL
);
883 ok( hr
== S_OK
, "got %08x\n", hr
);
884 check_output( writer
, "<struct>value</struct>", __LINE__
);
887 hr
= set_output( writer
);
888 ok( hr
== S_OK
, "got %08x\n", hr
);
890 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
891 ok( hr
== S_OK
, "got %08x\n", hr
);
893 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
894 WS_WRITE_REQUIRED_VALUE
, test
, sizeof(*test
), NULL
);
895 ok( hr
== S_OK
, "got %08x\n", hr
);
897 hr
= WsWriteEndElement( writer
, NULL
);
898 ok( hr
== S_OK
, "got %08x\n", hr
);
899 check_output( writer
, "<struct>value</struct>", __LINE__
);
901 hr
= set_output( writer
);
902 ok( hr
== S_OK
, "got %08x\n", hr
);
904 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
905 ok( hr
== S_OK
, "got %08x\n", hr
);
907 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
908 WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
909 ok( hr
== S_OK
, "got %08x\n", hr
);
911 hr
= WsWriteEndElement( writer
, NULL
);
912 ok( hr
== S_OK
, "got %08x\n", hr
);
913 check_output( writer
, "<struct>value</struct>", __LINE__
);
915 hr
= set_output( writer
);
916 ok( hr
== S_OK
, "got %08x\n", hr
);
918 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
919 ok( hr
== S_OK
, "got %08x\n", hr
);
921 hr
= WsWriteStartAttribute( writer
, NULL
, &localname
, &ns
, FALSE
, NULL
);
922 ok( hr
== S_OK
, "got %08x\n", hr
);
924 hr
= WsWriteType( writer
, WS_ATTRIBUTE_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
925 WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
926 ok( hr
== S_OK
, "got %08x\n", hr
);
928 hr
= WsWriteEndAttribute( writer
, NULL
);
929 ok( hr
== S_OK
, "got %08x\n", hr
);
931 hr
= WsWriteEndElement( writer
, NULL
);
932 ok( hr
== S_OK
, "got %08x\n", hr
);
933 check_output( writer
, "<struct struct=\"value\"/>", __LINE__
);
935 HeapFree( GetProcessHeap(), 0, test
);
936 WsFreeWriter( writer
);
939 static void test_WsWriteElement(void)
941 static const WCHAR testW
[] = {'t','e','s','t',0};
943 WS_XML_WRITER
*writer
;
944 WS_STRUCT_DESCRIPTION s
;
945 WS_FIELD_DESCRIPTION f
, *fields
[1];
946 WS_ELEMENT_DESCRIPTION desc
;
947 WS_XML_STRING localname
= {3, (BYTE
*)"str"}, ns
= {0, NULL
};
948 struct test
{ const WCHAR
*str
; } *test
;
950 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
951 ok( hr
== S_OK
, "got %08x\n", hr
);
953 hr
= set_output( writer
);
954 ok( hr
== S_OK
, "got %08x\n", hr
);
956 /* text field mapping */
957 memset( &f
, 0, sizeof(f
) );
958 f
.mapping
= WS_TEXT_FIELD_MAPPING
;
959 f
.type
= WS_WSZ_TYPE
;
962 memset( &s
, 0, sizeof(s
) );
963 s
.size
= sizeof(struct test
);
964 s
.alignment
= TYPE_ALIGNMENT(struct test
);
968 desc
.elementLocalName
= &localname
;
969 desc
.elementNs
= &ns
;
970 desc
.type
= WS_STRUCT_TYPE
;
971 desc
.typeDescription
= &s
;
973 test
= HeapAlloc( GetProcessHeap(), 0, sizeof(*test
) );
975 hr
= WsWriteElement( NULL
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
976 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
978 hr
= WsWriteElement( writer
, NULL
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
979 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
981 hr
= WsWriteElement( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, NULL
, 0, NULL
);
982 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
984 hr
= WsWriteElement( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
985 ok( hr
== S_OK
, "got %08x\n", hr
);
986 check_output( writer
, "<str>test</str>", __LINE__
);
988 hr
= set_output( writer
);
989 ok( hr
== S_OK
, "got %08x\n", hr
);
991 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
992 ok( hr
== S_OK
, "got %08x\n", hr
);
994 hr
= WsWriteElement( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
995 ok( hr
== S_OK
, "got %08x\n", hr
);
996 check_output( writer
, "<str><str>test</str>", __LINE__
);
998 hr
= set_output( writer
);
999 ok( hr
== S_OK
, "got %08x\n", hr
);
1001 /* attribute field mapping */
1002 f
.mapping
= WS_ATTRIBUTE_FIELD_MAPPING
;
1004 /* requires localName and ns to be set */
1005 hr
= WsWriteElement( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1006 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1008 hr
= set_output( writer
);
1009 ok( hr
== S_OK
, "got %08x\n", hr
);
1011 f
.localName
= &localname
;
1013 hr
= WsWriteElement( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1014 ok( hr
== S_OK
, "got %08x\n", hr
);
1015 check_output( writer
, "<str str=\"test\"/>", __LINE__
);
1017 HeapFree( GetProcessHeap(), 0, test
);
1018 WsFreeWriter( writer
);
1021 static void test_WsWriteValue(void)
1024 WS_XML_WRITER
*writer
;
1025 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
1033 const char *result2
;
1037 { WS_BOOL_VALUE_TYPE
, ~0, sizeof(BOOL
), "<t>true</t>", "<t t=\"true\"/>" },
1038 { WS_BOOL_VALUE_TYPE
, FALSE
, sizeof(BOOL
), "<t>false</t>", "<t t=\"false\"/>" },
1039 { WS_INT8_VALUE_TYPE
, -128, sizeof(INT8
), "<t>-128</t>", "<t t=\"-128\"/>" },
1040 { WS_INT16_VALUE_TYPE
, -32768, sizeof(INT16
), "<t>-32768</t>", "<t t=\"-32768\"/>" },
1041 { WS_INT32_VALUE_TYPE
, -2147483647 - 1, sizeof(INT32
), "<t>-2147483648</t>",
1042 "<t t=\"-2147483648\"/>" },
1043 { WS_INT64_VALUE_TYPE
, -9223372036854775807 - 1, sizeof(INT64
), "<t>-9223372036854775808</t>",
1044 "<t t=\"-9223372036854775808\"/>" },
1045 { WS_UINT8_VALUE_TYPE
, 255, sizeof(UINT8
), "<t>255</t>", "<t t=\"255\"/>" },
1046 { WS_UINT16_VALUE_TYPE
, 65535, sizeof(UINT16
), "<t>65535</t>", "<t t=\"65535\"/>" },
1047 { WS_UINT32_VALUE_TYPE
, ~0u, sizeof(UINT32
), "<t>4294967295</t>", "<t t=\"4294967295\"/>" },
1048 { WS_UINT64_VALUE_TYPE
, ~0, sizeof(UINT64
), "<t>18446744073709551615</t>",
1049 "<t t=\"18446744073709551615\"/>" },
1052 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1053 ok( hr
== S_OK
, "got %08x\n", hr
);
1055 hr
= set_output( writer
);
1056 ok( hr
== S_OK
, "got %08x\n", hr
);
1058 hr
= WsWriteValue( NULL
, tests
[0].type
, &tests
[0].val
, tests
[0].size
, NULL
);
1059 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1061 hr
= WsWriteValue( writer
, tests
[0].type
, &tests
[0].val
, tests
[0].size
, NULL
);
1062 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1064 hr
= set_output( writer
);
1065 ok( hr
== S_OK
, "got %08x\n", hr
);
1067 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1068 ok( hr
== S_OK
, "got %08x\n", hr
);
1071 hr
= WsWriteValue( writer
, tests
[0].type
, &tests
[0].val
, 0, NULL
);
1072 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1074 hr
= set_output( writer
);
1075 ok( hr
== S_OK
, "got %08x\n", hr
);
1077 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1078 ok( hr
== S_OK
, "got %08x\n", hr
);
1081 hr
= WsWriteValue( writer
, tests
[0].type
, NULL
, 0, NULL
);
1082 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1084 /* element type mapping */
1085 for (i
= 0; i
< sizeof(tests
)/sizeof(tests
[0]); i
++)
1087 hr
= set_output( writer
);
1088 ok( hr
== S_OK
, "got %08x\n", hr
);
1090 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1091 ok( hr
== S_OK
, "got %08x\n", hr
);
1093 hr
= WsWriteValue( writer
, tests
[i
].type
, &tests
[i
].val
, tests
[i
].size
, NULL
);
1094 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
1096 hr
= WsWriteEndElement( writer
, NULL
);
1097 ok( hr
== S_OK
, "got %08x\n", hr
);
1098 check_output( writer
, tests
[i
].result
, __LINE__
);
1101 /* attribute type mapping */
1102 for (i
= 0; i
< sizeof(tests
)/sizeof(tests
[0]); i
++)
1104 hr
= set_output( writer
);
1105 ok( hr
== S_OK
, "got %08x\n", hr
);
1107 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1108 ok( hr
== S_OK
, "got %08x\n", hr
);
1110 hr
= WsWriteStartAttribute( writer
, NULL
, &localname
, &ns
, FALSE
, NULL
);
1111 ok( hr
== S_OK
, "got %08x\n", hr
);
1113 hr
= WsWriteValue( writer
, tests
[i
].type
, &tests
[i
].val
, tests
[i
].size
, NULL
);
1114 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
1116 hr
= WsWriteEndAttribute( writer
, NULL
);
1117 ok( hr
== S_OK
, "got %08x\n", hr
);
1119 hr
= WsWriteEndElement( writer
, NULL
);
1120 ok( hr
== S_OK
, "got %08x\n", hr
);
1121 check_output( writer
, tests
[i
].result2
, __LINE__
);
1124 WsFreeWriter( writer
);
1127 static void test_WsWriteAttribute(void)
1129 static const WCHAR testW
[] = {'t','e','s','t',0};
1131 WS_XML_WRITER
*writer
;
1132 WS_STRUCT_DESCRIPTION s
;
1133 WS_FIELD_DESCRIPTION f
, *fields
[1];
1134 WS_ATTRIBUTE_DESCRIPTION desc
;
1135 WS_XML_STRING localname
= {3, (BYTE
*)"str"}, ns
= {0, NULL
};
1136 struct test
{ const WCHAR
*str
; } *test
;
1138 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1139 ok( hr
== S_OK
, "got %08x\n", hr
);
1141 hr
= set_output( writer
);
1142 ok( hr
== S_OK
, "got %08x\n", hr
);
1144 /* text field mapping */
1145 memset( &f
, 0, sizeof(f
) );
1146 f
.mapping
= WS_TEXT_FIELD_MAPPING
;
1147 f
.type
= WS_WSZ_TYPE
;
1150 memset( &s
, 0, sizeof(s
) );
1151 s
.size
= sizeof(struct test
);
1152 s
.alignment
= TYPE_ALIGNMENT(struct test
);
1156 desc
.attributeLocalName
= &localname
;
1157 desc
.attributeNs
= &ns
;
1158 desc
.type
= WS_STRUCT_TYPE
;
1159 desc
.typeDescription
= &s
;
1161 test
= HeapAlloc( GetProcessHeap(), 0, sizeof(*test
) );
1163 hr
= WsWriteAttribute( NULL
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1164 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1166 hr
= WsWriteAttribute( writer
, NULL
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1167 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1169 hr
= WsWriteAttribute( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, NULL
, 0, NULL
);
1170 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1172 hr
= WsWriteAttribute( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1173 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1175 hr
= set_output( writer
);
1176 ok( hr
== S_OK
, "got %08x\n", hr
);
1178 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1179 ok( hr
== S_OK
, "got %08x\n", hr
);
1181 hr
= WsWriteAttribute( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1182 ok( hr
== S_OK
, "got %08x\n", hr
);
1184 hr
= WsWriteEndElement( writer
, NULL
);
1185 ok( hr
== S_OK
, "got %08x\n", hr
);
1186 check_output( writer
, "<str str=\"test\"/>", __LINE__
);
1188 HeapFree( GetProcessHeap(), 0, test
);
1189 WsFreeWriter( writer
);
1192 static void test_WsWriteStartCData(void)
1195 WS_XML_WRITER
*writer
;
1196 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
1197 WS_XML_UTF8_TEXT text
= {{WS_XML_TEXT_TYPE_UTF8
}};
1199 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1200 ok( hr
== S_OK
, "got %08x\n", hr
);
1202 hr
= set_output( writer
);
1203 ok( hr
== S_OK
, "got %08x\n", hr
);
1205 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1206 ok( hr
== S_OK
, "got %08x\n", hr
);
1208 hr
= WsWriteEndCData( writer
, NULL
);
1209 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1211 hr
= set_output( writer
);
1212 ok( hr
== S_OK
, "got %08x\n", hr
);
1214 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1215 ok( hr
== S_OK
, "got %08x\n", hr
);
1216 check_output( writer
, "", __LINE__
);
1218 hr
= WsWriteStartCData( writer
, NULL
);
1219 ok( hr
== S_OK
, "got %08x\n", hr
);
1220 check_output( writer
, "<t><![CDATA[", __LINE__
);
1222 text
.value
.bytes
= (BYTE
*)"<data>";
1223 text
.value
.length
= 6;
1224 hr
= WsWriteText( writer
, &text
.text
, NULL
);
1225 ok( hr
== S_OK
, "got %08x\n", hr
);
1226 check_output( writer
, "<t><![CDATA[<data>", __LINE__
);
1228 hr
= WsWriteEndCData( writer
, NULL
);
1229 ok( hr
== S_OK
, "got %08x\n", hr
);
1230 check_output( writer
, "<t><![CDATA[<data>]]>", __LINE__
);
1232 hr
= WsWriteEndElement( writer
, NULL
);
1233 ok( hr
== S_OK
, "got %08x\n", hr
);
1234 check_output( writer
, "<t><![CDATA[<data>]]></t>", __LINE__
);
1236 WsFreeWriter( writer
);
1239 static void check_output_buffer( WS_XML_BUFFER
*buffer
, const char *expected
, unsigned int line
)
1241 WS_XML_WRITER
*writer
;
1243 ULONG size
= sizeof(bytes
);
1244 int len
= strlen(expected
);
1247 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1248 ok( hr
== S_OK
, "got %08x\n", hr
);
1250 hr
= set_output( writer
);
1251 ok( hr
== S_OK
, "got %08x\n", hr
);
1253 hr
= WsWriteXmlBuffer( writer
, buffer
, NULL
);
1254 ok( hr
== S_OK
, "got %08x\n", hr
);
1256 memset( &bytes
, 0, sizeof(bytes
) );
1257 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
1258 ok( hr
== S_OK
, "%u: got %08x\n", line
, hr
);
1259 ok( bytes
.length
== len
, "%u: got %u expected %u\n", line
, bytes
.length
, len
);
1260 if (bytes
.length
!= len
) return;
1261 ok( !memcmp( bytes
.bytes
, expected
, len
), "%u: got %s expected %s\n", line
, bytes
.bytes
, expected
);
1263 WsFreeWriter( writer
);
1266 static void prepare_xmlns_test( WS_XML_WRITER
*writer
, WS_HEAP
**heap
, WS_XML_BUFFER
**buffer
)
1268 WS_XML_STRING prefix
= {6, (BYTE
*)"prefix"}, localname
= {1, (BYTE
*)"t"}, ns
= {2, (BYTE
*)"ns"};
1271 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, heap
, NULL
);
1272 ok( hr
== S_OK
, "got %08x\n", hr
);
1274 hr
= WsCreateXmlBuffer( *heap
, NULL
, 0, buffer
, NULL
);
1275 ok( hr
== S_OK
, "got %08x\n", hr
);
1277 hr
= WsSetOutputToBuffer( writer
, *buffer
, NULL
, 0, NULL
);
1278 ok( hr
== S_OK
, "got %08x\n", hr
);
1280 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
1281 ok( hr
== S_OK
, "got %08x\n", hr
);
1284 static void test_WsWriteXmlnsAttribute(void)
1286 WS_XML_STRING ns
= {2, (BYTE
*)"ns"}, ns2
= {3, (BYTE
*)"ns2"};
1287 WS_XML_STRING prefix
= {6, (BYTE
*)"prefix"}, prefix2
= {7, (BYTE
*)"prefix2"};
1288 WS_XML_STRING xmlns
= {6, (BYTE
*)"xmlns"}, attr
= {4, (BYTE
*)"attr"};
1289 WS_XML_STRING localname
= {1, (BYTE
*)"u"};
1291 WS_XML_BUFFER
*buffer
;
1292 WS_XML_WRITER
*writer
;
1295 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1296 ok( hr
== S_OK
, "got %08x\n", hr
);
1298 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
1299 ok( hr
== S_OK
, "got %08x\n", hr
);
1301 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1302 ok( hr
== S_OK
, "got %08x\n", hr
);
1304 hr
= WsWriteXmlnsAttribute( NULL
, NULL
, NULL
, FALSE
, NULL
);
1305 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1308 prepare_xmlns_test( writer
, &heap
, &buffer
);
1309 hr
= WsWriteXmlnsAttribute( writer
, NULL
, NULL
, FALSE
, NULL
);
1310 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1313 prepare_xmlns_test( writer
, &heap
, &buffer
);
1314 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, NULL
, FALSE
, NULL
);
1315 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1317 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
1318 ok( hr
== S_OK
, "got %08x\n", hr
);
1319 hr
= WsWriteXmlnsAttribute( writer
, NULL
, &ns
, FALSE
, NULL
);
1320 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1324 prepare_xmlns_test( writer
, &heap
, &buffer
);
1325 hr
= WsWriteXmlnsAttribute( writer
, NULL
, &ns2
, FALSE
, NULL
);
1326 ok( hr
== S_OK
, "got %08x\n", hr
);
1327 hr
= WsWriteEndElement( writer
, NULL
);
1328 ok( hr
== S_OK
, "got %08x\n", hr
);
1329 check_output_buffer( buffer
, "<prefix:t xmlns:prefix=\"ns\" xmlns=\"ns2\"/>", __LINE__
);
1333 prepare_xmlns_test( writer
, &heap
, &buffer
);
1334 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns2
, FALSE
, NULL
);
1335 ok( hr
== S_OK
, "got %08x\n", hr
);
1336 hr
= WsWriteEndElement( writer
, NULL
);
1337 ok( hr
== S_OK
, "got %08x\n", hr
);
1338 check_output_buffer( buffer
, "<prefix:t xmlns:prefix2=\"ns2\" xmlns:prefix=\"ns\"/>", __LINE__
);
1341 /* implicitly set element prefix namespace */
1342 prepare_xmlns_test( writer
, &heap
, &buffer
);
1343 hr
= WsWriteEndElement( writer
, NULL
);
1344 ok( hr
== S_OK
, "got %08x\n", hr
);
1345 check_output_buffer( buffer
, "<prefix:t xmlns:prefix=\"ns\"/>", __LINE__
);
1348 /* explicitly set element prefix namespace */
1349 prepare_xmlns_test( writer
, &heap
, &buffer
);
1350 hr
= WsWriteXmlnsAttribute( writer
, &prefix
, &ns
, TRUE
, NULL
);
1351 ok( hr
== S_OK
, "got %08x\n", hr
);
1352 hr
= WsWriteEndElement( writer
, NULL
);
1353 ok( hr
== S_OK
, "got %08x\n", hr
);
1354 check_output_buffer( buffer
, "<prefix:t xmlns:prefix='ns'/>", __LINE__
);
1357 /* repeated calls, same namespace */
1358 prepare_xmlns_test( writer
, &heap
, &buffer
);
1359 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns
, FALSE
, NULL
);
1360 ok( hr
== S_OK
, "got %08x\n", hr
);
1361 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns
, FALSE
, NULL
);
1362 ok( hr
== S_OK
, "got %08x\n", hr
);
1363 hr
= WsWriteEndElement( writer
, NULL
);
1364 ok( hr
== S_OK
, "got %08x\n", hr
);
1365 check_output_buffer( buffer
, "<prefix:t xmlns:prefix2=\"ns\" xmlns:prefix=\"ns\"/>", __LINE__
);
1368 /* repeated calls, different namespace */
1369 prepare_xmlns_test( writer
, &heap
, &buffer
);
1370 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns
, FALSE
, NULL
);
1371 ok( hr
== S_OK
, "got %08x\n", hr
);
1372 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns2
, FALSE
, NULL
);
1373 ok( hr
== S_OK
, "got %08x\n", hr
);
1374 hr
= WsWriteEndElement( writer
, NULL
);
1375 todo_wine
ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1379 prepare_xmlns_test( writer
, &heap
, &buffer
);
1380 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns
, TRUE
, NULL
);
1381 ok( hr
== S_OK
, "got %08x\n", hr
);
1382 hr
= WsWriteEndElement( writer
, NULL
);
1383 ok( hr
== S_OK
, "got %08x\n", hr
);
1384 check_output_buffer( buffer
, "<prefix:t xmlns:prefix2='ns' xmlns:prefix=\"ns\"/>", __LINE__
);
1387 /* different namespace, different prefix */
1388 prepare_xmlns_test( writer
, &heap
, &buffer
);
1389 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns2
, TRUE
, NULL
);
1390 ok( hr
== S_OK
, "got %08x\n", hr
);
1391 hr
= WsWriteEndElement( writer
, NULL
);
1392 ok( hr
== S_OK
, "got %08x\n", hr
);
1393 check_output_buffer( buffer
, "<prefix:t xmlns:prefix2='ns2' xmlns:prefix=\"ns\"/>", __LINE__
);
1396 /* different namespace, same prefix */
1397 prepare_xmlns_test( writer
, &heap
, &buffer
);
1398 hr
= WsWriteXmlnsAttribute( writer
, &prefix
, &ns2
, TRUE
, NULL
);
1399 ok( hr
== S_OK
, "got %08x\n", hr
);
1400 hr
= WsWriteEndElement( writer
, NULL
);
1401 todo_wine
ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1404 /* regular attribute */
1405 prepare_xmlns_test( writer
, &heap
, &buffer
);
1406 hr
= WsWriteStartAttribute( writer
, &xmlns
, &prefix2
, &ns2
, TRUE
, NULL
);
1407 ok( hr
== S_OK
, "got %08x\n", hr
);
1408 hr
= WsWriteEndAttribute( writer
, NULL
);
1409 ok( hr
== S_OK
, "got %08x\n", hr
);
1410 hr
= WsWriteEndElement( writer
, NULL
);
1411 todo_wine
ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1414 /* attribute order */
1415 prepare_xmlns_test( writer
, &heap
, &buffer
);
1416 hr
= WsWriteXmlnsAttribute( writer
, &prefix
, &ns
, TRUE
, NULL
);
1417 ok( hr
== S_OK
, "got %08x\n", hr
);
1418 hr
= WsWriteStartAttribute( writer
, &prefix
, &attr
, &ns
, TRUE
, NULL
);
1419 ok( hr
== S_OK
, "got %08x\n", hr
);
1420 hr
= WsWriteEndAttribute( writer
, NULL
);
1421 ok( hr
== S_OK
, "got %08x\n", hr
);
1422 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns2
, TRUE
, NULL
);
1423 ok( hr
== S_OK
, "got %08x\n", hr
);
1424 hr
= WsWriteEndElement( writer
, NULL
);
1425 ok( hr
== S_OK
, "got %08x\n", hr
);
1426 check_output_buffer( buffer
, "<prefix:t prefix:attr='' xmlns:prefix='ns' xmlns:prefix2='ns2'/>", __LINE__
);
1430 prepare_xmlns_test( writer
, &heap
, &buffer
);
1431 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns2
, TRUE
, NULL
);
1432 ok( hr
== S_OK
, "got %08x\n", hr
);
1433 hr
= WsWriteStartElement( writer
, &prefix2
, &localname
, &ns2
, NULL
);
1434 ok( hr
== S_OK
, "got %08x\n", hr
);
1435 hr
= WsWriteEndElement( writer
, NULL
);
1436 ok( hr
== S_OK
, "got %08x\n", hr
);
1437 hr
= WsWriteEndElement( writer
, NULL
);
1438 ok( hr
== S_OK
, "got %08x\n", hr
);
1439 check_output_buffer( buffer
, "<prefix:t xmlns:prefix2='ns2' xmlns:prefix=\"ns\"><prefix2:u/></prefix:t>",
1443 WsFreeWriter( writer
);
1446 static void prepare_prefix_test( WS_XML_WRITER
*writer
)
1448 const WS_XML_STRING p
= {1, (BYTE
*)"p"}, localname
= {1, (BYTE
*)"t"}, ns
= {2, (BYTE
*)"ns"};
1451 hr
= set_output( writer
);
1452 ok( hr
== S_OK
, "got %08x\n", hr
);
1453 hr
= WsWriteStartElement( writer
, &p
, &localname
, &ns
, NULL
);
1454 ok( hr
== S_OK
, "got %08x\n", hr
);
1455 hr
= WsWriteEndStartElement( writer
, NULL
);
1456 ok( hr
== S_OK
, "got %08x\n", hr
);
1459 static void test_WsGetPrefixFromNamespace(void)
1461 const WS_XML_STRING p
= {1, (BYTE
*)"p"}, localname
= {1, (BYTE
*)"t"}, *prefix
;
1462 const WS_XML_STRING ns
= {2, (BYTE
*)"ns"}, ns2
= {3, (BYTE
*)"ns2"};
1463 WS_XML_WRITER
*writer
;
1466 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1467 ok( hr
== S_OK
, "got %08x\n", hr
);
1469 hr
= set_output( writer
);
1470 ok( hr
== S_OK
, "got %08x\n", hr
);
1471 hr
= WsWriteStartElement( writer
, &p
, &localname
, &ns
, NULL
);
1472 ok( hr
== S_OK
, "got %08x\n", hr
);
1474 hr
= WsGetPrefixFromNamespace( NULL
, NULL
, FALSE
, NULL
, NULL
);
1475 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1477 hr
= WsGetPrefixFromNamespace( NULL
, NULL
, FALSE
, &prefix
, NULL
);
1478 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1480 hr
= WsGetPrefixFromNamespace( writer
, NULL
, FALSE
, &prefix
, NULL
);
1481 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1483 /* element must be committed */
1484 hr
= set_output( writer
);
1485 ok( hr
== S_OK
, "got %08x\n", hr
);
1486 hr
= WsWriteStartElement( writer
, &p
, &localname
, &ns
, NULL
);
1487 ok( hr
== S_OK
, "got %08x\n", hr
);
1488 hr
= WsGetPrefixFromNamespace( writer
, &ns
, TRUE
, &prefix
, NULL
);
1489 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1491 /* but writer can't be positioned on end element node */
1492 hr
= set_output( writer
);
1493 ok( hr
== S_OK
, "got %08x\n", hr
);
1494 hr
= WsWriteStartElement( writer
, &p
, &localname
, &ns
, NULL
);
1495 ok( hr
== S_OK
, "got %08x\n", hr
);
1496 hr
= WsWriteEndElement( writer
, NULL
);
1497 ok( hr
== S_OK
, "got %08x\n", hr
);
1498 hr
= WsGetPrefixFromNamespace( writer
, &ns
, TRUE
, &prefix
, NULL
);
1499 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1501 /* required = TRUE */
1503 prepare_prefix_test( writer
);
1504 hr
= WsGetPrefixFromNamespace( writer
, &ns
, TRUE
, &prefix
, NULL
);
1505 ok( hr
== S_OK
, "got %08x\n", hr
);
1506 ok( prefix
!= NULL
, "prefix not set\n" );
1509 ok( prefix
->length
== 1, "got %u\n", prefix
->length
);
1510 ok( !memcmp( prefix
->bytes
, "p", 1 ), "wrong prefix\n" );
1513 prefix
= (const WS_XML_STRING
*)0xdeadbeef;
1514 hr
= WsGetPrefixFromNamespace( writer
, &ns2
, TRUE
, &prefix
, NULL
);
1515 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1516 ok( prefix
== (const WS_XML_STRING
*)0xdeadbeef, "prefix set\n" );
1518 /* required = FALSE */
1520 prepare_prefix_test( writer
);
1521 hr
= WsGetPrefixFromNamespace( writer
, &ns
, FALSE
, &prefix
, NULL
);
1522 ok( hr
== S_OK
, "got %08x\n", hr
);
1523 ok( prefix
!= NULL
, "prefix not set\n" );
1526 ok( prefix
->length
== 1, "got %u\n", prefix
->length
);
1527 ok( !memcmp( prefix
->bytes
, "p", 1 ), "wrong prefix\n" );
1530 prefix
= (const WS_XML_STRING
*)0xdeadbeef;
1531 hr
= WsGetPrefixFromNamespace( writer
, &ns2
, FALSE
, &prefix
, NULL
);
1532 ok( hr
== S_FALSE
, "got %08x\n", hr
);
1533 ok( prefix
== NULL
, "prefix not set\n" );
1535 WsFreeWriter( writer
);
1538 static void test_complex_struct_type(void)
1540 static const char expected
[] =
1541 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
1542 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\"/>"
1543 "</o:OfficeConfig>";
1544 static const WCHAR timestampW
[] =
1545 {'2','0','1','5','-','0','9','-','0','3','T','1','8',':','4','7',':','5','4',0};
1546 WS_XML_STRING str_officeconfig
= {12, (BYTE
*)"OfficeConfig"};
1547 WS_XML_STRING str_services
= {8, (BYTE
*)"services"};
1548 WS_XML_STRING str_generationtime
= {14, (BYTE
*)"GenerationTime"};
1549 WS_XML_STRING ns
= {39, (BYTE
*)"urn:schemas-microsoft-com:office:office"};
1550 WS_XML_STRING prefix
= {1, (BYTE
*)"o"};
1554 WS_XML_BUFFER
*buffer
;
1555 WS_XML_WRITER
*writer
;
1556 WS_STRUCT_DESCRIPTION s
, s2
;
1557 WS_FIELD_DESCRIPTION f
, f2
, *fields
[1], *fields2
[1];
1560 const WCHAR
*generationtime
;
1564 struct services
*services
;
1567 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1568 ok( hr
== S_OK
, "got %08x\n", hr
);
1570 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1571 ok( hr
== S_OK
, "got %08x\n", hr
);
1573 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
1574 ok( hr
== S_OK
, "got %08x\n", hr
);
1576 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
1577 ok( hr
== S_OK
, "got %08x\n", hr
);
1579 hr
= WsWriteStartElement( writer
, &prefix
, &str_officeconfig
, &ns
, NULL
);
1580 ok( hr
== S_OK
, "got %08x\n", hr
);
1582 memset( &f2
, 0, sizeof(f2
) );
1583 f2
.mapping
= WS_ATTRIBUTE_FIELD_MAPPING
;
1584 f2
.localName
= &str_generationtime
;
1586 f2
.type
= WS_WSZ_TYPE
;
1587 f2
.options
= WS_FIELD_OPTIONAL
;
1590 memset( &s2
, 0, sizeof(s2
) );
1591 s2
.size
= sizeof(*test
->services
);
1593 s2
.fields
= fields2
;
1595 s2
.typeLocalName
= &str_services
;
1598 memset( &f
, 0, sizeof(f
) );
1599 f
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
1600 f
.localName
= &str_services
;
1602 f
.type
= WS_STRUCT_TYPE
;
1603 f
.typeDescription
= &s2
;
1604 f
.options
= WS_FIELD_POINTER
;
1607 memset( &s
, 0, sizeof(s
) );
1608 s
.size
= sizeof(*test
);
1612 s
.typeLocalName
= &str_officeconfig
;
1615 size
= sizeof(struct officeconfig
) + sizeof(struct services
);
1616 test
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
1617 test
->services
= (struct services
*)(test
+ 1);
1618 test
->services
->generationtime
= timestampW
;
1619 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
1620 WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1621 ok( hr
== S_OK
, "got %08x\n", hr
);
1623 hr
= WsWriteEndElement( writer
, NULL
);
1624 ok( hr
== S_OK
, "got %08x\n", hr
);
1625 check_output_buffer( buffer
, expected
, __LINE__
);
1627 HeapFree( GetProcessHeap(), 0, test
);
1628 WsFreeWriter( writer
);
1632 static void test_WsMoveWriter(void)
1634 WS_XML_STRING localname
= {1, (BYTE
*)"a"}, localname2
= {1, (BYTE
*)"b"}, ns
= {0, NULL
};
1636 WS_XML_WRITER
*writer
;
1637 WS_XML_BUFFER
*buffer
;
1640 hr
= WsMoveWriter( NULL
, WS_MOVE_TO_EOF
, NULL
, NULL
);
1641 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1643 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1644 ok( hr
== S_OK
, "got %08x\n", hr
);
1646 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1647 ok( hr
== S_OK
, "got %08x\n", hr
);
1649 hr
= set_output( writer
);
1650 ok( hr
== S_OK
, "got %08x\n", hr
);
1652 /* writer must be set to an XML buffer */
1653 hr
= WsMoveWriter( writer
, WS_MOVE_TO_EOF
, NULL
, NULL
);
1654 todo_wine
ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1656 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
1657 ok( hr
== S_OK
, "got %08x\n", hr
);
1659 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
1660 ok( hr
== S_OK
, "got %08x\n", hr
);
1662 hr
= WsMoveWriter( writer
, WS_MOVE_TO_EOF
, NULL
, NULL
);
1663 ok( hr
== S_OK
, "got %08x\n", hr
);
1666 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1667 ok( hr
== S_OK
, "got %08x\n", hr
);
1669 hr
= WsWriteStartElement( writer
, NULL
, &localname2
, &ns
, NULL
);
1670 ok( hr
== S_OK
, "got %08x\n", hr
);
1672 hr
= WsWriteEndElement( writer
, NULL
);
1673 ok( hr
== S_OK
, "got %08x\n", hr
);
1675 hr
= WsWriteEndElement( writer
, NULL
);
1676 ok( hr
== S_OK
, "got %08x\n", hr
);
1678 hr
= WsMoveWriter( writer
, WS_MOVE_TO_EOF
, NULL
, NULL
);
1679 ok( hr
== S_OK
, "got %08x\n", hr
);
1681 hr
= WsMoveWriter( writer
, WS_MOVE_TO_ROOT_ELEMENT
, NULL
, NULL
);
1682 ok( hr
== S_OK
, "got %08x\n", hr
);
1684 hr
= WsMoveWriter( writer
, WS_MOVE_TO_CHILD_ELEMENT
, NULL
, NULL
);
1685 ok( hr
== S_OK
, "got %08x\n", hr
);
1687 hr
= WsMoveWriter( writer
, WS_MOVE_TO_END_ELEMENT
, NULL
, NULL
);
1688 ok( hr
== S_OK
, "got %08x\n", hr
);
1690 hr
= WsMoveWriter( writer
, WS_MOVE_TO_PARENT_ELEMENT
, NULL
, NULL
);
1691 ok( hr
== S_OK
, "got %08x\n", hr
);
1693 hr
= WsMoveWriter( writer
, WS_MOVE_TO_END_ELEMENT
, NULL
, NULL
);
1694 ok( hr
== S_OK
, "got %08x\n", hr
);
1696 hr
= WsMoveWriter( writer
, WS_MOVE_TO_BOF
, NULL
, NULL
);
1697 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1699 WsFreeWriter( writer
);
1703 static void test_WsGetWriterPosition(void)
1706 WS_XML_WRITER
*writer
;
1707 WS_XML_BUFFER
*buffer
;
1708 WS_XML_NODE_POSITION pos
;
1711 hr
= WsGetWriterPosition( NULL
, NULL
, NULL
);
1712 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1714 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1715 ok( hr
== S_OK
, "got %08x\n", hr
);
1717 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1718 ok( hr
== S_OK
, "got %08x\n", hr
);
1720 hr
= WsGetWriterPosition( writer
, &pos
, NULL
);
1721 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1723 hr
= set_output( writer
);
1724 ok( hr
== S_OK
, "got %08x\n", hr
);
1726 /* writer must be set to an XML buffer */
1727 hr
= WsGetWriterPosition( writer
, &pos
, NULL
);
1728 todo_wine
ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1730 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
1731 ok( hr
== S_OK
, "got %08x\n", hr
);
1733 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
1734 ok( hr
== S_OK
, "got %08x\n", hr
);
1736 hr
= WsGetWriterPosition( writer
, NULL
, NULL
);
1737 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1739 pos
.buffer
= pos
.node
= NULL
;
1740 hr
= WsGetWriterPosition( writer
, &pos
, NULL
);
1741 ok( hr
== S_OK
, "got %08x\n", hr
);
1742 ok( pos
.buffer
!= NULL
, "buffer not set\n" );
1743 ok( pos
.node
!= NULL
, "node not set\n" );
1745 WsFreeWriter( writer
);
1749 static void test_WsSetWriterPosition(void)
1751 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
1753 WS_XML_WRITER
*writer
;
1754 WS_XML_BUFFER
*buf1
, *buf2
;
1755 WS_XML_NODE_POSITION pos
;
1758 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1759 ok( hr
== S_OK
, "got %08x\n", hr
);
1761 hr
= WsSetWriterPosition( NULL
, NULL
, NULL
);
1762 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1764 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1765 ok( hr
== S_OK
, "got %08x\n", hr
);
1767 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buf1
, NULL
);
1768 ok( hr
== S_OK
, "got %08x\n", hr
);
1770 hr
= WsSetOutputToBuffer( writer
, buf1
, NULL
, 0, NULL
);
1771 ok( hr
== S_OK
, "got %08x\n", hr
);
1773 hr
= WsSetWriterPosition( writer
, NULL
, NULL
);
1774 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1776 pos
.buffer
= pos
.node
= NULL
;
1777 hr
= WsGetWriterPosition( writer
, &pos
, NULL
);
1778 ok( hr
== S_OK
, "got %08x\n", hr
);
1779 ok( pos
.buffer
== buf1
, "wrong buffer\n" );
1780 ok( pos
.node
!= NULL
, "node not set\n" );
1782 hr
= WsSetWriterPosition( writer
, &pos
, NULL
);
1783 ok( hr
== S_OK
, "got %08x\n", hr
);
1785 /* different buffer */
1786 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buf2
, NULL
);
1787 ok( hr
== S_OK
, "got %08x\n", hr
);
1790 hr
= WsSetWriterPosition( writer
, &pos
, NULL
);
1791 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1793 hr
= WsSetOutputToBuffer( writer
, buf1
, NULL
, 0, NULL
);
1794 ok( hr
== S_OK
, "got %08x\n", hr
);
1796 /* try to write at non-final position */
1797 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1798 ok( hr
== S_OK
, "got %08x\n", hr
);
1800 pos
.buffer
= pos
.node
= NULL
;
1801 hr
= WsGetWriterPosition( writer
, &pos
, NULL
);
1802 ok( hr
== S_OK
, "got %08x\n", hr
);
1803 ok( pos
.buffer
== buf1
, "wrong buffer\n" );
1804 ok( pos
.node
!= NULL
, "node not set\n" );
1806 hr
= WsWriteEndElement( writer
, NULL
);
1807 ok( hr
== S_OK
, "got %08x\n", hr
);
1808 check_output_buffer( buf1
, "<t/>", __LINE__
);
1810 hr
= WsSetWriterPosition( writer
, &pos
, NULL
);
1811 ok( hr
== S_OK
, "got %08x\n", hr
);
1813 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1814 todo_wine
ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1816 WsFreeWriter( writer
);
1820 static void test_WsWriteXmlBuffer(void)
1822 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
1823 WS_XML_WRITER
*writer1
, *writer2
;
1824 WS_XML_BUFFER
*buffer1
, *buffer2
;
1828 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1829 ok( hr
== S_OK
, "got %08x\n", hr
);
1831 hr
= WsCreateXmlBuffer( NULL
, NULL
, 0, NULL
, NULL
);
1832 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1834 hr
= WsCreateWriter( NULL
, 0, &writer1
, NULL
);
1835 ok( hr
== S_OK
, "got %08x\n", hr
);
1837 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, NULL
, NULL
);
1838 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1840 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer1
, NULL
);
1841 ok( hr
== S_OK
, "got %08x\n", hr
);
1843 hr
= WsSetOutputToBuffer( writer1
, buffer1
, NULL
, 0, NULL
);
1844 ok( hr
== S_OK
, "got %08x\n", hr
);
1846 hr
= WsWriteStartElement( writer1
, NULL
, &localname
, &ns
, NULL
);
1847 ok( hr
== S_OK
, "got %08x\n", hr
);
1849 hr
= WsWriteEndElement( writer1
, NULL
);
1850 ok( hr
== S_OK
, "got %08x\n", hr
);
1851 check_output_buffer( buffer1
, "<t/>", __LINE__
);
1853 hr
= WsCreateWriter( NULL
, 0, &writer2
, NULL
);
1854 ok( hr
== S_OK
, "got %08x\n", hr
);
1856 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer2
, NULL
);
1857 ok( hr
== S_OK
, "got %08x\n", hr
);
1859 hr
= WsSetOutputToBuffer( writer2
, buffer2
, NULL
, 0, NULL
);
1860 ok( hr
== S_OK
, "got %08x\n", hr
);
1862 hr
= WsWriteXmlBuffer( writer2
, buffer1
, NULL
);
1863 ok( hr
== S_OK
, "got %08x\n", hr
);
1864 check_output_buffer( buffer2
, "<t/>", __LINE__
);
1866 hr
= WsMoveWriter( writer2
, WS_MOVE_TO_PREVIOUS_ELEMENT
, NULL
, NULL
);
1867 todo_wine
ok( hr
== S_OK
, "got %08x\n", hr
);
1869 hr
= WsWriteXmlBuffer( writer2
, buffer1
, NULL
);
1870 todo_wine
ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1872 WsFreeWriter( writer1
);
1873 WsFreeWriter( writer2
);
1877 static void test_WsWriteNode(void)
1879 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {4, (BYTE
*)"attr"}, ns
= {0, NULL
};
1880 WS_XML_WRITER
*writer
;
1881 WS_XML_BUFFER
*buffer
;
1882 WS_XML_UTF8_TEXT utf8
= {{WS_XML_TEXT_TYPE_UTF8
}};
1883 WS_XML_ATTRIBUTE attr
, *attrs
[1];
1884 WS_XML_ELEMENT_NODE elem
;
1885 WS_XML_COMMENT_NODE comment
= {{WS_XML_NODE_TYPE_COMMENT
}};
1887 WS_XML_TEXT_NODE text
= {{WS_XML_NODE_TYPE_TEXT
}};
1891 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1892 ok( hr
== S_OK
, "got %08x\n", hr
);
1894 hr
= WsWriteNode( NULL
, NULL
, NULL
);
1895 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1897 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1898 ok( hr
== S_OK
, "got %08x\n", hr
);
1900 hr
= WsWriteNode( writer
, NULL
, NULL
);
1901 todo_wine
ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1903 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
1904 ok( hr
== S_OK
, "got %08x\n", hr
);
1906 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
1907 ok( hr
== S_OK
, "got %08x\n", hr
);
1909 utf8
.value
.bytes
= (BYTE
*)"value";
1910 utf8
.value
.length
= sizeof("value") - 1;
1912 attr
.singleQuote
= TRUE
;
1913 attr
.isXmlNs
= FALSE
;
1915 attr
.localName
= &localname2
;
1917 attr
.value
= &utf8
.text
;
1920 elem
.node
.nodeType
= WS_XML_NODE_TYPE_ELEMENT
;
1922 elem
.localName
= &localname
;
1924 elem
.attributeCount
= 1;
1925 elem
.attributes
= attrs
;
1926 elem
.isEmpty
= FALSE
;
1927 hr
= WsWriteNode( writer
, &elem
.node
, NULL
);
1928 ok( hr
== S_OK
, "got %08x\n", hr
);
1930 comment
.value
.bytes
= (BYTE
*)"comment";
1931 comment
.value
.length
= sizeof("comment") - 1;
1932 hr
= WsWriteNode( writer
, &comment
.node
, NULL
);
1933 ok( hr
== S_OK
, "got %08x\n", hr
);
1935 node
.nodeType
= WS_XML_NODE_TYPE_EOF
;
1936 hr
= WsWriteNode( writer
, &node
, NULL
);
1937 ok( hr
== S_OK
, "got %08x\n", hr
);
1939 node
.nodeType
= WS_XML_NODE_TYPE_BOF
;
1940 hr
= WsWriteNode( writer
, &node
, NULL
);
1941 ok( hr
== S_OK
, "got %08x\n", hr
);
1943 node
.nodeType
= WS_XML_NODE_TYPE_CDATA
;
1944 hr
= WsWriteNode( writer
, &node
, NULL
);
1945 ok( hr
== S_OK
, "got %08x\n", hr
);
1947 utf8
.value
.bytes
= (BYTE
*)"cdata";
1948 utf8
.value
.length
= sizeof("cdata") - 1;
1949 text
.text
= &utf8
.text
;
1950 hr
= WsWriteNode( writer
, &text
.node
, NULL
);
1951 ok( hr
== S_OK
, "got %08x\n", hr
);
1953 node
.nodeType
= WS_XML_NODE_TYPE_END_CDATA
;
1954 hr
= WsWriteNode( writer
, &node
, NULL
);
1955 ok( hr
== S_OK
, "got %08x\n", hr
);
1957 utf8
.value
.bytes
= (BYTE
*)"text";
1958 utf8
.value
.length
= sizeof("text") - 1;
1959 hr
= WsWriteNode( writer
, &text
.node
, NULL
);
1960 ok( hr
== S_OK
, "got %08x\n", hr
);
1962 node
.nodeType
= WS_XML_NODE_TYPE_END_ELEMENT
;
1963 hr
= WsWriteNode( writer
, &node
, NULL
);
1964 ok( hr
== S_OK
, "got %08x\n", hr
);
1965 check_output_buffer( buffer
, "<t attr='value'><!--comment--><![CDATA[cdata]]>text</t>", __LINE__
);
1967 WsFreeWriter( writer
);
1971 static HRESULT
set_input( WS_XML_READER
*reader
, const char *data
, ULONG size
)
1973 WS_XML_READER_TEXT_ENCODING enc
;
1974 WS_XML_READER_BUFFER_INPUT input
;
1976 enc
.encoding
.encodingType
= WS_XML_READER_ENCODING_TYPE_TEXT
;
1977 enc
.charSet
= WS_CHARSET_AUTO
;
1979 input
.input
.inputType
= WS_XML_READER_INPUT_TYPE_BUFFER
;
1980 input
.encodedData
= (void *)data
;
1981 input
.encodedDataSize
= size
;
1983 return WsSetInput( reader
, &enc
.encoding
, &input
.input
, NULL
, 0, NULL
);
1986 static void test_WsCopyNode(void)
1988 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {1, (BYTE
*)"u"}, ns
= {0, NULL
};
1989 WS_XML_NODE_POSITION pos
, pos2
;
1990 const WS_XML_NODE
*node
;
1991 WS_XML_WRITER
*writer
;
1992 WS_XML_READER
*reader
;
1993 WS_XML_BUFFER
*buffer
;
1998 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1999 ok( hr
== S_OK
, "got %08x\n", hr
);
2001 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2002 ok( hr
== S_OK
, "got %08x\n", hr
);
2004 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
2005 ok( hr
== S_OK
, "got %08x\n", hr
);
2007 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
2008 ok( hr
== S_OK
, "got %08x\n", hr
);
2010 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2011 ok( hr
== S_OK
, "got %08x\n", hr
);
2013 hr
= WsWriteStartElement( writer
, NULL
, &localname2
, &ns
, NULL
);
2014 ok( hr
== S_OK
, "got %08x\n", hr
);
2016 hr
= WsWriteEndElement( writer
, NULL
);
2017 ok( hr
== S_OK
, "got %08x\n", hr
);
2019 hr
= WsGetWriterPosition( writer
, &pos
, NULL
);
2020 ok( hr
== S_OK
, "got %08x\n", hr
);
2022 hr
= WsWriteEndElement( writer
, NULL
);
2023 ok( hr
== S_OK
, "got %08x\n", hr
);
2024 check_output_buffer( buffer
, "<t><u/></t>", __LINE__
);
2026 hr
= WsCreateReader( NULL
, 0, &reader
, NULL
);
2027 ok( hr
== S_OK
, "got %08x\n", hr
);
2029 hr
= set_input( reader
, "<v/>", sizeof("<v/>") - 1 );
2030 ok( hr
== S_OK
, "got %08x\n", hr
);
2032 hr
= WsFillReader( reader
, sizeof("<v/>") - 1, NULL
, NULL
);
2033 ok( hr
== S_OK
, "got %08x\n", hr
);
2035 hr
= WsReadToStartElement( reader
, NULL
, NULL
, NULL
, NULL
);
2036 ok( hr
== S_OK
, "got %08x\n", hr
);
2038 hr
= WsSetWriterPosition( writer
, &pos
, NULL
);
2039 ok( hr
== S_OK
, "got %08x\n", hr
);
2041 hr
= WsCopyNode( writer
, reader
, NULL
);
2042 ok( hr
== S_OK
, "got %08x\n", hr
);
2043 check_output_buffer( buffer
, "<t><u/><v/></t>", __LINE__
);
2045 hr
= WsGetWriterPosition( writer
, &pos2
, NULL
);
2046 ok( hr
== S_OK
, "got %08x\n", hr
);
2047 ok( pos2
.buffer
== pos
.buffer
, "wrong buffer\n" );
2048 ok( pos2
.node
== pos
.node
, "wrong node\n" );
2050 hr
= WsGetReaderNode( reader
, &node
, NULL
);
2051 ok( hr
== S_OK
, "got %08x\n", hr
);
2052 ok( node
->nodeType
== WS_XML_NODE_TYPE_EOF
, "got %u\n", node
->nodeType
);
2054 /* reader positioned at EOF */
2055 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
2056 ok( hr
== S_OK
, "got %08x\n", hr
);
2058 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
2059 ok( hr
== S_OK
, "got %08x\n", hr
);
2061 hr
= WsCopyNode( writer
, reader
, NULL
);
2062 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
2064 /* reader positioned at BOF */
2065 hr
= set_input( reader
, "<v/>", sizeof("<v/>") - 1 );
2066 ok( hr
== S_OK
, "got %08x\n", hr
);
2068 hr
= WsFillReader( reader
, sizeof("<v/>") - 1, NULL
, NULL
);
2069 ok( hr
== S_OK
, "got %08x\n", hr
);
2071 hr
= WsGetReaderNode( reader
, &node
, NULL
);
2072 ok( hr
== S_OK
, "got %08x\n", hr
);
2073 ok( node
->nodeType
== WS_XML_NODE_TYPE_BOF
, "got %u\n", node
->nodeType
);
2075 hr
= set_output( writer
);
2076 ok( hr
== S_OK
, "got %08x\n", hr
);
2078 hr
= WsCopyNode( writer
, reader
, NULL
);
2079 ok( hr
== S_OK
, "got %08x\n", hr
);
2080 check_output( writer
, "<v/>", __LINE__
);
2082 hr
= WsGetReaderNode( reader
, &node
, NULL
);
2083 ok( hr
== S_OK
, "got %08x\n", hr
);
2084 ok( node
->nodeType
== WS_XML_NODE_TYPE_EOF
, "got %u\n", node
->nodeType
);
2086 memset( &bufs
, 0, sizeof(bufs
) );
2087 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BUFFERS
, &bufs
, sizeof(bufs
), NULL
);
2088 ok( hr
== S_OK
, "got %08x\n", hr
);
2089 ok( bufs
.bufferCount
== 1, "got %u\n", bufs
.bufferCount
);
2090 ok( bufs
.buffers
!= NULL
, "buffers not set\n" );
2092 WsFreeReader( reader
);
2093 WsFreeWriter( writer
);
2097 static void test_text_types(void)
2099 static const WCHAR utf16W
[] = {'u','t','f','1','6'};
2100 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
2101 WS_XML_WRITER
*writer
;
2102 static const WS_XML_UTF8_TEXT val_utf8
= { {WS_XML_TEXT_TYPE_UTF8
}, {4, (BYTE
*)"utf8"} };
2103 static WS_XML_UTF16_TEXT val_utf16
= { {WS_XML_TEXT_TYPE_UTF16
} };
2104 static const WS_XML_GUID_TEXT val_guid
= { {WS_XML_TEXT_TYPE_GUID
} };
2105 static const WS_XML_UNIQUE_ID_TEXT val_urn
= { {WS_XML_TEXT_TYPE_UNIQUE_ID
} };
2106 static const WS_XML_BOOL_TEXT val_bool
= { {WS_XML_TEXT_TYPE_BOOL
}, TRUE
};
2107 static const WS_XML_INT32_TEXT val_int32
= { {WS_XML_TEXT_TYPE_INT32
}, -2147483647 - 1 };
2108 static const WS_XML_INT64_TEXT val_int64
= { {WS_XML_TEXT_TYPE_INT64
}, -9223372036854775807 - 1 };
2109 static const WS_XML_UINT64_TEXT val_uint64
= { {WS_XML_TEXT_TYPE_UINT64
}, ~0 };
2110 static const WS_XML_DATETIME_TEXT val_datetime
= { {WS_XML_TEXT_TYPE_DATETIME
}, {0, WS_DATETIME_FORMAT_UTC
} };
2111 static const WS_XML_DOUBLE_TEXT val_double
= { {WS_XML_TEXT_TYPE_DOUBLE
}, 1.1 };
2112 static const WS_XML_BASE64_TEXT val_base64
= { {WS_XML_TEXT_TYPE_BASE64
}, (BYTE
*)"test", 4 };
2115 const WS_XML_TEXT
*text
;
2120 { &val_utf8
.text
, "<t>utf8</t>" },
2121 { &val_utf16
.text
, "<t>utf16</t>" },
2122 { &val_guid
.text
, "<t>00000000-0000-0000-0000-000000000000</t>" },
2123 { &val_urn
.text
, "<t>urn:uuid:00000000-0000-0000-0000-000000000000</t>" },
2124 { &val_bool
.text
, "<t>true</t>" },
2125 { &val_int32
.text
, "<t>-2147483648</t>" },
2126 { &val_int64
.text
, "<t>-9223372036854775808</t>" },
2127 { &val_uint64
.text
, "<t>18446744073709551615</t>" },
2128 { &val_datetime
.text
, "<t>0001-01-01T00:00:00Z</t>" },
2129 { &val_double
.text
, "<t>1.1</t>" },
2130 { &val_base64
.text
, "<t>dGVzdA==</t>" },
2135 val_utf16
.bytes
= (BYTE
*)utf16W
;
2136 val_utf16
.byteCount
= sizeof(utf16W
);
2138 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2139 ok( hr
== S_OK
, "got %08x\n", hr
);
2141 for (i
= 0; i
< sizeof(tests
)/sizeof(tests
[0]); i
++)
2143 hr
= set_output( writer
);
2144 ok( hr
== S_OK
, "got %08x\n", hr
);
2145 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2146 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2148 hr
= WsWriteText( writer
, tests
[i
].text
, NULL
);
2149 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2151 hr
= WsWriteEndElement( writer
, NULL
);
2152 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2153 check_output( writer
, tests
[i
].result
, __LINE__
);
2156 WsFreeWriter( writer
);
2159 static BOOL
get_fpword( unsigned short *ret
)
2161 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
2162 unsigned short fpword
;
2163 __asm__
__volatile__( "fstcw %0" : "=m" (fpword
) );
2170 static void set_fpword( unsigned short fpword
)
2172 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
2173 __asm__
__volatile__( "fldcw %0" : : "m" (fpword
) );
2177 static void test_double(void)
2179 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
2180 unsigned short fpword
;
2190 {-1.0, "<t>-1</t>"},
2191 {1.0000000000000001, "<t>1</t>"},
2192 {1.0000000000000002, "<t>1.0000000000000002</t>"},
2193 {1.0000000000000003, "<t>1.0000000000000002</t>"},
2194 {1.0000000000000004, "<t>1.0000000000000004</t>"},
2195 {100000000000000, "<t>100000000000000</t>"},
2196 {1000000000000000, "<t>1E+15</t>"},
2197 {0.1, "<t>0.1</t>"},
2198 {0.01, "<t>1E-2</t>"},
2199 {-0.1, "<t>-0.1</t>"},
2200 {-0.01, "<t>-1E-2</t>"},
2201 {1.7976931348623158e308
, "<t>1.7976931348623157E+308</t>"},
2202 {-1.7976931348623158e308
, "<t>-1.7976931348623157E+308</t>"},
2205 WS_XML_WRITER
*writer
;
2206 WS_XML_DOUBLE_TEXT text
;
2209 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
) ;
2210 ok( hr
== S_OK
, "got %08x\n", hr
);
2212 text
.text
.textType
= WS_XML_TEXT_TYPE_DOUBLE
;
2213 for (i
= 0; i
< sizeof(tests
)/sizeof(tests
[0]); i
++)
2215 hr
= set_output( writer
);
2216 ok( hr
== S_OK
, "got %08x\n", hr
);
2217 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2218 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2220 text
.value
= tests
[i
].val
;
2221 hr
= WsWriteText( writer
, &text
.text
, NULL
);
2222 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2224 hr
= WsWriteEndElement( writer
, NULL
);
2225 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2226 check_output( writer
, tests
[i
].result
, __LINE__
);
2229 hr
= set_output( writer
);
2230 ok( hr
== S_OK
, "got %08x\n", hr
);
2231 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2232 ok( hr
== S_OK
, "got %08x\n", hr
);
2235 hr
= WsWriteText( writer
, &text
.text
, NULL
);
2236 ok( hr
== S_OK
, "got %08x\n", hr
);
2238 hr
= WsWriteEndElement( writer
, NULL
);
2239 ok( hr
== S_OK
, "got %08x\n", hr
);
2240 check_output( writer
, "<t>NaN</t>", __LINE__
);
2242 hr
= set_output( writer
);
2243 ok( hr
== S_OK
, "got %08x\n", hr
);
2244 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2245 ok( hr
== S_OK
, "got %08x\n", hr
);
2247 text
.value
= INFINITY
;
2248 hr
= WsWriteText( writer
, &text
.text
, NULL
);
2249 ok( hr
== S_OK
, "got %08x\n", hr
);
2251 hr
= WsWriteEndElement( writer
, NULL
);
2252 ok( hr
== S_OK
, "got %08x\n", hr
);
2253 check_output( writer
, "<t>INF</t>", __LINE__
);
2255 hr
= set_output( writer
);
2256 ok( hr
== S_OK
, "got %08x\n", hr
);
2257 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2258 ok( hr
== S_OK
, "got %08x\n", hr
);
2260 text
.value
= -INFINITY
;
2261 hr
= WsWriteText( writer
, &text
.text
, NULL
);
2262 ok( hr
== S_OK
, "got %08x\n", hr
);
2264 hr
= WsWriteEndElement( writer
, NULL
);
2265 ok( hr
== S_OK
, "got %08x\n", hr
);
2266 check_output( writer
, "<t>-INF</t>", __LINE__
);
2268 if (!get_fpword( &fpword
))
2270 skip( "can't get floating point control word\n" );
2271 WsFreeWriter( writer
);
2274 ok( fpword
== 0x27f, "got %04x\n", fpword
);
2275 set_fpword( 0x1f7f );
2276 get_fpword( &fpword
);
2277 ok( fpword
== 0x1f7f, "got %04x\n", fpword
);
2279 hr
= set_output( writer
);
2280 ok( hr
== S_OK
, "got %08x\n", hr
);
2281 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2282 ok( hr
== S_OK
, "got %08x\n", hr
);
2284 text
.value
= 100000000000000;
2285 hr
= WsWriteText( writer
, &text
.text
, NULL
);
2286 ok( hr
== S_OK
, "got %08x\n", hr
);
2288 hr
= WsWriteEndElement( writer
, NULL
);
2289 ok( hr
== S_OK
, "got %08x\n", hr
);
2290 check_output( writer
, "<t>100000000000000</t>", __LINE__
);
2292 get_fpword( &fpword
);
2293 ok( fpword
== 0x1f7f, "got %04x\n", fpword
);
2294 set_fpword( 0x27f );
2296 WsFreeWriter( writer
);
2299 static void test_field_options(void)
2301 static const char expected
[] =
2302 "<t><bool a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/><int32>-1</int32>"
2303 "<xmlstr a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/></t>";
2305 WS_XML_WRITER
*writer
;
2306 WS_STRUCT_DESCRIPTION s
;
2307 WS_FIELD_DESCRIPTION f
, f2
, f3
, f4
, f5
, *fields
[5];
2308 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
}, str_guid
= {4, (BYTE
*)"guid"};
2309 WS_XML_STRING str_int32
= {5, (BYTE
*)"int32"}, str_bool
= {4, (BYTE
*)"bool"};
2310 WS_XML_STRING str_xmlstr
= {6, (BYTE
*)"xmlstr"}, str_str
= {3, (BYTE
*)"str"};
2317 WS_XML_STRING xmlstr
;
2321 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2322 ok( hr
== S_OK
, "got %08x\n", hr
);
2324 hr
= set_output( writer
);
2325 ok( hr
== S_OK
, "got %08x\n", hr
);
2327 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2328 ok( hr
== S_OK
, "got %08x\n", hr
);
2330 memset( &f
, 0, sizeof(f
) );
2331 f
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
2332 f
.localName
= &str_guid
;
2334 f
.type
= WS_GUID_TYPE
;
2335 f
.options
= WS_FIELD_OPTIONAL
;
2338 memset( &f2
, 0, sizeof(f2
) );
2339 f2
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
2340 f2
.localName
= &str_bool
;
2341 f2
.offset
= FIELD_OFFSET(struct test
, bool_ptr
);
2343 f2
.type
= WS_BOOL_TYPE
;
2344 f2
.options
= WS_FIELD_POINTER
|WS_FIELD_NILLABLE
;
2347 memset( &f3
, 0, sizeof(f3
) );
2348 f3
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
2349 f3
.localName
= &str_int32
;
2350 f3
.offset
= FIELD_OFFSET(struct test
, int32_ptr
);
2352 f3
.type
= WS_INT32_TYPE
;
2353 f3
.options
= WS_FIELD_POINTER
|WS_FIELD_NILLABLE
;
2356 memset( &f4
, 0, sizeof(f4
) );
2357 f4
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
2358 f4
.localName
= &str_xmlstr
;
2359 f4
.offset
= FIELD_OFFSET(struct test
, xmlstr
);
2361 f4
.type
= WS_XML_STRING_TYPE
;
2362 f4
.options
= WS_FIELD_NILLABLE
;
2365 memset( &f5
, 0, sizeof(f5
) );
2366 f5
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
2367 f5
.localName
= &str_str
;
2368 f5
.offset
= FIELD_OFFSET(struct test
, str
);
2370 f5
.type
= WS_WSZ_TYPE
;
2371 f5
.options
= WS_FIELD_OPTIONAL
|WS_FIELD_NILLABLE
;
2374 memset( &s
, 0, sizeof(s
) );
2375 s
.size
= sizeof(struct test
);
2376 s
.alignment
= TYPE_ALIGNMENT(struct test
);
2380 memset( &test
, 0, sizeof(test
) );
2381 test
.int32_ptr
= &val
;
2382 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
2383 &test
, sizeof(test
), NULL
);
2384 ok( hr
== S_OK
, "got %08x\n", hr
);
2386 hr
= WsWriteEndElement( writer
, NULL
);
2387 ok( hr
== S_OK
, "got %08x\n", hr
);
2388 check_output( writer
, expected
, __LINE__
);
2390 WsFreeWriter( writer
);
2393 static void test_WsWriteText(void)
2395 static const WCHAR testW
[] = {'t','e','s','t'};
2396 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {1, (BYTE
*)"a"}, ns
= {0, NULL
};
2398 WS_XML_WRITER
*writer
;
2399 WS_XML_UTF8_TEXT utf8
= {{WS_XML_TEXT_TYPE_UTF8
}};
2400 WS_XML_UTF16_TEXT utf16
= {{WS_XML_TEXT_TYPE_UTF16
}};
2401 WS_XML_GUID_TEXT guid
= {{WS_XML_TEXT_TYPE_GUID
}};
2403 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2404 ok( hr
== S_OK
, "got %08x\n", hr
);
2406 hr
= set_output( writer
);
2407 ok( hr
== S_OK
, "got %08x\n", hr
);
2409 utf8
.value
.bytes
= (BYTE
*)"test";
2410 utf8
.value
.length
= 4;
2411 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2412 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
2414 hr
= set_output( writer
);
2415 ok( hr
== S_OK
, "got %08x\n", hr
);
2418 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2419 ok( hr
== S_OK
, "got %08x\n", hr
);
2421 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2422 ok( hr
== S_OK
, "got %08x\n", hr
);
2423 check_output( writer
, "<t>test", __LINE__
);
2425 utf8
.value
.bytes
= (BYTE
*)"tset";
2426 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2427 ok( hr
== S_OK
, "got %08x\n", hr
);
2428 check_output( writer
, "<t>testtset", __LINE__
);
2430 hr
= WsWriteEndElement( writer
, NULL
);
2431 ok( hr
== S_OK
, "got %08x\n", hr
);
2432 check_output( writer
, "<t>testtset</t>", __LINE__
);
2434 hr
= set_output( writer
);
2435 ok( hr
== S_OK
, "got %08x\n", hr
);
2437 /* attribute, utf8 */
2438 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2439 ok( hr
== S_OK
, "got %08x\n", hr
);
2441 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
2442 ok( hr
== S_OK
, "got %08x\n", hr
);
2444 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2445 ok( hr
== S_OK
, "got %08x\n", hr
);
2446 check_output( writer
, "", __LINE__
);
2448 utf8
.value
.bytes
= (BYTE
*)"test";
2449 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2450 ok( hr
== S_OK
, "got %08x\n", hr
);
2451 check_output( writer
, "", __LINE__
);
2453 hr
= WsWriteEndAttribute( writer
, NULL
);
2454 ok( hr
== S_OK
, "got %08x\n", hr
);
2456 hr
= WsWriteEndElement( writer
, NULL
);
2457 ok( hr
== S_OK
, "got %08x\n", hr
);
2458 check_output( writer
, "<t a=\"tsettest\"/>", __LINE__
);
2460 hr
= set_output( writer
);
2461 ok( hr
== S_OK
, "got %08x\n", hr
);
2463 /* element, utf16 */
2464 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2465 ok( hr
== S_OK
, "got %08x\n", hr
);
2467 utf16
.bytes
= (BYTE
*)testW
;
2468 utf16
.byteCount
= sizeof(testW
);
2469 hr
= WsWriteText( writer
, &utf16
.text
, NULL
);
2470 ok( hr
== S_OK
, "got %08x\n", hr
);
2471 check_output( writer
, "<t>test", __LINE__
);
2473 hr
= WsWriteText( writer
, &utf16
.text
, NULL
);
2474 ok( hr
== S_OK
, "got %08x\n", hr
);
2475 check_output( writer
, "<t>testtest", __LINE__
);
2477 hr
= WsWriteEndElement( writer
, NULL
);
2478 ok( hr
== S_OK
, "got %08x\n", hr
);
2479 check_output( writer
, "<t>testtest</t>", __LINE__
);
2481 hr
= set_output( writer
);
2482 ok( hr
== S_OK
, "got %08x\n", hr
);
2484 /* attribute, utf16 */
2485 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2486 ok( hr
== S_OK
, "got %08x\n", hr
);
2488 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
2489 ok( hr
== S_OK
, "got %08x\n", hr
);
2491 hr
= WsWriteText( writer
, &utf16
.text
, NULL
);
2492 ok( hr
== S_OK
, "got %08x\n", hr
);
2493 check_output( writer
, "", __LINE__
);
2495 hr
= WsWriteText( writer
, &utf16
.text
, NULL
);
2496 ok( hr
== S_OK
, "got %08x\n", hr
);
2497 check_output( writer
, "", __LINE__
);
2499 hr
= WsWriteEndAttribute( writer
, NULL
);
2500 ok( hr
== S_OK
, "got %08x\n", hr
);
2502 hr
= WsWriteEndElement( writer
, NULL
);
2503 ok( hr
== S_OK
, "got %08x\n", hr
);
2504 check_output( writer
, "<t a=\"testtest\"/>", __LINE__
);
2506 hr
= set_output( writer
);
2507 ok( hr
== S_OK
, "got %08x\n", hr
);
2510 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2511 ok( hr
== S_OK
, "got %08x\n", hr
);
2513 hr
= WsWriteText( writer
, &guid
.text
, NULL
);
2514 ok( hr
== S_OK
, "got %08x\n", hr
);
2515 check_output( writer
, "<t>00000000-0000-0000-0000-000000000000", __LINE__
);
2517 hr
= WsWriteText( writer
, &guid
.text
, NULL
);
2518 ok( hr
== S_OK
, "got %08x\n", hr
);
2519 check_output( writer
, "<t>00000000-0000-0000-0000-00000000000000000000-0000-0000-0000-000000000000",
2522 /* continue with different text type */
2523 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2524 ok( hr
== S_OK
, "got %08x\n", hr
);
2525 check_output( writer
, "<t>00000000-0000-0000-0000-00000000000000000000-0000-0000-0000-000000000000test",
2528 hr
= WsWriteEndElement( writer
, NULL
);
2529 ok( hr
== S_OK
, "got %08x\n", hr
);
2531 hr
= set_output( writer
);
2532 ok( hr
== S_OK
, "got %08x\n", hr
);
2534 /* attribute, guid */
2535 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2536 ok( hr
== S_OK
, "got %08x\n", hr
);
2538 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
2539 ok( hr
== S_OK
, "got %08x\n", hr
);
2541 hr
= WsWriteText( writer
, &guid
.text
, NULL
);
2542 ok( hr
== S_OK
, "got %08x\n", hr
);
2543 check_output( writer
, "", __LINE__
);
2545 hr
= WsWriteText( writer
, &guid
.text
, NULL
);
2546 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
2548 hr
= set_output( writer
);
2549 ok( hr
== S_OK
, "got %08x\n", hr
);
2551 /* attribute, mix allowed text types */
2552 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2553 ok( hr
== S_OK
, "got %08x\n", hr
);
2555 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
2556 ok( hr
== S_OK
, "got %08x\n", hr
);
2558 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2559 ok( hr
== S_OK
, "got %08x\n", hr
);
2561 hr
= WsWriteText( writer
, &utf16
.text
, NULL
);
2562 todo_wine
ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
2564 hr
= set_output( writer
);
2565 ok( hr
== S_OK
, "got %08x\n", hr
);
2568 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2569 ok( hr
== S_OK
, "got %08x\n", hr
);
2570 hr
= WsWriteStartCData( writer
, NULL
);
2571 ok( hr
== S_OK
, "got %08x\n", hr
);
2573 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2574 ok( hr
== S_OK
, "got %08x\n", hr
);
2576 hr
= WsWriteText( writer
, &guid
.text
, NULL
);
2577 ok( hr
== S_OK
, "got %08x\n", hr
);
2579 hr
= WsWriteEndCData( writer
, NULL
);
2580 ok( hr
== S_OK
, "got %08x\n", hr
);
2581 hr
= WsWriteEndElement( writer
, NULL
);
2582 ok( hr
== S_OK
, "got %08x\n", hr
);
2583 check_output( writer
, "<t><![CDATA[test00000000-0000-0000-0000-000000000000]]></t>", __LINE__
);
2585 WsFreeWriter( writer
);
2588 static void test_WsWriteArray(void)
2590 static const WS_XML_STRING localname
= {4, (BYTE
*)"item"}, localname2
= {5, (BYTE
*)"array"};
2591 static const WS_XML_STRING ns
= {0, NULL
};
2592 WS_XML_WRITER
*writer
;
2596 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2597 ok( hr
== S_OK
, "got %08x\n", hr
);
2599 hr
= WsWriteArray( writer
, NULL
, NULL
, 0, NULL
, 0, 0, 0, NULL
);
2600 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
2602 hr
= set_output( writer
);
2603 ok( hr
== S_OK
, "got %08x\n", hr
);
2604 hr
= WsWriteArray( writer
, NULL
, NULL
, 0, NULL
, 0, 0, 0, NULL
);
2605 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2607 hr
= set_output( writer
);
2608 ok( hr
== S_OK
, "got %08x\n", hr
);
2609 hr
= WsWriteArray( writer
, &localname
, NULL
, 0, NULL
, 0, 0, 0, NULL
);
2610 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2612 hr
= set_output( writer
);
2613 ok( hr
== S_OK
, "got %08x\n", hr
);
2614 hr
= WsWriteArray( writer
, &localname
, &ns
, 0, NULL
, 0, 0, 0, NULL
);
2615 ok( hr
== S_OK
, "got %08x\n", hr
);
2616 check_output( writer
, "", __LINE__
);
2618 hr
= WsWriteArray( writer
, &localname
, &ns
, ~0u, NULL
, 0, 0, 0, NULL
);
2619 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2621 hr
= set_output( writer
);
2622 ok( hr
== S_OK
, "got %08x\n", hr
);
2623 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, NULL
, 0, 0, 0, NULL
);
2624 ok( hr
== S_OK
, "got %08x\n", hr
);
2625 check_output( writer
, "", __LINE__
);
2627 array_bool
[0] = FALSE
;
2628 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, array_bool
, 0, 0, 0, NULL
);
2629 ok( hr
== S_OK
, "got %08x\n", hr
);
2630 check_output( writer
, "", __LINE__
);
2632 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, array_bool
, sizeof(array_bool
), 0, 0, NULL
);
2633 ok( hr
== S_OK
, "got %08x\n", hr
);
2634 check_output( writer
, "", __LINE__
);
2636 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, NULL
, sizeof(array_bool
), 0, 0, NULL
);
2637 ok( hr
== S_OK
, "got %08x\n", hr
);
2638 check_output( writer
, "", __LINE__
);
2640 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, NULL
, sizeof(array_bool
), 0, 1, NULL
);
2641 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2643 hr
= set_output( writer
);
2644 ok( hr
== S_OK
, "got %08x\n", hr
);
2645 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, array_bool
, sizeof(array_bool
), 0, 1, NULL
);
2646 ok( hr
== S_OK
, "got %08x\n", hr
);
2647 check_output( writer
, "<item>false</item>", __LINE__
);
2649 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, array_bool
, sizeof(array_bool
) - 1, 0, 2, NULL
);
2650 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2652 hr
= set_output( writer
);
2653 ok( hr
== S_OK
, "got %08x\n", hr
);
2654 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, array_bool
, sizeof(array_bool
), 0, 3, NULL
);
2655 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2657 hr
= set_output( writer
);
2658 ok( hr
== S_OK
, "got %08x\n", hr
);
2660 hr
= WsWriteStartElement( writer
, NULL
, &localname2
, &ns
, NULL
);
2661 ok( hr
== S_OK
, "got %08x\n", hr
);
2663 array_bool
[1] = TRUE
;
2664 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, array_bool
, sizeof(array_bool
), 0, 2, NULL
);
2665 ok( hr
== S_OK
, "got %08x\n", hr
);
2667 hr
= WsWriteEndElement( writer
, NULL
);
2668 ok( hr
== S_OK
, "got %08x\n", hr
);
2669 check_output( writer
, "<array><item>false</item><item>true</item></array>", __LINE__
);
2671 WsFreeWriter( writer
);
2674 static void test_escapes(void)
2676 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
2677 WS_XML_UTF8_TEXT utf8
= {{WS_XML_TEXT_TYPE_UTF8
}};
2678 WS_XML_WRITER
*writer
;
2685 static const struct test tests_elem
[] =
2687 { "<", "<t><</t>" },
2688 { ">", "<t>></t>" },
2689 { "\"", "<t>\"</t>" },
2690 { "&", "<t>&</t>" },
2691 { "&&", "<t>&&</t>" },
2692 { "'", "<t>'</t>" },
2694 static const struct test tests_attr
[] =
2696 { "<", "<t t=\"<\"/>" },
2697 { ">", "<t t=\">\"/>" },
2698 { "\"", "<t t=\""\"/>" },
2699 { "&", "<t t=\"&\"/>" },
2700 { "'", "<t t=\"'\"/>" },
2701 { "\"", "<t t='\"'/>", TRUE
},
2702 { "'", "<t t='''/>", TRUE
},
2704 static const struct test tests_cdata
[] =
2706 { "<", "<t><![CDATA[<]]></t>" },
2707 { ">", "<t><![CDATA[>]]></t>" },
2708 { "\"", "<t><![CDATA[\"]]></t>" },
2709 { "&", "<t><![CDATA[&]]></t>" },
2710 { "[", "<t><![CDATA[[]]></t>" },
2711 { "]", "<t><![CDATA[]]]></t>" },
2712 { "'", "<t><![CDATA[']]></t>" },
2714 static const struct test tests_comment
[] =
2716 { "<", "<t><!--<--></t>" },
2717 { ">", "<t><!-->--></t>" },
2718 { "\"", "<t><!--\"--></t>" },
2719 { "&", "<t><!--&--></t>" },
2720 { "'", "<t><!--'--></t>" },
2725 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2726 ok( hr
== S_OK
, "got %08x\n", hr
);
2728 for (i
= 0; i
< sizeof(tests_elem
)/sizeof(tests_elem
[0]); i
++)
2730 hr
= set_output( writer
);
2731 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2732 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2733 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2735 utf8
.value
.bytes
= (BYTE
*)tests_elem
[i
].text
;
2736 utf8
.value
.length
= strlen( tests_elem
[i
].text
);
2737 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2738 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2740 hr
= WsWriteEndElement( writer
, NULL
);
2741 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2742 check_output( writer
, tests_elem
[i
].result
, __LINE__
);
2745 for (i
= 0; i
< sizeof(tests_attr
)/sizeof(tests_attr
[0]); i
++)
2747 hr
= set_output( writer
);
2748 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2749 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2750 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2752 hr
= WsWriteStartAttribute( writer
, NULL
, &localname
, &ns
, tests_attr
[i
].single
, NULL
);
2753 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2755 utf8
.value
.bytes
= (BYTE
*)tests_attr
[i
].text
;
2756 utf8
.value
.length
= strlen( tests_attr
[i
].text
);
2757 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2758 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2760 hr
= WsWriteEndAttribute( writer
, NULL
);
2761 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2763 hr
= WsWriteEndElement( writer
, NULL
);
2764 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2765 check_output( writer
, tests_attr
[i
].result
, __LINE__
);
2768 for (i
= 0; i
< sizeof(tests_cdata
)/sizeof(tests_cdata
[0]); i
++)
2770 hr
= set_output( writer
);
2771 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2772 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2773 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2775 hr
= WsWriteStartCData( writer
, NULL
);
2776 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2778 utf8
.value
.bytes
= (BYTE
*)tests_cdata
[i
].text
;
2779 utf8
.value
.length
= strlen( tests_cdata
[i
].text
);
2780 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2781 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2783 hr
= WsWriteEndCData( writer
, NULL
);
2784 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2786 hr
= WsWriteEndElement( writer
, NULL
);
2787 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2788 check_output( writer
, tests_cdata
[i
].result
, __LINE__
);
2791 for (i
= 0; i
< sizeof(tests_comment
)/sizeof(tests_comment
[0]); i
++)
2793 WS_XML_COMMENT_NODE comment
= {{WS_XML_NODE_TYPE_COMMENT
}};
2795 hr
= set_output( writer
);
2796 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2797 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2798 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2800 comment
.value
.bytes
= (BYTE
*)tests_comment
[i
].text
;
2801 comment
.value
.length
= strlen( tests_comment
[i
].text
);
2802 hr
= WsWriteNode( writer
, &comment
.node
, NULL
);
2803 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2805 hr
= WsWriteEndElement( writer
, NULL
);
2806 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2807 check_output( writer
, tests_comment
[i
].result
, __LINE__
);
2810 WsFreeWriter( writer
);
2813 static void test_write_option(void)
2815 static const WCHAR sW
[] = {'s',0};
2816 static const WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
2817 WS_XML_WRITER
*writer
;
2818 int val_int
= -1, val_int_zero
= 0, *ptr_int
= &val_int
, *ptr_int_null
= NULL
;
2819 const WCHAR
*ptr_wsz
= sW
, *ptr_wsz_null
= NULL
;
2820 static const WS_XML_STRING val_xmlstr
= {1, (BYTE
*)"x"}, val_xmlstr_zero
= {0, NULL
};
2821 const WS_XML_STRING
*ptr_xmlstr
= &val_xmlstr
, *ptr_xmlstr_null
= NULL
;
2825 WS_WRITE_OPTION option
;
2833 { WS_INT32_TYPE
, 0, NULL
, 0, E_INVALIDARG
},
2834 { WS_INT32_TYPE
, 0, "str", 0, E_INVALIDARG
},
2835 { WS_INT32_TYPE
, 0, NULL
, sizeof(val_int
), E_INVALIDARG
},
2836 { WS_INT32_TYPE
, 0, &val_int
, sizeof(val_int
), E_INVALIDARG
},
2837 { WS_INT32_TYPE
, 0, &val_int_zero
, sizeof(val_int_zero
), E_INVALIDARG
},
2838 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_VALUE
, NULL
, 0, E_INVALIDARG
},
2839 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_VALUE
, &val_int
, 0, E_INVALIDARG
},
2840 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_VALUE
, NULL
, sizeof(val_int
), E_INVALIDARG
},
2841 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_VALUE
, &val_int
, sizeof(val_int
), S_OK
, "<t>-1</t>" },
2842 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_VALUE
, &val_int_zero
, sizeof(val_int_zero
), S_OK
, "<t>0</t>" },
2843 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_VALUE
, NULL
, 0, E_INVALIDARG
},
2844 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_VALUE
, &val_int
, 0, E_INVALIDARG
},
2845 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_VALUE
, NULL
, sizeof(val_int
), E_INVALIDARG
},
2846 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_VALUE
, &val_int
, sizeof(val_int
), E_INVALIDARG
},
2847 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_VALUE
, &val_int_zero
, sizeof(val_int_zero
), E_INVALIDARG
},
2848 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_POINTER
, NULL
, 0, E_INVALIDARG
},
2849 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_int
, 0, E_INVALIDARG
},
2850 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_POINTER
, NULL
, sizeof(ptr_int
), E_INVALIDARG
},
2851 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_int
, sizeof(ptr_int
), S_OK
, "<t>-1</t>" },
2852 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_int_null
, sizeof(ptr_int_null
), E_INVALIDARG
},
2853 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_POINTER
, NULL
, 0, E_INVALIDARG
},
2854 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_int
, 0, E_INVALIDARG
},
2855 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_POINTER
, NULL
, sizeof(ptr_int
), E_INVALIDARG
},
2856 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_int
, sizeof(ptr_int
), S_OK
, "<t>-1</t>" },
2857 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_int_null
, sizeof(ptr_int_null
), S_OK
,
2858 "<t a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/>" },
2859 { WS_XML_STRING_TYPE
, 0, NULL
, 0, E_INVALIDARG
},
2860 { WS_XML_STRING_TYPE
, 0, &val_xmlstr
, 0, E_INVALIDARG
},
2861 { WS_XML_STRING_TYPE
, 0, NULL
, sizeof(val_xmlstr
), E_INVALIDARG
},
2862 { WS_XML_STRING_TYPE
, 0, &val_xmlstr
, sizeof(val_xmlstr
), E_INVALIDARG
},
2863 { WS_XML_STRING_TYPE
, 0, &val_xmlstr_zero
, sizeof(val_xmlstr_zero
), E_INVALIDARG
},
2864 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_VALUE
, NULL
, 0, E_INVALIDARG
},
2865 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_VALUE
, &val_xmlstr
, 0, E_INVALIDARG
},
2866 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_VALUE
, NULL
, sizeof(&val_xmlstr
), E_INVALIDARG
},
2867 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_VALUE
, &val_xmlstr
, sizeof(val_xmlstr
), S_OK
, "<t>x</t>" },
2868 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_VALUE
, &val_xmlstr_zero
, sizeof(val_xmlstr_zero
), S_OK
, "<t/>" },
2869 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_VALUE
, &val_xmlstr
, 0, E_INVALIDARG
},
2870 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_VALUE
, NULL
, sizeof(&val_xmlstr
), E_INVALIDARG
},
2871 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_VALUE
, &val_xmlstr
, sizeof(&val_xmlstr
), E_INVALIDARG
},
2872 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_VALUE
, &val_xmlstr_zero
, sizeof(val_xmlstr_zero
), S_OK
,
2873 "<t a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/>" },
2874 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_POINTER
, NULL
, 0, E_INVALIDARG
},
2875 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_xmlstr
, 0, E_INVALIDARG
},
2876 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_POINTER
, NULL
, sizeof(ptr_xmlstr
), E_INVALIDARG
},
2877 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_xmlstr
, sizeof(ptr_xmlstr
), S_OK
, "<t>x</t>" },
2878 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_xmlstr_null
, sizeof(ptr_xmlstr_null
), E_INVALIDARG
},
2879 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_POINTER
, NULL
, 0, E_INVALIDARG
},
2880 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_xmlstr
, 0, E_INVALIDARG
},
2881 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_POINTER
, NULL
, sizeof(ptr_xmlstr
), E_INVALIDARG
},
2882 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_xmlstr
, sizeof(ptr_xmlstr
), S_OK
, "<t>x</t>" },
2883 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_xmlstr_null
, sizeof(ptr_xmlstr_null
), S_OK
,
2884 "<t a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/>" },
2885 { WS_WSZ_TYPE
, 0, NULL
, 0, E_INVALIDARG
},
2886 { WS_WSZ_TYPE
, 0, &ptr_wsz
, 0, E_INVALIDARG
},
2887 { WS_WSZ_TYPE
, 0, NULL
, sizeof(ptr_wsz
), E_INVALIDARG
},
2888 { WS_WSZ_TYPE
, 0, &ptr_wsz
, sizeof(ptr_wsz
), E_INVALIDARG
},
2889 { WS_WSZ_TYPE
, 0, &ptr_wsz_null
, sizeof(ptr_wsz_null
), E_INVALIDARG
},
2890 { WS_WSZ_TYPE
, WS_WRITE_REQUIRED_VALUE
, &ptr_wsz
, sizeof(ptr_wsz
), E_INVALIDARG
},
2891 { WS_WSZ_TYPE
, WS_WRITE_NILLABLE_VALUE
, &ptr_wsz
, sizeof(ptr_wsz
), E_INVALIDARG
},
2892 { WS_WSZ_TYPE
, WS_WRITE_REQUIRED_POINTER
, NULL
, 0, E_INVALIDARG
},
2893 { WS_WSZ_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_wsz
, 0, E_INVALIDARG
},
2894 { WS_WSZ_TYPE
, WS_WRITE_REQUIRED_POINTER
, NULL
, sizeof(ptr_wsz
), E_INVALIDARG
},
2895 { WS_WSZ_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_wsz
, sizeof(ptr_wsz
), S_OK
, "<t>s</t>" },
2896 { WS_WSZ_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_wsz_null
, sizeof(ptr_wsz_null
), E_INVALIDARG
},
2897 { WS_WSZ_TYPE
, WS_WRITE_NILLABLE_POINTER
, NULL
, 0, E_INVALIDARG
},
2898 { WS_WSZ_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_wsz
, 0, E_INVALIDARG
},
2899 { WS_WSZ_TYPE
, WS_WRITE_NILLABLE_POINTER
, NULL
, sizeof(ptr_wsz
), E_INVALIDARG
},
2900 { WS_WSZ_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_wsz
, sizeof(ptr_wsz
), S_OK
, "<t>s</t>" },
2901 { WS_WSZ_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_wsz_null
, sizeof(ptr_wsz_null
), S_OK
,
2902 "<t a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/>" },
2907 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2908 ok( hr
== S_OK
, "got %08x\n", hr
);
2910 for (i
= 0; i
< sizeof(tests
)/sizeof(tests
[0]); i
++)
2912 hr
= set_output( writer
);
2913 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2914 WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2915 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, tests
[i
].type
, NULL
, tests
[i
].option
, tests
[i
].value
,
2916 tests
[i
].size
, NULL
);
2917 ok( hr
== tests
[i
].hr
, "%u: got %08x\n", i
, hr
);
2918 WsWriteEndElement( writer
, NULL
);
2919 if (hr
== S_OK
) check_output( writer
, tests
[i
].result
, __LINE__
);
2922 WsFreeWriter( writer
);
2925 static BOOL
check_result( WS_XML_WRITER
*writer
, const char *expected
)
2928 ULONG size
= sizeof(bytes
);
2929 int len
= strlen( expected
);
2931 memset( &bytes
, 0, sizeof(bytes
) );
2932 WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
2933 if (bytes
.length
!= len
) return FALSE
;
2934 return !memcmp( bytes
.bytes
, expected
, len
);
2937 static void test_datetime(void)
2939 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
2942 unsigned __int64 ticks
;
2943 WS_DATETIME_FORMAT format
;
2946 const char *result2
;
2951 { 0, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>0001-01-01T00:00:00Z</t>" },
2952 { 0, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>0001-01-01T00:00:00+00:00</t>" },
2953 { 0, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T00:00:00</t>" },
2954 { 1, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>0001-01-01T00:00:00.0000001Z</t>" },
2955 { 1, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>0001-01-01T00:00:00.0000001+00:00</t>" },
2956 { 1, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T00:00:00.0000001</t>" },
2957 { 10, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T00:00:00.000001</t>" },
2958 { 1000000, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T00:00:00.1</t>" },
2959 { 0x23c34600, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>0001-01-01T00:01:00+00:00</t>" },
2960 { 0x861c46800, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>0001-01-01T01:00:00+00:00</t>" },
2961 { 0x430e234000, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>0001-01-01T08:00:00+00:00</t>" },
2962 { 0x4b6fe7a800, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>0001-01-01T09:00:00+00:00</t>" },
2963 { 0x989680, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T00:00:01</t>" },
2964 { 0x23c34600, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T00:01:00</t>" },
2965 { 0x861c46800, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T01:00:00</t>" },
2966 { 0xc92a69c000, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-02T00:00:00</t>" },
2967 { 0x11ed178c6c000, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0002-01-01T00:00:00</t>" },
2968 { 0x2bca2875f4373fff, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>9999-12-31T23:59:59.9999999Z</t>" },
2969 { 0x2bca2875f4373fff, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>9999-12-31T15:59:59.9999999-08:00</t>",
2970 "<t>9999-12-31T17:59:59.9999999-06:00</t>" /* win7 */, WS_E_INVALID_FORMAT
},
2971 { 0x2bca2875f4373fff, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>9999-12-31T23:59:59.9999999</t>" },
2972 { 0x2bca2875f4374000, WS_DATETIME_FORMAT_UTC
, WS_E_INVALID_FORMAT
},
2973 { 0x2bca2875f4374000, WS_DATETIME_FORMAT_LOCAL
, WS_E_INVALID_FORMAT
},
2974 { 0x2bca2875f4374000, WS_DATETIME_FORMAT_NONE
, WS_E_INVALID_FORMAT
},
2975 { 0x8d3123e7df74000, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>2015-12-31T16:00:00-08:00</t>",
2976 "<t>2015-12-31T18:00:00-06:00</t>" /* win7 */ },
2977 { 0x701ce1722770000, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>1601-01-01T00:00:00+00:00</t>" },
2978 { 0x701ce5a309a4000, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>1601-01-01T00:00:00-08:00</t>",
2979 "<t>1601-01-01T02:00:00-06:00</t>" /* win7 */ },
2980 { 0x701ce5e617c7400, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>1601-01-01T00:30:00-08:00</t>",
2981 "<t>1601-01-01T02:30:00-06:00</t>" /* win7 */ },
2982 { 0x701ce51ced5d800, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>1601-01-01T07:00:00+00:00</t>",
2983 "<t>1601-01-01T01:00:00-06:00</t>" /* win7 */ },
2984 { 0, WS_DATETIME_FORMAT_NONE
+ 1, WS_E_INVALID_FORMAT
},
2985 { 0x38a080649c000, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>0004-02-28T00:00:00Z</t>" },
2986 { 0x38ad130b38000, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>0004-02-29T00:00:00Z</t>" },
2987 { 0x8c1505f0e438000, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>2000-02-29T00:00:00Z</t>" },
2988 { 0x8d46035e7870000, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>2017-03-01T00:00:00Z</t>" },
2991 WS_XML_WRITER
*writer
;
2995 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2996 ok( hr
== S_OK
, "got %08x\n", hr
);
2997 for (i
= 0; i
< sizeof(tests
)/sizeof(tests
[0]); i
++)
2999 hr
= set_output( writer
);
3000 ok( hr
== S_OK
, "got %08x\n", hr
);
3002 date
.ticks
= tests
[i
].ticks
;
3003 date
.format
= tests
[i
].format
;
3004 WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3005 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_DATETIME_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
3006 &date
, sizeof(date
), NULL
);
3007 WsWriteEndElement( writer
, NULL
);
3008 ok( hr
== tests
[i
].hr
|| broken(hr
== tests
[i
].hr_broken
), "%u: got %08x\n", i
, hr
);
3009 if (hr
!= tests
[i
].hr
&& hr
== tests
[i
].hr_broken
) break;
3012 ok( check_result( writer
, tests
[i
].result
) ||
3013 (tests
[i
].result2
&& broken(check_result( writer
, tests
[i
].result2
))),
3014 "%u: wrong result\n", i
);
3018 WsFreeWriter( writer
);
3021 static void test_repeating_element(void)
3023 static const WCHAR oneW
[] = {'1',0}, twoW
[] = {'2',0};
3024 WS_XML_STRING localname
= {4, (BYTE
*)"test"}, ns
= {0, NULL
};
3025 WS_XML_STRING val
= {3, (BYTE
*)"val"}, wrapper
= {7, (BYTE
*)"wrapper"};
3027 WS_XML_WRITER
*writer
;
3028 WS_STRUCT_DESCRIPTION s
;
3029 WS_FIELD_DESCRIPTION f
, *fields
[1];
3030 WS_ITEM_RANGE range
;
3042 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3043 ok( hr
== S_OK
, "got %08x\n", hr
);
3045 /* array of strings, wrapper */
3046 hr
= set_output( writer
);
3047 ok( hr
== S_OK
, "got %08x\n", hr
);
3048 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3049 ok( hr
== S_OK
, "got %08x\n", hr
);
3051 memset( &f
, 0, sizeof(f
) );
3052 f
.mapping
= WS_REPEATING_ELEMENT_FIELD_MAPPING
;
3053 f
.localName
= &wrapper
;
3055 f
.type
= WS_WSZ_TYPE
;
3056 f
.countOffset
= FIELD_OFFSET(struct test
, count
);
3057 f
.itemLocalName
= &val
;
3061 memset( &s
, 0, sizeof(s
) );
3062 s
.size
= sizeof(struct test
);
3063 s
.alignment
= TYPE_ALIGNMENT(struct test
);
3064 s
.typeLocalName
= &localname
;
3069 hr
= set_output( writer
);
3070 ok( hr
== S_OK
, "got %08x\n", hr
);
3071 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3072 ok( hr
== S_OK
, "got %08x\n", hr
);
3074 test
= HeapAlloc( GetProcessHeap(), 0, sizeof(*test
) + 2 * sizeof(const WCHAR
*) );
3075 test
->val
= (const WCHAR
**)(test
+ 1);
3076 test
->val
[0] = oneW
;
3077 test
->val
[1] = twoW
;
3079 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
3080 WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
3081 ok( hr
== S_OK
, "got %08x\n", hr
);
3082 hr
= WsWriteEndElement( writer
, NULL
);
3083 ok( hr
== S_OK
, "got %08x\n", hr
);
3084 check_output( writer
, "<test><wrapper><val>1</val><val>2</val></wrapper></test>", __LINE__
);
3085 HeapFree( GetProcessHeap(), 0, test
);
3087 /* array of integers, no wrapper */
3088 hr
= set_output( writer
);
3089 ok( hr
== S_OK
, "got %08x\n", hr
);
3090 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3091 ok( hr
== S_OK
, "got %08x\n", hr
);
3093 f
.type
= WS_INT32_TYPE
;
3097 test2
= HeapAlloc( GetProcessHeap(), 0, sizeof(*test2
) + 2 * sizeof(INT32
) );
3098 test2
->val
= (INT32
*)(test2
+ 1);
3102 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
3103 WS_WRITE_REQUIRED_POINTER
, &test2
, sizeof(test2
), NULL
);
3104 ok( hr
== S_OK
, "got %08x\n", hr
);
3105 hr
= WsWriteEndElement( writer
, NULL
);
3106 ok( hr
== S_OK
, "got %08x\n", hr
);
3107 check_output( writer
, "<test><val>1</val><val>2</val></test>", __LINE__
);
3109 /* item range has no effect */
3110 hr
= set_output( writer
);
3111 ok( hr
== S_OK
, "got %08x\n", hr
);
3112 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3113 ok( hr
== S_OK
, "got %08x\n", hr
);
3115 range
.minItemCount
= 0;
3116 range
.maxItemCount
= 0;
3117 f
.itemRange
= &range
;
3119 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
3120 WS_WRITE_REQUIRED_POINTER
, &test2
, sizeof(test2
), NULL
);
3121 ok( hr
== S_OK
, "got %08x\n", hr
);
3122 hr
= WsWriteEndElement( writer
, NULL
);
3123 ok( hr
== S_OK
, "got %08x\n", hr
);
3124 check_output( writer
, "<test><val>1</val><val>2</val></test>", __LINE__
);
3125 HeapFree( GetProcessHeap(), 0, test2
);
3127 WsFreeWriter( writer
);
3130 static const WS_XML_STRING
*init_xmlstring( const char *src
, WS_XML_STRING
*str
)
3132 if (!src
) return NULL
;
3133 str
->length
= strlen( src
);
3134 str
->bytes
= (BYTE
*)src
;
3138 static void test_WsWriteQualifiedName(void)
3140 WS_XML_STRING prefix
= {1, (BYTE
*)"p"}, localname
= {1, (BYTE
*)"t"}, ns
= {2, (BYTE
*)"ns"};
3141 WS_XML_WRITER
*writer
;
3147 const char *localname
;
3153 { NULL
, NULL
, NULL
, E_INVALIDARG
, NULL
},
3154 { NULL
, "t2", NULL
, E_INVALIDARG
, NULL
},
3155 { "p2", "t2", NULL
, S_OK
, "<p:t xmlns:p=\"ns\">p2:t2" },
3156 { NULL
, "t2", "ns2", WS_E_INVALID_FORMAT
, NULL
},
3157 { NULL
, "t2", "ns", S_OK
, "<p:t xmlns:p=\"ns\">p:t2" },
3158 { "p2", "t2", "ns2", S_OK
, "<p:t xmlns:p=\"ns\">p2:t2" },
3159 { "p2", "t2", "ns", S_OK
, "<p:t xmlns:p=\"ns\">p2:t2" },
3160 { "p", "t", NULL
, S_OK
, "<p:t xmlns:p=\"ns\">p:t" },
3161 { NULL
, "t", "ns", S_OK
, "<p:t xmlns:p=\"ns\">p:t" },
3162 { "p2", "", "", S_OK
, "<p:t xmlns:p=\"ns\">p2:" },
3163 { "p2", "", "ns2", S_OK
, "<p:t xmlns:p=\"ns\">p2:" },
3164 { "p2", "t2", "", S_OK
, "<p:t xmlns:p=\"ns\">p2:t2" },
3165 { "", "t2", "", S_OK
, "<p:t xmlns:p=\"ns\">t2" },
3166 { "", "", "ns2", S_OK
, "<p:t xmlns:p=\"ns\">" },
3167 { "", "", "", S_OK
, "<p:t xmlns:p=\"ns\">" },
3170 hr
= WsWriteQualifiedName( NULL
, NULL
, NULL
, NULL
, NULL
);
3171 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3173 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3174 ok( hr
== S_OK
, "got %08x\n", hr
);
3176 hr
= WsWriteQualifiedName( writer
, NULL
, NULL
, NULL
, NULL
);
3177 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3179 hr
= set_output( writer
);
3180 ok( hr
== S_OK
, "got %08x\n", hr
);
3182 hr
= WsWriteQualifiedName( writer
, NULL
, NULL
, NULL
, NULL
);
3183 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
3185 for (i
= 0; i
< sizeof(tests
)/sizeof(tests
[0]); i
++)
3187 WS_XML_STRING prefix2
, localname2
, ns2
;
3188 const WS_XML_STRING
*prefix_ptr
, *localname_ptr
, *ns_ptr
;
3190 hr
= set_output( writer
);
3191 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3193 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
3194 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3196 prefix_ptr
= init_xmlstring( tests
[i
].prefix
, &prefix2
);
3197 localname_ptr
= init_xmlstring( tests
[i
].localname
, &localname2
);
3198 ns_ptr
= init_xmlstring( tests
[i
].ns
, &ns2
);
3200 hr
= WsWriteQualifiedName( writer
, prefix_ptr
, localname_ptr
, ns_ptr
, NULL
);
3201 ok( hr
== tests
[i
].hr
, "%u: got %08x\n", i
, hr
);
3202 if (tests
[i
].hr
== S_OK
&& hr
== S_OK
) check_output( writer
, tests
[i
].result
, __LINE__
);
3205 WsFreeWriter( writer
);
3208 static void test_WsWriteBytes(void)
3210 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {1, (BYTE
*)"a"}, ns
= {0, NULL
};
3211 WS_XML_WRITER
*writer
;
3214 hr
= WsWriteBytes( NULL
, NULL
, 0, NULL
);
3215 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3217 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3218 ok( hr
== S_OK
, "got %08x\n", hr
);
3220 hr
= WsWriteBytes( writer
, NULL
, 0, NULL
);
3221 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3223 hr
= WsWriteBytes( writer
, "test", 0, NULL
);
3224 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3226 hr
= WsWriteBytes( writer
, NULL
, 1, NULL
);
3227 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3229 hr
= WsWriteBytes( writer
, "test", sizeof("test"), NULL
);
3230 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3232 hr
= set_output( writer
);
3233 ok( hr
== S_OK
, "got %08x\n", hr
);
3235 hr
= WsWriteBytes( writer
, "test", sizeof("test"), NULL
);
3236 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
3238 hr
= set_output( writer
);
3239 ok( hr
== S_OK
, "got %08x\n", hr
);
3242 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3243 ok( hr
== S_OK
, "got %08x\n", hr
);
3245 hr
= WsWriteBytes( writer
, "test", sizeof("test"), NULL
);
3246 ok( hr
== S_OK
, "got %08x\n", hr
);
3248 hr
= WsWriteEndElement( writer
, NULL
);
3249 ok( hr
== S_OK
, "got %08x\n", hr
);
3250 check_output( writer
, "<t>dGVzdAA=</t>", __LINE__
);
3252 hr
= set_output( writer
);
3253 ok( hr
== S_OK
, "got %08x\n", hr
);
3256 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3257 ok( hr
== S_OK
, "got %08x\n", hr
);
3259 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
3260 ok( hr
== S_OK
, "got %08x\n", hr
);
3262 hr
= WsWriteBytes( writer
, "test", sizeof("test"), NULL
);
3263 ok( hr
== S_OK
, "got %08x\n", hr
);
3265 hr
= WsWriteEndAttribute( writer
, NULL
);
3266 ok( hr
== S_OK
, "got %08x\n", hr
);
3268 hr
= WsWriteEndElement( writer
, NULL
);
3269 ok( hr
== S_OK
, "got %08x\n", hr
);
3270 check_output( writer
, "<t a=\"dGVzdAA=\"/>", __LINE__
);
3272 WsFreeWriter( writer
);
3275 static void test_WsWriteChars(void)
3277 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {1, (BYTE
*)"a"}, ns
= {0, NULL
};
3278 static const WCHAR testW
[] = {'t','e','s','t'};
3279 WS_XML_WRITER
*writer
;
3282 hr
= WsWriteChars( NULL
, NULL
, 0, NULL
);
3283 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3285 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3286 ok( hr
== S_OK
, "got %08x\n", hr
);
3288 hr
= WsWriteChars( writer
, NULL
, 0, NULL
);
3289 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3291 hr
= WsWriteChars( writer
, testW
, 0, NULL
);
3292 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3294 hr
= WsWriteChars( writer
, NULL
, 1, NULL
);
3295 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3297 hr
= WsWriteChars( writer
, testW
, 4, NULL
);
3298 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3300 hr
= set_output( writer
);
3301 ok( hr
== S_OK
, "got %08x\n", hr
);
3303 hr
= WsWriteChars( writer
, testW
, 4, NULL
);
3304 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
3306 hr
= set_output( writer
);
3307 ok( hr
== S_OK
, "got %08x\n", hr
);
3310 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3311 ok( hr
== S_OK
, "got %08x\n", hr
);
3313 hr
= WsWriteChars( writer
, testW
, 4, NULL
);
3314 ok( hr
== S_OK
, "got %08x\n", hr
);
3316 hr
= WsWriteChars( writer
, testW
, 4, NULL
);
3317 ok( hr
== S_OK
, "got %08x\n", hr
);
3319 hr
= WsWriteEndElement( writer
, NULL
);
3320 ok( hr
== S_OK
, "got %08x\n", hr
);
3321 check_output( writer
, "<t>testtest</t>", __LINE__
);
3323 hr
= set_output( writer
);
3324 ok( hr
== S_OK
, "got %08x\n", hr
);
3327 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3328 ok( hr
== S_OK
, "got %08x\n", hr
);
3330 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
3331 ok( hr
== S_OK
, "got %08x\n", hr
);
3333 hr
= WsWriteChars( writer
, testW
, 4, NULL
);
3334 ok( hr
== S_OK
, "got %08x\n", hr
);
3336 hr
= WsWriteChars( writer
, testW
, 4, NULL
);
3337 ok( hr
== S_OK
, "got %08x\n", hr
);
3339 hr
= WsWriteEndAttribute( writer
, NULL
);
3340 ok( hr
== S_OK
, "got %08x\n", hr
);
3342 hr
= WsWriteEndElement( writer
, NULL
);
3343 ok( hr
== S_OK
, "got %08x\n", hr
);
3344 check_output( writer
, "<t a=\"testtest\"/>", __LINE__
);
3346 WsFreeWriter( writer
);
3349 static void test_WsWriteCharsUtf8(void)
3351 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {1, (BYTE
*)"a"}, ns
= {0, NULL
};
3352 static const BYTE test
[] = {'t','e','s','t'};
3353 WS_XML_WRITER
*writer
;
3356 hr
= WsWriteCharsUtf8( NULL
, NULL
, 0, NULL
);
3357 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3359 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3360 ok( hr
== S_OK
, "got %08x\n", hr
);
3362 hr
= WsWriteCharsUtf8( writer
, NULL
, 0, NULL
);
3363 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3365 hr
= WsWriteCharsUtf8( writer
, test
, 0, NULL
);
3366 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3368 hr
= WsWriteCharsUtf8( writer
, NULL
, 1, NULL
);
3369 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3371 hr
= WsWriteCharsUtf8( writer
, test
, sizeof(test
), NULL
);
3372 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3374 hr
= set_output( writer
);
3375 ok( hr
== S_OK
, "got %08x\n", hr
);
3377 hr
= WsWriteCharsUtf8( writer
, test
, sizeof(test
), NULL
);
3378 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
3380 hr
= set_output( writer
);
3381 ok( hr
== S_OK
, "got %08x\n", hr
);
3384 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3385 ok( hr
== S_OK
, "got %08x\n", hr
);
3387 hr
= WsWriteCharsUtf8( writer
, test
, sizeof(test
), NULL
);
3388 ok( hr
== S_OK
, "got %08x\n", hr
);
3390 hr
= WsWriteCharsUtf8( writer
, test
, sizeof(test
), NULL
);
3391 ok( hr
== S_OK
, "got %08x\n", hr
);
3393 hr
= WsWriteEndElement( writer
, NULL
);
3394 ok( hr
== S_OK
, "got %08x\n", hr
);
3395 check_output( writer
, "<t>testtest</t>", __LINE__
);
3397 hr
= set_output( writer
);
3398 ok( hr
== S_OK
, "got %08x\n", hr
);
3401 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3402 ok( hr
== S_OK
, "got %08x\n", hr
);
3404 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
3405 ok( hr
== S_OK
, "got %08x\n", hr
);
3407 hr
= WsWriteCharsUtf8( writer
, test
, sizeof(test
), NULL
);
3408 ok( hr
== S_OK
, "got %08x\n", hr
);
3410 hr
= WsWriteCharsUtf8( writer
, test
, sizeof(test
), NULL
);
3411 ok( hr
== S_OK
, "got %08x\n", hr
);
3413 hr
= WsWriteEndAttribute( writer
, NULL
);
3414 ok( hr
== S_OK
, "got %08x\n", hr
);
3416 hr
= WsWriteEndElement( writer
, NULL
);
3417 ok( hr
== S_OK
, "got %08x\n", hr
);
3418 check_output( writer
, "<t a=\"testtest\"/>", __LINE__
);
3420 WsFreeWriter( writer
);
3425 test_WsCreateWriter();
3426 test_WsCreateXmlBuffer();
3428 test_WsSetOutputToBuffer();
3429 test_WsWriteStartElement();
3430 test_WsWriteStartAttribute();
3433 test_simple_struct_type();
3434 test_WsWriteElement();
3435 test_WsWriteValue();
3436 test_WsWriteAttribute();
3437 test_WsWriteStartCData();
3438 test_WsWriteXmlnsAttribute();
3439 test_WsGetPrefixFromNamespace();
3440 test_complex_struct_type();
3441 test_WsMoveWriter();
3442 test_WsGetWriterPosition();
3443 test_WsSetWriterPosition();
3444 test_WsWriteXmlBuffer();
3449 test_field_options();
3451 test_WsWriteArray();
3453 test_write_option();
3455 test_repeating_element();
3456 test_WsWriteQualifiedName();
3457 test_WsWriteBytes();
3458 test_WsWriteChars();
3459 test_WsWriteCharsUtf8();