makefiles: Don't use standard libs for programs that specify -nodefaultlibs.
[wine/zf.git] / dlls / webservices / tests / reader.c
blob7d56ebccd53f32386c66b7a9cc160bcb0f8ebf28
1 /*
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
19 #include <stdio.h>
20 #include "windows.h"
21 #include "rpc.h"
22 #include "webservices.h"
23 #include "wine/test.h"
25 static const GUID guid_null;
27 static const char data1[] =
28 "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
30 static const char data2[] =
31 {0xef,0xbb,0xbf,'<','t','e','x','t','>','t','e','s','t','<','/','t','e','x','t','>',0};
33 static const char data3[] =
34 "<?xml version=\"1.0\" encoding=\"utf-8\"?> "
35 "<text>test</TEXT>";
37 static const char data4[] =
38 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
39 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">\r\n"
40 " <o:services o:GenerationTime=\"2015-09-03T18:47:54\">\r\n"
41 " <!--Build: 16.0.6202.6852-->\r\n"
42 " <o:default>\r\n"
43 " <o:ticket o:headerName=\"Authorization\" o:headerValue=\"{}\" />\r\n"
44 " </o:default>\r\n"
45 " <o:service o:name=\"LiveOAuthLoginStart\">\r\n"
46 " <o:url>https://login.[Live.WebHost]/oauth20_authorize.srf</o:url>\r\n"
47 " </o:service>\r\n"
48 "</o:services>\r\n"
49 "</o:OfficeConfig>\r\n";
51 static const char data5[] =
52 "</text>";
54 static const char data6[] =
55 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
56 "<text attr= \"value\" attr2='value2'>test</text>";
58 static const char data7[] =
59 "<!-- comment -->";
61 static const char data8[] =
62 "<node1><node2>test</node2></node1>";
64 static const char data9[] =
65 "<text xml:attr=\"value\">test</text>";
67 static const char data10[] =
68 "<a></b>";
70 static void test_WsCreateError(void)
72 HRESULT hr;
73 WS_ERROR *error;
74 WS_ERROR_PROPERTY prop;
75 ULONG size, code, count;
76 LANGID langid;
78 hr = WsCreateError( NULL, 0, NULL );
79 ok( hr == E_INVALIDARG, "got %08x\n", hr );
81 error = NULL;
82 hr = WsCreateError( NULL, 0, &error );
83 ok( hr == S_OK, "got %08x\n", hr );
84 ok( error != NULL, "error not set\n" );
86 count = 0xdeadbeef;
87 size = sizeof(count);
88 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
89 ok( hr == S_OK, "got %08x\n", hr );
90 ok( !count, "got %u\n", count );
92 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
93 ok( hr == E_INVALIDARG, "got %08x\n", hr );
95 code = 0xdeadbeef;
96 size = sizeof(code);
97 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
98 ok( hr == S_OK, "got %08x\n", hr );
99 ok( !code, "got %u\n", code );
101 code = 0xdeadbeef;
102 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
103 ok( hr == S_OK, "got %08x\n", hr );
104 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
105 ok( hr == S_OK, "got %08x\n", hr );
106 ok( code == 0xdeadbeef, "got %u\n", code );
108 langid = 0xdead;
109 size = sizeof(langid);
110 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
111 ok( hr == S_OK, "got %08x\n", hr );
112 ok( langid == GetUserDefaultUILanguage(), "got %u\n", langid );
114 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
115 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
116 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
118 count = 0xdeadbeef;
119 size = sizeof(count);
120 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID + 1, &count, size );
121 ok( hr == E_INVALIDARG, "got %08x\n", hr );
122 ok( count == 0xdeadbeef, "got %u\n", count );
123 WsFreeError( error );
125 count = 1;
126 prop.id = WS_ERROR_PROPERTY_STRING_COUNT;
127 prop.value = &count;
128 prop.valueSize = sizeof(count);
129 hr = WsCreateError( &prop, 1, &error );
130 ok( hr == E_INVALIDARG, "got %08x\n", hr );
132 code = 0xdeadbeef;
133 prop.id = WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE;
134 prop.value = &code;
135 prop.valueSize = sizeof(code);
136 hr = WsCreateError( &prop, 1, &error );
137 ok( hr == E_INVALIDARG, "got %08x\n", hr );
139 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
140 prop.id = WS_ERROR_PROPERTY_LANGID;
141 prop.value = &langid;
142 prop.valueSize = sizeof(langid);
143 hr = WsCreateError( &prop, 1, &error );
144 ok( hr == S_OK, "got %08x\n", hr );
146 langid = 0xdead;
147 size = sizeof(langid);
148 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
149 ok( hr == S_OK, "got %08x\n", hr );
150 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
151 WsFreeError( error );
153 count = 0xdeadbeef;
154 prop.id = WS_ERROR_PROPERTY_LANGID + 1;
155 prop.value = &count;
156 prop.valueSize = sizeof(count);
157 hr = WsCreateError( &prop, 1, &error );
158 ok( hr == E_INVALIDARG, "got %08x\n", hr );
161 static void test_WsCreateHeap(void)
163 HRESULT hr;
164 WS_HEAP *heap;
165 WS_HEAP_PROPERTY prop;
166 SIZE_T max, trim, requested, actual;
167 ULONG size;
169 hr = WsCreateHeap( 0, 0, NULL, 0, NULL, NULL );
170 ok( hr == E_INVALIDARG, "got %08x\n", hr );
172 heap = NULL;
173 hr = WsCreateHeap( 0, 0, NULL, 0, &heap, NULL );
174 ok( hr == S_OK, "got %08x\n", hr );
175 ok( heap != NULL, "heap not set\n" );
176 WsFreeHeap( heap );
178 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, NULL, NULL );
179 ok( hr == E_INVALIDARG, "got %08x\n", hr );
181 heap = NULL;
182 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
183 ok( hr == S_OK, "got %08x\n", hr );
184 ok( heap != NULL, "heap not set\n" );
185 WsFreeHeap( heap );
187 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, &heap, NULL );
188 ok( hr == S_OK, "got %08x\n", hr );
190 max = 0xdeadbeef;
191 size = sizeof(max);
192 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_MAX_SIZE, &max, size, NULL );
193 ok( hr == S_OK, "got %08x\n", hr );
194 ok( max == 1 << 16, "got %u\n", (ULONG)max );
196 trim = 0xdeadbeef;
197 size = sizeof(trim);
198 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_TRIM_SIZE, &trim, size, NULL );
199 ok( hr == S_OK, "got %08x\n", hr );
200 ok( trim == 1 << 6, "got %u\n", (ULONG)trim );
202 requested = 0xdeadbeef;
203 size = sizeof(requested);
204 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
205 ok( hr == S_OK, "got %08x\n", hr );
206 ok( !requested, "got %u\n", (ULONG)requested );
208 actual = 0xdeadbeef;
209 size = sizeof(actual);
210 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
211 ok( hr == S_OK, "got %08x\n", hr );
212 ok( !actual, "got %u\n", (ULONG)actual );
214 actual = 0xdeadbeef;
215 size = sizeof(actual);
216 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE + 1, &actual, size, NULL );
217 ok( hr == E_INVALIDARG, "got %08x\n", hr );
218 ok( actual == 0xdeadbeef, "got %u\n", (ULONG)actual );
219 WsFreeHeap( heap );
221 max = 1 << 16;
222 prop.id = WS_HEAP_PROPERTY_MAX_SIZE;
223 prop.value = &max;
224 prop.valueSize = sizeof(max);
225 hr = WsCreateHeap( 1 << 16, 1 << 6, &prop, 1, &heap, NULL );
226 ok( hr == E_INVALIDARG, "got %08x\n", hr );
228 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 1, &heap, NULL );
229 ok( hr == E_INVALIDARG, "got %08x\n", hr );
232 static HRESULT set_input( WS_XML_READER *reader, const char *data, ULONG size )
234 WS_XML_READER_TEXT_ENCODING text = {{WS_XML_READER_ENCODING_TYPE_TEXT}, WS_CHARSET_AUTO};
235 WS_XML_READER_BUFFER_INPUT buf;
237 buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
238 buf.encodedData = (void *)data;
239 buf.encodedDataSize = size;
240 return WsSetInput( reader, &text.encoding, &buf.input, NULL, 0, NULL );
243 static void test_WsCreateReader(void)
245 HRESULT hr;
246 WS_XML_READER *reader;
247 WS_XML_READER_PROPERTY prop;
248 ULONG size, max_depth, max_attrs, trim_size, buffer_size, max_ns;
249 BOOL allow_fragment, read_decl, in_attr;
250 ULONGLONG row, column;
251 WS_CHARSET charset;
253 hr = WsCreateReader( NULL, 0, NULL, NULL );
254 ok( hr == E_INVALIDARG, "got %08x\n", hr );
256 reader = NULL;
257 hr = WsCreateReader( NULL, 0, &reader, NULL );
258 ok( hr == S_OK, "got %08x\n", hr );
259 ok( reader != NULL, "reader not set\n" );
261 /* can't retrieve properties before input is set */
262 max_depth = 0xdeadbeef;
263 size = sizeof(max_depth);
264 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
265 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
266 ok( max_depth == 0xdeadbeef, "max_depth set\n" );
268 hr = set_input( reader, data1, sizeof(data1) - 1 );
269 ok( hr == S_OK, "got %08x\n", hr );
271 /* check some defaults */
272 max_depth = 0xdeadbeef;
273 size = sizeof(max_depth);
274 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
275 ok( hr == S_OK, "got %08x\n", hr );
276 ok( max_depth == 32, "got %u\n", max_depth );
278 allow_fragment = TRUE;
279 size = sizeof(allow_fragment);
280 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_ALLOW_FRAGMENT, &allow_fragment, size, NULL );
281 ok( hr == S_OK, "got %08x\n", hr );
282 ok( !allow_fragment, "got %d\n", allow_fragment );
284 max_attrs = 0xdeadbeef;
285 size = sizeof(max_attrs);
286 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES, &max_attrs, size, NULL );
287 ok( hr == S_OK, "got %08x\n", hr );
288 ok( max_attrs == 128, "got %u\n", max_attrs );
290 read_decl = FALSE;
291 size = sizeof(read_decl);
292 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_READ_DECLARATION, &read_decl, size, NULL );
293 ok( hr == S_OK, "got %08x\n", hr );
294 ok( read_decl, "got %u\n", read_decl );
296 charset = 0xdeadbeef;
297 size = sizeof(charset);
298 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
299 ok( hr == S_OK, "got %08x\n", hr );
300 ok( charset == WS_CHARSET_UTF8, "got %u\n", charset );
302 size = sizeof(trim_size);
303 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_UTF8_TRIM_SIZE, &trim_size, size, NULL );
304 todo_wine ok( hr == E_INVALIDARG, "got %08x\n", hr );
305 WsFreeReader( reader );
307 hr = WsCreateReader( NULL, 0, &reader, NULL );
308 ok( hr == S_OK, "got %08x\n", hr );
310 hr = set_input( reader, data1, sizeof(data1) - 1 );
311 ok( hr == S_OK, "got %08x\n", hr );
313 size = sizeof(buffer_size);
314 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_STREAM_BUFFER_SIZE, &buffer_size, size, NULL );
315 todo_wine ok( hr == E_INVALIDARG, "got %08x\n", hr );
316 WsFreeReader( reader );
318 hr = WsCreateReader( NULL, 0, &reader, NULL );
319 ok( hr == S_OK, "got %08x\n", hr );
321 hr = set_input( reader, data1, sizeof(data1) - 1 );
322 ok( hr == S_OK, "got %08x\n", hr );
324 max_ns = 0xdeadbeef;
325 size = sizeof(max_ns);
326 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_NAMESPACES, &max_ns, size, NULL );
327 ok( hr == S_OK, "got %08x\n", hr );
328 ok( max_ns == 32, "got %u\n", max_ns );
329 WsFreeReader( reader );
331 /* change a property */
332 max_depth = 16;
333 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
334 prop.value = &max_depth;
335 prop.valueSize = sizeof(max_depth);
336 hr = WsCreateReader( &prop, 1, &reader, NULL );
337 ok( hr == S_OK, "got %08x\n", hr );
339 hr = set_input( reader, data1, sizeof(data1) - 1 );
340 ok( hr == S_OK, "got %08x\n", hr );
342 max_depth = 0xdeadbeef;
343 size = sizeof(max_depth);
344 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
345 ok( hr == S_OK, "got %08x\n", hr );
346 ok( max_depth == 16, "got %u\n", max_depth );
347 WsFreeReader( reader );
349 /* show that some properties are read-only */
350 row = 1;
351 prop.id = WS_XML_READER_PROPERTY_ROW;
352 prop.value = &row;
353 prop.valueSize = sizeof(row);
354 hr = WsCreateReader( &prop, 1, &reader, NULL );
355 ok( hr == E_INVALIDARG, "got %08x\n", hr );
357 column = 1;
358 prop.id = WS_XML_READER_PROPERTY_COLUMN;
359 prop.value = &column;
360 prop.valueSize = sizeof(column);
361 hr = WsCreateReader( &prop, 1, &reader, NULL );
362 ok( hr == E_INVALIDARG, "got %08x\n", hr );
364 in_attr = TRUE;
365 prop.id = WS_XML_READER_PROPERTY_IN_ATTRIBUTE;
366 prop.value = &in_attr;
367 prop.valueSize = sizeof(in_attr);
368 hr = WsCreateReader( &prop, 1, &reader, NULL );
369 ok( hr == E_INVALIDARG, "got %08x\n", hr );
372 static void test_WsSetInput(void)
374 static char test1[] = {0xef,0xbb,0xbf,'<','a','/','>'};
375 static char test2[] = {'<','a','/','>'};
376 static char test3[] = {'<','!','-','-'};
377 static char test4[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"',
378 ' ','e','n','c','o','d','i','n','g','=','"','u','t','f','-','8','"','?','>'};
379 static char test5[] = {'<','?','x','m','l',' ','e','n','c','o','d','i','n','g','=',
380 '"','u','t','f','-','8','"','?','>'};
381 static char test6[] = {'<','?','x','m','l'};
382 static char test7[] = {'<','?','y','m','l'};
383 static char test8[] = {'<','?'};
384 static char test9[] = {'<','!'};
385 static char test10[] = {0xff,0xfe,'<',0,'a',0,'/',0,'>',0};
386 static char test11[] = {'<',0,'a',0,'/',0,'>',0};
387 static char test12[] = {'<',0,'!',0,'-',0,'-',0};
388 static char test13[] = {'<',0,'?',0};
389 static char test14[] = {'a','b'};
390 static char test15[] = {'a','b','c'};
391 static char test16[] = {'a',0};
392 static char test17[] = {'a',0,'b',0};
393 static char test18[] = {'<',0,'a',0,'b',0};
394 static char test19[] = {'<',0,'a',0};
395 static char test20[] = {0,'a','b'};
396 static char test21[] = {0,0};
397 static char test22[] = {0,0,0};
398 static char test23[] = {'<',0,'?',0,'x',0,'m',0,'l',0};
399 static char test24[] = {'<',0,'a',0,'>',0,'b',0,'<',0,'/',0,'>',0};
400 HRESULT hr;
401 WS_XML_READER *reader;
402 WS_XML_READER_PROPERTY prop;
403 WS_XML_READER_TEXT_ENCODING enc;
404 WS_XML_READER_BUFFER_INPUT input;
405 WS_XML_TEXT_NODE *text;
406 WS_XML_UTF8_TEXT *utf8;
407 WS_CHARSET charset;
408 const WS_XML_NODE *node;
409 ULONG i, size, max_depth;
410 BOOL found;
411 static const struct
413 void *data;
414 ULONG size;
415 HRESULT hr;
416 WS_CHARSET charset;
417 int todo;
419 tests[] =
421 { test1, sizeof(test1), S_OK, WS_CHARSET_UTF8 },
422 { test2, sizeof(test2), S_OK, WS_CHARSET_UTF8 },
423 { test3, sizeof(test3), S_OK, WS_CHARSET_UTF8 },
424 { test4, sizeof(test4), S_OK, WS_CHARSET_UTF8 },
425 { test5, sizeof(test5), WS_E_INVALID_FORMAT, 0, 1 },
426 { test6, sizeof(test6), WS_E_INVALID_FORMAT, 0, 1 },
427 { test7, sizeof(test7), WS_E_INVALID_FORMAT, 0, 1 },
428 { test8, sizeof(test8), WS_E_INVALID_FORMAT, 0 },
429 { test9, sizeof(test9), WS_E_INVALID_FORMAT, 0 },
430 { test10, sizeof(test10), S_OK, WS_CHARSET_UTF16LE },
431 { test11, sizeof(test11), S_OK, WS_CHARSET_UTF16LE },
432 { test12, sizeof(test12), S_OK, WS_CHARSET_UTF16LE },
433 { test13, sizeof(test13), WS_E_INVALID_FORMAT, 0, 1 },
434 { test14, sizeof(test14), WS_E_INVALID_FORMAT, 0 },
435 { test15, sizeof(test15), S_OK, WS_CHARSET_UTF8 },
436 { test16, sizeof(test16), WS_E_INVALID_FORMAT, 0 },
437 { test17, sizeof(test17), S_OK, WS_CHARSET_UTF8 },
438 { test18, sizeof(test18), S_OK, WS_CHARSET_UTF16LE },
439 { test19, sizeof(test19), S_OK, WS_CHARSET_UTF16LE },
440 { test20, sizeof(test20), S_OK, WS_CHARSET_UTF8 },
441 { test21, sizeof(test21), WS_E_INVALID_FORMAT, 0 },
442 { test22, sizeof(test22), S_OK, WS_CHARSET_UTF8 },
443 { test23, sizeof(test23), WS_E_INVALID_FORMAT, 0, 1 },
446 hr = WsCreateReader( NULL, 0, &reader, NULL );
447 ok( hr == S_OK, "got %08x\n", hr );
449 hr = WsSetInput( NULL, NULL, NULL, NULL, 0, NULL );
450 ok( hr == E_INVALIDARG, "got %08x\n", hr );
452 node = NULL;
453 hr = WsGetReaderNode( reader, &node, NULL );
454 ok( hr == S_OK, "got %08x\n", hr );
455 ok( node != NULL, "node not set\n" );
456 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
458 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
459 enc.charSet = WS_CHARSET_UTF8;
461 input.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
462 input.encodedData = (void *)data1;
463 input.encodedDataSize = sizeof(data1) - 1;
465 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
466 ok( hr == S_OK, "got %08x\n", hr );
468 node = NULL;
469 hr = WsGetReaderNode( reader, &node, NULL );
470 ok( hr == S_OK, "got %08x\n", hr );
471 ok( node != NULL, "node not set\n" );
472 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
474 /* multiple calls are allowed */
475 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
476 ok( hr == S_OK, "got %08x\n", hr );
478 /* charset is detected by WsSetInput */
479 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
480 enc.charSet = WS_CHARSET_AUTO;
482 for (i = 0; i < ARRAY_SIZE( tests ); i++)
484 input.encodedData = tests[i].data;
485 input.encodedDataSize = tests[i].size;
486 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
487 ok( hr == S_OK, "%u: got %08x\n", i, hr );
489 charset = 0xdeadbeef;
490 size = sizeof(charset);
491 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
492 todo_wine_if (tests[i].todo)
494 ok( hr == tests[i].hr, "%u: got %08x expected %08x\n", i, hr, tests[i].hr );
495 if (hr == S_OK)
496 ok( charset == tests[i].charset, "%u: got %u expected %u\n", i, charset, tests[i].charset );
500 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
501 enc.charSet = WS_CHARSET_UTF8;
503 /* reader properties can be set with WsSetInput */
504 max_depth = 16;
505 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
506 prop.value = &max_depth;
507 prop.valueSize = sizeof(max_depth);
508 hr = WsSetInput( reader, &enc.encoding, &input.input, &prop, 1, NULL );
509 ok( hr == S_OK, "got %08x\n", hr );
511 max_depth = 0xdeadbeef;
512 size = sizeof(max_depth);
513 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
514 ok( hr == S_OK, "got %08x\n", hr );
515 ok( max_depth == 16, "got %u\n", max_depth );
517 /* show that the reader converts text to UTF-8 */
518 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
519 enc.charSet = WS_CHARSET_UTF16LE;
520 input.encodedData = (void *)test24;
521 input.encodedDataSize = sizeof(test24);
522 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
523 ok( hr == S_OK, "got %08x\n", hr );
525 found = -1;
526 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
527 ok( hr == S_OK, "got %08x\n", hr );
528 if (hr == S_OK)
530 ok( found == TRUE, "got %d\n", found );
532 hr = WsReadStartElement( reader, NULL );
533 ok( hr == S_OK, "got %08x\n", hr );
535 hr = WsGetReaderNode( reader, &node, NULL );
536 ok( hr == S_OK, "got %08x\n", hr );
537 text = (WS_XML_TEXT_NODE *)node;
538 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
539 ok( text->text != NULL, "text not set\n" );
540 utf8 = (WS_XML_UTF8_TEXT *)text->text;
541 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
542 ok( utf8->value.length == 1, "got %u\n", utf8->value.length );
543 ok( utf8->value.bytes[0] == 'b', "wrong data\n" );
545 WsFreeReader( reader );
548 static void test_WsSetInputToBuffer(void)
550 HRESULT hr;
551 WS_HEAP *heap;
552 WS_XML_BUFFER *buffer;
553 WS_XML_READER *reader;
554 WS_XML_READER_PROPERTY prop;
555 const WS_XML_NODE *node;
556 ULONG size, max_depth;
558 hr = WsCreateReader( NULL, 0, &reader, NULL );
559 ok( hr == S_OK, "got %08x\n", hr );
561 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
562 ok( hr == S_OK, "got %08x\n", hr );
564 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
565 ok( hr == S_OK, "got %08x\n", hr );
567 hr = WsSetInputToBuffer( NULL, NULL, NULL, 0, NULL );
568 ok( hr == E_INVALIDARG, "got %08x\n", hr );
570 hr = WsSetInputToBuffer( reader, NULL, NULL, 0, NULL );
571 ok( hr == E_INVALIDARG, "got %08x\n", hr );
573 node = NULL;
574 hr = WsGetReaderNode( reader, &node, NULL );
575 ok( hr == S_OK, "got %08x\n", hr );
576 ok( node != NULL, "node not set\n" );
577 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
579 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
580 ok( hr == S_OK, "got %08x\n", hr );
582 node = NULL;
583 hr = WsGetReaderNode( reader, &node, NULL );
584 ok( hr == S_OK, "got %08x\n", hr );
585 ok( node != NULL, "node not set\n" );
586 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
588 /* multiple calls are allowed */
589 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
590 ok( hr == S_OK, "got %08x\n", hr );
592 /* reader properties can be set with WsSetInputToBuffer */
593 max_depth = 16;
594 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
595 prop.value = &max_depth;
596 prop.valueSize = sizeof(max_depth);
597 hr = WsSetInputToBuffer( reader, buffer, &prop, 1, NULL );
598 ok( hr == S_OK, "got %08x\n", hr );
600 max_depth = 0xdeadbeef;
601 size = sizeof(max_depth);
602 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
603 ok( hr == S_OK, "got %08x\n", hr );
604 ok( max_depth == 16, "got %u\n", max_depth );
606 WsFreeReader( reader );
607 WsFreeHeap( heap );
610 static void test_WsFillReader(void)
612 HRESULT hr;
613 WS_XML_READER *reader;
614 const WS_XML_NODE *node;
616 /* what happens of we don't call WsFillReader? */
617 hr = WsCreateReader( NULL, 0, &reader, NULL );
618 ok( hr == S_OK, "got %08x\n", hr );
620 node = NULL;
621 hr = WsGetReaderNode( reader, &node, NULL );
622 ok( hr == S_OK, "got %08x\n", hr );
623 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
625 hr = set_input( reader, data1, sizeof(data1) - 1 );
626 ok( hr == S_OK, "got %08x\n", hr );
628 node = NULL;
629 hr = WsGetReaderNode( reader, &node, NULL );
630 ok( hr == S_OK, "got %08x\n", hr );
631 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
633 hr = WsReadNode( reader, NULL );
634 ok( hr == S_OK, "got %08x\n", hr );
636 node = NULL;
637 hr = WsGetReaderNode( reader, &node, NULL );
638 ok( hr == S_OK, "got %08x\n", hr );
639 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
640 WsFreeReader( reader );
642 hr = WsCreateReader( NULL, 0, &reader, NULL );
643 ok( hr == S_OK, "got %08x\n", hr );
645 hr = set_input( reader, data1, sizeof(data1) - 1 );
646 ok( hr == S_OK, "got %08x\n", hr );
648 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
649 ok( hr == S_OK, "got %08x\n", hr );
651 hr = set_input( reader, data1, sizeof(data1) - 1 );
652 ok( hr == S_OK, "got %08x\n", hr );
654 node = NULL;
655 hr = WsGetReaderNode( reader, &node, NULL );
656 ok( hr == S_OK, "got %08x\n", hr );
657 ok( node != NULL, "node not set\n" );
658 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
660 hr = WsFillReader( NULL, sizeof(data1) - 1, NULL, NULL );
661 ok( hr == E_INVALIDARG, "got %08x\n", hr );
663 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
664 ok( hr == S_OK, "got %08x\n", hr );
666 node = NULL;
667 hr = WsGetReaderNode( reader, &node, NULL );
668 ok( hr == S_OK, "got %08x\n", hr );
669 ok( node != NULL, "node not set\n" );
670 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
672 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
673 ok( hr == S_OK, "got %08x\n", hr );
675 /* min_size larger than input size */
676 hr = WsFillReader( reader, sizeof(data1), NULL, NULL );
677 ok( hr == S_OK, "got %08x\n", hr );
678 WsFreeReader( reader );
681 static void test_WsReadToStartElement(void)
683 HRESULT hr;
684 WS_XML_READER *reader;
685 const WS_XML_NODE *node, *node2;
686 int found;
688 hr = WsCreateReader( NULL, 0, &reader, NULL );
689 ok( hr == S_OK, "got %08x\n", hr );
691 hr = set_input( reader, data1, sizeof(data1) - 1 );
692 ok( hr == S_OK, "got %08x\n", hr );
694 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
695 ok( hr == S_OK, "got %08x\n", hr );
697 hr = WsGetReaderNode( reader, &node, NULL );
698 ok( hr == S_OK, "got %08x\n", hr );
699 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
701 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
702 ok( hr == S_OK, "got %08x\n", hr );
704 hr = WsReadToStartElement( NULL, NULL, NULL, NULL, NULL );
705 ok( hr == E_INVALIDARG, "got %08x\n", hr );
707 found = -1;
708 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
709 ok( hr == S_OK, "got %08x\n", hr );
710 ok( found == FALSE, "got %d\n", found );
712 hr = WsGetReaderNode( reader, &node, NULL );
713 ok( hr == S_OK, "got %08x\n", hr );
714 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
716 hr = set_input( reader, data2, sizeof(data2) - 1 );
717 ok( hr == S_OK, "got %08x\n", hr );
719 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
720 ok( hr == S_OK, "got %08x\n", hr );
722 hr = WsGetReaderNode( reader, &node, NULL );
723 ok( hr == S_OK, "got %08x\n", hr );
724 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
726 found = -1;
727 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
728 ok( hr == S_OK, "got %08x\n", hr );
729 ok( found == TRUE, "got %d\n", found );
731 hr = WsGetReaderNode( reader, &node, NULL );
732 ok( hr == S_OK, "got %08x\n", hr );
733 if (node)
735 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
737 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
738 ok( elem->prefix != NULL, "prefix not set\n" );
739 if (elem->prefix)
741 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
743 ok( elem->localName != NULL, "localName not set\n" );
744 if (elem->localName)
746 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
747 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
749 ok( elem->ns != NULL, "ns not set\n" );
750 if (elem->ns)
752 ok( !elem->ns->length, "got %u\n", elem->ns->length );
754 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
755 ok( elem->attributes == NULL, "attributes set\n" );
756 ok( !elem->isEmpty, "isEmpty not zero\n" );
759 found = -1;
760 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
761 ok( hr == S_OK, "got %08x\n", hr );
762 ok( found == TRUE, "got %d\n", found );
764 node2 = NULL;
765 hr = WsGetReaderNode( reader, &node2, NULL );
766 ok( hr == S_OK, "got %08x\n", hr );
767 ok( node2 == node, "different node\n" );
769 hr = set_input( reader, data3, sizeof(data3) - 1 );
770 ok( hr == S_OK, "got %08x\n", hr );
772 hr = WsFillReader( reader, sizeof(data3) - 1, NULL, NULL );
773 ok( hr == S_OK, "got %08x\n", hr );
775 found = -1;
776 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
777 ok( hr == S_OK, "got %08x\n", hr );
778 ok( found == TRUE, "got %d\n", found );
780 hr = WsGetReaderNode( reader, &node, NULL );
781 ok( hr == S_OK, "got %08x\n", hr );
782 if (node)
784 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
786 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
787 ok( elem->localName != NULL, "localName not set\n" );
788 if (elem->localName)
790 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
791 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
795 hr = set_input( reader, data4, sizeof(data4) - 1 );
796 ok( hr == S_OK, "got %08x\n", hr );
798 hr = WsFillReader( reader, sizeof(data4) - 1, NULL, NULL );
799 ok( hr == S_OK, "got %08x\n", hr );
801 found = -1;
802 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
803 ok( hr == S_OK, "got %08x\n", hr );
804 ok( found == TRUE, "got %d\n", found );
805 WsFreeReader( reader );
808 static void test_WsReadStartElement(void)
810 HRESULT hr;
811 WS_XML_READER *reader;
812 const WS_XML_NODE *node, *node2;
813 int found;
815 hr = WsCreateReader( NULL, 0, &reader, NULL );
816 ok( hr == S_OK, "got %08x\n", hr );
818 hr = set_input( reader, data2, sizeof(data2) - 1 );
819 ok( hr == S_OK, "got %08x\n", hr );
821 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
822 ok( hr == S_OK, "got %08x\n", hr );
824 found = -1;
825 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
826 ok( hr == S_OK, "got %08x\n", hr );
827 ok( found == TRUE, "got %d\n", found );
829 hr = WsReadStartElement( NULL, NULL );
830 ok( hr == E_INVALIDARG, "got %08x\n", hr );
832 hr = WsGetReaderNode( reader, &node, NULL );
833 ok( hr == S_OK, "got %08x\n", hr );
834 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
836 hr = WsReadStartElement( reader, NULL );
837 ok( hr == S_OK, "got %08x\n", hr );
839 hr = WsGetReaderNode( reader, &node, NULL );
840 ok( hr == S_OK, "got %08x\n", hr );
841 if (node)
843 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
844 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
845 ok( text->text != NULL, "text not set\n" );
846 if (text->text)
848 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
849 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
850 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
851 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong data\n" );
855 hr = WsReadStartElement( reader, NULL );
856 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
858 node2 = NULL;
859 hr = WsGetReaderNode( reader, &node2, NULL );
860 ok( hr == S_OK, "got %08x\n", hr );
861 ok( node2 == node, "different node\n" );
863 hr = set_input( reader, data8, sizeof(data8) - 1 );
864 ok( hr == S_OK, "got %08x\n", hr );
866 hr = WsFillReader( reader, sizeof(data8) - 1, NULL, NULL );
867 ok( hr == S_OK, "got %08x\n", hr );
869 found = -1;
870 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
871 ok( hr == S_OK, "got %08x\n", hr );
872 ok( found == TRUE, "got %d\n", found );
874 hr = WsGetReaderNode( reader, &node, NULL );
875 ok( hr == S_OK, "got %08x\n", hr );
876 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
878 hr = WsGetReaderNode( reader, &node, NULL );
879 ok( hr == S_OK, "got %08x\n", hr );
880 if (node)
882 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
883 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
884 ok( !memcmp( elem->localName->bytes, "node1", 5), "wrong name\n" );
887 hr = WsReadStartElement( reader, NULL );
888 ok( hr == S_OK, "got %08x\n", hr );
890 hr = WsGetReaderNode( reader, &node, NULL );
891 ok( hr == S_OK, "got %08x\n", hr );
892 if (node)
894 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
895 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
896 ok( !memcmp( elem->localName->bytes, "node2", 5), "wrong name\n" );
899 hr = WsReadNode( reader, NULL );
900 ok( hr == S_OK, "got %08x\n", hr );
902 hr = WsGetReaderNode( reader, &node, NULL );
903 ok( hr == S_OK, "got %08x\n", hr );
904 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
906 hr = WsReadNode( reader, NULL );
907 ok( hr == S_OK, "got %08x\n", hr );
909 hr = WsGetReaderNode( reader, &node, NULL );
910 ok( hr == S_OK, "got %08x\n", hr );
911 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
913 hr = WsReadEndElement( reader, NULL );
914 ok( hr == S_OK, "got %08x\n", hr );
916 hr = WsGetReaderNode( reader, &node, NULL );
917 ok( hr == S_OK, "got %08x\n", hr );
918 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
920 /* WsReadEndElement advances reader to EOF */
921 hr = WsReadEndElement( reader, NULL );
922 ok( hr == S_OK, "got %08x\n", hr );
924 hr = WsGetReaderNode( reader, &node, NULL );
925 ok( hr == S_OK, "got %08x\n", hr );
926 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
928 hr = WsReadEndElement( reader, NULL );
929 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
931 hr = set_input( reader, data3, sizeof(data3) - 1 );
932 ok( hr == S_OK, "got %08x\n", hr );
934 hr = WsReadStartElement( reader, NULL );
935 ok( hr == S_OK, "got %08x\n", hr );
937 node = NULL;
938 hr = WsGetReaderNode( reader, &node, NULL );
939 ok( hr == S_OK, "got %08x\n", hr );
940 if (node)
942 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
943 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
944 ok( text->text != NULL, "text not set\n" );
945 if (text->text)
947 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
948 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
949 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
950 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong data\n" );
954 hr = set_input( reader, " <text>test</text>", sizeof(" <text>test</text>") - 1 );
955 ok( hr == S_OK, "got %08x\n", hr );
957 hr = WsReadStartElement( reader, NULL );
958 ok( hr == S_OK, "got %08x\n", hr );
960 node = NULL;
961 hr = WsGetReaderNode( reader, &node, NULL );
962 ok( hr == S_OK, "got %08x\n", hr );
963 if (node)
965 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
966 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
967 ok( text->text != NULL, "text not set\n" );
968 if (text->text)
970 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
971 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
972 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
973 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong data\n" );
977 WsFreeReader( reader );
980 static void test_WsReadEndElement(void)
982 HRESULT hr;
983 WS_XML_READER *reader;
984 const WS_XML_NODE *node;
985 int found;
987 hr = WsCreateReader( NULL, 0, &reader, NULL );
988 ok( hr == S_OK, "got %08x\n", hr );
990 hr = set_input( reader, data2, sizeof(data2) - 1 );
991 ok( hr == S_OK, "got %08x\n", hr );
993 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
994 ok( hr == S_OK, "got %08x\n", hr );
996 hr = WsReadEndElement( reader, NULL );
997 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
999 hr = set_input( reader, data2, sizeof(data2) - 1 );
1000 ok( hr == S_OK, "got %08x\n", hr );
1002 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
1003 ok( hr == S_OK, "got %08x\n", hr );
1005 hr = WsReadNode( reader, NULL );
1006 ok( hr == S_OK, "got %08x\n", hr );
1008 hr = WsGetReaderNode( reader, &node, NULL );
1009 ok( hr == S_OK, "got %08x\n", hr );
1010 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1012 hr = WsReadNode( reader, NULL );
1013 ok( hr == S_OK, "got %08x\n", hr );
1015 hr = WsGetReaderNode( reader, &node, NULL );
1016 ok( hr == S_OK, "got %08x\n", hr );
1017 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
1019 hr = WsReadNode( reader, NULL );
1020 ok( hr == S_OK, "got %08x\n", hr );
1022 hr = WsGetReaderNode( reader, &node, NULL );
1023 ok( hr == S_OK, "got %08x\n", hr );
1024 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1026 hr = WsReadNode( reader, NULL );
1027 ok( hr == S_OK, "got %08x\n", hr );
1029 hr = WsGetReaderNode( reader, &node, NULL );
1030 ok( hr == S_OK, "got %08x\n", hr );
1031 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1033 hr = set_input( reader, data2, sizeof(data2) - 1 );
1034 ok( hr == S_OK, "got %08x\n", hr );
1036 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
1037 ok( hr == S_OK, "got %08x\n", hr );
1039 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1040 ok( hr == S_OK, "got %08x\n", hr );
1042 hr = WsReadStartElement( reader, NULL );
1043 ok( hr == S_OK, "got %08x\n", hr );
1045 hr = WsGetReaderNode( reader, &node, NULL );
1046 ok( hr == S_OK, "got %08x\n", hr );
1047 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
1049 hr = WsReadNode( reader, NULL );
1050 ok( hr == S_OK, "got %08x\n", hr );
1052 hr = WsGetReaderNode( reader, &node, NULL );
1053 ok( hr == S_OK, "got %08x\n", hr );
1054 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1056 /* WsReadEndElement advances reader to EOF */
1057 hr = WsReadEndElement( reader, NULL );
1058 ok( hr == S_OK, "got %08x\n", hr );
1060 hr = WsGetReaderNode( reader, &node, NULL );
1061 ok( hr == S_OK, "got %08x\n", hr );
1062 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1064 hr = WsReadEndElement( reader, NULL );
1065 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1067 hr = set_input( reader, data5, sizeof(data5) - 1 );
1068 ok( hr == S_OK, "got %08x\n", hr );
1070 hr = WsFillReader( reader, sizeof(data5) - 1, NULL, NULL );
1071 ok( hr == S_OK, "got %08x\n", hr );
1073 hr = WsReadEndElement( reader, NULL );
1074 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1076 hr = set_input( reader, data10, sizeof(data10) - 1 );
1077 ok( hr == S_OK, "got %08x\n", hr );
1079 hr = WsFillReader( reader, sizeof(data10) - 1, NULL, NULL );
1080 ok( hr == S_OK, "got %08x\n", hr );
1082 hr = WsReadNode( reader, NULL );
1083 ok( hr == S_OK, "got %08x\n", hr );
1085 hr = WsGetReaderNode( reader, &node, NULL );
1086 ok( hr == S_OK, "got %08x\n", hr );
1087 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1089 hr = WsReadEndElement( reader, NULL );
1090 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1092 hr = set_input( reader, "<a></A>", sizeof("<a></A>") - 1 );
1093 ok( hr == S_OK, "got %08x\n", hr );
1095 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1096 ok( hr == S_OK, "got %08x\n", hr );
1098 found = -1;
1099 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1100 ok( hr == S_OK, "got %08x\n", hr );
1101 ok( found == TRUE, "got %d\n", found );
1103 hr = WsGetReaderNode( reader, &node, NULL );
1104 ok( hr == S_OK, "got %08x\n", hr );
1105 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1107 hr = WsReadEndElement( reader, NULL );
1108 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1110 hr = set_input( reader, "<a></a>", sizeof("<a></a>") - 1 );
1111 ok( hr == S_OK, "got %08x\n", hr );
1113 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1114 ok( hr == S_OK, "got %08x\n", hr );
1116 found = -1;
1117 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1118 ok( hr == S_OK, "got %08x\n", hr );
1119 ok( found == TRUE, "got %d\n", found );
1121 hr = WsGetReaderNode( reader, &node, NULL );
1122 ok( hr == S_OK, "got %08x\n", hr );
1123 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1125 hr = WsReadStartElement( reader, NULL );
1126 ok( hr == S_OK, "got %08x\n", hr );
1128 hr = WsGetReaderNode( reader, &node, NULL );
1129 ok( hr == S_OK, "got %08x\n", hr );
1130 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1132 hr = WsReadEndElement( reader, NULL );
1133 ok( hr == S_OK, "got %08x\n", hr );
1135 hr = WsGetReaderNode( reader, &node, NULL );
1136 ok( hr == S_OK, "got %08x\n", hr );
1137 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1139 hr = set_input( reader, "<a/>", sizeof("<a/>") - 1 );
1140 ok( hr == S_OK, "got %08x\n", hr );
1142 hr = WsFillReader( reader, sizeof("<a/>") - 1, NULL, NULL );
1143 ok( hr == S_OK, "got %08x\n", hr );
1145 found = -1;
1146 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1147 ok( hr == S_OK, "got %08x\n", hr );
1148 ok( found == TRUE, "got %d\n", found );
1150 hr = WsGetReaderNode( reader, &node, NULL );
1151 ok( hr == S_OK, "got %08x\n", hr );
1152 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1154 hr = WsReadStartElement( reader, NULL );
1155 ok( hr == S_OK, "got %08x\n", hr );
1157 hr = WsGetReaderNode( reader, &node, NULL );
1158 ok( hr == S_OK, "got %08x\n", hr );
1159 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1161 hr = WsReadEndElement( reader, NULL );
1162 ok( hr == S_OK, "got %08x\n", hr );
1164 WsFreeReader( reader );
1167 static void test_WsReadNode(void)
1169 static const char str1[] = "<a>";
1170 static const char str2[] = "< a>";
1171 static const char str3[] = "<a >";
1172 static const char str4[] = "<<a>>";
1173 static const char str5[] = "<>";
1174 static const char str6[] = "</a>";
1175 static const char str7[] = " <a>";
1176 static const char str8[] = "<?xml>";
1177 static const char str9[] = "<?xml?>";
1178 static const char str10[] = "<?xml ?>";
1179 static const char str11[] = "<?xml version=\"1.0\"?>";
1180 static const char str12[] = "<text>test</text>";
1181 static const char str13[] = "<?xml version=\"1.0\"?><text>test</text>";
1182 static const char str14[] = "";
1183 static const char str15[] = "<!--";
1184 static const char str16[] = "<!---->";
1185 static const char str17[] = "<!--comment-->";
1186 HRESULT hr;
1187 WS_XML_READER *reader;
1188 WS_XML_DICTIONARY *dict;
1189 const WS_XML_NODE *node;
1190 unsigned int i;
1191 int found;
1192 static const struct
1194 const char *text;
1195 HRESULT hr;
1196 WS_XML_NODE_TYPE type;
1197 int todo;
1199 tests[] =
1201 { str1, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1202 { str2, WS_E_INVALID_FORMAT, 0 },
1203 { str3, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1204 { str4, WS_E_INVALID_FORMAT, 0 },
1205 { str5, WS_E_INVALID_FORMAT, 0 },
1206 { str6, WS_E_INVALID_FORMAT, 0 },
1207 { str7, S_OK, WS_XML_NODE_TYPE_TEXT },
1208 { str8, WS_E_INVALID_FORMAT, 0 },
1209 { str9, WS_E_INVALID_FORMAT, 0 },
1210 { str10, WS_E_INVALID_FORMAT, 0, 1 },
1211 { str11, S_OK, WS_XML_NODE_TYPE_EOF },
1212 { str12, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1213 { str13, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1214 { str14, WS_E_INVALID_FORMAT, 0, 1 },
1215 { str15, WS_E_INVALID_FORMAT, 0 },
1216 { str16, S_OK, WS_XML_NODE_TYPE_COMMENT },
1217 { str17, S_OK, WS_XML_NODE_TYPE_COMMENT },
1220 hr = WsCreateReader( NULL, 0, &reader, NULL );
1221 ok( hr == S_OK, "got %08x\n", hr );
1223 for (i = 0; i < ARRAY_SIZE( tests ); i++)
1225 hr = set_input( reader, tests[i].text, strlen(tests[i].text) );
1226 ok( hr == S_OK, "got %08x\n", hr );
1228 hr = WsFillReader( reader, strlen(tests[i].text), NULL, NULL );
1229 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1231 hr = WsReadNode( reader, NULL );
1232 todo_wine_if (tests[i].todo)
1233 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
1234 if (hr == S_OK)
1236 node = NULL;
1237 hr = WsGetReaderNode( reader, &node, NULL );
1238 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1239 ok( node != NULL, "%u: node not set\n", i );
1240 if (node)
1242 todo_wine_if (tests[i].todo)
1243 ok( node->nodeType == tests[i].type, "%u: got %u\n", i, node->nodeType );
1248 hr = set_input( reader, data6, sizeof(data6) - 1 );
1249 ok( hr == S_OK, "got %08x\n", hr );
1251 hr = WsFillReader( reader, sizeof(data6) - 1, NULL, NULL );
1252 ok( hr == S_OK, "got %08x\n", hr );
1254 found = -1;
1255 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1256 ok( hr == S_OK, "got %08x\n", hr );
1257 ok( found == TRUE, "got %d\n", found );
1259 hr = WsGetReaderNode( reader, &node, NULL );
1260 ok( hr == S_OK, "got %08x\n", hr );
1261 if (node)
1263 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
1264 WS_XML_ATTRIBUTE *attr;
1265 WS_XML_UTF8_TEXT *text;
1267 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1268 ok( elem->prefix != NULL, "prefix not set\n" );
1269 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
1270 ok( elem->prefix->bytes == NULL, "bytes set\n" );
1271 ok( elem->localName != NULL, "localName not set\n" );
1272 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
1273 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
1274 ok( elem->ns != NULL, "ns not set\n" );
1275 ok( !elem->ns->length, "got %u\n", elem->ns->length );
1276 ok( elem->ns->bytes != NULL, "bytes not set\n" );
1277 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
1278 ok( elem->attributes != NULL, "attributes not set\n" );
1279 ok( !elem->isEmpty, "isEmpty not zero\n" );
1281 attr = elem->attributes[0];
1282 ok( !attr->singleQuote, "got %u\n", attr->singleQuote );
1283 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1284 ok( attr->prefix != NULL, "prefix not set\n" );
1285 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1286 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1287 ok( attr->localName != NULL, "localName not set\n" );
1288 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
1289 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
1290 ok( attr->ns != NULL, "ns not set\n" );
1291 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1292 ok( attr->ns->bytes == NULL, "bytes set\n" );
1293 ok( attr->value != NULL, "value not set\n" );
1295 text = (WS_XML_UTF8_TEXT *)attr->value;
1296 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1297 ok( text->value.length == 5, "got %u\n", text->value.length );
1298 ok( !memcmp( text->value.bytes, "value", 5 ), "wrong data\n" );
1300 attr = elem->attributes[1];
1301 ok( attr->singleQuote == 1, "got %u\n", attr->singleQuote );
1302 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1303 ok( attr->prefix != NULL, "prefix not set\n" );
1304 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1305 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1306 ok( attr->localName != NULL, "localName not set\n" );
1307 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
1308 ok( !memcmp( attr->localName->bytes, "attr2", 5 ), "wrong data\n" );
1309 ok( attr->ns != NULL, "ns not set\n" );
1310 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1311 ok( attr->ns->bytes == NULL, "bytes set\n" );
1312 ok( attr->value != NULL, "value not set\n" );
1314 text = (WS_XML_UTF8_TEXT *)attr->value;
1315 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1316 ok( text->value.length == 6, "got %u\n", text->value.length );
1317 ok( !memcmp( text->value.bytes, "value2", 6 ), "wrong data\n" );
1320 hr = set_input( reader, data7, sizeof(data7) - 1 );
1321 ok( hr == S_OK, "got %08x\n", hr );
1323 hr = WsFillReader( reader, sizeof(data7) - 1, NULL, NULL );
1324 ok( hr == S_OK, "got %08x\n", hr );
1326 hr = WsReadNode( reader, NULL );
1327 ok( hr == S_OK, "got %08x\n", hr );
1329 hr = WsGetReaderNode( reader, &node, NULL );
1330 ok( hr == S_OK, "got %08x\n", hr );
1331 if (node)
1333 WS_XML_COMMENT_NODE *comment = (WS_XML_COMMENT_NODE *)node;
1335 ok( comment->node.nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", comment->node.nodeType );
1336 ok( comment->value.length == 9, "got %u\n", comment->value.length );
1337 ok( !memcmp( comment->value.bytes, " comment ", 9 ), "wrong data\n" );
1340 dict = (WS_XML_DICTIONARY *)0xdeadbeef;
1341 hr = WsGetDictionary( WS_ENCODING_XML_UTF8, &dict, NULL );
1342 ok( hr == S_OK, "got %08x\n", hr );
1343 ok( dict == NULL, "got %p\n", dict );
1345 dict = NULL;
1346 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_1, &dict, NULL );
1347 ok( hr == S_OK, "got %08x\n", hr );
1348 ok( dict != NULL, "dict not set\n" );
1350 dict = NULL;
1351 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_SESSION_1, &dict, NULL );
1352 ok( hr == S_OK, "got %08x\n", hr );
1353 ok( dict != NULL, "dict not set\n" );
1355 WsFreeReader( reader );
1358 static void prepare_type_test( WS_XML_READER *reader, const char *data, ULONG size )
1360 HRESULT hr;
1362 hr = set_input( reader, data, size );
1363 ok( hr == S_OK, "got %08x\n", hr );
1365 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1366 ok( hr == S_OK, "got %08x\n", hr );
1368 hr = WsReadStartElement( reader, NULL );
1369 ok( hr == S_OK, "got %08x\n", hr );
1372 static void test_WsReadType(void)
1374 static const GUID guid = {0,0,0,{0,0,0,0,0,0,0,0xa1}};
1375 static const char utf8[] = {'<','t','>',0xe2,0x80,0x99,'<','/','t','>'};
1376 HRESULT hr;
1377 WS_XML_READER *reader;
1378 WS_HEAP *heap;
1379 enum { ONE = 1, TWO = 2 };
1380 WS_XML_STRING one = { 3, (BYTE *)"ONE" }, two = { 3, (BYTE *)"TWO" }, val_xmlstr, *ptr_xmlstr;
1381 WS_ENUM_VALUE enum_values[] = { { ONE, &one }, { TWO, &two } };
1382 WS_ENUM_DESCRIPTION enum_desc;
1383 int val_enum, *ptr_enum;
1384 WCHAR *val_str;
1385 BOOL val_bool, *ptr_bool;
1386 INT8 val_int8, *ptr_int8;
1387 INT16 val_int16, *ptr_int16;
1388 INT32 val_int32, *ptr_int32;
1389 INT64 val_int64, *ptr_int64;
1390 UINT8 val_uint8, *ptr_uint8;
1391 UINT16 val_uint16, *ptr_uint16;
1392 UINT32 val_uint32, *ptr_uint32;
1393 UINT64 val_uint64, *ptr_uint64;
1394 GUID val_guid, *ptr_guid;
1395 WS_BYTES val_bytes, *ptr_bytes;
1396 WS_STRING val_string, *ptr_string;
1397 WS_UNIQUE_ID val_id, *ptr_id;
1398 WS_XML_QNAME val_qname, *ptr_qname;
1400 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1401 ok( hr == S_OK, "got %08x\n", hr );
1403 hr = WsCreateReader( NULL, 0, &reader, NULL );
1404 ok( hr == S_OK, "got %08x\n", hr );
1406 prepare_type_test( reader, data2, sizeof(data2) - 1 );
1407 hr = WsReadType( NULL, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1408 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1409 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1411 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1412 WS_READ_REQUIRED_POINTER, heap, &val_str, 0, NULL );
1413 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1415 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1416 WS_READ_REQUIRED_POINTER, heap, NULL, sizeof(val_str), NULL );
1417 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1419 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1420 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str) + 1, NULL );
1421 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1423 val_str = NULL;
1424 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1425 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1426 ok( hr == S_OK, "got %08x\n", hr );
1427 ok( val_str != NULL, "pointer not set\n" );
1428 if (val_str) ok( !wcscmp( val_str, L"test" ), "wrong data\n" );
1430 val_bool = -1;
1431 prepare_type_test( reader, "<t>true</t>", sizeof("<t>true</t>") - 1 );
1432 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1433 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1434 ok( hr == S_OK, "got %08x\n", hr );
1435 ok( val_bool == TRUE, "got %d\n", val_bool );
1437 val_bool = -1;
1438 prepare_type_test( reader, "<t>false</t>", sizeof("<t>false</t>") - 1 );
1439 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1440 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1441 ok( hr == S_OK, "got %08x\n", hr );
1442 ok( val_bool == FALSE, "got %d\n", val_bool );
1444 val_bool = -1;
1445 prepare_type_test( reader, "<t>FALSE</t>", sizeof("<t>FALSE</t>") - 1 );
1446 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1447 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1448 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1449 ok( val_bool == -1, "got %d\n", val_bool );
1451 val_bool = -1;
1452 prepare_type_test( reader, "<t>1</t>", sizeof("<t>1</t>") - 1 );
1453 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1454 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1455 ok( hr == S_OK, "got %08x\n", hr );
1456 ok( val_bool == TRUE, "got %d\n", val_bool );
1458 val_bool = -1;
1459 prepare_type_test( reader, "<t>2</t>", sizeof("<t>2</t>") - 1 );
1460 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1461 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1462 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1463 ok( val_bool == -1, "got %d\n", val_bool );
1465 val_bool = -1;
1466 prepare_type_test( reader, "<t>0</t>", sizeof("<t>0</t>") - 1 );
1467 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1468 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1469 ok( hr == S_OK, "got %08x\n", hr );
1470 ok( val_bool == FALSE, "got %d\n", val_bool );
1472 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1473 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1474 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1475 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1477 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1478 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1479 WS_READ_REQUIRED_POINTER, heap, &ptr_bool, sizeof(ptr_bool), NULL );
1480 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1482 val_int8 = 0;
1483 prepare_type_test( reader, "<t>-128</t>", sizeof("<t>-128</t>") - 1 );
1484 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1485 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1486 ok( hr == S_OK, "got %08x\n", hr );
1487 ok( val_int8 == -128, "got %d\n", val_int8 );
1489 prepare_type_test( reader, "<t> </t>", sizeof("<t> </t>") - 1 );
1490 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1491 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1492 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1494 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1495 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1496 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1497 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1499 prepare_type_test( reader, "<t>-</t>", sizeof("<t>-</t>") - 1 );
1500 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1501 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1502 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1504 val_int8 = -1;
1505 prepare_type_test( reader, "<t>-0</t>", sizeof("<t>-0</t>") - 1 );
1506 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1507 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1508 ok( hr == S_OK, "got %08x\n", hr );
1509 ok( !val_int8, "got %d\n", val_int8 );
1511 prepare_type_test( reader, "<t>-129</t>", sizeof("<t>-129</t>") - 1 );
1512 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1513 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1514 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1516 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1517 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1518 WS_READ_REQUIRED_POINTER, heap, &ptr_int8, sizeof(ptr_int8), NULL );
1519 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1521 val_int16 = 0;
1522 prepare_type_test( reader, "<t>-32768</t>", sizeof("<t>-32768</t>") - 1 );
1523 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1524 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1525 ok( hr == S_OK, "got %08x\n", hr );
1526 ok( val_int16 == -32768, "got %d\n", val_int16 );
1528 prepare_type_test( reader, "<t>-32769</t>", sizeof("<t>-32769</t>") - 1 );
1529 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1530 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1531 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1533 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1534 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1535 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1536 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1538 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1539 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1540 WS_READ_REQUIRED_POINTER, heap, &ptr_int16, sizeof(ptr_int16), NULL );
1541 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1543 val_int32 = 0;
1544 prepare_type_test( reader, "<t>-2147483648</t>", sizeof("<t>-2147483648</t>") - 1 );
1545 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1546 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1547 ok( hr == S_OK, "got %08x\n", hr );
1548 ok( val_int32 == -2147483647 - 1, "got %d\n", val_int32 );
1550 prepare_type_test( reader, "<t>-2147483649</t>", sizeof("<t>-2147483649</t>") - 1 );
1551 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1552 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1553 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1555 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1556 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1557 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1558 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1560 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1561 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1562 WS_READ_REQUIRED_POINTER, heap, &ptr_int32, sizeof(ptr_int32), NULL );
1563 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1565 val_int64 = 0;
1566 prepare_type_test( reader, "<t>-9223372036854775808</t>", sizeof("<t>-9223372036854775808</t>") - 1 );
1567 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1568 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1569 ok( hr == S_OK, "got %08x\n", hr );
1570 ok( val_int64 == -9223372036854775807 - 1, "wrong value\n" );
1572 prepare_type_test( reader, "<t>-9223372036854775809</t>", sizeof("<t>-9223372036854775809</t>") - 1 );
1573 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1574 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1575 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1577 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1578 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1579 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1580 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1582 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1583 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1584 WS_READ_REQUIRED_POINTER, heap, &ptr_int64, sizeof(ptr_int64), NULL );
1585 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1587 val_uint8 = 0;
1588 prepare_type_test( reader, "<t> 255 </t>", sizeof("<t> 255 </t>") - 1 );
1589 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1590 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1591 ok( hr == S_OK, "got %08x\n", hr );
1592 ok( val_uint8 == 255, "got %u\n", val_uint8 );
1594 prepare_type_test( reader, "<t>+255</t>", sizeof("<t>+255</t>") - 1 );
1595 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1596 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1597 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1599 prepare_type_test( reader, "<t>-255</t>", sizeof("<t>-255</t>") - 1 );
1600 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1601 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1602 todo_wine ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1604 prepare_type_test( reader, "<t>0xff</t>", sizeof("<t>0xff</t>") - 1 );
1605 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1606 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1607 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1609 prepare_type_test( reader, "<t>256</t>", sizeof("<t>256</t>") - 1 );
1610 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1611 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1612 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1614 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1615 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1616 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1617 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1619 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1620 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1621 WS_READ_REQUIRED_POINTER, heap, &ptr_uint8, sizeof(ptr_uint8), NULL );
1622 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1624 val_uint16 = 0;
1625 prepare_type_test( reader, "<t>65535</t>", sizeof("<t>65535</t>") - 1 );
1626 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1627 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1628 ok( hr == S_OK, "got %08x\n", hr );
1629 ok( val_uint16 == 65535, "got %u\n", val_uint16 );
1631 prepare_type_test( reader, "<t>65536</t>", sizeof("<t>65536</t>") - 1 );
1632 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1633 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1634 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1636 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1637 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1638 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1639 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1641 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1642 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1643 WS_READ_REQUIRED_POINTER, heap, &ptr_uint16, sizeof(ptr_uint16), NULL );
1644 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1646 val_uint32 = 0;
1647 prepare_type_test( reader, "<t>4294967295</t>", sizeof("<t>4294967295</t>") - 1 );
1648 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1649 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1650 ok( hr == S_OK, "got %08x\n", hr );
1651 ok( val_uint32 == ~0, "got %u\n", val_uint32 );
1653 prepare_type_test( reader, "<t>4294967296</t>", sizeof("<t>4294967296</t>") - 1 );
1654 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1655 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1656 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1658 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1659 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1660 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1661 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1663 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1664 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1665 WS_READ_REQUIRED_POINTER, heap, &ptr_uint32, sizeof(ptr_uint32), NULL );
1666 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1668 val_uint64 = 0;
1669 prepare_type_test( reader, "<t>18446744073709551615</t>", sizeof("<t>18446744073709551615</t>") - 1 );
1670 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1671 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1672 ok( hr == S_OK, "got %08x\n", hr );
1673 ok( val_uint64 == ~0, "wrong value\n" );
1675 prepare_type_test( reader, "<t>18446744073709551616</t>", sizeof("<t>18446744073709551616</t>") - 1 );
1676 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1677 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1678 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1680 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1681 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1682 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1683 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1685 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1686 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1687 WS_READ_REQUIRED_POINTER, heap, &ptr_uint64, sizeof(ptr_uint64), NULL );
1688 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1690 enum_desc.values = enum_values;
1691 enum_desc.valueCount = ARRAY_SIZE( enum_values );
1692 enum_desc.maxByteCount = 3;
1693 enum_desc.nameIndices = NULL;
1695 val_enum = 0;
1696 prepare_type_test( reader, "<t>ONE</t>", sizeof("<t>ONE</t>") - 1 );
1697 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1698 WS_READ_REQUIRED_VALUE, heap, &val_enum, sizeof(val_enum), NULL );
1699 ok( hr == S_OK, "got %08x\n", hr );
1700 ok( val_enum == 1, "got %d\n", val_enum );
1702 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1703 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1704 WS_READ_REQUIRED_VALUE, heap, &val_enum, sizeof(val_enum), NULL );
1705 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1707 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1708 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1709 WS_READ_REQUIRED_POINTER, heap, &ptr_enum, sizeof(ptr_enum), NULL );
1710 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1712 prepare_type_test( reader, "<t>{00000000-0000-0000-0000-000000000000}</t>",
1713 sizeof("<t>{00000000-0000-0000-0000-000000000000}</t>") - 1 );
1714 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1715 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1716 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1718 memset( &val_guid, 0xff, sizeof(val_guid) );
1719 prepare_type_test( reader, "<t> 00000000-0000-0000-0000-000000000000 </t>",
1720 sizeof("<t> 00000000-0000-0000-0000-000000000000 </t>") - 1 );
1721 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1722 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1723 ok( hr == S_OK, "got %08x\n", hr );
1724 ok( IsEqualGUID( &val_guid, &guid_null ), "wrong guid\n" );
1726 memset( &val_guid, 0, sizeof(val_guid) );
1727 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000a1</t>",
1728 sizeof("<t>00000000-0000-0000-0000-0000000000a1</t>") - 1 );
1729 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1730 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1731 ok( hr == S_OK, "got %08x\n", hr );
1732 ok( IsEqualGUID( &val_guid, &guid ), "wrong guid\n" );
1734 memset( &val_guid, 0, sizeof(val_guid) );
1735 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000A1</t>",
1736 sizeof("<t>00000000-0000-0000-0000-0000000000A1</t>") - 1 );
1737 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1738 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1739 ok( hr == S_OK, "got %08x\n", hr );
1740 ok( IsEqualGUID( &val_guid, &guid ), "wrong guid\n" );
1742 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1743 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1744 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1745 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1747 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1748 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1749 WS_READ_REQUIRED_POINTER, heap, &ptr_guid, sizeof(ptr_guid), NULL );
1750 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1752 memset( &val_bytes, 0, sizeof(val_bytes) );
1753 prepare_type_test( reader, "<t>dGVzdA==</t>", sizeof("<t>dGVzdA==</t>") - 1 );
1754 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1755 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1756 ok( hr == S_OK, "got %08x\n", hr );
1757 ok( val_bytes.length == 4, "got %u\n", val_bytes.length );
1758 ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" );
1760 memset( &val_bytes, 0, sizeof(val_bytes) );
1761 prepare_type_test( reader, "<t> dGVzdA== </t>", sizeof("<t> dGVzdA== </t>") - 1 );
1762 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1763 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1764 ok( hr == S_OK, "got %08x\n", hr );
1765 ok( val_bytes.length == 4, "got %u\n", val_bytes.length );
1766 ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" );
1768 prepare_type_test( reader, "<t>dGVzdA===</t>", sizeof("<t>dGVzdA===</t>") - 1 );
1769 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1770 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1771 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1773 val_bytes.length = 0xdeadbeef;
1774 val_bytes.bytes = (BYTE *)0xdeadbeef;
1775 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1776 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1777 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1778 ok( hr == S_OK, "got %08x\n", hr );
1779 ok( !val_bytes.length, "got %u\n", val_bytes.length );
1780 todo_wine ok( val_bytes.bytes != NULL, "got %p\n", val_bytes.bytes );
1782 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1783 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1784 WS_READ_REQUIRED_POINTER, heap, &ptr_bytes, sizeof(ptr_bytes), NULL );
1785 ok( hr == S_OK, "got %08x\n", hr );
1786 ok( !ptr_bytes->length, "got %u\n", ptr_bytes->length );
1787 todo_wine ok( ptr_bytes->bytes != NULL, "got %p\n", ptr_bytes->bytes );
1789 val_str = NULL;
1790 prepare_type_test( reader, utf8, sizeof(utf8) );
1791 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1792 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1793 ok( hr == S_OK, "got %08x\n", hr );
1794 ok( val_str != NULL, "pointer not set\n" );
1795 ok( !lstrcmpW( val_str, L"\x2019" ), "got %s\n", wine_dbgstr_w(val_str) );
1797 val_str = NULL;
1798 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1799 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1800 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1801 ok( hr == S_OK, "got %08x\n", hr );
1802 ok( val_str != NULL, "got %p\n", val_str );
1803 ok( !val_str[0], "got %s\n", wine_dbgstr_w(val_str) );
1805 memset( &val_xmlstr, 0, sizeof(val_xmlstr) );
1806 prepare_type_test( reader, "<t> test </t>", sizeof("<t> test </t>") - 1 );
1807 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_XML_STRING_TYPE, NULL,
1808 WS_READ_REQUIRED_VALUE, heap, &val_xmlstr, sizeof(val_xmlstr), NULL );
1809 ok( hr == S_OK, "got %08x\n", hr );
1810 ok( val_xmlstr.length == 6, "got %u\n", val_xmlstr.length );
1811 ok( !memcmp( val_xmlstr.bytes, " test ", 6 ), "wrong data\n" );
1813 val_xmlstr.length = 0xdeadbeef;
1814 val_xmlstr.bytes = (BYTE *)0xdeadbeef;
1815 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1816 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_XML_STRING_TYPE, NULL,
1817 WS_READ_REQUIRED_VALUE, heap, &val_xmlstr, sizeof(val_xmlstr), NULL );
1818 ok( hr == S_OK, "got %08x\n", hr );
1819 ok( !val_xmlstr.length, "got %u\n", val_bytes.length );
1820 todo_wine ok( val_xmlstr.bytes != NULL, "got %p\n", val_bytes.bytes );
1822 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_XML_STRING_TYPE, NULL,
1823 WS_READ_REQUIRED_POINTER, heap, &ptr_xmlstr, sizeof(ptr_xmlstr), NULL );
1824 ok( hr == S_OK, "got %08x\n", hr );
1825 ok( !ptr_xmlstr->length, "got %u\n", ptr_bytes->length );
1826 todo_wine ok( ptr_xmlstr->bytes != NULL, "got %p\n", ptr_bytes->bytes );
1828 memset( &val_string, 0, sizeof(val_string) );
1829 prepare_type_test( reader, "<t> test </t>", sizeof("<t> test </t>") - 1 );
1830 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRING_TYPE, NULL,
1831 WS_READ_REQUIRED_VALUE, heap, &val_string, sizeof(val_string), NULL );
1832 ok( hr == S_OK, "got %08x\n", hr );
1833 ok( val_string.length == 6, "got %u\n", val_string.length );
1834 ok( !memcmp( val_string.chars, L" test ", 12 ), "wrong data\n" );
1836 val_string.length = 0xdeadbeef;
1837 val_string.chars = (WCHAR *)0xdeadbeef;
1838 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1839 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRING_TYPE, NULL,
1840 WS_READ_REQUIRED_VALUE, heap, &val_string, sizeof(val_string), NULL );
1841 ok( hr == S_OK, "got %08x\n", hr );
1842 ok( !val_string.length, "got %u\n", val_string.length );
1843 todo_wine ok( val_string.chars != NULL, "got %p\n", val_string.chars );
1845 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRING_TYPE, NULL,
1846 WS_READ_REQUIRED_POINTER, heap, &ptr_string, sizeof(ptr_string), NULL );
1847 ok( hr == S_OK, "got %08x\n", hr );
1848 ok( !ptr_string->length, "got %u\n", ptr_string->length );
1849 todo_wine ok( ptr_string->chars != NULL, "got %p\n", ptr_string->chars );
1851 memset( &val_id, 0, sizeof(val_id) );
1852 val_id.guid.Data1 = 0xdeadbeef;
1853 prepare_type_test( reader, "<t> test </t>", sizeof("<t> test </t>") - 1 );
1854 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL,
1855 WS_READ_REQUIRED_VALUE, heap, &val_id, sizeof(val_id), NULL );
1856 ok( hr == S_OK, "got %08x\n", hr );
1857 ok( val_id.uri.length == 6, "got %u\n", val_string.length );
1858 ok( !memcmp( val_id.uri.chars, L" test ", 12 ), "wrong data\n" );
1859 ok( IsEqualGUID( &val_id.guid, &guid_null ), "wrong guid\n" );
1861 memset( &val_id, 0, sizeof(val_id) );
1862 prepare_type_test( reader, "<t>urn:uuid:00000000-0000-0000-0000-0000000000a1</t>",
1863 sizeof("<t>urn:uuid:00000000-0000-0000-0000-0000000000a1</t>") - 1 );
1864 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL,
1865 WS_READ_REQUIRED_VALUE, heap, &val_id, sizeof(val_id), NULL );
1866 ok( hr == S_OK, "got %08x\n", hr );
1867 ok( !val_id.uri.length, "got %u\n", val_string.length );
1868 ok( val_id.uri.chars == NULL, "chars set %s\n", wine_dbgstr_wn(val_id.uri.chars, val_id.uri.length) );
1869 ok( IsEqualGUID( &val_id.guid, &guid ), "wrong guid\n" );
1871 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1872 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL,
1873 WS_READ_REQUIRED_VALUE, heap, &val_id, sizeof(val_id), NULL );
1874 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1876 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1877 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL,
1878 WS_READ_REQUIRED_POINTER, heap, &ptr_id, sizeof(ptr_id), NULL );
1879 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1881 memset( &val_qname, 0, sizeof(val_qname) );
1882 hr = set_input( reader, "<t>u</t>", sizeof("<t>u</t>") - 1 );
1883 ok( hr == S_OK, "got %08x\n", hr );
1884 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1885 ok( hr == S_OK, "got %08x\n", hr );
1886 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_XML_QNAME_TYPE, NULL,
1887 WS_READ_REQUIRED_VALUE, heap, &val_qname, sizeof(val_qname), NULL );
1888 ok( hr == S_OK, "got %08x\n", hr );
1889 ok( val_qname.localName.length == 1, "got %u\n", val_qname.localName.length );
1890 ok( val_qname.localName.bytes[0] == 'u', "wrong data\n" );
1891 ok( !val_qname.ns.length, "got %u\n", val_qname.ns.length );
1892 ok( val_qname.ns.bytes != NULL, "bytes not set\n" );
1894 memset( &val_qname, 0, sizeof(val_qname) );
1895 hr = set_input( reader, "<p:t xmlns:p=\"ns\"> p:u </p:t>", sizeof("<p:t xmlns:p=\"ns\"> p:u </p:t>") - 1 );
1896 ok( hr == S_OK, "got %08x\n", hr );
1897 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1898 ok( hr == S_OK, "got %08x\n", hr );
1899 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_XML_QNAME_TYPE, NULL,
1900 WS_READ_REQUIRED_VALUE, heap, &val_qname, sizeof(val_qname), NULL );
1901 ok( hr == S_OK, "got %08x\n", hr );
1902 ok( val_qname.localName.length == 1, "got %u\n", val_qname.localName.length );
1903 ok( val_qname.localName.bytes[0] == 'u', "wrong data\n" );
1904 ok( val_qname.ns.length == 2, "got %u\n", val_qname.ns.length );
1905 ok( !memcmp( val_qname.ns.bytes, "ns", 2 ), "wrong data\n" );
1907 hr = set_input( reader, "<t></t>", sizeof("<t></t>") - 1 );
1908 ok( hr == S_OK, "got %08x\n", hr );
1909 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1910 ok( hr == S_OK, "got %08x\n", hr );
1911 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_XML_QNAME_TYPE, NULL,
1912 WS_READ_REQUIRED_VALUE, heap, &val_qname, sizeof(val_qname), NULL );
1913 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1915 hr = set_input( reader, "<t></t>", sizeof("<t></t>") - 1 );
1916 ok( hr == S_OK, "got %08x\n", hr );
1917 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1918 ok( hr == S_OK, "got %08x\n", hr );
1919 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_XML_QNAME_TYPE, NULL,
1920 WS_READ_REQUIRED_POINTER, heap, &ptr_qname, sizeof(ptr_qname), NULL );
1921 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1923 WsFreeReader( reader );
1924 WsFreeHeap( heap );
1927 static void test_WsGetXmlAttribute(void)
1929 HRESULT hr;
1930 WS_XML_READER *reader;
1931 WS_XML_STRING xmlstr;
1932 WS_HEAP *heap;
1933 WCHAR *str;
1934 ULONG count;
1935 int found;
1937 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1938 ok( hr == S_OK, "got %08x\n", hr );
1940 hr = WsCreateReader( NULL, 0, &reader, NULL );
1941 ok( hr == S_OK, "got %08x\n", hr );
1943 hr = set_input( reader, data9, sizeof(data9) - 1 );
1944 ok( hr == S_OK, "got %08x\n", hr );
1946 hr = WsFillReader( reader, sizeof(data9) - 1, NULL, NULL );
1947 ok( hr == S_OK, "got %08x\n", hr );
1949 found = -1;
1950 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1951 ok( hr == S_OK, "got %08x\n", hr );
1952 ok( found == TRUE, "got %d\n", found );
1954 xmlstr.bytes = (BYTE *)"attr";
1955 xmlstr.length = sizeof("attr") - 1;
1956 xmlstr.dictionary = NULL;
1957 xmlstr.id = 0;
1958 str = NULL;
1959 count = 0;
1960 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1961 todo_wine ok( hr == S_OK, "got %08x\n", hr );
1962 todo_wine ok( str != NULL, "str not set\n" );
1963 todo_wine ok( count == 5, "got %u\n", count );
1964 /* string is not null-terminated */
1965 if (str) ok( !memcmp( str, L"value", count * sizeof(WCHAR) ), "wrong data\n" );
1967 xmlstr.bytes = (BYTE *)"none";
1968 xmlstr.length = sizeof("none") - 1;
1969 xmlstr.dictionary = NULL;
1970 xmlstr.id = 0;
1971 str = (WCHAR *)0xdeadbeef;
1972 count = 0xdeadbeef;
1973 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1974 todo_wine ok( hr == S_FALSE, "got %08x\n", hr );
1975 todo_wine ok( str == NULL, "str not set\n" );
1976 todo_wine ok( !count, "got %u\n", count );
1978 WsFreeReader( reader );
1979 WsFreeHeap( heap );
1982 static void test_WsXmlStringEquals(void)
1984 BYTE bom[] = {0xef,0xbb,0xbf};
1985 WS_XML_STRING str1 = {0, NULL}, str2 = {0, NULL};
1986 HRESULT hr;
1988 hr = WsXmlStringEquals( NULL, NULL, NULL );
1989 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1991 hr = WsXmlStringEquals( &str1, NULL, NULL );
1992 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1994 hr = WsXmlStringEquals( NULL, &str2, NULL );
1995 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1997 hr = WsXmlStringEquals( &str1, &str2, NULL );
1998 ok( hr == S_OK, "got %08x\n", hr );
2000 str1.length = 1;
2001 str1.bytes = (BYTE *)"a";
2002 hr = WsXmlStringEquals( &str1, &str1, NULL );
2003 ok( hr == S_OK, "got %08x\n", hr );
2005 str2.length = 1;
2006 str2.bytes = (BYTE *)"b";
2007 hr = WsXmlStringEquals( &str1, &str2, NULL );
2008 ok( hr == S_FALSE, "got %08x\n", hr );
2010 str2.length = 1;
2011 str2.bytes = bom;
2012 hr = WsXmlStringEquals( &str1, &str2, NULL );
2013 ok( hr == S_FALSE, "got %08x\n", hr );
2015 str1.length = 3;
2016 hr = WsXmlStringEquals( &str1, &str2, NULL );
2017 ok( hr == S_FALSE, "got %08x\n", hr );
2019 str2.length = 3;
2020 hr = WsXmlStringEquals( &str1, &str2, NULL );
2021 ok( hr == S_FALSE, "got %08x\n", hr );
2023 str1.length = 3;
2024 str1.bytes = bom;
2025 hr = WsXmlStringEquals( &str1, &str2, NULL );
2026 ok( hr == S_OK, "got %08x\n", hr );
2029 static void test_WsAlloc(void)
2031 HRESULT hr;
2032 WS_HEAP *heap;
2033 void *ptr;
2034 SIZE_T requested, actual;
2035 ULONG size;
2037 hr = WsCreateHeap( 256, 0, NULL, 0, &heap, NULL );
2038 ok( hr == S_OK, "got %08x\n", hr );
2040 ptr = (void *)0xdeadbeef;
2041 hr = WsAlloc( NULL, 16, &ptr, NULL );
2042 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2043 ok( ptr == (void *)0xdeadbeef, "ptr set\n" );
2045 ptr = (void *)0xdeadbeef;
2046 hr = WsAlloc( heap, 512, &ptr, NULL );
2047 ok( hr == WS_E_QUOTA_EXCEEDED, "got %08x\n", hr );
2048 ok( ptr == (void *)0xdeadbeef, "ptr set\n" );
2050 ptr = NULL;
2051 hr = WsAlloc( heap, 16, &ptr, NULL );
2052 ok( hr == S_OK, "got %08x\n", hr );
2053 ok( ptr != NULL, "ptr not set\n" );
2055 requested = 0xdeadbeef;
2056 size = sizeof(requested);
2057 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
2058 ok( hr == S_OK, "got %08x\n", hr );
2059 ok( requested == 16, "got %u\n", (ULONG)requested );
2061 actual = 0xdeadbeef;
2062 size = sizeof(actual);
2063 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
2064 ok( hr == S_OK, "got %08x\n", hr );
2065 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
2067 WsFreeHeap( heap );
2070 static void test_WsMoveReader(void)
2072 HRESULT hr;
2073 WS_HEAP *heap;
2074 WS_XML_READER *reader;
2075 WS_XML_WRITER *writer;
2076 WS_XML_BUFFER *buffer;
2077 WS_XML_STRING localname = {1, (BYTE *)"a"}, localname2 = {1, (BYTE *)"b"}, ns = {0, NULL};
2078 const WS_XML_NODE *node;
2079 WS_XML_ELEMENT_NODE *elem;
2080 WS_XML_UTF8_TEXT utf8;
2082 hr = WsCreateReader( NULL, 0, &reader, NULL );
2083 ok( hr == S_OK, "got %08x\n", hr );
2085 hr = WsMoveReader( NULL, WS_MOVE_TO_EOF, NULL, NULL );
2086 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2088 /* reader must be set to an XML buffer */
2089 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
2090 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2092 hr = set_input( reader, data8, sizeof(data8) - 1 );
2093 ok( hr == S_OK, "got %08x\n", hr );
2095 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
2096 todo_wine ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2097 WsFreeReader( reader );
2099 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2100 ok( hr == S_OK, "got %08x\n", hr );
2102 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
2103 ok( hr == S_OK, "got %08x\n", hr );
2105 hr = WsCreateWriter( NULL, 0, &writer, NULL );
2106 ok( hr == S_OK, "got %08x\n", hr );
2108 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
2109 ok( hr == S_OK, "got %08x\n", hr );
2111 /* <a><b/></a> */
2112 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
2113 ok( hr == S_OK, "got %08x\n", hr );
2115 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
2116 ok( hr == S_OK, "got %08x\n", hr );
2118 hr = WsWriteEndElement( writer, NULL );
2119 ok( hr == S_OK, "got %08x\n", hr );
2121 hr = WsWriteEndElement( writer, NULL );
2122 ok( hr == S_OK, "got %08x\n", hr );
2124 hr = WsCreateReader( NULL, 0, &reader, NULL );
2125 ok( hr == S_OK, "got %08x\n", hr );
2127 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
2128 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2130 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
2131 ok( hr == S_OK, "got %08x\n", hr );
2133 /* first element is child node of BOF node */
2134 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
2135 ok( hr == S_OK, "got %08x\n", hr );
2137 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2138 ok( hr == S_OK, "got %08x\n", hr );
2140 hr = WsGetReaderNode( reader, &node, NULL );
2141 ok( hr == S_OK, "got %08x\n", hr );
2142 elem = (WS_XML_ELEMENT_NODE *)node;
2143 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2144 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2145 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
2147 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2148 ok( hr == S_OK, "got %08x\n", hr );
2150 hr = WsGetReaderNode( reader, &node, NULL );
2151 ok( hr == S_OK, "got %08x\n", hr );
2152 elem = (WS_XML_ELEMENT_NODE *)node;
2153 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2154 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2155 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2157 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2158 ok( hr == S_OK, "got %08x\n", hr );
2160 hr = WsGetReaderNode( reader, &node, NULL );
2161 ok( hr == S_OK, "got %08x\n", hr );
2162 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2164 /* EOF node is last child of BOF node */
2165 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
2166 ok( hr == S_OK, "got %08x\n", hr );
2168 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2169 ok( hr == S_OK, "got %08x\n", hr );
2171 hr = WsGetReaderNode( reader, &node, NULL );
2172 ok( hr == S_OK, "got %08x\n", hr );
2173 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2175 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2176 ok( hr == S_OK, "got %08x\n", hr );
2178 hr = WsGetReaderNode( reader, &node, NULL );
2179 ok( hr == S_OK, "got %08x\n", hr );
2180 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2182 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2183 ok( hr == S_OK, "got %08x\n", hr );
2185 hr = WsGetReaderNode( reader, &node, NULL );
2186 ok( hr == S_OK, "got %08x\n", hr );
2187 elem = (WS_XML_ELEMENT_NODE *)node;
2188 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2189 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2190 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
2192 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_ELEMENT, NULL, NULL );
2193 ok( hr == S_OK, "got %08x\n", hr );
2195 hr = WsGetReaderNode( reader, &node, NULL );
2196 ok( hr == S_OK, "got %08x\n", hr );
2197 elem = (WS_XML_ELEMENT_NODE *)node;
2198 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2199 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2200 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2202 hr = WsMoveReader( reader, WS_MOVE_TO_END_ELEMENT, NULL, NULL );
2203 ok( hr == S_OK, "got %08x\n", hr );
2205 hr = WsGetReaderNode( reader, &node, NULL );
2206 ok( hr == S_OK, "got %08x\n", hr );
2207 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2209 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2210 ok( hr == S_OK, "got %08x\n", hr );
2212 hr = WsGetReaderNode( reader, &node, NULL );
2213 ok( hr == S_OK, "got %08x\n", hr );
2214 elem = (WS_XML_ELEMENT_NODE *)node;
2215 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2216 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2217 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2219 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2220 ok( hr == S_OK, "got %08x\n", hr );
2222 hr = WsGetReaderNode( reader, &node, NULL );
2223 ok( hr == S_OK, "got %08x\n", hr );
2224 elem = (WS_XML_ELEMENT_NODE *)node;
2225 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2226 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2227 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
2229 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2230 ok( hr == S_OK, "got %08x\n", hr );
2232 hr = WsGetReaderNode( reader, &node, NULL );
2233 ok( hr == S_OK, "got %08x\n", hr );
2234 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
2236 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2237 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2239 WsFreeWriter( writer );
2240 WsFreeHeap( heap );
2242 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2243 ok( hr == S_OK, "got %08x\n", hr );
2245 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
2246 ok( hr == S_OK, "got %08x\n", hr );
2248 hr = WsCreateWriter( NULL, 0, &writer, NULL );
2249 ok( hr == S_OK, "got %08x\n", hr );
2251 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
2252 ok( hr == S_OK, "got %08x\n", hr );
2254 /* <a><b>test</b></a> */
2255 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
2256 ok( hr == S_OK, "got %08x\n", hr );
2258 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
2259 ok( hr == S_OK, "got %08x\n", hr );
2261 memset(&utf8, 0, sizeof(utf8));
2262 utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
2263 utf8.value.bytes = (BYTE *)"test";
2264 utf8.value.length = sizeof("test") - 1;
2265 hr = WsWriteText( writer, &utf8.text, NULL );
2266 ok( hr == S_OK, "got %08x\n", hr );
2268 hr = WsWriteEndElement( writer, NULL );
2269 ok( hr == S_OK, "got %08x\n", hr );
2271 hr = WsWriteEndElement( writer, NULL );
2272 ok( hr == S_OK, "got %08x\n", hr );
2274 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
2275 ok( hr == S_OK, "got %08x\n", hr );
2277 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2278 ok( hr == S_OK, "got %08x\n", hr );
2280 hr = WsGetReaderNode( reader, &node, NULL );
2281 ok( hr == S_OK, "got %08x\n", hr );
2282 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2284 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2285 ok( hr == S_OK, "got %08x\n", hr );
2287 hr = WsGetReaderNode( reader, &node, NULL );
2288 ok( hr == S_OK, "got %08x\n", hr );
2289 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2291 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2292 ok( hr == S_OK, "got %08x\n", hr );
2294 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2295 ok( hr == S_OK, "got %08x\n", hr );
2297 hr = WsGetReaderNode( reader, &node, NULL );
2298 ok( hr == S_OK, "got %08x\n", hr );
2299 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2301 hr = WsGetReaderNode( reader, &node, NULL );
2302 ok( hr == S_OK, "got %08x\n", hr );
2303 elem = (WS_XML_ELEMENT_NODE *)node;
2304 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2305 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2306 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2308 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2309 ok( hr == S_OK, "got %08x\n", hr );
2311 hr = WsGetReaderNode( reader, &node, NULL );
2312 ok( hr == S_OK, "got %08x\n", hr );
2313 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2315 WsFreeReader( reader );
2316 WsFreeWriter( writer );
2317 WsFreeHeap( heap );
2320 static void prepare_struct_type_test( WS_XML_READER *reader, const char *data )
2322 HRESULT hr;
2323 ULONG size = strlen( data );
2325 hr = set_input( reader, data, size );
2326 ok( hr == S_OK, "got %08x\n", hr );
2329 static void test_simple_struct_type(void)
2331 HRESULT hr;
2332 WS_XML_READER *reader;
2333 WS_HEAP *heap;
2334 WS_STRUCT_DESCRIPTION s;
2335 WS_FIELD_DESCRIPTION f, *fields[1];
2336 WS_XML_STRING ns = {0, NULL}, localname = {3, (BYTE *)"str"};
2337 WS_XML_STRING localname2 = {4, (BYTE *)"test"};
2338 const WS_XML_NODE *node;
2339 const WS_XML_ELEMENT_NODE *elem;
2340 struct test { WCHAR *str; } *test;
2342 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2343 ok( hr == S_OK, "got %08x\n", hr );
2345 hr = WsCreateReader( NULL, 0, &reader, NULL );
2346 ok( hr == S_OK, "got %08x\n", hr );
2348 prepare_struct_type_test( reader, "<str>test</str>" );
2349 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL,
2350 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2351 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2353 hr = WsGetReaderNode( reader, &node, NULL );
2354 ok( hr == S_OK, "got %08x\n", hr );
2355 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
2357 /* element field mapping */
2358 memset( &f, 0, sizeof(f) );
2359 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2360 f.localName = &localname;
2361 f.ns = &ns;
2362 f.type = WS_WSZ_TYPE;
2363 fields[0] = &f;
2365 memset( &s, 0, sizeof(s) );
2366 s.size = sizeof(struct test);
2367 s.alignment = TYPE_ALIGNMENT(struct test);
2368 s.fields = fields;
2369 s.fieldCount = 1;
2370 s.typeLocalName = &localname2;
2371 s.typeNs = &ns;
2373 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2374 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2375 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2376 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2378 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2379 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2380 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2381 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2383 s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
2384 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2385 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2386 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2387 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2388 s.structOptions = 0;
2390 test = NULL;
2391 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str>" );
2392 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2393 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2394 ok( hr == S_OK, "got %08x\n", hr );
2395 ok( test != NULL, "test not set\n" );
2396 if (test)
2398 ok( test->str != NULL, "str not set\n" );
2399 if (test->str) ok( !wcscmp( test->str, L"test" ), "wrong data\n" );
2402 hr = WsGetReaderNode( reader, &node, NULL );
2403 ok( hr == S_OK, "got %08x\n", hr );
2404 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2406 test = NULL;
2407 prepare_struct_type_test( reader, "<str>test</str>" );
2408 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2409 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2410 ok( hr == S_OK, "got %08x\n", hr );
2411 ok( test != NULL, "test not set\n" );
2412 if (test)
2414 ok( test->str != NULL, "str not set\n" );
2415 if (test->str) ok( !wcscmp( test->str, L"test" ), "wrong data\n" );
2418 hr = WsGetReaderNode( reader, &node, NULL );
2419 ok( hr == S_OK, "got %08x\n", hr );
2420 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2422 test = NULL;
2423 prepare_struct_type_test( reader, "<str>test</str>" );
2424 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2425 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2426 ok( hr == S_OK, "got %08x\n", hr );
2427 ok( test != NULL, "test not set\n" );
2428 if (test)
2430 ok( test->str != NULL, "str not set\n" );
2431 if (test->str) ok( !wcscmp( test->str, L"test" ), "wrong data\n" );
2434 hr = WsGetReaderNode( reader, &node, NULL );
2435 ok( hr == S_OK, "got %08x\n", hr );
2436 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2438 prepare_struct_type_test( reader, "<str>test</str>" );
2439 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2440 ok( hr == S_OK, "got %08x\n", hr );
2442 hr = WsGetReaderNode( reader, &node, NULL );
2443 ok( hr == S_OK, "got %08x\n", hr );
2444 elem = (const WS_XML_ELEMENT_NODE *)node;
2445 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2446 ok( elem->localName->length == 3, "got %u\n", elem->localName->length );
2447 ok( !memcmp( elem->localName->bytes, "str", 3 ), "wrong data\n" );
2449 test = NULL;
2450 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2451 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2452 ok( hr == S_OK, "got %08x\n", hr );
2453 ok( test != NULL, "test not set\n" );
2454 if (test)
2456 ok( test->str != NULL, "str not set\n" );
2457 if (test->str) ok( !wcscmp( test->str, L"test" ), "wrong data\n" );
2460 hr = WsGetReaderNode( reader, &node, NULL );
2461 ok( hr == S_OK, "got %08x\n", hr );
2462 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2464 /* attribute field mapping */
2465 f.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2467 test = NULL;
2468 prepare_struct_type_test( reader, "<test str=\"test\"/>" );
2469 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2470 ok( hr == S_OK, "got %08x\n", hr );
2472 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2473 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2474 ok( hr == S_OK, "got %08x\n", hr );
2475 ok( test != NULL, "test not set\n" );
2476 if (test)
2478 ok( test->str != NULL, "str not set\n" );
2479 if (test->str) ok( !wcscmp( test->str, L"test" ), "wrong data test %p test->str %p\n", test, test->str );
2482 hr = WsGetReaderNode( reader, &node, NULL );
2483 ok( hr == S_OK, "got %08x\n", hr );
2484 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2486 WsFreeReader( reader );
2487 WsFreeHeap( heap );
2490 static void test_cdata(void)
2492 static const char test[] = "<t><![CDATA[<data>]]></t>";
2493 HRESULT hr;
2494 WS_XML_READER *reader;
2495 const WS_XML_NODE *node;
2497 hr = WsCreateReader( NULL, 0, &reader, NULL );
2498 ok( hr == S_OK, "got %08x\n", hr );
2500 hr = set_input( reader, test, sizeof(test) - 1 );
2501 ok( hr == S_OK, "got %08x\n", hr );
2503 hr = WsFillReader( reader, sizeof(test) - 1, NULL, NULL );
2504 ok( hr == S_OK, "got %08x\n", hr );
2506 hr = WsReadNode( reader, NULL );
2507 ok( hr == S_OK, "got %08x\n", hr );
2509 hr = WsGetReaderNode( reader, &node, NULL );
2510 ok( hr == S_OK, "got %08x\n", hr );
2511 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2513 hr = WsReadNode( reader, NULL );
2514 ok( hr == S_OK, "got %08x\n", hr );
2516 hr = WsGetReaderNode( reader, &node, NULL );
2517 ok( hr == S_OK, "got %08x\n", hr );
2518 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_CDATA, "got %u\n", node->nodeType );
2520 hr = WsReadNode( reader, NULL );
2521 ok( hr == S_OK, "got %08x\n", hr );
2523 hr = WsGetReaderNode( reader, &node, NULL );
2524 ok( hr == S_OK, "got %08x\n", hr );
2525 if (node)
2527 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
2528 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
2529 ok( text->text != NULL, "text not set\n" );
2530 if (text->text)
2532 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
2533 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
2534 ok( utf8->value.length == 6, "got %u\n", utf8->value.length );
2535 ok( !memcmp( utf8->value.bytes, "<data>", 6 ), "wrong data\n" );
2539 hr = WsReadNode( reader, NULL );
2540 ok( hr == S_OK, "got %08x\n", hr );
2542 hr = WsGetReaderNode( reader, &node, NULL );
2543 ok( hr == S_OK, "got %08x\n", hr );
2544 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_CDATA, "got %u\n", node->nodeType );
2546 hr = WsReadNode( reader, NULL );
2547 ok( hr == S_OK, "got %08x\n", hr );
2549 hr = WsGetReaderNode( reader, &node, NULL );
2550 ok( hr == S_OK, "got %08x\n", hr );
2551 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2553 WsFreeReader( reader );
2556 static void test_WsFindAttribute(void)
2558 static const char test[] = "<t attr='value' attr2='value2'></t>";
2559 static const char test2[] = "<p:t attr='value' p:attr2='value2' xmlns:p=\"ns\"></t>";
2560 WS_XML_STRING ns = {0, NULL}, ns2 = {2, (BYTE *)"ns"}, localname = {4, (BYTE *)"attr"};
2561 WS_XML_STRING localname2 = {5, (BYTE *)"attr2"}, localname3 = {5, (BYTE *)"attr3"};
2562 WS_XML_READER *reader;
2563 ULONG index;
2564 HRESULT hr;
2566 hr = WsCreateReader( NULL, 0, &reader, NULL );
2567 ok( hr == S_OK, "got %08x\n", hr );
2569 hr = set_input( reader, test, sizeof(test) - 1 );
2570 ok( hr == S_OK, "got %08x\n", hr );
2572 hr = WsReadNode( reader, NULL );
2573 ok( hr == S_OK, "got %08x\n", hr );
2575 hr = WsFindAttribute( reader, &localname, &ns, TRUE, NULL, NULL );
2576 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2578 hr = set_input( reader, test, sizeof(test) - 1 );
2579 ok( hr == S_OK, "got %08x\n", hr );
2581 hr = WsReadNode( reader, NULL );
2582 ok( hr == S_OK, "got %08x\n", hr );
2584 hr = WsFindAttribute( reader, &localname, NULL, TRUE, &index, NULL );
2585 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2587 hr = set_input( reader, test, sizeof(test) - 1 );
2588 ok( hr == S_OK, "got %08x\n", hr );
2590 hr = WsReadNode( reader, NULL );
2591 ok( hr == S_OK, "got %08x\n", hr );
2593 hr = WsFindAttribute( reader, NULL, &ns, TRUE, &index, NULL );
2594 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2596 hr = set_input( reader, test, sizeof(test) - 1 );
2597 ok( hr == S_OK, "got %08x\n", hr );
2599 hr = WsReadNode( reader, NULL );
2600 ok( hr == S_OK, "got %08x\n", hr );
2602 index = 0xdeadbeef;
2603 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2604 ok( hr == S_OK, "got %08x\n", hr );
2605 ok( !index, "got %u\n", index );
2607 index = 0xdeadbeef;
2608 hr = WsFindAttribute( reader, &localname2, &ns, TRUE, &index, NULL );
2609 ok( hr == S_OK, "got %08x\n", hr );
2610 ok( index == 1, "got %u\n", index );
2612 hr = WsReadNode( reader, NULL );
2613 ok( hr == S_OK, "got %08x\n", hr );
2615 index = 0xdeadbeef;
2616 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2617 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2618 ok( index == 0xdeadbeef, "got %u\n", index );
2620 hr = set_input( reader, test, sizeof(test) - 1 );
2621 ok( hr == S_OK, "got %08x\n", hr );
2623 hr = WsReadNode( reader, NULL );
2624 ok( hr == S_OK, "got %08x\n", hr );
2626 index = 0xdeadbeef;
2627 hr = WsFindAttribute( reader, &localname3, &ns, TRUE, &index, NULL );
2628 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2629 ok( index == 0xdeadbeef, "got %u\n", index );
2631 hr = set_input( reader, test, sizeof(test) - 1 );
2632 ok( hr == S_OK, "got %08x\n", hr );
2634 hr = WsReadNode( reader, NULL );
2635 ok( hr == S_OK, "got %08x\n", hr );
2637 index = 0xdeadbeef;
2638 hr = WsFindAttribute( reader, &localname3, &ns, FALSE, &index, NULL );
2639 ok( hr == S_FALSE, "got %08x\n", hr );
2640 ok( index == ~0u, "got %u\n", index );
2642 hr = set_input( reader, test2, sizeof(test2) - 1 );
2643 ok( hr == S_OK, "got %08x\n", hr );
2645 hr = WsReadNode( reader, NULL );
2646 ok( hr == S_OK, "got %08x\n", hr );
2648 index = 0xdeadbeef;
2649 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2650 ok( hr == S_OK, "got %08x\n", hr );
2651 ok( !index, "got %u\n", index );
2653 hr = WsFindAttribute( reader, &localname2, &ns2, TRUE, &index, NULL );
2654 ok( hr == S_OK, "got %08x\n", hr );
2656 hr = WsFindAttribute( reader, &localname2, &ns, TRUE, &index, NULL );
2657 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2659 hr = set_input( reader, test2, sizeof(test2) - 1 );
2660 ok( hr == S_OK, "got %08x\n", hr );
2662 hr = WsReadNode( reader, NULL );
2663 ok( hr == S_OK, "got %08x\n", hr );
2665 hr = WsFindAttribute( reader, &localname, &ns2, TRUE, &index, NULL );
2666 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2668 WsFreeReader( reader );
2671 static void prepare_namespace_test( WS_XML_READER *reader, const char *data )
2673 HRESULT hr;
2674 ULONG size = strlen( data );
2676 hr = set_input( reader, data, size );
2677 ok( hr == S_OK, "got %08x\n", hr );
2679 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2680 ok( hr == S_OK, "got %08x\n", hr );
2683 static void test_WsGetNamespaceFromPrefix(void)
2685 WS_XML_STRING prefix = {0, NULL};
2686 const WS_XML_STRING *ns;
2687 const WS_XML_NODE *node;
2688 WS_XML_READER *reader;
2689 HRESULT hr;
2691 hr = WsCreateReader( NULL, 0, &reader, NULL );
2692 ok( hr == S_OK, "got %08x\n", hr );
2694 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, NULL, NULL );
2695 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2697 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, &ns, NULL );
2698 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2700 hr = WsGetNamespaceFromPrefix( NULL, &prefix, FALSE, &ns, NULL );
2701 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2703 ns = (const WS_XML_STRING *)0xdeadbeef;
2704 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2705 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2706 ok( ns == (const WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2708 hr = set_input( reader, "<prefix:t xmlns:prefix2='ns'/>", sizeof("<prefix:t xmlns:prefix2='ns'/>") - 1 );
2709 ok( hr == S_OK, "got %08x\n", hr );
2710 hr = WsReadStartElement( reader, NULL );
2711 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2713 prepare_namespace_test( reader, "<t></t>" );
2714 ns = NULL;
2715 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2716 ok( hr == S_OK, "got %08x\n", hr );
2717 ok( ns != NULL, "ns not set\n" );
2718 if (ns) ok( !ns->length, "got %u\n", ns->length );
2720 prepare_namespace_test( reader, "<t xmls='ns'></t>" );
2721 ns = NULL;
2722 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2723 ok( hr == S_OK, "got %08x\n", hr );
2724 ok( ns != NULL, "ns not set\n" );
2725 if (ns) ok( !ns->length, "got %u\n", ns->length );
2727 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2728 ns = NULL;
2729 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2730 ok( hr == S_OK, "got %08x\n", hr );
2731 ok( ns != NULL, "ns not set\n" );
2732 if (ns) ok( !ns->length, "got %u\n", ns->length );
2734 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2735 prefix.bytes = (BYTE *)"prefix";
2736 prefix.length = 6;
2737 ns = NULL;
2738 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2739 ok( hr == S_OK, "got %08x\n", hr );
2740 ok( ns != NULL, "ns not set\n" );
2741 if (ns)
2743 ok( ns->length == 2, "got %u\n", ns->length );
2744 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2747 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2748 ns = NULL;
2749 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2750 ok( hr == S_OK, "got %08x\n", hr );
2751 ok( ns != NULL, "ns not set\n" );
2752 if (ns)
2754 ok( ns->length == 2, "got %u\n", ns->length );
2755 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2758 hr = set_input( reader, "<t xmlns:prefix='ns'></t>", sizeof("<t xmlns:prefix='ns'></t>") - 1 );
2759 ok( hr == S_OK, "got %08x\n", hr );
2760 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2761 ok( hr == S_OK, "got %08x\n", hr );
2762 hr = WsGetReaderNode( reader, &node, NULL );
2763 ok( hr == S_OK, "got %08x\n", hr );
2764 if (node)
2766 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2767 WS_XML_ATTRIBUTE *attr;
2768 WS_XML_UTF8_TEXT *text;
2770 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2771 ok( elem->prefix != NULL, "prefix not set\n" );
2772 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2773 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2774 ok( elem->ns != NULL, "ns not set\n" );
2775 ok( !elem->ns->length, "got %u\n", elem->ns->length );
2776 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2777 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2778 ok( elem->attributes != NULL, "attributes not set\n" );
2780 attr = elem->attributes[0];
2781 ok( attr->singleQuote, "singleQuote not set\n" );
2782 ok( attr->isXmlNs, "isXmlNs not set\n" );
2783 ok( attr->prefix != NULL, "prefix not set\n" );
2784 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2785 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2786 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2787 ok( attr->localName != NULL, "localName not set\n" );
2788 ok( attr->localName->length == 6, "got %u\n", attr->localName->length );
2789 ok( !memcmp( attr->localName->bytes, "prefix", 6 ), "wrong data\n" );
2790 ok( attr->ns != NULL, "ns not set\n" );
2791 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2792 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2793 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2794 ok( attr->value != NULL, "value not set\n" );
2796 text = (WS_XML_UTF8_TEXT *)attr->value;
2797 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
2798 ok( !text->value.length, "got %u\n", text->value.length );
2799 ok( text->value.bytes == NULL, "bytes set\n" );
2802 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2803 hr = WsReadStartElement( reader, NULL );
2804 ok( hr == S_OK, "got %08x\n", hr );
2805 hr = WsReadEndElement( reader, NULL );
2806 ok( hr == S_OK, "got %08x\n", hr );
2807 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2808 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2810 prepare_namespace_test( reader, "<t></t>" );
2811 ns = NULL;
2812 prefix.bytes = (BYTE *)"xml";
2813 prefix.length = 3;
2814 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2815 ok( hr == S_OK, "got %08x\n", hr );
2816 ok( ns != NULL, "ns not set\n" );
2817 if (ns)
2819 ok( ns->length == 36, "got %u\n", ns->length );
2820 ok( !memcmp( ns->bytes, "http://www.w3.org/XML/1998/namespace", 36 ), "wrong data\n" );
2823 prepare_namespace_test( reader, "<t></t>" );
2824 ns = NULL;
2825 prefix.bytes = (BYTE *)"xmlns";
2826 prefix.length = 5;
2827 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2828 ok( hr == S_OK, "got %08x\n", hr );
2829 ok( ns != NULL, "ns not set\n" );
2830 if (ns)
2832 ok( ns->length == 29, "got %u\n", ns->length );
2833 ok( !memcmp( ns->bytes, "http://www.w3.org/2000/xmlns/", 29 ), "wrong data\n" );
2836 prepare_namespace_test( reader, "<t></t>" );
2837 ns = (WS_XML_STRING *)0xdeadbeef;
2838 prefix.bytes = (BYTE *)"prefix2";
2839 prefix.length = 7;
2840 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2841 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2842 ok( ns == (WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2844 prepare_namespace_test( reader, "<t></t>" );
2845 ns = (WS_XML_STRING *)0xdeadbeef;
2846 prefix.bytes = (BYTE *)"prefix2";
2847 prefix.length = 7;
2848 hr = WsGetNamespaceFromPrefix( reader, &prefix, FALSE, &ns, NULL );
2849 ok( hr == S_FALSE, "got %08x\n", hr );
2850 ok( ns == NULL, "ns not set\n" );
2852 hr = set_input( reader, "<t prefix:attr='' xmlns:prefix='ns'></t>", sizeof("<t prefix:attr='' xmlns:prefix='ns'></t>") - 1 );
2853 ok( hr == S_OK, "got %08x\n", hr );
2854 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2855 ok( hr == S_OK, "got %08x\n", hr );
2856 hr = WsGetReaderNode( reader, &node, NULL );
2857 ok( hr == S_OK, "got %08x\n", hr );
2858 if (node)
2860 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2861 WS_XML_ATTRIBUTE *attr;
2863 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2864 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
2865 ok( elem->attributes != NULL, "attributes not set\n" );
2867 attr = elem->attributes[0];
2868 ok( attr->singleQuote, "singleQuote not set\n" );
2869 ok( !attr->isXmlNs, "isXmlNs is set\n" );
2870 ok( attr->prefix != NULL, "prefix not set\n" );
2871 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2872 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2873 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2874 ok( attr->localName != NULL, "localName not set\n" );
2875 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
2876 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
2877 ok( attr->ns != NULL, "ns not set\n" );
2878 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2879 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2880 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2883 hr = set_input( reader, "<t xmlns:p='ns'><u xmlns:p='ns2'/></t>", sizeof("<t xmlns:p='ns'><u xmlns:p='ns2'/></t>") - 1 );
2884 ok( hr == S_OK, "got %08x\n", hr );
2885 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2886 ok( hr == S_OK, "got %08x\n", hr );
2887 hr = WsReadStartElement( reader, NULL );
2888 ok( hr == S_OK, "got %08x\n", hr );
2890 hr = set_input( reader, "<t xmlns:p='ns'><p:u p:a=''/></t>", sizeof("<t xmlns:p='ns'><p:u p:a=''/></t>") - 1 );
2891 ok( hr == S_OK, "got %08x\n", hr );
2892 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2893 ok( hr == S_OK, "got %08x\n", hr );
2894 hr = WsReadStartElement( reader, NULL );
2895 ok( hr == S_OK, "got %08x\n", hr );
2896 hr = WsGetReaderNode( reader, &node, NULL );
2897 ok( hr == S_OK, "got %08x\n", hr );
2898 if (node)
2900 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2901 WS_XML_ATTRIBUTE *attr;
2903 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2904 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2905 ok( elem->attributes != NULL, "attributes not set\n" );
2907 attr = elem->attributes[0];
2908 ok( attr->prefix != NULL, "prefix not set\n" );
2909 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
2910 ok( attr->prefix->bytes != NULL, "bytes set\n" );
2911 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong data\n" );
2912 ok( attr->localName != NULL, "localName not set\n" );
2913 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
2914 ok( !memcmp( attr->localName->bytes, "a", 1 ), "wrong data\n" );
2915 ok( attr->ns != NULL, "ns not set\n" );
2916 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2917 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2918 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2921 hr = set_input( reader, "<t xmlns='ns'></t>", sizeof("<t xmlns='ns'></t>") - 1 );
2922 ok( hr == S_OK, "got %08x\n", hr );
2923 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2924 ok( hr == S_OK, "got %08x\n", hr );
2925 hr = WsGetReaderNode( reader, &node, NULL );
2926 ok( hr == S_OK, "got %08x\n", hr );
2927 if (node)
2929 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2930 WS_XML_ATTRIBUTE *attr;
2932 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2933 ok( elem->prefix != NULL, "prefix not set\n" );
2934 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2935 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2936 ok( elem->ns != NULL, "ns not set\n" );
2937 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
2938 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2939 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong data\n" );
2941 attr = elem->attributes[0];
2942 ok( attr->isXmlNs, "isXmlNs is not set\n" );
2943 ok( attr->prefix != NULL, "prefix not set\n" );
2944 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
2945 ok( attr->prefix->bytes == NULL, "bytes set\n" );
2946 ok( attr->localName != NULL, "localName not set\n" );
2947 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
2948 ok( !memcmp( attr->localName->bytes, "xmlns", 5 ), "wrong data\n" );
2949 ok( attr->ns != NULL, "ns not set\n" );
2950 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2951 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2952 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2955 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns2'></t>") - 1 );
2956 ok( hr == S_OK, "got %08x\n", hr );
2957 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2958 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2960 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns'></t>") - 1 );
2961 ok( hr == S_OK, "got %08x\n", hr );
2962 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2963 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2965 hr = set_input( reader, "<t xmlns:p='ns' xmlns:P='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:P='ns2'></t>") - 1 );
2966 ok( hr == S_OK, "got %08x\n", hr );
2967 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2968 ok( hr == S_OK, "got %08x\n", hr );
2970 WsFreeReader( reader );
2973 static void test_text_field_mapping(void)
2975 HRESULT hr;
2976 WS_XML_READER *reader;
2977 WS_HEAP *heap;
2978 WS_STRUCT_DESCRIPTION s;
2979 WS_FIELD_DESCRIPTION f, *fields[1];
2980 struct test
2982 WCHAR *str;
2983 } *test;
2985 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2986 ok( hr == S_OK, "got %08x\n", hr );
2988 hr = WsCreateReader( NULL, 0, &reader, NULL );
2989 ok( hr == S_OK, "got %08x\n", hr );
2991 prepare_struct_type_test( reader, "<a>test</a>" );
2993 memset( &f, 0, sizeof(f) );
2994 f.mapping = WS_TEXT_FIELD_MAPPING;
2995 f.type = WS_WSZ_TYPE;
2996 fields[0] = &f;
2998 memset( &s, 0, sizeof(s) );
2999 s.size = sizeof(struct test);
3000 s.alignment = TYPE_ALIGNMENT(struct test);
3001 s.fields = fields;
3002 s.fieldCount = 1;
3004 test = NULL;
3005 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3006 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3007 ok( hr == S_OK, "got %08x\n", hr );
3008 ok( test != NULL, "test not set\n" );
3009 ok( test->str != NULL, "str not set\n" );
3010 ok( !wcscmp( test->str, L"test" ), "got %s\n", wine_dbgstr_w(test->str) );
3012 WsFreeReader( reader );
3013 WsFreeHeap( heap );
3016 static void test_complex_struct_type(void)
3018 static const char data[] =
3019 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
3020 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\">"
3021 "<!--Build: 16.0.6202.6852-->"
3022 "</o:services>"
3023 "</o:OfficeConfig>";
3024 static const char data2[] =
3025 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
3026 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\"></o:services>"
3027 "<trailing>content</trailing>"
3028 "</o:OfficeConfig>";
3029 HRESULT hr;
3030 WS_ERROR *error;
3031 WS_ERROR_PROPERTY prop;
3032 WS_XML_READER *reader;
3033 WS_HEAP *heap;
3034 WS_STRUCT_DESCRIPTION s, s2;
3035 WS_FIELD_DESCRIPTION f, f2, *fields[1], *fields2[1];
3036 WS_XML_STRING str_officeconfig = {12, (BYTE *)"OfficeConfig"};
3037 WS_XML_STRING str_services = {8, (BYTE *)"services"};
3038 WS_XML_STRING str_generationtime = {14, (BYTE *)"GenerationTime"};
3039 WS_XML_STRING ns = {39, (BYTE *)"urn:schemas-microsoft-com:office:office"};
3040 LANGID langid = MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT );
3041 const WS_XML_NODE *node;
3042 const WS_XML_ELEMENT_NODE *elem;
3043 struct services
3045 WCHAR *generationtime;
3047 struct officeconfig
3049 struct services *services;
3050 } *test;
3052 prop.id = WS_ERROR_PROPERTY_LANGID;
3053 prop.value = &langid;
3054 prop.valueSize = sizeof(langid);
3055 hr = WsCreateError( &prop, 1, &error );
3056 ok( hr == S_OK, "got %08x\n", hr );
3058 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3059 ok( hr == S_OK, "got %08x\n", hr );
3061 hr = WsCreateReader( NULL, 0, &reader, NULL );
3062 ok( hr == S_OK, "got %08x\n", hr );
3064 /* element content type mapping */
3065 prepare_struct_type_test( reader, data );
3067 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3068 ok( hr == S_OK, "got %08x\n", hr );
3070 hr = WsGetReaderNode( reader, &node, NULL );
3071 ok( hr == S_OK, "got %08x\n", hr );
3072 elem = (const WS_XML_ELEMENT_NODE *)node;
3073 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
3074 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
3075 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
3077 hr = WsReadStartElement( reader, NULL );
3078 ok( hr == S_OK, "got %08x\n", hr );
3080 hr = WsGetReaderNode( reader, &node, NULL );
3081 ok( hr == S_OK, "got %08x\n", hr );
3082 elem = (const WS_XML_ELEMENT_NODE *)node;
3083 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
3084 ok( elem->localName->length == 8, "got %u\n", elem->localName->length );
3085 ok( !memcmp( elem->localName->bytes, "services", 8 ), "wrong data\n" );
3087 memset( &f2, 0, sizeof(f2) );
3088 f2.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
3089 f2.localName = &str_generationtime;
3090 f2.ns = &ns;
3091 f2.type = WS_WSZ_TYPE;
3092 f2.options = WS_FIELD_OPTIONAL;
3093 fields2[0] = &f2;
3095 memset( &s2, 0, sizeof(s2) );
3096 s2.size = sizeof(*test->services);
3097 s2.alignment = TYPE_ALIGNMENT(struct services);
3098 s2.fields = fields2;
3099 s2.fieldCount = 1;
3100 s2.typeLocalName = &str_services;
3101 s2.typeNs = &ns;
3103 memset( &f, 0, sizeof(f) );
3104 f.mapping = WS_ELEMENT_FIELD_MAPPING;
3105 f.localName = &str_services;
3106 f.ns = &ns;
3107 f.type = WS_STRUCT_TYPE;
3108 f.typeDescription = &s2;
3109 f.options = WS_FIELD_POINTER;
3110 fields[0] = &f;
3112 memset( &s, 0, sizeof(s) );
3113 s.size = sizeof(*test);
3114 s.alignment = TYPE_ALIGNMENT(struct officeconfig);
3115 s.fields = fields;
3116 s.fieldCount = 1;
3117 s.typeLocalName = &str_officeconfig;
3118 s.typeNs = &ns;
3120 test = NULL;
3121 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3122 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
3123 ok( hr == S_OK, "got %08x\n", hr );
3124 ok( test != NULL, "test not set\n" );
3125 ok( !wcscmp( test->services->generationtime, L"2015-09-03T18:47:54" ), "wrong data\n" );
3127 hr = WsGetReaderNode( reader, &node, NULL );
3128 ok( hr == S_OK, "got %08x\n", hr );
3129 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
3131 hr = WsReadEndElement( reader, NULL );
3132 ok( hr == S_OK, "got %08x\n", hr );
3134 hr = WsGetReaderNode( reader, &node, NULL );
3135 ok( hr == S_OK, "got %08x\n", hr );
3136 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
3138 hr = WsReadEndElement( reader, NULL );
3139 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3141 /* element type mapping */
3142 prepare_struct_type_test( reader, data );
3144 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3145 ok( hr == S_OK, "got %08x\n", hr );
3147 hr = WsGetReaderNode( reader, &node, NULL );
3148 ok( hr == S_OK, "got %08x\n", hr );
3149 elem = (const WS_XML_ELEMENT_NODE *)node;
3150 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
3151 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
3152 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
3154 test = NULL;
3155 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3156 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
3157 ok( hr == S_OK, "got %08x\n", hr );
3158 ok( test != NULL, "test not set\n" );
3159 if (test) ok( !wcscmp( test->services->generationtime, L"2015-09-03T18:47:54" ), "wrong data\n" );
3161 hr = WsGetReaderNode( reader, &node, NULL );
3162 ok( hr == S_OK, "got %08x\n", hr );
3163 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
3165 /* trailing content */
3166 prepare_struct_type_test( reader, data2 );
3167 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3168 ok( hr == S_OK, "got %08x\n", hr );
3170 s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
3171 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3172 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
3173 ok( hr == S_OK, "got %08x\n", hr );
3175 hr = WsGetReaderNode( reader, &node, NULL );
3176 ok( hr == S_OK, "got %08x\n", hr );
3177 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
3179 prepare_struct_type_test( reader, data2 );
3180 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3181 ok( hr == S_OK, "got %08x\n", hr );
3183 s.structOptions = 0;
3184 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3185 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
3186 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3188 WsFreeReader( reader );
3189 WsFreeHeap( heap );
3190 WsFreeError( error );
3193 static void test_repeating_element(void)
3195 static const char data[] =
3196 "<services>"
3197 "<service><id>1</id></service>"
3198 "<service><id>2</id></service>"
3199 "</services>";
3200 static const char data2[] =
3201 "<services></services>";
3202 static const char data3[] =
3203 "<services>"
3204 "<wrapper>"
3205 "<service><id>1</id></service>"
3206 "<service><id>2</id></service>"
3207 "</wrapper>"
3208 "</services>";
3209 static const char data4[] =
3210 "<services>"
3211 "<wrapper>"
3212 "<service>1</service>"
3213 "<service>2</service>"
3214 "</wrapper>"
3215 "</services>";
3216 static const char data5[] =
3217 "<services>"
3218 "<wrapper>"
3219 "<service name='1'>1</service>"
3220 "<service name='2'>2</service>"
3221 "</wrapper>"
3222 "</services>";
3223 static const char data6[] =
3224 "<services>"
3225 "<service><name></name></service>"
3226 "</services>";
3227 WS_XML_STRING str_name = {4, (BYTE *)"name"};
3228 WS_XML_STRING str_services = {8, (BYTE *)"services"};
3229 WS_XML_STRING str_service = {7, (BYTE *)"service"};
3230 WS_XML_STRING str_wrapper = {7, (BYTE *)"wrapper"};
3231 WS_XML_STRING str_id = {2, (BYTE *)"id"};
3232 WS_XML_STRING str_ns = {0, NULL};
3233 HRESULT hr;
3234 WS_XML_READER *reader;
3235 WS_HEAP *heap;
3236 WS_STRUCT_DESCRIPTION s, s2;
3237 WS_FIELD_DESCRIPTION f, f2, f3, *fields[1], *fields2[2];
3238 WS_ITEM_RANGE range;
3239 struct service { UINT32 id; };
3240 struct service2 { WCHAR *id; };
3241 struct service3 { WCHAR *name; WCHAR *id; };
3242 struct service4 { WS_STRING name; };
3243 struct services
3245 struct service *service;
3246 ULONG service_count;
3247 } *test;
3248 struct services2
3250 struct service2 *service;
3251 ULONG service_count;
3252 } *test2;
3253 struct services3
3255 struct service3 *service;
3256 ULONG service_count;
3257 } *test3;
3258 struct services4
3260 struct service **service;
3261 ULONG service_count;
3262 } *test4;
3263 struct services5
3265 struct service4 *service;
3266 ULONG service_count;
3267 } *test5;
3269 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3270 ok( hr == S_OK, "got %08x\n", hr );
3272 hr = WsCreateReader( NULL, 0, &reader, NULL );
3273 ok( hr == S_OK, "got %08x\n", hr );
3275 prepare_struct_type_test( reader, data );
3277 memset( &f2, 0, sizeof(f2) );
3278 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
3279 f2.localName = &str_id;
3280 f2.ns = &str_ns;
3281 f2.type = WS_UINT32_TYPE;
3282 fields2[0] = &f2;
3284 memset( &s2, 0, sizeof(s2) );
3285 s2.size = sizeof(struct service);
3286 s2.alignment = TYPE_ALIGNMENT(struct service);
3287 s2.fields = fields2;
3288 s2.fieldCount = 1;
3289 s2.typeLocalName = &str_service;
3291 memset( &f, 0, sizeof(f) );
3292 f.mapping = WS_REPEATING_ELEMENT_FIELD_MAPPING;
3293 f.countOffset = FIELD_OFFSET(struct services, service_count);
3294 f.type = WS_STRUCT_TYPE;
3295 f.typeDescription = &s2;
3296 f.itemLocalName = &str_service;
3297 f.itemNs = &str_ns;
3298 fields[0] = &f;
3300 memset( &s, 0, sizeof(s) );
3301 s.size = sizeof(struct services);
3302 s.alignment = TYPE_ALIGNMENT(struct services);
3303 s.fields = fields;
3304 s.fieldCount = 1;
3305 s.typeLocalName = &str_services;
3307 test = NULL;
3308 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3309 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3310 ok( hr == S_OK, "got %08x\n", hr );
3311 ok( test != NULL, "test not set\n" );
3312 ok( test->service != NULL, "service not set\n" );
3313 ok( test->service_count == 2, "got %u\n", test->service_count );
3314 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
3315 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
3317 /* array of pointers */
3318 prepare_struct_type_test( reader, data );
3319 f.options = WS_FIELD_POINTER;
3320 test4 = NULL;
3321 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3322 WS_READ_REQUIRED_POINTER, heap, &test4, sizeof(test4), NULL );
3323 ok( hr == S_OK || broken(hr == E_INVALIDARG) /* win7 */, "got %08x\n", hr );
3324 if (test4)
3326 ok( test4->service != NULL, "service not set\n" );
3327 ok( test4->service_count == 2, "got %u\n", test4->service_count );
3328 ok( test4->service[0]->id == 1, "got %u\n", test4->service[0]->id );
3329 ok( test4->service[1]->id == 2, "got %u\n", test4->service[1]->id );
3332 /* item range */
3333 prepare_struct_type_test( reader, data2 );
3334 f.options = 0;
3335 range.minItemCount = 0;
3336 range.maxItemCount = 1;
3337 f.itemRange = &range;
3338 test = NULL;
3339 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3340 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3341 ok( hr == S_OK, "got %08x\n", hr );
3342 ok( test != NULL, "test not set\n" );
3343 ok( test->service != NULL, "service not set\n" );
3344 ok( !test->service_count, "got %u\n", test->service_count );
3346 /* wrapper element */
3347 prepare_struct_type_test( reader, data3 );
3348 f.itemRange = NULL;
3349 f.localName = &str_wrapper;
3350 f.ns = &str_ns;
3351 test = NULL;
3352 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3353 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3354 ok( hr == S_OK, "got %08x\n", hr );
3355 ok( test != NULL, "test not set\n" );
3356 ok( test->service != NULL, "service not set\n" );
3357 ok( test->service_count == 2, "got %u\n", test->service_count );
3358 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
3359 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
3361 /* repeating text field mapping */
3362 prepare_struct_type_test( reader, data4 );
3363 f2.mapping = WS_TEXT_FIELD_MAPPING;
3364 f2.localName = NULL;
3365 f2.ns = NULL;
3366 f2.type = WS_WSZ_TYPE;
3367 s2.size = sizeof(struct service2);
3368 s2.alignment = TYPE_ALIGNMENT(struct service2);
3369 test2 = NULL;
3370 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3371 WS_READ_REQUIRED_POINTER, heap, &test2, sizeof(test2), NULL );
3372 ok( hr == S_OK, "got %08x\n", hr );
3373 ok( test2 != NULL, "test2 not set\n" );
3374 ok( test2->service != NULL, "service not set\n" );
3375 ok( test2->service_count == 2, "got %u\n", test2->service_count );
3376 ok( !wcscmp( test2->service[0].id, L"1" ), "wrong data\n" );
3377 ok( !wcscmp( test2->service[1].id, L"2" ), "wrong data\n" );
3379 /* repeating attribute field + text field mapping */
3380 prepare_struct_type_test( reader, data5 );
3381 f2.offset = FIELD_OFFSET(struct service3, id);
3382 memset( &f3, 0, sizeof(f3) );
3383 f3.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
3384 f3.localName = &str_name;
3385 f3.ns = &str_ns;
3386 f3.type = WS_WSZ_TYPE;
3387 fields2[0] = &f3;
3388 fields2[1] = &f2;
3389 s2.size = sizeof(struct service3);
3390 s2.alignment = TYPE_ALIGNMENT(struct service3);
3391 s2.fieldCount = 2;
3392 test3 = NULL;
3393 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3394 WS_READ_REQUIRED_POINTER, heap, &test3, sizeof(test3), NULL );
3395 ok( hr == S_OK, "got %08x\n", hr );
3396 ok( test3 != NULL, "test3 not set\n" );
3397 ok( test3->service != NULL, "service not set\n" );
3398 ok( test3->service_count == 2, "got %u\n", test3->service_count );
3399 ok( !wcscmp( test3->service[0].name, L"1" ), "wrong data\n" );
3400 ok( !wcscmp( test3->service[0].id, L"1" ), "wrong data\n" );
3401 ok( !wcscmp( test3->service[1].name, L"2" ), "wrong data\n" );
3402 ok( !wcscmp( test3->service[1].id, L"2" ), "wrong data\n" );
3404 /* empty text, item range */
3405 prepare_struct_type_test( reader, data6 );
3407 memset( &f2, 0, sizeof(f2) );
3408 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
3409 f2.localName = &str_name;
3410 f2.ns = &str_ns;
3411 f2.type = WS_STRING_TYPE;
3412 fields2[0] = &f2;
3414 memset( &s2, 0, sizeof(s2) );
3415 s2.size = sizeof(struct service4);
3416 s2.alignment = TYPE_ALIGNMENT(struct service4);
3417 s2.fields = fields2;
3418 s2.fieldCount = 1;
3419 s2.typeLocalName = &str_service;
3421 range.minItemCount = 1;
3422 range.maxItemCount = 2;
3423 memset( &f, 0, sizeof(f) );
3424 f.mapping = WS_REPEATING_ELEMENT_FIELD_MAPPING;
3425 f.countOffset = FIELD_OFFSET(struct services5, service_count);
3426 f.type = WS_STRUCT_TYPE;
3427 f.typeDescription = &s2;
3428 f.itemLocalName = &str_service;
3429 f.itemNs = &str_ns;
3430 f.itemRange = &range;
3431 fields[0] = &f;
3433 memset( &s, 0, sizeof(s) );
3434 s.size = sizeof(struct services5);
3435 s.alignment = TYPE_ALIGNMENT(struct services5);
3436 s.fields = fields;
3437 s.fieldCount = 1;
3438 s.typeLocalName = &str_services;
3440 test5 = NULL;
3441 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3442 WS_READ_REQUIRED_POINTER, heap, &test5, sizeof(test5), NULL );
3443 ok( hr == S_OK, "got %08x\n", hr );
3444 ok( test5 != NULL, "test5 not set\n" );
3445 ok( test5->service != NULL, "service not set\n" );
3446 ok( test5->service_count == 1, "got %u\n", test5->service_count );
3447 ok( !test5->service[0].name.length, "got %u\n", test5->service[0].name.length );
3448 todo_wine ok( test5->service[0].name.chars != NULL, "chars set\n" );
3450 WsFreeReader( reader );
3451 WsFreeHeap( heap );
3454 static void test_WsResetHeap(void)
3456 HRESULT hr;
3457 WS_HEAP *heap;
3458 SIZE_T requested, actual;
3459 ULONG size;
3460 void *ptr;
3462 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3463 ok( hr == S_OK, "got %08x\n", hr );
3465 requested = 0xdeadbeef;
3466 size = sizeof(requested);
3467 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3468 ok( hr == S_OK, "got %08x\n", hr );
3469 ok( !requested, "got %u\n", (ULONG)requested );
3471 actual = 0xdeadbeef;
3472 size = sizeof(actual);
3473 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3474 ok( hr == S_OK, "got %08x\n", hr );
3475 ok( !actual, "got %u\n", (ULONG)actual );
3477 hr = WsAlloc( heap, 128, &ptr, NULL );
3478 ok( hr == S_OK, "got %08x\n", hr );
3480 requested = 0xdeadbeef;
3481 size = sizeof(requested);
3482 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3483 ok( hr == S_OK, "got %08x\n", hr );
3484 ok( requested == 128, "got %u\n", (ULONG)requested );
3486 actual = 0xdeadbeef;
3487 size = sizeof(actual);
3488 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3489 ok( hr == S_OK, "got %08x\n", hr );
3490 ok( actual == 128, "got %u\n", (ULONG)actual );
3492 hr = WsAlloc( heap, 1, &ptr, NULL );
3493 ok( hr == S_OK, "got %08x\n", hr );
3495 requested = 0xdeadbeef;
3496 size = sizeof(requested);
3497 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3498 ok( hr == S_OK, "got %08x\n", hr );
3499 ok( requested == 129, "got %u\n", (ULONG)requested );
3501 actual = 0xdeadbeef;
3502 size = sizeof(actual);
3503 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3504 ok( hr == S_OK, "got %08x\n", hr );
3505 todo_wine ok( actual == 384, "got %u\n", (ULONG)actual );
3507 hr = WsResetHeap( NULL, NULL );
3508 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3510 hr = WsResetHeap( heap, NULL );
3511 ok( hr == S_OK, "got %08x\n", hr );
3513 requested = 0xdeadbeef;
3514 size = sizeof(requested);
3515 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3516 ok( hr == S_OK, "got %08x\n", hr );
3517 ok( !requested, "got %u\n", (ULONG)requested );
3519 actual = 0xdeadbeef;
3520 size = sizeof(actual);
3521 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3522 ok( hr == S_OK, "got %08x\n", hr );
3523 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
3525 WsFreeHeap( heap );
3528 static void test_datetime(void)
3530 static const struct
3532 const char *str;
3533 HRESULT hr;
3534 __int64 ticks;
3535 WS_DATETIME_FORMAT format;
3537 tests[] =
3539 {"<t>0000-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3540 {"<t>0001-01-01T00:00:00Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3541 {"<t>0001-01-01T00:00:00.Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3542 {"<t>0001-01-01T00:00:00.0Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3543 {"<t>0001-01-01T00:00:00.1Z</t>", S_OK, 0x0000f4240, WS_DATETIME_FORMAT_UTC},
3544 {"<t>0001-01-01T00:00:00.01Z</t>", S_OK, 0x0000186a0, WS_DATETIME_FORMAT_UTC},
3545 {"<t>0001-01-01T00:00:00.0000001Z</t>", S_OK, 1, WS_DATETIME_FORMAT_UTC},
3546 {"<t>0001-01-01T00:00:00.9999999Z</t>", S_OK, 0x00098967f, WS_DATETIME_FORMAT_UTC},
3547 {"<t>0001-01-01T00:00:00.0000000Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3548 {"<t>0001-01-01T00:00:00.00000001Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3549 {"<t>0001-01-01T00:00:00Z-</t>", WS_E_INVALID_FORMAT, 0},
3550 {"<t>-0001-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3551 {"<t>0001-00-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3552 {"<t>0001-13-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3553 {"<t>0001-12-01T00:00:00Z</t>", S_OK, 0x1067555f88000, WS_DATETIME_FORMAT_UTC},
3554 {"<t>0001-01-00T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3555 {"<t>2001-01-32T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3556 {"<t>2001-01-31T00:00:00Z</t>", S_OK, 0x8c2592fe3794000, WS_DATETIME_FORMAT_UTC},
3557 {"<t>1900-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3558 {"<t>2000-02-29T00:00:00Z</t>", S_OK, 0x8c1505f0e438000, 0},
3559 {"<t>2001-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3560 {"<t>2001-02-28T00:00:00Z</t>", S_OK, 0x8c26f30870a4000, WS_DATETIME_FORMAT_UTC},
3561 {"<t>0001-00-01U00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3562 {"<t>0001-01-01T24:00:00Z</t>", S_OK, 0xc92a69c000, WS_DATETIME_FORMAT_UTC},
3563 {"<t>0001-01-01T24:00:01Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3564 {"<t>0001-01-01T00:60:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3565 {"<t>0001-01-01T00:00:60Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3566 {"<t>0001-01-01T00:00:00Y</t>", WS_E_INVALID_FORMAT, 0, 0},
3567 {"<t>0001-01-01T00:00:00+00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3568 {"<t>0001-01-01T00:00:00-00:01</t>", S_OK, 0x023c34600, WS_DATETIME_FORMAT_LOCAL},
3569 {"<t>9999-12-31T24:00:00+00:01</t>", S_OK, 0x2bca2875d073fa00, WS_DATETIME_FORMAT_LOCAL},
3570 {"<t>9999-12-31T24:00:00-00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3571 {"<t>0002-01-01T00:00:00+14:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3572 {"<t>0002-01-01T00:00:00+15:00</t>", WS_E_INVALID_FORMAT, 0, 0},
3573 {"<t>0002-01-01T00:00:00+13:60</t>", WS_E_INVALID_FORMAT, 0, 0},
3574 {"<t>0002-01-01T00:00:00+13:59</t>", S_OK, 0x11e5c43cc5600, WS_DATETIME_FORMAT_LOCAL},
3575 {"<t>0002-01-01T00:00:00+01:00</t>", S_OK, 0x11ec917025800, WS_DATETIME_FORMAT_LOCAL},
3576 {"<t>2016-01-01T00:00:00-01:00</t>", S_OK, 0x8d31246dfbba800, WS_DATETIME_FORMAT_LOCAL},
3577 {"<t>2016-01-01T00:00:00Z</t>", S_OK, 0x8d3123e7df74000, WS_DATETIME_FORMAT_UTC},
3578 {"<t> 2016-01-02T03:04:05Z </t>", S_OK, 0x8d313215fb64080, WS_DATETIME_FORMAT_UTC},
3579 {"<t>+2016-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3580 {"<t></t>", WS_E_INVALID_FORMAT, 0, 0},
3581 {"<t>01-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3582 {"<t>1601-01-01T00:00:00Z</t>", S_OK, 0x701ce1722770000, WS_DATETIME_FORMAT_UTC},
3584 HRESULT hr;
3585 WS_XML_READER *reader;
3586 WS_HEAP *heap;
3587 WS_DATETIME date;
3588 ULONG i;
3590 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3591 ok( hr == S_OK, "got %08x\n", hr );
3593 hr = WsCreateReader( NULL, 0, &reader, NULL );
3594 ok( hr == S_OK, "got %08x\n", hr );
3595 for (i = 0; i < ARRAY_SIZE( tests ); i++)
3597 memset( &date, 0, sizeof(date) );
3598 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3599 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DATETIME_TYPE, NULL,
3600 WS_READ_REQUIRED_VALUE, heap, &date, sizeof(date), NULL );
3601 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3602 if (hr == S_OK)
3604 ok( date.ticks == tests[i].ticks, "%u: got %s\n", i, wine_dbgstr_longlong(date.ticks) );
3605 ok( date.format == tests[i].format, "%u: got %u\n", i, date.format );
3609 WsFreeReader( reader );
3610 WsFreeHeap( heap );
3613 static void test_WsDateTimeToFileTime(void)
3615 static const struct
3617 WS_DATETIME dt;
3618 HRESULT hr;
3619 FILETIME ft;
3621 tests[] =
3623 { {0, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3624 { {0x701ce172276ffff, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3625 { {0x701ce1722770000, WS_DATETIME_FORMAT_UTC}, S_OK, {0, 0} },
3626 { {0x2bca2875f4373fff, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c03fff, 0x24c85a5e} },
3627 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c04000, 0x24c85a5e} },
3628 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_LOCAL}, S_OK, {0xd1c04000, 0x24c85a5e} },
3629 { {~0, WS_DATETIME_FORMAT_UTC}, S_OK, {0xdd88ffff, 0xf8fe31e8} },
3631 WS_DATETIME dt;
3632 FILETIME ft;
3633 HRESULT hr;
3634 ULONG i;
3636 hr = WsDateTimeToFileTime( NULL, NULL, NULL );
3637 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3639 dt.ticks = 0x701ce172277000;
3640 dt.format = WS_DATETIME_FORMAT_UTC;
3641 hr = WsDateTimeToFileTime( &dt, NULL, NULL );
3642 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3644 hr = WsDateTimeToFileTime( NULL, &ft, NULL );
3645 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3647 for (i = 0; i < ARRAY_SIZE( tests ); i++)
3649 memset( &ft, 0, sizeof(ft) );
3650 hr = WsDateTimeToFileTime( &tests[i].dt, &ft, NULL );
3651 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3652 if (hr == S_OK)
3654 ok( ft.dwLowDateTime == tests[i].ft.dwLowDateTime, "%u: got %08x\n", i, ft.dwLowDateTime );
3655 ok( ft.dwHighDateTime == tests[i].ft.dwHighDateTime, "%u: got %08x\n", i, ft.dwHighDateTime );
3660 static void test_WsFileTimeToDateTime(void)
3662 WS_DATETIME dt;
3663 FILETIME ft;
3664 HRESULT hr;
3666 hr = WsFileTimeToDateTime( NULL, NULL, NULL );
3667 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3669 ft.dwLowDateTime = ft.dwHighDateTime = 0;
3670 hr = WsFileTimeToDateTime( &ft, NULL, NULL );
3671 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3673 hr = WsFileTimeToDateTime( NULL, &dt, NULL );
3674 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3676 dt.ticks = 0xdeadbeef;
3677 dt.format = 0xdeadbeef;
3678 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3679 ok( hr == S_OK, "got %08x\n", hr );
3680 ok( dt.ticks == 0x701ce1722770000, "got %s\n", wine_dbgstr_longlong(dt.ticks) );
3681 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3683 ft.dwLowDateTime = 0xd1c03fff;
3684 ft.dwHighDateTime = 0x24c85a5e;
3685 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3686 ok( hr == S_OK, "got %08x\n", hr );
3687 ok( dt.ticks == 0x2bca2875f4373fff, "got %s\n", wine_dbgstr_longlong(dt.ticks) );
3688 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3690 ft.dwLowDateTime++;
3691 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3692 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3694 ft.dwLowDateTime = 0xdd88ffff;
3695 ft.dwHighDateTime = 0xf8fe31e8;
3696 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3697 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3699 ft.dwLowDateTime++;
3700 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3701 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
3704 static void test_double(void)
3706 static const struct
3708 const char *str;
3709 HRESULT hr;
3710 ULONGLONG val;
3712 tests[] =
3714 {"<t>0.0</t>", S_OK, 0},
3715 {"<t>-0.0</t>", S_OK, 0x8000000000000000},
3716 {"<t>+0.0</t>", S_OK, 0},
3717 {"<t>-</t>", S_OK, 0},
3718 {"<t>-.</t>", S_OK, 0},
3719 {"<t>+</t>", S_OK, 0},
3720 {"<t>+.</t>", S_OK, 0},
3721 {"<t>.</t>", S_OK, 0},
3722 {"<t>.0</t>", S_OK, 0},
3723 {"<t>0.</t>", S_OK, 0},
3724 {"<t>0</t>", S_OK, 0},
3725 {"<t> 0 </t>", S_OK, 0},
3726 {"<t></t>", WS_E_INVALID_FORMAT, 0},
3727 {"<t>0,1</t>", WS_E_INVALID_FORMAT, 0},
3728 {"<t>1.1.</t>", WS_E_INVALID_FORMAT, 0},
3729 {"<t>1</t>", S_OK, 0x3ff0000000000000},
3730 {"<t>1.0000000000000002</t>", S_OK, 0x3ff0000000000001},
3731 {"<t>1.0000000000000004</t>", S_OK, 0x3ff0000000000002},
3732 {"<t>10000000000000000000</t>", S_OK, 0x43e158e460913d00},
3733 {"<t>100000000000000000000</t>", S_OK, 0x4415af1d78b58c40},
3734 {"<t>2</t>", S_OK, 0x4000000000000000},
3735 {"<t>-2</t>", S_OK, 0xc000000000000000},
3736 {"<t>nodouble</t>", WS_E_INVALID_FORMAT, 0},
3737 {"<t>INF</t>", S_OK, 0x7ff0000000000000},
3738 {"<t>-INF</t>", S_OK, 0xfff0000000000000},
3739 {"<t>+INF</t>", WS_E_INVALID_FORMAT, 0},
3740 {"<t>Infinity</t>", WS_E_INVALID_FORMAT, 0},
3741 {"<t>-Infinity</t>", WS_E_INVALID_FORMAT, 0},
3742 {"<t>inf</t>", WS_E_INVALID_FORMAT, 0},
3743 {"<t>NaN</t>", S_OK, 0xfff8000000000000},
3744 {"<t>-NaN</t>", WS_E_INVALID_FORMAT, 0},
3745 {"<t>NAN</t>", WS_E_INVALID_FORMAT, 0},
3746 {"<t>0.3</t>", S_OK, 0x3fd3333333333333},
3747 {"<t>0.33</t>", S_OK, 0x3fd51eb851eb851f},
3748 {"<t>0.333</t>", S_OK, 0x3fd54fdf3b645a1d},
3749 {"<t>0.3333</t>", S_OK, 0x3fd554c985f06f69},
3750 {"<t>0.33333</t>", S_OK, 0x3fd555475a31a4be},
3751 {"<t>0.333333</t>", S_OK, 0x3fd55553ef6b5d46},
3752 {"<t>0.3333333</t>", S_OK, 0x3fd55555318abc87},
3753 {"<t>0.33333333</t>", S_OK, 0x3fd5555551c112da},
3754 {"<t>0.333333333</t>", S_OK, 0x3fd5555554f9b516},
3755 {"<t>0.3333333333</t>", S_OK, 0x3fd55555554c2bb5},
3756 {"<t>0.33333333333</t>", S_OK, 0x3fd5555555546ac5},
3757 {"<t>0.3333333333333</t>", S_OK, 0x3fd55555555552fd},
3758 {"<t>0.33333333333333</t>", S_OK, 0x3fd5555555555519},
3759 {"<t>0.333333333333333</t>", S_OK, 0x3fd555555555554f},
3760 {"<t>0.3333333333333333</t>", S_OK, 0x3fd5555555555555},
3761 {"<t>0.33333333333333333</t>", S_OK, 0x3fd5555555555555},
3762 {"<t>0.1e10</t>", S_OK, 0x41cdcd6500000000},
3763 {"<t>1e</t>", WS_E_INVALID_FORMAT, 0},
3764 {"<t>1e0</t>", S_OK, 0x3ff0000000000000},
3765 {"<t>1e+1</t>", S_OK, 0x4024000000000000},
3766 {"<t>1e-1</t>", S_OK, 0x3fb999999999999a},
3767 {"<t>e10</t>", WS_E_INVALID_FORMAT, 0},
3768 {"<t>1e10.</t>", WS_E_INVALID_FORMAT, 0},
3769 {"<t>1E10</t>", S_OK, 0x4202a05f20000000},
3770 {"<t>1e10</t>", S_OK, 0x4202a05f20000000},
3771 {"<t>1e-10</t>", S_OK, 0x3ddb7cdfd9d7bdbb},
3772 {"<t>1.7976931348623158e308</t>", S_OK, 0x7fefffffffffffff},
3773 {"<t>1.7976931348623159e308</t>", S_OK, 0x7ff0000000000000},
3774 {"<t>4.94065645841247e-324</t>", S_OK, 0x1},
3776 HRESULT hr;
3777 WS_XML_READER *reader;
3778 WS_HEAP *heap;
3779 ULONGLONG val;
3780 ULONG i;
3782 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3783 ok( hr == S_OK, "got %08x\n", hr );
3785 hr = WsCreateReader( NULL, 0, &reader, NULL );
3786 ok( hr == S_OK, "got %08x\n", hr );
3788 for (i = 0; i < ARRAY_SIZE( tests ); i++)
3790 val = 0;
3791 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3792 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DOUBLE_TYPE, NULL,
3793 WS_READ_REQUIRED_VALUE, heap, &val, sizeof(val), NULL );
3794 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3795 if (hr == tests[i].hr) ok( val == tests[i].val, "%u: got %s\n", i, wine_dbgstr_longlong(val) );
3798 WsFreeReader( reader );
3799 WsFreeHeap( heap );
3802 static void test_WsReadElement(void)
3804 WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
3805 HRESULT hr;
3806 WS_XML_READER *reader;
3807 WS_ELEMENT_DESCRIPTION desc;
3808 UINT32 val;
3810 hr = WsCreateReader( NULL, 0, &reader, NULL );
3811 ok( hr == S_OK, "got %08x\n", hr );
3813 desc.elementLocalName = &localname;
3814 desc.elementNs = &ns;
3815 desc.type = WS_UINT32_TYPE;
3816 desc.typeDescription = NULL;
3818 prepare_struct_type_test( reader, "<t>1</t>" );
3819 hr = WsReadElement( NULL, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3820 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3822 prepare_struct_type_test( reader, "<t>1</t>" );
3823 hr = WsReadElement( reader, NULL, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3824 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3826 prepare_struct_type_test( reader, "<t>1</t>" );
3827 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, NULL, sizeof(val), NULL );
3828 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3830 prepare_struct_type_test( reader, "<t>1</t>" );
3831 val = 0xdeadbeef;
3832 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3833 ok( hr == S_OK, "got %08x\n", hr );
3834 ok( val == 1, "got %u\n", val );
3836 WsFreeReader( reader );
3839 static void test_WsReadValue(void)
3841 HRESULT hr;
3842 WS_XML_READER *reader;
3843 UINT32 val;
3845 hr = WsCreateReader( NULL, 0, &reader, NULL );
3846 ok( hr == S_OK, "got %08x\n", hr );
3848 prepare_struct_type_test( reader, "<t>1</t>" );
3849 hr = WsReadValue( NULL, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3850 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3852 prepare_struct_type_test( reader, "<t>1</t>" );
3853 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, NULL, sizeof(val), NULL );
3854 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3856 /* reader must be positioned correctly */
3857 prepare_struct_type_test( reader, "<t>1</t>" );
3858 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3859 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3861 prepare_struct_type_test( reader, "<t>1</t>" );
3862 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3863 ok( hr == S_OK, "got %08x\n", hr );
3865 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3866 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3868 prepare_struct_type_test( reader, "<t>1</t>" );
3869 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3870 ok( hr == S_OK, "got %08x\n", hr );
3872 hr = WsReadStartElement( reader, NULL );
3873 ok( hr == S_OK, "got %08x\n", hr );
3875 val = 0xdeadbeef;
3876 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3877 ok( hr == S_OK, "got %08x\n", hr );
3878 ok( val == 1, "got %u\n", val );
3880 prepare_struct_type_test( reader, "<u t='1'></u>" );
3881 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3882 ok( hr == S_OK, "got %08x\n", hr );
3884 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3885 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3887 WsFreeReader( reader );
3890 static void test_WsResetError(void)
3892 WS_ERROR_PROPERTY prop;
3893 ULONG size, code;
3894 WS_ERROR *error;
3895 LANGID langid;
3896 HRESULT hr;
3898 hr = WsResetError( NULL );
3899 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3901 error = NULL;
3902 hr = WsCreateError( NULL, 0, &error );
3903 ok( hr == S_OK, "got %08x\n", hr );
3904 ok( error != NULL, "error not set\n" );
3906 code = 0xdeadbeef;
3907 size = sizeof(code);
3908 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3909 ok( hr == S_OK, "got %08x\n", hr );
3911 hr = WsResetError( error );
3912 ok( hr == S_OK, "got %08x\n", hr );
3914 code = 0xdeadbeef;
3915 size = sizeof(code);
3916 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3917 ok( hr == S_OK, "got %08x\n", hr );
3918 ok( !code, "got %u\n", code );
3920 WsFreeError( error );
3922 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
3923 prop.id = WS_ERROR_PROPERTY_LANGID;
3924 prop.value = &langid;
3925 prop.valueSize = sizeof(langid);
3926 hr = WsCreateError( &prop, 1, &error );
3927 ok( hr == S_OK, "got %08x\n", hr );
3929 langid = 0xdead;
3930 size = sizeof(langid);
3931 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3932 ok( hr == S_OK, "got %08x\n", hr );
3933 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3935 hr = WsResetError( error );
3936 ok( hr == S_OK, "got %08x\n", hr );
3938 langid = 0xdead;
3939 size = sizeof(langid);
3940 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3941 ok( hr == S_OK, "got %08x\n", hr );
3942 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3944 WsFreeError( error );
3947 static void test_WsGetReaderPosition(void)
3949 WS_HEAP *heap;
3950 WS_XML_READER *reader;
3951 WS_XML_BUFFER *buffer;
3952 WS_XML_NODE_POSITION pos;
3953 HRESULT hr;
3955 hr = WsGetReaderPosition( NULL, NULL, NULL );
3956 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3958 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3959 ok( hr == S_OK, "got %08x\n", hr );
3961 hr = WsCreateReader( NULL, 0, &reader, NULL );
3962 ok( hr == S_OK, "got %08x\n", hr );
3964 /* reader must be set to an XML buffer */
3965 hr = WsGetReaderPosition( reader, &pos, NULL );
3966 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3968 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
3969 ok( hr == S_OK, "got %08x\n", hr );
3971 hr = WsGetReaderPosition( reader, &pos, NULL );
3972 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3974 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
3975 ok( hr == S_OK, "got %08x\n", hr );
3977 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
3978 ok( hr == S_OK, "got %08x\n", hr );
3980 hr = WsGetReaderPosition( reader, NULL, NULL );
3981 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3983 pos.buffer = pos.node = NULL;
3984 hr = WsGetReaderPosition( reader, &pos, NULL );
3985 ok( hr == S_OK, "got %08x\n", hr );
3986 ok( pos.buffer != NULL, "buffer not set\n" );
3987 ok( pos.node != NULL, "node not set\n" );
3989 WsFreeReader( reader );
3990 WsFreeHeap( heap );
3993 static void test_WsSetReaderPosition(void)
3995 WS_HEAP *heap;
3996 WS_XML_READER *reader;
3997 WS_XML_BUFFER *buf1, *buf2;
3998 WS_XML_NODE_POSITION pos;
3999 HRESULT hr;
4001 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
4002 ok( hr == S_OK, "got %08x\n", hr );
4004 hr = WsSetReaderPosition( NULL, NULL, NULL );
4005 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4007 hr = WsCreateReader( NULL, 0, &reader, NULL );
4008 ok( hr == S_OK, "got %08x\n", hr );
4010 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf1, NULL );
4011 ok( hr == S_OK, "got %08x\n", hr );
4013 hr = WsSetInputToBuffer( reader, buf1, NULL, 0, NULL );
4014 ok( hr == S_OK, "got %08x\n", hr );
4016 hr = WsSetReaderPosition( reader, NULL, NULL );
4017 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4019 pos.buffer = pos.node = NULL;
4020 hr = WsGetReaderPosition( reader, &pos, NULL );
4021 ok( hr == S_OK, "got %08x\n", hr );
4022 ok( pos.buffer == buf1, "wrong buffer\n" );
4023 ok( pos.node != NULL, "node not set\n" );
4025 hr = WsSetReaderPosition( reader, &pos, NULL );
4026 ok( hr == S_OK, "got %08x\n", hr );
4028 /* different buffer */
4029 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf2, NULL );
4030 ok( hr == S_OK, "got %08x\n", hr );
4032 pos.buffer = buf2;
4033 hr = WsSetReaderPosition( reader, &pos, NULL );
4034 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4036 WsFreeReader( reader );
4037 WsFreeHeap( heap );
4040 static void test_entities(void)
4042 static const char str1[] = "<t>&#xA</t>";
4043 static const char str2[] = "<t>&#xA;</t>";
4044 static const char str3[] = "<t>&#xa;</t>";
4045 static const char str4[] = "<t>&#xaaaa;</t>";
4046 static const char str5[] = "<t>&#xaaaaa;</t>";
4047 static const char str6[] = "<t>&1</t>";
4048 static const char str7[] = "<t>&1;</t>";
4049 static const char str8[] = "<t>&1111;</t>";
4050 static const char str9[] = "<t>&11111;</t>";
4051 static const char str10[] = "<t>&lt;</t>";
4052 static const char str11[] = "<t>&gt;</t>";
4053 static const char str12[] = "<t>&quot;</t>";
4054 static const char str13[] = "<t>&amp;</t>";
4055 static const char str14[] = "<t>&apos;</t>";
4056 static const char str15[] = "<t>&sopa;</t>";
4057 static const char str16[] = "<t>&#;</t>";
4058 static const char str17[] = "<t>&;</t>";
4059 static const char str18[] = "<t>&&</t>";
4060 static const char str19[] = "<t>&</t>";
4061 static const char str20[] = "<t>&#xaaaaaa;</t>";
4062 static const char str21[] = "<t>&#xd7ff;</t>";
4063 static const char str22[] = "<t>&#xd800;</t>";
4064 static const char str23[] = "<t>&#xdfff;</t>";
4065 static const char str24[] = "<t>&#xe000;</t>";
4066 static const char str25[] = "<t>&#xfffe;</t>";
4067 static const char str26[] = "<t>&#xffff;</t>";
4068 static const char str27[] = "<t>&LT;</t>";
4069 static const char str28[] = "<t>&#x0;</t>";
4070 static const char str29[] = "<t>&#0;</t>";
4071 static const char str30[] = "<t>&#65;</t>";
4072 static const char str31[] = "<t>&#65393;</t>";
4073 static const char str32[] = "<t>&#x10ffff;</t>";
4074 static const char str33[] = "<t>&#x110000;</t>";
4075 static const char str34[] = "<t>&#1114111;</t>";
4076 static const char str35[] = "<t>&#1114112;</t>";
4077 static const char res4[] = {0xea, 0xaa, 0xaa, 0x00};
4078 static const char res5[] = {0xf2, 0xaa, 0xaa, 0xaa, 0x00};
4079 static const char res21[] = {0xed, 0x9f, 0xbf, 0x00};
4080 static const char res24[] = {0xee, 0x80, 0x80, 0x00};
4081 static const char res31[] = {0xef, 0xbd, 0xb1, 0x00};
4082 static const char res32[] = {0xf4, 0x8f, 0xbf, 0xbf, 0x00};
4083 static const struct
4085 const char *str;
4086 HRESULT hr;
4087 const char *res;
4089 tests[] =
4091 { str1, WS_E_INVALID_FORMAT },
4092 { str2, S_OK, "\n" },
4093 { str3, S_OK, "\n" },
4094 { str4, S_OK, res4 },
4095 { str5, S_OK, res5 },
4096 { str6, WS_E_INVALID_FORMAT },
4097 { str7, WS_E_INVALID_FORMAT },
4098 { str8, WS_E_INVALID_FORMAT },
4099 { str9, WS_E_INVALID_FORMAT },
4100 { str10, S_OK, "<" },
4101 { str11, S_OK, ">" },
4102 { str12, S_OK, "\"" },
4103 { str13, S_OK, "&" },
4104 { str14, S_OK, "'" },
4105 { str15, WS_E_INVALID_FORMAT },
4106 { str16, WS_E_INVALID_FORMAT },
4107 { str17, WS_E_INVALID_FORMAT },
4108 { str18, WS_E_INVALID_FORMAT },
4109 { str19, WS_E_INVALID_FORMAT },
4110 { str20, WS_E_INVALID_FORMAT },
4111 { str21, S_OK, res21 },
4112 { str22, WS_E_INVALID_FORMAT },
4113 { str23, WS_E_INVALID_FORMAT },
4114 { str24, S_OK, res24 },
4115 { str25, WS_E_INVALID_FORMAT },
4116 { str26, WS_E_INVALID_FORMAT },
4117 { str27, WS_E_INVALID_FORMAT },
4118 { str28, WS_E_INVALID_FORMAT },
4119 { str29, WS_E_INVALID_FORMAT },
4120 { str30, S_OK, "A" },
4121 { str31, S_OK, res31 },
4122 { str32, S_OK, res32 },
4123 { str33, WS_E_INVALID_FORMAT },
4124 { str34, S_OK, res32 },
4125 { str35, WS_E_INVALID_FORMAT },
4127 HRESULT hr;
4128 WS_XML_READER *reader;
4129 const WS_XML_NODE *node;
4130 const WS_XML_UTF8_TEXT *utf8;
4131 ULONG i;
4133 hr = WsCreateReader( NULL, 0, &reader, NULL );
4134 ok( hr == S_OK, "got %08x\n", hr );
4136 for (i = 0; i < ARRAY_SIZE( tests ); i++)
4138 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
4139 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4141 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4142 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4144 hr = WsReadNode( reader, NULL );
4145 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
4146 if (hr != S_OK) continue;
4148 hr = WsGetReaderNode( reader, &node, NULL );
4149 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4151 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_TEXT_NODE *)node)->text;
4152 ok( utf8->value.length == strlen(tests[i].res), "%u: got %u\n", i, utf8->value.length );
4153 ok( !memcmp( utf8->value.bytes, tests[i].res, strlen(tests[i].res) ), "%u: wrong data\n", i );
4156 hr = set_input( reader, "<t a='&#xA;&#xA;'/>", sizeof("<t a='&#xA;&#xA;'/>") - 1 );
4157 ok( hr == S_OK, "got %08x\n", hr );
4159 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4160 ok( hr == S_OK, "got %08x\n", hr );
4162 hr = WsGetReaderNode( reader, &node, NULL );
4163 ok( hr == S_OK, "got %08x\n", hr );
4165 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_ELEMENT_NODE *)node)->attributes[0]->value;
4166 ok( utf8->value.length == 2, "got %u\n", utf8->value.length );
4167 ok( !memcmp( utf8->value.bytes, "\n\n", 2 ), "wrong data\n" );
4169 WsFreeReader( reader );
4172 static void test_field_options(void)
4174 static const char xml[] =
4175 "<t xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><wsz i:nil=\"true\"/>"
4176 "<s i:nil=\"true\"/></t>";
4177 HRESULT hr;
4178 WS_HEAP *heap;
4179 WS_XML_READER *reader;
4180 WS_STRUCT_DESCRIPTION s, s2;
4181 WS_FIELD_DESCRIPTION f, f2, f3, f4, f5, *fields[4], *fields2[1];
4182 WS_XML_STRING ns = {0, NULL}, str_wsz = {3, (BYTE *)"wsz"}, str_s = {1, (BYTE *)"s"};
4183 WS_XML_STRING str_int32 = {5, (BYTE *)"int32"}, str_guid = {4, (BYTE *)"guid"};
4184 WS_DEFAULT_VALUE def_val;
4185 INT32 val_int32;
4186 struct s
4188 INT32 int32;
4190 struct test
4192 WCHAR *wsz;
4193 struct s *s;
4194 INT32 int32;
4195 GUID guid;
4196 } *test;
4198 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
4199 ok( hr == S_OK, "got %08x\n", hr );
4201 hr = WsCreateReader( NULL, 0, &reader, NULL );
4202 ok( hr == S_OK, "got %08x\n", hr );
4204 hr = set_input( reader, xml, sizeof(xml) - 1 );
4205 ok( hr == S_OK, "got %08x\n", hr );
4207 memset( &f, 0, sizeof(f) );
4208 f.mapping = WS_ELEMENT_FIELD_MAPPING;
4209 f.localName = &str_wsz;
4210 f.ns = &ns;
4211 f.type = WS_WSZ_TYPE;
4212 f.options = WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
4213 fields[0] = &f;
4215 memset( &f3, 0, sizeof(f3) );
4216 f3.mapping = WS_ELEMENT_FIELD_MAPPING;
4217 f3.localName = &str_int32;
4218 f3.ns = &ns;
4219 f3.type = WS_INT32_TYPE;
4220 fields2[0] = &f3;
4222 memset( &s2, 0, sizeof(s2) );
4223 s2.size = sizeof(struct s);
4224 s2.alignment = TYPE_ALIGNMENT(struct s);
4225 s2.fields = fields2;
4226 s2.fieldCount = 1;
4228 memset( &f2, 0, sizeof(f2) );
4229 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
4230 f2.localName = &str_s;
4231 f2.ns = &ns;
4232 f2.type = WS_STRUCT_TYPE;
4233 f2.typeDescription = &s2;
4234 f2.offset = FIELD_OFFSET(struct test, s);
4235 f2.options = WS_FIELD_POINTER|WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
4236 fields[1] = &f2;
4238 val_int32 = -1;
4239 def_val.value = &val_int32;
4240 def_val.valueSize = sizeof(val_int32);
4242 memset( &f4, 0, sizeof(f4) );
4243 f4.mapping = WS_ELEMENT_FIELD_MAPPING;
4244 f4.localName = &str_int32;
4245 f4.ns = &ns;
4246 f4.type = WS_INT32_TYPE;
4247 f4.offset = FIELD_OFFSET(struct test, int32);
4248 f4.options = WS_FIELD_OPTIONAL;
4249 f4.defaultValue = &def_val;
4250 fields[2] = &f4;
4252 memset( &f5, 0, sizeof(f5) );
4253 f5.mapping = WS_ELEMENT_FIELD_MAPPING;
4254 f5.localName = &str_guid;
4255 f5.ns = &ns;
4256 f5.type = WS_GUID_TYPE;
4257 f5.offset = FIELD_OFFSET(struct test, guid);
4258 f5.options = WS_FIELD_OPTIONAL;
4259 fields[3] = &f5;
4261 memset( &s, 0, sizeof(s) );
4262 s.size = sizeof(struct test);
4263 s.alignment = TYPE_ALIGNMENT(struct test);
4264 s.fields = fields;
4265 s.fieldCount = 4;
4267 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
4268 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
4269 ok( hr == S_OK, "got %08x\n", hr );
4270 ok( !test->wsz, "wsz is set\n" );
4271 ok( !test->s, "s is set\n" );
4272 ok( test->int32 == -1, "got %d\n", test->int32 );
4273 ok( IsEqualGUID( &test->guid, &guid_null ), "wrong guid\n" );
4275 WsFreeReader( reader );
4276 WsFreeHeap( heap );
4279 static void test_WsReadBytes(void)
4281 HRESULT hr;
4282 WS_XML_READER *reader;
4283 const WS_XML_NODE *node;
4284 const WS_XML_TEXT_NODE *text;
4285 const WS_XML_UTF8_TEXT *utf8;
4286 BYTE buf[4];
4287 ULONG count;
4289 hr = WsCreateReader( NULL, 0, &reader, NULL );
4290 ok( hr == S_OK, "got %08x\n", hr );
4292 hr = WsReadBytes( NULL, NULL, 0, NULL, NULL );
4293 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4295 hr = WsReadBytes( reader, NULL, 0, NULL, NULL );
4296 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4298 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
4299 ok( hr == S_OK, "got %08x\n", hr );
4301 hr = WsReadBytes( reader, NULL, 0, NULL, NULL );
4302 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4304 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
4305 ok( hr == S_OK, "got %08x\n", hr );
4307 hr = WsReadBytes( reader, buf, 0, NULL, NULL );
4308 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4310 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
4311 ok( hr == S_OK, "got %08x\n", hr );
4313 count = 0xdeadbeef;
4314 hr = WsReadBytes( reader, NULL, 0, &count, NULL );
4315 ok( hr == S_OK, "got %08x\n", hr );
4316 ok( !count, "got %u\n", count );
4318 count = 0xdeadbeef;
4319 hr = WsReadBytes( reader, NULL, 1, &count, NULL );
4320 ok( hr == S_OK, "got %08x\n", hr );
4321 ok( !count, "got %u\n", count );
4323 buf[0] = 0;
4324 count = 0xdeadbeef;
4325 hr = WsReadBytes( reader, buf, 0, &count, NULL );
4326 ok( hr == S_OK, "got %08x\n", hr );
4327 ok( !count, "got %u\n", count );
4328 ok( !buf[0], "wrong data\n" );
4330 buf[0] = 0;
4331 count = 0xdeadbeef;
4332 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4333 ok( hr == S_OK, "got %08x\n", hr );
4334 ok( !count, "got %u\n", count );
4335 ok( !buf[0], "wrong data\n" );
4337 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4338 ok( hr == S_OK, "got %08x\n", hr );
4340 buf[0] = 0;
4341 count = 0xdeadbeef;
4342 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4343 ok( hr == S_OK, "got %08x\n", hr );
4344 ok( !count, "got %u\n", count );
4345 ok( !buf[0], "wrong data\n" );
4347 hr = WsReadStartElement( reader, NULL );
4348 ok( hr == S_OK, "got %08x\n", hr );
4350 count = 0xdeadbeef;
4351 hr = WsReadBytes( reader, NULL, 0, &count, NULL );
4352 ok( hr == S_OK, "got %08x\n", hr );
4353 ok( !count, "got %u\n", count );
4355 buf[0] = 0;
4356 count = 0xdeadbeef;
4357 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4358 ok( hr == S_OK, "got %08x\n", hr );
4359 ok( count == 2, "got %u\n", count );
4360 ok( !memcmp( buf, "te", 2 ), "wrong data\n" );
4362 hr = WsGetReaderNode( reader, &node, NULL );
4363 ok( hr == S_OK, "got %08x\n", hr );
4364 text = (const WS_XML_TEXT_NODE *)node;
4365 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4366 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4367 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4368 ok( utf8->value.length == 8, "got %u\n", utf8->value.length );
4369 ok( !memcmp( utf8->value.bytes, "dGV4dA==", 8 ), "wrong data\n" );
4371 buf[0] = 0;
4372 count = 0xdeadbeef;
4373 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4374 ok( hr == S_OK, "got %08x\n", hr );
4375 ok( count == 2, "got %u\n", count );
4376 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4378 hr = WsGetReaderNode( reader, &node, NULL );
4379 ok( hr == S_OK, "got %08x\n", hr );
4380 text = (const WS_XML_TEXT_NODE *)node;
4381 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4383 count = 0xdeadbeef;
4384 hr = WsReadBytes( reader, buf, 1, &count, NULL );
4385 ok( hr == S_OK, "got %08x\n", hr );
4386 ok( !count, "got %u\n", count );
4388 hr = WsGetReaderNode( reader, &node, NULL );
4389 ok( hr == S_OK, "got %08x\n", hr );
4390 text = (const WS_XML_TEXT_NODE *)node;
4391 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4393 WsFreeReader( reader );
4396 static void test_WsReadChars(void)
4398 HRESULT hr;
4399 WS_XML_READER *reader;
4400 const WS_XML_NODE *node;
4401 const WS_XML_TEXT_NODE *text;
4402 const WS_XML_UTF8_TEXT *utf8;
4403 unsigned char buf[4];
4404 WCHAR bufW[4];
4405 ULONG count;
4407 hr = WsCreateReader( NULL, 0, &reader, NULL );
4408 ok( hr == S_OK, "got %08x\n", hr );
4410 hr = WsReadChars( NULL, NULL, 0, NULL, NULL );
4411 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4413 hr = WsReadChars( reader, NULL, 0, NULL, NULL );
4414 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4416 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4417 ok( hr == S_OK, "got %08x\n", hr );
4419 hr = WsReadChars( reader, NULL, 0, NULL, NULL );
4420 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4422 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4423 ok( hr == S_OK, "got %08x\n", hr );
4425 hr = WsReadChars( reader, bufW, 0, NULL, NULL );
4426 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4428 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4429 ok( hr == S_OK, "got %08x\n", hr );
4431 count = 0xdeadbeef;
4432 hr = WsReadChars( reader, NULL, 0, &count, NULL );
4433 ok( hr == S_OK, "got %08x\n", hr );
4434 ok( !count, "got %u\n", count );
4436 count = 0xdeadbeef;
4437 hr = WsReadChars( reader, NULL, 1, &count, NULL );
4438 ok( hr == S_OK, "got %08x\n", hr );
4439 ok( !count, "got %u\n", count );
4441 buf[0] = 0;
4442 count = 0xdeadbeef;
4443 hr = WsReadChars( reader, bufW, 0, &count, NULL );
4444 ok( hr == S_OK, "got %08x\n", hr );
4445 ok( !count, "got %u\n", count );
4446 ok( !buf[0], "wrong data\n" );
4448 buf[0] = 0;
4449 count = 0xdeadbeef;
4450 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4451 ok( hr == S_OK, "got %08x\n", hr );
4452 ok( !count, "got %u\n", count );
4453 ok( !buf[0], "wrong data\n" );
4455 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4456 ok( hr == S_OK, "got %08x\n", hr );
4458 buf[0] = 0;
4459 count = 0xdeadbeef;
4460 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4461 ok( hr == S_OK, "got %08x\n", hr );
4462 ok( !count, "got %u\n", count );
4463 ok( !buf[0], "wrong data\n" );
4465 hr = WsReadStartElement( reader, NULL );
4466 ok( hr == S_OK, "got %08x\n", hr );
4468 count = 0xdeadbeef;
4469 hr = WsReadChars( reader, NULL, 0, &count, NULL );
4470 ok( hr == S_OK, "got %08x\n", hr );
4471 ok( !count, "got %u\n", count );
4473 buf[0] = 0;
4474 count = 0xdeadbeef;
4475 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4476 ok( hr == S_OK, "got %08x\n", hr );
4477 ok( count == 2, "got %u\n", count );
4478 ok( !memcmp( bufW, L"te", 2 * sizeof(WCHAR) ), "wrong data\n" );
4480 hr = WsGetReaderNode( reader, &node, NULL );
4481 ok( hr == S_OK, "got %08x\n", hr );
4482 text = (const WS_XML_TEXT_NODE *)node;
4483 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4484 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4485 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4486 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4487 ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" );
4489 /* continue reading in a different encoding */
4490 buf[0] = 0;
4491 count = 0xdeadbeef;
4492 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4493 ok( hr == S_OK, "got %08x\n", hr );
4494 ok( count == 2, "got %u\n", count );
4495 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4497 hr = WsGetReaderNode( reader, &node, NULL );
4498 ok( hr == S_OK, "got %08x\n", hr );
4499 text = (const WS_XML_TEXT_NODE *)node;
4500 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4502 count = 0xdeadbeef;
4503 hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL );
4504 ok( hr == S_OK, "got %08x\n", hr );
4505 ok( !count, "got %u\n", count );
4507 hr = WsGetReaderNode( reader, &node, NULL );
4508 ok( hr == S_OK, "got %08x\n", hr );
4509 text = (const WS_XML_TEXT_NODE *)node;
4510 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4512 WsFreeReader( reader );
4515 static void test_WsReadCharsUtf8(void)
4517 HRESULT hr;
4518 WS_XML_READER *reader;
4519 const WS_XML_NODE *node;
4520 const WS_XML_TEXT_NODE *text;
4521 const WS_XML_UTF8_TEXT *utf8;
4522 BYTE buf[4];
4523 ULONG count;
4525 hr = WsCreateReader( NULL, 0, &reader, NULL );
4526 ok( hr == S_OK, "got %08x\n", hr );
4528 hr = WsReadCharsUtf8( NULL, NULL, 0, NULL, NULL );
4529 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4531 hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL );
4532 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4534 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4535 ok( hr == S_OK, "got %08x\n", hr );
4537 hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL );
4538 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4540 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4541 ok( hr == S_OK, "got %08x\n", hr );
4543 hr = WsReadCharsUtf8( reader, buf, 0, NULL, NULL );
4544 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4546 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4547 ok( hr == S_OK, "got %08x\n", hr );
4549 count = 0xdeadbeef;
4550 hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL );
4551 ok( hr == S_OK, "got %08x\n", hr );
4552 ok( !count, "got %u\n", count );
4554 count = 0xdeadbeef;
4555 hr = WsReadCharsUtf8( reader, NULL, 1, &count, NULL );
4556 ok( hr == S_OK, "got %08x\n", hr );
4557 ok( !count, "got %u\n", count );
4559 buf[0] = 0;
4560 count = 0xdeadbeef;
4561 hr = WsReadCharsUtf8( reader, buf, 0, &count, NULL );
4562 ok( hr == S_OK, "got %08x\n", hr );
4563 ok( !count, "got %u\n", count );
4564 ok( !buf[0], "wrong data\n" );
4566 buf[0] = 0;
4567 count = 0xdeadbeef;
4568 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4569 ok( hr == S_OK, "got %08x\n", hr );
4570 ok( !count, "got %u\n", count );
4571 ok( !buf[0], "wrong data\n" );
4573 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4574 ok( hr == S_OK, "got %08x\n", hr );
4576 buf[0] = 0;
4577 count = 0xdeadbeef;
4578 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4579 ok( hr == S_OK, "got %08x\n", hr );
4580 ok( !count, "got %u\n", count );
4581 ok( !buf[0], "wrong data\n" );
4583 hr = WsReadStartElement( reader, NULL );
4584 ok( hr == S_OK, "got %08x\n", hr );
4586 count = 0xdeadbeef;
4587 hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL );
4588 ok( hr == S_OK, "got %08x\n", hr );
4589 ok( !count, "got %u\n", count );
4591 buf[0] = 0;
4592 count = 0xdeadbeef;
4593 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4594 ok( hr == S_OK, "got %08x\n", hr );
4595 ok( count == 2, "got %u\n", count );
4596 ok( !memcmp( buf, "te", 2 ), "wrong data\n" );
4598 hr = WsGetReaderNode( reader, &node, NULL );
4599 ok( hr == S_OK, "got %08x\n", hr );
4600 text = (const WS_XML_TEXT_NODE *)node;
4601 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4602 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4603 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4604 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4605 ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" );
4607 buf[0] = 0;
4608 count = 0xdeadbeef;
4609 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4610 ok( hr == S_OK, "got %08x\n", hr );
4611 ok( count == 2, "got %u\n", count );
4612 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4614 hr = WsGetReaderNode( reader, &node, NULL );
4615 ok( hr == S_OK, "got %08x\n", hr );
4616 text = (const WS_XML_TEXT_NODE *)node;
4617 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4619 count = 0xdeadbeef;
4620 hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL );
4621 ok( hr == S_OK, "got %08x\n", hr );
4622 ok( !count, "got %u\n", count );
4624 hr = WsGetReaderNode( reader, &node, NULL );
4625 ok( hr == S_OK, "got %08x\n", hr );
4626 text = (const WS_XML_TEXT_NODE *)node;
4627 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4629 WsFreeReader( reader );
4632 static void test_WsReadQualifiedName(void)
4634 static const char utf8[] = {'<','a','>',0xc3,0xab,'<','/','a','>',0};
4635 static const char localname_utf8[] = {0xc3,0xab,0};
4636 WS_XML_STRING prefix, localname, ns;
4637 WS_XML_READER *reader;
4638 WS_HEAP *heap;
4639 HRESULT hr;
4640 BOOL found;
4641 ULONG i;
4642 static const struct
4644 const char *str;
4645 HRESULT hr;
4646 const char *prefix;
4647 const char *localname;
4648 const char *ns;
4649 } tests[] =
4651 { "<a></a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4652 { "<a> </a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4653 { "<a>:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4654 { "<a>t</a>", S_OK, "", "t", "" },
4655 { "<a>p:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4656 { "<a>p:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4657 { "<a>:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4658 { "<a xmlns:p=\"ns\">p:t</a>", S_OK, "p", "t", "ns" },
4659 { "<a xmlns:p=\"ns\">p:t:</a>", S_OK, "p", "t:", "ns" },
4660 { "<a xmlns:p=\"ns\">p:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4661 { "<a xmlns:p=\"ns\">:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4662 { "<a xmlns:p=\"ns\">:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4663 { "<a xmlns:p=\"ns\">t</a>", S_OK, "", "t", "" },
4664 { "<a xmlns:p=\"ns\"> </a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4665 { "<a xmlns:p=\"ns\"></a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4666 { "<a xmlns:p=\"ns\">p:t u</a>", S_OK, "p", "t u", "ns" },
4667 { utf8, S_OK, "", localname_utf8, "" },
4668 { "<a> t </a>", S_OK, "", "t", "" },
4669 { "<a xmlns:p=\"ns\"> p:t</a>", S_OK, "p", "t", "ns" },
4670 { "<a xmlns:p=\"ns\">p :t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4671 { "<a xmlns:p=\"ns\">p: t</a>", S_OK, "p", " t", "ns" },
4674 hr = WsReadQualifiedName( NULL, NULL, NULL, NULL, NULL, NULL );
4675 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4677 hr = WsCreateReader( NULL, 0, &reader, NULL );
4678 ok( hr == S_OK, "got %08x\n", hr );
4680 hr = WsReadQualifiedName( reader, NULL, NULL, NULL, NULL, NULL );
4681 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4683 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
4684 ok( hr == S_OK, "got %08x\n", hr );
4686 hr = WsReadQualifiedName( reader, heap, NULL, NULL, NULL, NULL );
4687 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4689 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4690 ok( hr == S_OK, "got %08x\n", hr );
4691 hr = WsReadQualifiedName( reader, heap, NULL, NULL, NULL, NULL );
4692 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4694 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4695 ok( hr == S_OK, "got %08x\n", hr );
4696 hr = WsReadQualifiedName( reader, heap, NULL, &localname, NULL, NULL );
4697 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
4699 for (i = 0; i < ARRAY_SIZE( tests ); i++)
4701 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
4702 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4704 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4705 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4707 hr = WsReadStartElement( reader, NULL );
4708 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4710 prefix.length = localname.length = ns.length = 0xdeadbeef;
4711 prefix.bytes = localname.bytes = ns.bytes = (BYTE *)0xdeadbeef;
4713 hr = WsReadQualifiedName( reader, heap, &prefix, &localname, &ns, NULL );
4714 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
4715 if (tests[i].hr == S_OK && hr == S_OK)
4717 ok( prefix.length == strlen( tests[i].prefix ), "%u: got %u\n", i, prefix.length );
4718 ok( !memcmp( prefix.bytes, tests[i].prefix, prefix.length ), "%u: wrong data\n", i );
4720 ok( localname.length == strlen( tests[i].localname ), "%u: got %u\n", i, localname.length );
4721 ok( !memcmp( localname.bytes, tests[i].localname, localname.length ), "%u: wrong data\n", i );
4723 ok( ns.length == strlen( tests[i].ns ), "%u: got %u\n", i, ns.length );
4724 ok( !memcmp( ns.bytes, tests[i].ns, ns.length ), "%u: wrong data\n", i );
4726 else if (tests[i].hr != S_OK)
4728 ok( prefix.length == 0xdeadbeef, "got %u\n", prefix.length );
4729 ok( prefix.bytes == (BYTE *)0xdeadbeef, "got %p\n", prefix.bytes );
4731 ok( localname.length == 0xdeadbeef, "got %u\n", localname.length );
4732 ok( localname.bytes == (BYTE *)0xdeadbeef, "got %p\n", localname.bytes );
4734 ok( ns.length == 0xdeadbeef, "got %u\n", ns.length );
4735 ok( ns.bytes == (BYTE *)0xdeadbeef, "got %p\n", ns.bytes );
4739 WsFreeHeap( heap );
4740 WsFreeReader( reader );
4743 static void test_WsReadAttribute(void)
4745 WS_XML_STRING localname = {1, (BYTE *)"a"}, ns = {0, NULL};
4746 WS_XML_READER *reader;
4747 WS_ATTRIBUTE_DESCRIPTION desc;
4748 WS_HEAP *heap;
4749 UINT32 *val;
4750 BOOL found;
4751 HRESULT hr;
4753 hr = WsReadAttribute( NULL, NULL, 0, NULL, NULL, 0, NULL );
4754 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4756 hr = WsCreateReader( NULL, 0, &reader, NULL );
4757 ok( hr == S_OK, "got %08x\n", hr );
4759 hr = WsReadAttribute( reader, NULL, 0, NULL, NULL, 0, NULL );
4760 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4762 desc.attributeLocalName = &localname;
4763 desc.attributeNs = &ns;
4764 desc.type = WS_UINT32_TYPE;
4765 desc.typeDescription = NULL;
4766 hr = WsReadAttribute( reader, &desc, 0, NULL, NULL, 0, NULL );
4767 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4769 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, NULL, NULL, 0, NULL );
4770 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4772 hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL );
4773 ok( hr == S_OK, "got %08x\n", hr );
4775 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, NULL, 0, NULL );
4776 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4778 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, &val, sizeof(val), NULL );
4779 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4781 prepare_struct_type_test( reader, "<t a='1'>" );
4782 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4783 ok( hr == S_OK, "got %08x\n", hr );
4785 val = NULL;
4786 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, &val, sizeof(val), NULL );
4787 ok( hr == S_OK, "got %08x\n", hr );
4788 ok( val != NULL, "val not set\n" );
4789 ok( *val == 1, "got %u\n", *val );
4791 WsFreeHeap( heap );
4792 WsFreeReader( reader );
4795 static void test_WsSkipNode(void)
4797 const WS_XML_NODE *node;
4798 WS_XML_READER *reader;
4799 HRESULT hr;
4801 hr = WsSkipNode( NULL, NULL );
4802 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4804 hr = WsCreateReader( NULL, 0, &reader, NULL );
4805 ok( hr == S_OK, "got %08x\n", hr );
4807 hr = WsSkipNode( reader, NULL );
4808 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4810 hr = set_input( reader, "<t><u></u></t>", sizeof("<t><u></u></t>") - 1 );
4811 ok( hr == S_OK, "got %08x\n", hr );
4813 hr = WsGetReaderNode( reader, &node, NULL );
4814 ok( hr == S_OK, "got %08x\n", hr );
4815 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
4817 /* BOF */
4818 hr = WsSkipNode( reader, NULL );
4819 ok( hr == S_OK, "got %08x\n", hr );
4820 hr = WsGetReaderNode( reader, &node, NULL );
4821 ok( hr == S_OK, "got %08x\n", hr );
4822 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4824 /* element */
4825 hr = WsSkipNode( reader, NULL );
4826 ok( hr == S_OK, "got %08x\n", hr );
4827 hr = WsGetReaderNode( reader, &node, NULL );
4828 ok( hr == S_OK, "got %08x\n", hr );
4829 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
4831 /* EOF */
4832 hr = WsSkipNode( reader, NULL );
4833 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4835 hr = set_input( reader, "<!--comment--><t></t>", sizeof("<!--comment--><t></t>") - 1 );
4836 ok( hr == S_OK, "got %08x\n", hr );
4838 /* non-element */
4839 hr = WsSkipNode( reader, NULL );
4840 ok( hr == S_OK, "got %08x\n", hr );
4841 hr = WsGetReaderNode( reader, &node, NULL );
4842 ok( hr == S_OK, "got %08x\n", hr );
4843 ok( node->nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", node->nodeType );
4845 hr = WsSkipNode( reader, NULL );
4846 ok( hr == S_OK, "got %08x\n", hr );
4847 hr = WsGetReaderNode( reader, &node, NULL );
4848 ok( hr == S_OK, "got %08x\n", hr );
4849 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4851 WsFreeReader( reader );
4854 static HRESULT set_input_bin( WS_XML_READER *reader, const char *data, ULONG size, WS_XML_DICTIONARY *dict )
4856 WS_XML_READER_BINARY_ENCODING bin = {{WS_XML_READER_ENCODING_TYPE_BINARY}, dict};
4857 WS_XML_READER_BUFFER_INPUT buf;
4859 buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
4860 buf.encodedData = (void *)data;
4861 buf.encodedDataSize = size;
4862 return WsSetInput( reader, &bin.encoding, &buf.input, NULL, 0, NULL );
4865 static const WS_XML_TEXT_NODE *read_text_node( WS_XML_READER *reader )
4867 const WS_XML_NODE *node;
4868 if (WsReadNode( reader, NULL ) != S_OK) return NULL;
4869 if (WsReadNode( reader, NULL ) != S_OK) return NULL;
4870 if (WsGetReaderNode( reader, &node, NULL ) != S_OK) return NULL;
4871 if (node->nodeType != WS_XML_NODE_TYPE_TEXT) return NULL;
4872 return (const WS_XML_TEXT_NODE *)node;
4875 static void test_binary_encoding(void)
4877 static WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
4878 static const char test[] =
4879 {0x40,0x01,'t',0x01};
4880 static const char test2[] =
4881 {0x6d,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01};
4882 static const char test3[] =
4883 {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x01};
4884 static const char test4[] =
4885 {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x99,0x04,'t','e','s','t'};
4886 static const char test5[] =
4887 {0x40,0x01,'t',0x9f,0x01,'a'};
4888 static const char test6[] =
4889 {0x40,0x01,'t',0xa0,0x01,0x00,'a',0x9f,0x01,'b'};
4890 static const char test7[] =
4891 {0x40,0x01,'t',0xb5,0xff,0xff,0xff,0xff};
4892 static const char test8[] =
4893 {0x40,0x01,'t',0xb5,0x00,0x00,0x00,0x00};
4894 static const char test9[] =
4895 {0x40,0x01,'t',0x81};
4896 static const char test10[] =
4897 {0x40,0x01,'t',0x83};
4898 static const char test11[] =
4899 {0x40,0x01,'t',0x85};
4900 static const char test12[] =
4901 {0x40,0x01,'t',0x87};
4902 static const char test13[] =
4903 {0x40,0x01,'t',0x89,0xff};
4904 static const char test14[] =
4905 {0x40,0x01,'t',0x8b,0xff,0xff};
4906 static const char test15[] =
4907 {0x40,0x01,'t',0x8d,0xff,0xff,0xff,0xff};
4908 static const char test16[] =
4909 {0x40,0x01,'t',0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
4910 static const char test17[] =
4911 {0x40,0x01,'t',0x93,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
4912 static const char test18[] =
4913 {0x40,0x01,'t',0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
4914 static const char test19[] =
4915 {0x40,0x01,'t',0x99,0x01,0x61};
4916 static const char test20[] =
4917 {0x40,0x01,'t',0x9b,0x01,0x00,0x61};
4918 static const char test21[] =
4919 {0x40,0x01,'t',0x9d,0x01,0x00,0x00,0x00,0x61};
4920 static const char test22[] =
4921 {0x40,0x01,'t',0x9f,0x01,0x61};
4922 static const char test23[] =
4923 {0x40,0x01,'t',0xa1,0x01,0x00,0x61};
4924 static const char test24[] =
4925 {0x40,0x01,'t',0xa3,0x01,0x00,0x00,0x00,0x61};
4926 static const char test25[] =
4927 {0x40,0x01,'t',0xa9};
4928 static const char test26[] =
4929 {0x40,0x01,'t',0xab,0x0c};
4930 static const char test27[] =
4931 {0x40,0x01,'t',0xad,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
4932 static const char test28[] =
4933 {0x40,0x01,'t',0xb1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
4934 static const char test29[] =
4935 {0x40,0x01,'t',0xb3,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
4936 static const char test30[] =
4937 {0x40,0x01,'t',0x08,0x02,'n','s',0x01};
4938 static const char test31[] =
4939 {0x40,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01};
4940 static const char test100[] =
4941 {0x40,0x01,'t',0x04,0x01,'t',0x98,0x00,0x01};
4942 static const char test101[] =
4943 {0x40,0x01,'t',0x35,0x01,'t',0x98,0x00,0x09,0x01,'p',0x02,'n','s',0x01};
4944 static const char test102[] =
4945 {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x00,0x09,0x02,'p','2',0x02,'n','s',0x01};
4946 static const char test103[] =
4947 {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x04,'t','e','s','t',0x09,0x02,'p','2',0x02,'n','s',0x01};
4948 static const char test200[] =
4949 {0x02,0x07,'c','o','m','m','e','n','t'};
4950 const WS_XML_NODE *node;
4951 const WS_XML_TEXT_NODE *text_node;
4952 const WS_XML_ELEMENT_NODE *elem;
4953 const WS_XML_ATTRIBUTE *attr;
4954 const WS_XML_UTF8_TEXT *utf8_text;
4955 const WS_XML_BASE64_TEXT *base64_text;
4956 const WS_XML_INT32_TEXT *int32_text;
4957 const WS_XML_INT64_TEXT *int64_text;
4958 const WS_XML_DOUBLE_TEXT *double_text;
4959 const WS_XML_DATETIME_TEXT *datetime_text;
4960 const WS_XML_BOOL_TEXT *bool_text;
4961 const WS_XML_UNIQUE_ID_TEXT *unique_id_text;
4962 const WS_XML_GUID_TEXT *guid_text;
4963 const WS_XML_UINT64_TEXT *uint64_text;
4964 const WS_XML_COMMENT_NODE *comment;
4965 WS_XML_DICTIONARY *dict;
4966 WS_XML_READER *reader;
4967 WS_HEAP *heap;
4968 BOOL found;
4969 HRESULT hr;
4970 WS_STRUCT_DESCRIPTION s;
4971 WS_FIELD_DESCRIPTION f, *fields[1];
4972 struct typetest
4974 WS_BYTES data;
4975 } *typetest;
4977 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_1, &dict, NULL );
4978 ok( hr == S_OK, "got %08x\n", hr );
4980 hr = WsCreateReader( NULL, 0, &reader, NULL );
4981 ok( hr == S_OK, "got %08x\n", hr );
4983 /* short element */
4984 hr = set_input_bin( reader, test, sizeof(test), NULL );
4985 ok( hr == S_OK, "got %08x\n", hr );
4987 hr = WsReadNode( reader, NULL );
4988 ok( hr == S_OK, "got %08x\n", hr );
4989 hr = WsGetReaderNode( reader, &node, NULL );
4990 ok( hr == S_OK, "got %08x\n", hr );
4991 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4992 elem = (const WS_XML_ELEMENT_NODE *)node;
4993 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
4994 ok( elem->prefix->bytes == NULL, "bytes set\n" );
4995 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4996 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4997 ok( elem->localName->dictionary != NULL, "dictionary not set\n" );
4998 ok( !elem->ns->length, "got %u\n", elem->ns->length );
4999 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5000 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
5001 ok( !elem->isEmpty, "empty\n" );
5003 hr = WsReadNode( reader, NULL );
5004 ok( hr == S_OK, "got %08x\n", hr );
5005 hr = WsGetReaderNode( reader, &node, NULL );
5006 ok( hr == S_OK, "got %08x\n", hr );
5007 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5009 /* single character prefix element */
5010 hr = set_input_bin( reader, test2, sizeof(test2), NULL );
5011 ok( hr == S_OK, "got %08x\n", hr );
5013 hr = WsReadNode( reader, NULL );
5014 ok( hr == S_OK, "got %08x\n", hr );
5015 hr = WsGetReaderNode( reader, &node, NULL );
5016 ok( hr == S_OK, "got %08x\n", hr );
5017 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5018 elem = (const WS_XML_ELEMENT_NODE *)node;
5019 ok( elem->prefix->length == 1, "got %u\n", elem->prefix->length );
5020 ok( !memcmp( elem->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5021 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5022 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5023 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
5024 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5025 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5026 ok( !elem->isEmpty, "empty\n" );
5027 attr = elem->attributes[0];
5028 ok( !attr->singleQuote, "single quote\n" );
5029 ok( attr->isXmlNs, "not xmlns\n" );
5030 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5031 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5032 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5033 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5035 hr = WsReadNode( reader, NULL );
5036 ok( hr == S_OK, "got %08x\n", hr );
5037 hr = WsGetReaderNode( reader, &node, NULL );
5038 ok( hr == S_OK, "got %08x\n", hr );
5039 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5041 /* element */
5042 hr = set_input_bin( reader, test3, sizeof(test3), NULL );
5043 ok( hr == S_OK, "got %08x\n", hr );
5045 hr = WsReadNode( reader, NULL );
5046 ok( hr == S_OK, "got %08x\n", hr );
5047 hr = WsGetReaderNode( reader, &node, NULL );
5048 ok( hr == S_OK, "got %08x\n", hr );
5049 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5050 elem = (const WS_XML_ELEMENT_NODE *)node;
5051 ok( elem->prefix->length == 2, "got %u\n", elem->prefix->length );
5052 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5053 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5054 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5055 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
5056 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5057 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5058 ok( !elem->isEmpty, "empty\n" );
5059 attr = elem->attributes[0];
5060 ok( !attr->singleQuote, "single quote\n" );
5061 ok( attr->isXmlNs, "not xmlns\n" );
5062 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5063 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5064 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5065 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5067 hr = WsReadNode( reader, NULL );
5068 ok( hr == S_OK, "got %08x\n", hr );
5069 hr = WsGetReaderNode( reader, &node, NULL );
5070 ok( hr == S_OK, "got %08x\n", hr );
5071 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5073 /* element with text */
5074 hr = set_input_bin( reader, test4, sizeof(test4), NULL );
5075 ok( hr == S_OK, "got %08x\n", hr );
5077 hr = WsReadNode( reader, NULL );
5078 ok( hr == S_OK, "got %08x\n", hr );
5079 hr = WsGetReaderNode( reader, &node, NULL );
5080 ok( hr == S_OK, "got %08x\n", hr );
5081 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5082 elem = (const WS_XML_ELEMENT_NODE *)node;
5083 ok( elem->prefix->length == 2, "got %u\n", elem->prefix->length );
5084 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5085 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5086 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5087 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
5088 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5089 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5090 ok( !elem->isEmpty, "empty\n" );
5091 attr = elem->attributes[0];
5092 ok( !attr->singleQuote, "single quote\n" );
5093 ok( attr->isXmlNs, "not xmlns\n" );
5094 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5095 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5096 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5097 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5099 hr = WsReadNode( reader, NULL );
5100 ok( hr == S_OK, "got %08x\n", hr );
5101 hr = WsGetReaderNode( reader, &node, NULL );
5102 ok( hr == S_OK, "got %08x\n", hr );
5103 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
5104 text_node = (const WS_XML_TEXT_NODE *)node;
5105 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text_node->text->textType );
5106 utf8_text = (const WS_XML_UTF8_TEXT *)text_node->text;
5107 ok( utf8_text->value.length == 4, "got %u\n", utf8_text->value.length );
5108 ok( !memcmp( utf8_text->value.bytes, "test", 4 ), "wrong text\n" );
5110 hr = WsReadNode( reader, NULL );
5111 ok( hr == S_OK, "got %08x\n", hr );
5112 hr = WsGetReaderNode( reader, &node, NULL );
5113 ok( hr == S_OK, "got %08x\n", hr );
5114 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5116 /* bool text, TRUE */
5117 hr = set_input_bin( reader, test7, sizeof(test7), NULL );
5118 ok( hr == S_OK, "got %08x\n", hr );
5119 text_node = read_text_node( reader );
5120 ok( text_node != NULL, "no text\n" );
5121 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BOOL, "got %u\n", text_node->text->textType );
5122 bool_text = (WS_XML_BOOL_TEXT *)text_node->text;
5123 ok( bool_text->value == TRUE, "got %d\n", bool_text->value );
5125 /* bool text, FALSE */
5126 hr = set_input_bin( reader, test8, sizeof(test8), NULL );
5127 ok( hr == S_OK, "got %08x\n", hr );
5128 text_node = read_text_node( reader );
5129 ok( text_node != NULL, "no text\n" );
5130 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BOOL, "got %u\n", text_node->text->textType );
5131 bool_text = (WS_XML_BOOL_TEXT *)text_node->text;
5132 ok( !bool_text->value, "got %d\n", bool_text->value );
5134 /* zero text */
5135 hr = set_input_bin( reader, test9, sizeof(test9), NULL );
5136 ok( hr == S_OK, "got %08x\n", hr );
5137 text_node = read_text_node( reader );
5138 ok( text_node != NULL, "no text\n" );
5139 ok( text_node->text->textType == WS_XML_TEXT_TYPE_INT32, "got %u\n", text_node->text->textType );
5140 int32_text = (WS_XML_INT32_TEXT *)text_node->text;
5141 ok( !int32_text->value, "got %d\n", int32_text->value );
5143 /* one text */
5144 hr = set_input_bin( reader, test10, sizeof(test10), NULL );
5145 ok( hr == S_OK, "got %08x\n", hr );
5146 text_node = read_text_node( reader );
5147 ok( text_node != NULL, "no text\n" );
5148 ok( text_node->text->textType == WS_XML_TEXT_TYPE_INT32, "got %u\n", text_node->text->textType );
5149 int32_text = (WS_XML_INT32_TEXT *)text_node->text;
5150 ok( int32_text->value == 1, "got %d\n", int32_text->value );
5152 /* false text */
5153 hr = set_input_bin( reader, test11, sizeof(test11), NULL );
5154 ok( hr == S_OK, "got %08x\n", hr );
5155 text_node = read_text_node( reader );
5156 ok( text_node != NULL, "no text\n" );
5157 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BOOL, "got %u\n", text_node->text->textType );
5158 bool_text = (WS_XML_BOOL_TEXT *)text_node->text;
5159 ok( !bool_text->value, "got %d\n", bool_text->value );
5161 /* true text */
5162 hr = set_input_bin( reader, test12, sizeof(test12), NULL );
5163 ok( hr == S_OK, "got %08x\n", hr );
5164 text_node = read_text_node( reader );
5165 ok( text_node != NULL, "no text\n" );
5166 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BOOL, "got %u\n", text_node->text->textType );
5167 bool_text = (WS_XML_BOOL_TEXT *)text_node->text;
5168 ok( bool_text->value == TRUE, "got %d\n", bool_text->value );
5170 /* int32 text, int8 record */
5171 hr = set_input_bin( reader, test13, sizeof(test13), NULL );
5172 ok( hr == S_OK, "got %08x\n", hr );
5173 text_node = read_text_node( reader );
5174 ok( text_node != NULL, "no text\n" );
5175 ok( text_node->text->textType == WS_XML_TEXT_TYPE_INT32, "got %u\n", text_node->text->textType );
5176 int32_text = (WS_XML_INT32_TEXT *)text_node->text;
5177 ok( int32_text->value == -1, "got %d\n", int32_text->value );
5179 /* int32 text, int16 record */
5180 hr = set_input_bin( reader, test14, sizeof(test14), NULL );
5181 ok( hr == S_OK, "got %08x\n", hr );
5182 text_node = read_text_node( reader );
5183 ok( text_node != NULL, "no text\n" );
5184 ok( text_node->text->textType == WS_XML_TEXT_TYPE_INT32, "got %u\n", text_node->text->textType );
5185 int32_text = (WS_XML_INT32_TEXT *)text_node->text;
5186 ok( int32_text->value == -1, "got %d\n", int32_text->value );
5188 /* int32 text, int32 record */
5189 hr = set_input_bin( reader, test15, sizeof(test15), NULL );
5190 ok( hr == S_OK, "got %08x\n", hr );
5191 text_node = read_text_node( reader );
5192 ok( text_node != NULL, "no text\n" );
5193 ok( text_node->text->textType == WS_XML_TEXT_TYPE_INT32, "got %u\n", text_node->text->textType );
5194 int32_text = (WS_XML_INT32_TEXT *)text_node->text;
5195 ok( int32_text->value == -1, "got %d\n", int32_text->value );
5197 /* int64 text, int64 record */
5198 hr = set_input_bin( reader, test16, sizeof(test16), NULL );
5199 ok( hr == S_OK, "got %08x\n", hr );
5200 text_node = read_text_node( reader );
5201 ok( text_node != NULL, "no text\n" );
5202 ok( text_node->text->textType == WS_XML_TEXT_TYPE_INT64, "got %u\n", text_node->text->textType );
5203 int64_text = (WS_XML_INT64_TEXT *)text_node->text;
5204 ok( int64_text->value == -1, "got %s\n", wine_dbgstr_longlong(int64_text->value) );
5206 /* double text */
5207 hr = set_input_bin( reader, test17, sizeof(test17), NULL );
5208 ok( hr == S_OK, "got %08x\n", hr );
5209 text_node = read_text_node( reader );
5210 ok( text_node != NULL, "no text\n" );
5211 ok( text_node->text->textType == WS_XML_TEXT_TYPE_DOUBLE, "got %u\n", text_node->text->textType );
5212 double_text = (WS_XML_DOUBLE_TEXT *)text_node->text;
5213 ok( !double_text->value, "got %s\n", wine_dbgstr_longlong(double_text->value) );
5215 /* datetime text */
5216 hr = set_input_bin( reader, test18, sizeof(test18), NULL );
5217 ok( hr == S_OK, "got %08x\n", hr );
5218 text_node = read_text_node( reader );
5219 ok( text_node != NULL, "no text\n" );
5220 ok( text_node->text->textType == WS_XML_TEXT_TYPE_DATETIME, "got %u\n", text_node->text->textType );
5221 datetime_text = (WS_XML_DATETIME_TEXT *)text_node->text;
5222 ok( !datetime_text->value.ticks, "got %s\n", wine_dbgstr_longlong(datetime_text->value.ticks) );
5223 ok( datetime_text->value.format == WS_DATETIME_FORMAT_NONE, "got %u\n", datetime_text->value.format );
5225 /* utf8 text, chars8 record */
5226 hr = set_input_bin( reader, test19, sizeof(test19), NULL );
5227 ok( hr == S_OK, "got %08x\n", hr );
5228 text_node = read_text_node( reader );
5229 ok( text_node != NULL, "no text\n" );
5230 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text_node->text->textType );
5231 utf8_text = (WS_XML_UTF8_TEXT *)text_node->text;
5232 ok( utf8_text->value.length == 1, "got %u\n", utf8_text->value.length );
5233 ok( utf8_text->value.bytes[0] == 'a', "got %02x\n", utf8_text->value.bytes[0] );
5235 /* utf8 text, chars16 record */
5236 hr = set_input_bin( reader, test20, sizeof(test20), NULL );
5237 ok( hr == S_OK, "got %08x\n", hr );
5238 text_node = read_text_node( reader );
5239 ok( text_node != NULL, "no text\n" );
5240 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text_node->text->textType );
5241 utf8_text = (WS_XML_UTF8_TEXT *)text_node->text;
5242 ok( utf8_text->value.length == 1, "got %u\n", utf8_text->value.length );
5243 ok( utf8_text->value.bytes[0] == 'a', "got %02x\n", utf8_text->value.bytes[0] );
5245 /* utf8 text, chars32 record */
5246 hr = set_input_bin( reader, test21, sizeof(test21), NULL );
5247 ok( hr == S_OK, "got %08x\n", hr );
5248 text_node = read_text_node( reader );
5249 ok( text_node != NULL, "no text\n" );
5250 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text_node->text->textType );
5251 utf8_text = (WS_XML_UTF8_TEXT *)text_node->text;
5252 ok( utf8_text->value.length == 1, "got %u\n", utf8_text->value.length );
5253 ok( utf8_text->value.bytes[0] == 'a', "got %02x\n", utf8_text->value.bytes[0] );
5255 /* base64 text, bytes8 record */
5256 hr = set_input_bin( reader, test22, sizeof(test22), NULL );
5257 ok( hr == S_OK, "got %08x\n", hr );
5258 text_node = read_text_node( reader );
5259 ok( text_node != NULL, "no text\n" );
5260 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text_node->text->textType );
5261 base64_text = (WS_XML_BASE64_TEXT *)text_node->text;
5262 ok( base64_text->length == 1, "got %u\n", base64_text->length );
5263 ok( base64_text->bytes[0] == 'a', "got %02x\n", base64_text->bytes[0] );
5265 /* base64 text, bytes16 record */
5266 hr = set_input_bin( reader, test23, sizeof(test23), NULL );
5267 ok( hr == S_OK, "got %08x\n", hr );
5268 text_node = read_text_node( reader );
5269 ok( text_node != NULL, "no text\n" );
5270 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text_node->text->textType );
5271 base64_text = (WS_XML_BASE64_TEXT *)text_node->text;
5272 ok( base64_text->length == 1, "got %u\n", base64_text->length );
5273 ok( base64_text->bytes[0] == 'a', "got %02x\n", base64_text->bytes[0] );
5275 /* base64 text, bytes32 record */
5276 hr = set_input_bin( reader, test24, sizeof(test24), NULL );
5277 ok( hr == S_OK, "got %08x\n", hr );
5278 text_node = read_text_node( reader );
5279 ok( text_node != NULL, "no text\n" );
5280 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text_node->text->textType );
5281 base64_text = (WS_XML_BASE64_TEXT *)text_node->text;
5282 ok( base64_text->length == 1, "got %u\n", base64_text->length );
5283 ok( base64_text->bytes[0] == 'a', "got %02x\n", base64_text->bytes[0] );
5285 /* empty text */
5286 hr = set_input_bin( reader, test25, sizeof(test25), NULL );
5287 ok( hr == S_OK, "got %08x\n", hr );
5288 text_node = read_text_node( reader );
5289 ok( text_node != NULL, "no text\n" );
5290 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text_node->text->textType );
5291 utf8_text = (WS_XML_UTF8_TEXT *)text_node->text;
5292 ok( !utf8_text->value.length, "got %u\n", utf8_text->value.length );
5293 ok( utf8_text->value.bytes != NULL, "bytes not set\n" );
5295 /* dictionary text */
5296 hr = set_input_bin( reader, test26, sizeof(test26), dict );
5297 ok( hr == S_OK, "got %08x\n", hr );
5298 text_node = read_text_node( reader );
5299 ok( text_node != NULL, "no text\n" );
5300 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text_node->text->textType );
5301 utf8_text = (WS_XML_UTF8_TEXT *)text_node->text;
5302 ok( utf8_text->value.length == 2, "got %u\n", utf8_text->value.length );
5303 ok( utf8_text->value.bytes[0] == 'T', "got %02x\n", utf8_text->value.bytes[0] );
5304 ok( utf8_text->value.bytes[1] == 'o', "got %02x\n", utf8_text->value.bytes[0] );
5306 /* unique id text */
5307 hr = set_input_bin( reader, test27, sizeof(test27), NULL );
5308 ok( hr == S_OK, "got %08x\n", hr );
5309 text_node = read_text_node( reader );
5310 ok( text_node != NULL, "no text\n" );
5311 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UNIQUE_ID, "got %u\n", text_node->text->textType );
5312 unique_id_text = (WS_XML_UNIQUE_ID_TEXT *)text_node->text;
5313 ok( IsEqualGUID( &unique_id_text->value, &guid_null ), "wrong data\n" );
5315 /* guid text */
5316 hr = set_input_bin( reader, test28, sizeof(test28), NULL );
5317 ok( hr == S_OK, "got %08x\n", hr );
5318 text_node = read_text_node( reader );
5319 ok( text_node != NULL, "no text\n" );
5320 ok( text_node->text->textType == WS_XML_TEXT_TYPE_GUID, "got %u\n", text_node->text->textType );
5321 guid_text = (WS_XML_GUID_TEXT *)text_node->text;
5322 ok( IsEqualGUID( &guid_text->value, &guid_null ), "wrong data\n" );
5324 /* uint64 text */
5325 hr = set_input_bin( reader, test29, sizeof(test29), NULL );
5326 ok( hr == S_OK, "got %08x\n", hr );
5327 text_node = read_text_node( reader );
5328 ok( text_node != NULL, "no text\n" );
5329 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UINT64, "got %u\n", text_node->text->textType );
5330 uint64_text = (WS_XML_UINT64_TEXT *)text_node->text;
5331 ok( uint64_text->value == 1, "got %s\n", wine_dbgstr_longlong(uint64_text->value) );
5333 /* short xmlns attribute */
5334 hr = set_input_bin( reader, test30, sizeof(test30), NULL );
5335 ok( hr == S_OK, "got %08x\n", hr );
5337 hr = WsReadNode( reader, NULL );
5338 ok( hr == S_OK, "got %08x\n", hr );
5339 hr = WsGetReaderNode( reader, &node, NULL );
5340 ok( hr == S_OK, "got %08x\n", hr );
5341 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5342 elem = (const WS_XML_ELEMENT_NODE *)node;
5343 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5344 ok( elem->prefix->bytes == NULL, "bytes set\n" );
5345 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5346 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5347 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
5348 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5349 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5350 ok( !elem->isEmpty, "empty\n" );
5351 attr = elem->attributes[0];
5352 ok( !attr->singleQuote, "single quote\n" );
5353 ok( attr->isXmlNs, "not xmlns\n" );
5354 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
5355 ok( attr->prefix->bytes == NULL, "bytes set\n" );
5356 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5357 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5359 /* xmlns attribute */
5360 hr = set_input_bin( reader, test31, sizeof(test31), NULL );
5361 ok( hr == S_OK, "got %08x\n", hr );
5363 hr = WsReadNode( reader, NULL );
5364 ok( hr == S_OK, "got %08x\n", hr );
5365 hr = WsGetReaderNode( reader, &node, NULL );
5366 ok( hr == S_OK, "got %08x\n", hr );
5367 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5368 elem = (const WS_XML_ELEMENT_NODE *)node;
5369 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5370 ok( elem->prefix->bytes == NULL, "bytes set\n" );
5371 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5372 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5373 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5374 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5375 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5376 ok( !elem->isEmpty, "empty\n" );
5377 attr = elem->attributes[0];
5378 ok( !attr->singleQuote, "single quote\n" );
5379 ok( attr->isXmlNs, "not xmlns\n" );
5380 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5381 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5382 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5383 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5385 /* short attribute */
5386 hr = set_input_bin( reader, test100, sizeof(test100), NULL );
5387 ok( hr == S_OK, "got %08x\n", hr );
5389 hr = WsReadNode( reader, NULL );
5390 ok( hr == S_OK, "got %08x\n", hr );
5391 hr = WsGetReaderNode( reader, &node, NULL );
5392 ok( hr == S_OK, "got %08x\n", hr );
5393 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5394 elem = (const WS_XML_ELEMENT_NODE *)node;
5395 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5396 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5397 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5398 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5399 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5400 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5401 ok( !elem->isEmpty, "empty\n" );
5402 attr = elem->attributes[0];
5403 ok( !attr->singleQuote, "single quote\n" );
5404 ok( !attr->isXmlNs, "is xmlns\n" );
5405 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
5406 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5407 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
5408 ok( !attr->ns->length, "got %u\n", attr->ns->length );
5409 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5410 ok( attr->value != NULL, "value not set\n" );
5411 utf8_text = (const WS_XML_UTF8_TEXT *)attr->value;
5412 ok( utf8_text->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8_text->text.textType );
5413 ok( !utf8_text->value.length, "got %u\n", utf8_text->value.length );
5414 ok( utf8_text->value.bytes != NULL, "bytes not set\n" );
5416 hr = WsReadNode( reader, NULL );
5417 ok( hr == S_OK, "got %08x\n", hr );
5418 hr = WsGetReaderNode( reader, &node, NULL );
5419 ok( hr == S_OK, "got %08x\n", hr );
5420 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5422 /* single character prefix attribute */
5423 hr = set_input_bin( reader, test101, sizeof(test101), NULL );
5424 ok( hr == S_OK, "got %08x\n", hr );
5426 hr = WsReadNode( reader, NULL );
5427 ok( hr == S_OK, "got %08x\n", hr );
5428 hr = WsGetReaderNode( reader, &node, NULL );
5429 ok( hr == S_OK, "got %08x\n", hr );
5430 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5431 elem = (const WS_XML_ELEMENT_NODE *)node;
5432 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5433 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5434 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5435 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5436 ok( elem->ns->bytes != NULL, "ns not set\n" );
5437 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
5438 ok( !elem->isEmpty, "empty\n" );
5439 attr = elem->attributes[0];
5440 ok( !attr->singleQuote, "single quote\n" );
5441 ok( !attr->isXmlNs, "is xmlns\n" );
5442 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5443 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5444 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5445 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
5446 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5447 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5448 ok( attr->value != NULL, "value not set\n" );
5449 utf8_text = (const WS_XML_UTF8_TEXT *)attr->value;
5450 ok( utf8_text->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8_text->text.textType );
5451 ok( !utf8_text->value.length, "got %u\n", utf8_text->value.length );
5452 ok( utf8_text->value.bytes != NULL, "bytes not set\n" );
5453 attr = elem->attributes[1];
5454 ok( !attr->singleQuote, "single quote\n" );
5455 ok( attr->isXmlNs, "not xmlns\n" );
5456 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5457 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5458 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5459 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5461 hr = WsReadNode( reader, NULL );
5462 ok( hr == S_OK, "got %08x\n", hr );
5463 hr = WsGetReaderNode( reader, &node, NULL );
5464 ok( hr == S_OK, "got %08x\n", hr );
5465 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5467 /* attribute */
5468 hr = set_input_bin( reader, test102, sizeof(test102), NULL );
5469 ok( hr == S_OK, "got %08x\n", hr );
5471 hr = WsReadNode( reader, NULL );
5472 ok( hr == S_OK, "got %08x\n", hr );
5473 hr = WsGetReaderNode( reader, &node, NULL );
5474 ok( hr == S_OK, "got %08x\n", hr );
5475 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5476 elem = (const WS_XML_ELEMENT_NODE *)node;
5477 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5478 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5479 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5480 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5481 ok( elem->ns->bytes != NULL, "ns not set\n" );
5482 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
5483 ok( !elem->isEmpty, "empty\n" );
5484 attr = elem->attributes[0];
5485 ok( !attr->singleQuote, "single quote\n" );
5486 ok( !attr->isXmlNs, "is xmlns\n" );
5487 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5488 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5489 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5490 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
5491 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5492 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5493 ok( attr->value != NULL, "value not set\n" );
5494 utf8_text = (const WS_XML_UTF8_TEXT *)attr->value;
5495 ok( utf8_text->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8_text->text.textType );
5496 ok( !utf8_text->value.length, "got %u\n", utf8_text->value.length );
5497 ok( utf8_text->value.bytes != NULL, "bytes not set\n" );
5498 attr = elem->attributes[1];
5499 ok( !attr->singleQuote, "single quote\n" );
5500 ok( attr->isXmlNs, "not xmlns\n" );
5501 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5502 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5503 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5504 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5506 hr = WsReadNode( reader, NULL );
5507 ok( hr == S_OK, "got %08x\n", hr );
5508 hr = WsGetReaderNode( reader, &node, NULL );
5509 ok( hr == S_OK, "got %08x\n", hr );
5510 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5512 /* attribute with value */
5513 hr = set_input_bin( reader, test103, sizeof(test103), NULL );
5514 ok( hr == S_OK, "got %08x\n", hr );
5516 hr = WsReadNode( reader, NULL );
5517 ok( hr == S_OK, "got %08x\n", hr );
5518 hr = WsGetReaderNode( reader, &node, NULL );
5519 ok( hr == S_OK, "got %08x\n", hr );
5520 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5521 elem = (const WS_XML_ELEMENT_NODE *)node;
5522 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5523 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5524 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5525 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5526 ok( elem->ns->bytes != NULL, "ns not set\n" );
5527 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
5528 ok( !elem->isEmpty, "empty\n" );
5529 attr = elem->attributes[0];
5530 ok( !attr->singleQuote, "single quote\n" );
5531 ok( !attr->isXmlNs, "is xmlns\n" );
5532 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5533 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5534 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5535 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
5536 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5537 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5538 ok( attr->value != NULL, "value not set\n" );
5539 utf8_text = (const WS_XML_UTF8_TEXT *)attr->value;
5540 ok( utf8_text->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8_text->text.textType );
5541 ok( utf8_text->value.length == 4, "got %u\n", utf8_text->value.length );
5542 ok( !memcmp( utf8_text->value.bytes, "test", 4 ), "wrong value\n" );
5543 attr = elem->attributes[1];
5544 ok( !attr->singleQuote, "single quote\n" );
5545 ok( attr->isXmlNs, "not xmlns\n" );
5546 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5547 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5548 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5549 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5551 hr = WsReadNode( reader, NULL );
5552 ok( hr == S_OK, "got %08x\n", hr );
5553 hr = WsGetReaderNode( reader, &node, NULL );
5554 ok( hr == S_OK, "got %08x\n", hr );
5555 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5557 hr = WsReadNode( reader, NULL );
5558 ok( hr == S_OK, "got %08x\n", hr );
5559 hr = WsGetReaderNode( reader, &node, NULL );
5560 ok( hr == S_OK, "got %08x\n", hr );
5561 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
5563 /* comment */
5564 hr = set_input_bin( reader, test200, sizeof(test200), NULL );
5565 ok( hr == S_OK, "got %08x\n", hr );
5567 hr = WsReadNode( reader, NULL );
5568 ok( hr == S_OK, "got %08x\n", hr );
5569 hr = WsGetReaderNode( reader, &node, NULL );
5570 ok( hr == S_OK, "got %08x\n", hr );
5571 ok( node->nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", node->nodeType );
5572 comment = (const WS_XML_COMMENT_NODE *)node;
5573 ok( comment->value.length == 7, "got %u\n", comment->value.length );
5574 ok( !memcmp( comment->value.bytes, "comment", 7 ), "wrong data\n" );
5576 hr = set_input_bin( reader, test, sizeof(test), NULL );
5577 ok( hr == S_OK, "got %08x\n", hr );
5579 found = -1;
5580 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
5581 ok( hr == S_OK, "got %08x\n", hr );
5582 ok( found == TRUE, "got %d\n", found );
5583 hr = WsReadStartElement( reader, NULL );
5584 ok( hr == S_OK, "got %08x\n", hr );
5585 hr = WsReadEndElement( reader, NULL );
5586 ok( hr == S_OK, "got %08x\n", hr );
5588 /* element with byte record text */
5589 hr = set_input_bin( reader, test5, sizeof(test5), NULL );
5590 ok( hr == S_OK, "got %08x\n", hr );
5592 hr = WsReadNode( reader, NULL );
5593 ok( hr == S_OK, "got %08x\n", hr );
5594 hr = WsReadNode( reader, NULL );
5595 ok( hr == S_OK, "got %08x\n", hr );
5596 hr = WsGetReaderNode( reader, &node, NULL );
5597 ok( hr == S_OK, "got %08x\n", hr );
5598 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
5599 text_node = (const WS_XML_TEXT_NODE *)node;
5600 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text_node->text->textType );
5601 base64_text = (const WS_XML_BASE64_TEXT *)text_node->text;
5602 ok( base64_text->length == 1, "got %u\n", base64_text->length );
5603 ok( base64_text->bytes[0] == 'a', "wrong data %02x\n", base64_text->bytes[0] );
5605 /* element with mixed byte record text */
5606 hr = set_input_bin( reader, test6, sizeof(test6), NULL );
5607 ok( hr == S_OK, "got %08x\n", hr );
5609 hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL );
5610 ok( hr == S_OK, "got %08x\n", hr );
5612 memset( &f, 0, sizeof(f) );
5613 f.mapping = WS_ELEMENT_FIELD_MAPPING;
5614 f.localName = &localname;
5615 f.ns = &ns;
5616 f.type = WS_BYTES_TYPE;
5617 f.offset = FIELD_OFFSET(struct typetest, data);
5618 fields[0] = &f;
5620 memset( &s, 0, sizeof(s) );
5621 s.size = sizeof(struct typetest);
5622 s.alignment = TYPE_ALIGNMENT(struct typetest);
5623 s.fields = fields;
5624 s.fieldCount = 1;
5626 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
5627 WS_READ_REQUIRED_POINTER, heap, &typetest, sizeof(typetest), NULL );
5628 ok( hr == S_OK, "got %08x\n", hr );
5629 ok( typetest->data.length == 2, "got %u\n", typetest->data.length );
5630 ok( !memcmp( typetest->data.bytes, "ab", 2 ), "wrong data\n" );
5632 WsFreeHeap( heap );
5633 WsFreeReader( reader );
5636 static void test_dictionary(void)
5638 static const GUID dict_static =
5639 {0xf93578f8,0x5852,0x4eb7,{0xa6,0xfc,0xe7,0x2b,0xb7,0x1d,0xb6,0x22}};
5640 static const char test[] =
5641 {0x42,0x04,0x01};
5642 static const char test2[] =
5643 {0x53,0x06,0x0b,0x01,'p',0x0a,0x01};
5644 static const char test3[] =
5645 {0x43,0x02,'p','2',0x06,0x0b,0x02,'p','2',0x0a,0x01};
5646 static const char test4[] =
5647 {0x42,0x06,0x06,0x06,0x98,0x00,0x01};
5648 static const char test5[] =
5649 {0x42,0x06,0x1b,0x06,0x98,0x00,0x0b,0x01,'p',0x0a,0x01};
5650 static const char test6[] =
5651 {0x42,0x06,0x07,0x02,'p','2',0x06,0x98,0x00,0x0b,0x02,'p','2',0x0a,0x01};
5652 static const char test7[] =
5653 {0x40,0x01,'t',0x0a,0x0a,0x01};
5654 static const char test8[] =
5655 {0x40,0x01,'t',0x0b,0x01,'p',0x0a,0x01};
5656 static const char test9[] =
5657 {0x42,0x0c,0x01};
5658 static const char test10[] =
5659 {0x42,0x04,0xab,0x0c,0x01};
5660 const WS_XML_NODE *node;
5661 const WS_XML_ELEMENT_NODE *elem;
5662 const WS_XML_ATTRIBUTE *attr;
5663 const WS_XML_UTF8_TEXT *utf8;
5664 WS_XML_STRING strings[6];
5665 WS_XML_DICTIONARY dict, *dict2;
5666 WS_XML_READER *reader;
5667 HRESULT hr;
5669 hr = WsCreateReader( NULL, 0, &reader, NULL );
5670 ok( hr == S_OK, "got %08x\n", hr );
5672 strings[0].length = 0;
5673 strings[0].bytes = NULL;
5674 strings[0].dictionary = &dict;
5675 strings[0].id = 0;
5676 strings[1].length = 1;
5677 strings[1].bytes = (BYTE *)"p";
5678 strings[1].dictionary = &dict;
5679 strings[1].id = 1;
5680 strings[2].length = 1;
5681 strings[2].bytes = (BYTE *)"t";
5682 strings[2].dictionary = &dict;
5683 strings[2].id = ~0u;
5684 strings[3].length = 1;
5685 strings[3].bytes = (BYTE *)"u";
5686 strings[3].dictionary = &dict;
5687 strings[3].id = 3;
5688 strings[4].length = 2;
5689 strings[4].bytes = (BYTE *)"p2";
5690 strings[4].dictionary = &dict;
5691 strings[4].id = 4;
5692 strings[5].length = 2;
5693 strings[5].bytes = (BYTE *)"ns";
5694 strings[5].dictionary = &dict;
5695 strings[5].id = 5;
5697 UuidCreate( &dict.guid );
5698 dict.strings = strings;
5699 dict.stringCount = ARRAY_SIZE( strings );
5700 dict.isConst = TRUE;
5702 /* short dictionary element */
5703 hr = set_input_bin( reader, test, sizeof(test), &dict );
5704 ok( hr == S_OK, "got %08x\n", hr );
5706 hr = WsReadNode( reader, NULL );
5707 ok( hr == S_OK, "got %08x\n", hr );
5708 hr = WsGetReaderNode( reader, &node, NULL );
5709 ok( hr == S_OK, "got %08x\n", hr );
5710 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5711 elem = (const WS_XML_ELEMENT_NODE *)node;
5712 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5713 ok( elem->prefix->bytes == NULL, "bytes set\n" );
5714 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5715 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5716 ok( elem->localName->dictionary == &dict, "unexpected dict\n" );
5717 ok( elem->localName->id == ~0u, "unexpected id %08x\n", elem->localName->id );
5718 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5719 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5720 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
5721 ok( !elem->isEmpty, "empty\n" );
5723 hr = WsReadNode( reader, NULL );
5724 ok( hr == S_OK, "got %08x\n", hr );
5725 hr = WsGetReaderNode( reader, &node, NULL );
5726 ok( hr == S_OK, "got %08x\n", hr );
5727 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5729 /* single character prefix dictionary element */
5730 hr = set_input_bin( reader, test2, sizeof(test2), &dict );
5731 ok( hr == S_OK, "got %08x\n", hr );
5733 hr = WsReadNode( reader, NULL );
5734 ok( hr == S_OK, "got %08x\n", hr );
5735 hr = WsGetReaderNode( reader, &node, NULL );
5736 ok( hr == S_OK, "got %08x\n", hr );
5737 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5738 elem = (const WS_XML_ELEMENT_NODE *)node;
5739 ok( elem->prefix->length == 1, "got %u\n", elem->prefix->length );
5740 ok( !memcmp( elem->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5741 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5742 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5743 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
5744 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5745 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5746 ok( !elem->isEmpty, "empty\n" );
5747 attr = elem->attributes[0];
5748 ok( !attr->singleQuote, "single quote\n" );
5749 ok( attr->isXmlNs, "not xmlns\n" );
5750 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5751 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5752 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5753 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5754 ok( attr->ns->dictionary == &dict, "unexpected dict\n" );
5755 ok( attr->ns->id == 5, "unexpected id %08x\n", attr->ns->id );
5757 hr = WsReadNode( reader, NULL );
5758 ok( hr == S_OK, "got %08x\n", hr );
5759 hr = WsGetReaderNode( reader, &node, NULL );
5760 ok( hr == S_OK, "got %08x\n", hr );
5761 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5763 /* dictionary element */
5764 hr = set_input_bin( reader, test3, sizeof(test3), &dict );
5765 ok( hr == S_OK, "got %08x\n", hr );
5767 hr = WsReadNode( reader, NULL );
5768 ok( hr == S_OK, "got %08x\n", hr );
5769 hr = WsGetReaderNode( reader, &node, NULL );
5770 ok( hr == S_OK, "got %08x\n", hr );
5771 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5772 elem = (const WS_XML_ELEMENT_NODE *)node;
5773 ok( elem->prefix->length == 2, "got %u\n", elem->prefix->length );
5774 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5775 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5776 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5777 ok( elem->localName->dictionary == &dict, "unexpected dict\n" );
5778 ok( elem->localName->id == 3, "unexpected id %08x\n", elem->localName->id );
5779 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
5780 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5781 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5782 ok( !elem->isEmpty, "empty\n" );
5783 attr = elem->attributes[0];
5784 ok( !attr->singleQuote, "single quote\n" );
5785 ok( attr->isXmlNs, "not xmlns\n" );
5786 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5787 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5788 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5789 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5791 hr = WsReadNode( reader, NULL );
5792 ok( hr == S_OK, "got %08x\n", hr );
5793 hr = WsGetReaderNode( reader, &node, NULL );
5794 ok( hr == S_OK, "got %08x\n", hr );
5795 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5797 /* short dictionary attribute */
5798 hr = set_input_bin( reader, test4, sizeof(test4), &dict );
5799 ok( hr == S_OK, "got %08x\n", hr );
5801 hr = WsReadNode( reader, NULL );
5802 ok( hr == S_OK, "got %08x\n", hr );
5803 hr = WsGetReaderNode( reader, &node, NULL );
5804 ok( hr == S_OK, "got %08x\n", hr );
5805 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5806 elem = (const WS_XML_ELEMENT_NODE *)node;
5807 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5808 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5809 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5810 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5811 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5812 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5813 ok( !elem->isEmpty, "empty\n" );
5814 attr = elem->attributes[0];
5815 ok( !attr->singleQuote, "single quote\n" );
5816 ok( !attr->isXmlNs, "is xmlns\n" );
5817 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
5818 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5819 ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
5820 ok( attr->localName->id == 3, "unexpected id %08x\n", attr->localName->id );
5821 ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
5822 ok( !attr->ns->length, "got %u\n", attr->ns->length );
5823 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5824 ok( attr->value != NULL, "value not set\n" );
5825 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5826 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5827 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5828 ok( utf8->value.bytes != NULL, "bytes not set\n" );
5830 hr = WsReadNode( reader, NULL );
5831 ok( hr == S_OK, "got %08x\n", hr );
5832 hr = WsGetReaderNode( reader, &node, NULL );
5833 ok( hr == S_OK, "got %08x\n", hr );
5834 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5836 /* single character prefix dictionary attribute */
5837 hr = set_input_bin( reader, test5, sizeof(test5), &dict );
5838 ok( hr == S_OK, "got %08x\n", hr );
5840 hr = WsReadNode( reader, NULL );
5841 ok( hr == S_OK, "got %08x\n", hr );
5842 hr = WsGetReaderNode( reader, &node, NULL );
5843 ok( hr == S_OK, "got %08x\n", hr );
5844 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5845 elem = (const WS_XML_ELEMENT_NODE *)node;
5846 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5847 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5848 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5849 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5850 ok( elem->ns->bytes != NULL, "ns not set\n" );
5851 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
5852 ok( !elem->isEmpty, "empty\n" );
5853 attr = elem->attributes[0];
5854 ok( !attr->singleQuote, "single quote\n" );
5855 ok( !attr->isXmlNs, "is xmlns\n" );
5856 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5857 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5858 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5859 ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
5860 ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
5861 ok( attr->localName->id == 3, "unexpected id %08x\n", attr->localName->id );
5862 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5863 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5864 ok( attr->value != NULL, "value not set\n" );
5865 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5866 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5867 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5868 ok( utf8->value.bytes != NULL, "bytes not set\n" );
5869 attr = elem->attributes[1];
5870 ok( !attr->singleQuote, "single quote\n" );
5871 ok( attr->isXmlNs, "not xmlns\n" );
5872 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5873 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5874 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5875 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5877 hr = WsReadNode( reader, NULL );
5878 ok( hr == S_OK, "got %08x\n", hr );
5879 hr = WsGetReaderNode( reader, &node, NULL );
5880 ok( hr == S_OK, "got %08x\n", hr );
5881 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5883 /* dictionary attribute */
5884 hr = set_input_bin( reader, test6, sizeof(test6), &dict );
5885 ok( hr == S_OK, "got %08x\n", hr );
5887 hr = WsReadNode( reader, NULL );
5888 ok( hr == S_OK, "got %08x\n", hr );
5889 hr = WsGetReaderNode( reader, &node, NULL );
5890 ok( hr == S_OK, "got %08x\n", hr );
5891 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5892 elem = (const WS_XML_ELEMENT_NODE *)node;
5893 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5894 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5895 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5896 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5897 ok( elem->ns->bytes != NULL, "ns not set\n" );
5898 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
5899 ok( !elem->isEmpty, "empty\n" );
5900 attr = elem->attributes[0];
5901 ok( !attr->singleQuote, "single quote\n" );
5902 ok( !attr->isXmlNs, "is xmlns\n" );
5903 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5904 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5905 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5906 ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
5907 ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
5908 ok( attr->localName->id == 3, "unexpected id %08x\n", attr->localName->id );
5909 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5910 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5911 ok( attr->value != NULL, "value not set\n" );
5912 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5913 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5914 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5915 ok( utf8->value.bytes != NULL, "bytes not set\n" );
5916 attr = elem->attributes[1];
5917 ok( !attr->singleQuote, "single quote\n" );
5918 ok( attr->isXmlNs, "not xmlns\n" );
5919 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5920 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5921 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5922 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5924 /* short dictionary xmlns attribute */
5925 hr = set_input_bin( reader, test7, sizeof(test7), &dict );
5926 ok( hr == S_OK, "got %08x\n", hr );
5928 hr = WsReadNode( reader, NULL );
5929 ok( hr == S_OK, "got %08x\n", hr );
5930 hr = WsGetReaderNode( reader, &node, NULL );
5931 ok( hr == S_OK, "got %08x\n", hr );
5932 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5933 elem = (const WS_XML_ELEMENT_NODE *)node;
5934 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5935 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5936 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5937 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5938 ok( !elem->isEmpty, "empty\n" );
5939 attr = elem->attributes[0];
5940 ok( !attr->singleQuote, "single quote\n" );
5941 ok( attr->isXmlNs, "not xmlns\n" );
5942 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
5943 ok( attr->prefix->bytes == NULL, "bytes set\n" );
5944 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5945 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5946 ok( attr->ns->dictionary == &dict, "unexpected dict\n" );
5947 ok( attr->ns->id == 5, "unexpected id %08x\n", attr->ns->id );
5948 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5949 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5950 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5951 todo_wine ok( utf8->value.bytes != NULL, "bytes not set\n" );
5953 /* dictionary xmlns attribute */
5954 hr = set_input_bin( reader, test8, sizeof(test8), &dict );
5955 ok( hr == S_OK, "got %08x\n", hr );
5957 hr = WsReadNode( reader, NULL );
5958 ok( hr == S_OK, "got %08x\n", hr );
5959 hr = WsGetReaderNode( reader, &node, NULL );
5960 ok( hr == S_OK, "got %08x\n", hr );
5961 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5962 elem = (const WS_XML_ELEMENT_NODE *)node;
5963 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5964 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5965 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5966 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5967 ok( !elem->isEmpty, "empty\n" );
5968 attr = elem->attributes[0];
5969 ok( !attr->singleQuote, "single quote\n" );
5970 ok( attr->isXmlNs, "not xmlns\n" );
5971 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5972 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5973 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5974 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5975 ok( attr->ns->dictionary == &dict, "unexpected dict\n" );
5976 ok( attr->ns->id == 5, "unexpected id %08x\n", attr->ns->id );
5977 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5978 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5979 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5980 todo_wine ok( utf8->value.bytes != NULL, "bytes not set\n" );
5982 hr = WsReadNode( reader, NULL );
5983 ok( hr == S_OK, "got %08x\n", hr );
5984 hr = WsGetReaderNode( reader, &node, NULL );
5985 ok( hr == S_OK, "got %08x\n", hr );
5986 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5988 /* element name string id out of range */
5989 hr = set_input_bin( reader, test9, sizeof(test9), &dict );
5990 ok( hr == S_OK, "got %08x\n", hr );
5991 hr = WsReadNode( reader, NULL );
5992 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
5994 /* text string id out of range */
5995 hr = set_input_bin( reader, test10, sizeof(test10), &dict );
5996 ok( hr == S_OK, "got %08x\n", hr );
5997 hr = WsReadNode( reader, NULL );
5998 ok( hr == S_OK, "got %08x\n", hr );
5999 hr = WsGetReaderNode( reader, &node, NULL );
6000 ok( hr == S_OK, "got %08x\n", hr );
6001 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6002 hr = WsReadNode( reader, NULL );
6003 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
6005 hr = WsGetDictionary( 0, NULL, NULL );
6006 ok( hr == E_INVALIDARG, "got %08x\n", hr );
6008 hr = WsGetDictionary( WS_ENCODING_XML_UTF8, NULL, NULL );
6009 ok( hr == E_INVALIDARG, "got %08x\n", hr );
6011 dict2 = (WS_XML_DICTIONARY *)0xdeadbeef;
6012 hr = WsGetDictionary( WS_ENCODING_XML_UTF8, &dict2, NULL );
6013 ok( hr == S_OK, "got %08x\n", hr );
6014 ok( dict2 == NULL, "got %p\n", dict2 );
6016 dict2 = NULL;
6017 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_1, &dict2, NULL );
6018 ok( hr == S_OK, "got %08x\n", hr );
6019 ok( dict2 != NULL, "dict2 not set\n" );
6020 ok( dict2 != &dict, "got %p\n", dict2 );
6022 dict2 = NULL;
6023 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_SESSION_1, &dict2, NULL );
6024 ok( hr == S_OK, "got %08x\n", hr );
6025 ok( dict2 != NULL, "dict2 not set\n" );
6026 ok( dict2 != &dict, "got %p\n", dict2 );
6027 ok( !memcmp( &dict2->guid, &dict_static, sizeof(dict_static) ),
6028 "got %s\n", wine_dbgstr_guid(&dict2->guid) );
6029 ok( dict2->stringCount == 488 || dict2->stringCount == 487 /* < win10 */, "got %u\n", dict2->stringCount );
6030 ok( dict2->strings[0].length == 14, "got %u\n", dict2->strings[0].length );
6031 ok( !memcmp( dict2->strings[0].bytes, "mustUnderstand", 14 ), "wrong data\n" );
6033 WsFreeReader( reader );
6036 static HRESULT set_output( WS_XML_WRITER *writer )
6038 WS_XML_WRITER_TEXT_ENCODING text = {{WS_XML_WRITER_ENCODING_TYPE_TEXT}, WS_CHARSET_UTF8};
6039 WS_XML_WRITER_BUFFER_OUTPUT buf = {{WS_XML_WRITER_OUTPUT_TYPE_BUFFER}};
6040 return WsSetOutput( writer, &text.encoding, &buf.output, NULL, 0, NULL );
6043 static void check_output_buffer( WS_XML_BUFFER *buffer, const char *expected, unsigned int line )
6045 WS_XML_WRITER *writer;
6046 WS_BYTES bytes;
6047 ULONG size = sizeof(bytes);
6048 int len = strlen(expected);
6049 HRESULT hr;
6051 hr = WsCreateWriter( NULL, 0, &writer, NULL );
6052 ok( hr == S_OK, "got %08x\n", hr );
6054 hr = set_output( writer );
6055 ok( hr == S_OK, "got %08x\n", hr );
6057 hr = WsWriteXmlBuffer( writer, buffer, NULL );
6058 ok( hr == S_OK, "got %08x\n", hr );
6060 memset( &bytes, 0, sizeof(bytes) );
6061 hr = WsGetWriterProperty( writer, WS_XML_WRITER_PROPERTY_BYTES, &bytes, size, NULL );
6062 ok( hr == S_OK, "%u: got %08x\n", line, hr );
6063 ok( bytes.length == len, "%u: got %u expected %u\n", line, bytes.length, len );
6064 if (bytes.length != len) return;
6065 ok( !memcmp( bytes.bytes, expected, len ), "%u: got %s expected %s\n", line, bytes.bytes, expected );
6067 WsFreeWriter( writer );
6070 static HRESULT prepare_xml_buffer_test( WS_XML_READER *reader, WS_HEAP *heap )
6072 WS_XML_STRING localname = {1, (BYTE *)"t"}, localname2 = {1, (BYTE *)"u"}, ns = {0, NULL};
6073 WS_XML_WRITER *writer;
6074 WS_XML_BUFFER *buffer;
6075 HRESULT hr;
6077 hr = WsCreateWriter( NULL, 0, &writer, NULL );
6078 ok( hr == S_OK, "got %08x\n", hr );
6080 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
6081 ok( hr == S_OK, "got %08x\n", hr );
6083 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
6084 ok( hr == S_OK, "got %08x\n", hr );
6086 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
6087 ok( hr == S_OK, "got %08x\n", hr );
6088 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
6089 ok( hr == S_OK, "got %08x\n", hr );
6090 hr = WsWriteEndElement( writer, NULL );
6091 ok( hr == S_OK, "got %08x\n", hr );
6092 hr = WsWriteEndElement( writer, NULL );
6093 ok( hr == S_OK, "got %08x\n", hr );
6095 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
6096 ok( hr == S_OK, "got %08x\n", hr );
6097 WsFreeWriter( writer );
6098 return S_OK;
6101 static void test_WsReadXmlBuffer(void)
6103 const WS_XML_NODE *node;
6104 WS_XML_READER *reader;
6105 WS_XML_BUFFER *buffer;
6106 WS_HEAP *heap;
6107 HRESULT hr;
6109 hr = WsReadXmlBuffer( NULL, NULL, NULL, NULL );
6110 ok( hr == E_INVALIDARG, "got %08x\n", hr );
6112 hr = WsCreateReader( NULL, 0, &reader, NULL );
6113 ok( hr == S_OK, "got %08x\n", hr );
6115 hr = WsReadXmlBuffer( reader, NULL, NULL, NULL );
6116 ok( hr == E_INVALIDARG, "got %08x\n", hr );
6118 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
6119 ok( hr == S_OK, "got %08x\n", hr );
6121 hr = WsReadXmlBuffer( reader, heap, NULL, NULL );
6122 ok( hr == E_FAIL, "got %08x\n", hr );
6124 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6125 todo_wine ok( hr == E_FAIL, "got %08x\n", hr );
6127 hr = set_input( reader, "<t><u><v/></u></t></w>", sizeof("<t><u><v/></u></t></w>") - 1 );
6128 ok( hr == S_OK, "got %08x\n", hr );
6130 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
6131 ok( hr == S_OK, "got %08x\n", hr );
6133 hr = WsReadStartElement( reader, NULL );
6134 ok( hr == S_OK, "got %08x\n", hr );
6136 hr = WsGetReaderNode( reader, &node, NULL );
6137 ok( hr == S_OK, "got %08x\n", hr );
6138 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6140 /* reader positioned at element */
6141 buffer = NULL;
6142 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6143 ok( hr == S_OK, "got %08x\n", hr );
6144 ok( buffer != NULL, "buffer not set\n" );
6145 check_output_buffer( buffer, "<u><v/></u>", __LINE__ );
6147 hr = WsGetReaderNode( reader, &node, NULL );
6148 ok( hr == S_OK, "got %08x\n", hr );
6149 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
6151 /* reader positioned at end element */
6152 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6153 ok( hr == E_FAIL, "got %08x\n", hr );
6155 hr = set_input( reader, "<t><u/></t><v/>", sizeof("<t><u/></t><v/>") - 1 );
6156 ok( hr == S_OK, "got %08x\n", hr );
6158 hr = WsGetReaderNode( reader, &node, NULL );
6159 ok( hr == S_OK, "got %08x\n", hr );
6160 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
6162 /* reader positioned at BOF */
6163 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6164 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
6166 hr = WsGetReaderNode( reader, &node, NULL );
6167 ok( hr == S_OK, "got %08x\n", hr );
6168 todo_wine ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
6170 hr = set_input( reader, "<!--comment--><t></t>", sizeof("<!--comment--><t></t>") - 1 );
6171 ok( hr == S_OK, "got %08x\n", hr );
6173 hr = WsReadNode( reader, NULL );
6174 ok( hr == S_OK, "got %08x\n", hr );
6176 hr = WsGetReaderNode( reader, &node, NULL );
6177 ok( hr == S_OK, "got %08x\n", hr );
6178 ok( node->nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", node->nodeType );
6180 /* reader positioned at non-element */
6181 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6182 ok( hr == E_FAIL, "got %08x\n", hr );
6184 hr = prepare_xml_buffer_test( reader, heap );
6185 ok( hr == S_OK, "got %08x\n", hr );
6187 hr = WsGetReaderNode( reader, &node, NULL );
6188 ok( hr == S_OK, "got %08x\n", hr );
6189 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
6191 /* reader positioned at BOF, input buffer */
6192 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6193 ok( hr == S_OK, "got %08x\n", hr );
6194 check_output_buffer( buffer, "<t><u/></t>", __LINE__ );
6196 hr = WsGetReaderNode( reader, &node, NULL );
6197 ok( hr == S_OK, "got %08x\n", hr );
6198 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
6200 /* reader positioned at EOF, input buffer */
6201 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6202 ok( hr == E_FAIL, "got %08x\n", hr );
6204 hr = prepare_xml_buffer_test( reader, heap );
6205 ok( hr == S_OK, "got %08x\n", hr );
6207 hr = WsReadNode( reader, NULL );
6208 ok( hr == S_OK, "got %08x\n", hr );
6209 hr = WsReadNode( reader, NULL );
6210 ok( hr == S_OK, "got %08x\n", hr );
6212 hr = WsGetReaderNode( reader, &node, NULL );
6213 ok( hr == S_OK, "got %08x\n", hr );
6214 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6216 /* reader positioned at element, input buffer */
6217 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6218 ok( hr == S_OK, "got %08x\n", hr );
6219 check_output_buffer( buffer, "<u/>", __LINE__ );
6221 hr = WsGetReaderNode( reader, &node, NULL );
6222 ok( hr == S_OK, "got %08x\n", hr );
6223 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
6225 /* reader positioned at end element, input buffer */
6226 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6227 ok( hr == E_FAIL, "got %08x\n", hr );
6229 WsFreeReader( reader );
6230 WsFreeHeap( heap );
6233 static void test_union_type(void)
6235 static WS_XML_STRING str_ns = {0, NULL}, str_a = {1, (BYTE *)"a"}, str_b = {1, (BYTE *)"b"};
6236 static WS_XML_STRING str_s = {1, (BYTE *)"s"};
6237 HRESULT hr;
6238 WS_XML_READER *reader;
6239 WS_HEAP *heap;
6240 WS_UNION_DESCRIPTION u;
6241 WS_UNION_FIELD_DESCRIPTION f, f2, *fields[2];
6242 WS_FIELD_DESCRIPTION f_struct, *fields_struct[1];
6243 WS_STRUCT_DESCRIPTION s;
6244 const WS_XML_NODE *node;
6245 enum choice {CHOICE_A, CHOICE_B, CHOICE_NONE};
6246 struct test
6248 enum choice choice;
6249 union
6251 WCHAR *a;
6252 UINT32 b;
6253 } value;
6254 } *test;
6256 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
6257 ok( hr == S_OK, "got %08x\n", hr );
6259 hr = WsCreateReader( NULL, 0, &reader, NULL );
6260 ok( hr == S_OK, "got %08x\n", hr );
6262 memset( &f, 0, sizeof(f) );
6263 f.value = CHOICE_A;
6264 f.field.mapping = WS_ELEMENT_FIELD_MAPPING;
6265 f.field.localName = &str_a;
6266 f.field.ns = &str_ns;
6267 f.field.type = WS_WSZ_TYPE;
6268 f.field.offset = FIELD_OFFSET(struct test, value.a);
6269 fields[0] = &f;
6271 memset( &f2, 0, sizeof(f2) );
6272 f2.value = CHOICE_B;
6273 f2.field.mapping = WS_ELEMENT_FIELD_MAPPING;
6274 f2.field.localName = &str_b;
6275 f2.field.ns = &str_ns;
6276 f2.field.type = WS_UINT32_TYPE;
6277 f2.field.offset = FIELD_OFFSET(struct test, value.b);
6278 fields[1] = &f2;
6280 memset( &u, 0, sizeof(u) );
6281 u.size = sizeof(struct test);
6282 u.alignment = TYPE_ALIGNMENT(struct test);
6283 u.fields = fields;
6284 u.fieldCount = 2;
6285 u.enumOffset = FIELD_OFFSET(struct test, choice);
6286 u.noneEnumValue = CHOICE_NONE;
6288 memset( &f_struct, 0, sizeof(f_struct) );
6289 f_struct.mapping = WS_ELEMENT_CHOICE_FIELD_MAPPING;
6290 f_struct.type = WS_UNION_TYPE;
6291 f_struct.typeDescription = &u;
6292 fields_struct[0] = &f_struct;
6294 memset( &s, 0, sizeof(s) );
6295 s.size = sizeof(struct test);
6296 s.alignment = TYPE_ALIGNMENT(struct test);
6297 s.fields = fields_struct;
6298 s.fieldCount = 1;
6299 s.typeLocalName = &str_s;
6300 s.typeNs = &str_ns;
6302 test = NULL;
6303 prepare_struct_type_test( reader, "<a>test</a>" );
6304 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6305 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6306 ok( hr == S_OK, "got %08x\n", hr );
6307 ok( test != NULL, "test not set\n" );
6308 ok( test->choice == CHOICE_A, "got %d\n", test->choice );
6309 ok( !wcscmp(test->value.a, L"test"), "got %s\n", wine_dbgstr_w(test->value.a) );
6310 hr = WsGetReaderNode( reader, &node, NULL );
6311 ok( hr == S_OK, "got %08x\n", hr );
6312 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
6314 test = NULL;
6315 prepare_struct_type_test( reader, "<b>123</b>" );
6316 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6317 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6318 ok( hr == S_OK, "got %08x\n", hr );
6319 ok( test != NULL, "test not set\n" );
6320 ok( test->choice == CHOICE_B, "got %d\n", test->choice );
6321 ok( test->value.b == 123, "got %u\n", test->value.b );
6323 prepare_struct_type_test( reader, "<c>456</c>" );
6324 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6325 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6326 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
6327 hr = WsGetReaderNode( reader, &node, NULL );
6328 ok( hr == S_OK, "got %08x\n", hr );
6329 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6331 f_struct.options = WS_FIELD_NILLABLE;
6332 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6333 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6334 ok( hr == E_INVALIDARG, "got %08x\n", hr );
6336 f_struct.options = WS_FIELD_POINTER|WS_FIELD_NILLABLE;
6337 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6338 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6339 ok( hr == E_INVALIDARG, "got %08x\n", hr );
6341 f_struct.options = WS_FIELD_POINTER;
6342 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6343 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6344 ok( hr == E_INVALIDARG, "got %08x\n", hr );
6346 test = NULL;
6347 f_struct.options = WS_FIELD_OPTIONAL;
6348 prepare_struct_type_test( reader, "<c>456</c>" );
6349 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6350 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6351 todo_wine ok( hr == S_OK, "got %08x\n", hr );
6352 ok( test != NULL, "test not set\n" );
6353 ok( test->choice == CHOICE_NONE, "got %d\n", test->choice );
6354 hr = WsGetReaderNode( reader, &node, NULL );
6355 ok( hr == S_OK, "got %08x\n", hr );
6356 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6358 WsFreeReader( reader );
6359 WsFreeHeap( heap );
6362 static void test_float(void)
6364 static const struct
6366 const char *str;
6367 HRESULT hr;
6368 ULONG val;
6370 tests[] =
6372 {"<t>0.0</t>", S_OK, 0},
6373 {"<t>-0.0</t>", S_OK, 0x80000000},
6374 {"<t>+0.0</t>", S_OK, 0},
6375 {"<t>-</t>", S_OK, 0},
6376 {"<t>+</t>", S_OK, 0},
6377 {"<t>.0</t>", S_OK, 0},
6378 {"<t>0.</t>", S_OK, 0},
6379 {"<t>0</t>", S_OK, 0},
6380 {"<t> 0 </t>", S_OK, 0},
6381 {"<t></t>", WS_E_INVALID_FORMAT, 0},
6382 {"<t>0,1</t>", WS_E_INVALID_FORMAT, 0},
6383 {"<t>1.1.</t>", WS_E_INVALID_FORMAT, 0},
6384 {"<t>1</t>", S_OK, 0x3f800000},
6385 {"<t>1.0000001</t>", S_OK, 0x3f800001},
6386 {"<t>1.0000002</t>", S_OK, 0x3f800002},
6387 {"<t>10000000000000000000</t>", S_OK, 0x5f0ac723},
6388 {"<t>100000000000000000000</t>", S_OK, 0x60ad78ec},
6389 {"<t>2</t>", S_OK, 0x40000000},
6390 {"<t>-2</t>", S_OK, 0xc0000000},
6391 {"<t>nofloat</t>", WS_E_INVALID_FORMAT, 0},
6392 {"<t>INF</t>", S_OK, 0x7f800000},
6393 {"<t>-INF</t>", S_OK, 0xff800000},
6394 {"<t>+INF</t>", WS_E_INVALID_FORMAT, 0},
6395 {"<t>Infinity</t>", WS_E_INVALID_FORMAT, 0},
6396 {"<t>-Infinity</t>", WS_E_INVALID_FORMAT, 0},
6397 {"<t>inf</t>", WS_E_INVALID_FORMAT, 0},
6398 {"<t>NaN</t>", S_OK, 0xffc00000},
6399 {"<t>-NaN</t>", WS_E_INVALID_FORMAT, 0},
6400 {"<t>NAN</t>", WS_E_INVALID_FORMAT, 0},
6401 {"<t>0.3</t>", S_OK, 0x3e99999a},
6402 {"<t>0.33</t>", S_OK, 0x3ea8f5c3},
6403 {"<t>0.333</t>", S_OK, 0x3eaa7efa},
6404 {"<t>0.3333</t>", S_OK, 0x3eaaa64c},
6405 {"<t>0.33333</t>", S_OK, 0x3eaaaa3b},
6406 {"<t>0.333333</t>", S_OK, 0x3eaaaa9f},
6407 {"<t>0.3333333</t>", S_OK, 0x3eaaaaaa},
6408 {"<t>0.33333333</t>", S_OK, 0x3eaaaaab},
6409 {"<t>0.333333333</t>", S_OK, 0x3eaaaaab},
6410 {"<t>0.1e10</t>", S_OK, 0x4e6e6b28},
6411 {"<t>1e</t>", WS_E_INVALID_FORMAT, 0},
6412 {"<t>1e0</t>", S_OK, 0x3f800000},
6413 {"<t>1e+1</t>", S_OK, 0x41200000},
6414 {"<t>1e-1</t>", S_OK, 0x3dcccccd},
6415 {"<t>e10</t>", WS_E_INVALID_FORMAT, 0},
6416 {"<t>1e10.</t>", WS_E_INVALID_FORMAT, 0},
6417 {"<t>1E10</t>", S_OK, 0x501502f9},
6418 {"<t>1e10</t>", S_OK, 0x501502f9},
6419 {"<t>1e-10</t>", S_OK, 0x2edbe6ff},
6420 {"<t>3.4028235e38</t>", S_OK, 0x7f7fffff},
6421 {"<t>3.4028236e38</t>", S_OK, 0x7f800000},
6422 {"<t>1.1754942e-38</t>", S_OK, 0x007fffff},
6423 {"<t>1.1754943e-38</t>", S_OK, 0x00800000},
6425 HRESULT hr;
6426 WS_XML_READER *reader;
6427 WS_HEAP *heap;
6428 ULONG val, i;
6430 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
6431 ok( hr == S_OK, "got %08x\n", hr );
6433 hr = WsCreateReader( NULL, 0, &reader, NULL );
6434 ok( hr == S_OK, "got %08x\n", hr );
6436 for (i = 0; i < ARRAY_SIZE( tests ); i++)
6438 val = 0;
6439 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
6440 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_FLOAT_TYPE, NULL,
6441 WS_READ_REQUIRED_VALUE, heap, &val, sizeof(val), NULL );
6442 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
6443 if (hr == tests[i].hr) ok( val == tests[i].val, "%u: got %08x\n", i, val );
6446 WsFreeReader( reader );
6447 WsFreeHeap( heap );
6450 static void test_repeating_element_choice(void)
6452 static WS_XML_STRING str_ns = {0, NULL}, str_a = {1, (BYTE *)"a"}, str_b = {1, (BYTE *)"b"};
6453 static WS_XML_STRING str_s = {1, (BYTE *)"s"}, str_t = {1, (BYTE *)"t"};
6454 HRESULT hr;
6455 WS_XML_READER *reader;
6456 WS_HEAP *heap;
6457 WS_UNION_DESCRIPTION u;
6458 WS_UNION_FIELD_DESCRIPTION f, f2, *fields[2];
6459 WS_FIELD_DESCRIPTION f_items, *fields_items[1];
6460 WS_STRUCT_DESCRIPTION s;
6461 const WS_XML_NODE *node;
6462 enum choice {CHOICE_A, CHOICE_B, CHOICE_NONE};
6463 struct item
6465 enum choice choice;
6466 union
6468 WCHAR *a;
6469 UINT32 b;
6470 } value;
6472 struct test
6474 struct item *items;
6475 ULONG count;
6476 } *test;
6478 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
6479 ok( hr == S_OK, "got %08x\n", hr );
6481 hr = WsCreateReader( NULL, 0, &reader, NULL );
6482 ok( hr == S_OK, "got %08x\n", hr );
6484 memset( &f, 0, sizeof(f) );
6485 f.value = CHOICE_A;
6486 f.field.mapping = WS_ELEMENT_FIELD_MAPPING;
6487 f.field.localName = &str_a;
6488 f.field.ns = &str_ns;
6489 f.field.type = WS_WSZ_TYPE;
6490 f.field.offset = FIELD_OFFSET(struct item, value.a);
6491 fields[0] = &f;
6493 memset( &f2, 0, sizeof(f2) );
6494 f2.value = CHOICE_B;
6495 f2.field.mapping = WS_ELEMENT_FIELD_MAPPING;
6496 f2.field.localName = &str_b;
6497 f2.field.ns = &str_ns;
6498 f2.field.type = WS_UINT32_TYPE;
6499 f2.field.offset = FIELD_OFFSET(struct item, value.b);
6500 fields[1] = &f2;
6502 memset( &u, 0, sizeof(u) );
6503 u.size = sizeof(struct item);
6504 u.alignment = TYPE_ALIGNMENT(struct item);
6505 u.fields = fields;
6506 u.fieldCount = 2;
6507 u.enumOffset = FIELD_OFFSET(struct item, choice);
6508 u.noneEnumValue = CHOICE_NONE;
6510 memset( &f_items, 0, sizeof(f_items) );
6511 f_items.mapping = WS_REPEATING_ELEMENT_CHOICE_FIELD_MAPPING;
6512 f_items.localName = &str_t;
6513 f_items.ns = &str_ns;
6514 f_items.type = WS_UNION_TYPE;
6515 f_items.typeDescription = &u;
6516 f_items.countOffset = FIELD_OFFSET(struct test, count);
6517 fields_items[0] = &f_items;
6519 memset( &s, 0, sizeof(s) );
6520 s.size = sizeof(struct test);
6521 s.alignment = TYPE_ALIGNMENT(struct test);
6522 s.fields = fields_items;
6523 s.fieldCount = 1;
6524 s.typeLocalName = &str_s;
6525 s.typeNs = &str_ns;
6527 test = NULL;
6528 prepare_struct_type_test( reader, "<t><a>test</a></t>" );
6529 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6530 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6531 ok( hr == S_OK, "got %08x\n", hr );
6532 ok( test != NULL, "test not set\n" );
6533 ok( test->count == 1, "got %u\n", test->count );
6534 ok( test->items[0].choice == CHOICE_A, "got %d\n", test->items[0].choice );
6535 ok( !wcscmp(test->items[0].value.a, L"test"), "got %s\n", wine_dbgstr_w(test->items[0].value.a) );
6537 test = NULL;
6538 prepare_struct_type_test( reader, "<t><b>123</b></t>" );
6539 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6540 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6541 ok( hr == S_OK, "got %08x\n", hr );
6542 ok( test != NULL, "test not set\n" );
6543 ok( test->count == 1, "got %u\n", test->count );
6544 ok( test->items[0].choice == CHOICE_B, "got %d\n", test->items[0].choice );
6545 ok( test->items[0].value.b == 123, "got %u\n", test->items[0].value.b );
6547 test = NULL;
6548 prepare_struct_type_test( reader, "<t><a>test</a><b>123</b></t>" );
6549 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6550 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6551 ok( hr == S_OK, "got %08x\n", hr );
6552 ok( test != NULL, "test not set\n" );
6553 ok( test->count == 2, "got %u\n", test->count );
6554 ok( test->items[0].choice == CHOICE_A, "got %d\n", test->items[0].choice );
6555 ok( !wcscmp(test->items[0].value.a, L"test"), "got %s\n", wine_dbgstr_w(test->items[0].value.a) );
6556 ok( test->items[1].choice == CHOICE_B, "got %d\n", test->items[1].choice );
6557 ok( test->items[1].value.b == 123, "got %u\n", test->items[1].value.b );
6559 prepare_struct_type_test( reader, "<t><c>123</c></t>" );
6560 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6561 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6562 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
6564 hr = WsGetReaderNode( reader, &node, NULL );
6565 ok( hr == S_OK, "got %08x\n", hr );
6566 todo_wine ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6567 if (node->nodeType == WS_XML_NODE_TYPE_ELEMENT)
6569 const WS_XML_ELEMENT_NODE *elem = (const WS_XML_ELEMENT_NODE *)node;
6570 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
6571 ok( elem->localName->bytes[0] == 'c', "got '%c'\n", elem->localName->bytes[0] );
6574 prepare_struct_type_test( reader, "<t></t>" );
6575 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6576 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6577 ok( hr == S_OK, "got %08x\n", hr );
6578 ok( test != NULL, "test not set\n" );
6579 ok( !test->count, "got %u\n", test->count );
6581 hr = WsGetReaderNode( reader, &node, NULL );
6582 ok( hr == S_OK, "got %08x\n", hr );
6583 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
6585 WsFreeReader( reader );
6586 WsFreeHeap( heap );
6589 static void test_empty_text_field(void)
6591 static WS_XML_STRING str_ns = {0, NULL}, str_t = {1, (BYTE *)"t"};
6592 HRESULT hr;
6593 WS_XML_READER *reader;
6594 WS_HEAP *heap;
6595 WS_FIELD_DESCRIPTION f, *fields[1];
6596 WS_STRUCT_DESCRIPTION s;
6597 struct test
6599 WS_STRING str;
6600 } *test;
6601 struct test2
6603 WCHAR *str;
6604 } *test2;
6605 struct test3
6607 BOOL bool;
6608 } *test3;
6609 struct test4
6611 WS_XML_STRING str;
6612 } *test4;
6613 struct test5
6615 WS_BYTES bytes;
6616 } *test5;
6618 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
6619 ok( hr == S_OK, "got %08x\n", hr );
6621 hr = WsCreateReader( NULL, 0, &reader, NULL );
6622 ok( hr == S_OK, "got %08x\n", hr );
6624 memset( &f, 0, sizeof(f) );
6625 f.mapping = WS_TEXT_FIELD_MAPPING;
6626 f.type = WS_STRING_TYPE;
6627 f.offset = FIELD_OFFSET(struct test, str);
6628 fields[0] = &f;
6630 memset( &s, 0, sizeof(s) );
6631 s.size = sizeof(struct test);
6632 s.alignment = TYPE_ALIGNMENT(struct test);
6633 s.fields = fields;
6634 s.fieldCount = 1;
6635 s.typeLocalName = &str_t;
6636 s.typeNs = &str_ns;
6638 test = NULL;
6639 prepare_struct_type_test( reader, "<t></t>" );
6640 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6641 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6642 ok( hr == S_OK, "got %08x\n", hr );
6643 ok( test != NULL, "test not set\n" );
6644 ok( !test->str.length, "got %u\n", test->str.length );
6645 todo_wine ok( test->str.chars != NULL, "chars not set\n" );
6647 memset( &f, 0, sizeof(f) );
6648 f.mapping = WS_TEXT_FIELD_MAPPING;
6649 f.type = WS_WSZ_TYPE;
6650 f.offset = FIELD_OFFSET(struct test2, str);
6651 fields[0] = &f;
6653 memset( &s, 0, sizeof(s) );
6654 s.size = sizeof(struct test2);
6655 s.alignment = TYPE_ALIGNMENT(struct test2);
6656 s.fields = fields;
6657 s.fieldCount = 1;
6658 s.typeLocalName = &str_t;
6659 s.typeNs = &str_ns;
6661 test2 = NULL;
6662 prepare_struct_type_test( reader, "<t></t>" );
6663 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6664 WS_READ_REQUIRED_POINTER, heap, &test2, sizeof(test2), NULL );
6665 ok( hr == S_OK, "got %08x\n", hr );
6666 ok( test2 != NULL, "test2 not set\n" );
6667 ok( test2->str != NULL, "str not set\n" );
6668 ok( !test2->str[0], "not empty\n" );
6670 memset( &f, 0, sizeof(f) );
6671 f.mapping = WS_TEXT_FIELD_MAPPING;
6672 f.type = WS_BOOL_TYPE;
6673 f.offset = FIELD_OFFSET(struct test3, bool);
6674 fields[0] = &f;
6676 memset( &s, 0, sizeof(s) );
6677 s.size = sizeof(struct test3);
6678 s.alignment = TYPE_ALIGNMENT(struct test3);
6679 s.fields = fields;
6680 s.fieldCount = 1;
6681 s.typeLocalName = &str_t;
6682 s.typeNs = &str_ns;
6684 prepare_struct_type_test( reader, "<t></t>" );
6685 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6686 WS_READ_REQUIRED_POINTER, heap, &test3, sizeof(test3), NULL );
6687 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
6689 memset( &f, 0, sizeof(f) );
6690 f.mapping = WS_TEXT_FIELD_MAPPING;
6691 f.type = WS_XML_STRING_TYPE;
6692 f.offset = FIELD_OFFSET(struct test4, str);
6693 fields[0] = &f;
6695 memset( &s, 0, sizeof(s) );
6696 s.size = sizeof(struct test4);
6697 s.alignment = TYPE_ALIGNMENT(struct test4);
6698 s.fields = fields;
6699 s.fieldCount = 1;
6700 s.typeLocalName = &str_t;
6701 s.typeNs = &str_ns;
6703 test4 = NULL;
6704 prepare_struct_type_test( reader, "<t></t>" );
6705 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6706 WS_READ_REQUIRED_POINTER, heap, &test4, sizeof(test4), NULL );
6707 ok( hr == S_OK, "got %08x\n", hr );
6708 ok( test4 != NULL, "test4 not set\n" );
6709 ok( !test4->str.length, "got %u\n", test4->str.length );
6710 todo_wine ok( test4->str.bytes != NULL, "bytes not set\n" );
6712 memset( &f, 0, sizeof(f) );
6713 f.mapping = WS_TEXT_FIELD_MAPPING;
6714 f.type = WS_BYTES_TYPE;
6715 f.offset = FIELD_OFFSET(struct test5, bytes);
6716 fields[0] = &f;
6718 memset( &s, 0, sizeof(s) );
6719 s.size = sizeof(struct test5);
6720 s.alignment = TYPE_ALIGNMENT(struct test5);
6721 s.fields = fields;
6722 s.fieldCount = 1;
6723 s.typeLocalName = &str_t;
6724 s.typeNs = &str_ns;
6726 test5 = NULL;
6727 prepare_struct_type_test( reader, "<t></t>" );
6728 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6729 WS_READ_REQUIRED_POINTER, heap, &test5, sizeof(test5), NULL );
6730 ok( hr == S_OK, "got %08x\n", hr );
6731 ok( test5 != NULL, "test5 not set\n" );
6732 ok( !test5->bytes.length, "got %u\n", test5->bytes.length );
6733 todo_wine ok( test5->bytes.bytes != NULL, "bytes not set\n" );
6735 WsFreeReader( reader );
6736 WsFreeHeap( heap );
6739 static const char stream_utf8[] = {0xef,0xbb,0xbf,'<','t','/','>',0};
6740 static const struct stream_test
6742 const char *xml;
6743 HRESULT hr;
6744 int todo;
6746 stream_tests[] =
6748 { "", WS_E_QUOTA_EXCEEDED },
6749 { "<?xml version=\"1.0\" encoding=\"utf-8\"?><t/>", S_OK },
6750 { "<t/>", S_OK },
6751 { stream_utf8, S_OK, 1 },
6754 static CALLBACK HRESULT read_callback( void *state, void *buf, ULONG buflen, ULONG *retlen,
6755 const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
6757 struct stream_test *test = state;
6758 ULONG len = strlen( test->xml );
6760 ok( state != NULL, "NULL state\n" );
6761 ok( buf != NULL, "NULL buf\n" );
6762 ok( buflen > 0, "zero buflen\n" );
6763 ok( retlen != NULL, "NULL retlen\n" );
6764 if (buflen < len) return WS_E_QUOTA_EXCEEDED;
6765 memcpy( buf, test->xml, len );
6766 *retlen = len;
6767 return S_OK;
6770 static void test_stream_input(void)
6772 static WS_XML_STRING str_ns = {0, NULL}, str_t = {1, (BYTE *)"t"};
6773 WS_XML_READER_TEXT_ENCODING text = {{WS_XML_READER_ENCODING_TYPE_TEXT}};
6774 WS_XML_READER_STREAM_INPUT stream;
6775 WS_XML_READER *reader;
6776 const WS_XML_NODE *node;
6777 WS_CHARSET charset;
6778 HRESULT hr;
6779 BOOL found;
6780 ULONG i, size;
6782 hr = WsCreateReader( NULL, 0, &reader, NULL );
6783 ok( hr == S_OK, "got %08x\n", hr );
6785 stream.input.inputType = WS_XML_READER_INPUT_TYPE_STREAM;
6786 stream.readCallback = read_callback;
6787 stream.readCallbackState = (void *)&stream_tests[2];
6788 hr = WsSetInput( reader, &text.encoding, &stream.input, NULL, 0, NULL );
6789 ok( hr == S_OK, "got %08x\n", hr );
6791 size = sizeof(charset);
6792 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
6793 todo_wine ok( hr == WS_E_QUOTA_EXCEEDED, "got %08x\n", hr );
6795 hr = WsSetInput( reader, &text.encoding, &stream.input, NULL, 0, NULL );
6796 ok( hr == S_OK, "got %08x\n", hr );
6798 hr = WsFillReader( reader, strlen(stream_tests[2].xml), NULL, NULL );
6799 ok( hr == S_OK, "got %08x\n", hr );
6801 charset = 0xdeadbeef;
6802 size = sizeof(charset);
6803 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
6804 ok( hr == S_OK, "got %08x\n", hr );
6805 ok( charset == WS_CHARSET_UTF8, "got %u\n", charset );
6807 found = -1;
6808 hr = WsReadToStartElement( reader, &str_t, &str_ns, &found, NULL );
6809 ok( hr == S_OK, "got %08x\n", hr );
6811 hr = WsFillReader( reader, 1, NULL, NULL );
6812 ok( hr == S_OK, "got %08x\n", hr );
6814 hr = WsReadStartElement( reader, NULL );
6815 ok( hr == S_OK, "got %08x\n", hr );
6817 for (i = 0; i < ARRAY_SIZE(stream_tests); i++)
6819 stream.readCallbackState = (void *)&stream_tests[i];
6820 hr = WsSetInput( reader, &text.encoding, &stream.input, NULL, 0, NULL );
6821 ok( hr == S_OK, "%u: got %08x\n", i, hr );
6823 hr = WsFillReader( reader, strlen( stream_tests[i].xml ), NULL, NULL );
6824 ok( hr == S_OK, "%u: got %08x\n", i, hr );
6826 found = -1;
6827 hr = WsReadToStartElement( reader, &str_t, &str_ns, &found, NULL );
6828 todo_wine_if(stream_tests[i].todo) ok( hr == stream_tests[i].hr, "%u: got %08x\n", i, hr );
6829 if (hr == S_OK)
6831 ok( found == TRUE, "%u: got %d\n", i, found );
6832 hr = WsReadStartElement( reader, NULL );
6833 ok( hr == S_OK, "%u: got %08x\n", i, hr );
6835 hr = WsGetReaderNode( reader, &node, NULL );
6836 ok( hr == S_OK, "%u: got %08x\n", i, hr );
6837 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "%u: got %u\n", i, node->nodeType );
6841 WsFreeReader( reader );
6844 static void test_description_type(void)
6846 static WS_XML_STRING ns = {0, NULL}, ns2 = {2, (BYTE *)"ns"}, localname = {1, (BYTE *)"t"};
6847 static WS_XML_STRING val = {3, (BYTE *)"val"};
6848 HRESULT hr;
6849 WS_XML_READER *reader;
6850 WS_HEAP *heap;
6851 WS_FIELD_DESCRIPTION f, f2, *fields[2];
6852 WS_STRUCT_DESCRIPTION s;
6853 struct test
6855 const WS_STRUCT_DESCRIPTION *desc;
6856 INT32 val;
6857 } *test;
6859 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
6860 ok( hr == S_OK, "got %08x\n", hr );
6862 hr = WsCreateReader( NULL, 0, &reader, NULL );
6863 ok( hr == S_OK, "got %08x\n", hr );
6865 memset( &f, 0, sizeof(f) );
6866 f.mapping = WS_TYPE_ATTRIBUTE_FIELD_MAPPING;
6867 f.type = WS_DESCRIPTION_TYPE;
6868 fields[0] = &f;
6870 memset( &f2, 0, sizeof(f2) );
6871 f2.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
6872 f2.localName = &val;
6873 f2.ns = &ns;
6874 f2.offset = FIELD_OFFSET(struct test, val);
6875 f2.type = WS_INT32_TYPE;
6876 fields[1] = &f2;
6878 memset( &s, 0, sizeof(s) );
6879 s.size = sizeof(struct test);
6880 s.alignment = TYPE_ALIGNMENT(struct test);
6881 s.fields = fields;
6882 s.fieldCount = 2;
6883 s.typeLocalName = &localname;
6884 s.typeNs = &ns;
6886 prepare_struct_type_test( reader, "<t val=\"-1\" xmlns=\"ns\"/>" );
6887 hr = WsReadToStartElement( reader, &localname, &ns2, NULL, NULL );
6888 ok( hr == S_OK, "got %08x\n", hr );
6890 test = NULL;
6891 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6892 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6893 ok( hr == S_OK, "got %08x\n", hr );
6894 ok( test != NULL, "test not set\n" );
6895 if (test)
6897 ok( test->val == -1, "got %d\n", test->val );
6898 ok( test->desc == &s, "got %p\n", test->desc );
6901 WsFreeReader( reader );
6902 WsFreeHeap( heap );
6905 START_TEST(reader)
6907 test_WsCreateError();
6908 test_WsCreateHeap();
6909 test_WsCreateReader();
6910 test_WsSetInput();
6911 test_WsSetInputToBuffer();
6912 test_WsFillReader();
6913 test_WsReadToStartElement();
6914 test_WsReadStartElement();
6915 test_WsReadEndElement();
6916 test_WsReadNode();
6917 test_WsReadType();
6918 test_WsGetXmlAttribute();
6919 test_WsXmlStringEquals();
6920 test_WsAlloc();
6921 test_WsMoveReader();
6922 test_simple_struct_type();
6923 test_cdata();
6924 test_WsFindAttribute();
6925 test_WsGetNamespaceFromPrefix();
6926 test_text_field_mapping();
6927 test_complex_struct_type();
6928 test_repeating_element();
6929 test_WsResetHeap();
6930 test_datetime();
6931 test_WsDateTimeToFileTime();
6932 test_WsFileTimeToDateTime();
6933 test_double();
6934 test_WsReadElement();
6935 test_WsReadValue();
6936 test_WsResetError();
6937 test_WsGetReaderPosition();
6938 test_WsSetReaderPosition();
6939 test_entities();
6940 test_field_options();
6941 test_WsReadBytes();
6942 test_WsReadChars();
6943 test_WsReadCharsUtf8();
6944 test_WsReadQualifiedName();
6945 test_WsReadAttribute();
6946 test_WsSkipNode();
6947 test_binary_encoding();
6948 test_dictionary();
6949 test_WsReadXmlBuffer();
6950 test_union_type();
6951 test_float();
6952 test_repeating_element_choice();
6953 test_empty_text_field();
6954 test_stream_input();
6955 test_description_type();