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
22 #include "webservices.h"
23 #include "wine/test.h"
27 static inline float __port_infinity(void)
29 static const unsigned __inf_bytes
= 0x7f800000;
30 return *(const float *)&__inf_bytes
;
32 #define INFINITY __port_infinity()
36 static inline float __port_nan(void)
38 static const unsigned __nan_bytes
= 0x7fc00000;
39 return *(const float *)&__nan_bytes
;
41 #define NAN __port_nan()
44 static HRESULT
set_output( WS_XML_WRITER
*writer
)
46 WS_XML_WRITER_TEXT_ENCODING text
= { {WS_XML_WRITER_ENCODING_TYPE_TEXT
}, WS_CHARSET_UTF8
};
47 WS_XML_WRITER_BUFFER_OUTPUT buf
= { {WS_XML_WRITER_OUTPUT_TYPE_BUFFER
} };
48 return WsSetOutput( writer
, &text
.encoding
, &buf
.output
, NULL
, 0, NULL
);
51 static void test_WsCreateWriter(void)
54 WS_XML_WRITER
*writer
;
55 WS_XML_WRITER_PROPERTY prop
;
56 ULONG size
, max_depth
, max_attrs
, indent
, trim_size
, max_size
, max_ns
;
57 BOOL allow_fragment
, write_decl
, in_attr
;
62 hr
= WsCreateWriter( NULL
, 0, NULL
, NULL
);
63 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
66 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
67 ok( hr
== S_OK
, "got %08x\n", hr
);
68 ok( writer
!= NULL
, "writer not set\n" );
70 /* can't retrieve properties before output is set */
71 max_depth
= 0xdeadbeef;
72 size
= sizeof(max_depth
);
73 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_DEPTH
, &max_depth
, size
, NULL
);
74 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
75 ok( max_depth
== 0xdeadbeef, "max_depth set\n" );
77 hr
= set_output( writer
);
78 ok( hr
== S_OK
, "got %08x\n", hr
);
80 /* check some defaults */
81 max_depth
= 0xdeadbeef;
82 size
= sizeof(max_depth
);
83 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_DEPTH
, &max_depth
, size
, NULL
);
84 ok( hr
== S_OK
, "got %08x\n", hr
);
85 ok( max_depth
== 32, "got %u\n", max_depth
);
87 allow_fragment
= TRUE
;
88 size
= sizeof(allow_fragment
);
89 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_ALLOW_FRAGMENT
, &allow_fragment
, size
, NULL
);
90 ok( hr
== S_OK
, "got %08x\n", hr
);
91 ok( !allow_fragment
, "got %d\n", allow_fragment
);
93 max_attrs
= 0xdeadbeef;
94 size
= sizeof(max_attrs
);
95 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_ATTRIBUTES
, &max_attrs
, size
, NULL
);
96 ok( hr
== S_OK
, "got %08x\n", hr
);
97 ok( max_attrs
== 128, "got %u\n", max_attrs
);
100 size
= sizeof(write_decl
);
101 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_WRITE_DECLARATION
, &write_decl
, size
, NULL
);
102 ok( hr
== S_OK
, "got %08x\n", hr
);
103 ok( !write_decl
, "got %d\n", write_decl
);
106 size
= sizeof(indent
);
107 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_INDENT
, &indent
, size
, NULL
);
108 ok( hr
== S_OK
, "got %08x\n", hr
);
109 ok( !indent
, "got %u\n", indent
);
111 trim_size
= 0xdeadbeef;
112 size
= sizeof(trim_size
);
113 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BUFFER_TRIM_SIZE
, &trim_size
, size
, NULL
);
114 ok( hr
== S_OK
, "got %08x\n", hr
);
115 ok( trim_size
== 4096, "got %u\n", trim_size
);
117 charset
= 0xdeadbeef;
118 size
= sizeof(charset
);
119 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_CHARSET
, &charset
, size
, NULL
);
120 ok( hr
== S_OK
, "got %08x\n", hr
);
121 ok( charset
== WS_CHARSET_UTF8
, "got %u\n", charset
);
123 buffers
.bufferCount
= 0xdeadbeef;
124 buffers
.buffers
= (WS_BYTES
*)0xdeadbeef;
125 size
= sizeof(buffers
);
126 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BUFFERS
, &buffers
, size
, NULL
);
127 ok( hr
== S_OK
, "got %08x\n", hr
);
128 ok( !buffers
.bufferCount
, "got %u\n", buffers
.bufferCount
);
129 ok( !buffers
.buffers
, "got %p\n", buffers
.buffers
);
131 max_size
= 0xdeadbeef;
132 size
= sizeof(max_size
);
133 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BUFFER_MAX_SIZE
, &max_size
, size
, NULL
);
134 ok( hr
== S_OK
, "got %08x\n", hr
);
135 ok( max_size
== 65536, "got %u\n", max_size
);
137 bytes
.length
= 0xdeadbeef;
138 bytes
.bytes
= (BYTE
*)0xdeadbeef;
139 size
= sizeof(bytes
);
140 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
141 ok( hr
== S_OK
, "got %08x\n", hr
);
142 ok( !bytes
.length
, "got %u\n", bytes
.length
);
143 ok( bytes
.bytes
!= NULL
, "got %p\n", bytes
.bytes
);
145 max_size
= 0xdeadbeef;
146 size
= sizeof(max_size
);
147 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_MIME_PARTS_BUFFER_SIZE
, &max_size
, size
, NULL
);
148 ok( hr
== S_OK
, "got %08x\n", hr
);
149 ok( max_size
== 65536, "got %u\n", max_size
);
151 bytes
.length
= 0xdeadbeef;
152 bytes
.bytes
= (BYTE
*)0xdeadbeef;
153 size
= sizeof(bytes
);
154 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_INITIAL_BUFFER
, &bytes
, size
, NULL
);
155 ok( hr
== S_OK
, "got %08x\n", hr
);
156 ok( !bytes
.length
, "got %u\n", bytes
.length
);
157 ok( !bytes
.bytes
, "got %p\n", bytes
.bytes
);
160 size
= sizeof(max_ns
);
161 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_NAMESPACES
, &max_ns
, size
, NULL
);
162 ok( hr
== S_OK
, "got %08x\n", hr
);
163 ok( max_ns
== 32, "got %u\n", max_ns
);
164 WsFreeWriter( writer
);
166 /* change a property */
168 prop
.id
= WS_XML_WRITER_PROPERTY_MAX_DEPTH
;
169 prop
.value
= &max_depth
;
170 prop
.valueSize
= sizeof(max_depth
);
171 hr
= WsCreateWriter( &prop
, 1, &writer
, NULL
);
172 ok( hr
== S_OK
, "got %08x\n", hr
);
174 hr
= set_output( writer
);
175 ok( hr
== S_OK
, "got %08x\n", hr
);
177 max_depth
= 0xdeadbeef;
178 size
= sizeof(max_depth
);
179 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_DEPTH
, &max_depth
, size
, NULL
);
180 ok( hr
== S_OK
, "got %08x\n", hr
);
181 ok( max_depth
== 16, "got %u\n", max_depth
);
182 WsFreeWriter( writer
);
184 /* show that some properties are read-only */
186 prop
.id
= WS_XML_WRITER_PROPERTY_IN_ATTRIBUTE
;
187 prop
.value
= &in_attr
;
188 prop
.valueSize
= sizeof(in_attr
);
189 hr
= WsCreateWriter( &prop
, 1, &writer
, NULL
);
190 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
193 prop
.id
= WS_XML_WRITER_PROPERTY_BYTES_WRITTEN
;
195 prop
.valueSize
= sizeof(size
);
196 hr
= WsCreateWriter( &prop
, 1, &writer
, NULL
);
197 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
200 prop
.id
= WS_XML_WRITER_PROPERTY_BYTES_TO_CLOSE
;
202 prop
.valueSize
= sizeof(size
);
203 hr
= WsCreateWriter( &prop
, 1, &writer
, NULL
);
204 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
207 static void test_WsCreateXmlBuffer(void)
211 WS_XML_WRITER
*writer
;
212 WS_XML_BUFFER
*buffer
;
216 hr
= WsCreateXmlBuffer( NULL
, NULL
, 0, NULL
, NULL
);
217 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
219 hr
= WsCreateXmlBuffer( NULL
, NULL
, 0, &buffer
, NULL
);
220 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
222 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
223 ok( hr
== S_OK
, "got %08x\n", hr
);
225 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, NULL
, NULL
);
226 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
229 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
230 ok( hr
== S_OK
, "got %08x\n", hr
);
231 ok( buffer
!= NULL
, "buffer not set\n" );
233 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
234 ok( hr
== S_OK
, "got %08x\n", hr
);
236 size
= sizeof(bytes
);
237 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
238 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
240 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
241 ok( hr
== S_OK
, "got %08x\n", hr
);
243 size
= sizeof(bytes
);
244 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
245 todo_wine
ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
247 WsFreeWriter( writer
);
251 static void test_WsSetOutput(void)
254 WS_XML_WRITER
*writer
;
255 WS_XML_WRITER_PROPERTY prop
;
256 WS_XML_WRITER_TEXT_ENCODING encoding
;
257 WS_XML_WRITER_BUFFER_OUTPUT output
;
258 ULONG size
, max_depth
;
260 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
261 ok( hr
== S_OK
, "got %08x\n", hr
);
263 hr
= WsSetOutput( NULL
, NULL
, NULL
, NULL
, 0, NULL
);
264 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
266 encoding
.encoding
.encodingType
= WS_XML_WRITER_ENCODING_TYPE_TEXT
;
267 encoding
.charSet
= WS_CHARSET_UTF8
;
269 output
.output
.outputType
= WS_XML_WRITER_OUTPUT_TYPE_BUFFER
;
271 hr
= WsSetOutput( writer
, &encoding
.encoding
, &output
.output
, NULL
, 0, NULL
);
272 ok( hr
== S_OK
, "got %08x\n", hr
);
274 /* multiple calls are allowed */
275 hr
= WsSetOutput( writer
, &encoding
.encoding
, &output
.output
, NULL
, 0, NULL
);
276 ok( hr
== S_OK
, "got %08x\n", hr
);
278 /* writer properties can be set with WsSetOutput */
280 prop
.id
= WS_XML_WRITER_PROPERTY_MAX_DEPTH
;
281 prop
.value
= &max_depth
;
282 prop
.valueSize
= sizeof(max_depth
);
283 hr
= WsSetOutput( writer
, &encoding
.encoding
, &output
.output
, &prop
, 1, NULL
);
284 ok( hr
== S_OK
, "got %08x\n", hr
);
286 max_depth
= 0xdeadbeef;
287 size
= sizeof(max_depth
);
288 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_DEPTH
, &max_depth
, size
, NULL
);
289 ok( hr
== S_OK
, "got %08x\n", hr
);
290 ok( max_depth
== 16, "got %u\n", max_depth
);
291 WsFreeWriter( writer
);
294 static void test_WsSetOutputToBuffer(void)
298 WS_XML_BUFFER
*buffer
;
299 WS_XML_WRITER
*writer
;
300 WS_XML_WRITER_PROPERTY prop
;
301 ULONG size
, max_depth
;
303 hr
= WsSetOutputToBuffer( NULL
, NULL
, NULL
, 0, NULL
);
304 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
306 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
307 ok( hr
== S_OK
, "got %08x\n", hr
);
309 hr
= WsSetOutputToBuffer( writer
, NULL
, NULL
, 0, NULL
);
310 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
312 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
313 ok( hr
== S_OK
, "got %08x\n", hr
);
315 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
316 ok( hr
== S_OK
, "got %08x\n", hr
);
318 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
319 ok( hr
== S_OK
, "got %08x\n", hr
);
321 /* multiple calls are allowed */
322 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
323 ok( hr
== S_OK
, "got %08x\n", hr
);
325 /* writer properties can be set with WsSetOutputToBuffer */
327 prop
.id
= WS_XML_WRITER_PROPERTY_MAX_DEPTH
;
328 prop
.value
= &max_depth
;
329 prop
.valueSize
= sizeof(max_depth
);
330 hr
= WsSetOutputToBuffer( writer
, buffer
, &prop
, 1, NULL
);
331 ok( hr
== S_OK
, "got %08x\n", hr
);
333 max_depth
= 0xdeadbeef;
334 size
= sizeof(max_depth
);
335 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_MAX_DEPTH
, &max_depth
, size
, NULL
);
336 ok( hr
== S_OK
, "got %08x\n", hr
);
337 ok( max_depth
== 16, "got %u\n", max_depth
);
339 WsFreeWriter( writer
);
343 static char strbuf
[512];
344 static const char *debugstr_bytes( const BYTE
*bytes
, ULONG len
)
346 const BYTE
*src
= bytes
;
352 if (dst
- strbuf
> sizeof(strbuf
) - 7) break;
355 case '\n': *dst
++ = '\\'; *dst
++ = 'n'; break;
356 case '\r': *dst
++ = '\\'; *dst
++ = 'r'; break;
357 case '\t': *dst
++ = '\\'; *dst
++ = 't'; break;
359 if (c
>= ' ' && c
< 127) *dst
++ = c
;
362 sprintf( dst
, "\\%02x", c
);
378 static void check_output( WS_XML_WRITER
*writer
, const char *expected
, unsigned int line
)
381 ULONG size
= sizeof(bytes
);
382 int len
= strlen( expected
);
385 memset( &bytes
, 0, sizeof(bytes
) );
386 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
387 ok( hr
== S_OK
, "%u: got %08x\n", line
, hr
);
388 ok( bytes
.length
== len
, "%u: got %u expected %u\n", line
, bytes
.length
, len
);
389 if (bytes
.length
!= len
) return;
390 ok( !memcmp( bytes
.bytes
, expected
, len
),
391 "%u: got %s expected %s\n", line
, debugstr_bytes(bytes
.bytes
, bytes
.length
), expected
);
394 static void test_WsWriteStartElement(void)
397 WS_XML_WRITER
*writer
;
398 WS_XML_STRING prefix
= {1, (BYTE
*)"p"}, ns
= {2, (BYTE
*)"ns"}, ns2
= {3, (BYTE
*)"ns2"};
399 WS_XML_STRING localname
= {1, (BYTE
*)"a"}, localname2
= {1, (BYTE
*)"b"}, empty
= {0, NULL
};
401 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
402 ok( hr
== S_OK
, "got %08x\n", hr
);
404 hr
= set_output( writer
);
405 ok( hr
== S_OK
, "got %08x\n", hr
);
407 hr
= WsWriteStartElement( NULL
, &prefix
, &localname
, &ns
, NULL
);
408 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
410 /* first call to WsWriteStartElement doesn't output anything */
411 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
412 ok( hr
== S_OK
, "got %08x\n", hr
);
413 check_output( writer
, "", __LINE__
);
415 /* two ways to close an element */
416 hr
= WsWriteEndStartElement( writer
, NULL
);
417 ok( hr
== S_OK
, "got %08x\n", hr
);
418 check_output( writer
, "<p:a xmlns:p=\"ns\">", __LINE__
);
420 hr
= WsWriteEndElement( writer
, NULL
);
421 ok( hr
== S_OK
, "got %08x\n", hr
);
422 check_output( writer
, "<p:a xmlns:p=\"ns\"></p:a>", __LINE__
);
424 hr
= set_output( writer
);
425 ok( hr
== S_OK
, "got %08x\n", hr
);
427 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
428 ok( hr
== S_OK
, "got %08x\n", hr
);
430 hr
= WsWriteEndElement( writer
, NULL
);
431 ok( hr
== S_OK
, "got %08x\n", hr
);
432 check_output( writer
, "<p:a xmlns:p=\"ns\"/>", __LINE__
);
434 /* nested elements */
435 hr
= set_output( writer
);
436 ok( hr
== S_OK
, "got %08x\n", hr
);
438 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
439 ok( hr
== S_OK
, "got %08x\n", hr
);
440 check_output( writer
, "", __LINE__
);
442 hr
= WsWriteStartElement( writer
, NULL
, &localname2
, &ns
, NULL
);
443 ok( hr
== S_OK
, "got %08x\n", hr
);
444 check_output( writer
, "<p:a xmlns:p=\"ns\">", __LINE__
);
446 hr
= WsWriteEndElement( writer
, NULL
);
447 ok( hr
== S_OK
, "got %08x\n", hr
);
448 check_output( writer
, "<p:a xmlns:p=\"ns\"><p:b/>", __LINE__
);
450 hr
= WsWriteEndElement( writer
, NULL
);
451 ok( hr
== S_OK
, "got %08x\n", hr
);
452 check_output( writer
, "<p:a xmlns:p=\"ns\"><p:b/></p:a>", __LINE__
);
454 hr
= set_output( writer
);
455 ok( hr
== S_OK
, "got %08x\n", hr
);
457 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
458 ok( hr
== S_OK
, "got %08x\n", hr
);
459 check_output( writer
, "", __LINE__
);
461 hr
= WsWriteStartElement( writer
, NULL
, &localname2
, &ns2
, NULL
);
462 ok( hr
== S_OK
, "got %08x\n", hr
);
463 check_output( writer
, "<p:a xmlns:p=\"ns\">", __LINE__
);
465 hr
= WsWriteEndElement( writer
, NULL
);
466 ok( hr
== S_OK
, "got %08x\n", hr
);
467 check_output( writer
, "<p:a xmlns:p=\"ns\"><b xmlns=\"ns2\"/>", __LINE__
);
469 hr
= WsWriteEndElement( writer
, NULL
);
470 ok( hr
== S_OK
, "got %08x\n", hr
);
471 check_output( writer
, "<p:a xmlns:p=\"ns\"><b xmlns=\"ns2\"/></p:a>", __LINE__
);
473 hr
= set_output( writer
);
474 ok( hr
== S_OK
, "got %08x\n", hr
);
476 hr
= WsWriteStartElement( writer
, &empty
, &localname
, &empty
, NULL
);
477 ok( hr
== S_OK
, "got %08x\n", hr
);
478 hr
= WsWriteEndStartElement( writer
, NULL
);
479 ok( hr
== S_OK
, "got %08x\n", hr
);
480 hr
= WsWriteEndElement( writer
, NULL
);
481 ok( hr
== S_OK
, "got %08x\n", hr
);
482 check_output( writer
, "<a></a>", __LINE__
);
484 WsFreeWriter( writer
);
487 static void test_WsWriteStartAttribute(void)
490 WS_XML_WRITER
*writer
;
491 WS_XML_STRING prefix
= {1, (BYTE
*)"p"}, localname
= {3, (BYTE
*)"str"};
492 WS_XML_STRING localname2
= {3, (BYTE
*)"len"}, ns
= {2, (BYTE
*)"ns"}, empty
= {0, NULL
};
493 WS_XML_UTF8_TEXT text
= {{WS_XML_TEXT_TYPE_UTF8
}};
495 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
496 ok( hr
== S_OK
, "got %08x\n", hr
);
498 hr
= set_output( writer
);
499 ok( hr
== S_OK
, "got %08x\n", hr
);
501 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
502 ok( hr
== S_OK
, "got %08x\n", hr
);
504 hr
= WsWriteStartAttribute( NULL
, &prefix
, &localname
, &ns
, FALSE
, NULL
);
505 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
507 /* WsWriteStartAttribute doesn't output anything */
508 hr
= WsWriteStartAttribute( writer
, &prefix
, &localname2
, &ns
, FALSE
, NULL
);
509 ok( hr
== S_OK
, "got %08x\n", hr
);
510 check_output( writer
, "", __LINE__
);
512 text
.value
.length
= 1;
513 text
.value
.bytes
= (BYTE
*)"0";
514 hr
= WsWriteText( writer
, &text
.text
, NULL
);
515 ok( hr
== S_OK
, "got %08x\n", hr
);
516 check_output( writer
, "", __LINE__
);
518 /* WsWriteEndAttribute doesn't output anything */
519 hr
= WsWriteEndAttribute( writer
, NULL
);
520 ok( hr
== S_OK
, "got %08x\n", hr
);
521 check_output( writer
, "", __LINE__
);
523 hr
= WsWriteEndElement( writer
, NULL
);
524 ok( hr
== S_OK
, "got %08x\n", hr
);
525 check_output( writer
, "<p:str p:len=\"0\" xmlns:p=\"ns\"/>", __LINE__
);
527 hr
= set_output( writer
);
528 ok( hr
== S_OK
, "got %08x\n", hr
);
530 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
531 ok( hr
== S_OK
, "got %08x\n", hr
);
533 hr
= WsWriteStartAttribute( writer
, &empty
, &localname2
, &empty
, FALSE
, NULL
);
534 ok( hr
== S_OK
, "got %08x\n", hr
);
535 hr
= WsWriteEndAttribute( writer
, NULL
);
536 ok( hr
== S_OK
, "got %08x\n", hr
);
538 hr
= WsWriteEndElement( writer
, NULL
);
539 ok( hr
== S_OK
, "got %08x\n", hr
);
540 check_output( writer
, "<p:str len=\"\" xmlns:p=\"ns\"/>", __LINE__
);
542 hr
= set_output( writer
);
543 ok( hr
== S_OK
, "got %08x\n", hr
);
545 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
546 ok( hr
== S_OK
, "got %08x\n", hr
);
548 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &empty
, FALSE
, NULL
);
549 ok( hr
== S_OK
, "got %08x\n", hr
);
551 hr
= WsWriteEndAttribute( writer
, NULL
);
552 ok( hr
== S_OK
, "got %08x\n", hr
);
554 hr
= WsWriteStartAttribute( writer
, NULL
, &localname
, &ns
, FALSE
, NULL
);
555 ok( hr
== S_OK
, "got %08x\n", hr
);
557 hr
= WsWriteEndAttribute( writer
, NULL
);
558 ok( hr
== S_OK
, "got %08x\n", hr
);
560 hr
= WsWriteEndElement( writer
, NULL
);
561 ok( hr
== S_OK
, "got %08x\n", hr
);
562 check_output( writer
, "<p:str len=\"\" p:str=\"\" xmlns:p=\"ns\"/>", __LINE__
);
564 WsFreeWriter( writer
);
567 static void test_WsWriteType(void)
569 static const WCHAR testW
[] = {'t','e','s','t',0};
571 WS_XML_WRITER
*writer
;
572 WS_XML_STRING prefix
= {1, (BYTE
*)"p"}, localname
= {3, (BYTE
*)"str"}, ns
= {2, (BYTE
*)"ns"};
573 const WCHAR
*val_str
;
575 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
576 ok( hr
== S_OK
, "got %08x\n", hr
);
578 hr
= set_output( writer
);
579 ok( hr
== S_OK
, "got %08x\n", hr
);
582 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
583 WS_WRITE_REQUIRED_POINTER
, &val_str
, sizeof(val_str
), NULL
);
584 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
586 hr
= set_output( writer
);
587 ok( hr
== S_OK
, "got %08x\n", hr
);
589 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
590 ok( hr
== S_OK
, "got %08x\n", hr
);
593 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
594 WS_WRITE_REQUIRED_VALUE
, NULL
, sizeof(testW
), NULL
);
595 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
597 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
598 WS_WRITE_REQUIRED_VALUE
, testW
, sizeof(testW
), NULL
);
599 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
601 /* required pointer */
602 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
603 WS_WRITE_REQUIRED_POINTER
, NULL
, sizeof(val_str
), NULL
);
604 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
606 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
607 WS_WRITE_REQUIRED_VALUE
, testW
, sizeof(testW
), NULL
);
608 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
610 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
611 WS_WRITE_REQUIRED_POINTER
, &val_str
, sizeof(WCHAR
**), NULL
);
612 ok( hr
== S_OK
, "got %08x\n", hr
);
613 check_output( writer
, "<p:str xmlns:p=\"ns\">test", __LINE__
);
615 hr
= WsWriteEndElement( writer
, NULL
);
616 ok( hr
== S_OK
, "got %08x\n", hr
);
617 check_output( writer
, "<p:str xmlns:p=\"ns\">test</p:str>", __LINE__
);
619 hr
= set_output( writer
);
620 ok( hr
== S_OK
, "got %08x\n", hr
);
622 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
623 ok( hr
== S_OK
, "got %08x\n", hr
);
625 hr
= WsWriteStartAttribute( writer
, NULL
, &localname
, &ns
, FALSE
, NULL
);
626 ok( hr
== S_OK
, "got %08x\n", hr
);
629 hr
= WsWriteType( writer
, WS_ATTRIBUTE_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
630 WS_WRITE_REQUIRED_POINTER
, &val_str
, sizeof(val_str
), NULL
);
631 ok( hr
== S_OK
, "got %08x\n", hr
);
632 check_output( writer
, "", __LINE__
);
634 hr
= WsWriteEndAttribute( writer
, NULL
);
635 ok( hr
== S_OK
, "got %08x\n", hr
);
636 check_output( writer
, "", __LINE__
);
638 hr
= WsWriteEndElement( writer
, NULL
);
639 ok( hr
== S_OK
, "got %08x\n", hr
);
640 check_output( writer
, "<p:str p:str=\"test\" xmlns:p=\"ns\"/>", __LINE__
);
642 hr
= set_output( writer
);
643 ok( hr
== S_OK
, "got %08x\n", hr
);
645 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
646 ok( hr
== S_OK
, "got %08x\n", hr
);
649 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
,
650 WS_WRITE_REQUIRED_POINTER
, &val_str
, sizeof(val_str
), NULL
);
651 ok( hr
== S_OK
, "got %08x\n", hr
);
652 check_output( writer
, "<p:str xmlns:p=\"ns\">test", __LINE__
);
654 hr
= WsWriteEndElement( writer
, NULL
);
655 ok( hr
== S_OK
, "got %08x\n", hr
);
656 check_output( writer
, "<p:str xmlns:p=\"ns\">test</p:str>", __LINE__
);
658 WsFreeWriter( writer
);
661 static void prepare_basic_type_test( WS_XML_WRITER
*writer
)
663 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
666 hr
= set_output( writer
);
667 ok( hr
== S_OK
, "got %08x\n", hr
);
668 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
669 ok( hr
== S_OK
, "got %08x\n", hr
);
672 static void test_basic_type(void)
674 static WCHAR testW
[] = {'t','e','s','t',0};
676 WS_XML_WRITER
*writer
;
677 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
}, xmlstr
;
694 { WS_BOOL_TYPE
, TRUE
, sizeof(BOOL
), "<t>true</t>", "<t t=\"true\"/>" },
695 { WS_BOOL_TYPE
, FALSE
, sizeof(BOOL
), "<t>false</t>", "<t t=\"false\"/>" },
696 { WS_INT8_TYPE
, -128, sizeof(INT8
), "<t>-128</t>", "<t t=\"-128\"/>" },
697 { WS_INT16_TYPE
, -32768, sizeof(INT16
), "<t>-32768</t>", "<t t=\"-32768\"/>" },
698 { WS_INT32_TYPE
, -2147483647 - 1, sizeof(INT32
), "<t>-2147483648</t>",
699 "<t t=\"-2147483648\"/>" },
700 { WS_INT64_TYPE
, -9223372036854775807 - 1, sizeof(INT64
), "<t>-9223372036854775808</t>",
701 "<t t=\"-9223372036854775808\"/>" },
702 { WS_UINT8_TYPE
, 255, sizeof(UINT8
), "<t>255</t>", "<t t=\"255\"/>" },
703 { WS_UINT16_TYPE
, 65535, sizeof(UINT16
), "<t>65535</t>", "<t t=\"65535\"/>" },
704 { WS_UINT32_TYPE
, ~0u, sizeof(UINT32
), "<t>4294967295</t>", "<t t=\"4294967295\"/>" },
705 { WS_UINT64_TYPE
, ~0, sizeof(UINT64
), "<t>18446744073709551615</t>",
706 "<t t=\"18446744073709551615\"/>" },
709 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
710 ok( hr
== S_OK
, "got %08x\n", hr
);
712 /* element content type mapping */
713 for (i
= 0; i
< ARRAY_SIZE( tests
); i
++)
715 prepare_basic_type_test( writer
);
716 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, tests
[i
].type
, NULL
,
717 WS_WRITE_REQUIRED_VALUE
, &tests
[i
].val
, tests
[i
].size
, NULL
);
718 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
720 hr
= WsWriteEndElement( writer
, NULL
);
721 ok( hr
== S_OK
, "got %08x\n", hr
);
722 check_output( writer
, tests
[i
].result
, __LINE__
);
725 /* element type mapping is the same as element content type mapping for basic types */
726 for (i
= 0; i
< ARRAY_SIZE( tests
); i
++)
728 const INT64
*ptr
= &tests
[i
].val
;
730 prepare_basic_type_test( writer
);
731 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, tests
[i
].type
, NULL
,
732 WS_WRITE_REQUIRED_POINTER
, &ptr
, sizeof(ptr
), NULL
);
733 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
735 hr
= WsWriteEndElement( writer
, NULL
);
736 ok( hr
== S_OK
, "got %08x\n", hr
);
737 check_output( writer
, tests
[i
].result
, __LINE__
);
740 /* attribute type mapping */
741 for (i
= 0; i
< ARRAY_SIZE( tests
); i
++)
743 prepare_basic_type_test( writer
);
744 hr
= WsWriteStartAttribute( writer
, NULL
, &localname
, &ns
, FALSE
, NULL
);
745 ok( hr
== S_OK
, "got %08x\n", hr
);
747 hr
= WsWriteType( writer
, WS_ATTRIBUTE_TYPE_MAPPING
, tests
[i
].type
, NULL
,
748 WS_WRITE_REQUIRED_VALUE
, &tests
[i
].val
, tests
[i
].size
, NULL
);
749 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
751 hr
= WsWriteEndAttribute( writer
, NULL
);
752 ok( hr
== S_OK
, "got %08x\n", hr
);
754 hr
= WsWriteEndElement( writer
, NULL
);
755 ok( hr
== S_OK
, "got %08x\n", hr
);
756 check_output( writer
, tests
[i
].result2
, __LINE__
);
759 prepare_basic_type_test( writer
);
760 memset( &guid
, 0, sizeof(guid
) );
761 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_GUID_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
762 &guid
, sizeof(guid
), NULL
);
763 ok( hr
== S_OK
, "got %08x\n", hr
);
764 hr
= WsWriteEndElement( writer
, NULL
);
765 ok( hr
== S_OK
, "got %08x\n", hr
);
766 check_output( writer
, "<t>00000000-0000-0000-0000-000000000000</t>", __LINE__
);
768 prepare_basic_type_test( writer
);
769 string
.chars
= testW
;
771 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_STRING_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
772 &string
, sizeof(string
), NULL
);
773 ok( hr
== S_OK
, "got %08x\n", hr
);
774 hr
= WsWriteEndElement( writer
, NULL
);
775 ok( hr
== S_OK
, "got %08x\n", hr
);
776 check_output( writer
, "<t>test</t>", __LINE__
);
778 prepare_basic_type_test( writer
);
780 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_WSZ_TYPE
, NULL
, WS_WRITE_REQUIRED_POINTER
,
781 &str
, sizeof(str
), NULL
);
782 ok( hr
== S_OK
, "got %08x\n", hr
);
783 hr
= WsWriteEndElement( writer
, NULL
);
784 ok( hr
== S_OK
, "got %08x\n", hr
);
785 check_output( writer
, "<t>test</t>", __LINE__
);
787 prepare_basic_type_test( writer
);
788 xmlstr
.bytes
= (BYTE
*)"test";
790 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_XML_STRING_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
791 &xmlstr
, sizeof(xmlstr
), NULL
);
792 ok( hr
== S_OK
, "got %08x\n", hr
);
793 hr
= WsWriteEndElement( writer
, NULL
);
794 ok( hr
== S_OK
, "got %08x\n", hr
);
795 check_output( writer
, "<t>test</t>", __LINE__
);
797 prepare_basic_type_test( writer
);
798 bytes
.bytes
= (BYTE
*)"test";
800 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_BYTES_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
801 &bytes
, sizeof(bytes
), NULL
);
802 ok( hr
== S_OK
, "got %08x\n", hr
);
803 hr
= WsWriteEndElement( writer
, NULL
);
804 ok( hr
== S_OK
, "got %08x\n", hr
);
805 check_output( writer
, "<t>dGVzdA==</t>", __LINE__
);
807 prepare_basic_type_test( writer
);
809 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_BYTES_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
810 &bytes
, sizeof(bytes
), NULL
);
811 ok( hr
== S_OK
, "got %08x\n", hr
);
812 hr
= WsWriteEndElement( writer
, NULL
);
813 ok( hr
== S_OK
, "got %08x\n", hr
);
814 check_output( writer
, "<t/>", __LINE__
);
816 prepare_basic_type_test( writer
);
818 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_BYTES_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
819 &bytes
, sizeof(bytes
), NULL
);
820 ok( hr
== S_OK
, "got %08x\n", hr
);
821 hr
= WsWriteEndElement( writer
, NULL
);
822 ok( hr
== S_OK
, "got %08x\n", hr
);
823 check_output( writer
, "<t/>", __LINE__
);
825 prepare_basic_type_test( writer
);
826 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_BYTES_TYPE
, NULL
, WS_WRITE_NILLABLE_VALUE
,
827 &bytes
, sizeof(bytes
), NULL
);
828 ok( hr
== S_OK
, "got %08x\n", hr
);
829 hr
= WsWriteEndElement( writer
, NULL
);
830 ok( hr
== S_OK
, "got %08x\n", hr
);
831 check_output( writer
, "<t a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/>",
834 prepare_basic_type_test( writer
);
835 memset( &id
, 0, sizeof(id
) );
836 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_UNIQUE_ID_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
837 &id
, sizeof(id
), NULL
);
838 ok( hr
== S_OK
, "got %08x\n", hr
);
839 hr
= WsWriteEndElement( writer
, NULL
);
840 ok( hr
== S_OK
, "got %08x\n", hr
);
841 check_output( writer
, "<t>urn:uuid:00000000-0000-0000-0000-000000000000</t>", __LINE__
);
843 prepare_basic_type_test( writer
);
845 id
.uri
.chars
= testW
;
846 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_UNIQUE_ID_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
847 &id
, sizeof(id
), NULL
);
848 ok( hr
== S_OK
, "got %08x\n", hr
);
849 hr
= WsWriteEndElement( writer
, NULL
);
850 ok( hr
== S_OK
, "got %08x\n", hr
);
851 check_output( writer
, "<t>test</t>", __LINE__
);
853 WsFreeWriter( writer
);
856 static void test_simple_struct_type(void)
858 static const WCHAR valueW
[] = {'v','a','l','u','e',0};
860 WS_XML_WRITER
*writer
;
861 WS_STRUCT_DESCRIPTION s
;
862 WS_FIELD_DESCRIPTION f
, *fields
[1];
863 WS_XML_STRING localname
= {6, (BYTE
*)"struct"}, ns
= {0, NULL
};
869 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
870 ok( hr
== S_OK
, "got %08x\n", hr
);
872 hr
= set_output( writer
);
873 ok( hr
== S_OK
, "got %08x\n", hr
);
875 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
876 ok( hr
== S_OK
, "got %08x\n", hr
);
878 memset( &f
, 0, sizeof(f
) );
879 f
.mapping
= WS_TEXT_FIELD_MAPPING
;
880 f
.type
= WS_WSZ_TYPE
;
883 memset( &s
, 0, sizeof(s
) );
884 s
.size
= sizeof(struct test
);
885 s
.alignment
= TYPE_ALIGNMENT(struct test
);
889 test
= HeapAlloc( GetProcessHeap(), 0, sizeof(*test
) );
890 test
->field
= valueW
;
891 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, NULL
,
892 WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
893 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
895 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, NULL
,
896 WS_WRITE_REQUIRED_VALUE
, test
, sizeof(*test
), NULL
);
897 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
899 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
900 WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
901 ok( hr
== S_OK
, "got %08x\n", hr
);
903 hr
= WsWriteEndElement( writer
, NULL
);
904 ok( hr
== S_OK
, "got %08x\n", hr
);
905 check_output( writer
, "<struct>value</struct>", __LINE__
);
908 hr
= set_output( writer
);
909 ok( hr
== S_OK
, "got %08x\n", hr
);
911 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
912 ok( hr
== S_OK
, "got %08x\n", hr
);
914 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
915 WS_WRITE_REQUIRED_VALUE
, test
, sizeof(*test
), NULL
);
916 ok( hr
== S_OK
, "got %08x\n", hr
);
918 hr
= WsWriteEndElement( writer
, NULL
);
919 ok( hr
== S_OK
, "got %08x\n", hr
);
920 check_output( writer
, "<struct>value</struct>", __LINE__
);
922 hr
= set_output( writer
);
923 ok( hr
== S_OK
, "got %08x\n", hr
);
925 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
926 ok( hr
== S_OK
, "got %08x\n", hr
);
928 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
929 WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
930 ok( hr
== S_OK
, "got %08x\n", hr
);
932 hr
= WsWriteEndElement( writer
, NULL
);
933 ok( hr
== S_OK
, "got %08x\n", hr
);
934 check_output( writer
, "<struct>value</struct>", __LINE__
);
936 hr
= set_output( writer
);
937 ok( hr
== S_OK
, "got %08x\n", hr
);
939 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
940 ok( hr
== S_OK
, "got %08x\n", hr
);
942 hr
= WsWriteStartAttribute( writer
, NULL
, &localname
, &ns
, FALSE
, NULL
);
943 ok( hr
== S_OK
, "got %08x\n", hr
);
945 hr
= WsWriteType( writer
, WS_ATTRIBUTE_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
946 WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
947 ok( hr
== S_OK
, "got %08x\n", hr
);
949 hr
= WsWriteEndAttribute( writer
, NULL
);
950 ok( hr
== S_OK
, "got %08x\n", hr
);
952 hr
= WsWriteEndElement( writer
, NULL
);
953 ok( hr
== S_OK
, "got %08x\n", hr
);
954 check_output( writer
, "<struct struct=\"value\"/>", __LINE__
);
956 HeapFree( GetProcessHeap(), 0, test
);
957 WsFreeWriter( writer
);
960 static void test_WsWriteElement(void)
962 static const WCHAR testW
[] = {'t','e','s','t',0};
964 WS_XML_WRITER
*writer
;
965 WS_STRUCT_DESCRIPTION s
;
966 WS_FIELD_DESCRIPTION f
, *fields
[1];
967 WS_ELEMENT_DESCRIPTION desc
;
968 WS_XML_STRING localname
= {3, (BYTE
*)"str"}, ns
= {0, NULL
};
969 struct test
{ const WCHAR
*str
; } *test
;
971 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
972 ok( hr
== S_OK
, "got %08x\n", hr
);
974 hr
= set_output( writer
);
975 ok( hr
== S_OK
, "got %08x\n", hr
);
977 /* text field mapping */
978 memset( &f
, 0, sizeof(f
) );
979 f
.mapping
= WS_TEXT_FIELD_MAPPING
;
980 f
.type
= WS_WSZ_TYPE
;
983 memset( &s
, 0, sizeof(s
) );
984 s
.size
= sizeof(struct test
);
985 s
.alignment
= TYPE_ALIGNMENT(struct test
);
989 desc
.elementLocalName
= &localname
;
990 desc
.elementNs
= &ns
;
991 desc
.type
= WS_STRUCT_TYPE
;
992 desc
.typeDescription
= &s
;
994 test
= HeapAlloc( GetProcessHeap(), 0, sizeof(*test
) );
996 hr
= WsWriteElement( NULL
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
997 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
999 hr
= WsWriteElement( writer
, NULL
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1000 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1002 hr
= WsWriteElement( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, NULL
, 0, NULL
);
1003 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1005 hr
= WsWriteElement( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1006 ok( hr
== S_OK
, "got %08x\n", hr
);
1007 check_output( writer
, "<str>test</str>", __LINE__
);
1009 hr
= set_output( writer
);
1010 ok( hr
== S_OK
, "got %08x\n", hr
);
1012 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1013 ok( hr
== S_OK
, "got %08x\n", hr
);
1015 hr
= WsWriteElement( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1016 ok( hr
== S_OK
, "got %08x\n", hr
);
1017 check_output( writer
, "<str><str>test</str>", __LINE__
);
1019 hr
= set_output( writer
);
1020 ok( hr
== S_OK
, "got %08x\n", hr
);
1022 /* attribute field mapping */
1023 f
.mapping
= WS_ATTRIBUTE_FIELD_MAPPING
;
1025 /* requires localName and ns to be set */
1026 hr
= WsWriteElement( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1027 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1029 hr
= set_output( writer
);
1030 ok( hr
== S_OK
, "got %08x\n", hr
);
1032 f
.localName
= &localname
;
1034 hr
= WsWriteElement( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1035 ok( hr
== S_OK
, "got %08x\n", hr
);
1036 check_output( writer
, "<str str=\"test\"/>", __LINE__
);
1038 HeapFree( GetProcessHeap(), 0, test
);
1039 WsFreeWriter( writer
);
1042 static void test_WsWriteValue(void)
1045 WS_XML_WRITER
*writer
;
1046 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
1054 const char *result2
;
1058 { WS_BOOL_VALUE_TYPE
, ~0, sizeof(BOOL
), "<t>true</t>", "<t t=\"true\"/>" },
1059 { WS_BOOL_VALUE_TYPE
, FALSE
, sizeof(BOOL
), "<t>false</t>", "<t t=\"false\"/>" },
1060 { WS_INT8_VALUE_TYPE
, -128, sizeof(INT8
), "<t>-128</t>", "<t t=\"-128\"/>" },
1061 { WS_INT16_VALUE_TYPE
, -32768, sizeof(INT16
), "<t>-32768</t>", "<t t=\"-32768\"/>" },
1062 { WS_INT32_VALUE_TYPE
, -2147483647 - 1, sizeof(INT32
), "<t>-2147483648</t>",
1063 "<t t=\"-2147483648\"/>" },
1064 { WS_INT64_VALUE_TYPE
, -9223372036854775807 - 1, sizeof(INT64
), "<t>-9223372036854775808</t>",
1065 "<t t=\"-9223372036854775808\"/>" },
1066 { WS_UINT8_VALUE_TYPE
, 255, sizeof(UINT8
), "<t>255</t>", "<t t=\"255\"/>" },
1067 { WS_UINT16_VALUE_TYPE
, 65535, sizeof(UINT16
), "<t>65535</t>", "<t t=\"65535\"/>" },
1068 { WS_UINT32_VALUE_TYPE
, ~0u, sizeof(UINT32
), "<t>4294967295</t>", "<t t=\"4294967295\"/>" },
1069 { WS_UINT64_VALUE_TYPE
, ~0, sizeof(UINT64
), "<t>18446744073709551615</t>",
1070 "<t t=\"18446744073709551615\"/>" },
1073 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1074 ok( hr
== S_OK
, "got %08x\n", hr
);
1076 hr
= set_output( writer
);
1077 ok( hr
== S_OK
, "got %08x\n", hr
);
1079 hr
= WsWriteValue( NULL
, tests
[0].type
, &tests
[0].val
, tests
[0].size
, NULL
);
1080 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1082 hr
= WsWriteValue( writer
, tests
[0].type
, &tests
[0].val
, tests
[0].size
, NULL
);
1083 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1085 hr
= set_output( writer
);
1086 ok( hr
== S_OK
, "got %08x\n", hr
);
1088 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1089 ok( hr
== S_OK
, "got %08x\n", hr
);
1092 hr
= WsWriteValue( writer
, tests
[0].type
, &tests
[0].val
, 0, NULL
);
1093 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1095 hr
= set_output( writer
);
1096 ok( hr
== S_OK
, "got %08x\n", hr
);
1098 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1099 ok( hr
== S_OK
, "got %08x\n", hr
);
1102 hr
= WsWriteValue( writer
, tests
[0].type
, NULL
, 0, NULL
);
1103 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1105 /* element type mapping */
1106 for (i
= 0; i
< ARRAY_SIZE( tests
); i
++)
1108 hr
= set_output( writer
);
1109 ok( hr
== S_OK
, "got %08x\n", hr
);
1111 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1112 ok( hr
== S_OK
, "got %08x\n", hr
);
1114 hr
= WsWriteValue( writer
, tests
[i
].type
, &tests
[i
].val
, tests
[i
].size
, NULL
);
1115 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
1117 hr
= WsWriteEndElement( writer
, NULL
);
1118 ok( hr
== S_OK
, "got %08x\n", hr
);
1119 check_output( writer
, tests
[i
].result
, __LINE__
);
1122 /* attribute type mapping */
1123 for (i
= 0; i
< ARRAY_SIZE( tests
); i
++)
1125 hr
= set_output( writer
);
1126 ok( hr
== S_OK
, "got %08x\n", hr
);
1128 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1129 ok( hr
== S_OK
, "got %08x\n", hr
);
1131 hr
= WsWriteStartAttribute( writer
, NULL
, &localname
, &ns
, FALSE
, NULL
);
1132 ok( hr
== S_OK
, "got %08x\n", hr
);
1134 hr
= WsWriteValue( writer
, tests
[i
].type
, &tests
[i
].val
, tests
[i
].size
, NULL
);
1135 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
1137 hr
= WsWriteEndAttribute( writer
, NULL
);
1138 ok( hr
== S_OK
, "got %08x\n", hr
);
1140 hr
= WsWriteEndElement( writer
, NULL
);
1141 ok( hr
== S_OK
, "got %08x\n", hr
);
1142 check_output( writer
, tests
[i
].result2
, __LINE__
);
1145 WsFreeWriter( writer
);
1148 static void test_WsWriteAttribute(void)
1150 static const WCHAR testW
[] = {'t','e','s','t',0};
1152 WS_XML_WRITER
*writer
;
1153 WS_STRUCT_DESCRIPTION s
;
1154 WS_FIELD_DESCRIPTION f
, *fields
[1];
1155 WS_ATTRIBUTE_DESCRIPTION desc
;
1156 WS_XML_STRING localname
= {3, (BYTE
*)"str"}, ns
= {0, NULL
};
1157 struct test
{ const WCHAR
*str
; } *test
;
1159 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1160 ok( hr
== S_OK
, "got %08x\n", hr
);
1162 hr
= set_output( writer
);
1163 ok( hr
== S_OK
, "got %08x\n", hr
);
1165 /* text field mapping */
1166 memset( &f
, 0, sizeof(f
) );
1167 f
.mapping
= WS_TEXT_FIELD_MAPPING
;
1168 f
.type
= WS_WSZ_TYPE
;
1171 memset( &s
, 0, sizeof(s
) );
1172 s
.size
= sizeof(struct test
);
1173 s
.alignment
= TYPE_ALIGNMENT(struct test
);
1177 desc
.attributeLocalName
= &localname
;
1178 desc
.attributeNs
= &ns
;
1179 desc
.type
= WS_STRUCT_TYPE
;
1180 desc
.typeDescription
= &s
;
1182 test
= HeapAlloc( GetProcessHeap(), 0, sizeof(*test
) );
1184 hr
= WsWriteAttribute( NULL
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1185 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1187 hr
= WsWriteAttribute( writer
, NULL
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1188 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1190 hr
= WsWriteAttribute( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, NULL
, 0, NULL
);
1191 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1193 hr
= WsWriteAttribute( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1194 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1196 hr
= set_output( writer
);
1197 ok( hr
== S_OK
, "got %08x\n", hr
);
1199 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1200 ok( hr
== S_OK
, "got %08x\n", hr
);
1202 hr
= WsWriteAttribute( writer
, &desc
, WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1203 ok( hr
== S_OK
, "got %08x\n", hr
);
1205 hr
= WsWriteEndElement( writer
, NULL
);
1206 ok( hr
== S_OK
, "got %08x\n", hr
);
1207 check_output( writer
, "<str str=\"test\"/>", __LINE__
);
1209 HeapFree( GetProcessHeap(), 0, test
);
1210 WsFreeWriter( writer
);
1213 static void test_WsWriteStartCData(void)
1216 WS_XML_WRITER
*writer
;
1217 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
1218 WS_XML_UTF8_TEXT text
= {{WS_XML_TEXT_TYPE_UTF8
}};
1220 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1221 ok( hr
== S_OK
, "got %08x\n", hr
);
1223 hr
= set_output( writer
);
1224 ok( hr
== S_OK
, "got %08x\n", hr
);
1226 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1227 ok( hr
== S_OK
, "got %08x\n", hr
);
1229 hr
= WsWriteEndCData( writer
, NULL
);
1230 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1232 hr
= set_output( writer
);
1233 ok( hr
== S_OK
, "got %08x\n", hr
);
1235 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1236 ok( hr
== S_OK
, "got %08x\n", hr
);
1237 check_output( writer
, "", __LINE__
);
1239 hr
= WsWriteStartCData( writer
, NULL
);
1240 ok( hr
== S_OK
, "got %08x\n", hr
);
1241 check_output( writer
, "<t><![CDATA[", __LINE__
);
1243 text
.value
.bytes
= (BYTE
*)"<data>";
1244 text
.value
.length
= 6;
1245 hr
= WsWriteText( writer
, &text
.text
, NULL
);
1246 ok( hr
== S_OK
, "got %08x\n", hr
);
1247 check_output( writer
, "<t><![CDATA[<data>", __LINE__
);
1249 hr
= WsWriteEndCData( writer
, NULL
);
1250 ok( hr
== S_OK
, "got %08x\n", hr
);
1251 check_output( writer
, "<t><![CDATA[<data>]]>", __LINE__
);
1253 hr
= WsWriteEndElement( writer
, NULL
);
1254 ok( hr
== S_OK
, "got %08x\n", hr
);
1255 check_output( writer
, "<t><![CDATA[<data>]]></t>", __LINE__
);
1257 WsFreeWriter( writer
);
1260 static void check_output_buffer( WS_XML_BUFFER
*buffer
, const char *expected
, unsigned int line
)
1262 WS_XML_WRITER
*writer
;
1264 ULONG size
= sizeof(bytes
);
1265 int len
= strlen(expected
);
1268 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1269 ok( hr
== S_OK
, "got %08x\n", hr
);
1271 hr
= set_output( writer
);
1272 ok( hr
== S_OK
, "got %08x\n", hr
);
1274 hr
= WsWriteXmlBuffer( writer
, buffer
, NULL
);
1275 ok( hr
== S_OK
, "got %08x\n", hr
);
1277 memset( &bytes
, 0, sizeof(bytes
) );
1278 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
1279 ok( hr
== S_OK
, "%u: got %08x\n", line
, hr
);
1280 ok( bytes
.length
== len
, "%u: got %u expected %u\n", line
, bytes
.length
, len
);
1281 if (bytes
.length
!= len
) return;
1282 ok( !memcmp( bytes
.bytes
, expected
, len
), "%u: got %s expected %s\n", line
, bytes
.bytes
, expected
);
1284 WsFreeWriter( writer
);
1287 static void prepare_xmlns_test( WS_XML_WRITER
*writer
, WS_HEAP
**heap
, WS_XML_BUFFER
**buffer
)
1289 WS_XML_STRING prefix
= {6, (BYTE
*)"prefix"}, localname
= {1, (BYTE
*)"t"}, ns
= {2, (BYTE
*)"ns"};
1292 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, heap
, NULL
);
1293 ok( hr
== S_OK
, "got %08x\n", hr
);
1295 hr
= WsCreateXmlBuffer( *heap
, NULL
, 0, buffer
, NULL
);
1296 ok( hr
== S_OK
, "got %08x\n", hr
);
1298 hr
= WsSetOutputToBuffer( writer
, *buffer
, NULL
, 0, NULL
);
1299 ok( hr
== S_OK
, "got %08x\n", hr
);
1301 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
1302 ok( hr
== S_OK
, "got %08x\n", hr
);
1305 static void test_WsWriteXmlnsAttribute(void)
1307 WS_XML_STRING ns
= {2, (BYTE
*)"ns"}, ns2
= {3, (BYTE
*)"ns2"};
1308 WS_XML_STRING prefix
= {6, (BYTE
*)"prefix"}, prefix2
= {7, (BYTE
*)"prefix2"};
1309 WS_XML_STRING xmlns
= {6, (BYTE
*)"xmlns"}, attr
= {4, (BYTE
*)"attr"};
1310 WS_XML_STRING localname
= {1, (BYTE
*)"u"};
1312 WS_XML_BUFFER
*buffer
;
1313 WS_XML_WRITER
*writer
;
1316 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1317 ok( hr
== S_OK
, "got %08x\n", hr
);
1319 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
1320 ok( hr
== S_OK
, "got %08x\n", hr
);
1322 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1323 ok( hr
== S_OK
, "got %08x\n", hr
);
1325 hr
= WsWriteXmlnsAttribute( NULL
, NULL
, NULL
, FALSE
, NULL
);
1326 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1329 prepare_xmlns_test( writer
, &heap
, &buffer
);
1330 hr
= WsWriteXmlnsAttribute( writer
, NULL
, NULL
, FALSE
, NULL
);
1331 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1334 prepare_xmlns_test( writer
, &heap
, &buffer
);
1335 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, NULL
, FALSE
, NULL
);
1336 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1338 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
1339 ok( hr
== S_OK
, "got %08x\n", hr
);
1340 hr
= WsWriteXmlnsAttribute( writer
, NULL
, &ns
, FALSE
, NULL
);
1341 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1345 prepare_xmlns_test( writer
, &heap
, &buffer
);
1346 hr
= WsWriteXmlnsAttribute( writer
, NULL
, &ns2
, FALSE
, NULL
);
1347 ok( hr
== S_OK
, "got %08x\n", hr
);
1348 hr
= WsWriteEndElement( writer
, NULL
);
1349 ok( hr
== S_OK
, "got %08x\n", hr
);
1350 check_output_buffer( buffer
, "<prefix:t xmlns:prefix=\"ns\" xmlns=\"ns2\"/>", __LINE__
);
1354 prepare_xmlns_test( writer
, &heap
, &buffer
);
1355 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns2
, FALSE
, NULL
);
1356 ok( hr
== S_OK
, "got %08x\n", hr
);
1357 hr
= WsWriteEndElement( writer
, NULL
);
1358 ok( hr
== S_OK
, "got %08x\n", hr
);
1359 check_output_buffer( buffer
, "<prefix:t xmlns:prefix2=\"ns2\" xmlns:prefix=\"ns\"/>", __LINE__
);
1362 /* implicitly set element prefix namespace */
1363 prepare_xmlns_test( writer
, &heap
, &buffer
);
1364 hr
= WsWriteEndElement( writer
, NULL
);
1365 ok( hr
== S_OK
, "got %08x\n", hr
);
1366 check_output_buffer( buffer
, "<prefix:t xmlns:prefix=\"ns\"/>", __LINE__
);
1369 /* explicitly set element prefix namespace */
1370 prepare_xmlns_test( writer
, &heap
, &buffer
);
1371 hr
= WsWriteXmlnsAttribute( writer
, &prefix
, &ns
, TRUE
, NULL
);
1372 ok( hr
== S_OK
, "got %08x\n", hr
);
1373 hr
= WsWriteEndElement( writer
, NULL
);
1374 ok( hr
== S_OK
, "got %08x\n", hr
);
1375 check_output_buffer( buffer
, "<prefix:t xmlns:prefix='ns'/>", __LINE__
);
1378 /* repeated calls, same namespace */
1379 prepare_xmlns_test( writer
, &heap
, &buffer
);
1380 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns
, FALSE
, NULL
);
1381 ok( hr
== S_OK
, "got %08x\n", hr
);
1382 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns
, FALSE
, NULL
);
1383 ok( hr
== S_OK
, "got %08x\n", hr
);
1384 hr
= WsWriteEndElement( writer
, NULL
);
1385 ok( hr
== S_OK
, "got %08x\n", hr
);
1386 check_output_buffer( buffer
, "<prefix:t xmlns:prefix2=\"ns\" xmlns:prefix=\"ns\"/>", __LINE__
);
1389 /* repeated calls, different namespace */
1390 prepare_xmlns_test( writer
, &heap
, &buffer
);
1391 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns
, FALSE
, NULL
);
1392 ok( hr
== S_OK
, "got %08x\n", hr
);
1393 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns2
, FALSE
, NULL
);
1394 ok( hr
== S_OK
, "got %08x\n", hr
);
1395 hr
= WsWriteEndElement( writer
, NULL
);
1396 todo_wine
ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1400 prepare_xmlns_test( writer
, &heap
, &buffer
);
1401 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns
, TRUE
, NULL
);
1402 ok( hr
== S_OK
, "got %08x\n", hr
);
1403 hr
= WsWriteEndElement( writer
, NULL
);
1404 ok( hr
== S_OK
, "got %08x\n", hr
);
1405 check_output_buffer( buffer
, "<prefix:t xmlns:prefix2='ns' xmlns:prefix=\"ns\"/>", __LINE__
);
1408 /* different namespace, different prefix */
1409 prepare_xmlns_test( writer
, &heap
, &buffer
);
1410 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns2
, TRUE
, NULL
);
1411 ok( hr
== S_OK
, "got %08x\n", hr
);
1412 hr
= WsWriteEndElement( writer
, NULL
);
1413 ok( hr
== S_OK
, "got %08x\n", hr
);
1414 check_output_buffer( buffer
, "<prefix:t xmlns:prefix2='ns2' xmlns:prefix=\"ns\"/>", __LINE__
);
1417 /* different namespace, same prefix */
1418 prepare_xmlns_test( writer
, &heap
, &buffer
);
1419 hr
= WsWriteXmlnsAttribute( writer
, &prefix
, &ns2
, TRUE
, NULL
);
1420 ok( hr
== S_OK
, "got %08x\n", hr
);
1421 hr
= WsWriteEndElement( writer
, NULL
);
1422 todo_wine
ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1425 /* regular attribute */
1426 prepare_xmlns_test( writer
, &heap
, &buffer
);
1427 hr
= WsWriteStartAttribute( writer
, &xmlns
, &prefix2
, &ns2
, TRUE
, NULL
);
1428 ok( hr
== S_OK
, "got %08x\n", hr
);
1429 hr
= WsWriteEndAttribute( writer
, NULL
);
1430 ok( hr
== S_OK
, "got %08x\n", hr
);
1431 hr
= WsWriteEndElement( writer
, NULL
);
1432 todo_wine
ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1435 /* attribute order */
1436 prepare_xmlns_test( writer
, &heap
, &buffer
);
1437 hr
= WsWriteXmlnsAttribute( writer
, &prefix
, &ns
, TRUE
, NULL
);
1438 ok( hr
== S_OK
, "got %08x\n", hr
);
1439 hr
= WsWriteStartAttribute( writer
, &prefix
, &attr
, &ns
, TRUE
, NULL
);
1440 ok( hr
== S_OK
, "got %08x\n", hr
);
1441 hr
= WsWriteEndAttribute( writer
, NULL
);
1442 ok( hr
== S_OK
, "got %08x\n", hr
);
1443 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns2
, TRUE
, NULL
);
1444 ok( hr
== S_OK
, "got %08x\n", hr
);
1445 hr
= WsWriteEndElement( writer
, NULL
);
1446 ok( hr
== S_OK
, "got %08x\n", hr
);
1447 check_output_buffer( buffer
, "<prefix:t prefix:attr='' xmlns:prefix='ns' xmlns:prefix2='ns2'/>", __LINE__
);
1451 prepare_xmlns_test( writer
, &heap
, &buffer
);
1452 hr
= WsWriteXmlnsAttribute( writer
, &prefix2
, &ns2
, TRUE
, NULL
);
1453 ok( hr
== S_OK
, "got %08x\n", hr
);
1454 hr
= WsWriteStartElement( writer
, &prefix2
, &localname
, &ns2
, NULL
);
1455 ok( hr
== S_OK
, "got %08x\n", hr
);
1456 hr
= WsWriteEndElement( writer
, NULL
);
1457 ok( hr
== S_OK
, "got %08x\n", hr
);
1458 hr
= WsWriteEndElement( writer
, NULL
);
1459 ok( hr
== S_OK
, "got %08x\n", hr
);
1460 check_output_buffer( buffer
, "<prefix:t xmlns:prefix2='ns2' xmlns:prefix=\"ns\"><prefix2:u/></prefix:t>",
1464 WsFreeWriter( writer
);
1467 static void prepare_prefix_test( WS_XML_WRITER
*writer
)
1469 const WS_XML_STRING p
= {1, (BYTE
*)"p"}, localname
= {1, (BYTE
*)"t"}, ns
= {2, (BYTE
*)"ns"};
1472 hr
= set_output( writer
);
1473 ok( hr
== S_OK
, "got %08x\n", hr
);
1474 hr
= WsWriteStartElement( writer
, &p
, &localname
, &ns
, NULL
);
1475 ok( hr
== S_OK
, "got %08x\n", hr
);
1476 hr
= WsWriteEndStartElement( writer
, NULL
);
1477 ok( hr
== S_OK
, "got %08x\n", hr
);
1480 static void test_WsGetPrefixFromNamespace(void)
1482 const WS_XML_STRING p
= {1, (BYTE
*)"p"}, localname
= {1, (BYTE
*)"t"}, *prefix
;
1483 const WS_XML_STRING ns
= {2, (BYTE
*)"ns"}, ns2
= {3, (BYTE
*)"ns2"};
1484 WS_XML_WRITER
*writer
;
1487 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1488 ok( hr
== S_OK
, "got %08x\n", hr
);
1490 hr
= set_output( writer
);
1491 ok( hr
== S_OK
, "got %08x\n", hr
);
1492 hr
= WsWriteStartElement( writer
, &p
, &localname
, &ns
, NULL
);
1493 ok( hr
== S_OK
, "got %08x\n", hr
);
1495 hr
= WsGetPrefixFromNamespace( NULL
, NULL
, FALSE
, NULL
, NULL
);
1496 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1498 hr
= WsGetPrefixFromNamespace( NULL
, NULL
, FALSE
, &prefix
, NULL
);
1499 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1501 hr
= WsGetPrefixFromNamespace( writer
, NULL
, FALSE
, &prefix
, NULL
);
1502 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1504 /* element must be committed */
1505 hr
= set_output( writer
);
1506 ok( hr
== S_OK
, "got %08x\n", hr
);
1507 hr
= WsWriteStartElement( writer
, &p
, &localname
, &ns
, NULL
);
1508 ok( hr
== S_OK
, "got %08x\n", hr
);
1509 hr
= WsGetPrefixFromNamespace( writer
, &ns
, TRUE
, &prefix
, NULL
);
1510 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1512 /* but writer can't be positioned on end element node */
1513 hr
= set_output( writer
);
1514 ok( hr
== S_OK
, "got %08x\n", hr
);
1515 hr
= WsWriteStartElement( writer
, &p
, &localname
, &ns
, NULL
);
1516 ok( hr
== S_OK
, "got %08x\n", hr
);
1517 hr
= WsWriteEndElement( writer
, NULL
);
1518 ok( hr
== S_OK
, "got %08x\n", hr
);
1519 hr
= WsGetPrefixFromNamespace( writer
, &ns
, TRUE
, &prefix
, NULL
);
1520 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1522 /* required = TRUE */
1524 prepare_prefix_test( writer
);
1525 hr
= WsGetPrefixFromNamespace( writer
, &ns
, TRUE
, &prefix
, NULL
);
1526 ok( hr
== S_OK
, "got %08x\n", hr
);
1527 ok( prefix
!= NULL
, "prefix not set\n" );
1530 ok( prefix
->length
== 1, "got %u\n", prefix
->length
);
1531 ok( !memcmp( prefix
->bytes
, "p", 1 ), "wrong prefix\n" );
1534 prefix
= (const WS_XML_STRING
*)0xdeadbeef;
1535 hr
= WsGetPrefixFromNamespace( writer
, &ns2
, TRUE
, &prefix
, NULL
);
1536 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1537 ok( prefix
== (const WS_XML_STRING
*)0xdeadbeef, "prefix set\n" );
1539 /* required = FALSE */
1541 prepare_prefix_test( writer
);
1542 hr
= WsGetPrefixFromNamespace( writer
, &ns
, FALSE
, &prefix
, NULL
);
1543 ok( hr
== S_OK
, "got %08x\n", hr
);
1544 ok( prefix
!= NULL
, "prefix not set\n" );
1547 ok( prefix
->length
== 1, "got %u\n", prefix
->length
);
1548 ok( !memcmp( prefix
->bytes
, "p", 1 ), "wrong prefix\n" );
1551 prefix
= (const WS_XML_STRING
*)0xdeadbeef;
1552 hr
= WsGetPrefixFromNamespace( writer
, &ns2
, FALSE
, &prefix
, NULL
);
1553 ok( hr
== S_FALSE
, "got %08x\n", hr
);
1554 ok( prefix
== NULL
, "prefix not set\n" );
1556 WsFreeWriter( writer
);
1559 static void test_complex_struct_type(void)
1561 static const char expected
[] =
1562 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
1563 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\"/>"
1564 "</o:OfficeConfig>";
1565 static const WCHAR timestampW
[] =
1566 {'2','0','1','5','-','0','9','-','0','3','T','1','8',':','4','7',':','5','4',0};
1567 WS_XML_STRING str_officeconfig
= {12, (BYTE
*)"OfficeConfig"};
1568 WS_XML_STRING str_services
= {8, (BYTE
*)"services"};
1569 WS_XML_STRING str_generationtime
= {14, (BYTE
*)"GenerationTime"};
1570 WS_XML_STRING ns
= {39, (BYTE
*)"urn:schemas-microsoft-com:office:office"};
1571 WS_XML_STRING prefix
= {1, (BYTE
*)"o"};
1575 WS_XML_BUFFER
*buffer
;
1576 WS_XML_WRITER
*writer
;
1577 WS_STRUCT_DESCRIPTION s
, s2
;
1578 WS_FIELD_DESCRIPTION f
, f2
, *fields
[1], *fields2
[1];
1581 const WCHAR
*generationtime
;
1585 struct services
*services
;
1588 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1589 ok( hr
== S_OK
, "got %08x\n", hr
);
1591 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1592 ok( hr
== S_OK
, "got %08x\n", hr
);
1594 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
1595 ok( hr
== S_OK
, "got %08x\n", hr
);
1597 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
1598 ok( hr
== S_OK
, "got %08x\n", hr
);
1600 hr
= WsWriteStartElement( writer
, &prefix
, &str_officeconfig
, &ns
, NULL
);
1601 ok( hr
== S_OK
, "got %08x\n", hr
);
1603 memset( &f2
, 0, sizeof(f2
) );
1604 f2
.mapping
= WS_ATTRIBUTE_FIELD_MAPPING
;
1605 f2
.localName
= &str_generationtime
;
1607 f2
.type
= WS_WSZ_TYPE
;
1608 f2
.options
= WS_FIELD_OPTIONAL
;
1611 memset( &s2
, 0, sizeof(s2
) );
1612 s2
.size
= sizeof(*test
->services
);
1614 s2
.fields
= fields2
;
1616 s2
.typeLocalName
= &str_services
;
1619 memset( &f
, 0, sizeof(f
) );
1620 f
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
1621 f
.localName
= &str_services
;
1623 f
.type
= WS_STRUCT_TYPE
;
1624 f
.typeDescription
= &s2
;
1625 f
.options
= WS_FIELD_POINTER
;
1628 memset( &s
, 0, sizeof(s
) );
1629 s
.size
= sizeof(*test
);
1633 s
.typeLocalName
= &str_officeconfig
;
1636 size
= sizeof(struct officeconfig
) + sizeof(struct services
);
1637 test
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
1638 test
->services
= (struct services
*)(test
+ 1);
1639 test
->services
->generationtime
= timestampW
;
1640 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
1641 WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
1642 ok( hr
== S_OK
, "got %08x\n", hr
);
1644 hr
= WsWriteEndElement( writer
, NULL
);
1645 ok( hr
== S_OK
, "got %08x\n", hr
);
1646 check_output_buffer( buffer
, expected
, __LINE__
);
1648 HeapFree( GetProcessHeap(), 0, test
);
1649 WsFreeWriter( writer
);
1653 static void test_WsMoveWriter(void)
1655 WS_XML_STRING localname
= {1, (BYTE
*)"a"}, localname2
= {1, (BYTE
*)"b"}, ns
= {0, NULL
};
1657 WS_XML_WRITER
*writer
;
1658 WS_XML_BUFFER
*buffer
;
1661 hr
= WsMoveWriter( NULL
, WS_MOVE_TO_EOF
, NULL
, NULL
);
1662 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1664 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1665 ok( hr
== S_OK
, "got %08x\n", hr
);
1667 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1668 ok( hr
== S_OK
, "got %08x\n", hr
);
1670 hr
= set_output( writer
);
1671 ok( hr
== S_OK
, "got %08x\n", hr
);
1673 /* writer must be set to an XML buffer */
1674 hr
= WsMoveWriter( writer
, WS_MOVE_TO_EOF
, NULL
, NULL
);
1675 todo_wine
ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1677 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
1678 ok( hr
== S_OK
, "got %08x\n", hr
);
1680 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
1681 ok( hr
== S_OK
, "got %08x\n", hr
);
1683 hr
= WsMoveWriter( writer
, WS_MOVE_TO_EOF
, NULL
, NULL
);
1684 ok( hr
== S_OK
, "got %08x\n", hr
);
1687 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1688 ok( hr
== S_OK
, "got %08x\n", hr
);
1690 hr
= WsWriteStartElement( writer
, NULL
, &localname2
, &ns
, NULL
);
1691 ok( hr
== S_OK
, "got %08x\n", hr
);
1693 hr
= WsWriteEndElement( writer
, NULL
);
1694 ok( hr
== S_OK
, "got %08x\n", hr
);
1696 hr
= WsWriteEndElement( writer
, NULL
);
1697 ok( hr
== S_OK
, "got %08x\n", hr
);
1699 hr
= WsMoveWriter( writer
, WS_MOVE_TO_EOF
, NULL
, NULL
);
1700 ok( hr
== S_OK
, "got %08x\n", hr
);
1702 hr
= WsMoveWriter( writer
, WS_MOVE_TO_ROOT_ELEMENT
, NULL
, NULL
);
1703 ok( hr
== S_OK
, "got %08x\n", hr
);
1705 hr
= WsMoveWriter( writer
, WS_MOVE_TO_CHILD_ELEMENT
, NULL
, NULL
);
1706 ok( hr
== S_OK
, "got %08x\n", hr
);
1708 hr
= WsMoveWriter( writer
, WS_MOVE_TO_END_ELEMENT
, NULL
, NULL
);
1709 ok( hr
== S_OK
, "got %08x\n", hr
);
1711 hr
= WsMoveWriter( writer
, WS_MOVE_TO_PARENT_ELEMENT
, NULL
, NULL
);
1712 ok( hr
== S_OK
, "got %08x\n", hr
);
1714 hr
= WsMoveWriter( writer
, WS_MOVE_TO_END_ELEMENT
, NULL
, NULL
);
1715 ok( hr
== S_OK
, "got %08x\n", hr
);
1717 hr
= WsMoveWriter( writer
, WS_MOVE_TO_BOF
, NULL
, NULL
);
1718 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1720 WsFreeWriter( writer
);
1724 static void test_WsGetWriterPosition(void)
1727 WS_XML_WRITER
*writer
;
1728 WS_XML_BUFFER
*buffer
;
1729 WS_XML_NODE_POSITION pos
;
1732 hr
= WsGetWriterPosition( NULL
, NULL
, NULL
);
1733 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1735 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1736 ok( hr
== S_OK
, "got %08x\n", hr
);
1738 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1739 ok( hr
== S_OK
, "got %08x\n", hr
);
1741 hr
= WsGetWriterPosition( writer
, &pos
, NULL
);
1742 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1744 hr
= set_output( writer
);
1745 ok( hr
== S_OK
, "got %08x\n", hr
);
1747 /* writer must be set to an XML buffer */
1748 hr
= WsGetWriterPosition( writer
, &pos
, NULL
);
1749 todo_wine
ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1751 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
1752 ok( hr
== S_OK
, "got %08x\n", hr
);
1754 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
1755 ok( hr
== S_OK
, "got %08x\n", hr
);
1757 hr
= WsGetWriterPosition( writer
, NULL
, NULL
);
1758 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1760 pos
.buffer
= pos
.node
= NULL
;
1761 hr
= WsGetWriterPosition( writer
, &pos
, NULL
);
1762 ok( hr
== S_OK
, "got %08x\n", hr
);
1763 ok( pos
.buffer
!= NULL
, "buffer not set\n" );
1764 ok( pos
.node
!= NULL
, "node not set\n" );
1766 WsFreeWriter( writer
);
1770 static void test_WsSetWriterPosition(void)
1772 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
1774 WS_XML_WRITER
*writer
;
1775 WS_XML_BUFFER
*buf1
, *buf2
;
1776 WS_XML_NODE_POSITION pos
;
1779 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1780 ok( hr
== S_OK
, "got %08x\n", hr
);
1782 hr
= WsSetWriterPosition( NULL
, NULL
, NULL
);
1783 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1785 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1786 ok( hr
== S_OK
, "got %08x\n", hr
);
1788 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buf1
, NULL
);
1789 ok( hr
== S_OK
, "got %08x\n", hr
);
1791 hr
= WsSetOutputToBuffer( writer
, buf1
, NULL
, 0, NULL
);
1792 ok( hr
== S_OK
, "got %08x\n", hr
);
1794 hr
= WsSetWriterPosition( writer
, NULL
, NULL
);
1795 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1797 pos
.buffer
= pos
.node
= NULL
;
1798 hr
= WsGetWriterPosition( writer
, &pos
, NULL
);
1799 ok( hr
== S_OK
, "got %08x\n", hr
);
1800 ok( pos
.buffer
== buf1
, "wrong buffer\n" );
1801 ok( pos
.node
!= NULL
, "node not set\n" );
1803 hr
= WsSetWriterPosition( writer
, &pos
, NULL
);
1804 ok( hr
== S_OK
, "got %08x\n", hr
);
1806 /* different buffer */
1807 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buf2
, NULL
);
1808 ok( hr
== S_OK
, "got %08x\n", hr
);
1811 hr
= WsSetWriterPosition( writer
, &pos
, NULL
);
1812 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1814 hr
= WsSetOutputToBuffer( writer
, buf1
, NULL
, 0, NULL
);
1815 ok( hr
== S_OK
, "got %08x\n", hr
);
1817 /* try to write at non-final position */
1818 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1819 ok( hr
== S_OK
, "got %08x\n", hr
);
1821 pos
.buffer
= pos
.node
= NULL
;
1822 hr
= WsGetWriterPosition( writer
, &pos
, NULL
);
1823 ok( hr
== S_OK
, "got %08x\n", hr
);
1824 ok( pos
.buffer
== buf1
, "wrong buffer\n" );
1825 ok( pos
.node
!= NULL
, "node not set\n" );
1827 hr
= WsWriteEndElement( writer
, NULL
);
1828 ok( hr
== S_OK
, "got %08x\n", hr
);
1829 check_output_buffer( buf1
, "<t/>", __LINE__
);
1831 hr
= WsSetWriterPosition( writer
, &pos
, NULL
);
1832 ok( hr
== S_OK
, "got %08x\n", hr
);
1834 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
1835 todo_wine
ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1837 WsFreeWriter( writer
);
1841 static void test_WsWriteXmlBuffer(void)
1843 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
1844 WS_XML_WRITER
*writer1
, *writer2
;
1845 WS_XML_BUFFER
*buffer1
, *buffer2
;
1849 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1850 ok( hr
== S_OK
, "got %08x\n", hr
);
1852 hr
= WsCreateXmlBuffer( NULL
, NULL
, 0, NULL
, NULL
);
1853 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1855 hr
= WsCreateWriter( NULL
, 0, &writer1
, NULL
);
1856 ok( hr
== S_OK
, "got %08x\n", hr
);
1858 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, NULL
, NULL
);
1859 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1861 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer1
, NULL
);
1862 ok( hr
== S_OK
, "got %08x\n", hr
);
1864 hr
= WsSetOutputToBuffer( writer1
, buffer1
, NULL
, 0, NULL
);
1865 ok( hr
== S_OK
, "got %08x\n", hr
);
1867 hr
= WsWriteStartElement( writer1
, NULL
, &localname
, &ns
, NULL
);
1868 ok( hr
== S_OK
, "got %08x\n", hr
);
1870 hr
= WsWriteEndElement( writer1
, NULL
);
1871 ok( hr
== S_OK
, "got %08x\n", hr
);
1872 check_output_buffer( buffer1
, "<t/>", __LINE__
);
1874 hr
= WsCreateWriter( NULL
, 0, &writer2
, NULL
);
1875 ok( hr
== S_OK
, "got %08x\n", hr
);
1877 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer2
, NULL
);
1878 ok( hr
== S_OK
, "got %08x\n", hr
);
1880 hr
= WsSetOutputToBuffer( writer2
, buffer2
, NULL
, 0, NULL
);
1881 ok( hr
== S_OK
, "got %08x\n", hr
);
1883 hr
= WsWriteXmlBuffer( writer2
, buffer1
, NULL
);
1884 ok( hr
== S_OK
, "got %08x\n", hr
);
1885 check_output_buffer( buffer2
, "<t/>", __LINE__
);
1887 hr
= WsMoveWriter( writer2
, WS_MOVE_TO_PREVIOUS_ELEMENT
, NULL
, NULL
);
1888 todo_wine
ok( hr
== S_OK
, "got %08x\n", hr
);
1890 hr
= WsWriteXmlBuffer( writer2
, buffer1
, NULL
);
1891 todo_wine
ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
1893 WsFreeWriter( writer1
);
1894 WsFreeWriter( writer2
);
1898 static void test_WsWriteNode(void)
1900 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {4, (BYTE
*)"attr"}, ns
= {0, NULL
};
1901 WS_XML_WRITER
*writer
;
1902 WS_XML_BUFFER
*buffer
;
1903 WS_XML_UTF8_TEXT utf8
= {{WS_XML_TEXT_TYPE_UTF8
}};
1904 WS_XML_ATTRIBUTE attr
, *attrs
[1];
1905 WS_XML_ELEMENT_NODE elem
;
1906 WS_XML_COMMENT_NODE comment
= {{WS_XML_NODE_TYPE_COMMENT
}};
1908 WS_XML_TEXT_NODE text
= {{WS_XML_NODE_TYPE_TEXT
}};
1912 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
1913 ok( hr
== S_OK
, "got %08x\n", hr
);
1915 hr
= WsWriteNode( NULL
, NULL
, NULL
);
1916 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
1918 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
1919 ok( hr
== S_OK
, "got %08x\n", hr
);
1921 hr
= WsWriteNode( writer
, NULL
, NULL
);
1922 todo_wine
ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
1924 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
1925 ok( hr
== S_OK
, "got %08x\n", hr
);
1927 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
1928 ok( hr
== S_OK
, "got %08x\n", hr
);
1930 utf8
.value
.bytes
= (BYTE
*)"value";
1931 utf8
.value
.length
= sizeof("value") - 1;
1933 attr
.singleQuote
= TRUE
;
1934 attr
.isXmlNs
= FALSE
;
1936 attr
.localName
= &localname2
;
1938 attr
.value
= &utf8
.text
;
1941 elem
.node
.nodeType
= WS_XML_NODE_TYPE_ELEMENT
;
1943 elem
.localName
= &localname
;
1945 elem
.attributeCount
= 1;
1946 elem
.attributes
= attrs
;
1947 elem
.isEmpty
= FALSE
;
1948 hr
= WsWriteNode( writer
, &elem
.node
, NULL
);
1949 ok( hr
== S_OK
, "got %08x\n", hr
);
1951 comment
.value
.bytes
= (BYTE
*)"comment";
1952 comment
.value
.length
= sizeof("comment") - 1;
1953 hr
= WsWriteNode( writer
, &comment
.node
, NULL
);
1954 ok( hr
== S_OK
, "got %08x\n", hr
);
1956 node
.nodeType
= WS_XML_NODE_TYPE_EOF
;
1957 hr
= WsWriteNode( writer
, &node
, NULL
);
1958 ok( hr
== S_OK
, "got %08x\n", hr
);
1960 node
.nodeType
= WS_XML_NODE_TYPE_BOF
;
1961 hr
= WsWriteNode( writer
, &node
, NULL
);
1962 ok( hr
== S_OK
, "got %08x\n", hr
);
1964 node
.nodeType
= WS_XML_NODE_TYPE_CDATA
;
1965 hr
= WsWriteNode( writer
, &node
, NULL
);
1966 ok( hr
== S_OK
, "got %08x\n", hr
);
1968 utf8
.value
.bytes
= (BYTE
*)"cdata";
1969 utf8
.value
.length
= sizeof("cdata") - 1;
1970 text
.text
= &utf8
.text
;
1971 hr
= WsWriteNode( writer
, &text
.node
, NULL
);
1972 ok( hr
== S_OK
, "got %08x\n", hr
);
1974 node
.nodeType
= WS_XML_NODE_TYPE_END_CDATA
;
1975 hr
= WsWriteNode( writer
, &node
, NULL
);
1976 ok( hr
== S_OK
, "got %08x\n", hr
);
1978 utf8
.value
.bytes
= (BYTE
*)"text";
1979 utf8
.value
.length
= sizeof("text") - 1;
1980 hr
= WsWriteNode( writer
, &text
.node
, NULL
);
1981 ok( hr
== S_OK
, "got %08x\n", hr
);
1983 node
.nodeType
= WS_XML_NODE_TYPE_END_ELEMENT
;
1984 hr
= WsWriteNode( writer
, &node
, NULL
);
1985 ok( hr
== S_OK
, "got %08x\n", hr
);
1986 check_output_buffer( buffer
, "<t attr='value'><!--comment--><![CDATA[cdata]]>text</t>", __LINE__
);
1988 WsFreeWriter( writer
);
1992 static HRESULT
set_input( WS_XML_READER
*reader
, const char *data
, ULONG size
)
1994 WS_XML_READER_TEXT_ENCODING text
= {{WS_XML_READER_ENCODING_TYPE_TEXT
}, WS_CHARSET_AUTO
};
1995 WS_XML_READER_BUFFER_INPUT buf
= {{WS_XML_READER_INPUT_TYPE_BUFFER
}, (void *)data
, size
};
1996 return WsSetInput( reader
, &text
.encoding
, &buf
.input
, NULL
, 0, NULL
);
1999 static void test_WsCopyNode(void)
2001 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {1, (BYTE
*)"u"}, ns
= {0, NULL
};
2002 WS_XML_NODE_POSITION pos
, pos2
;
2003 const WS_XML_NODE
*node
;
2004 WS_XML_WRITER
*writer
;
2005 WS_XML_READER
*reader
;
2006 WS_XML_BUFFER
*buffer
;
2011 hr
= WsCreateHeap( 1 << 16, 0, NULL
, 0, &heap
, NULL
);
2012 ok( hr
== S_OK
, "got %08x\n", hr
);
2014 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2015 ok( hr
== S_OK
, "got %08x\n", hr
);
2017 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
2018 ok( hr
== S_OK
, "got %08x\n", hr
);
2020 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
2021 ok( hr
== S_OK
, "got %08x\n", hr
);
2023 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2024 ok( hr
== S_OK
, "got %08x\n", hr
);
2026 hr
= WsWriteStartElement( writer
, NULL
, &localname2
, &ns
, NULL
);
2027 ok( hr
== S_OK
, "got %08x\n", hr
);
2029 hr
= WsWriteEndElement( writer
, NULL
);
2030 ok( hr
== S_OK
, "got %08x\n", hr
);
2032 hr
= WsGetWriterPosition( writer
, &pos
, NULL
);
2033 ok( hr
== S_OK
, "got %08x\n", hr
);
2035 hr
= WsWriteEndElement( writer
, NULL
);
2036 ok( hr
== S_OK
, "got %08x\n", hr
);
2037 check_output_buffer( buffer
, "<t><u/></t>", __LINE__
);
2039 hr
= WsCreateReader( NULL
, 0, &reader
, NULL
);
2040 ok( hr
== S_OK
, "got %08x\n", hr
);
2042 hr
= set_input( reader
, "<v/>", sizeof("<v/>") - 1 );
2043 ok( hr
== S_OK
, "got %08x\n", hr
);
2045 hr
= WsFillReader( reader
, sizeof("<v/>") - 1, NULL
, NULL
);
2046 ok( hr
== S_OK
, "got %08x\n", hr
);
2048 hr
= WsReadToStartElement( reader
, NULL
, NULL
, NULL
, NULL
);
2049 ok( hr
== S_OK
, "got %08x\n", hr
);
2051 hr
= WsSetWriterPosition( writer
, &pos
, NULL
);
2052 ok( hr
== S_OK
, "got %08x\n", hr
);
2054 hr
= WsCopyNode( writer
, reader
, NULL
);
2055 ok( hr
== S_OK
, "got %08x\n", hr
);
2056 check_output_buffer( buffer
, "<t><u/><v/></t>", __LINE__
);
2058 hr
= WsGetWriterPosition( writer
, &pos2
, NULL
);
2059 ok( hr
== S_OK
, "got %08x\n", hr
);
2060 ok( pos2
.buffer
== pos
.buffer
, "wrong buffer\n" );
2061 ok( pos2
.node
== pos
.node
, "wrong node\n" );
2063 hr
= WsGetReaderNode( reader
, &node
, NULL
);
2064 ok( hr
== S_OK
, "got %08x\n", hr
);
2065 ok( node
->nodeType
== WS_XML_NODE_TYPE_EOF
, "got %u\n", node
->nodeType
);
2067 /* reader positioned at EOF */
2068 hr
= WsCreateXmlBuffer( heap
, NULL
, 0, &buffer
, NULL
);
2069 ok( hr
== S_OK
, "got %08x\n", hr
);
2071 hr
= WsSetOutputToBuffer( writer
, buffer
, NULL
, 0, NULL
);
2072 ok( hr
== S_OK
, "got %08x\n", hr
);
2074 hr
= WsCopyNode( writer
, reader
, NULL
);
2075 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
2077 /* reader positioned at BOF */
2078 hr
= set_input( reader
, "<v/>", sizeof("<v/>") - 1 );
2079 ok( hr
== S_OK
, "got %08x\n", hr
);
2081 hr
= WsFillReader( reader
, sizeof("<v/>") - 1, NULL
, NULL
);
2082 ok( hr
== S_OK
, "got %08x\n", hr
);
2084 hr
= WsGetReaderNode( reader
, &node
, NULL
);
2085 ok( hr
== S_OK
, "got %08x\n", hr
);
2086 ok( node
->nodeType
== WS_XML_NODE_TYPE_BOF
, "got %u\n", node
->nodeType
);
2088 hr
= set_output( writer
);
2089 ok( hr
== S_OK
, "got %08x\n", hr
);
2091 hr
= WsCopyNode( writer
, reader
, NULL
);
2092 ok( hr
== S_OK
, "got %08x\n", hr
);
2093 check_output( writer
, "<v/>", __LINE__
);
2095 hr
= WsGetReaderNode( reader
, &node
, NULL
);
2096 ok( hr
== S_OK
, "got %08x\n", hr
);
2097 ok( node
->nodeType
== WS_XML_NODE_TYPE_EOF
, "got %u\n", node
->nodeType
);
2099 memset( &bufs
, 0, sizeof(bufs
) );
2100 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BUFFERS
, &bufs
, sizeof(bufs
), NULL
);
2101 ok( hr
== S_OK
, "got %08x\n", hr
);
2102 ok( bufs
.bufferCount
== 1, "got %u\n", bufs
.bufferCount
);
2103 ok( bufs
.buffers
!= NULL
, "buffers not set\n" );
2105 /* reader positioned at BOF, single text node */
2106 hr
= set_input( reader
, "text", sizeof("text") - 1 );
2107 ok( hr
== S_OK
, "got %08x\n", hr
);
2109 hr
= WsGetReaderNode( reader
, &node
, NULL
);
2110 ok( hr
== S_OK
, "got %08x\n", hr
);
2111 ok( node
->nodeType
== WS_XML_NODE_TYPE_BOF
, "got %u\n", node
->nodeType
);
2113 hr
= set_output( writer
);
2114 ok( hr
== S_OK
, "got %08x\n", hr
);
2116 hr
= WsCopyNode( writer
, reader
, NULL
);
2117 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
2119 WsFreeReader( reader
);
2120 WsFreeWriter( writer
);
2124 static void test_text_types(void)
2126 static const WCHAR utf16W
[] = {'u','t','f','1','6'};
2127 WS_XML_STRING prefix
= {1, (BYTE
*)"p"}, localname
= {1, (BYTE
*)"t"}, localname2
= {1, (BYTE
*)"u"};
2128 WS_XML_STRING ns
= {0, NULL
}, ns2
= {2, (BYTE
*)"ns"};
2129 WS_XML_WRITER
*writer
;
2130 static const WS_XML_UTF8_TEXT val_utf8
= { {WS_XML_TEXT_TYPE_UTF8
}, {4, (BYTE
*)"utf8"} };
2131 static WS_XML_UTF16_TEXT val_utf16
= { {WS_XML_TEXT_TYPE_UTF16
} };
2132 static WS_XML_QNAME_TEXT val_qname
= { {WS_XML_TEXT_TYPE_QNAME
} };
2133 static const WS_XML_GUID_TEXT val_guid
= { {WS_XML_TEXT_TYPE_GUID
} };
2134 static const WS_XML_UNIQUE_ID_TEXT val_urn
= { {WS_XML_TEXT_TYPE_UNIQUE_ID
} };
2135 static const WS_XML_BOOL_TEXT val_bool
= { {WS_XML_TEXT_TYPE_BOOL
}, TRUE
};
2136 static const WS_XML_INT32_TEXT val_int32
= { {WS_XML_TEXT_TYPE_INT32
}, -2147483647 - 1 };
2137 static const WS_XML_INT64_TEXT val_int64
= { {WS_XML_TEXT_TYPE_INT64
}, -9223372036854775807 - 1 };
2138 static const WS_XML_UINT64_TEXT val_uint64
= { {WS_XML_TEXT_TYPE_UINT64
}, ~0 };
2139 static const WS_XML_DATETIME_TEXT val_datetime
= { {WS_XML_TEXT_TYPE_DATETIME
}, {0, WS_DATETIME_FORMAT_UTC
} };
2140 static const WS_XML_DOUBLE_TEXT val_double
= { {WS_XML_TEXT_TYPE_DOUBLE
}, 1.1 };
2141 static const WS_XML_BASE64_TEXT val_base64
= { {WS_XML_TEXT_TYPE_BASE64
}, (BYTE
*)"test", 4 };
2144 const WS_XML_TEXT
*text
;
2149 { &val_utf8
.text
, "<t>utf8</t>" },
2150 { &val_utf16
.text
, "<t>utf16</t>" },
2151 { &val_guid
.text
, "<t>00000000-0000-0000-0000-000000000000</t>" },
2152 { &val_urn
.text
, "<t>urn:uuid:00000000-0000-0000-0000-000000000000</t>" },
2153 { &val_bool
.text
, "<t>true</t>" },
2154 { &val_int32
.text
, "<t>-2147483648</t>" },
2155 { &val_int64
.text
, "<t>-9223372036854775808</t>" },
2156 { &val_uint64
.text
, "<t>18446744073709551615</t>" },
2157 { &val_datetime
.text
, "<t>0001-01-01T00:00:00Z</t>" },
2158 { &val_double
.text
, "<t>1.1</t>" },
2159 { &val_base64
.text
, "<t>dGVzdA==</t>" },
2160 { &val_qname
.text
, "<t>u</t>" },
2165 val_utf16
.bytes
= (BYTE
*)utf16W
;
2166 val_utf16
.byteCount
= sizeof(utf16W
);
2167 val_qname
.localName
= &localname2
;
2170 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2171 ok( hr
== S_OK
, "got %08x\n", hr
);
2173 for (i
= 0; i
< ARRAY_SIZE( tests
); i
++)
2175 hr
= set_output( writer
);
2176 ok( hr
== S_OK
, "got %08x\n", hr
);
2177 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2178 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2180 hr
= WsWriteText( writer
, tests
[i
].text
, NULL
);
2181 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2183 hr
= WsWriteEndElement( writer
, NULL
);
2184 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2185 check_output( writer
, tests
[i
].result
, __LINE__
);
2188 hr
= set_output( writer
);
2189 ok( hr
== S_OK
, "got %08x\n", hr
);
2190 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns2
, NULL
);
2191 ok( hr
== S_OK
, "got %08x\n", hr
);
2193 val_qname
.prefix
= &prefix
;
2194 val_qname
.localName
= &localname2
;
2195 val_qname
.ns
= &ns2
;
2196 hr
= WsWriteText( writer
, &val_qname
.text
, NULL
);
2197 ok( hr
== S_OK
, "got %08x\n", hr
);
2199 hr
= WsWriteEndElement( writer
, NULL
);
2200 ok( hr
== S_OK
, "got %08x\n", hr
);
2201 check_output( writer
, "<p:t xmlns:p=\"ns\">p:u</p:t>", __LINE__
);
2203 WsFreeWriter( writer
);
2206 static BOOL
get_fpword( unsigned short *ret
)
2208 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
2209 unsigned short fpword
;
2210 __asm__
__volatile__( "fstcw %0" : "=m" (fpword
) );
2217 static void set_fpword( unsigned short fpword
)
2219 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
2220 __asm__
__volatile__( "fldcw %0" : : "m" (fpword
) );
2224 static void test_double(void)
2226 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
2227 unsigned short fpword
;
2237 {-1.0, "<t>-1</t>"},
2238 {1.0000000000000001, "<t>1</t>"},
2239 {1.0000000000000002, "<t>1.0000000000000002</t>"},
2240 {1.0000000000000003, "<t>1.0000000000000002</t>"},
2241 {1.0000000000000004, "<t>1.0000000000000004</t>"},
2242 {100000000000000, "<t>100000000000000</t>"},
2243 {1000000000000000, "<t>1E+15</t>"},
2244 {0.1, "<t>0.1</t>"},
2245 {0.01, "<t>1E-2</t>"},
2246 {-0.1, "<t>-0.1</t>"},
2247 {-0.01, "<t>-1E-2</t>"},
2248 {1.7976931348623158e308
, "<t>1.7976931348623157E+308</t>"},
2249 {-1.7976931348623158e308
, "<t>-1.7976931348623157E+308</t>"},
2252 WS_XML_WRITER
*writer
;
2253 WS_XML_DOUBLE_TEXT text
;
2256 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
) ;
2257 ok( hr
== S_OK
, "got %08x\n", hr
);
2259 text
.text
.textType
= WS_XML_TEXT_TYPE_DOUBLE
;
2260 for (i
= 0; i
< ARRAY_SIZE( tests
); i
++)
2262 hr
= set_output( writer
);
2263 ok( hr
== S_OK
, "got %08x\n", hr
);
2264 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2265 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2267 text
.value
= tests
[i
].val
;
2268 hr
= WsWriteText( writer
, &text
.text
, NULL
);
2269 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2271 hr
= WsWriteEndElement( writer
, NULL
);
2272 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2273 check_output( writer
, tests
[i
].result
, __LINE__
);
2276 hr
= set_output( writer
);
2277 ok( hr
== S_OK
, "got %08x\n", hr
);
2278 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2279 ok( hr
== S_OK
, "got %08x\n", hr
);
2282 hr
= WsWriteText( writer
, &text
.text
, NULL
);
2283 ok( hr
== S_OK
, "got %08x\n", hr
);
2285 hr
= WsWriteEndElement( writer
, NULL
);
2286 ok( hr
== S_OK
, "got %08x\n", hr
);
2287 check_output( writer
, "<t>NaN</t>", __LINE__
);
2289 hr
= set_output( writer
);
2290 ok( hr
== S_OK
, "got %08x\n", hr
);
2291 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2292 ok( hr
== S_OK
, "got %08x\n", hr
);
2294 text
.value
= INFINITY
;
2295 hr
= WsWriteText( writer
, &text
.text
, NULL
);
2296 ok( hr
== S_OK
, "got %08x\n", hr
);
2298 hr
= WsWriteEndElement( writer
, NULL
);
2299 ok( hr
== S_OK
, "got %08x\n", hr
);
2300 check_output( writer
, "<t>INF</t>", __LINE__
);
2302 hr
= set_output( writer
);
2303 ok( hr
== S_OK
, "got %08x\n", hr
);
2304 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2305 ok( hr
== S_OK
, "got %08x\n", hr
);
2307 text
.value
= -INFINITY
;
2308 hr
= WsWriteText( writer
, &text
.text
, NULL
);
2309 ok( hr
== S_OK
, "got %08x\n", hr
);
2311 hr
= WsWriteEndElement( writer
, NULL
);
2312 ok( hr
== S_OK
, "got %08x\n", hr
);
2313 check_output( writer
, "<t>-INF</t>", __LINE__
);
2315 if (!get_fpword( &fpword
))
2317 skip( "can't get floating point control word\n" );
2318 WsFreeWriter( writer
);
2321 ok( fpword
== 0x27f, "got %04x\n", fpword
);
2322 set_fpword( 0x1f7f );
2323 get_fpword( &fpword
);
2324 ok( fpword
== 0x1f7f, "got %04x\n", fpword
);
2326 hr
= set_output( writer
);
2327 ok( hr
== S_OK
, "got %08x\n", hr
);
2328 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2329 ok( hr
== S_OK
, "got %08x\n", hr
);
2331 text
.value
= 100000000000000;
2332 hr
= WsWriteText( writer
, &text
.text
, NULL
);
2333 ok( hr
== S_OK
, "got %08x\n", hr
);
2335 hr
= WsWriteEndElement( writer
, NULL
);
2336 ok( hr
== S_OK
, "got %08x\n", hr
);
2337 check_output( writer
, "<t>100000000000000</t>", __LINE__
);
2339 get_fpword( &fpword
);
2340 ok( fpword
== 0x1f7f, "got %04x\n", fpword
);
2341 set_fpword( 0x27f );
2343 WsFreeWriter( writer
);
2346 static void test_field_options(void)
2348 static const char expected
[] =
2349 "<t><bool a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/><int32>-1</int32>"
2350 "<xmlstr a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/></t>";
2352 WS_XML_WRITER
*writer
;
2353 WS_STRUCT_DESCRIPTION s
;
2354 WS_FIELD_DESCRIPTION f
, f2
, f3
, f4
, f5
, *fields
[5];
2355 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
}, str_guid
= {4, (BYTE
*)"guid"};
2356 WS_XML_STRING str_int32
= {5, (BYTE
*)"int32"}, str_bool
= {4, (BYTE
*)"bool"};
2357 WS_XML_STRING str_xmlstr
= {6, (BYTE
*)"xmlstr"}, str_str
= {3, (BYTE
*)"str"};
2364 WS_XML_STRING xmlstr
;
2368 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2369 ok( hr
== S_OK
, "got %08x\n", hr
);
2371 hr
= set_output( writer
);
2372 ok( hr
== S_OK
, "got %08x\n", hr
);
2374 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2375 ok( hr
== S_OK
, "got %08x\n", hr
);
2377 memset( &f
, 0, sizeof(f
) );
2378 f
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
2379 f
.localName
= &str_guid
;
2381 f
.type
= WS_GUID_TYPE
;
2382 f
.options
= WS_FIELD_OPTIONAL
;
2385 memset( &f2
, 0, sizeof(f2
) );
2386 f2
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
2387 f2
.localName
= &str_bool
;
2388 f2
.offset
= FIELD_OFFSET(struct test
, bool_ptr
);
2390 f2
.type
= WS_BOOL_TYPE
;
2391 f2
.options
= WS_FIELD_POINTER
|WS_FIELD_NILLABLE
;
2394 memset( &f3
, 0, sizeof(f3
) );
2395 f3
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
2396 f3
.localName
= &str_int32
;
2397 f3
.offset
= FIELD_OFFSET(struct test
, int32_ptr
);
2399 f3
.type
= WS_INT32_TYPE
;
2400 f3
.options
= WS_FIELD_POINTER
|WS_FIELD_NILLABLE
;
2403 memset( &f4
, 0, sizeof(f4
) );
2404 f4
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
2405 f4
.localName
= &str_xmlstr
;
2406 f4
.offset
= FIELD_OFFSET(struct test
, xmlstr
);
2408 f4
.type
= WS_XML_STRING_TYPE
;
2409 f4
.options
= WS_FIELD_NILLABLE
;
2412 memset( &f5
, 0, sizeof(f5
) );
2413 f5
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
2414 f5
.localName
= &str_str
;
2415 f5
.offset
= FIELD_OFFSET(struct test
, str
);
2417 f5
.type
= WS_WSZ_TYPE
;
2418 f5
.options
= WS_FIELD_OPTIONAL
|WS_FIELD_NILLABLE
;
2421 memset( &s
, 0, sizeof(s
) );
2422 s
.size
= sizeof(struct test
);
2423 s
.alignment
= TYPE_ALIGNMENT(struct test
);
2427 memset( &test
, 0, sizeof(test
) );
2428 test
.int32_ptr
= &val
;
2429 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
2430 &test
, sizeof(test
), NULL
);
2431 ok( hr
== S_OK
, "got %08x\n", hr
);
2433 hr
= WsWriteEndElement( writer
, NULL
);
2434 ok( hr
== S_OK
, "got %08x\n", hr
);
2435 check_output( writer
, expected
, __LINE__
);
2437 WsFreeWriter( writer
);
2440 static void test_WsWriteText(void)
2442 static const WCHAR testW
[] = {'t','e','s','t'};
2443 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {1, (BYTE
*)"a"}, ns
= {0, NULL
};
2445 WS_XML_WRITER
*writer
;
2446 WS_XML_UTF8_TEXT utf8
= {{WS_XML_TEXT_TYPE_UTF8
}};
2447 WS_XML_UTF16_TEXT utf16
= {{WS_XML_TEXT_TYPE_UTF16
}};
2448 WS_XML_GUID_TEXT guid
= {{WS_XML_TEXT_TYPE_GUID
}};
2450 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2451 ok( hr
== S_OK
, "got %08x\n", hr
);
2453 hr
= set_output( writer
);
2454 ok( hr
== S_OK
, "got %08x\n", hr
);
2456 utf8
.value
.bytes
= (BYTE
*)"test";
2457 utf8
.value
.length
= 4;
2458 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2459 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
2461 hr
= set_output( writer
);
2462 ok( hr
== S_OK
, "got %08x\n", hr
);
2465 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2466 ok( hr
== S_OK
, "got %08x\n", hr
);
2468 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2469 ok( hr
== S_OK
, "got %08x\n", hr
);
2470 check_output( writer
, "<t>test", __LINE__
);
2472 utf8
.value
.bytes
= (BYTE
*)"tset";
2473 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2474 ok( hr
== S_OK
, "got %08x\n", hr
);
2475 check_output( writer
, "<t>testtset", __LINE__
);
2477 hr
= WsWriteEndElement( writer
, NULL
);
2478 ok( hr
== S_OK
, "got %08x\n", hr
);
2479 check_output( writer
, "<t>testtset</t>", __LINE__
);
2481 hr
= set_output( writer
);
2482 ok( hr
== S_OK
, "got %08x\n", hr
);
2484 /* attribute, utf8 */
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
, &utf8
.text
, NULL
);
2492 ok( hr
== S_OK
, "got %08x\n", hr
);
2493 check_output( writer
, "", __LINE__
);
2495 utf8
.value
.bytes
= (BYTE
*)"test";
2496 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2497 ok( hr
== S_OK
, "got %08x\n", hr
);
2498 check_output( writer
, "", __LINE__
);
2500 hr
= WsWriteEndAttribute( writer
, NULL
);
2501 ok( hr
== S_OK
, "got %08x\n", hr
);
2503 hr
= WsWriteEndElement( writer
, NULL
);
2504 ok( hr
== S_OK
, "got %08x\n", hr
);
2505 check_output( writer
, "<t a=\"tsettest\"/>", __LINE__
);
2507 hr
= set_output( writer
);
2508 ok( hr
== S_OK
, "got %08x\n", hr
);
2510 /* element, utf16 */
2511 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2512 ok( hr
== S_OK
, "got %08x\n", hr
);
2514 utf16
.bytes
= (BYTE
*)testW
;
2515 utf16
.byteCount
= sizeof(testW
);
2516 hr
= WsWriteText( writer
, &utf16
.text
, NULL
);
2517 ok( hr
== S_OK
, "got %08x\n", hr
);
2518 check_output( writer
, "<t>test", __LINE__
);
2520 hr
= WsWriteText( writer
, &utf16
.text
, NULL
);
2521 ok( hr
== S_OK
, "got %08x\n", hr
);
2522 check_output( writer
, "<t>testtest", __LINE__
);
2524 hr
= WsWriteEndElement( writer
, NULL
);
2525 ok( hr
== S_OK
, "got %08x\n", hr
);
2526 check_output( writer
, "<t>testtest</t>", __LINE__
);
2528 hr
= set_output( writer
);
2529 ok( hr
== S_OK
, "got %08x\n", hr
);
2531 /* attribute, utf16 */
2532 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2533 ok( hr
== S_OK
, "got %08x\n", hr
);
2535 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
2536 ok( hr
== S_OK
, "got %08x\n", hr
);
2538 hr
= WsWriteText( writer
, &utf16
.text
, NULL
);
2539 ok( hr
== S_OK
, "got %08x\n", hr
);
2540 check_output( writer
, "", __LINE__
);
2542 hr
= WsWriteText( writer
, &utf16
.text
, NULL
);
2543 ok( hr
== S_OK
, "got %08x\n", hr
);
2544 check_output( writer
, "", __LINE__
);
2546 hr
= WsWriteEndAttribute( writer
, NULL
);
2547 ok( hr
== S_OK
, "got %08x\n", hr
);
2549 hr
= WsWriteEndElement( writer
, NULL
);
2550 ok( hr
== S_OK
, "got %08x\n", hr
);
2551 check_output( writer
, "<t a=\"testtest\"/>", __LINE__
);
2553 hr
= set_output( writer
);
2554 ok( hr
== S_OK
, "got %08x\n", hr
);
2557 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2558 ok( hr
== S_OK
, "got %08x\n", hr
);
2560 hr
= WsWriteText( writer
, &guid
.text
, NULL
);
2561 ok( hr
== S_OK
, "got %08x\n", hr
);
2562 check_output( writer
, "<t>00000000-0000-0000-0000-000000000000", __LINE__
);
2564 hr
= WsWriteText( writer
, &guid
.text
, NULL
);
2565 ok( hr
== S_OK
, "got %08x\n", hr
);
2566 check_output( writer
, "<t>00000000-0000-0000-0000-00000000000000000000-0000-0000-0000-000000000000",
2569 /* continue with different text type */
2570 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2571 ok( hr
== S_OK
, "got %08x\n", hr
);
2572 check_output( writer
, "<t>00000000-0000-0000-0000-00000000000000000000-0000-0000-0000-000000000000test",
2575 hr
= WsWriteEndElement( writer
, NULL
);
2576 ok( hr
== S_OK
, "got %08x\n", hr
);
2578 hr
= set_output( writer
);
2579 ok( hr
== S_OK
, "got %08x\n", hr
);
2581 /* attribute, guid */
2582 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2583 ok( hr
== S_OK
, "got %08x\n", hr
);
2585 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
2586 ok( hr
== S_OK
, "got %08x\n", hr
);
2588 hr
= WsWriteText( writer
, &guid
.text
, NULL
);
2589 ok( hr
== S_OK
, "got %08x\n", hr
);
2590 check_output( writer
, "", __LINE__
);
2592 hr
= WsWriteText( writer
, &guid
.text
, NULL
);
2593 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
2595 hr
= set_output( writer
);
2596 ok( hr
== S_OK
, "got %08x\n", hr
);
2598 /* attribute, mix allowed text types */
2599 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2600 ok( hr
== S_OK
, "got %08x\n", hr
);
2602 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
2603 ok( hr
== S_OK
, "got %08x\n", hr
);
2605 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2606 ok( hr
== S_OK
, "got %08x\n", hr
);
2608 hr
= WsWriteText( writer
, &utf16
.text
, NULL
);
2609 todo_wine
ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
2611 hr
= set_output( writer
);
2612 ok( hr
== S_OK
, "got %08x\n", hr
);
2615 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2616 ok( hr
== S_OK
, "got %08x\n", hr
);
2617 hr
= WsWriteStartCData( writer
, NULL
);
2618 ok( hr
== S_OK
, "got %08x\n", hr
);
2620 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2621 ok( hr
== S_OK
, "got %08x\n", hr
);
2623 hr
= WsWriteText( writer
, &guid
.text
, NULL
);
2624 ok( hr
== S_OK
, "got %08x\n", hr
);
2626 hr
= WsWriteEndCData( writer
, NULL
);
2627 ok( hr
== S_OK
, "got %08x\n", hr
);
2628 hr
= WsWriteEndElement( writer
, NULL
);
2629 ok( hr
== S_OK
, "got %08x\n", hr
);
2630 check_output( writer
, "<t><![CDATA[test00000000-0000-0000-0000-000000000000]]></t>", __LINE__
);
2632 WsFreeWriter( writer
);
2635 static void test_WsWriteArray(void)
2637 static const WS_XML_STRING localname
= {4, (BYTE
*)"item"}, localname2
= {5, (BYTE
*)"array"};
2638 static const WS_XML_STRING ns
= {0, NULL
};
2639 WS_XML_WRITER
*writer
;
2643 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2644 ok( hr
== S_OK
, "got %08x\n", hr
);
2646 hr
= WsWriteArray( writer
, NULL
, NULL
, 0, NULL
, 0, 0, 0, NULL
);
2647 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
2649 hr
= set_output( writer
);
2650 ok( hr
== S_OK
, "got %08x\n", hr
);
2651 hr
= WsWriteArray( writer
, NULL
, NULL
, 0, NULL
, 0, 0, 0, NULL
);
2652 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2654 hr
= set_output( writer
);
2655 ok( hr
== S_OK
, "got %08x\n", hr
);
2656 hr
= WsWriteArray( writer
, &localname
, NULL
, 0, NULL
, 0, 0, 0, NULL
);
2657 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2659 hr
= set_output( writer
);
2660 ok( hr
== S_OK
, "got %08x\n", hr
);
2661 hr
= WsWriteArray( writer
, &localname
, &ns
, 0, NULL
, 0, 0, 0, NULL
);
2662 ok( hr
== S_OK
, "got %08x\n", hr
);
2663 check_output( writer
, "", __LINE__
);
2665 hr
= WsWriteArray( writer
, &localname
, &ns
, ~0u, NULL
, 0, 0, 0, NULL
);
2666 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2668 hr
= set_output( writer
);
2669 ok( hr
== S_OK
, "got %08x\n", hr
);
2670 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, NULL
, 0, 0, 0, NULL
);
2671 ok( hr
== S_OK
, "got %08x\n", hr
);
2672 check_output( writer
, "", __LINE__
);
2674 array_bool
[0] = FALSE
;
2675 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, array_bool
, 0, 0, 0, NULL
);
2676 ok( hr
== S_OK
, "got %08x\n", hr
);
2677 check_output( writer
, "", __LINE__
);
2679 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, array_bool
, sizeof(array_bool
), 0, 0, NULL
);
2680 ok( hr
== S_OK
, "got %08x\n", hr
);
2681 check_output( writer
, "", __LINE__
);
2683 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, NULL
, sizeof(array_bool
), 0, 0, NULL
);
2684 ok( hr
== S_OK
, "got %08x\n", hr
);
2685 check_output( writer
, "", __LINE__
);
2687 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, NULL
, sizeof(array_bool
), 0, 1, NULL
);
2688 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2690 hr
= set_output( writer
);
2691 ok( hr
== S_OK
, "got %08x\n", hr
);
2692 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, array_bool
, sizeof(array_bool
), 0, 1, NULL
);
2693 ok( hr
== S_OK
, "got %08x\n", hr
);
2694 check_output( writer
, "<item>false</item>", __LINE__
);
2696 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, array_bool
, sizeof(array_bool
) - 1, 0, 2, NULL
);
2697 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2699 hr
= set_output( writer
);
2700 ok( hr
== S_OK
, "got %08x\n", hr
);
2701 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, array_bool
, sizeof(array_bool
), 0, 3, NULL
);
2702 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2704 hr
= set_output( writer
);
2705 ok( hr
== S_OK
, "got %08x\n", hr
);
2707 hr
= WsWriteStartElement( writer
, NULL
, &localname2
, &ns
, NULL
);
2708 ok( hr
== S_OK
, "got %08x\n", hr
);
2710 array_bool
[1] = TRUE
;
2711 hr
= WsWriteArray( writer
, &localname
, &ns
, WS_BOOL_VALUE_TYPE
, array_bool
, sizeof(array_bool
), 0, 2, NULL
);
2712 ok( hr
== S_OK
, "got %08x\n", hr
);
2714 hr
= WsWriteEndElement( writer
, NULL
);
2715 ok( hr
== S_OK
, "got %08x\n", hr
);
2716 check_output( writer
, "<array><item>false</item><item>true</item></array>", __LINE__
);
2718 WsFreeWriter( writer
);
2721 static void test_escapes(void)
2723 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
2724 WS_XML_UTF8_TEXT utf8
= {{WS_XML_TEXT_TYPE_UTF8
}};
2725 WS_XML_WRITER
*writer
;
2732 static const struct test tests_elem
[] =
2734 { "<", "<t><</t>" },
2735 { ">", "<t>></t>" },
2736 { "\"", "<t>\"</t>" },
2737 { "&", "<t>&</t>" },
2738 { "&&", "<t>&&</t>" },
2739 { "'", "<t>'</t>" },
2741 static const struct test tests_attr
[] =
2743 { "<", "<t t=\"<\"/>" },
2744 { ">", "<t t=\">\"/>" },
2745 { "\"", "<t t=\""\"/>" },
2746 { "&", "<t t=\"&\"/>" },
2747 { "'", "<t t=\"'\"/>" },
2748 { "\"", "<t t='\"'/>", TRUE
},
2749 { "'", "<t t='''/>", TRUE
},
2751 static const struct test tests_cdata
[] =
2753 { "<", "<t><![CDATA[<]]></t>" },
2754 { ">", "<t><![CDATA[>]]></t>" },
2755 { "\"", "<t><![CDATA[\"]]></t>" },
2756 { "&", "<t><![CDATA[&]]></t>" },
2757 { "[", "<t><![CDATA[[]]></t>" },
2758 { "]", "<t><![CDATA[]]]></t>" },
2759 { "'", "<t><![CDATA[']]></t>" },
2761 static const struct test tests_comment
[] =
2763 { "<", "<t><!--<--></t>" },
2764 { ">", "<t><!-->--></t>" },
2765 { "\"", "<t><!--\"--></t>" },
2766 { "&", "<t><!--&--></t>" },
2767 { "'", "<t><!--'--></t>" },
2772 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2773 ok( hr
== S_OK
, "got %08x\n", hr
);
2775 for (i
= 0; i
< ARRAY_SIZE( tests_elem
); i
++)
2777 hr
= set_output( writer
);
2778 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2779 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2780 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2782 utf8
.value
.bytes
= (BYTE
*)tests_elem
[i
].text
;
2783 utf8
.value
.length
= strlen( tests_elem
[i
].text
);
2784 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2785 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2787 hr
= WsWriteEndElement( writer
, NULL
);
2788 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2789 check_output( writer
, tests_elem
[i
].result
, __LINE__
);
2792 for (i
= 0; i
< ARRAY_SIZE( tests_attr
); i
++)
2794 hr
= set_output( writer
);
2795 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2796 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2797 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2799 hr
= WsWriteStartAttribute( writer
, NULL
, &localname
, &ns
, tests_attr
[i
].single
, NULL
);
2800 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2802 utf8
.value
.bytes
= (BYTE
*)tests_attr
[i
].text
;
2803 utf8
.value
.length
= strlen( tests_attr
[i
].text
);
2804 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2805 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2807 hr
= WsWriteEndAttribute( writer
, NULL
);
2808 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2810 hr
= WsWriteEndElement( writer
, NULL
);
2811 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2812 check_output( writer
, tests_attr
[i
].result
, __LINE__
);
2815 for (i
= 0; i
< ARRAY_SIZE( tests_cdata
); i
++)
2817 hr
= set_output( writer
);
2818 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2819 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2820 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2822 hr
= WsWriteStartCData( writer
, NULL
);
2823 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2825 utf8
.value
.bytes
= (BYTE
*)tests_cdata
[i
].text
;
2826 utf8
.value
.length
= strlen( tests_cdata
[i
].text
);
2827 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
2828 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2830 hr
= WsWriteEndCData( writer
, NULL
);
2831 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2833 hr
= WsWriteEndElement( writer
, NULL
);
2834 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2835 check_output( writer
, tests_cdata
[i
].result
, __LINE__
);
2838 for (i
= 0; i
< ARRAY_SIZE( tests_comment
); i
++)
2840 WS_XML_COMMENT_NODE comment
= {{WS_XML_NODE_TYPE_COMMENT
}};
2842 hr
= set_output( writer
);
2843 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2844 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2845 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2847 comment
.value
.bytes
= (BYTE
*)tests_comment
[i
].text
;
2848 comment
.value
.length
= strlen( tests_comment
[i
].text
);
2849 hr
= WsWriteNode( writer
, &comment
.node
, NULL
);
2850 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2852 hr
= WsWriteEndElement( writer
, NULL
);
2853 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2854 check_output( writer
, tests_comment
[i
].result
, __LINE__
);
2857 WsFreeWriter( writer
);
2860 static void test_write_option(void)
2862 static const WCHAR sW
[] = {'s',0};
2863 static const WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
2864 WS_XML_WRITER
*writer
;
2865 int val_int
= -1, val_int_zero
= 0, *ptr_int
= &val_int
, *ptr_int_null
= NULL
;
2866 const WCHAR
*ptr_wsz
= sW
, *ptr_wsz_null
= NULL
;
2867 static const WS_XML_STRING val_xmlstr
= {1, (BYTE
*)"x"}, val_xmlstr_zero
= {0, NULL
};
2868 const WS_XML_STRING
*ptr_xmlstr
= &val_xmlstr
, *ptr_xmlstr_null
= NULL
;
2872 WS_WRITE_OPTION option
;
2880 { WS_INT32_TYPE
, 0, NULL
, 0, E_INVALIDARG
},
2881 { WS_INT32_TYPE
, 0, "str", 0, E_INVALIDARG
},
2882 { WS_INT32_TYPE
, 0, NULL
, sizeof(val_int
), E_INVALIDARG
},
2883 { WS_INT32_TYPE
, 0, &val_int
, sizeof(val_int
), E_INVALIDARG
},
2884 { WS_INT32_TYPE
, 0, &val_int_zero
, sizeof(val_int_zero
), E_INVALIDARG
},
2885 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_VALUE
, NULL
, 0, E_INVALIDARG
},
2886 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_VALUE
, &val_int
, 0, E_INVALIDARG
},
2887 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_VALUE
, NULL
, sizeof(val_int
), E_INVALIDARG
},
2888 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_VALUE
, &val_int
, sizeof(val_int
), S_OK
, "<t>-1</t>" },
2889 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_VALUE
, &val_int_zero
, sizeof(val_int_zero
), S_OK
, "<t>0</t>" },
2890 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_VALUE
, NULL
, 0, E_INVALIDARG
},
2891 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_VALUE
, &val_int
, 0, E_INVALIDARG
},
2892 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_VALUE
, NULL
, sizeof(val_int
), E_INVALIDARG
},
2893 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_VALUE
, &val_int
, sizeof(val_int
), E_INVALIDARG
},
2894 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_VALUE
, &val_int_zero
, sizeof(val_int_zero
), E_INVALIDARG
},
2895 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_POINTER
, NULL
, 0, E_INVALIDARG
},
2896 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_int
, 0, E_INVALIDARG
},
2897 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_POINTER
, NULL
, sizeof(ptr_int
), E_INVALIDARG
},
2898 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_int
, sizeof(ptr_int
), S_OK
, "<t>-1</t>" },
2899 { WS_INT32_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_int_null
, sizeof(ptr_int_null
), E_INVALIDARG
},
2900 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_POINTER
, NULL
, 0, E_INVALIDARG
},
2901 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_int
, 0, E_INVALIDARG
},
2902 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_POINTER
, NULL
, sizeof(ptr_int
), E_INVALIDARG
},
2903 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_int
, sizeof(ptr_int
), S_OK
, "<t>-1</t>" },
2904 { WS_INT32_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_int_null
, sizeof(ptr_int_null
), S_OK
,
2905 "<t a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/>" },
2906 { WS_XML_STRING_TYPE
, 0, NULL
, 0, E_INVALIDARG
},
2907 { WS_XML_STRING_TYPE
, 0, &val_xmlstr
, 0, E_INVALIDARG
},
2908 { WS_XML_STRING_TYPE
, 0, NULL
, sizeof(val_xmlstr
), E_INVALIDARG
},
2909 { WS_XML_STRING_TYPE
, 0, &val_xmlstr
, sizeof(val_xmlstr
), E_INVALIDARG
},
2910 { WS_XML_STRING_TYPE
, 0, &val_xmlstr_zero
, sizeof(val_xmlstr_zero
), E_INVALIDARG
},
2911 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_VALUE
, NULL
, 0, E_INVALIDARG
},
2912 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_VALUE
, &val_xmlstr
, 0, E_INVALIDARG
},
2913 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_VALUE
, NULL
, sizeof(&val_xmlstr
), E_INVALIDARG
},
2914 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_VALUE
, &val_xmlstr
, sizeof(val_xmlstr
), S_OK
, "<t>x</t>" },
2915 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_VALUE
, &val_xmlstr_zero
, sizeof(val_xmlstr_zero
), S_OK
, "<t/>" },
2916 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_VALUE
, &val_xmlstr
, 0, E_INVALIDARG
},
2917 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_VALUE
, NULL
, sizeof(&val_xmlstr
), E_INVALIDARG
},
2918 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_VALUE
, &val_xmlstr
, sizeof(&val_xmlstr
), E_INVALIDARG
},
2919 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_VALUE
, &val_xmlstr_zero
, sizeof(val_xmlstr_zero
), S_OK
,
2920 "<t a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/>" },
2921 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_POINTER
, NULL
, 0, E_INVALIDARG
},
2922 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_xmlstr
, 0, E_INVALIDARG
},
2923 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_POINTER
, NULL
, sizeof(ptr_xmlstr
), E_INVALIDARG
},
2924 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_xmlstr
, sizeof(ptr_xmlstr
), S_OK
, "<t>x</t>" },
2925 { WS_XML_STRING_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_xmlstr_null
, sizeof(ptr_xmlstr_null
), E_INVALIDARG
},
2926 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_POINTER
, NULL
, 0, E_INVALIDARG
},
2927 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_xmlstr
, 0, E_INVALIDARG
},
2928 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_POINTER
, NULL
, sizeof(ptr_xmlstr
), E_INVALIDARG
},
2929 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_xmlstr
, sizeof(ptr_xmlstr
), S_OK
, "<t>x</t>" },
2930 { WS_XML_STRING_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_xmlstr_null
, sizeof(ptr_xmlstr_null
), S_OK
,
2931 "<t a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/>" },
2932 { WS_WSZ_TYPE
, 0, NULL
, 0, E_INVALIDARG
},
2933 { WS_WSZ_TYPE
, 0, &ptr_wsz
, 0, E_INVALIDARG
},
2934 { WS_WSZ_TYPE
, 0, NULL
, sizeof(ptr_wsz
), E_INVALIDARG
},
2935 { WS_WSZ_TYPE
, 0, &ptr_wsz
, sizeof(ptr_wsz
), E_INVALIDARG
},
2936 { WS_WSZ_TYPE
, 0, &ptr_wsz_null
, sizeof(ptr_wsz_null
), E_INVALIDARG
},
2937 { WS_WSZ_TYPE
, WS_WRITE_REQUIRED_VALUE
, &ptr_wsz
, sizeof(ptr_wsz
), E_INVALIDARG
},
2938 { WS_WSZ_TYPE
, WS_WRITE_NILLABLE_VALUE
, &ptr_wsz
, sizeof(ptr_wsz
), E_INVALIDARG
},
2939 { WS_WSZ_TYPE
, WS_WRITE_REQUIRED_POINTER
, NULL
, 0, E_INVALIDARG
},
2940 { WS_WSZ_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_wsz
, 0, E_INVALIDARG
},
2941 { WS_WSZ_TYPE
, WS_WRITE_REQUIRED_POINTER
, NULL
, sizeof(ptr_wsz
), E_INVALIDARG
},
2942 { WS_WSZ_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_wsz
, sizeof(ptr_wsz
), S_OK
, "<t>s</t>" },
2943 { WS_WSZ_TYPE
, WS_WRITE_REQUIRED_POINTER
, &ptr_wsz_null
, sizeof(ptr_wsz_null
), E_INVALIDARG
},
2944 { WS_WSZ_TYPE
, WS_WRITE_NILLABLE_POINTER
, NULL
, 0, E_INVALIDARG
},
2945 { WS_WSZ_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_wsz
, 0, E_INVALIDARG
},
2946 { WS_WSZ_TYPE
, WS_WRITE_NILLABLE_POINTER
, NULL
, sizeof(ptr_wsz
), E_INVALIDARG
},
2947 { WS_WSZ_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_wsz
, sizeof(ptr_wsz
), S_OK
, "<t>s</t>" },
2948 { WS_WSZ_TYPE
, WS_WRITE_NILLABLE_POINTER
, &ptr_wsz_null
, sizeof(ptr_wsz_null
), S_OK
,
2949 "<t a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/>" },
2954 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
2955 ok( hr
== S_OK
, "got %08x\n", hr
);
2957 for (i
= 0; i
< ARRAY_SIZE( tests
); i
++)
2959 hr
= set_output( writer
);
2960 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2961 WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
2962 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, tests
[i
].type
, NULL
, tests
[i
].option
, tests
[i
].value
,
2963 tests
[i
].size
, NULL
);
2964 ok( hr
== tests
[i
].hr
, "%u: got %08x\n", i
, hr
);
2965 WsWriteEndElement( writer
, NULL
);
2966 if (hr
== S_OK
) check_output( writer
, tests
[i
].result
, __LINE__
);
2969 WsFreeWriter( writer
);
2972 static BOOL
check_result( WS_XML_WRITER
*writer
, const char *expected
)
2975 ULONG size
= sizeof(bytes
);
2976 int len
= strlen( expected
);
2978 memset( &bytes
, 0, sizeof(bytes
) );
2979 WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
2980 if (bytes
.length
!= len
) return FALSE
;
2981 return !memcmp( bytes
.bytes
, expected
, len
);
2984 static void test_datetime(void)
2986 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, ns
= {0, NULL
};
2989 unsigned __int64 ticks
;
2990 WS_DATETIME_FORMAT format
;
2993 const char *result2
;
2998 { 0, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>0001-01-01T00:00:00Z</t>" },
2999 { 0, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>0001-01-01T00:00:00+00:00</t>" },
3000 { 0, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T00:00:00</t>" },
3001 { 1, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>0001-01-01T00:00:00.0000001Z</t>" },
3002 { 1, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>0001-01-01T00:00:00.0000001+00:00</t>" },
3003 { 1, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T00:00:00.0000001</t>" },
3004 { 10, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T00:00:00.000001</t>" },
3005 { 1000000, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T00:00:00.1</t>" },
3006 { 0x23c34600, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>0001-01-01T00:01:00+00:00</t>" },
3007 { 0x861c46800, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>0001-01-01T01:00:00+00:00</t>" },
3008 { 0x430e234000, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>0001-01-01T08:00:00+00:00</t>" },
3009 { 0x4b6fe7a800, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>0001-01-01T09:00:00+00:00</t>" },
3010 { 0x989680, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T00:00:01</t>" },
3011 { 0x23c34600, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T00:01:00</t>" },
3012 { 0x861c46800, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-01T01:00:00</t>" },
3013 { 0xc92a69c000, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0001-01-02T00:00:00</t>" },
3014 { 0x11ed178c6c000, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>0002-01-01T00:00:00</t>" },
3015 { 0x2bca2875f4373fff, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>9999-12-31T23:59:59.9999999Z</t>" },
3016 { 0x2bca2875f4373fff, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>9999-12-31T15:59:59.9999999-08:00</t>",
3017 "<t>9999-12-31T17:59:59.9999999-06:00</t>" /* win7 */, WS_E_INVALID_FORMAT
},
3018 { 0x2bca2875f4373fff, WS_DATETIME_FORMAT_NONE
, S_OK
, "<t>9999-12-31T23:59:59.9999999</t>" },
3019 { 0x2bca2875f4374000, WS_DATETIME_FORMAT_UTC
, WS_E_INVALID_FORMAT
},
3020 { 0x2bca2875f4374000, WS_DATETIME_FORMAT_LOCAL
, WS_E_INVALID_FORMAT
},
3021 { 0x2bca2875f4374000, WS_DATETIME_FORMAT_NONE
, WS_E_INVALID_FORMAT
},
3022 { 0x8d3123e7df74000, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>2015-12-31T16:00:00-08:00</t>",
3023 "<t>2015-12-31T18:00:00-06:00</t>" /* win7 */ },
3024 { 0x701ce1722770000, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>1601-01-01T00:00:00+00:00</t>" },
3025 { 0x701ce5a309a4000, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>1601-01-01T00:00:00-08:00</t>",
3026 "<t>1601-01-01T02:00:00-06:00</t>" /* win7 */ },
3027 { 0x701ce5e617c7400, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>1601-01-01T00:30:00-08:00</t>",
3028 "<t>1601-01-01T02:30:00-06:00</t>" /* win7 */ },
3029 { 0x701ce51ced5d800, WS_DATETIME_FORMAT_LOCAL
, S_OK
, "<t>1601-01-01T07:00:00+00:00</t>",
3030 "<t>1601-01-01T01:00:00-06:00</t>" /* win7 */ },
3031 { 0, WS_DATETIME_FORMAT_NONE
+ 1, WS_E_INVALID_FORMAT
},
3032 { 0x38a080649c000, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>0004-02-28T00:00:00Z</t>" },
3033 { 0x38ad130b38000, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>0004-02-29T00:00:00Z</t>" },
3034 { 0x8c1505f0e438000, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>2000-02-29T00:00:00Z</t>" },
3035 { 0x8d46035e7870000, WS_DATETIME_FORMAT_UTC
, S_OK
, "<t>2017-03-01T00:00:00Z</t>" },
3038 WS_XML_WRITER
*writer
;
3042 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3043 ok( hr
== S_OK
, "got %08x\n", hr
);
3044 for (i
= 0; i
< ARRAY_SIZE( tests
); i
++)
3046 hr
= set_output( writer
);
3047 ok( hr
== S_OK
, "got %08x\n", hr
);
3049 date
.ticks
= tests
[i
].ticks
;
3050 date
.format
= tests
[i
].format
;
3051 WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3052 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_DATETIME_TYPE
, NULL
, WS_WRITE_REQUIRED_VALUE
,
3053 &date
, sizeof(date
), NULL
);
3054 WsWriteEndElement( writer
, NULL
);
3055 ok( hr
== tests
[i
].hr
|| broken(hr
== tests
[i
].hr_broken
), "%u: got %08x\n", i
, hr
);
3056 if (hr
!= tests
[i
].hr
&& hr
== tests
[i
].hr_broken
) break;
3059 ok( check_result( writer
, tests
[i
].result
) ||
3060 (tests
[i
].result2
&& broken(check_result( writer
, tests
[i
].result2
))),
3061 "%u: wrong result\n", i
);
3065 WsFreeWriter( writer
);
3068 static void test_repeating_element(void)
3070 static const WCHAR oneW
[] = {'1',0}, twoW
[] = {'2',0};
3071 WS_XML_STRING localname
= {4, (BYTE
*)"test"}, ns
= {0, NULL
};
3072 WS_XML_STRING val
= {3, (BYTE
*)"val"}, wrapper
= {7, (BYTE
*)"wrapper"};
3074 WS_XML_WRITER
*writer
;
3075 WS_STRUCT_DESCRIPTION s
;
3076 WS_FIELD_DESCRIPTION f
, *fields
[1];
3077 WS_ITEM_RANGE range
;
3089 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3090 ok( hr
== S_OK
, "got %08x\n", hr
);
3092 /* array of strings, wrapper */
3093 hr
= set_output( writer
);
3094 ok( hr
== S_OK
, "got %08x\n", hr
);
3095 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3096 ok( hr
== S_OK
, "got %08x\n", hr
);
3098 memset( &f
, 0, sizeof(f
) );
3099 f
.mapping
= WS_REPEATING_ELEMENT_FIELD_MAPPING
;
3100 f
.localName
= &wrapper
;
3102 f
.type
= WS_WSZ_TYPE
;
3103 f
.countOffset
= FIELD_OFFSET(struct test
, count
);
3104 f
.itemLocalName
= &val
;
3108 memset( &s
, 0, sizeof(s
) );
3109 s
.size
= sizeof(struct test
);
3110 s
.alignment
= TYPE_ALIGNMENT(struct test
);
3111 s
.typeLocalName
= &localname
;
3116 hr
= set_output( writer
);
3117 ok( hr
== S_OK
, "got %08x\n", hr
);
3118 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3119 ok( hr
== S_OK
, "got %08x\n", hr
);
3121 test
= HeapAlloc( GetProcessHeap(), 0, sizeof(*test
) + 2 * sizeof(const WCHAR
*) );
3122 test
->val
= (const WCHAR
**)(test
+ 1);
3123 test
->val
[0] = oneW
;
3124 test
->val
[1] = twoW
;
3126 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
3127 WS_WRITE_REQUIRED_POINTER
, &test
, sizeof(test
), NULL
);
3128 ok( hr
== S_OK
, "got %08x\n", hr
);
3129 hr
= WsWriteEndElement( writer
, NULL
);
3130 ok( hr
== S_OK
, "got %08x\n", hr
);
3131 check_output( writer
, "<test><wrapper><val>1</val><val>2</val></wrapper></test>", __LINE__
);
3132 HeapFree( GetProcessHeap(), 0, test
);
3134 /* array of integers, no wrapper */
3135 hr
= set_output( writer
);
3136 ok( hr
== S_OK
, "got %08x\n", hr
);
3137 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3138 ok( hr
== S_OK
, "got %08x\n", hr
);
3140 f
.type
= WS_INT32_TYPE
;
3144 test2
= HeapAlloc( GetProcessHeap(), 0, sizeof(*test2
) + 2 * sizeof(INT32
) );
3145 test2
->val
= (INT32
*)(test2
+ 1);
3149 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
3150 WS_WRITE_REQUIRED_POINTER
, &test2
, sizeof(test2
), NULL
);
3151 ok( hr
== S_OK
, "got %08x\n", hr
);
3152 hr
= WsWriteEndElement( writer
, NULL
);
3153 ok( hr
== S_OK
, "got %08x\n", hr
);
3154 check_output( writer
, "<test><val>1</val><val>2</val></test>", __LINE__
);
3156 /* item range has no effect */
3157 hr
= set_output( writer
);
3158 ok( hr
== S_OK
, "got %08x\n", hr
);
3159 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3160 ok( hr
== S_OK
, "got %08x\n", hr
);
3162 range
.minItemCount
= 0;
3163 range
.maxItemCount
= 0;
3164 f
.itemRange
= &range
;
3166 hr
= WsWriteType( writer
, WS_ELEMENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
3167 WS_WRITE_REQUIRED_POINTER
, &test2
, sizeof(test2
), NULL
);
3168 ok( hr
== S_OK
, "got %08x\n", hr
);
3169 hr
= WsWriteEndElement( writer
, NULL
);
3170 ok( hr
== S_OK
, "got %08x\n", hr
);
3171 check_output( writer
, "<test><val>1</val><val>2</val></test>", __LINE__
);
3172 HeapFree( GetProcessHeap(), 0, test2
);
3174 WsFreeWriter( writer
);
3177 static const WS_XML_STRING
*init_xmlstring( const char *src
, WS_XML_STRING
*str
)
3179 if (!src
) return NULL
;
3180 str
->length
= strlen( src
);
3181 str
->bytes
= (BYTE
*)src
;
3182 str
->dictionary
= NULL
;
3187 static void test_WsWriteQualifiedName(void)
3189 WS_XML_STRING prefix
= {1, (BYTE
*)"p"}, localname
= {1, (BYTE
*)"t"}, ns
= {2, (BYTE
*)"ns"};
3190 WS_XML_WRITER
*writer
;
3196 const char *localname
;
3202 { NULL
, NULL
, NULL
, E_INVALIDARG
, NULL
},
3203 { NULL
, "t2", NULL
, E_INVALIDARG
, NULL
},
3204 { "p2", "t2", NULL
, S_OK
, "<p:t xmlns:p=\"ns\">p2:t2" },
3205 { NULL
, "t2", "ns2", WS_E_INVALID_FORMAT
, NULL
},
3206 { NULL
, "t2", "ns", S_OK
, "<p:t xmlns:p=\"ns\">p:t2" },
3207 { "p2", "t2", "ns2", S_OK
, "<p:t xmlns:p=\"ns\">p2:t2" },
3208 { "p2", "t2", "ns", S_OK
, "<p:t xmlns:p=\"ns\">p2:t2" },
3209 { "p", "t", NULL
, S_OK
, "<p:t xmlns:p=\"ns\">p:t" },
3210 { NULL
, "t", "ns", S_OK
, "<p:t xmlns:p=\"ns\">p:t" },
3211 { "p2", "", "", S_OK
, "<p:t xmlns:p=\"ns\">p2:" },
3212 { "p2", "", "ns2", S_OK
, "<p:t xmlns:p=\"ns\">p2:" },
3213 { "p2", "t2", "", S_OK
, "<p:t xmlns:p=\"ns\">p2:t2" },
3214 { "", "t2", "", S_OK
, "<p:t xmlns:p=\"ns\">t2" },
3215 { "", "", "ns2", S_OK
, "<p:t xmlns:p=\"ns\">" },
3216 { "", "", "", S_OK
, "<p:t xmlns:p=\"ns\">" },
3219 hr
= WsWriteQualifiedName( NULL
, NULL
, NULL
, NULL
, NULL
);
3220 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3222 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3223 ok( hr
== S_OK
, "got %08x\n", hr
);
3225 hr
= WsWriteQualifiedName( writer
, NULL
, NULL
, NULL
, NULL
);
3226 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3228 hr
= set_output( writer
);
3229 ok( hr
== S_OK
, "got %08x\n", hr
);
3231 hr
= WsWriteQualifiedName( writer
, NULL
, NULL
, NULL
, NULL
);
3232 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
3234 for (i
= 0; i
< ARRAY_SIZE( tests
); i
++)
3236 WS_XML_STRING prefix2
, localname2
, ns2
;
3237 const WS_XML_STRING
*prefix_ptr
, *localname_ptr
, *ns_ptr
;
3239 hr
= set_output( writer
);
3240 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3242 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
3243 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3245 prefix_ptr
= init_xmlstring( tests
[i
].prefix
, &prefix2
);
3246 localname_ptr
= init_xmlstring( tests
[i
].localname
, &localname2
);
3247 ns_ptr
= init_xmlstring( tests
[i
].ns
, &ns2
);
3249 hr
= WsWriteQualifiedName( writer
, prefix_ptr
, localname_ptr
, ns_ptr
, NULL
);
3250 ok( hr
== tests
[i
].hr
, "%u: got %08x\n", i
, hr
);
3251 if (tests
[i
].hr
== S_OK
&& hr
== S_OK
) check_output( writer
, tests
[i
].result
, __LINE__
);
3254 WsFreeWriter( writer
);
3257 static void test_WsWriteBytes(void)
3259 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {1, (BYTE
*)"a"}, ns
= {0, NULL
};
3260 WS_XML_WRITER
*writer
;
3263 hr
= WsWriteBytes( NULL
, NULL
, 0, NULL
);
3264 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3266 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3267 ok( hr
== S_OK
, "got %08x\n", hr
);
3269 hr
= WsWriteBytes( writer
, NULL
, 0, NULL
);
3270 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3272 hr
= WsWriteBytes( writer
, "test", 0, NULL
);
3273 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3275 hr
= WsWriteBytes( writer
, NULL
, 1, NULL
);
3276 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3278 hr
= WsWriteBytes( writer
, "test", sizeof("test"), NULL
);
3279 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3281 hr
= set_output( writer
);
3282 ok( hr
== S_OK
, "got %08x\n", hr
);
3284 hr
= WsWriteBytes( writer
, "test", sizeof("test"), NULL
);
3285 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
3287 hr
= set_output( writer
);
3288 ok( hr
== S_OK
, "got %08x\n", hr
);
3291 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3292 ok( hr
== S_OK
, "got %08x\n", hr
);
3294 hr
= WsWriteBytes( writer
, "test", sizeof("test"), NULL
);
3295 ok( hr
== S_OK
, "got %08x\n", hr
);
3297 hr
= WsWriteEndElement( writer
, NULL
);
3298 ok( hr
== S_OK
, "got %08x\n", hr
);
3299 check_output( writer
, "<t>dGVzdAA=</t>", __LINE__
);
3301 hr
= set_output( writer
);
3302 ok( hr
== S_OK
, "got %08x\n", hr
);
3305 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3306 ok( hr
== S_OK
, "got %08x\n", hr
);
3308 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
3309 ok( hr
== S_OK
, "got %08x\n", hr
);
3311 hr
= WsWriteBytes( writer
, "test", sizeof("test"), NULL
);
3312 ok( hr
== S_OK
, "got %08x\n", hr
);
3314 hr
= WsWriteEndAttribute( writer
, NULL
);
3315 ok( hr
== S_OK
, "got %08x\n", hr
);
3317 hr
= WsWriteEndElement( writer
, NULL
);
3318 ok( hr
== S_OK
, "got %08x\n", hr
);
3319 check_output( writer
, "<t a=\"dGVzdAA=\"/>", __LINE__
);
3321 WsFreeWriter( writer
);
3324 static void test_WsWriteChars(void)
3326 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {1, (BYTE
*)"a"}, ns
= {0, NULL
};
3327 static const WCHAR testW
[] = {'t','e','s','t'};
3328 WS_XML_WRITER
*writer
;
3331 hr
= WsWriteChars( NULL
, NULL
, 0, NULL
);
3332 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3334 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3335 ok( hr
== S_OK
, "got %08x\n", hr
);
3337 hr
= WsWriteChars( writer
, NULL
, 0, NULL
);
3338 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3340 hr
= WsWriteChars( writer
, testW
, 0, NULL
);
3341 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3343 hr
= WsWriteChars( writer
, NULL
, 1, NULL
);
3344 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3346 hr
= WsWriteChars( writer
, testW
, 4, NULL
);
3347 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3349 hr
= set_output( writer
);
3350 ok( hr
== S_OK
, "got %08x\n", hr
);
3352 hr
= WsWriteChars( writer
, testW
, 4, NULL
);
3353 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
3355 hr
= set_output( writer
);
3356 ok( hr
== S_OK
, "got %08x\n", hr
);
3359 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3360 ok( hr
== S_OK
, "got %08x\n", hr
);
3362 hr
= WsWriteChars( writer
, testW
, 4, NULL
);
3363 ok( hr
== S_OK
, "got %08x\n", hr
);
3365 hr
= WsWriteChars( writer
, testW
, 4, NULL
);
3366 ok( hr
== S_OK
, "got %08x\n", hr
);
3368 hr
= WsWriteEndElement( writer
, NULL
);
3369 ok( hr
== S_OK
, "got %08x\n", hr
);
3370 check_output( writer
, "<t>testtest</t>", __LINE__
);
3372 hr
= set_output( writer
);
3373 ok( hr
== S_OK
, "got %08x\n", hr
);
3376 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3377 ok( hr
== S_OK
, "got %08x\n", hr
);
3379 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
3380 ok( hr
== S_OK
, "got %08x\n", hr
);
3382 hr
= WsWriteChars( writer
, testW
, 4, NULL
);
3383 ok( hr
== S_OK
, "got %08x\n", hr
);
3385 hr
= WsWriteChars( writer
, testW
, 4, NULL
);
3386 ok( hr
== S_OK
, "got %08x\n", hr
);
3388 hr
= WsWriteEndAttribute( writer
, NULL
);
3389 ok( hr
== S_OK
, "got %08x\n", hr
);
3391 hr
= WsWriteEndElement( writer
, NULL
);
3392 ok( hr
== S_OK
, "got %08x\n", hr
);
3393 check_output( writer
, "<t a=\"testtest\"/>", __LINE__
);
3395 WsFreeWriter( writer
);
3398 static void test_WsWriteCharsUtf8(void)
3400 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {1, (BYTE
*)"a"}, ns
= {0, NULL
};
3401 static const BYTE test
[] = {'t','e','s','t'};
3402 WS_XML_WRITER
*writer
;
3405 hr
= WsWriteCharsUtf8( NULL
, NULL
, 0, NULL
);
3406 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3408 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3409 ok( hr
== S_OK
, "got %08x\n", hr
);
3411 hr
= WsWriteCharsUtf8( writer
, NULL
, 0, NULL
);
3412 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3414 hr
= WsWriteCharsUtf8( writer
, test
, 0, NULL
);
3415 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3417 hr
= WsWriteCharsUtf8( writer
, NULL
, 1, NULL
);
3418 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3420 hr
= WsWriteCharsUtf8( writer
, test
, sizeof(test
), NULL
);
3421 ok( hr
== WS_E_INVALID_OPERATION
, "got %08x\n", hr
);
3423 hr
= set_output( writer
);
3424 ok( hr
== S_OK
, "got %08x\n", hr
);
3426 hr
= WsWriteCharsUtf8( writer
, test
, sizeof(test
), NULL
);
3427 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
3429 hr
= set_output( writer
);
3430 ok( hr
== S_OK
, "got %08x\n", hr
);
3433 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3434 ok( hr
== S_OK
, "got %08x\n", hr
);
3436 hr
= WsWriteCharsUtf8( writer
, test
, sizeof(test
), NULL
);
3437 ok( hr
== S_OK
, "got %08x\n", hr
);
3439 hr
= WsWriteCharsUtf8( writer
, test
, sizeof(test
), NULL
);
3440 ok( hr
== S_OK
, "got %08x\n", hr
);
3442 hr
= WsWriteEndElement( writer
, NULL
);
3443 ok( hr
== S_OK
, "got %08x\n", hr
);
3444 check_output( writer
, "<t>testtest</t>", __LINE__
);
3446 hr
= set_output( writer
);
3447 ok( hr
== S_OK
, "got %08x\n", hr
);
3450 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3451 ok( hr
== S_OK
, "got %08x\n", hr
);
3453 hr
= WsWriteStartAttribute( writer
, NULL
, &localname2
, &ns
, FALSE
, NULL
);
3454 ok( hr
== S_OK
, "got %08x\n", hr
);
3456 hr
= WsWriteCharsUtf8( writer
, test
, sizeof(test
), NULL
);
3457 ok( hr
== S_OK
, "got %08x\n", hr
);
3459 hr
= WsWriteCharsUtf8( writer
, test
, sizeof(test
), NULL
);
3460 ok( hr
== S_OK
, "got %08x\n", hr
);
3462 hr
= WsWriteEndAttribute( writer
, NULL
);
3463 ok( hr
== S_OK
, "got %08x\n", hr
);
3465 hr
= WsWriteEndElement( writer
, NULL
);
3466 ok( hr
== S_OK
, "got %08x\n", hr
);
3467 check_output( writer
, "<t a=\"testtest\"/>", __LINE__
);
3469 WsFreeWriter( writer
);
3472 static void check_output_bin( WS_XML_WRITER
*writer
, const char *expected
, int len
, unsigned int line
)
3475 ULONG size
= sizeof(bytes
);
3478 memset( &bytes
, 0, sizeof(bytes
) );
3479 hr
= WsGetWriterProperty( writer
, WS_XML_WRITER_PROPERTY_BYTES
, &bytes
, size
, NULL
);
3480 ok( hr
== S_OK
, "%u: got %08x\n", line
, hr
);
3481 ok( bytes
.length
== len
, "%u: got %u expected %u\n", line
, bytes
.length
, len
);
3482 if (bytes
.length
!= len
) return;
3483 ok( !memcmp( bytes
.bytes
, expected
, bytes
.length
), "%u: got %s expected %s\n", line
,
3484 debugstr_bytes(bytes
.bytes
, bytes
.length
), debugstr_bytes((const BYTE
*)expected
, len
) );
3487 static void test_binary_encoding(void)
3489 static const char res
[] =
3490 {0x40,0x01,'t',0x01};
3491 static const char res2
[] =
3492 {0x6d,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01};
3493 static const char res3
[] =
3494 {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x01};
3495 static const char res4
[] =
3496 {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x99,0x04,'t','e','s','t'};
3497 static const char res100
[] =
3498 {0x40,0x01,'t',0x04,0x01,'t',0x98,0x00,0x01};
3499 static const char res101
[] =
3500 {0x40,0x01,'t',0x35,0x01,'t',0x98,0x00,0x09,0x01,'p',0x02,'n','s',0x01};
3501 static const char res102
[] =
3502 {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x00,0x09,0x02,'p','2',0x02,'n','s',0x01};
3503 static const char res103
[] =
3504 {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x04,'t','e','s','t',0x09,0x02,'p','2',0x02,'n','s',0x01};
3505 static const char res200
[] =
3506 {0x02,0x07,'c','o','m','m','e','n','t'};
3507 WS_XML_WRITER_BINARY_ENCODING bin
= {{WS_XML_WRITER_ENCODING_TYPE_BINARY
}};
3508 WS_XML_WRITER_BUFFER_OUTPUT buf
= {{WS_XML_WRITER_OUTPUT_TYPE_BUFFER
}};
3509 static const char prefix
[] = "p", prefix2
[] = "p2";
3510 static const char localname
[] = "t", ns
[] = "ns";
3511 const WS_XML_STRING
*prefix_ptr
, *localname_ptr
, *ns_ptr
;
3512 WS_XML_STRING str
, str2
, str3
, localname2
= {1, (BYTE
*)"t"}, empty
= {0, NULL
};
3513 WS_XML_UTF8_TEXT utf8
= {{WS_XML_TEXT_TYPE_UTF8
}};
3514 WS_XML_COMMENT_NODE comment
= {{WS_XML_NODE_TYPE_COMMENT
}};
3515 WS_XML_WRITER
*writer
;
3521 const char *localname
;
3529 { NULL
, localname
, "", NULL
, res
, sizeof(res
) }, /* short element */
3530 { prefix
, localname
, ns
, NULL
, res2
, sizeof(res2
) }, /* one character prefix element */
3531 { prefix2
, localname
, ns
, NULL
, res3
, sizeof(res3
) }, /* element */
3532 { prefix2
, localname
, ns
, "test", res4
, sizeof(res4
) }, /* element with text */
3537 const char *localname
;
3545 { NULL
, localname
, "", NULL
, res100
, sizeof(res100
) }, /* short attribute */
3546 { prefix
, localname
, ns
, NULL
, res101
, sizeof(res101
) }, /* one character prefix attribute */
3547 { prefix2
, localname
, ns
, NULL
, res102
, sizeof(res102
) }, /* attribute */
3548 { prefix2
, localname
, ns
, "test", res103
, sizeof(res103
) }, /* attribute with value */
3551 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3552 ok( hr
== S_OK
, "got %08x\n", hr
);
3554 for (i
= 0; i
< ARRAY_SIZE( elem_tests
); i
++)
3556 hr
= WsSetOutput( writer
, &bin
.encoding
, &buf
.output
, NULL
, 0, NULL
);
3557 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3559 prefix_ptr
= init_xmlstring( elem_tests
[i
].prefix
, &str
);
3560 localname_ptr
= init_xmlstring( elem_tests
[i
].localname
, &str2
);
3561 ns_ptr
= init_xmlstring( elem_tests
[i
].ns
, &str3
);
3563 hr
= WsWriteStartElement( writer
, prefix_ptr
, localname_ptr
, ns_ptr
, NULL
);
3564 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3565 if (elem_tests
[i
].text
)
3567 utf8
.value
.length
= strlen( elem_tests
[i
].text
);
3568 utf8
.value
.bytes
= (BYTE
*)elem_tests
[i
].text
;
3569 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
3570 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3572 hr
= WsWriteEndElement( writer
, NULL
);
3573 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3574 if (hr
== S_OK
) check_output_bin( writer
, elem_tests
[i
].result
, elem_tests
[i
].len_result
, __LINE__
);
3577 for (i
= 0; i
< ARRAY_SIZE( attr_tests
); i
++)
3579 hr
= WsSetOutput( writer
, &bin
.encoding
, &buf
.output
, NULL
, 0, NULL
);
3580 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3582 prefix_ptr
= init_xmlstring( attr_tests
[i
].prefix
, &str
);
3583 localname_ptr
= init_xmlstring( attr_tests
[i
].localname
, &str2
);
3584 ns_ptr
= init_xmlstring( elem_tests
[i
].ns
, &str3
);
3586 hr
= WsWriteStartElement( writer
, NULL
, &localname2
, &empty
, NULL
);
3587 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3588 hr
= WsWriteStartAttribute( writer
, prefix_ptr
, localname_ptr
, ns_ptr
, FALSE
, NULL
);
3589 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3590 if (attr_tests
[i
].value
)
3592 utf8
.value
.length
= strlen( attr_tests
[i
].value
);
3593 utf8
.value
.bytes
= (BYTE
*)attr_tests
[i
].value
;
3594 hr
= WsWriteText( writer
, &utf8
.text
, NULL
);
3595 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3597 hr
= WsWriteEndAttribute( writer
, NULL
);
3598 ok( hr
== S_OK
, "got %08x\n", hr
);
3599 hr
= WsWriteEndElement( writer
, NULL
);
3600 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3601 if (hr
== S_OK
) check_output_bin( writer
, attr_tests
[i
].result
, attr_tests
[i
].len_result
, __LINE__
);
3604 hr
= WsSetOutput( writer
, &bin
.encoding
, &buf
.output
, NULL
, 0, NULL
);
3605 ok( hr
== S_OK
, "got %08x\n", hr
);
3607 comment
.value
.bytes
= (BYTE
*)"comment";
3608 comment
.value
.length
= sizeof("comment") - 1;
3609 hr
= WsWriteNode( writer
, &comment
.node
, NULL
);
3610 ok( hr
== S_OK
, "got %08x\n", hr
);
3611 if (hr
== S_OK
) check_output_bin( writer
, res200
, sizeof(res200
), __LINE__
);
3613 WsFreeWriter( writer
);
3616 static void test_namespaces(void)
3618 WS_XML_STRING prefix
= {1, (BYTE
*)"p"}, prefix2
= {1, (BYTE
*)"q"};
3619 WS_XML_STRING localname
= {1, (BYTE
*)"t"}, localname2
= {1, (BYTE
*)"a"};
3620 WS_XML_STRING ns
= {1, (BYTE
*)"n"}, ns2
= {1, (BYTE
*)"o"};
3621 WS_XML_WRITER
*writer
;
3624 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3625 ok( hr
== S_OK
, "got %08x\n", hr
);
3627 hr
= set_output( writer
);
3628 ok( hr
== S_OK
, "got %08x\n", hr
);
3629 hr
= WsWriteStartElement( writer
, &prefix
, &localname
, &ns
, NULL
);
3630 ok( hr
== S_OK
, "got %08x\n", hr
);
3631 hr
= WsWriteStartAttribute( writer
, &prefix2
, &localname2
, &ns2
, FALSE
, NULL
);
3632 ok( hr
== S_OK
, "got %08x\n", hr
);
3633 hr
= WsWriteEndAttribute( writer
, NULL
);
3634 ok( hr
== S_OK
, "got %08x\n", hr
);
3635 hr
= WsWriteEndElement( writer
, NULL
);
3636 ok( hr
== S_OK
, "got %08x\n", hr
);
3637 check_output( writer
, "<p:t q:a=\"\" xmlns:p=\"n\" xmlns:q=\"o\"/>", __LINE__
);
3639 WsFreeWriter( writer
);
3642 static const WS_XML_STRING
*init_xmlstring_dict( WS_XML_DICTIONARY
*dict
, ULONG id
, WS_XML_STRING
*str
)
3644 if (id
>= dict
->stringCount
) return NULL
;
3645 str
->length
= dict
->strings
[id
].length
;
3646 str
->bytes
= dict
->strings
[id
].bytes
;
3647 str
->dictionary
= dict
;
3652 static HRESULT CALLBACK
dict_cb( void *state
, const WS_XML_STRING
*str
, BOOL
*found
, ULONG
*id
, WS_ERROR
*error
)
3654 ULONG
*call_count
= state
;
3657 switch (str
->bytes
[0])
3685 static void test_dictionary(void)
3687 static const char res
[] =
3689 static const char res2
[] =
3691 static const char res3
[] =
3692 {0x53,0x06,0x0b,0x01,'p',0x0a,0x01};
3693 static const char res4
[] =
3694 {0x43,0x02,'p','2',0x06,0x0b,0x02,'p','2',0x0a,0x01};
3695 static const char res5
[] =
3696 {0x42,0x03,0x0a,0x05,0x01};
3697 static const char res6
[] =
3698 {0x40,0x01,0x75,0x0a,0x05,0x01};
3699 static const char res7
[] =
3700 {0x40,0x01,0x76,0x0a,0x05,0x01};
3701 static const char res8
[] =
3702 {0x42,0x03,0x0a,0x05,0x01};
3703 static const char res9
[] =
3704 {0x42,0x07,0x0a,0x05,0x01};
3705 static const char res10
[] =
3706 {0x42,0xd6,0x03,0x0a,0x05,0x01};
3707 static const char res100
[] =
3708 {0x42,0x06,0x06,0x06,0x98,0x00,0x01};
3709 static const char res101
[] =
3710 {0x42,0x06,0x1b,0x06,0x98,0x00,0x0b,0x01,'p',0x0a,0x01};
3711 static const char res102
[] =
3712 {0x42,0x06,0x07,0x02,'p','2',0x06,0x98,0x00,0x0b,0x02,'p','2',0x0a,0x01};
3713 WS_XML_WRITER_BINARY_ENCODING bin
= {{WS_XML_WRITER_ENCODING_TYPE_BINARY
}};
3714 WS_XML_WRITER_BUFFER_OUTPUT buf
= {{WS_XML_WRITER_OUTPUT_TYPE_BUFFER
}};
3715 WS_XML_STRING prefix
, localname
, ns
, strings
[6];
3716 const WS_XML_STRING
*prefix_ptr
, *localname_ptr
, *ns_ptr
;
3717 WS_XML_DICTIONARY dict
, *dict_builtin
;
3718 WS_XML_WRITER
*writer
;
3720 ULONG i
, call_count
;
3731 { ~0u, 2, 0, res
, sizeof(res
) }, /* short dictionary element, invalid dict id */
3732 { ~0u, 3, 0, res2
, sizeof(res2
) }, /* short dictionary element */
3733 { 1, 3, 5, res3
, sizeof(res3
) }, /* single character prefix dictionary element */
3734 { 4, 3, 5, res4
, sizeof(res4
) }, /* dictionary element */
3746 { ~0u, 3, 0, res100
, sizeof(res100
) }, /* short dictionary attribute */
3747 { 1, 3, 5, res101
, sizeof(res101
) }, /* single character prefix dictionary attribute */
3748 { 4, 3, 5, res102
, sizeof(res102
) }, /* dictionary attribute */
3751 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3752 ok( hr
== S_OK
, "got %08x\n", hr
);
3754 strings
[0].length
= 0;
3755 strings
[0].bytes
= NULL
;
3756 strings
[0].dictionary
= &dict
;
3758 strings
[1].length
= 1;
3759 strings
[1].bytes
= (BYTE
*)"p";
3760 strings
[1].dictionary
= &dict
;
3762 strings
[2].length
= 1;
3763 strings
[2].bytes
= (BYTE
*)"t";
3764 strings
[2].dictionary
= &dict
;
3765 strings
[2].id
= ~0u;
3766 strings
[3].length
= 1;
3767 strings
[3].bytes
= (BYTE
*)"u";
3768 strings
[3].dictionary
= &dict
;
3770 strings
[4].length
= 2;
3771 strings
[4].bytes
= (BYTE
*)"p2";
3772 strings
[4].dictionary
= &dict
;
3774 strings
[5].length
= 2;
3775 strings
[5].bytes
= (BYTE
*)"ns";
3776 strings
[5].dictionary
= &dict
;
3779 UuidCreate( &dict
.guid
);
3780 dict
.strings
= strings
;
3781 dict
.stringCount
= ARRAY_SIZE( strings
);
3782 dict
.isConst
= TRUE
;
3784 bin
.staticDictionary
= &dict
;
3786 for (i
= 0; i
< ARRAY_SIZE( elem_tests
); i
++)
3788 hr
= WsSetOutput( writer
, &bin
.encoding
, &buf
.output
, NULL
, 0, NULL
);
3789 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3791 prefix_ptr
= init_xmlstring_dict( &dict
, elem_tests
[i
].prefix
, &prefix
);
3792 localname_ptr
= init_xmlstring_dict( &dict
, elem_tests
[i
].localname
, &localname
);
3793 ns_ptr
= init_xmlstring_dict( &dict
, elem_tests
[i
].ns
, &ns
);
3795 hr
= WsWriteStartElement( writer
, prefix_ptr
, localname_ptr
, ns_ptr
, NULL
);
3796 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3797 hr
= WsWriteEndElement( writer
, NULL
);
3798 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3799 if (hr
== S_OK
) check_output_bin( writer
, elem_tests
[i
].result
, elem_tests
[i
].len_result
, __LINE__
);
3802 for (i
= 0; i
< ARRAY_SIZE( attr_tests
); i
++)
3804 hr
= WsSetOutput( writer
, &bin
.encoding
, &buf
.output
, NULL
, 0, NULL
);
3805 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3807 prefix_ptr
= init_xmlstring_dict( &dict
, attr_tests
[i
].prefix
, &prefix
);
3808 localname_ptr
= init_xmlstring_dict( &dict
, attr_tests
[i
].localname
, &localname
);
3809 ns_ptr
= init_xmlstring_dict( &dict
, attr_tests
[i
].ns
, &ns
);
3811 hr
= WsWriteStartElement( writer
, NULL
, &strings
[3], &strings
[0], NULL
);
3812 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3813 hr
= WsWriteStartAttribute( writer
, prefix_ptr
, localname_ptr
, ns_ptr
, FALSE
, NULL
);
3814 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3815 hr
= WsWriteEndAttribute( writer
, NULL
);
3816 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3817 hr
= WsWriteEndElement( writer
, NULL
);
3818 ok( hr
== S_OK
, "%u: got %08x\n", i
, hr
);
3819 if (hr
== S_OK
) check_output_bin( writer
, attr_tests
[i
].result
, attr_tests
[i
].len_result
, __LINE__
);
3823 bin
.staticDictionary
= NULL
;
3824 bin
.dynamicStringCallback
= dict_cb
;
3825 bin
.dynamicStringCallbackState
= &call_count
;
3827 hr
= WsSetOutput( writer
, &bin
.encoding
, &buf
.output
, NULL
, 0, NULL
);
3828 ok( hr
== S_OK
, "got %08x\n", hr
);
3829 init_xmlstring( "t", &localname
);
3830 init_xmlstring( "ns", &ns
);
3832 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3833 ok( hr
== S_OK
, "got %08x\n", hr
);
3834 hr
= WsWriteEndElement( writer
, NULL
);
3835 ok( hr
== S_OK
, "got %08x\n", hr
);
3836 ok( call_count
== 2, "got %u\n", call_count
);
3837 check_output_bin( writer
, res5
, sizeof(res5
), __LINE__
);
3839 /* unknown string */
3840 hr
= WsSetOutput( writer
, &bin
.encoding
, &buf
.output
, NULL
, 0, NULL
);
3841 ok( hr
== S_OK
, "got %08x\n", hr
);
3842 init_xmlstring( "u", &localname
);
3843 init_xmlstring( "ns", &ns
);
3845 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3846 ok( hr
== S_OK
, "got %08x\n", hr
);
3847 hr
= WsWriteEndElement( writer
, NULL
);
3848 ok( hr
== S_OK
, "got %08x\n", hr
);
3849 ok( call_count
== 2, "got %u\n", call_count
);
3850 check_output_bin( writer
, res6
, sizeof(res6
), __LINE__
);
3852 /* unknown string, error return from callback */
3853 hr
= WsSetOutput( writer
, &bin
.encoding
, &buf
.output
, NULL
, 0, NULL
);
3854 ok( hr
== S_OK
, "got %08x\n", hr
);
3855 init_xmlstring( "v", &localname
);
3856 init_xmlstring( "ns", &ns
);
3858 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3859 ok( hr
== S_OK
, "got %08x\n", hr
);
3860 hr
= WsWriteEndElement( writer
, NULL
);
3861 ok( hr
== S_OK
, "got %08x\n", hr
);
3862 ok( call_count
== 2, "got %u\n", call_count
);
3863 check_output_bin( writer
, res7
, sizeof(res7
), __LINE__
);
3865 /* dictionary and callback */
3866 hr
= WsGetDictionary( WS_ENCODING_XML_BINARY_1
, &dict_builtin
, NULL
);
3867 ok( hr
== S_OK
, "got %08x\n", hr
);
3868 bin
.staticDictionary
= dict_builtin
;
3870 /* string in dictionary, no string dictionary set */
3871 hr
= WsSetOutput( writer
, &bin
.encoding
, &buf
.output
, NULL
, 0, NULL
);
3872 ok( hr
== S_OK
, "got %08x\n", hr
);
3873 init_xmlstring( "t", &localname
);
3874 init_xmlstring( "ns", &ns
);
3876 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3877 ok( hr
== S_OK
, "got %08x\n", hr
);
3878 hr
= WsWriteEndElement( writer
, NULL
);
3879 ok( hr
== S_OK
, "got %08x\n", hr
);
3880 ok( call_count
== 2, "got %u\n", call_count
);
3881 check_output_bin( writer
, res8
, sizeof(res8
), __LINE__
);
3883 /* string not in dictionary, no string dictionary set */
3884 hr
= WsSetOutput( writer
, &bin
.encoding
, &buf
.output
, NULL
, 0, NULL
);
3885 ok( hr
== S_OK
, "got %08x\n", hr
);
3886 init_xmlstring( "z", &localname
);
3887 init_xmlstring( "ns", &ns
);
3889 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3890 ok( hr
== S_OK
, "got %08x\n", hr
);
3891 hr
= WsWriteEndElement( writer
, NULL
);
3892 ok( hr
== S_OK
, "got %08x\n", hr
);
3893 ok( call_count
== 2, "got %u\n", call_count
);
3894 check_output_bin( writer
, res9
, sizeof(res9
), __LINE__
);
3896 /* string in dictionary, string dictionary set */
3897 hr
= WsSetOutput( writer
, &bin
.encoding
, &buf
.output
, NULL
, 0, NULL
);
3898 ok( hr
== S_OK
, "got %08x\n", hr
);
3899 init_xmlstring_dict( dict_builtin
, 235, &localname
);
3900 init_xmlstring( "ns", &ns
);
3902 hr
= WsWriteStartElement( writer
, NULL
, &localname
, &ns
, NULL
);
3903 ok( hr
== S_OK
, "got %08x\n", hr
);
3904 hr
= WsWriteEndElement( writer
, NULL
);
3905 ok( hr
== S_OK
, "got %08x\n", hr
);
3906 ok( call_count
== 1, "got %u\n", call_count
);
3907 check_output_bin( writer
, res10
, sizeof(res10
), __LINE__
);
3909 WsFreeWriter( writer
);
3912 static void test_union_type(void)
3914 static const WCHAR testW
[] = {'t','e','s','t',0};
3915 static WS_XML_STRING str_ns
= {0, NULL
}, str_a
= {1, (BYTE
*)"a"}, str_b
= {1, (BYTE
*)"b"};
3916 static WS_XML_STRING str_s
= {1, (BYTE
*)"s"}, str_t
= {1, (BYTE
*)"t"};
3918 WS_XML_WRITER
*writer
;
3919 WS_UNION_DESCRIPTION u
;
3920 WS_UNION_FIELD_DESCRIPTION f
, f2
, *fields
[2];
3921 WS_FIELD_DESCRIPTION f_struct
, *fields_struct
[1];
3922 WS_STRUCT_DESCRIPTION s
;
3923 enum choice
{CHOICE_A
, CHOICE_B
, CHOICE_NONE
};
3934 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
3935 ok( hr
== S_OK
, "got %08x\n", hr
);
3937 memset( &f
, 0, sizeof(f
) );
3939 f
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
3940 f
.field
.localName
= &str_a
;
3941 f
.field
.ns
= &str_ns
;
3942 f
.field
.type
= WS_WSZ_TYPE
;
3943 f
.field
.offset
= FIELD_OFFSET(struct test
, value
.a
);
3946 memset( &f2
, 0, sizeof(f2
) );
3947 f2
.value
= CHOICE_B
;
3948 f2
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
3949 f2
.field
.localName
= &str_b
;
3950 f2
.field
.ns
= &str_ns
;
3951 f2
.field
.type
= WS_UINT32_TYPE
;
3952 f2
.field
.offset
= FIELD_OFFSET(struct test
, value
.b
);
3955 memset( &u
, 0, sizeof(u
) );
3956 u
.size
= sizeof(struct test
);
3957 u
.alignment
= TYPE_ALIGNMENT(struct test
);
3960 u
.enumOffset
= FIELD_OFFSET(struct test
, choice
);
3961 u
.noneEnumValue
= CHOICE_NONE
;
3963 memset( &f_struct
, 0, sizeof(f_struct
) );
3964 f_struct
.mapping
= WS_ELEMENT_CHOICE_FIELD_MAPPING
;
3965 f_struct
.type
= WS_UNION_TYPE
;
3966 f_struct
.typeDescription
= &u
;
3967 fields_struct
[0] = &f_struct
;
3969 memset( &s
, 0, sizeof(s
) );
3970 s
.size
= sizeof(struct test
);
3971 s
.alignment
= TYPE_ALIGNMENT(struct test
);
3972 s
.fields
= fields_struct
;
3974 s
.typeLocalName
= &str_s
;
3977 hr
= set_output( writer
);
3978 ok( hr
== S_OK
, "got %08x\n", hr
);
3979 hr
= WsWriteStartElement( writer
, NULL
, &str_t
, &str_ns
, NULL
);
3980 ok( hr
== S_OK
, "got %08x\n", hr
);
3981 test
.choice
= CHOICE_A
;
3982 test
.value
.a
= testW
;
3983 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
3984 WS_WRITE_REQUIRED_VALUE
, &test
, sizeof(test
), NULL
);
3985 ok( hr
== S_OK
, "got %08x\n", hr
);
3986 hr
= WsWriteEndElement( writer
, NULL
);
3987 ok( hr
== S_OK
, "got %08x\n", hr
);
3988 check_output( writer
, "<t><a>test</a></t>", __LINE__
);
3990 hr
= set_output( writer
);
3991 ok( hr
== S_OK
, "got %08x\n", hr
);
3992 hr
= WsWriteStartElement( writer
, NULL
, &str_t
, &str_ns
, NULL
);
3993 ok( hr
== S_OK
, "got %08x\n", hr
);
3994 test
.choice
= CHOICE_B
;
3996 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
3997 WS_WRITE_REQUIRED_VALUE
, &test
, sizeof(test
), NULL
);
3998 ok( hr
== S_OK
, "got %08x\n", hr
);
3999 hr
= WsWriteEndElement( writer
, NULL
);
4000 ok( hr
== S_OK
, "got %08x\n", hr
);
4001 check_output( writer
, "<t><b>123</b></t>", __LINE__
);
4003 hr
= set_output( writer
);
4004 ok( hr
== S_OK
, "got %08x\n", hr
);
4005 hr
= WsWriteStartElement( writer
, NULL
, &str_t
, &str_ns
, NULL
);
4006 ok( hr
== S_OK
, "got %08x\n", hr
);
4007 test
.choice
= CHOICE_NONE
;
4008 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
4009 WS_WRITE_REQUIRED_VALUE
, &test
, sizeof(test
), NULL
);
4010 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
4012 hr
= set_output( writer
);
4013 ok( hr
== S_OK
, "got %08x\n", hr
);
4014 hr
= WsWriteStartElement( writer
, NULL
, &str_t
, &str_ns
, NULL
);
4015 ok( hr
== S_OK
, "got %08x\n", hr
);
4016 test
.choice
= CHOICE_NONE
;
4017 f_struct
.options
= WS_FIELD_OPTIONAL
;
4018 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
4019 WS_WRITE_REQUIRED_VALUE
, &test
, sizeof(test
), NULL
);
4020 ok( hr
== S_OK
, "got %08x\n", hr
);
4021 hr
= WsWriteEndElement( writer
, NULL
);
4022 ok( hr
== S_OK
, "got %08x\n", hr
);
4023 check_output( writer
, "<t/>", __LINE__
);
4025 WsFreeWriter( writer
);
4028 static void prepare_binary_type_test( WS_XML_WRITER
*writer
, const WS_XML_STRING
*prefix
,
4029 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
)
4031 WS_XML_WRITER_BINARY_ENCODING bin
= {{WS_XML_WRITER_ENCODING_TYPE_BINARY
}};
4032 WS_XML_WRITER_BUFFER_OUTPUT buf
= {{WS_XML_WRITER_OUTPUT_TYPE_BUFFER
}};
4035 hr
= WsSetOutput( writer
, &bin
.encoding
, &buf
.output
, NULL
, 0, NULL
);
4036 ok( hr
== S_OK
, "got %08x\n", hr
);
4037 hr
= WsWriteStartElement( writer
, prefix
, localname
, ns
, NULL
);
4038 ok( hr
== S_OK
, "got %08x\n", hr
);
4041 static void test_text_types_binary(void)
4043 static WCHAR testW
[] = {'t','e','s','t'};
4044 static WS_XML_STRING str_s
= {1, (BYTE
*)"s"}, str_t
= {1, (BYTE
*)"t"}, str_u
= {1, (BYTE
*)"u"};
4045 static WS_XML_STRING str_ns
= {0, NULL
};
4046 static const char res
[] =
4047 {0x40,0x01,'t',0x40,0x01,'u',0x99,0x04,'t','e','s','t',0x01};
4048 static const char res2
[] =
4049 {0x40,0x01,'t',0x40,0x01,'u',0x9e,0x03,'t','e','s',0x9f,0x01,'t',0x01};
4050 static const char res2a
[] =
4051 {0x40,0x01,'t',0x40,0x01,'u',0x9f,0x03,'t','e','s',0x01};
4052 static const char res2b
[] =
4053 {0x40,0x01,'t',0x40,0x01,'u',0x9f,0x01,'t',0x01};
4054 static const char res2c
[] =
4055 {0x40,0x01,'t',0x40,0x01,'u',0x01,0x01};
4056 static const char res2d
[] =
4057 {0x40,0x01,'t',0x40,0x01,'u',0x9f,0xff,'a','a','a','a','a','a','a','a','a','a',
4058 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4059 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4060 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4061 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4062 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4063 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4064 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4065 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4066 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4067 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4068 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4069 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4070 'a','a','a','a','a',0x01};
4071 static const char res2e
[] =
4072 {0x40,0x01,'t',0x40,0x01,'u',0x9e,0xff,'a','a','a','a','a','a','a','a','a','a',
4073 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4074 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4075 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4076 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4077 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4078 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4079 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4080 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4081 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4082 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4083 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4084 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4085 'a','a','a','a','a',0x9f,0x01,'a',0x01};
4086 static const char res2f
[] =
4087 {0x40,0x01,'t',0x40,0x01,'u',0x9f,0x06,'t','e','s','t','t','e',0x01};
4088 static const char res3
[] =
4089 {0x40,0x01,'t',0x40,0x01,'u',0x87,0x01};
4090 static const char res4
[] =
4091 {0x40,0x01,'t',0x40,0x01,'u',0x89,0xff,0x01};
4092 static const char res5
[] =
4093 {0x40,0x01,'t',0x40,0x01,'u',0x83,0x01};
4094 static const char res5b
[] =
4095 {0x40,0x01,'t',0x40,0x01,'u',0x89,0x02,0x01};
4096 static const char res6
[] =
4097 {0x40,0x01,'t',0x40,0x01,'u',0x81,0x01};
4098 static const char res7
[] =
4099 {0x40,0x01,'t',0x40,0x01,'u',0x89,0x02,0x01};
4100 static const char res8
[] =
4101 {0x40,0x01,'t',0x40,0x01,'u',0x93,0xcd,0xcc,0xcc,0xcc,0xcc,0xcc,0x00,0x40,0x01};
4102 static const char res8a
[] =
4103 {0x40,0x01,'t',0x40,0x01,'u',0x93,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x7f,0x01};
4104 static const char res8b
[] =
4105 {0x40,0x01,'t',0x40,0x01,'u',0x93,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0x01};
4106 static const char res8c
[] =
4107 {0x40,0x01,'t',0x40,0x01,'u',0x93,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x7f,0x01};
4108 static const char res9
[] =
4109 {0x40,0x01,'t',0x40,0x01,'u',0xb1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
4110 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
4111 static const char res10
[] =
4112 {0x40,0x01,'t',0x40,0x01,'u',0xad,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
4113 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
4114 static const char res11
[] =
4115 {0x40,0x01,'t',0x40,0x01,'u',0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01};
4116 static const char res11b
[] =
4117 {0x40,0x01,'t',0x40,0x01,'u',0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01};
4118 static const char res11c
[] =
4119 {0x40,0x01,'t',0x40,0x01,'u',0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
4120 static const char res11d
[] =
4121 {0x40,0x01,'t',0x40,0x01,'u',0x97,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01};
4123 WS_XML_WRITER
*writer
;
4124 WS_UNION_DESCRIPTION u
;
4125 WS_UNION_FIELD_DESCRIPTION f
, f2
, f3
, f4
, f5
, f6
, f7
, f8
, f9
, f10
, f11
, *fields
[11];
4126 WS_FIELD_DESCRIPTION f_struct
, *fields_struct
[1];
4127 WS_STRUCT_DESCRIPTION s
;
4130 WS_XML_TEXT_TYPE type
;
4133 WS_XML_STRING val_utf8
;
4134 WS_STRING val_utf16
;
4142 WS_UNIQUE_ID val_unique_id
;
4143 WS_DATETIME val_datetime
;
4148 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
4149 ok( hr
== S_OK
, "got %08x\n", hr
);
4151 memset( &f
, 0, sizeof(f
) );
4152 f
.value
= WS_XML_TEXT_TYPE_UTF8
;
4153 f
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4154 f
.field
.localName
= &str_u
;
4155 f
.field
.ns
= &str_ns
;
4156 f
.field
.type
= WS_XML_STRING_TYPE
;
4157 f
.field
.offset
= FIELD_OFFSET(struct test
, u
.val_utf8
);
4160 memset( &f2
, 0, sizeof(f2
) );
4161 f2
.value
= WS_XML_TEXT_TYPE_UTF16
;
4162 f2
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4163 f2
.field
.localName
= &str_u
;
4164 f2
.field
.ns
= &str_ns
;
4165 f2
.field
.type
= WS_STRING_TYPE
;
4166 f2
.field
.offset
= FIELD_OFFSET(struct test
, u
.val_utf16
);
4169 memset( &f3
, 0, sizeof(f3
) );
4170 f3
.value
= WS_XML_TEXT_TYPE_BASE64
;
4171 f3
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4172 f3
.field
.localName
= &str_u
;
4173 f3
.field
.ns
= &str_ns
;
4174 f3
.field
.type
= WS_BYTES_TYPE
;
4175 f3
.field
.offset
= FIELD_OFFSET(struct test
, u
.val_bytes
);
4178 memset( &f4
, 0, sizeof(f4
) );
4179 f4
.value
= WS_XML_TEXT_TYPE_BOOL
;
4180 f4
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4181 f4
.field
.localName
= &str_u
;
4182 f4
.field
.ns
= &str_ns
;
4183 f4
.field
.type
= WS_BOOL_TYPE
;
4184 f4
.field
.offset
= FIELD_OFFSET(struct test
, u
.val_bool
);
4187 memset( &f5
, 0, sizeof(f5
) );
4188 f5
.value
= WS_XML_TEXT_TYPE_INT32
;
4189 f5
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4190 f5
.field
.localName
= &str_u
;
4191 f5
.field
.ns
= &str_ns
;
4192 f5
.field
.type
= WS_INT32_TYPE
;
4193 f5
.field
.offset
= FIELD_OFFSET(struct test
, u
.val_int32
);
4196 memset( &f6
, 0, sizeof(f6
) );
4197 f6
.value
= WS_XML_TEXT_TYPE_INT64
;
4198 f6
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4199 f6
.field
.localName
= &str_u
;
4200 f6
.field
.ns
= &str_ns
;
4201 f6
.field
.type
= WS_INT64_TYPE
;
4202 f6
.field
.offset
= FIELD_OFFSET(struct test
, u
.val_int64
);
4205 memset( &f7
, 0, sizeof(f7
) );
4206 f7
.value
= WS_XML_TEXT_TYPE_UINT64
;
4207 f7
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4208 f7
.field
.localName
= &str_u
;
4209 f7
.field
.ns
= &str_ns
;
4210 f7
.field
.type
= WS_UINT64_TYPE
;
4211 f7
.field
.offset
= FIELD_OFFSET(struct test
, u
.val_uint64
);
4214 memset( &f8
, 0, sizeof(f8
) );
4215 f8
.value
= WS_XML_TEXT_TYPE_DOUBLE
;
4216 f8
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4217 f8
.field
.localName
= &str_u
;
4218 f8
.field
.ns
= &str_ns
;
4219 f8
.field
.type
= WS_DOUBLE_TYPE
;
4220 f8
.field
.offset
= FIELD_OFFSET(struct test
, u
.val_double
);
4223 memset( &f9
, 0, sizeof(f9
) );
4224 f9
.value
= WS_XML_TEXT_TYPE_GUID
;
4225 f9
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4226 f9
.field
.localName
= &str_u
;
4227 f9
.field
.ns
= &str_ns
;
4228 f9
.field
.type
= WS_GUID_TYPE
;
4229 f9
.field
.offset
= FIELD_OFFSET(struct test
, u
.val_guid
);
4232 memset( &f10
, 0, sizeof(f10
) );
4233 f10
.value
= WS_XML_TEXT_TYPE_UNIQUE_ID
;
4234 f10
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4235 f10
.field
.localName
= &str_u
;
4236 f10
.field
.ns
= &str_ns
;
4237 f10
.field
.type
= WS_UNIQUE_ID_TYPE
;
4238 f10
.field
.offset
= FIELD_OFFSET(struct test
, u
.val_unique_id
);
4241 memset( &f11
, 0, sizeof(f11
) );
4242 f11
.value
= WS_XML_TEXT_TYPE_DATETIME
;
4243 f11
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4244 f11
.field
.localName
= &str_u
;
4245 f11
.field
.ns
= &str_ns
;
4246 f11
.field
.type
= WS_DATETIME_TYPE
;
4247 f11
.field
.offset
= FIELD_OFFSET(struct test
, u
.val_datetime
);
4250 memset( &u
, 0, sizeof(u
) );
4251 u
.size
= sizeof(struct test
);
4252 u
.alignment
= TYPE_ALIGNMENT(struct test
);
4255 u
.enumOffset
= FIELD_OFFSET(struct test
, type
);
4257 memset( &f_struct
, 0, sizeof(f_struct
) );
4258 f_struct
.mapping
= WS_ELEMENT_CHOICE_FIELD_MAPPING
;
4259 f_struct
.type
= WS_UNION_TYPE
;
4260 f_struct
.typeDescription
= &u
;
4261 fields_struct
[0] = &f_struct
;
4263 memset( &s
, 0, sizeof(s
) );
4264 s
.size
= sizeof(struct test
);
4265 s
.alignment
= TYPE_ALIGNMENT(struct test
);
4266 s
.fields
= fields_struct
;
4268 s
.typeLocalName
= &str_s
;
4271 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4272 test
.type
= WS_XML_TEXT_TYPE_UTF8
;
4273 test
.u
.val_utf8
.bytes
= (BYTE
*)"test";
4274 test
.u
.val_utf8
.length
= 4;
4275 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4276 &test
, sizeof(test
), NULL
);
4277 ok( hr
== S_OK
, "got %08x\n", hr
);
4278 hr
= WsWriteEndElement( writer
, NULL
);
4279 ok( hr
== S_OK
, "got %08x\n", hr
);
4280 check_output_bin( writer
, res
, sizeof(res
), __LINE__
);
4282 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4283 test
.type
= WS_XML_TEXT_TYPE_UTF16
;
4284 test
.u
.val_utf16
.chars
= testW
;
4285 test
.u
.val_utf16
.length
= 4;
4286 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4287 &test
, sizeof(test
), NULL
);
4288 ok( hr
== S_OK
, "got %08x\n", hr
);
4289 hr
= WsWriteEndElement( writer
, NULL
);
4290 ok( hr
== S_OK
, "got %08x\n", hr
);
4291 check_output_bin( writer
, res
, sizeof(res
), __LINE__
);
4293 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4294 test
.type
= WS_XML_TEXT_TYPE_BASE64
;
4295 test
.u
.val_bytes
.bytes
= (BYTE
*)"test";
4296 test
.u
.val_bytes
.length
= 4;
4297 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4298 &test
, sizeof(test
), NULL
);
4299 ok( hr
== S_OK
, "got %08x\n", hr
);
4300 hr
= WsWriteEndElement( writer
, NULL
);
4301 ok( hr
== S_OK
, "got %08x\n", hr
);
4302 check_output_bin( writer
, res2
, sizeof(res2
), __LINE__
);
4304 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4305 test
.type
= WS_XML_TEXT_TYPE_BASE64
;
4306 test
.u
.val_bytes
.bytes
= (BYTE
*)"tes";
4307 test
.u
.val_bytes
.length
= 3;
4308 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4309 &test
, sizeof(test
), NULL
);
4310 ok( hr
== S_OK
, "got %08x\n", hr
);
4311 hr
= WsWriteEndElement( writer
, NULL
);
4312 ok( hr
== S_OK
, "got %08x\n", hr
);
4313 check_output_bin( writer
, res2a
, sizeof(res2a
), __LINE__
);
4315 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4316 test
.type
= WS_XML_TEXT_TYPE_BASE64
;
4317 test
.u
.val_bytes
.bytes
= (BYTE
*)"t";
4318 test
.u
.val_bytes
.length
= 1;
4319 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4320 &test
, sizeof(test
), NULL
);
4321 ok( hr
== S_OK
, "got %08x\n", hr
);
4322 hr
= WsWriteEndElement( writer
, NULL
);
4323 ok( hr
== S_OK
, "got %08x\n", hr
);
4324 check_output_bin( writer
, res2b
, sizeof(res2b
), __LINE__
);
4326 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4327 test
.type
= WS_XML_TEXT_TYPE_BASE64
;
4328 test
.u
.val_bytes
.bytes
= (BYTE
*)"";
4329 test
.u
.val_bytes
.length
= 0;
4330 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4331 &test
, sizeof(test
), NULL
);
4332 ok( hr
== S_OK
, "got %08x\n", hr
);
4333 hr
= WsWriteEndElement( writer
, NULL
);
4334 ok( hr
== S_OK
, "got %08x\n", hr
);
4335 check_output_bin( writer
, res2c
, sizeof(res2c
), __LINE__
);
4337 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4338 memset( buf
, 'a', sizeof(buf
) );
4339 test
.type
= WS_XML_TEXT_TYPE_BASE64
;
4340 test
.u
.val_bytes
.bytes
= buf
;
4341 test
.u
.val_bytes
.length
= 255;
4342 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4343 &test
, sizeof(test
), NULL
);
4344 ok( hr
== S_OK
, "got %08x\n", hr
);
4345 hr
= WsWriteEndElement( writer
, NULL
);
4346 ok( hr
== S_OK
, "got %08x\n", hr
);
4347 check_output_bin( writer
, res2d
, sizeof(res2d
), __LINE__
);
4349 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4350 test
.type
= WS_XML_TEXT_TYPE_BASE64
;
4351 test
.u
.val_bytes
.bytes
= buf
;
4352 test
.u
.val_bytes
.length
= 256;
4353 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4354 &test
, sizeof(test
), NULL
);
4355 ok( hr
== S_OK
, "got %08x\n", hr
);
4356 hr
= WsWriteEndElement( writer
, NULL
);
4357 ok( hr
== S_OK
, "got %08x\n", hr
);
4358 check_output_bin( writer
, res2e
, sizeof(res2e
), __LINE__
);
4360 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4361 test
.type
= WS_XML_TEXT_TYPE_BASE64
;
4362 test
.u
.val_bytes
.bytes
= (BYTE
*)"testte";
4363 test
.u
.val_bytes
.length
= 6;
4364 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4365 &test
, sizeof(test
), NULL
);
4366 ok( hr
== S_OK
, "got %08x\n", hr
);
4367 hr
= WsWriteEndElement( writer
, NULL
);
4368 ok( hr
== S_OK
, "got %08x\n", hr
);
4369 check_output_bin( writer
, res2f
, sizeof(res2f
), __LINE__
);
4371 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4372 test
.type
= WS_XML_TEXT_TYPE_BOOL
;
4373 test
.u
.val_bool
= TRUE
;
4374 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4375 &test
, sizeof(test
), NULL
);
4376 ok( hr
== S_OK
, "got %08x\n", hr
);
4377 hr
= WsWriteEndElement( writer
, NULL
);
4378 ok( hr
== S_OK
, "got %08x\n", hr
);
4379 check_output_bin( writer
, res3
, sizeof(res3
), __LINE__
);
4381 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4382 test
.type
= WS_XML_TEXT_TYPE_INT32
;
4383 test
.u
.val_int32
= -1;
4384 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4385 &test
, sizeof(test
), NULL
);
4386 ok( hr
== S_OK
, "got %08x\n", hr
);
4387 hr
= WsWriteEndElement( writer
, NULL
);
4388 ok( hr
== S_OK
, "got %08x\n", hr
);
4389 check_output_bin( writer
, res4
, sizeof(res4
), __LINE__
);
4391 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4392 test
.type
= WS_XML_TEXT_TYPE_INT64
;
4393 test
.u
.val_int64
= -1;
4394 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4395 &test
, sizeof(test
), NULL
);
4396 ok( hr
== S_OK
, "got %08x\n", hr
);
4397 hr
= WsWriteEndElement( writer
, NULL
);
4398 ok( hr
== S_OK
, "got %08x\n", hr
);
4399 check_output_bin( writer
, res4
, sizeof(res4
), __LINE__
);
4401 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4402 test
.type
= WS_XML_TEXT_TYPE_UINT64
;
4403 test
.u
.val_uint64
= 1;
4404 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4405 &test
, sizeof(test
), NULL
);
4406 ok( hr
== S_OK
, "got %08x\n", hr
);
4407 hr
= WsWriteEndElement( writer
, NULL
);
4408 ok( hr
== S_OK
, "got %08x\n", hr
);
4409 check_output_bin( writer
, res5
, sizeof(res5
), __LINE__
);
4411 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4412 test
.type
= WS_XML_TEXT_TYPE_UINT64
;
4413 test
.u
.val_uint64
= 2;
4414 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4415 &test
, sizeof(test
), NULL
);
4416 ok( hr
== S_OK
, "got %08x\n", hr
);
4417 hr
= WsWriteEndElement( writer
, NULL
);
4418 ok( hr
== S_OK
, "got %08x\n", hr
);
4419 check_output_bin( writer
, res5b
, sizeof(res5b
), __LINE__
);
4421 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4422 test
.type
= WS_XML_TEXT_TYPE_DOUBLE
;
4423 test
.u
.val_double
= 0.0;
4424 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4425 &test
, sizeof(test
), NULL
);
4426 ok( hr
== S_OK
, "got %08x\n", hr
);
4427 hr
= WsWriteEndElement( writer
, NULL
);
4428 ok( hr
== S_OK
, "got %08x\n", hr
);
4429 check_output_bin( writer
, res6
, sizeof(res6
), __LINE__
);
4431 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4432 test
.type
= WS_XML_TEXT_TYPE_DOUBLE
;
4433 test
.u
.val_double
= 2.0;
4434 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4435 &test
, sizeof(test
), NULL
);
4436 ok( hr
== S_OK
, "got %08x\n", hr
);
4437 hr
= WsWriteEndElement( writer
, NULL
);
4438 ok( hr
== S_OK
, "got %08x\n", hr
);
4439 check_output_bin( writer
, res7
, sizeof(res7
), __LINE__
);
4441 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4442 test
.type
= WS_XML_TEXT_TYPE_DOUBLE
;
4443 test
.u
.val_double
= 2.1;
4444 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4445 &test
, sizeof(test
), NULL
);
4446 ok( hr
== S_OK
, "got %08x\n", hr
);
4447 hr
= WsWriteEndElement( writer
, NULL
);
4448 ok( hr
== S_OK
, "got %08x\n", hr
);
4449 check_output_bin( writer
, res8
, sizeof(res8
), __LINE__
);
4451 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4452 test
.type
= WS_XML_TEXT_TYPE_DOUBLE
;
4453 test
.u
.val_double
= INFINITY
;
4454 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4455 &test
, sizeof(test
), NULL
);
4456 ok( hr
== S_OK
, "got %08x\n", hr
);
4457 hr
= WsWriteEndElement( writer
, NULL
);
4458 ok( hr
== S_OK
, "got %08x\n", hr
);
4459 check_output_bin( writer
, res8a
, sizeof(res8a
), __LINE__
);
4461 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4462 test
.type
= WS_XML_TEXT_TYPE_DOUBLE
;
4463 test
.u
.val_double
= -INFINITY
;
4464 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4465 &test
, sizeof(test
), NULL
);
4466 ok( hr
== S_OK
, "got %08x\n", hr
);
4467 hr
= WsWriteEndElement( writer
, NULL
);
4468 ok( hr
== S_OK
, "got %08x\n", hr
);
4469 check_output_bin( writer
, res8b
, sizeof(res8b
), __LINE__
);
4471 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4472 test
.type
= WS_XML_TEXT_TYPE_DOUBLE
;
4473 test
.u
.val_double
= NAN
;
4474 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4475 &test
, sizeof(test
), NULL
);
4476 ok( hr
== S_OK
, "got %08x\n", hr
);
4477 hr
= WsWriteEndElement( writer
, NULL
);
4478 ok( hr
== S_OK
, "got %08x\n", hr
);
4479 check_output_bin( writer
, res8c
, sizeof(res8c
), __LINE__
);
4481 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4482 test
.type
= WS_XML_TEXT_TYPE_GUID
;
4483 memset( &test
.u
.val_guid
, 0, sizeof(test
.u
.val_guid
) );
4484 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4485 &test
, sizeof(test
), NULL
);
4486 ok( hr
== S_OK
, "got %08x\n", hr
);
4487 hr
= WsWriteEndElement( writer
, NULL
);
4488 ok( hr
== S_OK
, "got %08x\n", hr
);
4489 check_output_bin( writer
, res9
, sizeof(res9
), __LINE__
);
4491 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4492 test
.type
= WS_XML_TEXT_TYPE_UNIQUE_ID
;
4493 memset( &test
.u
.val_unique_id
, 0, sizeof(test
.u
.val_unique_id
) );
4494 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4495 &test
, sizeof(test
), NULL
);
4496 ok( hr
== S_OK
, "got %08x\n", hr
);
4497 hr
= WsWriteEndElement( writer
, NULL
);
4498 ok( hr
== S_OK
, "got %08x\n", hr
);
4499 check_output_bin( writer
, res10
, sizeof(res10
), __LINE__
);
4501 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4502 test
.type
= WS_XML_TEXT_TYPE_DATETIME
;
4503 memset( &test
.u
.val_datetime
, 0, sizeof(test
.u
.val_datetime
) );
4504 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4505 &test
, sizeof(test
), NULL
);
4506 ok( hr
== S_OK
, "got %08x\n", hr
);
4507 hr
= WsWriteEndElement( writer
, NULL
);
4508 ok( hr
== S_OK
, "got %08x\n", hr
);
4509 check_output_bin( writer
, res11
, sizeof(res11
), __LINE__
);
4511 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4512 test
.type
= WS_XML_TEXT_TYPE_DATETIME
;
4513 memset( &test
.u
.val_datetime
, 0, sizeof(test
.u
.val_datetime
) );
4514 test
.u
.val_datetime
.format
= WS_DATETIME_FORMAT_LOCAL
;
4515 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4516 &test
, sizeof(test
), NULL
);
4517 ok( hr
== S_OK
, "got %08x\n", hr
);
4518 hr
= WsWriteEndElement( writer
, NULL
);
4519 ok( hr
== S_OK
, "got %08x\n", hr
);
4520 check_output_bin( writer
, res11b
, sizeof(res11b
), __LINE__
);
4522 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4523 test
.type
= WS_XML_TEXT_TYPE_DATETIME
;
4524 memset( &test
.u
.val_datetime
, 0, sizeof(test
.u
.val_datetime
) );
4525 test
.u
.val_datetime
.format
= WS_DATETIME_FORMAT_NONE
;
4526 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4527 &test
, sizeof(test
), NULL
);
4528 ok( hr
== S_OK
, "got %08x\n", hr
);
4529 hr
= WsWriteEndElement( writer
, NULL
);
4530 ok( hr
== S_OK
, "got %08x\n", hr
);
4531 check_output_bin( writer
, res11c
, sizeof(res11c
), __LINE__
);
4533 prepare_binary_type_test( writer
, NULL
, &str_t
, &str_ns
);
4534 test
.type
= WS_XML_TEXT_TYPE_DATETIME
;
4535 memset( &test
.u
.val_datetime
, 0, sizeof(test
.u
.val_datetime
) );
4536 test
.u
.val_datetime
.ticks
= 1;
4537 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
, WS_WRITE_REQUIRED_VALUE
,
4538 &test
, sizeof(test
), NULL
);
4539 ok( hr
== S_OK
, "got %08x\n", hr
);
4540 hr
= WsWriteEndElement( writer
, NULL
);
4541 ok( hr
== S_OK
, "got %08x\n", hr
);
4542 check_output_bin( writer
, res11d
, sizeof(res11d
), __LINE__
);
4544 WsFreeWriter( writer
);
4547 static void test_repeating_element_choice(void)
4549 static const WCHAR testW
[] = {'t','e','s','t',0};
4550 static WS_XML_STRING str_ns
= {0, NULL
}, str_a
= {1, (BYTE
*)"a"}, str_b
= {1, (BYTE
*)"b"};
4551 static WS_XML_STRING str_s
= {1, (BYTE
*)"s"}, str_t
= {1, (BYTE
*)"t"};
4553 WS_XML_WRITER
*writer
;
4554 WS_UNION_DESCRIPTION u
;
4555 WS_UNION_FIELD_DESCRIPTION f
, f2
, *fields
[2];
4556 WS_FIELD_DESCRIPTION f_items
, *fields_items
[1];
4557 WS_STRUCT_DESCRIPTION s
;
4558 enum choice
{CHOICE_A
, CHOICE_B
, CHOICE_NONE
};
4574 hr
= WsCreateWriter( NULL
, 0, &writer
, NULL
);
4575 ok( hr
== S_OK
, "got %08x\n", hr
);
4577 memset( &f
, 0, sizeof(f
) );
4579 f
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4580 f
.field
.localName
= &str_a
;
4581 f
.field
.ns
= &str_ns
;
4582 f
.field
.type
= WS_WSZ_TYPE
;
4583 f
.field
.offset
= FIELD_OFFSET(struct item
, value
.a
);
4586 memset( &f2
, 0, sizeof(f2
) );
4587 f2
.value
= CHOICE_B
;
4588 f2
.field
.mapping
= WS_ELEMENT_FIELD_MAPPING
;
4589 f2
.field
.localName
= &str_b
;
4590 f2
.field
.ns
= &str_ns
;
4591 f2
.field
.type
= WS_UINT32_TYPE
;
4592 f2
.field
.offset
= FIELD_OFFSET(struct item
, value
.b
);
4595 memset( &u
, 0, sizeof(u
) );
4596 u
.size
= sizeof(struct item
);
4597 u
.alignment
= TYPE_ALIGNMENT(struct item
);
4600 u
.enumOffset
= FIELD_OFFSET(struct item
, choice
);
4601 u
.noneEnumValue
= CHOICE_NONE
;
4603 memset( &f_items
, 0, sizeof(f_items
) );
4604 f_items
.mapping
= WS_REPEATING_ELEMENT_CHOICE_FIELD_MAPPING
;
4605 f_items
.localName
= &str_t
;
4606 f_items
.ns
= &str_ns
;
4607 f_items
.type
= WS_UNION_TYPE
;
4608 f_items
.typeDescription
= &u
;
4609 f_items
.countOffset
= FIELD_OFFSET(struct test
, count
);
4610 fields_items
[0] = &f_items
;
4612 memset( &s
, 0, sizeof(s
) );
4613 s
.size
= sizeof(struct test
);
4614 s
.alignment
= TYPE_ALIGNMENT(struct test
);
4615 s
.fields
= fields_items
;
4617 s
.typeLocalName
= &str_s
;
4620 items
[0].choice
= CHOICE_A
;
4621 items
[0].value
.a
= testW
;
4622 items
[1].choice
= CHOICE_B
;
4623 items
[1].value
.b
= 1;
4627 hr
= set_output( writer
);
4628 ok( hr
== S_OK
, "got %08x\n", hr
);
4629 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
4630 WS_WRITE_REQUIRED_VALUE
, &test
, sizeof(test
), NULL
);
4631 ok( hr
== S_OK
, "got %08x\n", hr
);
4632 check_output( writer
, "<t><a>test</a><b>1</b></t>", __LINE__
);
4634 items
[0].choice
= CHOICE_NONE
;
4635 hr
= set_output( writer
);
4636 ok( hr
== S_OK
, "got %08x\n", hr
);
4637 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
4638 WS_WRITE_REQUIRED_VALUE
, &test
, sizeof(test
), NULL
);
4639 ok( hr
== WS_E_INVALID_FORMAT
, "got %08x\n", hr
);
4642 hr
= set_output( writer
);
4643 ok( hr
== S_OK
, "got %08x\n", hr
);
4644 hr
= WsWriteType( writer
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, WS_STRUCT_TYPE
, &s
,
4645 WS_WRITE_REQUIRED_VALUE
, &test
, sizeof(test
), NULL
);
4646 ok( hr
== S_OK
, "got %08x\n", hr
);
4647 check_output( writer
, "<t/>", __LINE__
);
4649 WsFreeWriter( writer
);
4654 test_WsCreateWriter();
4655 test_WsCreateXmlBuffer();
4657 test_WsSetOutputToBuffer();
4658 test_WsWriteStartElement();
4659 test_WsWriteStartAttribute();
4662 test_simple_struct_type();
4663 test_WsWriteElement();
4664 test_WsWriteValue();
4665 test_WsWriteAttribute();
4666 test_WsWriteStartCData();
4667 test_WsWriteXmlnsAttribute();
4668 test_WsGetPrefixFromNamespace();
4669 test_complex_struct_type();
4670 test_WsMoveWriter();
4671 test_WsGetWriterPosition();
4672 test_WsSetWriterPosition();
4673 test_WsWriteXmlBuffer();
4678 test_field_options();
4680 test_WsWriteArray();
4682 test_write_option();
4684 test_repeating_element();
4685 test_WsWriteQualifiedName();
4686 test_WsWriteBytes();
4687 test_WsWriteChars();
4688 test_WsWriteCharsUtf8();
4689 test_binary_encoding();
4693 test_text_types_binary();
4694 test_repeating_element_choice();