webservices: Add support for union types in the reader.
[wine.git] / dlls / webservices / tests / reader.c
blobce8590a65745a413c43ef121f012661004dc9051
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 const char data11[] =
71 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
72 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\">"
73 "<!--Build: 16.0.6202.6852-->"
74 "</o:services>"
75 "</o:OfficeConfig>";
77 static const char data11b[] =
78 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
79 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\"></o:services>"
80 "<trailing>content</trailing>"
81 "</o:OfficeConfig>";
83 static const char data12[] =
84 "<services>"
85 "<service><id>1</id></service>"
86 "<service><id>2</id></service>"
87 "</services>";
89 static const char data13[] =
90 "<services></services>";
92 static const char data14[] =
93 "<services>"
94 "<wrapper>"
95 "<service><id>1</id></service>"
96 "<service><id>2</id></service>"
97 "</wrapper>"
98 "</services>";
100 static const char data15[] =
101 "<services>"
102 "<wrapper>"
103 "<service>1</service>"
104 "<service>2</service>"
105 "</wrapper>"
106 "</services>";
108 static const char data16[] =
109 "<services>"
110 "<wrapper>"
111 "<service name='1'>1</service>"
112 "<service name='2'>2</service>"
113 "</wrapper>"
114 "</services>";
116 static const char data17[] =
117 "<services>"
118 "<service><name></name></service>"
119 "</services>";
121 static void test_WsCreateError(void)
123 HRESULT hr;
124 WS_ERROR *error;
125 WS_ERROR_PROPERTY prop;
126 ULONG size, code, count;
127 LANGID langid;
129 hr = WsCreateError( NULL, 0, NULL );
130 ok( hr == E_INVALIDARG, "got %08x\n", hr );
132 error = NULL;
133 hr = WsCreateError( NULL, 0, &error );
134 ok( hr == S_OK, "got %08x\n", hr );
135 ok( error != NULL, "error not set\n" );
137 count = 0xdeadbeef;
138 size = sizeof(count);
139 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
140 ok( hr == S_OK, "got %08x\n", hr );
141 ok( !count, "got %u\n", count );
143 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
144 ok( hr == E_INVALIDARG, "got %08x\n", hr );
146 code = 0xdeadbeef;
147 size = sizeof(code);
148 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
149 ok( hr == S_OK, "got %08x\n", hr );
150 ok( !code, "got %u\n", code );
152 code = 0xdeadbeef;
153 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
154 ok( hr == S_OK, "got %08x\n", hr );
155 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
156 ok( hr == S_OK, "got %08x\n", hr );
157 ok( code == 0xdeadbeef, "got %u\n", code );
159 langid = 0xdead;
160 size = sizeof(langid);
161 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
162 ok( hr == S_OK, "got %08x\n", hr );
163 ok( langid == GetUserDefaultUILanguage(), "got %u\n", langid );
165 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
166 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
167 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
169 count = 0xdeadbeef;
170 size = sizeof(count);
171 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID + 1, &count, size );
172 ok( hr == E_INVALIDARG, "got %08x\n", hr );
173 ok( count == 0xdeadbeef, "got %u\n", count );
174 WsFreeError( error );
176 count = 1;
177 prop.id = WS_ERROR_PROPERTY_STRING_COUNT;
178 prop.value = &count;
179 prop.valueSize = sizeof(count);
180 hr = WsCreateError( &prop, 1, &error );
181 ok( hr == E_INVALIDARG, "got %08x\n", hr );
183 code = 0xdeadbeef;
184 prop.id = WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE;
185 prop.value = &code;
186 prop.valueSize = sizeof(code);
187 hr = WsCreateError( &prop, 1, &error );
188 ok( hr == E_INVALIDARG, "got %08x\n", hr );
190 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
191 prop.id = WS_ERROR_PROPERTY_LANGID;
192 prop.value = &langid;
193 prop.valueSize = sizeof(langid);
194 hr = WsCreateError( &prop, 1, &error );
195 ok( hr == S_OK, "got %08x\n", hr );
197 langid = 0xdead;
198 size = sizeof(langid);
199 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
200 ok( hr == S_OK, "got %08x\n", hr );
201 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
202 WsFreeError( error );
204 count = 0xdeadbeef;
205 prop.id = WS_ERROR_PROPERTY_LANGID + 1;
206 prop.value = &count;
207 prop.valueSize = sizeof(count);
208 hr = WsCreateError( &prop, 1, &error );
209 ok( hr == E_INVALIDARG, "got %08x\n", hr );
212 static void test_WsCreateHeap(void)
214 HRESULT hr;
215 WS_HEAP *heap;
216 WS_HEAP_PROPERTY prop;
217 SIZE_T max, trim, requested, actual;
218 ULONG size;
220 hr = WsCreateHeap( 0, 0, NULL, 0, NULL, NULL );
221 ok( hr == E_INVALIDARG, "got %08x\n", hr );
223 heap = NULL;
224 hr = WsCreateHeap( 0, 0, NULL, 0, &heap, NULL );
225 ok( hr == S_OK, "got %08x\n", hr );
226 ok( heap != NULL, "heap not set\n" );
227 WsFreeHeap( heap );
229 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, NULL, NULL );
230 ok( hr == E_INVALIDARG, "got %08x\n", hr );
232 heap = NULL;
233 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
234 ok( hr == S_OK, "got %08x\n", hr );
235 ok( heap != NULL, "heap not set\n" );
236 WsFreeHeap( heap );
238 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, &heap, NULL );
239 ok( hr == S_OK, "got %08x\n", hr );
241 max = 0xdeadbeef;
242 size = sizeof(max);
243 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_MAX_SIZE, &max, size, NULL );
244 ok( hr == S_OK, "got %08x\n", hr );
245 ok( max == 1 << 16, "got %u\n", (ULONG)max );
247 trim = 0xdeadbeef;
248 size = sizeof(trim);
249 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_TRIM_SIZE, &trim, size, NULL );
250 ok( hr == S_OK, "got %08x\n", hr );
251 ok( trim == 1 << 6, "got %u\n", (ULONG)trim );
253 requested = 0xdeadbeef;
254 size = sizeof(requested);
255 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
256 ok( hr == S_OK, "got %08x\n", hr );
257 ok( !requested, "got %u\n", (ULONG)requested );
259 actual = 0xdeadbeef;
260 size = sizeof(actual);
261 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
262 ok( hr == S_OK, "got %08x\n", hr );
263 ok( !actual, "got %u\n", (ULONG)actual );
265 actual = 0xdeadbeef;
266 size = sizeof(actual);
267 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE + 1, &actual, size, NULL );
268 ok( hr == E_INVALIDARG, "got %08x\n", hr );
269 ok( actual == 0xdeadbeef, "got %u\n", (ULONG)actual );
270 WsFreeHeap( heap );
272 max = 1 << 16;
273 prop.id = WS_HEAP_PROPERTY_MAX_SIZE;
274 prop.value = &max;
275 prop.valueSize = sizeof(max);
276 hr = WsCreateHeap( 1 << 16, 1 << 6, &prop, 1, &heap, NULL );
277 ok( hr == E_INVALIDARG, "got %08x\n", hr );
279 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 1, &heap, NULL );
280 ok( hr == E_INVALIDARG, "got %08x\n", hr );
283 static HRESULT set_input( WS_XML_READER *reader, const char *data, ULONG size )
285 WS_XML_READER_TEXT_ENCODING text = {{WS_XML_READER_ENCODING_TYPE_TEXT}, WS_CHARSET_AUTO};
286 WS_XML_READER_BUFFER_INPUT buf;
288 buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
289 buf.encodedData = (void *)data;
290 buf.encodedDataSize = size;
291 return WsSetInput( reader, &text.encoding, &buf.input, NULL, 0, NULL );
294 static void test_WsCreateReader(void)
296 HRESULT hr;
297 WS_XML_READER *reader;
298 WS_XML_READER_PROPERTY prop;
299 ULONG size, max_depth, max_attrs, trim_size, buffer_size, max_ns;
300 BOOL allow_fragment, read_decl, in_attr;
301 ULONGLONG row, column;
302 WS_CHARSET charset;
304 hr = WsCreateReader( NULL, 0, NULL, NULL );
305 ok( hr == E_INVALIDARG, "got %08x\n", hr );
307 reader = NULL;
308 hr = WsCreateReader( NULL, 0, &reader, NULL );
309 ok( hr == S_OK, "got %08x\n", hr );
310 ok( reader != NULL, "reader not set\n" );
312 /* can't retrieve properties before input is set */
313 max_depth = 0xdeadbeef;
314 size = sizeof(max_depth);
315 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
316 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
317 ok( max_depth == 0xdeadbeef, "max_depth set\n" );
319 hr = set_input( reader, data1, sizeof(data1) - 1 );
320 ok( hr == S_OK, "got %08x\n", hr );
322 /* check some defaults */
323 max_depth = 0xdeadbeef;
324 size = sizeof(max_depth);
325 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
326 ok( hr == S_OK, "got %08x\n", hr );
327 ok( max_depth == 32, "got %u\n", max_depth );
329 allow_fragment = TRUE;
330 size = sizeof(allow_fragment);
331 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_ALLOW_FRAGMENT, &allow_fragment, size, NULL );
332 ok( hr == S_OK, "got %08x\n", hr );
333 ok( !allow_fragment, "got %d\n", allow_fragment );
335 max_attrs = 0xdeadbeef;
336 size = sizeof(max_attrs);
337 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES, &max_attrs, size, NULL );
338 ok( hr == S_OK, "got %08x\n", hr );
339 ok( max_attrs == 128, "got %u\n", max_attrs );
341 read_decl = FALSE;
342 size = sizeof(read_decl);
343 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_READ_DECLARATION, &read_decl, size, NULL );
344 ok( hr == S_OK, "got %08x\n", hr );
345 ok( read_decl, "got %u\n", read_decl );
347 charset = 0xdeadbeef;
348 size = sizeof(charset);
349 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
350 ok( hr == S_OK, "got %08x\n", hr );
351 ok( charset == WS_CHARSET_UTF8, "got %u\n", charset );
353 size = sizeof(trim_size);
354 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_UTF8_TRIM_SIZE, &trim_size, size, NULL );
355 todo_wine ok( hr == E_INVALIDARG, "got %08x\n", hr );
356 WsFreeReader( reader );
358 hr = WsCreateReader( NULL, 0, &reader, NULL );
359 ok( hr == S_OK, "got %08x\n", hr );
361 hr = set_input( reader, data1, sizeof(data1) - 1 );
362 ok( hr == S_OK, "got %08x\n", hr );
364 size = sizeof(buffer_size);
365 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_STREAM_BUFFER_SIZE, &buffer_size, size, NULL );
366 todo_wine ok( hr == E_INVALIDARG, "got %08x\n", hr );
367 WsFreeReader( reader );
369 hr = WsCreateReader( NULL, 0, &reader, NULL );
370 ok( hr == S_OK, "got %08x\n", hr );
372 hr = set_input( reader, data1, sizeof(data1) - 1 );
373 ok( hr == S_OK, "got %08x\n", hr );
375 max_ns = 0xdeadbeef;
376 size = sizeof(max_ns);
377 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_NAMESPACES, &max_ns, size, NULL );
378 ok( hr == S_OK, "got %08x\n", hr );
379 ok( max_ns == 32, "got %u\n", max_ns );
380 WsFreeReader( reader );
382 /* change a property */
383 max_depth = 16;
384 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
385 prop.value = &max_depth;
386 prop.valueSize = sizeof(max_depth);
387 hr = WsCreateReader( &prop, 1, &reader, NULL );
388 ok( hr == S_OK, "got %08x\n", hr );
390 hr = set_input( reader, data1, sizeof(data1) - 1 );
391 ok( hr == S_OK, "got %08x\n", hr );
393 max_depth = 0xdeadbeef;
394 size = sizeof(max_depth);
395 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
396 ok( hr == S_OK, "got %08x\n", hr );
397 ok( max_depth == 16, "got %u\n", max_depth );
398 WsFreeReader( reader );
400 /* show that some properties are read-only */
401 row = 1;
402 prop.id = WS_XML_READER_PROPERTY_ROW;
403 prop.value = &row;
404 prop.valueSize = sizeof(row);
405 hr = WsCreateReader( &prop, 1, &reader, NULL );
406 ok( hr == E_INVALIDARG, "got %08x\n", hr );
408 column = 1;
409 prop.id = WS_XML_READER_PROPERTY_COLUMN;
410 prop.value = &column;
411 prop.valueSize = sizeof(column);
412 hr = WsCreateReader( &prop, 1, &reader, NULL );
413 ok( hr == E_INVALIDARG, "got %08x\n", hr );
415 in_attr = TRUE;
416 prop.id = WS_XML_READER_PROPERTY_IN_ATTRIBUTE;
417 prop.value = &in_attr;
418 prop.valueSize = sizeof(in_attr);
419 hr = WsCreateReader( &prop, 1, &reader, NULL );
420 ok( hr == E_INVALIDARG, "got %08x\n", hr );
423 static void test_WsSetInput(void)
425 static char test1[] = {0xef,0xbb,0xbf,'<','a','/','>'};
426 static char test2[] = {'<','a','/','>'};
427 static char test3[] = {'<','!','-','-'};
428 static char test4[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"',
429 ' ','e','n','c','o','d','i','n','g','=','"','u','t','f','-','8','"','?','>'};
430 static char test5[] = {'<','?','x','m','l',' ','e','n','c','o','d','i','n','g','=',
431 '"','u','t','f','-','8','"','?','>'};
432 static char test6[] = {'<','?','x','m','l'};
433 static char test7[] = {'<','?','y','m','l'};
434 static char test8[] = {'<','?'};
435 static char test9[] = {'<','!'};
436 static char test10[] = {0xff,0xfe,'<',0,'a',0,'/',0,'>',0};
437 static char test11[] = {'<',0,'a',0,'/',0,'>',0};
438 static char test12[] = {'<',0,'!',0,'-',0,'-',0};
439 static char test13[] = {'<',0,'?',0};
440 static char test14[] = {'a','b'};
441 static char test15[] = {'a','b','c'};
442 static char test16[] = {'a',0};
443 static char test17[] = {'a',0,'b',0};
444 static char test18[] = {'<',0,'a',0,'b',0};
445 static char test19[] = {'<',0,'a',0};
446 static char test20[] = {0,'a','b'};
447 static char test21[] = {0,0};
448 static char test22[] = {0,0,0};
449 static char test23[] = {'<',0,'?',0,'x',0,'m',0,'l',0};
450 static char test24[] = {'<',0,'a',0,'>',0,'b',0,'<',0,'/',0,'>',0};
451 HRESULT hr;
452 WS_XML_READER *reader;
453 WS_XML_READER_PROPERTY prop;
454 WS_XML_READER_TEXT_ENCODING enc;
455 WS_XML_READER_BUFFER_INPUT input;
456 WS_XML_TEXT_NODE *text;
457 WS_XML_UTF8_TEXT *utf8;
458 WS_CHARSET charset;
459 const WS_XML_NODE *node;
460 ULONG i, size, max_depth;
461 BOOL found;
462 static const struct
464 void *data;
465 ULONG size;
466 HRESULT hr;
467 WS_CHARSET charset;
468 int todo;
470 tests[] =
472 { test1, sizeof(test1), S_OK, WS_CHARSET_UTF8 },
473 { test2, sizeof(test2), S_OK, WS_CHARSET_UTF8 },
474 { test3, sizeof(test3), S_OK, WS_CHARSET_UTF8 },
475 { test4, sizeof(test4), S_OK, WS_CHARSET_UTF8 },
476 { test5, sizeof(test5), WS_E_INVALID_FORMAT, 0, 1 },
477 { test6, sizeof(test6), WS_E_INVALID_FORMAT, 0, 1 },
478 { test7, sizeof(test7), WS_E_INVALID_FORMAT, 0, 1 },
479 { test8, sizeof(test8), WS_E_INVALID_FORMAT, 0 },
480 { test9, sizeof(test9), WS_E_INVALID_FORMAT, 0 },
481 { test10, sizeof(test10), S_OK, WS_CHARSET_UTF16LE },
482 { test11, sizeof(test11), S_OK, WS_CHARSET_UTF16LE },
483 { test12, sizeof(test12), S_OK, WS_CHARSET_UTF16LE },
484 { test13, sizeof(test13), WS_E_INVALID_FORMAT, 0, 1 },
485 { test14, sizeof(test14), WS_E_INVALID_FORMAT, 0 },
486 { test15, sizeof(test15), S_OK, WS_CHARSET_UTF8 },
487 { test16, sizeof(test16), WS_E_INVALID_FORMAT, 0 },
488 { test17, sizeof(test17), S_OK, WS_CHARSET_UTF8 },
489 { test18, sizeof(test18), S_OK, WS_CHARSET_UTF16LE },
490 { test19, sizeof(test19), S_OK, WS_CHARSET_UTF16LE },
491 { test20, sizeof(test20), S_OK, WS_CHARSET_UTF8 },
492 { test21, sizeof(test21), WS_E_INVALID_FORMAT, 0 },
493 { test22, sizeof(test22), S_OK, WS_CHARSET_UTF8 },
494 { test23, sizeof(test23), WS_E_INVALID_FORMAT, 0, 1 },
497 hr = WsCreateReader( NULL, 0, &reader, NULL );
498 ok( hr == S_OK, "got %08x\n", hr );
500 hr = WsSetInput( NULL, NULL, NULL, NULL, 0, NULL );
501 ok( hr == E_INVALIDARG, "got %08x\n", hr );
503 node = NULL;
504 hr = WsGetReaderNode( reader, &node, NULL );
505 ok( hr == S_OK, "got %08x\n", hr );
506 ok( node != NULL, "node not set\n" );
507 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
509 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
510 enc.charSet = WS_CHARSET_UTF8;
512 input.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
513 input.encodedData = (void *)data1;
514 input.encodedDataSize = sizeof(data1) - 1;
516 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
517 ok( hr == S_OK, "got %08x\n", hr );
519 node = NULL;
520 hr = WsGetReaderNode( reader, &node, NULL );
521 ok( hr == S_OK, "got %08x\n", hr );
522 ok( node != NULL, "node not set\n" );
523 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
525 /* multiple calls are allowed */
526 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
527 ok( hr == S_OK, "got %08x\n", hr );
529 /* charset is detected by WsSetInput */
530 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
531 enc.charSet = WS_CHARSET_AUTO;
533 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
535 input.encodedData = tests[i].data;
536 input.encodedDataSize = tests[i].size;
537 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
538 ok( hr == S_OK, "%u: got %08x\n", i, hr );
540 charset = 0xdeadbeef;
541 size = sizeof(charset);
542 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
543 todo_wine_if (tests[i].todo)
545 ok( hr == tests[i].hr, "%u: got %08x expected %08x\n", i, hr, tests[i].hr );
546 if (hr == S_OK)
547 ok( charset == tests[i].charset, "%u: got %u expected %u\n", i, charset, tests[i].charset );
551 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
552 enc.charSet = WS_CHARSET_UTF8;
554 /* reader properties can be set with WsSetInput */
555 max_depth = 16;
556 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
557 prop.value = &max_depth;
558 prop.valueSize = sizeof(max_depth);
559 hr = WsSetInput( reader, &enc.encoding, &input.input, &prop, 1, NULL );
560 ok( hr == S_OK, "got %08x\n", hr );
562 max_depth = 0xdeadbeef;
563 size = sizeof(max_depth);
564 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
565 ok( hr == S_OK, "got %08x\n", hr );
566 ok( max_depth == 16, "got %u\n", max_depth );
568 /* show that the reader converts text to UTF-8 */
569 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
570 enc.charSet = WS_CHARSET_UTF16LE;
571 input.encodedData = (void *)test24;
572 input.encodedDataSize = sizeof(test24);
573 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
574 ok( hr == S_OK, "got %08x\n", hr );
576 found = -1;
577 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
578 todo_wine ok( hr == S_OK, "got %08x\n", hr );
579 if (hr == S_OK)
581 ok( found == TRUE, "got %d\n", found );
583 hr = WsReadStartElement( reader, NULL );
584 ok( hr == S_OK, "got %08x\n", hr );
586 hr = WsGetReaderNode( reader, &node, NULL );
587 ok( hr == S_OK, "got %08x\n", hr );
588 text = (WS_XML_TEXT_NODE *)node;
589 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
590 ok( text->text != NULL, "text not set\n" );
591 utf8 = (WS_XML_UTF8_TEXT *)text->text;
592 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
593 ok( utf8->value.length == 1, "got %u\n", utf8->value.length );
594 ok( utf8->value.bytes[0] == 'b', "wrong data\n" );
596 WsFreeReader( reader );
599 static void test_WsSetInputToBuffer(void)
601 HRESULT hr;
602 WS_HEAP *heap;
603 WS_XML_BUFFER *buffer;
604 WS_XML_READER *reader;
605 WS_XML_READER_PROPERTY prop;
606 const WS_XML_NODE *node;
607 ULONG size, max_depth;
609 hr = WsCreateReader( NULL, 0, &reader, NULL );
610 ok( hr == S_OK, "got %08x\n", hr );
612 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
613 ok( hr == S_OK, "got %08x\n", hr );
615 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
616 ok( hr == S_OK, "got %08x\n", hr );
618 hr = WsSetInputToBuffer( NULL, NULL, NULL, 0, NULL );
619 ok( hr == E_INVALIDARG, "got %08x\n", hr );
621 hr = WsSetInputToBuffer( reader, NULL, NULL, 0, NULL );
622 ok( hr == E_INVALIDARG, "got %08x\n", hr );
624 node = NULL;
625 hr = WsGetReaderNode( reader, &node, NULL );
626 ok( hr == S_OK, "got %08x\n", hr );
627 ok( node != NULL, "node not set\n" );
628 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
630 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
631 ok( hr == S_OK, "got %08x\n", hr );
633 node = NULL;
634 hr = WsGetReaderNode( reader, &node, NULL );
635 ok( hr == S_OK, "got %08x\n", hr );
636 ok( node != NULL, "node not set\n" );
637 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
639 /* multiple calls are allowed */
640 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
641 ok( hr == S_OK, "got %08x\n", hr );
643 /* reader properties can be set with WsSetInputToBuffer */
644 max_depth = 16;
645 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
646 prop.value = &max_depth;
647 prop.valueSize = sizeof(max_depth);
648 hr = WsSetInputToBuffer( reader, buffer, &prop, 1, NULL );
649 ok( hr == S_OK, "got %08x\n", hr );
651 max_depth = 0xdeadbeef;
652 size = sizeof(max_depth);
653 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
654 ok( hr == S_OK, "got %08x\n", hr );
655 ok( max_depth == 16, "got %u\n", max_depth );
657 WsFreeReader( reader );
658 WsFreeHeap( heap );
661 static void test_WsFillReader(void)
663 HRESULT hr;
664 WS_XML_READER *reader;
665 const WS_XML_NODE *node;
667 /* what happens of we don't call WsFillReader? */
668 hr = WsCreateReader( NULL, 0, &reader, NULL );
669 ok( hr == S_OK, "got %08x\n", hr );
671 node = NULL;
672 hr = WsGetReaderNode( reader, &node, NULL );
673 ok( hr == S_OK, "got %08x\n", hr );
674 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
676 hr = set_input( reader, data1, sizeof(data1) - 1 );
677 ok( hr == S_OK, "got %08x\n", hr );
679 node = NULL;
680 hr = WsGetReaderNode( reader, &node, NULL );
681 ok( hr == S_OK, "got %08x\n", hr );
682 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
684 hr = WsReadNode( reader, NULL );
685 ok( hr == S_OK, "got %08x\n", hr );
687 node = NULL;
688 hr = WsGetReaderNode( reader, &node, NULL );
689 ok( hr == S_OK, "got %08x\n", hr );
690 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
691 WsFreeReader( reader );
693 hr = WsCreateReader( NULL, 0, &reader, NULL );
694 ok( hr == S_OK, "got %08x\n", hr );
696 hr = set_input( reader, data1, sizeof(data1) - 1 );
697 ok( hr == S_OK, "got %08x\n", hr );
699 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
700 ok( hr == S_OK, "got %08x\n", hr );
702 hr = set_input( reader, data1, sizeof(data1) - 1 );
703 ok( hr == S_OK, "got %08x\n", hr );
705 node = NULL;
706 hr = WsGetReaderNode( reader, &node, NULL );
707 ok( hr == S_OK, "got %08x\n", hr );
708 ok( node != NULL, "node not set\n" );
709 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
711 hr = WsFillReader( NULL, sizeof(data1) - 1, NULL, NULL );
712 ok( hr == E_INVALIDARG, "got %08x\n", hr );
714 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
715 ok( hr == S_OK, "got %08x\n", hr );
717 node = NULL;
718 hr = WsGetReaderNode( reader, &node, NULL );
719 ok( hr == S_OK, "got %08x\n", hr );
720 ok( node != NULL, "node not set\n" );
721 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
723 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
724 ok( hr == S_OK, "got %08x\n", hr );
726 /* min_size larger than input size */
727 hr = WsFillReader( reader, sizeof(data1), NULL, NULL );
728 ok( hr == S_OK, "got %08x\n", hr );
729 WsFreeReader( reader );
732 static void test_WsReadToStartElement(void)
734 HRESULT hr;
735 WS_XML_READER *reader;
736 const WS_XML_NODE *node, *node2;
737 int found;
739 hr = WsCreateReader( NULL, 0, &reader, NULL );
740 ok( hr == S_OK, "got %08x\n", hr );
742 hr = set_input( reader, data1, sizeof(data1) - 1 );
743 ok( hr == S_OK, "got %08x\n", hr );
745 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
746 ok( hr == S_OK, "got %08x\n", hr );
748 hr = WsGetReaderNode( reader, &node, NULL );
749 ok( hr == S_OK, "got %08x\n", hr );
750 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
752 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
753 ok( hr == S_OK, "got %08x\n", hr );
755 hr = WsReadToStartElement( NULL, NULL, NULL, NULL, NULL );
756 ok( hr == E_INVALIDARG, "got %08x\n", hr );
758 found = -1;
759 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
760 ok( hr == S_OK, "got %08x\n", hr );
761 ok( found == FALSE, "got %d\n", found );
763 hr = WsGetReaderNode( reader, &node, NULL );
764 ok( hr == S_OK, "got %08x\n", hr );
765 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
767 hr = set_input( reader, data2, sizeof(data2) - 1 );
768 ok( hr == S_OK, "got %08x\n", hr );
770 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
771 ok( hr == S_OK, "got %08x\n", hr );
773 hr = WsGetReaderNode( reader, &node, NULL );
774 ok( hr == S_OK, "got %08x\n", hr );
775 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
777 found = -1;
778 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
779 ok( hr == S_OK, "got %08x\n", hr );
780 ok( found == TRUE, "got %d\n", found );
782 hr = WsGetReaderNode( reader, &node, NULL );
783 ok( hr == S_OK, "got %08x\n", hr );
784 if (node)
786 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
788 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
789 ok( elem->prefix != NULL, "prefix not set\n" );
790 if (elem->prefix)
792 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
794 ok( elem->localName != NULL, "localName not set\n" );
795 if (elem->localName)
797 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
798 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
800 ok( elem->ns != NULL, "ns not set\n" );
801 if (elem->ns)
803 ok( !elem->ns->length, "got %u\n", elem->ns->length );
805 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
806 ok( elem->attributes == NULL, "attributes set\n" );
807 ok( !elem->isEmpty, "isEmpty not zero\n" );
810 found = -1;
811 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
812 ok( hr == S_OK, "got %08x\n", hr );
813 ok( found == TRUE, "got %d\n", found );
815 node2 = NULL;
816 hr = WsGetReaderNode( reader, &node2, NULL );
817 ok( hr == S_OK, "got %08x\n", hr );
818 ok( node2 == node, "different node\n" );
820 hr = set_input( reader, data3, sizeof(data3) - 1 );
821 ok( hr == S_OK, "got %08x\n", hr );
823 hr = WsFillReader( reader, sizeof(data3) - 1, NULL, NULL );
824 ok( hr == S_OK, "got %08x\n", hr );
826 found = -1;
827 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
828 ok( hr == S_OK, "got %08x\n", hr );
829 ok( found == TRUE, "got %d\n", found );
831 hr = WsGetReaderNode( reader, &node, NULL );
832 ok( hr == S_OK, "got %08x\n", hr );
833 if (node)
835 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
837 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
838 ok( elem->localName != NULL, "localName not set\n" );
839 if (elem->localName)
841 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
842 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
846 hr = set_input( reader, data4, sizeof(data4) - 1 );
847 ok( hr == S_OK, "got %08x\n", hr );
849 hr = WsFillReader( reader, sizeof(data4) - 1, NULL, NULL );
850 ok( hr == S_OK, "got %08x\n", hr );
852 found = -1;
853 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
854 ok( hr == S_OK, "got %08x\n", hr );
855 ok( found == TRUE, "got %d\n", found );
856 WsFreeReader( reader );
859 static void test_WsReadStartElement(void)
861 HRESULT hr;
862 WS_XML_READER *reader;
863 const WS_XML_NODE *node, *node2;
864 int found;
866 hr = WsCreateReader( NULL, 0, &reader, NULL );
867 ok( hr == S_OK, "got %08x\n", hr );
869 hr = set_input( reader, data2, sizeof(data2) - 1 );
870 ok( hr == S_OK, "got %08x\n", hr );
872 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
873 ok( hr == S_OK, "got %08x\n", hr );
875 found = -1;
876 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
877 ok( hr == S_OK, "got %08x\n", hr );
878 ok( found == TRUE, "got %d\n", found );
880 hr = WsReadStartElement( NULL, NULL );
881 ok( hr == E_INVALIDARG, "got %08x\n", hr );
883 hr = WsGetReaderNode( reader, &node, NULL );
884 ok( hr == S_OK, "got %08x\n", hr );
885 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
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_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
895 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
896 ok( text->text != NULL, "text not set\n" );
897 if (text->text)
899 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
900 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
901 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
902 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong data\n" );
906 hr = WsReadStartElement( reader, NULL );
907 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
909 node2 = NULL;
910 hr = WsGetReaderNode( reader, &node2, NULL );
911 ok( hr == S_OK, "got %08x\n", hr );
912 ok( node2 == node, "different node\n" );
914 hr = set_input( reader, data8, sizeof(data8) - 1 );
915 ok( hr == S_OK, "got %08x\n", hr );
917 hr = WsFillReader( reader, sizeof(data8) - 1, NULL, NULL );
918 ok( hr == S_OK, "got %08x\n", hr );
920 found = -1;
921 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
922 ok( hr == S_OK, "got %08x\n", hr );
923 ok( found == TRUE, "got %d\n", found );
925 hr = WsGetReaderNode( reader, &node, NULL );
926 ok( hr == S_OK, "got %08x\n", hr );
927 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
929 hr = WsGetReaderNode( reader, &node, NULL );
930 ok( hr == S_OK, "got %08x\n", hr );
931 if (node)
933 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
934 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
935 ok( !memcmp( elem->localName->bytes, "node1", 5), "wrong name\n" );
938 hr = WsReadStartElement( reader, NULL );
939 ok( hr == S_OK, "got %08x\n", hr );
941 hr = WsGetReaderNode( reader, &node, NULL );
942 ok( hr == S_OK, "got %08x\n", hr );
943 if (node)
945 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
946 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
947 ok( !memcmp( elem->localName->bytes, "node2", 5), "wrong name\n" );
950 hr = WsReadNode( reader, NULL );
951 ok( hr == S_OK, "got %08x\n", hr );
953 hr = WsGetReaderNode( reader, &node, NULL );
954 ok( hr == S_OK, "got %08x\n", hr );
955 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
957 hr = WsReadNode( reader, NULL );
958 ok( hr == S_OK, "got %08x\n", hr );
960 hr = WsGetReaderNode( reader, &node, NULL );
961 ok( hr == S_OK, "got %08x\n", hr );
962 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
964 hr = WsReadEndElement( reader, NULL );
965 ok( hr == S_OK, "got %08x\n", hr );
967 hr = WsGetReaderNode( reader, &node, NULL );
968 ok( hr == S_OK, "got %08x\n", hr );
969 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
971 /* WsReadEndElement advances reader to EOF */
972 hr = WsReadEndElement( reader, NULL );
973 ok( hr == S_OK, "got %08x\n", hr );
975 hr = WsGetReaderNode( reader, &node, NULL );
976 ok( hr == S_OK, "got %08x\n", hr );
977 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
979 hr = WsReadEndElement( reader, NULL );
980 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
982 WsFreeReader( reader );
985 static void test_WsReadEndElement(void)
987 HRESULT hr;
988 WS_XML_READER *reader;
989 const WS_XML_NODE *node;
990 int found;
992 hr = WsCreateReader( NULL, 0, &reader, NULL );
993 ok( hr == S_OK, "got %08x\n", hr );
995 hr = set_input( reader, data2, sizeof(data2) - 1 );
996 ok( hr == S_OK, "got %08x\n", hr );
998 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
999 ok( hr == S_OK, "got %08x\n", hr );
1001 hr = WsReadEndElement( reader, NULL );
1002 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1004 hr = set_input( reader, data2, sizeof(data2) - 1 );
1005 ok( hr == S_OK, "got %08x\n", hr );
1007 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
1008 ok( hr == S_OK, "got %08x\n", hr );
1010 hr = WsReadNode( reader, NULL );
1011 ok( hr == S_OK, "got %08x\n", hr );
1013 hr = WsGetReaderNode( reader, &node, NULL );
1014 ok( hr == S_OK, "got %08x\n", hr );
1015 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1017 hr = WsReadNode( reader, NULL );
1018 ok( hr == S_OK, "got %08x\n", hr );
1020 hr = WsGetReaderNode( reader, &node, NULL );
1021 ok( hr == S_OK, "got %08x\n", hr );
1022 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
1024 hr = WsReadNode( reader, NULL );
1025 ok( hr == S_OK, "got %08x\n", hr );
1027 hr = WsGetReaderNode( reader, &node, NULL );
1028 ok( hr == S_OK, "got %08x\n", hr );
1029 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1031 hr = WsReadNode( reader, NULL );
1032 ok( hr == S_OK, "got %08x\n", hr );
1034 hr = WsGetReaderNode( reader, &node, NULL );
1035 ok( hr == S_OK, "got %08x\n", hr );
1036 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1038 hr = set_input( reader, data2, sizeof(data2) - 1 );
1039 ok( hr == S_OK, "got %08x\n", hr );
1041 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
1042 ok( hr == S_OK, "got %08x\n", hr );
1044 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1045 ok( hr == S_OK, "got %08x\n", hr );
1047 hr = WsReadStartElement( reader, NULL );
1048 ok( hr == S_OK, "got %08x\n", hr );
1050 hr = WsGetReaderNode( reader, &node, NULL );
1051 ok( hr == S_OK, "got %08x\n", hr );
1052 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
1054 hr = WsReadNode( reader, NULL );
1055 ok( hr == S_OK, "got %08x\n", hr );
1057 hr = WsGetReaderNode( reader, &node, NULL );
1058 ok( hr == S_OK, "got %08x\n", hr );
1059 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1061 /* WsReadEndElement advances reader to EOF */
1062 hr = WsReadEndElement( reader, NULL );
1063 ok( hr == S_OK, "got %08x\n", hr );
1065 hr = WsGetReaderNode( reader, &node, NULL );
1066 ok( hr == S_OK, "got %08x\n", hr );
1067 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1069 hr = WsReadEndElement( reader, NULL );
1070 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1072 hr = set_input( reader, data5, sizeof(data5) - 1 );
1073 ok( hr == S_OK, "got %08x\n", hr );
1075 hr = WsFillReader( reader, sizeof(data5) - 1, NULL, NULL );
1076 ok( hr == S_OK, "got %08x\n", hr );
1078 hr = WsReadEndElement( reader, NULL );
1079 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1081 hr = set_input( reader, data10, sizeof(data10) - 1 );
1082 ok( hr == S_OK, "got %08x\n", hr );
1084 hr = WsFillReader( reader, sizeof(data10) - 1, NULL, NULL );
1085 ok( hr == S_OK, "got %08x\n", hr );
1087 hr = WsReadNode( reader, NULL );
1088 ok( hr == S_OK, "got %08x\n", hr );
1090 hr = WsGetReaderNode( reader, &node, NULL );
1091 ok( hr == S_OK, "got %08x\n", hr );
1092 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1094 hr = WsReadEndElement( reader, NULL );
1095 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1097 hr = set_input( reader, "<a></A>", sizeof("<a></A>") - 1 );
1098 ok( hr == S_OK, "got %08x\n", hr );
1100 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1101 ok( hr == S_OK, "got %08x\n", hr );
1103 found = -1;
1104 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1105 ok( hr == S_OK, "got %08x\n", hr );
1106 ok( found == TRUE, "got %d\n", found );
1108 hr = WsGetReaderNode( reader, &node, NULL );
1109 ok( hr == S_OK, "got %08x\n", hr );
1110 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1112 hr = WsReadEndElement( reader, NULL );
1113 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1115 hr = set_input( reader, "<a></a>", sizeof("<a></a>") - 1 );
1116 ok( hr == S_OK, "got %08x\n", hr );
1118 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1119 ok( hr == S_OK, "got %08x\n", hr );
1121 found = -1;
1122 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1123 ok( hr == S_OK, "got %08x\n", hr );
1124 ok( found == TRUE, "got %d\n", found );
1126 hr = WsGetReaderNode( reader, &node, NULL );
1127 ok( hr == S_OK, "got %08x\n", hr );
1128 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1130 hr = WsReadStartElement( reader, NULL );
1131 ok( hr == S_OK, "got %08x\n", hr );
1133 hr = WsGetReaderNode( reader, &node, NULL );
1134 ok( hr == S_OK, "got %08x\n", hr );
1135 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1137 hr = WsReadEndElement( reader, NULL );
1138 ok( hr == S_OK, "got %08x\n", hr );
1140 hr = WsGetReaderNode( reader, &node, NULL );
1141 ok( hr == S_OK, "got %08x\n", hr );
1142 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1144 hr = set_input( reader, "<a/>", sizeof("<a/>") - 1 );
1145 ok( hr == S_OK, "got %08x\n", hr );
1147 hr = WsFillReader( reader, sizeof("<a/>") - 1, NULL, NULL );
1148 ok( hr == S_OK, "got %08x\n", hr );
1150 found = -1;
1151 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1152 ok( hr == S_OK, "got %08x\n", hr );
1153 ok( found == TRUE, "got %d\n", found );
1155 hr = WsGetReaderNode( reader, &node, NULL );
1156 ok( hr == S_OK, "got %08x\n", hr );
1157 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1159 hr = WsReadStartElement( reader, NULL );
1160 ok( hr == S_OK, "got %08x\n", hr );
1162 hr = WsGetReaderNode( reader, &node, NULL );
1163 ok( hr == S_OK, "got %08x\n", hr );
1164 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1166 hr = WsReadEndElement( reader, NULL );
1167 ok( hr == S_OK, "got %08x\n", hr );
1169 WsFreeReader( reader );
1172 static void test_WsReadNode(void)
1174 static const char str1[] = "<a>";
1175 static const char str2[] = "< a>";
1176 static const char str3[] = "<a >";
1177 static const char str4[] = "<<a>>";
1178 static const char str5[] = "<>";
1179 static const char str6[] = "</a>";
1180 static const char str7[] = " <a>";
1181 static const char str8[] = "<?xml>";
1182 static const char str9[] = "<?xml?>";
1183 static const char str10[] = "<?xml ?>";
1184 static const char str11[] = "<?xml version=\"1.0\"?>";
1185 static const char str12[] = "<text>test</text>";
1186 static const char str13[] = "<?xml version=\"1.0\"?><text>test</text>";
1187 static const char str14[] = "";
1188 static const char str15[] = "<!--";
1189 static const char str16[] = "<!---->";
1190 static const char str17[] = "<!--comment-->";
1191 HRESULT hr;
1192 WS_XML_READER *reader;
1193 WS_XML_DICTIONARY *dict;
1194 const WS_XML_NODE *node;
1195 unsigned int i;
1196 int found;
1197 static const struct
1199 const char *text;
1200 HRESULT hr;
1201 WS_XML_NODE_TYPE type;
1202 int todo;
1204 tests[] =
1206 { str1, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1207 { str2, WS_E_INVALID_FORMAT, 0 },
1208 { str3, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1209 { str4, WS_E_INVALID_FORMAT, 0 },
1210 { str5, WS_E_INVALID_FORMAT, 0 },
1211 { str6, WS_E_INVALID_FORMAT, 0 },
1212 { str7, S_OK, WS_XML_NODE_TYPE_TEXT },
1213 { str8, WS_E_INVALID_FORMAT, 0 },
1214 { str9, WS_E_INVALID_FORMAT, 0 },
1215 { str10, WS_E_INVALID_FORMAT, 0, 1 },
1216 { str11, S_OK, WS_XML_NODE_TYPE_EOF },
1217 { str12, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1218 { str13, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1219 { str14, WS_E_INVALID_FORMAT, 0, 1 },
1220 { str15, WS_E_INVALID_FORMAT, 0 },
1221 { str16, S_OK, WS_XML_NODE_TYPE_COMMENT },
1222 { str17, S_OK, WS_XML_NODE_TYPE_COMMENT },
1225 hr = WsCreateReader( NULL, 0, &reader, NULL );
1226 ok( hr == S_OK, "got %08x\n", hr );
1228 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
1230 hr = set_input( reader, tests[i].text, strlen(tests[i].text) );
1231 ok( hr == S_OK, "got %08x\n", hr );
1233 hr = WsFillReader( reader, strlen(tests[i].text), NULL, NULL );
1234 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1236 hr = WsReadNode( reader, NULL );
1237 todo_wine_if (tests[i].todo)
1238 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
1239 if (hr == S_OK)
1241 node = NULL;
1242 hr = WsGetReaderNode( reader, &node, NULL );
1243 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1244 ok( node != NULL, "%u: node not set\n", i );
1245 if (node)
1247 todo_wine_if (tests[i].todo)
1248 ok( node->nodeType == tests[i].type, "%u: got %u\n", i, node->nodeType );
1253 hr = set_input( reader, data6, sizeof(data6) - 1 );
1254 ok( hr == S_OK, "got %08x\n", hr );
1256 hr = WsFillReader( reader, sizeof(data6) - 1, NULL, NULL );
1257 ok( hr == S_OK, "got %08x\n", hr );
1259 found = -1;
1260 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1261 ok( hr == S_OK, "got %08x\n", hr );
1262 ok( found == TRUE, "got %d\n", found );
1264 hr = WsGetReaderNode( reader, &node, NULL );
1265 ok( hr == S_OK, "got %08x\n", hr );
1266 if (node)
1268 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
1269 WS_XML_ATTRIBUTE *attr;
1270 WS_XML_UTF8_TEXT *text;
1272 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1273 ok( elem->prefix != NULL, "prefix not set\n" );
1274 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
1275 ok( elem->prefix->bytes == NULL, "bytes set\n" );
1276 ok( elem->localName != NULL, "localName not set\n" );
1277 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
1278 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
1279 ok( elem->ns != NULL, "ns not set\n" );
1280 ok( !elem->ns->length, "got %u\n", elem->ns->length );
1281 ok( elem->ns->bytes != NULL, "bytes not set\n" );
1282 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
1283 ok( elem->attributes != NULL, "attributes not set\n" );
1284 ok( !elem->isEmpty, "isEmpty not zero\n" );
1286 attr = elem->attributes[0];
1287 ok( !attr->singleQuote, "got %u\n", attr->singleQuote );
1288 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1289 ok( attr->prefix != NULL, "prefix not set\n" );
1290 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1291 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1292 ok( attr->localName != NULL, "localName not set\n" );
1293 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
1294 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
1295 ok( attr->ns != NULL, "ns not set\n" );
1296 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1297 ok( attr->ns->bytes == NULL, "bytes set\n" );
1298 ok( attr->value != NULL, "value not set\n" );
1300 text = (WS_XML_UTF8_TEXT *)attr->value;
1301 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1302 ok( text->value.length == 5, "got %u\n", text->value.length );
1303 ok( !memcmp( text->value.bytes, "value", 5 ), "wrong data\n" );
1305 attr = elem->attributes[1];
1306 ok( attr->singleQuote == 1, "got %u\n", attr->singleQuote );
1307 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1308 ok( attr->prefix != NULL, "prefix not set\n" );
1309 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1310 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1311 ok( attr->localName != NULL, "localName not set\n" );
1312 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
1313 ok( !memcmp( attr->localName->bytes, "attr2", 5 ), "wrong data\n" );
1314 ok( attr->ns != NULL, "ns not set\n" );
1315 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1316 ok( attr->ns->bytes == NULL, "bytes set\n" );
1317 ok( attr->value != NULL, "value not set\n" );
1319 text = (WS_XML_UTF8_TEXT *)attr->value;
1320 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1321 ok( text->value.length == 6, "got %u\n", text->value.length );
1322 ok( !memcmp( text->value.bytes, "value2", 6 ), "wrong data\n" );
1325 hr = set_input( reader, data7, sizeof(data7) - 1 );
1326 ok( hr == S_OK, "got %08x\n", hr );
1328 hr = WsFillReader( reader, sizeof(data7) - 1, NULL, NULL );
1329 ok( hr == S_OK, "got %08x\n", hr );
1331 hr = WsReadNode( reader, NULL );
1332 ok( hr == S_OK, "got %08x\n", hr );
1334 hr = WsGetReaderNode( reader, &node, NULL );
1335 ok( hr == S_OK, "got %08x\n", hr );
1336 if (node)
1338 WS_XML_COMMENT_NODE *comment = (WS_XML_COMMENT_NODE *)node;
1340 ok( comment->node.nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", comment->node.nodeType );
1341 ok( comment->value.length == 9, "got %u\n", comment->value.length );
1342 ok( !memcmp( comment->value.bytes, " comment ", 9 ), "wrong data\n" );
1345 dict = (WS_XML_DICTIONARY *)0xdeadbeef;
1346 hr = WsGetDictionary( WS_ENCODING_XML_UTF8, &dict, NULL );
1347 ok( hr == S_OK, "got %08x\n", hr );
1348 ok( dict == NULL, "got %p\n", dict );
1350 dict = NULL;
1351 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_1, &dict, NULL );
1352 ok( hr == S_OK, "got %08x\n", hr );
1353 ok( dict != NULL, "dict not set\n" );
1355 dict = NULL;
1356 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_SESSION_1, &dict, NULL );
1357 ok( hr == S_OK, "got %08x\n", hr );
1358 ok( dict != NULL, "dict not set\n" );
1360 WsFreeReader( reader );
1363 static void prepare_type_test( WS_XML_READER *reader, const char *data, ULONG size )
1365 HRESULT hr;
1367 hr = set_input( reader, data, size );
1368 ok( hr == S_OK, "got %08x\n", hr );
1370 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1371 ok( hr == S_OK, "got %08x\n", hr );
1373 hr = WsReadStartElement( reader, NULL );
1374 ok( hr == S_OK, "got %08x\n", hr );
1377 static void test_WsReadType(void)
1379 static const WCHAR testW[] = {'t','e','s','t',0}, test2W[] = {' ','t','e','s','t',' '};
1380 static const GUID guid = {0,0,0,{0,0,0,0,0,0,0,0xa1}};
1381 static const char utf8[] = {'<','t','>',0xe2,0x80,0x99,'<','/','t','>'};
1382 static const WCHAR utf8W[] = {0x2019,0};
1383 HRESULT hr;
1384 WS_XML_READER *reader;
1385 WS_HEAP *heap;
1386 enum { ONE = 1, TWO = 2 };
1387 WS_XML_STRING one = { 3, (BYTE *)"ONE" }, two = { 3, (BYTE *)"TWO" }, val_xmlstr, *ptr_xmlstr;
1388 WS_ENUM_VALUE enum_values[] = { { ONE, &one }, { TWO, &two } };
1389 WS_ENUM_DESCRIPTION enum_desc;
1390 int val_enum, *ptr_enum;
1391 WCHAR *val_str;
1392 BOOL val_bool, *ptr_bool;
1393 INT8 val_int8, *ptr_int8;
1394 INT16 val_int16, *ptr_int16;
1395 INT32 val_int32, *ptr_int32;
1396 INT64 val_int64, *ptr_int64;
1397 UINT8 val_uint8, *ptr_uint8;
1398 UINT16 val_uint16, *ptr_uint16;
1399 UINT32 val_uint32, *ptr_uint32;
1400 UINT64 val_uint64, *ptr_uint64;
1401 GUID val_guid, *ptr_guid;
1402 WS_BYTES val_bytes, *ptr_bytes;
1403 WS_STRING val_string, *ptr_string;
1404 WS_UNIQUE_ID val_id, *ptr_id;
1405 WS_XML_QNAME val_qname, *ptr_qname;
1407 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1408 ok( hr == S_OK, "got %08x\n", hr );
1410 hr = WsCreateReader( NULL, 0, &reader, NULL );
1411 ok( hr == S_OK, "got %08x\n", hr );
1413 prepare_type_test( reader, data2, sizeof(data2) - 1 );
1414 hr = WsReadType( NULL, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1415 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1416 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1418 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1419 WS_READ_REQUIRED_POINTER, heap, &val_str, 0, NULL );
1420 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1422 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1423 WS_READ_REQUIRED_POINTER, heap, NULL, sizeof(val_str), NULL );
1424 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1426 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1427 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str) + 1, NULL );
1428 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1430 val_str = NULL;
1431 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1432 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1433 ok( hr == S_OK, "got %08x\n", hr );
1434 ok( val_str != NULL, "pointer not set\n" );
1435 if (val_str) ok( !lstrcmpW( val_str, testW ), "wrong data\n" );
1437 val_bool = -1;
1438 prepare_type_test( reader, "<t>true</t>", sizeof("<t>true</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 == TRUE, "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(BOOL), NULL );
1448 ok( hr == S_OK, "got %08x\n", hr );
1449 ok( val_bool == FALSE, "got %d\n", val_bool );
1451 val_bool = -1;
1452 prepare_type_test( reader, "<t>FALSE</t>", sizeof("<t>FALSE</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 == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1456 ok( val_bool == -1, "got %d\n", val_bool );
1458 val_bool = -1;
1459 prepare_type_test( reader, "<t>1</t>", sizeof("<t>1</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 == S_OK, "got %08x\n", hr );
1463 ok( val_bool == TRUE, "got %d\n", val_bool );
1465 val_bool = -1;
1466 prepare_type_test( reader, "<t>2</t>", sizeof("<t>2</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 == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1470 ok( val_bool == -1, "got %d\n", val_bool );
1472 val_bool = -1;
1473 prepare_type_test( reader, "<t>0</t>", sizeof("<t>0</t>") - 1 );
1474 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1475 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1476 ok( hr == S_OK, "got %08x\n", hr );
1477 ok( val_bool == FALSE, "got %d\n", val_bool );
1479 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1480 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1481 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1482 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1484 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1485 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1486 WS_READ_REQUIRED_POINTER, heap, &ptr_bool, sizeof(ptr_bool), NULL );
1487 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1489 val_int8 = 0;
1490 prepare_type_test( reader, "<t>-128</t>", sizeof("<t>-128</t>") - 1 );
1491 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1492 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1493 ok( hr == S_OK, "got %08x\n", hr );
1494 ok( val_int8 == -128, "got %d\n", val_int8 );
1496 prepare_type_test( reader, "<t> </t>", sizeof("<t> </t>") - 1 );
1497 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1498 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1499 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1501 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1502 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1503 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1504 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1506 prepare_type_test( reader, "<t>-</t>", sizeof("<t>-</t>") - 1 );
1507 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1508 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1509 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1511 val_int8 = -1;
1512 prepare_type_test( reader, "<t>-0</t>", sizeof("<t>-0</t>") - 1 );
1513 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1514 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1515 ok( hr == S_OK, "got %08x\n", hr );
1516 ok( !val_int8, "got %d\n", val_int8 );
1518 prepare_type_test( reader, "<t>-129</t>", sizeof("<t>-129</t>") - 1 );
1519 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1520 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1521 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1523 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1524 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1525 WS_READ_REQUIRED_POINTER, heap, &ptr_int8, sizeof(ptr_int8), NULL );
1526 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1528 val_int16 = 0;
1529 prepare_type_test( reader, "<t>-32768</t>", sizeof("<t>-32768</t>") - 1 );
1530 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1531 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1532 ok( hr == S_OK, "got %08x\n", hr );
1533 ok( val_int16 == -32768, "got %d\n", val_int16 );
1535 prepare_type_test( reader, "<t>-32769</t>", sizeof("<t>-32769</t>") - 1 );
1536 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1537 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1538 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1540 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1541 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1542 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1543 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1545 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1546 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1547 WS_READ_REQUIRED_POINTER, heap, &ptr_int16, sizeof(ptr_int16), NULL );
1548 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1550 val_int32 = 0;
1551 prepare_type_test( reader, "<t>-2147483648</t>", sizeof("<t>-2147483648</t>") - 1 );
1552 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1553 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1554 ok( hr == S_OK, "got %08x\n", hr );
1555 ok( val_int32 == -2147483647 - 1, "got %d\n", val_int32 );
1557 prepare_type_test( reader, "<t>-2147483649</t>", sizeof("<t>-2147483649</t>") - 1 );
1558 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1559 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1560 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1562 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1563 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1564 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1565 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1567 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1568 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1569 WS_READ_REQUIRED_POINTER, heap, &ptr_int32, sizeof(ptr_int32), NULL );
1570 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1572 val_int64 = 0;
1573 prepare_type_test( reader, "<t>-9223372036854775808</t>", sizeof("<t>-9223372036854775808</t>") - 1 );
1574 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1575 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1576 ok( hr == S_OK, "got %08x\n", hr );
1577 ok( val_int64 == -9223372036854775807 - 1, "wrong value\n" );
1579 prepare_type_test( reader, "<t>-9223372036854775809</t>", sizeof("<t>-9223372036854775809</t>") - 1 );
1580 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1581 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1582 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1584 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1585 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1586 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1587 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1589 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1590 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1591 WS_READ_REQUIRED_POINTER, heap, &ptr_int64, sizeof(ptr_int64), NULL );
1592 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1594 val_uint8 = 0;
1595 prepare_type_test( reader, "<t> 255 </t>", sizeof("<t> 255 </t>") - 1 );
1596 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1597 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1598 ok( hr == S_OK, "got %08x\n", hr );
1599 ok( val_uint8 == 255, "got %u\n", val_uint8 );
1601 prepare_type_test( reader, "<t>+255</t>", sizeof("<t>+255</t>") - 1 );
1602 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1603 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1604 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1606 prepare_type_test( reader, "<t>-255</t>", sizeof("<t>-255</t>") - 1 );
1607 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1608 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1609 todo_wine ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1611 prepare_type_test( reader, "<t>0xff</t>", sizeof("<t>0xff</t>") - 1 );
1612 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1613 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1614 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1616 prepare_type_test( reader, "<t>256</t>", sizeof("<t>256</t>") - 1 );
1617 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1618 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1619 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1621 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1622 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1623 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1624 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1626 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1627 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1628 WS_READ_REQUIRED_POINTER, heap, &ptr_uint8, sizeof(ptr_uint8), NULL );
1629 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1631 val_uint16 = 0;
1632 prepare_type_test( reader, "<t>65535</t>", sizeof("<t>65535</t>") - 1 );
1633 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1634 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1635 ok( hr == S_OK, "got %08x\n", hr );
1636 ok( val_uint16 == 65535, "got %u\n", val_uint16 );
1638 prepare_type_test( reader, "<t>65536</t>", sizeof("<t>65536</t>") - 1 );
1639 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1640 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1641 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1643 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1644 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1645 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1646 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1648 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1649 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1650 WS_READ_REQUIRED_POINTER, heap, &ptr_uint16, sizeof(ptr_uint16), NULL );
1651 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1653 val_uint32 = 0;
1654 prepare_type_test( reader, "<t>4294967295</t>", sizeof("<t>4294967295</t>") - 1 );
1655 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1656 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1657 ok( hr == S_OK, "got %08x\n", hr );
1658 ok( val_uint32 == ~0, "got %u\n", val_uint32 );
1660 prepare_type_test( reader, "<t>4294967296</t>", sizeof("<t>4294967296</t>") - 1 );
1661 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1662 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1663 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1665 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1666 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1667 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1668 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1670 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1671 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1672 WS_READ_REQUIRED_POINTER, heap, &ptr_uint32, sizeof(ptr_uint32), NULL );
1673 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1675 val_uint64 = 0;
1676 prepare_type_test( reader, "<t>18446744073709551615</t>", sizeof("<t>18446744073709551615</t>") - 1 );
1677 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1678 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1679 ok( hr == S_OK, "got %08x\n", hr );
1680 ok( val_uint64 == ~0, "wrong value\n" );
1682 prepare_type_test( reader, "<t>18446744073709551616</t>", sizeof("<t>18446744073709551616</t>") - 1 );
1683 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1684 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1685 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1687 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1688 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1689 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1690 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1692 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1693 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1694 WS_READ_REQUIRED_POINTER, heap, &ptr_uint64, sizeof(ptr_uint64), NULL );
1695 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1697 enum_desc.values = enum_values;
1698 enum_desc.valueCount = sizeof(enum_values)/sizeof(enum_values[0]);
1699 enum_desc.maxByteCount = 3;
1700 enum_desc.nameIndices = NULL;
1702 val_enum = 0;
1703 prepare_type_test( reader, "<t>ONE</t>", sizeof("<t>ONE</t>") - 1 );
1704 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1705 WS_READ_REQUIRED_VALUE, heap, &val_enum, sizeof(val_enum), NULL );
1706 ok( hr == S_OK, "got %08x\n", hr );
1707 ok( val_enum == 1, "got %d\n", val_enum );
1709 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1710 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1711 WS_READ_REQUIRED_VALUE, heap, &val_enum, sizeof(val_enum), NULL );
1712 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1714 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1715 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1716 WS_READ_REQUIRED_POINTER, heap, &ptr_enum, sizeof(ptr_enum), NULL );
1717 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
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 == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1725 memset( &val_guid, 0xff, sizeof(val_guid) );
1726 prepare_type_test( reader, "<t> 00000000-0000-0000-0000-000000000000 </t>",
1727 sizeof("<t> 00000000-0000-0000-0000-000000000000 </t>") - 1 );
1728 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1729 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1730 ok( hr == S_OK, "got %08x\n", hr );
1731 ok( IsEqualGUID( &val_guid, &guid_null ), "wrong guid\n" );
1733 memset( &val_guid, 0, sizeof(val_guid) );
1734 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000a1</t>",
1735 sizeof("<t>00000000-0000-0000-0000-0000000000a1</t>") - 1 );
1736 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1737 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1738 ok( hr == S_OK, "got %08x\n", hr );
1739 ok( IsEqualGUID( &val_guid, &guid ), "wrong guid\n" );
1741 memset( &val_guid, 0, sizeof(val_guid) );
1742 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000A1</t>",
1743 sizeof("<t>00000000-0000-0000-0000-0000000000A1</t>") - 1 );
1744 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1745 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1746 ok( hr == S_OK, "got %08x\n", hr );
1747 ok( IsEqualGUID( &val_guid, &guid ), "wrong guid\n" );
1749 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1750 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1751 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1752 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1754 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1755 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1756 WS_READ_REQUIRED_POINTER, heap, &ptr_guid, sizeof(ptr_guid), NULL );
1757 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1759 memset( &val_bytes, 0, sizeof(val_bytes) );
1760 prepare_type_test( reader, "<t>dGVzdA==</t>", sizeof("<t>dGVzdA==</t>") - 1 );
1761 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1762 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1763 ok( hr == S_OK, "got %08x\n", hr );
1764 ok( val_bytes.length == 4, "got %u\n", val_bytes.length );
1765 ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" );
1767 memset( &val_bytes, 0, sizeof(val_bytes) );
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 == S_OK, "got %08x\n", hr );
1772 ok( val_bytes.length == 4, "got %u\n", val_bytes.length );
1773 ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" );
1775 prepare_type_test( reader, "<t>dGVzdA===</t>", sizeof("<t>dGVzdA===</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 == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1780 val_bytes.length = 0xdeadbeef;
1781 val_bytes.bytes = (BYTE *)0xdeadbeef;
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_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1785 ok( hr == S_OK, "got %08x\n", hr );
1786 ok( !val_bytes.length, "got %u\n", val_bytes.length );
1787 todo_wine ok( val_bytes.bytes != NULL, "got %p\n", val_bytes.bytes );
1789 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1790 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1791 WS_READ_REQUIRED_POINTER, heap, &ptr_bytes, sizeof(ptr_bytes), NULL );
1792 ok( hr == S_OK, "got %08x\n", hr );
1793 ok( !ptr_bytes->length, "got %u\n", ptr_bytes->length );
1794 todo_wine ok( ptr_bytes->bytes != NULL, "got %p\n", ptr_bytes->bytes );
1796 val_str = NULL;
1797 prepare_type_test( reader, utf8, sizeof(utf8) );
1798 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1799 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1800 ok( hr == S_OK, "got %08x\n", hr );
1801 ok( val_str != NULL, "pointer not set\n" );
1802 ok( !lstrcmpW( val_str, utf8W ), "got %s\n", wine_dbgstr_w(val_str) );
1804 val_str = NULL;
1805 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1806 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1807 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1808 ok( hr == S_OK, "got %08x\n", hr );
1809 ok( val_str != NULL, "got %p\n", val_str );
1810 ok( !val_str[0], "got %s\n", wine_dbgstr_w(val_str) );
1812 memset( &val_xmlstr, 0, sizeof(val_xmlstr) );
1813 prepare_type_test( reader, "<t> test </t>", sizeof("<t> test </t>") - 1 );
1814 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_XML_STRING_TYPE, NULL,
1815 WS_READ_REQUIRED_VALUE, heap, &val_xmlstr, sizeof(val_xmlstr), NULL );
1816 ok( hr == S_OK, "got %08x\n", hr );
1817 ok( val_xmlstr.length == 6, "got %u\n", val_xmlstr.length );
1818 ok( !memcmp( val_xmlstr.bytes, " test ", 6 ), "wrong data\n" );
1820 val_xmlstr.length = 0xdeadbeef;
1821 val_xmlstr.bytes = (BYTE *)0xdeadbeef;
1822 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1823 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_XML_STRING_TYPE, NULL,
1824 WS_READ_REQUIRED_VALUE, heap, &val_xmlstr, sizeof(val_xmlstr), NULL );
1825 ok( hr == S_OK, "got %08x\n", hr );
1826 ok( !val_xmlstr.length, "got %u\n", val_bytes.length );
1827 todo_wine ok( val_xmlstr.bytes != NULL, "got %p\n", val_bytes.bytes );
1829 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_XML_STRING_TYPE, NULL,
1830 WS_READ_REQUIRED_POINTER, heap, &ptr_xmlstr, sizeof(ptr_xmlstr), NULL );
1831 ok( hr == S_OK, "got %08x\n", hr );
1832 ok( !ptr_xmlstr->length, "got %u\n", ptr_bytes->length );
1833 todo_wine ok( ptr_xmlstr->bytes != NULL, "got %p\n", ptr_bytes->bytes );
1835 memset( &val_string, 0, sizeof(val_string) );
1836 prepare_type_test( reader, "<t> test </t>", sizeof("<t> test </t>") - 1 );
1837 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRING_TYPE, NULL,
1838 WS_READ_REQUIRED_VALUE, heap, &val_string, sizeof(val_string), NULL );
1839 ok( hr == S_OK, "got %08x\n", hr );
1840 ok( val_string.length == 6, "got %u\n", val_string.length );
1841 ok( !memcmp( val_string.chars, test2W, sizeof(test2W) ), "wrong data\n" );
1843 val_string.length = 0xdeadbeef;
1844 val_string.chars = (WCHAR *)0xdeadbeef;
1845 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1846 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRING_TYPE, NULL,
1847 WS_READ_REQUIRED_VALUE, heap, &val_string, sizeof(val_string), NULL );
1848 ok( hr == S_OK, "got %08x\n", hr );
1849 ok( !val_string.length, "got %u\n", val_string.length );
1850 todo_wine ok( val_string.chars != NULL, "got %p\n", val_string.chars );
1852 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRING_TYPE, NULL,
1853 WS_READ_REQUIRED_POINTER, heap, &ptr_string, sizeof(ptr_string), NULL );
1854 ok( hr == S_OK, "got %08x\n", hr );
1855 ok( !ptr_string->length, "got %u\n", ptr_string->length );
1856 todo_wine ok( ptr_string->chars != NULL, "got %p\n", ptr_string->chars );
1858 memset( &val_id, 0, sizeof(val_id) );
1859 val_id.guid.Data1 = 0xdeadbeef;
1860 prepare_type_test( reader, "<t> test </t>", sizeof("<t> test </t>") - 1 );
1861 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL,
1862 WS_READ_REQUIRED_VALUE, heap, &val_id, sizeof(val_id), NULL );
1863 ok( hr == S_OK, "got %08x\n", hr );
1864 ok( val_id.uri.length == 6, "got %u\n", val_string.length );
1865 ok( !memcmp( val_id.uri.chars, test2W, sizeof(test2W) ), "wrong data\n" );
1866 ok( IsEqualGUID( &val_id.guid, &guid_null ), "wrong guid\n" );
1868 memset( &val_id, 0, sizeof(val_id) );
1869 prepare_type_test( reader, "<t>urn:uuid:00000000-0000-0000-0000-0000000000a1</t>",
1870 sizeof("<t>urn:uuid:00000000-0000-0000-0000-0000000000a1</t>") - 1 );
1871 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL,
1872 WS_READ_REQUIRED_VALUE, heap, &val_id, sizeof(val_id), NULL );
1873 ok( hr == S_OK, "got %08x\n", hr );
1874 ok( !val_id.uri.length, "got %u\n", val_string.length );
1875 ok( val_id.uri.chars == NULL, "chars set %s\n", wine_dbgstr_wn(val_id.uri.chars, val_id.uri.length) );
1876 ok( IsEqualGUID( &val_id.guid, &guid ), "wrong guid\n" );
1878 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1879 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL,
1880 WS_READ_REQUIRED_VALUE, heap, &val_id, sizeof(val_id), NULL );
1881 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1883 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1884 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL,
1885 WS_READ_REQUIRED_POINTER, heap, &ptr_id, sizeof(ptr_id), NULL );
1886 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1888 memset( &val_qname, 0, sizeof(val_qname) );
1889 hr = set_input( reader, "<t>u</t>", sizeof("<t>u</t>") - 1 );
1890 ok( hr == S_OK, "got %08x\n", hr );
1891 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1892 ok( hr == S_OK, "got %08x\n", hr );
1893 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_XML_QNAME_TYPE, NULL,
1894 WS_READ_REQUIRED_VALUE, heap, &val_qname, sizeof(val_qname), NULL );
1895 ok( hr == S_OK, "got %08x\n", hr );
1896 ok( val_qname.localName.length == 1, "got %u\n", val_qname.localName.length );
1897 ok( val_qname.localName.bytes[0] == 'u', "wrong data\n" );
1898 ok( !val_qname.ns.length, "got %u\n", val_qname.ns.length );
1899 ok( val_qname.ns.bytes != NULL, "bytes not set\n" );
1901 memset( &val_qname, 0, sizeof(val_qname) );
1902 hr = set_input( reader, "<p:t xmlns:p=\"ns\"> p:u </p:t>", sizeof("<p:t xmlns:p=\"ns\"> p:u </p:t>") - 1 );
1903 ok( hr == S_OK, "got %08x\n", hr );
1904 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1905 ok( hr == S_OK, "got %08x\n", hr );
1906 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_XML_QNAME_TYPE, NULL,
1907 WS_READ_REQUIRED_VALUE, heap, &val_qname, sizeof(val_qname), NULL );
1908 ok( hr == S_OK, "got %08x\n", hr );
1909 ok( val_qname.localName.length == 1, "got %u\n", val_qname.localName.length );
1910 ok( val_qname.localName.bytes[0] == 'u', "wrong data\n" );
1911 ok( val_qname.ns.length == 2, "got %u\n", val_qname.ns.length );
1912 ok( !memcmp( val_qname.ns.bytes, "ns", 2 ), "wrong data\n" );
1914 hr = set_input( reader, "<t></t>", sizeof("<t></t>") - 1 );
1915 ok( hr == S_OK, "got %08x\n", hr );
1916 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1917 ok( hr == S_OK, "got %08x\n", hr );
1918 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_XML_QNAME_TYPE, NULL,
1919 WS_READ_REQUIRED_VALUE, heap, &val_qname, sizeof(val_qname), NULL );
1920 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1922 hr = set_input( reader, "<t></t>", sizeof("<t></t>") - 1 );
1923 ok( hr == S_OK, "got %08x\n", hr );
1924 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1925 ok( hr == S_OK, "got %08x\n", hr );
1926 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_XML_QNAME_TYPE, NULL,
1927 WS_READ_REQUIRED_POINTER, heap, &ptr_qname, sizeof(ptr_qname), NULL );
1928 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1930 WsFreeReader( reader );
1931 WsFreeHeap( heap );
1934 static void test_WsGetXmlAttribute(void)
1936 static const WCHAR valueW[] = {'v','a','l','u','e',0};
1937 HRESULT hr;
1938 WS_XML_READER *reader;
1939 WS_XML_STRING xmlstr;
1940 WS_HEAP *heap;
1941 WCHAR *str;
1942 ULONG count;
1943 int found;
1945 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1946 ok( hr == S_OK, "got %08x\n", hr );
1948 hr = WsCreateReader( NULL, 0, &reader, NULL );
1949 ok( hr == S_OK, "got %08x\n", hr );
1951 hr = set_input( reader, data9, sizeof(data9) - 1 );
1952 ok( hr == S_OK, "got %08x\n", hr );
1954 hr = WsFillReader( reader, sizeof(data9) - 1, NULL, NULL );
1955 ok( hr == S_OK, "got %08x\n", hr );
1957 found = -1;
1958 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1959 ok( hr == S_OK, "got %08x\n", hr );
1960 ok( found == TRUE, "got %d\n", found );
1962 xmlstr.bytes = (BYTE *)"attr";
1963 xmlstr.length = sizeof("attr") - 1;
1964 xmlstr.dictionary = NULL;
1965 xmlstr.id = 0;
1966 str = NULL;
1967 count = 0;
1968 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1969 todo_wine ok( hr == S_OK, "got %08x\n", hr );
1970 todo_wine ok( str != NULL, "str not set\n" );
1971 todo_wine ok( count == 5, "got %u\n", count );
1972 /* string is not null-terminated */
1973 if (str) ok( !memcmp( str, valueW, count * sizeof(WCHAR) ), "wrong data\n" );
1975 xmlstr.bytes = (BYTE *)"none";
1976 xmlstr.length = sizeof("none") - 1;
1977 xmlstr.dictionary = NULL;
1978 xmlstr.id = 0;
1979 str = (WCHAR *)0xdeadbeef;
1980 count = 0xdeadbeef;
1981 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1982 todo_wine ok( hr == S_FALSE, "got %08x\n", hr );
1983 todo_wine ok( str == NULL, "str not set\n" );
1984 todo_wine ok( !count, "got %u\n", count );
1986 WsFreeReader( reader );
1987 WsFreeHeap( heap );
1990 static void test_WsXmlStringEquals(void)
1992 BYTE bom[] = {0xef,0xbb,0xbf};
1993 WS_XML_STRING str1 = {0, NULL}, str2 = {0, NULL};
1994 HRESULT hr;
1996 hr = WsXmlStringEquals( NULL, NULL, NULL );
1997 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1999 hr = WsXmlStringEquals( &str1, NULL, NULL );
2000 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2002 hr = WsXmlStringEquals( NULL, &str2, NULL );
2003 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2005 hr = WsXmlStringEquals( &str1, &str2, NULL );
2006 ok( hr == S_OK, "got %08x\n", hr );
2008 str1.length = 1;
2009 str1.bytes = (BYTE *)"a";
2010 hr = WsXmlStringEquals( &str1, &str1, NULL );
2011 ok( hr == S_OK, "got %08x\n", hr );
2013 str2.length = 1;
2014 str2.bytes = (BYTE *)"b";
2015 hr = WsXmlStringEquals( &str1, &str2, NULL );
2016 ok( hr == S_FALSE, "got %08x\n", hr );
2018 str2.length = 1;
2019 str2.bytes = bom;
2020 hr = WsXmlStringEquals( &str1, &str2, NULL );
2021 ok( hr == S_FALSE, "got %08x\n", hr );
2023 str1.length = 3;
2024 hr = WsXmlStringEquals( &str1, &str2, NULL );
2025 ok( hr == S_FALSE, "got %08x\n", hr );
2027 str2.length = 3;
2028 hr = WsXmlStringEquals( &str1, &str2, NULL );
2029 ok( hr == S_FALSE, "got %08x\n", hr );
2031 str1.length = 3;
2032 str1.bytes = bom;
2033 hr = WsXmlStringEquals( &str1, &str2, NULL );
2034 ok( hr == S_OK, "got %08x\n", hr );
2037 static void test_WsAlloc(void)
2039 HRESULT hr;
2040 WS_HEAP *heap;
2041 void *ptr;
2042 SIZE_T requested, actual;
2043 ULONG size;
2045 hr = WsCreateHeap( 256, 0, NULL, 0, &heap, NULL );
2046 ok( hr == S_OK, "got %08x\n", hr );
2048 ptr = (void *)0xdeadbeef;
2049 hr = WsAlloc( NULL, 16, &ptr, NULL );
2050 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2051 ok( ptr == (void *)0xdeadbeef, "ptr set\n" );
2053 ptr = (void *)0xdeadbeef;
2054 hr = WsAlloc( heap, 512, &ptr, NULL );
2055 ok( hr == WS_E_QUOTA_EXCEEDED, "got %08x\n", hr );
2056 ok( ptr == (void *)0xdeadbeef, "ptr set\n" );
2058 ptr = NULL;
2059 hr = WsAlloc( heap, 16, &ptr, NULL );
2060 ok( hr == S_OK, "got %08x\n", hr );
2061 ok( ptr != NULL, "ptr not set\n" );
2063 requested = 0xdeadbeef;
2064 size = sizeof(requested);
2065 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
2066 ok( hr == S_OK, "got %08x\n", hr );
2067 ok( requested == 16, "got %u\n", (ULONG)requested );
2069 actual = 0xdeadbeef;
2070 size = sizeof(actual);
2071 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
2072 ok( hr == S_OK, "got %08x\n", hr );
2073 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
2075 WsFreeHeap( heap );
2078 static void test_WsMoveReader(void)
2080 HRESULT hr;
2081 WS_HEAP *heap;
2082 WS_XML_READER *reader;
2083 WS_XML_WRITER *writer;
2084 WS_XML_BUFFER *buffer;
2085 WS_XML_STRING localname = {1, (BYTE *)"a"}, localname2 = {1, (BYTE *)"b"}, ns = {0, NULL};
2086 const WS_XML_NODE *node;
2087 WS_XML_ELEMENT_NODE *elem;
2088 WS_XML_UTF8_TEXT utf8;
2090 hr = WsCreateReader( NULL, 0, &reader, NULL );
2091 ok( hr == S_OK, "got %08x\n", hr );
2093 hr = WsMoveReader( NULL, WS_MOVE_TO_EOF, NULL, NULL );
2094 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2096 /* reader must be set to an XML buffer */
2097 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
2098 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2100 hr = set_input( reader, data8, sizeof(data8) - 1 );
2101 ok( hr == S_OK, "got %08x\n", hr );
2103 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
2104 todo_wine ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2105 WsFreeReader( reader );
2107 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2108 ok( hr == S_OK, "got %08x\n", hr );
2110 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
2111 ok( hr == S_OK, "got %08x\n", hr );
2113 hr = WsCreateWriter( NULL, 0, &writer, NULL );
2114 ok( hr == S_OK, "got %08x\n", hr );
2116 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
2117 ok( hr == S_OK, "got %08x\n", hr );
2119 /* <a><b/></a> */
2120 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
2121 ok( hr == S_OK, "got %08x\n", hr );
2123 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
2124 ok( hr == S_OK, "got %08x\n", hr );
2126 hr = WsWriteEndElement( writer, NULL );
2127 ok( hr == S_OK, "got %08x\n", hr );
2129 hr = WsWriteEndElement( writer, NULL );
2130 ok( hr == S_OK, "got %08x\n", hr );
2132 hr = WsCreateReader( NULL, 0, &reader, NULL );
2133 ok( hr == S_OK, "got %08x\n", hr );
2135 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
2136 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2138 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
2139 ok( hr == S_OK, "got %08x\n", hr );
2141 /* first element is child node of BOF node */
2142 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
2143 ok( hr == S_OK, "got %08x\n", hr );
2145 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2146 ok( hr == S_OK, "got %08x\n", hr );
2148 hr = WsGetReaderNode( reader, &node, NULL );
2149 ok( hr == S_OK, "got %08x\n", hr );
2150 elem = (WS_XML_ELEMENT_NODE *)node;
2151 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2152 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2153 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
2155 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2156 ok( hr == S_OK, "got %08x\n", hr );
2158 hr = WsGetReaderNode( reader, &node, NULL );
2159 ok( hr == S_OK, "got %08x\n", hr );
2160 elem = (WS_XML_ELEMENT_NODE *)node;
2161 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2162 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2163 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2165 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2166 ok( hr == S_OK, "got %08x\n", hr );
2168 hr = WsGetReaderNode( reader, &node, NULL );
2169 ok( hr == S_OK, "got %08x\n", hr );
2170 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2172 /* EOF node is last child of BOF node */
2173 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
2174 ok( hr == S_OK, "got %08x\n", hr );
2176 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2177 ok( hr == S_OK, "got %08x\n", hr );
2179 hr = WsGetReaderNode( reader, &node, NULL );
2180 ok( hr == S_OK, "got %08x\n", hr );
2181 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2183 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2184 ok( hr == S_OK, "got %08x\n", hr );
2186 hr = WsGetReaderNode( reader, &node, NULL );
2187 ok( hr == S_OK, "got %08x\n", hr );
2188 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2190 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2191 ok( hr == S_OK, "got %08x\n", hr );
2193 hr = WsGetReaderNode( reader, &node, NULL );
2194 ok( hr == S_OK, "got %08x\n", hr );
2195 elem = (WS_XML_ELEMENT_NODE *)node;
2196 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2197 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2198 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
2200 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_ELEMENT, NULL, NULL );
2201 ok( hr == S_OK, "got %08x\n", hr );
2203 hr = WsGetReaderNode( reader, &node, NULL );
2204 ok( hr == S_OK, "got %08x\n", hr );
2205 elem = (WS_XML_ELEMENT_NODE *)node;
2206 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2207 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2208 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2210 hr = WsMoveReader( reader, WS_MOVE_TO_END_ELEMENT, NULL, NULL );
2211 ok( hr == S_OK, "got %08x\n", hr );
2213 hr = WsGetReaderNode( reader, &node, NULL );
2214 ok( hr == S_OK, "got %08x\n", hr );
2215 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2217 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2218 ok( hr == S_OK, "got %08x\n", hr );
2220 hr = WsGetReaderNode( reader, &node, NULL );
2221 ok( hr == S_OK, "got %08x\n", hr );
2222 elem = (WS_XML_ELEMENT_NODE *)node;
2223 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2224 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2225 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2227 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2228 ok( hr == S_OK, "got %08x\n", hr );
2230 hr = WsGetReaderNode( reader, &node, NULL );
2231 ok( hr == S_OK, "got %08x\n", hr );
2232 elem = (WS_XML_ELEMENT_NODE *)node;
2233 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2234 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2235 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
2237 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2238 ok( hr == S_OK, "got %08x\n", hr );
2240 hr = WsGetReaderNode( reader, &node, NULL );
2241 ok( hr == S_OK, "got %08x\n", hr );
2242 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
2244 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2245 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2247 WsFreeWriter( writer );
2248 WsFreeHeap( heap );
2250 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2251 ok( hr == S_OK, "got %08x\n", hr );
2253 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
2254 ok( hr == S_OK, "got %08x\n", hr );
2256 hr = WsCreateWriter( NULL, 0, &writer, NULL );
2257 ok( hr == S_OK, "got %08x\n", hr );
2259 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
2260 ok( hr == S_OK, "got %08x\n", hr );
2262 /* <a><b>test</b></a> */
2263 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
2264 ok( hr == S_OK, "got %08x\n", hr );
2266 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
2267 ok( hr == S_OK, "got %08x\n", hr );
2269 utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
2270 utf8.value.bytes = (BYTE *)"test";
2271 utf8.value.length = sizeof("test") - 1;
2272 hr = WsWriteText( writer, &utf8.text, NULL );
2273 ok( hr == S_OK, "got %08x\n", hr );
2275 hr = WsWriteEndElement( writer, NULL );
2276 ok( hr == S_OK, "got %08x\n", hr );
2278 hr = WsWriteEndElement( writer, NULL );
2279 ok( hr == S_OK, "got %08x\n", hr );
2281 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
2282 ok( hr == S_OK, "got %08x\n", hr );
2284 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, 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_ELEMENT, "got %u\n", node->nodeType );
2291 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2292 ok( hr == S_OK, "got %08x\n", hr );
2294 hr = WsGetReaderNode( reader, &node, NULL );
2295 ok( hr == S_OK, "got %08x\n", hr );
2296 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2298 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2299 ok( hr == S_OK, "got %08x\n", hr );
2301 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2302 ok( hr == S_OK, "got %08x\n", hr );
2304 hr = WsGetReaderNode( reader, &node, NULL );
2305 ok( hr == S_OK, "got %08x\n", hr );
2306 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2308 hr = WsGetReaderNode( reader, &node, NULL );
2309 ok( hr == S_OK, "got %08x\n", hr );
2310 elem = (WS_XML_ELEMENT_NODE *)node;
2311 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2312 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2313 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2315 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2316 ok( hr == S_OK, "got %08x\n", hr );
2318 hr = WsGetReaderNode( reader, &node, NULL );
2319 ok( hr == S_OK, "got %08x\n", hr );
2320 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2322 WsFreeReader( reader );
2323 WsFreeWriter( writer );
2324 WsFreeHeap( heap );
2327 static void prepare_struct_type_test( WS_XML_READER *reader, const char *data )
2329 HRESULT hr;
2330 ULONG size = strlen( data );
2332 hr = set_input( reader, data, size );
2333 ok( hr == S_OK, "got %08x\n", hr );
2336 static void test_simple_struct_type(void)
2338 static const WCHAR testW[] = {'t','e','s','t',0};
2339 HRESULT hr;
2340 WS_XML_READER *reader;
2341 WS_HEAP *heap;
2342 WS_STRUCT_DESCRIPTION s;
2343 WS_FIELD_DESCRIPTION f, *fields[1];
2344 WS_XML_STRING ns = {0, NULL}, localname = {3, (BYTE *)"str"};
2345 WS_XML_STRING localname2 = {4, (BYTE *)"test"};
2346 const WS_XML_NODE *node;
2347 const WS_XML_ELEMENT_NODE *elem;
2348 struct test { WCHAR *str; } *test;
2350 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2351 ok( hr == S_OK, "got %08x\n", hr );
2353 hr = WsCreateReader( NULL, 0, &reader, NULL );
2354 ok( hr == S_OK, "got %08x\n", hr );
2356 prepare_struct_type_test( reader, "<str>test</str>" );
2357 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL,
2358 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2359 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2361 hr = WsGetReaderNode( reader, &node, NULL );
2362 ok( hr == S_OK, "got %08x\n", hr );
2363 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
2365 /* element field mapping */
2366 memset( &f, 0, sizeof(f) );
2367 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2368 f.localName = &localname;
2369 f.ns = &ns;
2370 f.type = WS_WSZ_TYPE;
2371 fields[0] = &f;
2373 memset( &s, 0, sizeof(s) );
2374 s.size = sizeof(struct test);
2375 s.alignment = TYPE_ALIGNMENT(struct test);
2376 s.fields = fields;
2377 s.fieldCount = 1;
2378 s.typeLocalName = &localname2;
2379 s.typeNs = &ns;
2381 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2382 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2383 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2384 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2386 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2387 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2388 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2389 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2391 s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
2392 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2393 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2394 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2395 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2396 s.structOptions = 0;
2398 test = NULL;
2399 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str>" );
2400 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2401 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2402 ok( hr == S_OK, "got %08x\n", hr );
2403 ok( test != NULL, "test not set\n" );
2404 if (test)
2406 ok( test->str != NULL, "str not set\n" );
2407 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2410 hr = WsGetReaderNode( reader, &node, NULL );
2411 ok( hr == S_OK, "got %08x\n", hr );
2412 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2414 test = NULL;
2415 prepare_struct_type_test( reader, "<str>test</str>" );
2416 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2417 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2418 ok( hr == S_OK, "got %08x\n", hr );
2419 ok( test != NULL, "test not set\n" );
2420 if (test)
2422 ok( test->str != NULL, "str not set\n" );
2423 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2426 hr = WsGetReaderNode( reader, &node, NULL );
2427 ok( hr == S_OK, "got %08x\n", hr );
2428 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2430 test = NULL;
2431 prepare_struct_type_test( reader, "<str>test</str>" );
2432 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2433 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2434 ok( hr == S_OK, "got %08x\n", hr );
2435 ok( test != NULL, "test not set\n" );
2436 if (test)
2438 ok( test->str != NULL, "str not set\n" );
2439 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2442 hr = WsGetReaderNode( reader, &node, NULL );
2443 ok( hr == S_OK, "got %08x\n", hr );
2444 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2446 prepare_struct_type_test( reader, "<str>test</str>" );
2447 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2448 ok( hr == S_OK, "got %08x\n", hr );
2450 hr = WsGetReaderNode( reader, &node, NULL );
2451 ok( hr == S_OK, "got %08x\n", hr );
2452 elem = (const WS_XML_ELEMENT_NODE *)node;
2453 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2454 ok( elem->localName->length == 3, "got %u\n", elem->localName->length );
2455 ok( !memcmp( elem->localName->bytes, "str", 3 ), "wrong data\n" );
2457 test = NULL;
2458 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2459 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2460 ok( hr == S_OK, "got %08x\n", hr );
2461 ok( test != NULL, "test not set\n" );
2462 if (test)
2464 ok( test->str != NULL, "str not set\n" );
2465 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2468 hr = WsGetReaderNode( reader, &node, NULL );
2469 ok( hr == S_OK, "got %08x\n", hr );
2470 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2472 /* attribute field mapping */
2473 f.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2475 test = NULL;
2476 prepare_struct_type_test( reader, "<test str=\"test\"/>" );
2477 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2478 ok( hr == S_OK, "got %08x\n", hr );
2480 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2481 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2482 ok( hr == S_OK, "got %08x\n", hr );
2483 ok( test != NULL, "test not set\n" );
2484 if (test)
2486 ok( test->str != NULL, "str not set\n" );
2487 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data test %p test->str %p\n", test, test->str );
2490 hr = WsGetReaderNode( reader, &node, NULL );
2491 ok( hr == S_OK, "got %08x\n", hr );
2492 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2494 WsFreeReader( reader );
2495 WsFreeHeap( heap );
2498 static void test_cdata(void)
2500 static const char test[] = "<t><![CDATA[<data>]]></t>";
2501 HRESULT hr;
2502 WS_XML_READER *reader;
2503 const WS_XML_NODE *node;
2505 hr = WsCreateReader( NULL, 0, &reader, NULL );
2506 ok( hr == S_OK, "got %08x\n", hr );
2508 hr = set_input( reader, test, sizeof(test) - 1 );
2509 ok( hr == S_OK, "got %08x\n", hr );
2511 hr = WsFillReader( reader, sizeof(test) - 1, NULL, NULL );
2512 ok( hr == S_OK, "got %08x\n", hr );
2514 hr = WsReadNode( reader, NULL );
2515 ok( hr == S_OK, "got %08x\n", hr );
2517 hr = WsGetReaderNode( reader, &node, NULL );
2518 ok( hr == S_OK, "got %08x\n", hr );
2519 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2521 hr = WsReadNode( reader, NULL );
2522 ok( hr == S_OK, "got %08x\n", hr );
2524 hr = WsGetReaderNode( reader, &node, NULL );
2525 ok( hr == S_OK, "got %08x\n", hr );
2526 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_CDATA, "got %u\n", node->nodeType );
2528 hr = WsReadNode( reader, NULL );
2529 ok( hr == S_OK, "got %08x\n", hr );
2531 hr = WsGetReaderNode( reader, &node, NULL );
2532 ok( hr == S_OK, "got %08x\n", hr );
2533 if (node)
2535 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
2536 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
2537 ok( text->text != NULL, "text not set\n" );
2538 if (text->text)
2540 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
2541 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
2542 ok( utf8->value.length == 6, "got %u\n", utf8->value.length );
2543 ok( !memcmp( utf8->value.bytes, "<data>", 6 ), "wrong data\n" );
2547 hr = WsReadNode( reader, NULL );
2548 ok( hr == S_OK, "got %08x\n", hr );
2550 hr = WsGetReaderNode( reader, &node, NULL );
2551 ok( hr == S_OK, "got %08x\n", hr );
2552 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_CDATA, "got %u\n", node->nodeType );
2554 hr = WsReadNode( reader, NULL );
2555 ok( hr == S_OK, "got %08x\n", hr );
2557 hr = WsGetReaderNode( reader, &node, NULL );
2558 ok( hr == S_OK, "got %08x\n", hr );
2559 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2561 WsFreeReader( reader );
2564 static void test_WsFindAttribute(void)
2566 static const char test[] = "<t attr='value' attr2='value2'></t>";
2567 WS_XML_STRING ns = {0, NULL}, localname = {4, (BYTE *)"attr"};
2568 WS_XML_STRING localname2 = {5, (BYTE *)"attr2"}, localname3 = {5, (BYTE *)"attr3"};
2569 WS_XML_READER *reader;
2570 ULONG index;
2571 HRESULT hr;
2573 hr = WsCreateReader( NULL, 0, &reader, NULL );
2574 ok( hr == S_OK, "got %08x\n", hr );
2576 hr = set_input( reader, test, sizeof(test) - 1 );
2577 ok( hr == S_OK, "got %08x\n", hr );
2579 hr = WsReadNode( reader, NULL );
2580 ok( hr == S_OK, "got %08x\n", hr );
2582 hr = WsFindAttribute( reader, &localname, &ns, TRUE, NULL, NULL );
2583 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2585 hr = set_input( reader, test, sizeof(test) - 1 );
2586 ok( hr == S_OK, "got %08x\n", hr );
2588 hr = WsReadNode( reader, NULL );
2589 ok( hr == S_OK, "got %08x\n", hr );
2591 hr = WsFindAttribute( reader, &localname, NULL, TRUE, &index, NULL );
2592 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2594 hr = set_input( reader, test, sizeof(test) - 1 );
2595 ok( hr == S_OK, "got %08x\n", hr );
2597 hr = WsReadNode( reader, NULL );
2598 ok( hr == S_OK, "got %08x\n", hr );
2600 hr = WsFindAttribute( reader, NULL, &ns, TRUE, &index, NULL );
2601 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2603 hr = set_input( reader, test, sizeof(test) - 1 );
2604 ok( hr == S_OK, "got %08x\n", hr );
2606 hr = WsReadNode( reader, NULL );
2607 ok( hr == S_OK, "got %08x\n", hr );
2609 index = 0xdeadbeef;
2610 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2611 ok( hr == S_OK, "got %08x\n", hr );
2612 ok( !index, "got %u\n", index );
2614 index = 0xdeadbeef;
2615 hr = WsFindAttribute( reader, &localname2, &ns, TRUE, &index, NULL );
2616 ok( hr == S_OK, "got %08x\n", hr );
2617 ok( index == 1, "got %u\n", index );
2619 hr = WsReadNode( reader, NULL );
2620 ok( hr == S_OK, "got %08x\n", hr );
2622 index = 0xdeadbeef;
2623 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2624 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2625 ok( index == 0xdeadbeef, "got %u\n", index );
2627 hr = set_input( reader, test, sizeof(test) - 1 );
2628 ok( hr == S_OK, "got %08x\n", hr );
2630 hr = WsReadNode( reader, NULL );
2631 ok( hr == S_OK, "got %08x\n", hr );
2633 index = 0xdeadbeef;
2634 hr = WsFindAttribute( reader, &localname3, &ns, TRUE, &index, NULL );
2635 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2636 ok( index == 0xdeadbeef, "got %u\n", index );
2638 hr = set_input( reader, test, sizeof(test) - 1 );
2639 ok( hr == S_OK, "got %08x\n", hr );
2641 hr = WsReadNode( reader, NULL );
2642 ok( hr == S_OK, "got %08x\n", hr );
2644 index = 0xdeadbeef;
2645 hr = WsFindAttribute( reader, &localname3, &ns, FALSE, &index, NULL );
2646 ok( hr == S_FALSE, "got %08x\n", hr );
2647 ok( index == ~0u, "got %u\n", index );
2649 WsFreeReader( reader );
2652 static void prepare_namespace_test( WS_XML_READER *reader, const char *data )
2654 HRESULT hr;
2655 ULONG size = strlen( data );
2657 hr = set_input( reader, data, size );
2658 ok( hr == S_OK, "got %08x\n", hr );
2660 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2661 ok( hr == S_OK, "got %08x\n", hr );
2664 static void test_WsGetNamespaceFromPrefix(void)
2666 WS_XML_STRING prefix = {0, NULL};
2667 const WS_XML_STRING *ns;
2668 const WS_XML_NODE *node;
2669 WS_XML_READER *reader;
2670 HRESULT hr;
2672 hr = WsCreateReader( NULL, 0, &reader, NULL );
2673 ok( hr == S_OK, "got %08x\n", hr );
2675 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, NULL, NULL );
2676 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2678 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, &ns, NULL );
2679 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2681 hr = WsGetNamespaceFromPrefix( NULL, &prefix, FALSE, &ns, NULL );
2682 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2684 ns = (const WS_XML_STRING *)0xdeadbeef;
2685 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2686 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2687 ok( ns == (const WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2689 hr = set_input( reader, "<prefix:t xmlns:prefix2='ns'/>", sizeof("<prefix:t xmlns:prefix2='ns'/>") - 1 );
2690 ok( hr == S_OK, "got %08x\n", hr );
2691 hr = WsReadStartElement( reader, NULL );
2692 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2694 prepare_namespace_test( reader, "<t></t>" );
2695 ns = NULL;
2696 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2697 ok( hr == S_OK, "got %08x\n", hr );
2698 ok( ns != NULL, "ns not set\n" );
2699 if (ns) ok( !ns->length, "got %u\n", ns->length );
2701 prepare_namespace_test( reader, "<t xmls='ns'></t>" );
2702 ns = NULL;
2703 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2704 ok( hr == S_OK, "got %08x\n", hr );
2705 ok( ns != NULL, "ns not set\n" );
2706 if (ns) ok( !ns->length, "got %u\n", ns->length );
2708 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2709 ns = NULL;
2710 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2711 ok( hr == S_OK, "got %08x\n", hr );
2712 ok( ns != NULL, "ns not set\n" );
2713 if (ns) ok( !ns->length, "got %u\n", ns->length );
2715 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2716 prefix.bytes = (BYTE *)"prefix";
2717 prefix.length = 6;
2718 ns = NULL;
2719 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2720 ok( hr == S_OK, "got %08x\n", hr );
2721 ok( ns != NULL, "ns not set\n" );
2722 if (ns)
2724 ok( ns->length == 2, "got %u\n", ns->length );
2725 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2728 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2729 ns = NULL;
2730 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2731 ok( hr == S_OK, "got %08x\n", hr );
2732 ok( ns != NULL, "ns not set\n" );
2733 if (ns)
2735 ok( ns->length == 2, "got %u\n", ns->length );
2736 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2739 hr = set_input( reader, "<t xmlns:prefix='ns'></t>", sizeof("<t xmlns:prefix='ns'></t>") - 1 );
2740 ok( hr == S_OK, "got %08x\n", hr );
2741 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2742 ok( hr == S_OK, "got %08x\n", hr );
2743 hr = WsGetReaderNode( reader, &node, NULL );
2744 ok( hr == S_OK, "got %08x\n", hr );
2745 if (node)
2747 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2748 WS_XML_ATTRIBUTE *attr;
2749 WS_XML_UTF8_TEXT *text;
2751 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2752 ok( elem->prefix != NULL, "prefix not set\n" );
2753 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2754 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2755 ok( elem->ns != NULL, "ns not set\n" );
2756 ok( !elem->ns->length, "got %u\n", elem->ns->length );
2757 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2758 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2759 ok( elem->attributes != NULL, "attributes not set\n" );
2761 attr = elem->attributes[0];
2762 ok( attr->singleQuote, "singleQuote not set\n" );
2763 ok( attr->isXmlNs, "isXmlNs not set\n" );
2764 ok( attr->prefix != NULL, "prefix not set\n" );
2765 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2766 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2767 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2768 ok( attr->localName != NULL, "localName not set\n" );
2769 ok( attr->localName->length == 6, "got %u\n", attr->localName->length );
2770 ok( !memcmp( attr->localName->bytes, "prefix", 6 ), "wrong data\n" );
2771 ok( attr->ns != NULL, "ns not set\n" );
2772 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2773 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2774 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2775 ok( attr->value != NULL, "value not set\n" );
2777 text = (WS_XML_UTF8_TEXT *)attr->value;
2778 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
2779 ok( !text->value.length, "got %u\n", text->value.length );
2780 ok( text->value.bytes == NULL, "bytes set\n" );
2783 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2784 hr = WsReadStartElement( reader, NULL );
2785 ok( hr == S_OK, "got %08x\n", hr );
2786 hr = WsReadEndElement( reader, NULL );
2787 ok( hr == S_OK, "got %08x\n", hr );
2788 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2789 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2791 prepare_namespace_test( reader, "<t></t>" );
2792 ns = NULL;
2793 prefix.bytes = (BYTE *)"xml";
2794 prefix.length = 3;
2795 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2796 ok( hr == S_OK, "got %08x\n", hr );
2797 ok( ns != NULL, "ns not set\n" );
2798 if (ns)
2800 ok( ns->length == 36, "got %u\n", ns->length );
2801 ok( !memcmp( ns->bytes, "http://www.w3.org/XML/1998/namespace", 36 ), "wrong data\n" );
2804 prepare_namespace_test( reader, "<t></t>" );
2805 ns = NULL;
2806 prefix.bytes = (BYTE *)"xmlns";
2807 prefix.length = 5;
2808 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2809 ok( hr == S_OK, "got %08x\n", hr );
2810 ok( ns != NULL, "ns not set\n" );
2811 if (ns)
2813 ok( ns->length == 29, "got %u\n", ns->length );
2814 ok( !memcmp( ns->bytes, "http://www.w3.org/2000/xmlns/", 29 ), "wrong data\n" );
2817 prepare_namespace_test( reader, "<t></t>" );
2818 ns = (WS_XML_STRING *)0xdeadbeef;
2819 prefix.bytes = (BYTE *)"prefix2";
2820 prefix.length = 7;
2821 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2822 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2823 ok( ns == (WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2825 prepare_namespace_test( reader, "<t></t>" );
2826 ns = (WS_XML_STRING *)0xdeadbeef;
2827 prefix.bytes = (BYTE *)"prefix2";
2828 prefix.length = 7;
2829 hr = WsGetNamespaceFromPrefix( reader, &prefix, FALSE, &ns, NULL );
2830 ok( hr == S_FALSE, "got %08x\n", hr );
2831 ok( ns == NULL, "ns not set\n" );
2833 hr = set_input( reader, "<t prefix:attr='' xmlns:prefix='ns'></t>", sizeof("<t prefix:attr='' xmlns:prefix='ns'></t>") - 1 );
2834 ok( hr == S_OK, "got %08x\n", hr );
2835 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2836 ok( hr == S_OK, "got %08x\n", hr );
2837 hr = WsGetReaderNode( reader, &node, NULL );
2838 ok( hr == S_OK, "got %08x\n", hr );
2839 if (node)
2841 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2842 WS_XML_ATTRIBUTE *attr;
2844 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2845 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
2846 ok( elem->attributes != NULL, "attributes not set\n" );
2848 attr = elem->attributes[0];
2849 ok( attr->singleQuote, "singleQuote not set\n" );
2850 ok( !attr->isXmlNs, "isXmlNs is set\n" );
2851 ok( attr->prefix != NULL, "prefix not set\n" );
2852 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2853 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2854 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2855 ok( attr->localName != NULL, "localName not set\n" );
2856 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
2857 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
2858 ok( attr->ns != NULL, "ns not set\n" );
2859 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2860 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2861 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2864 hr = set_input( reader, "<t xmlns:p='ns'><u xmlns:p='ns2'/></t>", sizeof("<t xmlns:p='ns'><u xmlns:p='ns2'/></t>") - 1 );
2865 ok( hr == S_OK, "got %08x\n", hr );
2866 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2867 ok( hr == S_OK, "got %08x\n", hr );
2868 hr = WsReadStartElement( reader, NULL );
2869 ok( hr == S_OK, "got %08x\n", hr );
2871 hr = set_input( reader, "<t xmlns:p='ns'><p:u p:a=''/></t>", sizeof("<t xmlns:p='ns'><p:u p:a=''/></t>") - 1 );
2872 ok( hr == S_OK, "got %08x\n", hr );
2873 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2874 ok( hr == S_OK, "got %08x\n", hr );
2875 hr = WsReadStartElement( reader, NULL );
2876 ok( hr == S_OK, "got %08x\n", hr );
2877 hr = WsGetReaderNode( reader, &node, NULL );
2878 ok( hr == S_OK, "got %08x\n", hr );
2879 if (node)
2881 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2882 WS_XML_ATTRIBUTE *attr;
2884 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2885 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2886 ok( elem->attributes != NULL, "attributes not set\n" );
2888 attr = elem->attributes[0];
2889 ok( attr->prefix != NULL, "prefix not set\n" );
2890 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
2891 ok( attr->prefix->bytes != NULL, "bytes set\n" );
2892 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong data\n" );
2893 ok( attr->localName != NULL, "localName not set\n" );
2894 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
2895 ok( !memcmp( attr->localName->bytes, "a", 1 ), "wrong data\n" );
2896 ok( attr->ns != NULL, "ns not set\n" );
2897 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2898 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2899 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2902 hr = set_input( reader, "<t xmlns='ns'></t>", sizeof("<t xmlns='ns'></t>") - 1 );
2903 ok( hr == S_OK, "got %08x\n", hr );
2904 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2905 ok( hr == S_OK, "got %08x\n", hr );
2906 hr = WsGetReaderNode( reader, &node, NULL );
2907 ok( hr == S_OK, "got %08x\n", hr );
2908 if (node)
2910 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2911 WS_XML_ATTRIBUTE *attr;
2913 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2914 ok( elem->prefix != NULL, "prefix not set\n" );
2915 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2916 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2917 ok( elem->ns != NULL, "ns not set\n" );
2918 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
2919 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2920 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong data\n" );
2922 attr = elem->attributes[0];
2923 ok( attr->isXmlNs, "isXmlNs is not set\n" );
2924 ok( attr->prefix != NULL, "prefix not set\n" );
2925 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
2926 ok( attr->prefix->bytes == NULL, "bytes set\n" );
2927 ok( attr->localName != NULL, "localName not set\n" );
2928 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
2929 ok( !memcmp( attr->localName->bytes, "xmlns", 5 ), "wrong data\n" );
2930 ok( attr->ns != NULL, "ns not set\n" );
2931 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2932 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2933 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2936 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns2'></t>") - 1 );
2937 ok( hr == S_OK, "got %08x\n", hr );
2938 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2939 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2941 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns'></t>") - 1 );
2942 ok( hr == S_OK, "got %08x\n", hr );
2943 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2944 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2946 hr = set_input( reader, "<t xmlns:p='ns' xmlns:P='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:P='ns2'></t>") - 1 );
2947 ok( hr == S_OK, "got %08x\n", hr );
2948 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2949 ok( hr == S_OK, "got %08x\n", hr );
2951 WsFreeReader( reader );
2954 static void test_text_field_mapping(void)
2956 static const WCHAR testW[] = {'t','e','s','t',0};
2957 HRESULT hr;
2958 WS_XML_READER *reader;
2959 WS_HEAP *heap;
2960 WS_STRUCT_DESCRIPTION s;
2961 WS_FIELD_DESCRIPTION f, *fields[1];
2962 struct test
2964 WCHAR *str;
2965 } *test;
2967 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2968 ok( hr == S_OK, "got %08x\n", hr );
2970 hr = WsCreateReader( NULL, 0, &reader, NULL );
2971 ok( hr == S_OK, "got %08x\n", hr );
2973 prepare_struct_type_test( reader, "<a>test</a>" );
2975 memset( &f, 0, sizeof(f) );
2976 f.mapping = WS_TEXT_FIELD_MAPPING;
2977 f.type = WS_WSZ_TYPE;
2978 fields[0] = &f;
2980 memset( &s, 0, sizeof(s) );
2981 s.size = sizeof(struct test);
2982 s.alignment = TYPE_ALIGNMENT(struct test);
2983 s.fields = fields;
2984 s.fieldCount = 1;
2986 test = NULL;
2987 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2988 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2989 ok( hr == S_OK, "got %08x\n", hr );
2990 ok( test != NULL, "test not set\n" );
2991 ok( test->str != NULL, "str not set\n" );
2992 ok( !lstrcmpW( test->str, testW ), "got %s\n", wine_dbgstr_w(test->str) );
2994 WsFreeReader( reader );
2995 WsFreeHeap( heap );
2998 static void test_complex_struct_type(void)
3000 static const WCHAR timestampW[] =
3001 {'2','0','1','5','-','0','9','-','0','3','T','1','8',':','4','7',':','5','4',0};
3002 HRESULT hr;
3003 WS_ERROR *error;
3004 WS_ERROR_PROPERTY prop;
3005 WS_XML_READER *reader;
3006 WS_HEAP *heap;
3007 WS_STRUCT_DESCRIPTION s, s2;
3008 WS_FIELD_DESCRIPTION f, f2, *fields[1], *fields2[1];
3009 WS_XML_STRING str_officeconfig = {12, (BYTE *)"OfficeConfig"};
3010 WS_XML_STRING str_services = {8, (BYTE *)"services"};
3011 WS_XML_STRING str_generationtime = {14, (BYTE *)"GenerationTime"};
3012 WS_XML_STRING ns = {39, (BYTE *)"urn:schemas-microsoft-com:office:office"};
3013 LANGID langid = MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT );
3014 const WS_XML_NODE *node;
3015 const WS_XML_ELEMENT_NODE *elem;
3016 struct services
3018 WCHAR *generationtime;
3020 struct officeconfig
3022 struct services *services;
3023 } *test;
3025 prop.id = WS_ERROR_PROPERTY_LANGID;
3026 prop.value = &langid;
3027 prop.valueSize = sizeof(langid);
3028 hr = WsCreateError( &prop, 1, &error );
3029 ok( hr == S_OK, "got %08x\n", hr );
3031 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3032 ok( hr == S_OK, "got %08x\n", hr );
3034 hr = WsCreateReader( NULL, 0, &reader, NULL );
3035 ok( hr == S_OK, "got %08x\n", hr );
3037 /* element content type mapping */
3038 prepare_struct_type_test( reader, data11 );
3040 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3041 ok( hr == S_OK, "got %08x\n", hr );
3043 hr = WsGetReaderNode( reader, &node, NULL );
3044 ok( hr == S_OK, "got %08x\n", hr );
3045 elem = (const WS_XML_ELEMENT_NODE *)node;
3046 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
3047 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
3048 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
3050 hr = WsReadStartElement( reader, NULL );
3051 ok( hr == S_OK, "got %08x\n", hr );
3053 hr = WsGetReaderNode( reader, &node, NULL );
3054 ok( hr == S_OK, "got %08x\n", hr );
3055 elem = (const WS_XML_ELEMENT_NODE *)node;
3056 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
3057 ok( elem->localName->length == 8, "got %u\n", elem->localName->length );
3058 ok( !memcmp( elem->localName->bytes, "services", 8 ), "wrong data\n" );
3060 memset( &f2, 0, sizeof(f2) );
3061 f2.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
3062 f2.localName = &str_generationtime;
3063 f2.ns = &ns;
3064 f2.type = WS_WSZ_TYPE;
3065 f2.options = WS_FIELD_OPTIONAL;
3066 fields2[0] = &f2;
3068 memset( &s2, 0, sizeof(s2) );
3069 s2.size = sizeof(*test->services);
3070 s2.alignment = TYPE_ALIGNMENT(struct services);
3071 s2.fields = fields2;
3072 s2.fieldCount = 1;
3073 s2.typeLocalName = &str_services;
3074 s2.typeNs = &ns;
3076 memset( &f, 0, sizeof(f) );
3077 f.mapping = WS_ELEMENT_FIELD_MAPPING;
3078 f.localName = &str_services;
3079 f.ns = &ns;
3080 f.type = WS_STRUCT_TYPE;
3081 f.typeDescription = &s2;
3082 f.options = WS_FIELD_POINTER;
3083 fields[0] = &f;
3085 memset( &s, 0, sizeof(s) );
3086 s.size = sizeof(*test);
3087 s.alignment = TYPE_ALIGNMENT(struct officeconfig);
3088 s.fields = fields;
3089 s.fieldCount = 1;
3090 s.typeLocalName = &str_officeconfig;
3091 s.typeNs = &ns;
3093 test = NULL;
3094 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3095 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
3096 ok( hr == S_OK, "got %08x\n", hr );
3097 ok( test != NULL, "test not set\n" );
3098 ok( !lstrcmpW( test->services->generationtime, timestampW ), "wrong data\n" );
3100 hr = WsGetReaderNode( reader, &node, NULL );
3101 ok( hr == S_OK, "got %08x\n", hr );
3102 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
3104 hr = WsReadEndElement( reader, NULL );
3105 ok( hr == S_OK, "got %08x\n", hr );
3107 hr = WsGetReaderNode( reader, &node, NULL );
3108 ok( hr == S_OK, "got %08x\n", hr );
3109 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
3111 hr = WsReadEndElement( reader, NULL );
3112 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3114 /* element type mapping */
3115 prepare_struct_type_test( reader, data11 );
3117 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3118 ok( hr == S_OK, "got %08x\n", hr );
3120 hr = WsGetReaderNode( reader, &node, NULL );
3121 ok( hr == S_OK, "got %08x\n", hr );
3122 elem = (const WS_XML_ELEMENT_NODE *)node;
3123 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
3124 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
3125 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
3127 test = NULL;
3128 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3129 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
3130 ok( hr == S_OK, "got %08x\n", hr );
3131 ok( test != NULL, "test not set\n" );
3132 if (test) ok( !lstrcmpW( test->services->generationtime, timestampW ), "wrong data\n" );
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 /* trailing content */
3139 prepare_struct_type_test( reader, data11b );
3140 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3141 ok( hr == S_OK, "got %08x\n", hr );
3143 s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
3144 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3145 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
3146 ok( hr == S_OK, "got %08x\n", hr );
3148 hr = WsGetReaderNode( reader, &node, NULL );
3149 ok( hr == S_OK, "got %08x\n", hr );
3150 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
3152 prepare_struct_type_test( reader, data11b );
3153 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3154 ok( hr == S_OK, "got %08x\n", hr );
3156 s.structOptions = 0;
3157 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3158 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
3159 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3161 WsFreeReader( reader );
3162 WsFreeHeap( heap );
3163 WsFreeError( error );
3166 static void test_repeating_element(void)
3168 static const WCHAR oneW[] = {'1',0}, twoW[] = {'2',0};
3169 WS_XML_STRING str_name = {4, (BYTE *)"name"};
3170 WS_XML_STRING str_services = {8, (BYTE *)"services"};
3171 WS_XML_STRING str_service = {7, (BYTE *)"service"};
3172 WS_XML_STRING str_wrapper = {7, (BYTE *)"wrapper"};
3173 WS_XML_STRING str_id = {2, (BYTE *)"id"};
3174 WS_XML_STRING str_ns = {0, NULL};
3175 HRESULT hr;
3176 WS_XML_READER *reader;
3177 WS_HEAP *heap;
3178 WS_STRUCT_DESCRIPTION s, s2;
3179 WS_FIELD_DESCRIPTION f, f2, f3, *fields[1], *fields2[2];
3180 WS_ITEM_RANGE range;
3181 struct service { UINT32 id; };
3182 struct service2 { WCHAR *id; };
3183 struct service3 { WCHAR *name; WCHAR *id; };
3184 struct service4 { WS_STRING name; };
3185 struct services
3187 struct service *service;
3188 ULONG service_count;
3189 } *test;
3190 struct services2
3192 struct service2 *service;
3193 ULONG service_count;
3194 } *test2;
3195 struct services3
3197 struct service3 *service;
3198 ULONG service_count;
3199 } *test3;
3200 struct services4
3202 struct service **service;
3203 ULONG service_count;
3204 } *test4;
3205 struct services5
3207 struct service4 *service;
3208 ULONG service_count;
3209 } *test5;
3211 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3212 ok( hr == S_OK, "got %08x\n", hr );
3214 hr = WsCreateReader( NULL, 0, &reader, NULL );
3215 ok( hr == S_OK, "got %08x\n", hr );
3217 prepare_struct_type_test( reader, data12 );
3219 memset( &f2, 0, sizeof(f2) );
3220 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
3221 f2.localName = &str_id;
3222 f2.ns = &str_ns;
3223 f2.type = WS_UINT32_TYPE;
3224 fields2[0] = &f2;
3226 memset( &s2, 0, sizeof(s2) );
3227 s2.size = sizeof(struct service);
3228 s2.alignment = TYPE_ALIGNMENT(struct service);
3229 s2.fields = fields2;
3230 s2.fieldCount = 1;
3231 s2.typeLocalName = &str_service;
3233 memset( &f, 0, sizeof(f) );
3234 f.mapping = WS_REPEATING_ELEMENT_FIELD_MAPPING;
3235 f.countOffset = FIELD_OFFSET(struct services, service_count);
3236 f.type = WS_STRUCT_TYPE;
3237 f.typeDescription = &s2;
3238 f.itemLocalName = &str_service;
3239 f.itemNs = &str_ns;
3240 fields[0] = &f;
3242 memset( &s, 0, sizeof(s) );
3243 s.size = sizeof(struct services);
3244 s.alignment = TYPE_ALIGNMENT(struct services);
3245 s.fields = fields;
3246 s.fieldCount = 1;
3247 s.typeLocalName = &str_services;
3249 test = NULL;
3250 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3251 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3252 ok( hr == S_OK, "got %08x\n", hr );
3253 ok( test != NULL, "test not set\n" );
3254 ok( test->service != NULL, "service not set\n" );
3255 ok( test->service_count == 2, "got %u\n", test->service_count );
3256 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
3257 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
3259 /* array of pointers */
3260 prepare_struct_type_test( reader, data12 );
3261 f.options = WS_FIELD_POINTER;
3262 test4 = NULL;
3263 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3264 WS_READ_REQUIRED_POINTER, heap, &test4, sizeof(test4), NULL );
3265 ok( hr == S_OK || broken(hr == E_INVALIDARG) /* win7 */, "got %08x\n", hr );
3266 if (test4)
3268 ok( test4->service != NULL, "service not set\n" );
3269 ok( test4->service_count == 2, "got %u\n", test4->service_count );
3270 ok( test4->service[0]->id == 1, "got %u\n", test4->service[0]->id );
3271 ok( test4->service[1]->id == 2, "got %u\n", test4->service[1]->id );
3274 /* item range */
3275 prepare_struct_type_test( reader, data13 );
3276 f.options = 0;
3277 range.minItemCount = 0;
3278 range.maxItemCount = 1;
3279 f.itemRange = &range;
3280 test = NULL;
3281 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3282 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3283 ok( hr == S_OK, "got %08x\n", hr );
3284 ok( test != NULL, "test not set\n" );
3285 ok( test->service != NULL, "service not set\n" );
3286 ok( !test->service_count, "got %u\n", test->service_count );
3288 /* wrapper element */
3289 prepare_struct_type_test( reader, data14 );
3290 f.itemRange = NULL;
3291 f.localName = &str_wrapper;
3292 f.ns = &str_ns;
3293 test = NULL;
3294 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3295 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3296 ok( hr == S_OK, "got %08x\n", hr );
3297 ok( test != NULL, "test not set\n" );
3298 ok( test->service != NULL, "service not set\n" );
3299 ok( test->service_count == 2, "got %u\n", test->service_count );
3300 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
3301 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
3303 /* repeating text field mapping */
3304 prepare_struct_type_test( reader, data15 );
3305 f2.mapping = WS_TEXT_FIELD_MAPPING;
3306 f2.localName = NULL;
3307 f2.ns = NULL;
3308 f2.type = WS_WSZ_TYPE;
3309 s2.size = sizeof(struct service2);
3310 s2.alignment = TYPE_ALIGNMENT(struct service2);
3311 test2 = NULL;
3312 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3313 WS_READ_REQUIRED_POINTER, heap, &test2, sizeof(test2), NULL );
3314 ok( hr == S_OK, "got %08x\n", hr );
3315 ok( test2 != NULL, "test2 not set\n" );
3316 ok( test2->service != NULL, "service not set\n" );
3317 ok( test2->service_count == 2, "got %u\n", test2->service_count );
3318 ok( !lstrcmpW( test2->service[0].id, oneW ), "wrong data\n" );
3319 ok( !lstrcmpW( test2->service[1].id, twoW ), "wrong data\n" );
3321 /* repeating attribute field + text field mapping */
3322 prepare_struct_type_test( reader, data16 );
3323 f2.offset = FIELD_OFFSET(struct service3, id);
3324 memset( &f3, 0, sizeof(f3) );
3325 f3.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
3326 f3.localName = &str_name;
3327 f3.ns = &str_ns;
3328 f3.type = WS_WSZ_TYPE;
3329 fields2[0] = &f3;
3330 fields2[1] = &f2;
3331 s2.size = sizeof(struct service3);
3332 s2.alignment = TYPE_ALIGNMENT(struct service3);
3333 s2.fieldCount = 2;
3334 test3 = NULL;
3335 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3336 WS_READ_REQUIRED_POINTER, heap, &test3, sizeof(test3), NULL );
3337 ok( hr == S_OK, "got %08x\n", hr );
3338 ok( test3 != NULL, "test3 not set\n" );
3339 ok( test3->service != NULL, "service not set\n" );
3340 ok( test3->service_count == 2, "got %u\n", test3->service_count );
3341 ok( !lstrcmpW( test3->service[0].name, oneW ), "wrong data\n" );
3342 ok( !lstrcmpW( test3->service[0].id, oneW ), "wrong data\n" );
3343 ok( !lstrcmpW( test3->service[1].name, twoW ), "wrong data\n" );
3344 ok( !lstrcmpW( test3->service[1].id, twoW ), "wrong data\n" );
3346 /* empty text, item range */
3347 prepare_struct_type_test( reader, data17 );
3349 memset( &f2, 0, sizeof(f2) );
3350 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
3351 f2.localName = &str_name;
3352 f2.ns = &str_ns;
3353 f2.type = WS_STRING_TYPE;
3354 fields2[0] = &f2;
3356 memset( &s2, 0, sizeof(s2) );
3357 s2.size = sizeof(struct service4);
3358 s2.alignment = TYPE_ALIGNMENT(struct service4);
3359 s2.fields = fields2;
3360 s2.fieldCount = 1;
3361 s2.typeLocalName = &str_service;
3363 range.minItemCount = 1;
3364 range.maxItemCount = 2;
3365 memset( &f, 0, sizeof(f) );
3366 f.mapping = WS_REPEATING_ELEMENT_FIELD_MAPPING;
3367 f.countOffset = FIELD_OFFSET(struct services5, service_count);
3368 f.type = WS_STRUCT_TYPE;
3369 f.typeDescription = &s2;
3370 f.itemLocalName = &str_service;
3371 f.itemNs = &str_ns;
3372 f.itemRange = &range;
3373 fields[0] = &f;
3375 memset( &s, 0, sizeof(s) );
3376 s.size = sizeof(struct services5);
3377 s.alignment = TYPE_ALIGNMENT(struct services5);
3378 s.fields = fields;
3379 s.fieldCount = 1;
3380 s.typeLocalName = &str_services;
3382 test5 = NULL;
3383 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3384 WS_READ_REQUIRED_POINTER, heap, &test5, sizeof(test5), NULL );
3385 ok( hr == S_OK, "got %08x\n", hr );
3386 ok( test5 != NULL, "test5 not set\n" );
3387 ok( test5->service != NULL, "service not set\n" );
3388 ok( test5->service_count == 1, "got %u\n", test5->service_count );
3389 ok( !test5->service[0].name.length, "got %u\n", test5->service[0].name.length );
3390 todo_wine ok( test5->service[0].name.chars != NULL, "chars set\n" );
3392 WsFreeReader( reader );
3393 WsFreeHeap( heap );
3396 static void test_WsResetHeap(void)
3398 HRESULT hr;
3399 WS_HEAP *heap;
3400 SIZE_T requested, actual;
3401 ULONG size;
3402 void *ptr;
3404 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3405 ok( hr == S_OK, "got %08x\n", hr );
3407 requested = 0xdeadbeef;
3408 size = sizeof(requested);
3409 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3410 ok( hr == S_OK, "got %08x\n", hr );
3411 ok( !requested, "got %u\n", (ULONG)requested );
3413 actual = 0xdeadbeef;
3414 size = sizeof(actual);
3415 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3416 ok( hr == S_OK, "got %08x\n", hr );
3417 ok( !actual, "got %u\n", (ULONG)actual );
3419 hr = WsAlloc( heap, 128, &ptr, NULL );
3420 ok( hr == S_OK, "got %08x\n", hr );
3422 requested = 0xdeadbeef;
3423 size = sizeof(requested);
3424 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3425 ok( hr == S_OK, "got %08x\n", hr );
3426 ok( requested == 128, "got %u\n", (ULONG)requested );
3428 actual = 0xdeadbeef;
3429 size = sizeof(actual);
3430 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3431 ok( hr == S_OK, "got %08x\n", hr );
3432 ok( actual == 128, "got %u\n", (ULONG)actual );
3434 hr = WsAlloc( heap, 1, &ptr, NULL );
3435 ok( hr == S_OK, "got %08x\n", hr );
3437 requested = 0xdeadbeef;
3438 size = sizeof(requested);
3439 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3440 ok( hr == S_OK, "got %08x\n", hr );
3441 ok( requested == 129, "got %u\n", (ULONG)requested );
3443 actual = 0xdeadbeef;
3444 size = sizeof(actual);
3445 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3446 ok( hr == S_OK, "got %08x\n", hr );
3447 todo_wine ok( actual == 384, "got %u\n", (ULONG)actual );
3449 hr = WsResetHeap( NULL, NULL );
3450 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3452 hr = WsResetHeap( heap, NULL );
3453 ok( hr == S_OK, "got %08x\n", hr );
3455 requested = 0xdeadbeef;
3456 size = sizeof(requested);
3457 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3458 ok( hr == S_OK, "got %08x\n", hr );
3459 ok( !requested, "got %u\n", (ULONG)requested );
3461 actual = 0xdeadbeef;
3462 size = sizeof(actual);
3463 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3464 ok( hr == S_OK, "got %08x\n", hr );
3465 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
3467 WsFreeHeap( heap );
3470 static void test_datetime(void)
3472 static const struct
3474 const char *str;
3475 HRESULT hr;
3476 __int64 ticks;
3477 WS_DATETIME_FORMAT format;
3479 tests[] =
3481 {"<t>0000-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3482 {"<t>0001-01-01T00:00:00Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3483 {"<t>0001-01-01T00:00:00.Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3484 {"<t>0001-01-01T00:00:00.0Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3485 {"<t>0001-01-01T00:00:00.1Z</t>", S_OK, 0x0000f4240, WS_DATETIME_FORMAT_UTC},
3486 {"<t>0001-01-01T00:00:00.01Z</t>", S_OK, 0x0000186a0, WS_DATETIME_FORMAT_UTC},
3487 {"<t>0001-01-01T00:00:00.0000001Z</t>", S_OK, 1, WS_DATETIME_FORMAT_UTC},
3488 {"<t>0001-01-01T00:00:00.9999999Z</t>", S_OK, 0x00098967f, WS_DATETIME_FORMAT_UTC},
3489 {"<t>0001-01-01T00:00:00.0000000Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3490 {"<t>0001-01-01T00:00:00.00000001Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3491 {"<t>0001-01-01T00:00:00Z-</t>", WS_E_INVALID_FORMAT, 0},
3492 {"<t>-0001-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3493 {"<t>0001-00-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3494 {"<t>0001-13-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3495 {"<t>0001-12-01T00:00:00Z</t>", S_OK, 0x1067555f88000, WS_DATETIME_FORMAT_UTC},
3496 {"<t>0001-01-00T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3497 {"<t>2001-01-32T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3498 {"<t>2001-01-31T00:00:00Z</t>", S_OK, 0x8c2592fe3794000, WS_DATETIME_FORMAT_UTC},
3499 {"<t>1900-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3500 {"<t>2000-02-29T00:00:00Z</t>", S_OK, 0x8c1505f0e438000, 0},
3501 {"<t>2001-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3502 {"<t>2001-02-28T00:00:00Z</t>", S_OK, 0x8c26f30870a4000, WS_DATETIME_FORMAT_UTC},
3503 {"<t>0001-00-01U00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3504 {"<t>0001-01-01T24:00:00Z</t>", S_OK, 0xc92a69c000, WS_DATETIME_FORMAT_UTC},
3505 {"<t>0001-01-01T24:00:01Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3506 {"<t>0001-01-01T00:60:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3507 {"<t>0001-01-01T00:00:60Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3508 {"<t>0001-01-01T00:00:00Y</t>", WS_E_INVALID_FORMAT, 0, 0},
3509 {"<t>0001-01-01T00:00:00+00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3510 {"<t>0001-01-01T00:00:00-00:01</t>", S_OK, 0x023c34600, WS_DATETIME_FORMAT_LOCAL},
3511 {"<t>9999-12-31T24:00:00+00:01</t>", S_OK, 0x2bca2875d073fa00, WS_DATETIME_FORMAT_LOCAL},
3512 {"<t>9999-12-31T24:00:00-00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3513 {"<t>0002-01-01T00:00:00+14:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3514 {"<t>0002-01-01T00:00:00+15:00</t>", WS_E_INVALID_FORMAT, 0, 0},
3515 {"<t>0002-01-01T00:00:00+13:60</t>", WS_E_INVALID_FORMAT, 0, 0},
3516 {"<t>0002-01-01T00:00:00+13:59</t>", S_OK, 0x11e5c43cc5600, WS_DATETIME_FORMAT_LOCAL},
3517 {"<t>0002-01-01T00:00:00+01:00</t>", S_OK, 0x11ec917025800, WS_DATETIME_FORMAT_LOCAL},
3518 {"<t>2016-01-01T00:00:00-01:00</t>", S_OK, 0x8d31246dfbba800, WS_DATETIME_FORMAT_LOCAL},
3519 {"<t>2016-01-01T00:00:00Z</t>", S_OK, 0x8d3123e7df74000, WS_DATETIME_FORMAT_UTC},
3520 {"<t> 2016-01-02T03:04:05Z </t>", S_OK, 0x8d313215fb64080, WS_DATETIME_FORMAT_UTC},
3521 {"<t>+2016-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3522 {"<t></t>", WS_E_INVALID_FORMAT, 0, 0},
3523 {"<t>01-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3524 {"<t>1601-01-01T00:00:00Z</t>", S_OK, 0x701ce1722770000, WS_DATETIME_FORMAT_UTC},
3526 HRESULT hr;
3527 WS_XML_READER *reader;
3528 WS_HEAP *heap;
3529 WS_DATETIME date;
3530 ULONG i;
3532 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3533 ok( hr == S_OK, "got %08x\n", hr );
3535 hr = WsCreateReader( NULL, 0, &reader, NULL );
3536 ok( hr == S_OK, "got %08x\n", hr );
3537 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3539 memset( &date, 0, sizeof(date) );
3540 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3541 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DATETIME_TYPE, NULL,
3542 WS_READ_REQUIRED_VALUE, heap, &date, sizeof(date), NULL );
3543 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3544 if (hr == S_OK)
3546 ok( date.ticks == tests[i].ticks, "%u: got %s\n", i, wine_dbgstr_longlong(date.ticks) );
3547 ok( date.format == tests[i].format, "%u: got %u\n", i, date.format );
3551 WsFreeReader( reader );
3552 WsFreeHeap( heap );
3555 static void test_WsDateTimeToFileTime(void)
3557 static const struct
3559 WS_DATETIME dt;
3560 HRESULT hr;
3561 FILETIME ft;
3563 tests[] =
3565 { {0, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3566 { {0x701ce172276ffff, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3567 { {0x701ce1722770000, WS_DATETIME_FORMAT_UTC}, S_OK, {0, 0} },
3568 { {0x2bca2875f4373fff, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c03fff, 0x24c85a5e} },
3569 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c04000, 0x24c85a5e} },
3570 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_LOCAL}, S_OK, {0xd1c04000, 0x24c85a5e} },
3571 { {~0, WS_DATETIME_FORMAT_UTC}, S_OK, {0xdd88ffff, 0xf8fe31e8} },
3573 WS_DATETIME dt;
3574 FILETIME ft;
3575 HRESULT hr;
3576 ULONG i;
3578 hr = WsDateTimeToFileTime( NULL, NULL, NULL );
3579 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3581 dt.ticks = 0x701ce172277000;
3582 dt.format = WS_DATETIME_FORMAT_UTC;
3583 hr = WsDateTimeToFileTime( &dt, NULL, NULL );
3584 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3586 hr = WsDateTimeToFileTime( NULL, &ft, NULL );
3587 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3589 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3591 memset( &ft, 0, sizeof(ft) );
3592 hr = WsDateTimeToFileTime( &tests[i].dt, &ft, NULL );
3593 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3594 if (hr == S_OK)
3596 ok( ft.dwLowDateTime == tests[i].ft.dwLowDateTime, "%u: got %08x\n", i, ft.dwLowDateTime );
3597 ok( ft.dwHighDateTime == tests[i].ft.dwHighDateTime, "%u: got %08x\n", i, ft.dwHighDateTime );
3602 static void test_WsFileTimeToDateTime(void)
3604 WS_DATETIME dt;
3605 FILETIME ft;
3606 HRESULT hr;
3608 hr = WsFileTimeToDateTime( NULL, NULL, NULL );
3609 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3611 ft.dwLowDateTime = ft.dwHighDateTime = 0;
3612 hr = WsFileTimeToDateTime( &ft, NULL, NULL );
3613 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3615 hr = WsFileTimeToDateTime( NULL, &dt, NULL );
3616 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3618 dt.ticks = 0xdeadbeef;
3619 dt.format = 0xdeadbeef;
3620 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3621 ok( hr == S_OK, "got %08x\n", hr );
3622 ok( dt.ticks == 0x701ce1722770000, "got %s\n", wine_dbgstr_longlong(dt.ticks) );
3623 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3625 ft.dwLowDateTime = 0xd1c03fff;
3626 ft.dwHighDateTime = 0x24c85a5e;
3627 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3628 ok( hr == S_OK, "got %08x\n", hr );
3629 ok( dt.ticks == 0x2bca2875f4373fff, "got %s\n", wine_dbgstr_longlong(dt.ticks) );
3630 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3632 ft.dwLowDateTime++;
3633 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3634 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3636 ft.dwLowDateTime = 0xdd88ffff;
3637 ft.dwHighDateTime = 0xf8fe31e8;
3638 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3639 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3641 ft.dwLowDateTime++;
3642 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3643 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
3646 static void test_double(void)
3648 static const struct
3650 const char *str;
3651 HRESULT hr;
3652 ULONGLONG val;
3654 tests[] =
3656 {"<t>0.0</t>", S_OK, 0},
3657 {"<t>-0.0</t>", S_OK, 0x8000000000000000},
3658 {"<t>+0.0</t>", S_OK, 0},
3659 {"<t>-</t>", S_OK, 0},
3660 {"<t>+</t>", S_OK, 0},
3661 {"<t>.0</t>", S_OK, 0},
3662 {"<t>0.</t>", S_OK, 0},
3663 {"<t>0</t>", S_OK, 0},
3664 {"<t> 0 </t>", S_OK, 0},
3665 {"<t></t>", WS_E_INVALID_FORMAT, 0},
3666 {"<t>0,1</t>", WS_E_INVALID_FORMAT, 0},
3667 {"<t>1.1.</t>", WS_E_INVALID_FORMAT, 0},
3668 {"<t>1</t>", S_OK, 0x3ff0000000000000},
3669 {"<t>1.0000000000000002</t>", S_OK, 0x3ff0000000000001},
3670 {"<t>1.0000000000000004</t>", S_OK, 0x3ff0000000000002},
3671 {"<t>10000000000000000000</t>", S_OK, 0x43e158e460913d00},
3672 {"<t>100000000000000000000</t>", S_OK, 0x4415af1d78b58c40},
3673 {"<t>2</t>", S_OK, 0x4000000000000000},
3674 {"<t>-2</t>", S_OK, 0xc000000000000000},
3675 {"<t>nodouble</t>", WS_E_INVALID_FORMAT, 0},
3676 {"<t>INF</t>", S_OK, 0x7ff0000000000000},
3677 {"<t>-INF</t>", S_OK, 0xfff0000000000000},
3678 {"<t>+INF</t>", WS_E_INVALID_FORMAT, 0},
3679 {"<t>Infinity</t>", WS_E_INVALID_FORMAT, 0},
3680 {"<t>-Infinity</t>", WS_E_INVALID_FORMAT, 0},
3681 {"<t>inf</t>", WS_E_INVALID_FORMAT, 0},
3682 {"<t>NaN</t>", S_OK, 0xfff8000000000000},
3683 {"<t>-NaN</t>", WS_E_INVALID_FORMAT, 0},
3684 {"<t>NAN</t>", WS_E_INVALID_FORMAT, 0},
3685 {"<t>0.3</t>", S_OK, 0x3fd3333333333333},
3686 {"<t>0.33</t>", S_OK, 0x3fd51eb851eb851f},
3687 {"<t>0.333</t>", S_OK, 0x3fd54fdf3b645a1d},
3688 {"<t>0.3333</t>", S_OK, 0x3fd554c985f06f69},
3689 {"<t>0.33333</t>", S_OK, 0x3fd555475a31a4be},
3690 {"<t>0.333333</t>", S_OK, 0x3fd55553ef6b5d46},
3691 {"<t>0.3333333</t>", S_OK, 0x3fd55555318abc87},
3692 {"<t>0.33333333</t>", S_OK, 0x3fd5555551c112da},
3693 {"<t>0.333333333</t>", S_OK, 0x3fd5555554f9b516},
3694 {"<t>0.3333333333</t>", S_OK, 0x3fd55555554c2bb5},
3695 {"<t>0.33333333333</t>", S_OK, 0x3fd5555555546ac5},
3696 {"<t>0.3333333333333</t>", S_OK, 0x3fd55555555552fd},
3697 {"<t>0.33333333333333</t>", S_OK, 0x3fd5555555555519},
3698 {"<t>0.333333333333333</t>", S_OK, 0x3fd555555555554f},
3699 {"<t>0.3333333333333333</t>", S_OK, 0x3fd5555555555555},
3700 {"<t>0.33333333333333333</t>", S_OK, 0x3fd5555555555555},
3701 {"<t>0.1e10</t>", S_OK, 0x41cdcd6500000000},
3702 {"<t>1e</t>", WS_E_INVALID_FORMAT, 0},
3703 {"<t>1e0</t>", S_OK, 0x3ff0000000000000},
3704 {"<t>1e+1</t>", S_OK, 0x4024000000000000},
3705 {"<t>1e-1</t>", S_OK, 0x3fb999999999999a},
3706 {"<t>e10</t>", WS_E_INVALID_FORMAT, 0},
3707 {"<t>1e10.</t>", WS_E_INVALID_FORMAT, 0},
3708 {"<t>1E10</t>", S_OK, 0x4202a05f20000000},
3709 {"<t>1e10</t>", S_OK, 0x4202a05f20000000},
3710 {"<t>1e-10</t>", S_OK, 0x3ddb7cdfd9d7bdbb},
3711 {"<t>1.7976931348623158e308</t>", S_OK, 0x7fefffffffffffff},
3712 {"<t>1.7976931348623159e308</t>", S_OK, 0x7ff0000000000000},
3713 {"<t>4.94065645841247e-324</t>", S_OK, 0x1},
3715 HRESULT hr;
3716 WS_XML_READER *reader;
3717 WS_HEAP *heap;
3718 ULONGLONG val;
3719 ULONG i;
3721 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3722 ok( hr == S_OK, "got %08x\n", hr );
3724 hr = WsCreateReader( NULL, 0, &reader, NULL );
3725 ok( hr == S_OK, "got %08x\n", hr );
3727 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3729 val = 0;
3730 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3731 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DOUBLE_TYPE, NULL,
3732 WS_READ_REQUIRED_VALUE, heap, &val, sizeof(val), NULL );
3733 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3734 if (hr == tests[i].hr) ok( val == tests[i].val, "%u: got %s\n", i, wine_dbgstr_longlong(val) );
3737 WsFreeReader( reader );
3738 WsFreeHeap( heap );
3741 static void test_WsReadElement(void)
3743 WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
3744 HRESULT hr;
3745 WS_XML_READER *reader;
3746 WS_ELEMENT_DESCRIPTION desc;
3747 UINT32 val;
3749 hr = WsCreateReader( NULL, 0, &reader, NULL );
3750 ok( hr == S_OK, "got %08x\n", hr );
3752 desc.elementLocalName = &localname;
3753 desc.elementNs = &ns;
3754 desc.type = WS_UINT32_TYPE;
3755 desc.typeDescription = NULL;
3757 prepare_struct_type_test( reader, "<t>1</t>" );
3758 hr = WsReadElement( NULL, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3759 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3761 prepare_struct_type_test( reader, "<t>1</t>" );
3762 hr = WsReadElement( reader, NULL, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3763 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3765 prepare_struct_type_test( reader, "<t>1</t>" );
3766 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, NULL, sizeof(val), NULL );
3767 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3769 prepare_struct_type_test( reader, "<t>1</t>" );
3770 val = 0xdeadbeef;
3771 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3772 ok( hr == S_OK, "got %08x\n", hr );
3773 ok( val == 1, "got %u\n", val );
3775 WsFreeReader( reader );
3778 static void test_WsReadValue(void)
3780 HRESULT hr;
3781 WS_XML_READER *reader;
3782 UINT32 val;
3784 hr = WsCreateReader( NULL, 0, &reader, NULL );
3785 ok( hr == S_OK, "got %08x\n", hr );
3787 prepare_struct_type_test( reader, "<t>1</t>" );
3788 hr = WsReadValue( NULL, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3789 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3791 prepare_struct_type_test( reader, "<t>1</t>" );
3792 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, NULL, sizeof(val), NULL );
3793 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3795 /* reader must be positioned correctly */
3796 prepare_struct_type_test( reader, "<t>1</t>" );
3797 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3798 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3800 prepare_struct_type_test( reader, "<t>1</t>" );
3801 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3802 ok( hr == S_OK, "got %08x\n", hr );
3804 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3805 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3807 prepare_struct_type_test( reader, "<t>1</t>" );
3808 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3809 ok( hr == S_OK, "got %08x\n", hr );
3811 hr = WsReadStartElement( reader, NULL );
3812 ok( hr == S_OK, "got %08x\n", hr );
3814 val = 0xdeadbeef;
3815 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3816 ok( hr == S_OK, "got %08x\n", hr );
3817 ok( val == 1, "got %u\n", val );
3819 prepare_struct_type_test( reader, "<u t='1'></u>" );
3820 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3821 ok( hr == S_OK, "got %08x\n", hr );
3823 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3824 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3826 WsFreeReader( reader );
3829 static void test_WsResetError(void)
3831 WS_ERROR_PROPERTY prop;
3832 ULONG size, code;
3833 WS_ERROR *error;
3834 LANGID langid;
3835 HRESULT hr;
3837 hr = WsResetError( NULL );
3838 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3840 error = NULL;
3841 hr = WsCreateError( NULL, 0, &error );
3842 ok( hr == S_OK, "got %08x\n", hr );
3843 ok( error != NULL, "error not set\n" );
3845 code = 0xdeadbeef;
3846 size = sizeof(code);
3847 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3848 ok( hr == S_OK, "got %08x\n", hr );
3850 hr = WsResetError( error );
3851 ok( hr == S_OK, "got %08x\n", hr );
3853 code = 0xdeadbeef;
3854 size = sizeof(code);
3855 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3856 ok( hr == S_OK, "got %08x\n", hr );
3857 ok( !code, "got %u\n", code );
3859 WsFreeError( error );
3861 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
3862 prop.id = WS_ERROR_PROPERTY_LANGID;
3863 prop.value = &langid;
3864 prop.valueSize = sizeof(langid);
3865 hr = WsCreateError( &prop, 1, &error );
3866 ok( hr == S_OK, "got %08x\n", hr );
3868 langid = 0xdead;
3869 size = sizeof(langid);
3870 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3871 ok( hr == S_OK, "got %08x\n", hr );
3872 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3874 hr = WsResetError( error );
3875 ok( hr == S_OK, "got %08x\n", hr );
3877 langid = 0xdead;
3878 size = sizeof(langid);
3879 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3880 ok( hr == S_OK, "got %08x\n", hr );
3881 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3883 WsFreeError( error );
3886 static void test_WsGetReaderPosition(void)
3888 WS_HEAP *heap;
3889 WS_XML_READER *reader;
3890 WS_XML_BUFFER *buffer;
3891 WS_XML_NODE_POSITION pos;
3892 HRESULT hr;
3894 hr = WsGetReaderPosition( NULL, NULL, NULL );
3895 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3897 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3898 ok( hr == S_OK, "got %08x\n", hr );
3900 hr = WsCreateReader( NULL, 0, &reader, NULL );
3901 ok( hr == S_OK, "got %08x\n", hr );
3903 /* reader must be set to an XML buffer */
3904 hr = WsGetReaderPosition( reader, &pos, NULL );
3905 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3907 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
3908 ok( hr == S_OK, "got %08x\n", hr );
3910 hr = WsGetReaderPosition( reader, &pos, NULL );
3911 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3913 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
3914 ok( hr == S_OK, "got %08x\n", hr );
3916 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
3917 ok( hr == S_OK, "got %08x\n", hr );
3919 hr = WsGetReaderPosition( reader, NULL, NULL );
3920 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3922 pos.buffer = pos.node = NULL;
3923 hr = WsGetReaderPosition( reader, &pos, NULL );
3924 ok( hr == S_OK, "got %08x\n", hr );
3925 ok( pos.buffer != NULL, "buffer not set\n" );
3926 ok( pos.node != NULL, "node not set\n" );
3928 WsFreeReader( reader );
3929 WsFreeHeap( heap );
3932 static void test_WsSetReaderPosition(void)
3934 WS_HEAP *heap;
3935 WS_XML_READER *reader;
3936 WS_XML_BUFFER *buf1, *buf2;
3937 WS_XML_NODE_POSITION pos;
3938 HRESULT hr;
3940 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3941 ok( hr == S_OK, "got %08x\n", hr );
3943 hr = WsSetReaderPosition( NULL, NULL, NULL );
3944 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3946 hr = WsCreateReader( NULL, 0, &reader, NULL );
3947 ok( hr == S_OK, "got %08x\n", hr );
3949 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf1, NULL );
3950 ok( hr == S_OK, "got %08x\n", hr );
3952 hr = WsSetInputToBuffer( reader, buf1, NULL, 0, NULL );
3953 ok( hr == S_OK, "got %08x\n", hr );
3955 hr = WsSetReaderPosition( reader, NULL, NULL );
3956 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3958 pos.buffer = pos.node = NULL;
3959 hr = WsGetReaderPosition( reader, &pos, NULL );
3960 ok( hr == S_OK, "got %08x\n", hr );
3961 ok( pos.buffer == buf1, "wrong buffer\n" );
3962 ok( pos.node != NULL, "node not set\n" );
3964 hr = WsSetReaderPosition( reader, &pos, NULL );
3965 ok( hr == S_OK, "got %08x\n", hr );
3967 /* different buffer */
3968 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf2, NULL );
3969 ok( hr == S_OK, "got %08x\n", hr );
3971 pos.buffer = buf2;
3972 hr = WsSetReaderPosition( reader, &pos, NULL );
3973 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3975 WsFreeReader( reader );
3976 WsFreeHeap( heap );
3979 static void test_entities(void)
3981 static const char str1[] = "<t>&#xA</t>";
3982 static const char str2[] = "<t>&#xA;</t>";
3983 static const char str3[] = "<t>&#xa;</t>";
3984 static const char str4[] = "<t>&#xaaaa;</t>";
3985 static const char str5[] = "<t>&#xaaaaa;</t>";
3986 static const char str6[] = "<t>&1</t>";
3987 static const char str7[] = "<t>&1;</t>";
3988 static const char str8[] = "<t>&1111;</t>";
3989 static const char str9[] = "<t>&11111;</t>";
3990 static const char str10[] = "<t>&lt;</t>";
3991 static const char str11[] = "<t>&gt;</t>";
3992 static const char str12[] = "<t>&quot;</t>";
3993 static const char str13[] = "<t>&amp;</t>";
3994 static const char str14[] = "<t>&apos;</t>";
3995 static const char str15[] = "<t>&sopa;</t>";
3996 static const char str16[] = "<t>&#;</t>";
3997 static const char str17[] = "<t>&;</t>";
3998 static const char str18[] = "<t>&&</t>";
3999 static const char str19[] = "<t>&</t>";
4000 static const char str20[] = "<t>&#xaaaaaa;</t>";
4001 static const char str21[] = "<t>&#xd7ff;</t>";
4002 static const char str22[] = "<t>&#xd800;</t>";
4003 static const char str23[] = "<t>&#xdfff;</t>";
4004 static const char str24[] = "<t>&#xe000;</t>";
4005 static const char str25[] = "<t>&#xfffe;</t>";
4006 static const char str26[] = "<t>&#xffff;</t>";
4007 static const char str27[] = "<t>&LT;</t>";
4008 static const char str28[] = "<t>&#x0;</t>";
4009 static const char str29[] = "<t>&#0;</t>";
4010 static const char str30[] = "<t>&#65;</t>";
4011 static const char str31[] = "<t>&#65393;</t>";
4012 static const char str32[] = "<t>&#x10ffff;</t>";
4013 static const char str33[] = "<t>&#x110000;</t>";
4014 static const char str34[] = "<t>&#1114111;</t>";
4015 static const char str35[] = "<t>&#1114112;</t>";
4016 static const char res4[] = {0xea, 0xaa, 0xaa, 0x00};
4017 static const char res5[] = {0xf2, 0xaa, 0xaa, 0xaa, 0x00};
4018 static const char res21[] = {0xed, 0x9f, 0xbf, 0x00};
4019 static const char res24[] = {0xee, 0x80, 0x80, 0x00};
4020 static const char res31[] = {0xef, 0xbd, 0xb1, 0x00};
4021 static const char res32[] = {0xf4, 0x8f, 0xbf, 0xbf, 0x00};
4022 static const struct
4024 const char *str;
4025 HRESULT hr;
4026 const char *res;
4028 tests[] =
4030 { str1, WS_E_INVALID_FORMAT },
4031 { str2, S_OK, "\n" },
4032 { str3, S_OK, "\n" },
4033 { str4, S_OK, res4 },
4034 { str5, S_OK, res5 },
4035 { str6, WS_E_INVALID_FORMAT },
4036 { str7, WS_E_INVALID_FORMAT },
4037 { str8, WS_E_INVALID_FORMAT },
4038 { str9, WS_E_INVALID_FORMAT },
4039 { str10, S_OK, "<" },
4040 { str11, S_OK, ">" },
4041 { str12, S_OK, "\"" },
4042 { str13, S_OK, "&" },
4043 { str14, S_OK, "'" },
4044 { str15, WS_E_INVALID_FORMAT },
4045 { str16, WS_E_INVALID_FORMAT },
4046 { str17, WS_E_INVALID_FORMAT },
4047 { str18, WS_E_INVALID_FORMAT },
4048 { str19, WS_E_INVALID_FORMAT },
4049 { str20, WS_E_INVALID_FORMAT },
4050 { str21, S_OK, res21 },
4051 { str22, WS_E_INVALID_FORMAT },
4052 { str23, WS_E_INVALID_FORMAT },
4053 { str24, S_OK, res24 },
4054 { str25, WS_E_INVALID_FORMAT },
4055 { str26, WS_E_INVALID_FORMAT },
4056 { str27, WS_E_INVALID_FORMAT },
4057 { str28, WS_E_INVALID_FORMAT },
4058 { str29, WS_E_INVALID_FORMAT },
4059 { str30, S_OK, "A" },
4060 { str31, S_OK, res31 },
4061 { str32, S_OK, res32 },
4062 { str33, WS_E_INVALID_FORMAT },
4063 { str34, S_OK, res32 },
4064 { str35, WS_E_INVALID_FORMAT },
4066 HRESULT hr;
4067 WS_XML_READER *reader;
4068 const WS_XML_NODE *node;
4069 const WS_XML_UTF8_TEXT *utf8;
4070 ULONG i;
4072 hr = WsCreateReader( NULL, 0, &reader, NULL );
4073 ok( hr == S_OK, "got %08x\n", hr );
4075 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
4077 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
4078 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4080 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4081 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4083 hr = WsReadNode( reader, NULL );
4084 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
4085 if (hr != S_OK) continue;
4087 hr = WsGetReaderNode( reader, &node, NULL );
4088 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4090 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_TEXT_NODE *)node)->text;
4091 ok( utf8->value.length == strlen(tests[i].res), "%u: got %u\n", i, utf8->value.length );
4092 ok( !memcmp( utf8->value.bytes, tests[i].res, strlen(tests[i].res) ), "%u: wrong data\n", i );
4095 hr = set_input( reader, "<t a='&#xA;&#xA;'/>", sizeof("<t a='&#xA;&#xA;'/>") - 1 );
4096 ok( hr == S_OK, "got %08x\n", hr );
4098 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4099 ok( hr == S_OK, "got %08x\n", hr );
4101 hr = WsGetReaderNode( reader, &node, NULL );
4102 ok( hr == S_OK, "got %08x\n", hr );
4104 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_ELEMENT_NODE *)node)->attributes[0]->value;
4105 ok( utf8->value.length == 2, "got %u\n", utf8->value.length );
4106 ok( !memcmp( utf8->value.bytes, "\n\n", 2 ), "wrong data\n" );
4108 WsFreeReader( reader );
4111 static void test_field_options(void)
4113 static const char xml[] =
4114 "<t xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><wsz i:nil=\"true\"/>"
4115 "<s i:nil=\"true\"/></t>";
4116 HRESULT hr;
4117 WS_HEAP *heap;
4118 WS_XML_READER *reader;
4119 WS_STRUCT_DESCRIPTION s, s2;
4120 WS_FIELD_DESCRIPTION f, f2, f3, f4, f5, *fields[4], *fields2[1];
4121 WS_XML_STRING ns = {0, NULL}, str_wsz = {3, (BYTE *)"wsz"}, str_s = {1, (BYTE *)"s"};
4122 WS_XML_STRING str_int32 = {5, (BYTE *)"int32"}, str_guid = {4, (BYTE *)"guid"};
4123 WS_DEFAULT_VALUE def_val;
4124 INT32 val_int32;
4125 struct s
4127 INT32 int32;
4129 struct test
4131 WCHAR *wsz;
4132 struct s *s;
4133 INT32 int32;
4134 GUID guid;
4135 } *test;
4137 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
4138 ok( hr == S_OK, "got %08x\n", hr );
4140 hr = WsCreateReader( NULL, 0, &reader, NULL );
4141 ok( hr == S_OK, "got %08x\n", hr );
4143 hr = set_input( reader, xml, sizeof(xml) - 1 );
4144 ok( hr == S_OK, "got %08x\n", hr );
4146 memset( &f, 0, sizeof(f) );
4147 f.mapping = WS_ELEMENT_FIELD_MAPPING;
4148 f.localName = &str_wsz;
4149 f.ns = &ns;
4150 f.type = WS_WSZ_TYPE;
4151 f.options = WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
4152 fields[0] = &f;
4154 memset( &f3, 0, sizeof(f3) );
4155 f3.mapping = WS_ELEMENT_FIELD_MAPPING;
4156 f3.localName = &str_int32;
4157 f3.ns = &ns;
4158 f3.type = WS_INT32_TYPE;
4159 fields2[0] = &f3;
4161 memset( &s2, 0, sizeof(s2) );
4162 s2.size = sizeof(struct s);
4163 s2.alignment = TYPE_ALIGNMENT(struct s);
4164 s2.fields = fields2;
4165 s2.fieldCount = 1;
4167 memset( &f2, 0, sizeof(f2) );
4168 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
4169 f2.localName = &str_s;
4170 f2.ns = &ns;
4171 f2.type = WS_STRUCT_TYPE;
4172 f2.typeDescription = &s2;
4173 f2.offset = FIELD_OFFSET(struct test, s);
4174 f2.options = WS_FIELD_POINTER|WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
4175 fields[1] = &f2;
4177 val_int32 = -1;
4178 def_val.value = &val_int32;
4179 def_val.valueSize = sizeof(val_int32);
4181 memset( &f4, 0, sizeof(f4) );
4182 f4.mapping = WS_ELEMENT_FIELD_MAPPING;
4183 f4.localName = &str_int32;
4184 f4.ns = &ns;
4185 f4.type = WS_INT32_TYPE;
4186 f4.offset = FIELD_OFFSET(struct test, int32);
4187 f4.options = WS_FIELD_OPTIONAL;
4188 f4.defaultValue = &def_val;
4189 fields[2] = &f4;
4191 memset( &f5, 0, sizeof(f5) );
4192 f5.mapping = WS_ELEMENT_FIELD_MAPPING;
4193 f5.localName = &str_guid;
4194 f5.ns = &ns;
4195 f5.type = WS_GUID_TYPE;
4196 f5.offset = FIELD_OFFSET(struct test, guid);
4197 f5.options = WS_FIELD_OPTIONAL;
4198 fields[3] = &f5;
4200 memset( &s, 0, sizeof(s) );
4201 s.size = sizeof(struct test);
4202 s.alignment = TYPE_ALIGNMENT(struct test);
4203 s.fields = fields;
4204 s.fieldCount = 4;
4206 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
4207 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
4208 ok( hr == S_OK, "got %08x\n", hr );
4209 ok( !test->wsz, "wsz is set\n" );
4210 ok( !test->s, "s is set\n" );
4211 ok( test->int32 == -1, "got %d\n", test->int32 );
4212 ok( IsEqualGUID( &test->guid, &guid_null ), "wrong guid\n" );
4214 WsFreeReader( reader );
4215 WsFreeHeap( heap );
4218 static void test_WsReadBytes(void)
4220 HRESULT hr;
4221 WS_XML_READER *reader;
4222 const WS_XML_NODE *node;
4223 const WS_XML_TEXT_NODE *text;
4224 const WS_XML_UTF8_TEXT *utf8;
4225 BYTE buf[4];
4226 ULONG count;
4228 hr = WsCreateReader( NULL, 0, &reader, NULL );
4229 ok( hr == S_OK, "got %08x\n", hr );
4231 hr = WsReadBytes( NULL, NULL, 0, NULL, NULL );
4232 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4234 hr = WsReadBytes( reader, NULL, 0, NULL, NULL );
4235 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4237 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
4238 ok( hr == S_OK, "got %08x\n", hr );
4240 hr = WsReadBytes( reader, NULL, 0, NULL, NULL );
4241 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4243 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
4244 ok( hr == S_OK, "got %08x\n", hr );
4246 hr = WsReadBytes( reader, buf, 0, NULL, NULL );
4247 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4249 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
4250 ok( hr == S_OK, "got %08x\n", hr );
4252 count = 0xdeadbeef;
4253 hr = WsReadBytes( reader, NULL, 0, &count, NULL );
4254 ok( hr == S_OK, "got %08x\n", hr );
4255 ok( !count, "got %u\n", count );
4257 count = 0xdeadbeef;
4258 hr = WsReadBytes( reader, NULL, 1, &count, NULL );
4259 ok( hr == S_OK, "got %08x\n", hr );
4260 ok( !count, "got %u\n", count );
4262 buf[0] = 0;
4263 count = 0xdeadbeef;
4264 hr = WsReadBytes( reader, buf, 0, &count, NULL );
4265 ok( hr == S_OK, "got %08x\n", hr );
4266 ok( !count, "got %u\n", count );
4267 ok( !buf[0], "wrong data\n" );
4269 buf[0] = 0;
4270 count = 0xdeadbeef;
4271 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4272 ok( hr == S_OK, "got %08x\n", hr );
4273 ok( !count, "got %u\n", count );
4274 ok( !buf[0], "wrong data\n" );
4276 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4277 ok( hr == S_OK, "got %08x\n", hr );
4279 buf[0] = 0;
4280 count = 0xdeadbeef;
4281 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4282 ok( hr == S_OK, "got %08x\n", hr );
4283 ok( !count, "got %u\n", count );
4284 ok( !buf[0], "wrong data\n" );
4286 hr = WsReadStartElement( reader, NULL );
4287 ok( hr == S_OK, "got %08x\n", hr );
4289 count = 0xdeadbeef;
4290 hr = WsReadBytes( reader, NULL, 0, &count, NULL );
4291 ok( hr == S_OK, "got %08x\n", hr );
4292 ok( !count, "got %u\n", count );
4294 buf[0] = 0;
4295 count = 0xdeadbeef;
4296 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4297 ok( hr == S_OK, "got %08x\n", hr );
4298 ok( count == 2, "got %u\n", count );
4299 ok( !memcmp( buf, "te", 2 ), "wrong data\n" );
4301 hr = WsGetReaderNode( reader, &node, NULL );
4302 ok( hr == S_OK, "got %08x\n", hr );
4303 text = (const WS_XML_TEXT_NODE *)node;
4304 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4305 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4306 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4307 ok( utf8->value.length == 8, "got %u\n", utf8->value.length );
4308 ok( !memcmp( utf8->value.bytes, "dGV4dA==", 8 ), "wrong data\n" );
4310 buf[0] = 0;
4311 count = 0xdeadbeef;
4312 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4313 ok( hr == S_OK, "got %08x\n", hr );
4314 ok( count == 2, "got %u\n", count );
4315 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4317 hr = WsGetReaderNode( reader, &node, NULL );
4318 ok( hr == S_OK, "got %08x\n", hr );
4319 text = (const WS_XML_TEXT_NODE *)node;
4320 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4322 count = 0xdeadbeef;
4323 hr = WsReadBytes( reader, buf, 1, &count, NULL );
4324 ok( hr == S_OK, "got %08x\n", hr );
4325 ok( !count, "got %u\n", count );
4327 hr = WsGetReaderNode( reader, &node, NULL );
4328 ok( hr == S_OK, "got %08x\n", hr );
4329 text = (const WS_XML_TEXT_NODE *)node;
4330 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4332 WsFreeReader( reader );
4335 static void test_WsReadChars(void)
4337 static const WCHAR textW[] = {'t','e','x','t'};
4338 HRESULT hr;
4339 WS_XML_READER *reader;
4340 const WS_XML_NODE *node;
4341 const WS_XML_TEXT_NODE *text;
4342 const WS_XML_UTF8_TEXT *utf8;
4343 unsigned char buf[4];
4344 WCHAR bufW[4];
4345 ULONG count;
4347 hr = WsCreateReader( NULL, 0, &reader, NULL );
4348 ok( hr == S_OK, "got %08x\n", hr );
4350 hr = WsReadChars( NULL, NULL, 0, NULL, NULL );
4351 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4353 hr = WsReadChars( reader, NULL, 0, NULL, NULL );
4354 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4356 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4357 ok( hr == S_OK, "got %08x\n", hr );
4359 hr = WsReadChars( reader, NULL, 0, NULL, NULL );
4360 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4362 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4363 ok( hr == S_OK, "got %08x\n", hr );
4365 hr = WsReadChars( reader, bufW, 0, NULL, NULL );
4366 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4368 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4369 ok( hr == S_OK, "got %08x\n", hr );
4371 count = 0xdeadbeef;
4372 hr = WsReadChars( reader, NULL, 0, &count, NULL );
4373 ok( hr == S_OK, "got %08x\n", hr );
4374 ok( !count, "got %u\n", count );
4376 count = 0xdeadbeef;
4377 hr = WsReadChars( reader, NULL, 1, &count, NULL );
4378 ok( hr == S_OK, "got %08x\n", hr );
4379 ok( !count, "got %u\n", count );
4381 buf[0] = 0;
4382 count = 0xdeadbeef;
4383 hr = WsReadChars( reader, bufW, 0, &count, NULL );
4384 ok( hr == S_OK, "got %08x\n", hr );
4385 ok( !count, "got %u\n", count );
4386 ok( !buf[0], "wrong data\n" );
4388 buf[0] = 0;
4389 count = 0xdeadbeef;
4390 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4391 ok( hr == S_OK, "got %08x\n", hr );
4392 ok( !count, "got %u\n", count );
4393 ok( !buf[0], "wrong data\n" );
4395 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4396 ok( hr == S_OK, "got %08x\n", hr );
4398 buf[0] = 0;
4399 count = 0xdeadbeef;
4400 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4401 ok( hr == S_OK, "got %08x\n", hr );
4402 ok( !count, "got %u\n", count );
4403 ok( !buf[0], "wrong data\n" );
4405 hr = WsReadStartElement( reader, NULL );
4406 ok( hr == S_OK, "got %08x\n", hr );
4408 count = 0xdeadbeef;
4409 hr = WsReadChars( reader, NULL, 0, &count, NULL );
4410 ok( hr == S_OK, "got %08x\n", hr );
4411 ok( !count, "got %u\n", count );
4413 buf[0] = 0;
4414 count = 0xdeadbeef;
4415 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4416 ok( hr == S_OK, "got %08x\n", hr );
4417 ok( count == 2, "got %u\n", count );
4418 ok( !memcmp( bufW, textW, 2 * sizeof(WCHAR) ), "wrong data\n" );
4420 hr = WsGetReaderNode( reader, &node, NULL );
4421 ok( hr == S_OK, "got %08x\n", hr );
4422 text = (const WS_XML_TEXT_NODE *)node;
4423 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4424 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4425 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4426 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4427 ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" );
4429 /* continue reading in a different encoding */
4430 buf[0] = 0;
4431 count = 0xdeadbeef;
4432 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4433 ok( hr == S_OK, "got %08x\n", hr );
4434 ok( count == 2, "got %u\n", count );
4435 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4437 hr = WsGetReaderNode( reader, &node, NULL );
4438 ok( hr == S_OK, "got %08x\n", hr );
4439 text = (const WS_XML_TEXT_NODE *)node;
4440 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4442 count = 0xdeadbeef;
4443 hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL );
4444 ok( hr == S_OK, "got %08x\n", hr );
4445 ok( !count, "got %u\n", count );
4447 hr = WsGetReaderNode( reader, &node, NULL );
4448 ok( hr == S_OK, "got %08x\n", hr );
4449 text = (const WS_XML_TEXT_NODE *)node;
4450 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4452 WsFreeReader( reader );
4455 static void test_WsReadCharsUtf8(void)
4457 HRESULT hr;
4458 WS_XML_READER *reader;
4459 const WS_XML_NODE *node;
4460 const WS_XML_TEXT_NODE *text;
4461 const WS_XML_UTF8_TEXT *utf8;
4462 BYTE buf[4];
4463 ULONG count;
4465 hr = WsCreateReader( NULL, 0, &reader, NULL );
4466 ok( hr == S_OK, "got %08x\n", hr );
4468 hr = WsReadCharsUtf8( NULL, NULL, 0, NULL, NULL );
4469 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4471 hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL );
4472 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4474 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4475 ok( hr == S_OK, "got %08x\n", hr );
4477 hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL );
4478 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4480 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4481 ok( hr == S_OK, "got %08x\n", hr );
4483 hr = WsReadCharsUtf8( reader, buf, 0, NULL, NULL );
4484 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4486 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4487 ok( hr == S_OK, "got %08x\n", hr );
4489 count = 0xdeadbeef;
4490 hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL );
4491 ok( hr == S_OK, "got %08x\n", hr );
4492 ok( !count, "got %u\n", count );
4494 count = 0xdeadbeef;
4495 hr = WsReadCharsUtf8( reader, NULL, 1, &count, NULL );
4496 ok( hr == S_OK, "got %08x\n", hr );
4497 ok( !count, "got %u\n", count );
4499 buf[0] = 0;
4500 count = 0xdeadbeef;
4501 hr = WsReadCharsUtf8( reader, buf, 0, &count, NULL );
4502 ok( hr == S_OK, "got %08x\n", hr );
4503 ok( !count, "got %u\n", count );
4504 ok( !buf[0], "wrong data\n" );
4506 buf[0] = 0;
4507 count = 0xdeadbeef;
4508 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4509 ok( hr == S_OK, "got %08x\n", hr );
4510 ok( !count, "got %u\n", count );
4511 ok( !buf[0], "wrong data\n" );
4513 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4514 ok( hr == S_OK, "got %08x\n", hr );
4516 buf[0] = 0;
4517 count = 0xdeadbeef;
4518 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4519 ok( hr == S_OK, "got %08x\n", hr );
4520 ok( !count, "got %u\n", count );
4521 ok( !buf[0], "wrong data\n" );
4523 hr = WsReadStartElement( reader, NULL );
4524 ok( hr == S_OK, "got %08x\n", hr );
4526 count = 0xdeadbeef;
4527 hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL );
4528 ok( hr == S_OK, "got %08x\n", hr );
4529 ok( !count, "got %u\n", count );
4531 buf[0] = 0;
4532 count = 0xdeadbeef;
4533 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4534 ok( hr == S_OK, "got %08x\n", hr );
4535 ok( count == 2, "got %u\n", count );
4536 ok( !memcmp( buf, "te", 2 ), "wrong data\n" );
4538 hr = WsGetReaderNode( reader, &node, NULL );
4539 ok( hr == S_OK, "got %08x\n", hr );
4540 text = (const WS_XML_TEXT_NODE *)node;
4541 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4542 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4543 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4544 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4545 ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" );
4547 buf[0] = 0;
4548 count = 0xdeadbeef;
4549 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4550 ok( hr == S_OK, "got %08x\n", hr );
4551 ok( count == 2, "got %u\n", count );
4552 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4554 hr = WsGetReaderNode( reader, &node, NULL );
4555 ok( hr == S_OK, "got %08x\n", hr );
4556 text = (const WS_XML_TEXT_NODE *)node;
4557 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4559 count = 0xdeadbeef;
4560 hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL );
4561 ok( hr == S_OK, "got %08x\n", hr );
4562 ok( !count, "got %u\n", count );
4564 hr = WsGetReaderNode( reader, &node, NULL );
4565 ok( hr == S_OK, "got %08x\n", hr );
4566 text = (const WS_XML_TEXT_NODE *)node;
4567 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4569 WsFreeReader( reader );
4572 static void test_WsReadQualifiedName(void)
4574 static const char utf8[] = {'<','a','>',0xc3,0xab,'<','/','a','>',0};
4575 static const char localname_utf8[] = {0xc3,0xab,0};
4576 WS_XML_STRING prefix, localname, ns;
4577 WS_XML_READER *reader;
4578 WS_HEAP *heap;
4579 HRESULT hr;
4580 BOOL found;
4581 ULONG i;
4582 static const struct
4584 const char *str;
4585 HRESULT hr;
4586 const char *prefix;
4587 const char *localname;
4588 const char *ns;
4589 } tests[] =
4591 { "<a></a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4592 { "<a> </a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4593 { "<a>:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4594 { "<a>t</a>", S_OK, "", "t", "" },
4595 { "<a>p:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4596 { "<a>p:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4597 { "<a>:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4598 { "<a xmlns:p=\"ns\">p:t</a>", S_OK, "p", "t", "ns" },
4599 { "<a xmlns:p=\"ns\">p:t:</a>", S_OK, "p", "t:", "ns" },
4600 { "<a xmlns:p=\"ns\">p:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4601 { "<a xmlns:p=\"ns\">:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4602 { "<a xmlns:p=\"ns\">:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4603 { "<a xmlns:p=\"ns\">t</a>", S_OK, "", "t", "" },
4604 { "<a xmlns:p=\"ns\"> </a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4605 { "<a xmlns:p=\"ns\"></a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4606 { "<a xmlns:p=\"ns\">p:t u</a>", S_OK, "p", "t u", "ns" },
4607 { utf8, S_OK, "", localname_utf8, "" },
4608 { "<a> t </a>", S_OK, "", "t", "" },
4609 { "<a xmlns:p=\"ns\"> p:t</a>", S_OK, "p", "t", "ns" },
4610 { "<a xmlns:p=\"ns\">p :t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4611 { "<a xmlns:p=\"ns\">p: t</a>", S_OK, "p", " t", "ns" },
4614 hr = WsReadQualifiedName( NULL, NULL, NULL, NULL, NULL, NULL );
4615 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4617 hr = WsCreateReader( NULL, 0, &reader, NULL );
4618 ok( hr == S_OK, "got %08x\n", hr );
4620 hr = WsReadQualifiedName( reader, NULL, NULL, NULL, NULL, NULL );
4621 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4623 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
4624 ok( hr == S_OK, "got %08x\n", hr );
4626 hr = WsReadQualifiedName( reader, heap, NULL, NULL, NULL, NULL );
4627 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4629 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4630 ok( hr == S_OK, "got %08x\n", hr );
4631 hr = WsReadQualifiedName( reader, heap, NULL, NULL, NULL, NULL );
4632 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4634 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4635 ok( hr == S_OK, "got %08x\n", hr );
4636 hr = WsReadQualifiedName( reader, heap, NULL, &localname, NULL, NULL );
4637 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
4639 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
4641 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
4642 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4644 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4645 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4647 hr = WsReadStartElement( reader, NULL );
4648 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4650 prefix.length = localname.length = ns.length = 0xdeadbeef;
4651 prefix.bytes = localname.bytes = ns.bytes = (BYTE *)0xdeadbeef;
4653 hr = WsReadQualifiedName( reader, heap, &prefix, &localname, &ns, NULL );
4654 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
4655 if (tests[i].hr == S_OK && hr == S_OK)
4657 ok( prefix.length == strlen( tests[i].prefix ), "%u: got %u\n", i, prefix.length );
4658 ok( !memcmp( prefix.bytes, tests[i].prefix, prefix.length ), "%u: wrong data\n", i );
4660 ok( localname.length == strlen( tests[i].localname ), "%u: got %u\n", i, localname.length );
4661 ok( !memcmp( localname.bytes, tests[i].localname, localname.length ), "%u: wrong data\n", i );
4663 ok( ns.length == strlen( tests[i].ns ), "%u: got %u\n", i, ns.length );
4664 ok( !memcmp( ns.bytes, tests[i].ns, ns.length ), "%u: wrong data\n", i );
4666 else if (tests[i].hr != S_OK)
4668 ok( prefix.length == 0xdeadbeef, "got %u\n", prefix.length );
4669 ok( prefix.bytes == (BYTE *)0xdeadbeef, "got %p\n", prefix.bytes );
4671 ok( localname.length == 0xdeadbeef, "got %u\n", localname.length );
4672 ok( localname.bytes == (BYTE *)0xdeadbeef, "got %p\n", localname.bytes );
4674 ok( ns.length == 0xdeadbeef, "got %u\n", ns.length );
4675 ok( ns.bytes == (BYTE *)0xdeadbeef, "got %p\n", ns.bytes );
4679 WsFreeHeap( heap );
4680 WsFreeReader( reader );
4683 static void test_WsReadAttribute(void)
4685 WS_XML_STRING localname = {1, (BYTE *)"a"}, ns = {0, NULL};
4686 WS_XML_READER *reader;
4687 WS_ATTRIBUTE_DESCRIPTION desc;
4688 WS_HEAP *heap;
4689 UINT32 *val;
4690 BOOL found;
4691 HRESULT hr;
4693 hr = WsReadAttribute( NULL, NULL, 0, NULL, NULL, 0, NULL );
4694 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4696 hr = WsCreateReader( NULL, 0, &reader, NULL );
4697 ok( hr == S_OK, "got %08x\n", hr );
4699 hr = WsReadAttribute( reader, NULL, 0, NULL, NULL, 0, NULL );
4700 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4702 desc.attributeLocalName = &localname;
4703 desc.attributeNs = &ns;
4704 desc.type = WS_UINT32_TYPE;
4705 desc.typeDescription = NULL;
4706 hr = WsReadAttribute( reader, &desc, 0, NULL, NULL, 0, NULL );
4707 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4709 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, NULL, NULL, 0, NULL );
4710 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4712 hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL );
4713 ok( hr == S_OK, "got %08x\n", hr );
4715 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, NULL, 0, NULL );
4716 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4718 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, &val, sizeof(val), NULL );
4719 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4721 prepare_struct_type_test( reader, "<t a='1'>" );
4722 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4723 ok( hr == S_OK, "got %08x\n", hr );
4725 val = NULL;
4726 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, &val, sizeof(val), NULL );
4727 ok( hr == S_OK, "got %08x\n", hr );
4728 ok( val != NULL, "val not set\n" );
4729 ok( *val == 1, "got %u\n", *val );
4731 WsFreeHeap( heap );
4732 WsFreeReader( reader );
4735 static void test_WsSkipNode(void)
4737 const WS_XML_NODE *node;
4738 WS_XML_READER *reader;
4739 HRESULT hr;
4741 hr = WsSkipNode( NULL, NULL );
4742 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4744 hr = WsCreateReader( NULL, 0, &reader, NULL );
4745 ok( hr == S_OK, "got %08x\n", hr );
4747 hr = WsSkipNode( reader, NULL );
4748 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4750 hr = set_input( reader, "<t><u></u></t>", sizeof("<t><u></u></t>") - 1 );
4751 ok( hr == S_OK, "got %08x\n", hr );
4753 hr = WsGetReaderNode( reader, &node, NULL );
4754 ok( hr == S_OK, "got %08x\n", hr );
4755 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
4757 /* BOF */
4758 hr = WsSkipNode( reader, NULL );
4759 ok( hr == S_OK, "got %08x\n", hr );
4760 hr = WsGetReaderNode( reader, &node, NULL );
4761 ok( hr == S_OK, "got %08x\n", hr );
4762 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4764 /* element */
4765 hr = WsSkipNode( reader, NULL );
4766 ok( hr == S_OK, "got %08x\n", hr );
4767 hr = WsGetReaderNode( reader, &node, NULL );
4768 ok( hr == S_OK, "got %08x\n", hr );
4769 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
4771 /* EOF */
4772 hr = WsSkipNode( reader, NULL );
4773 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4775 hr = set_input( reader, "<!--comment--><t></t>", sizeof("<!--comment--><t></t>") - 1 );
4776 ok( hr == S_OK, "got %08x\n", hr );
4778 /* non-element */
4779 hr = WsSkipNode( reader, NULL );
4780 ok( hr == S_OK, "got %08x\n", hr );
4781 hr = WsGetReaderNode( reader, &node, NULL );
4782 ok( hr == S_OK, "got %08x\n", hr );
4783 ok( node->nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", node->nodeType );
4785 hr = WsSkipNode( reader, NULL );
4786 ok( hr == S_OK, "got %08x\n", hr );
4787 hr = WsGetReaderNode( reader, &node, NULL );
4788 ok( hr == S_OK, "got %08x\n", hr );
4789 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4791 WsFreeReader( reader );
4794 static HRESULT set_input_bin( WS_XML_READER *reader, const char *data, ULONG size, WS_XML_DICTIONARY *dict )
4796 WS_XML_READER_BINARY_ENCODING bin = {{WS_XML_READER_ENCODING_TYPE_BINARY}, dict};
4797 WS_XML_READER_BUFFER_INPUT buf;
4799 buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
4800 buf.encodedData = (void *)data;
4801 buf.encodedDataSize = size;
4802 return WsSetInput( reader, &bin.encoding, &buf.input, NULL, 0, NULL );
4805 static void test_binary_encoding(void)
4807 static const char test[] =
4808 {0x40,0x01,'t',0x01};
4809 static const char test2[] =
4810 {0x6d,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01};
4811 static const char test3[] =
4812 {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x01};
4813 static const char test4[] =
4814 {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x99,0x04,'t','e','s','t'};
4815 static const char test5[] =
4816 {0x40,0x01,'t',0xa0,0x01,0x00,'a',0x9f,0x01,'b'};
4817 static const char test6[] =
4818 {0x40,0x01,'t',0x9e,0x01,'a',0x9f,0x01,'b'};
4819 static const char test100[] =
4820 {0x40,0x01,'t',0x04,0x01,'t',0x98,0x00,0x01};
4821 static const char test101[] =
4822 {0x40,0x01,'t',0x35,0x01,'t',0x98,0x00,0x09,0x01,'p',0x02,'n','s',0x01};
4823 static const char test102[] =
4824 {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x00,0x09,0x02,'p','2',0x02,'n','s',0x01};
4825 static const char test103[] =
4826 {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x04,'t','e','s','t',0x09,0x02,'p','2',0x02,'n','s',0x01};
4827 static const char test200[] =
4828 {0x02,0x07,'c','o','m','m','e','n','t'};
4829 const WS_XML_NODE *node, *node2;
4830 const WS_XML_ELEMENT_NODE *elem;
4831 const WS_XML_ATTRIBUTE *attr;
4832 const WS_XML_TEXT_NODE *text;
4833 const WS_XML_UTF8_TEXT *utf8;
4834 const WS_XML_BASE64_TEXT *base64;
4835 const WS_XML_COMMENT_NODE *comment;
4836 WS_XML_READER *reader;
4837 BOOL found;
4838 HRESULT hr;
4840 hr = WsCreateReader( NULL, 0, &reader, NULL );
4841 ok( hr == S_OK, "got %08x\n", hr );
4843 /* short element */
4844 hr = set_input_bin( reader, test, sizeof(test), NULL );
4845 ok( hr == S_OK, "got %08x\n", hr );
4847 hr = WsReadNode( reader, NULL );
4848 ok( hr == S_OK, "got %08x\n", hr );
4849 hr = WsGetReaderNode( reader, &node, NULL );
4850 ok( hr == S_OK, "got %08x\n", hr );
4851 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4852 elem = (const WS_XML_ELEMENT_NODE *)node;
4853 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
4854 ok( elem->prefix->bytes == NULL, "bytes set\n" );
4855 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4856 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4857 ok( elem->localName->dictionary != NULL, "dictionary not set\n" );
4858 ok( !elem->ns->length, "got %u\n", elem->ns->length );
4859 ok( elem->ns->bytes != NULL, "bytes not set\n" );
4860 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
4861 ok( !elem->isEmpty, "empty\n" );
4863 hr = WsReadNode( reader, NULL );
4864 ok( hr == S_OK, "got %08x\n", hr );
4865 hr = WsGetReaderNode( reader, &node, NULL );
4866 ok( hr == S_OK, "got %08x\n", hr );
4867 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4869 /* single character prefix element */
4870 hr = set_input_bin( reader, test2, sizeof(test2), NULL );
4871 ok( hr == S_OK, "got %08x\n", hr );
4873 hr = WsReadNode( reader, NULL );
4874 ok( hr == S_OK, "got %08x\n", hr );
4875 hr = WsGetReaderNode( reader, &node, NULL );
4876 ok( hr == S_OK, "got %08x\n", hr );
4877 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4878 elem = (const WS_XML_ELEMENT_NODE *)node;
4879 ok( elem->prefix->length == 1, "got %u\n", elem->prefix->length );
4880 ok( !memcmp( elem->prefix->bytes, "p", 1 ), "wrong prefix\n" );
4881 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4882 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4883 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
4884 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4885 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
4886 ok( !elem->isEmpty, "empty\n" );
4887 attr = elem->attributes[0];
4888 ok( !attr->singleQuote, "single quote\n" );
4889 ok( attr->isXmlNs, "not xmlns\n" );
4890 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
4891 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
4892 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4893 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4895 hr = WsReadNode( reader, NULL );
4896 ok( hr == S_OK, "got %08x\n", hr );
4897 hr = WsGetReaderNode( reader, &node, NULL );
4898 ok( hr == S_OK, "got %08x\n", hr );
4899 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4901 /* element */
4902 hr = set_input_bin( reader, test3, sizeof(test3), NULL );
4903 ok( hr == S_OK, "got %08x\n", hr );
4905 hr = WsReadNode( reader, NULL );
4906 ok( hr == S_OK, "got %08x\n", hr );
4907 hr = WsGetReaderNode( reader, &node, NULL );
4908 ok( hr == S_OK, "got %08x\n", hr );
4909 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4910 elem = (const WS_XML_ELEMENT_NODE *)node;
4911 ok( elem->prefix->length == 2, "got %u\n", elem->prefix->length );
4912 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4913 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4914 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4915 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
4916 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4917 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
4918 ok( !elem->isEmpty, "empty\n" );
4919 attr = elem->attributes[0];
4920 ok( !attr->singleQuote, "single quote\n" );
4921 ok( attr->isXmlNs, "not xmlns\n" );
4922 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
4923 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4924 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4925 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4927 hr = WsReadNode( reader, NULL );
4928 ok( hr == S_OK, "got %08x\n", hr );
4929 hr = WsGetReaderNode( reader, &node, NULL );
4930 ok( hr == S_OK, "got %08x\n", hr );
4931 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4933 /* element with text */
4934 hr = set_input_bin( reader, test4, sizeof(test4), NULL );
4935 ok( hr == S_OK, "got %08x\n", hr );
4937 hr = WsReadNode( reader, NULL );
4938 ok( hr == S_OK, "got %08x\n", hr );
4939 hr = WsGetReaderNode( reader, &node, NULL );
4940 ok( hr == S_OK, "got %08x\n", hr );
4941 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4942 elem = (const WS_XML_ELEMENT_NODE *)node;
4943 ok( elem->prefix->length == 2, "got %u\n", elem->prefix->length );
4944 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4945 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4946 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4947 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
4948 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4949 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
4950 ok( !elem->isEmpty, "empty\n" );
4951 attr = elem->attributes[0];
4952 ok( !attr->singleQuote, "single quote\n" );
4953 ok( attr->isXmlNs, "not xmlns\n" );
4954 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
4955 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4956 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4957 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4959 hr = WsReadNode( reader, NULL );
4960 ok( hr == S_OK, "got %08x\n", hr );
4961 hr = WsGetReaderNode( reader, &node, NULL );
4962 ok( hr == S_OK, "got %08x\n", hr );
4963 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
4964 text = (const WS_XML_TEXT_NODE *)node;
4965 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4966 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4967 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4968 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong text\n" );
4970 hr = WsReadNode( reader, NULL );
4971 ok( hr == S_OK, "got %08x\n", hr );
4972 hr = WsGetReaderNode( reader, &node, NULL );
4973 ok( hr == S_OK, "got %08x\n", hr );
4974 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4976 /* short attribute */
4977 hr = set_input_bin( reader, test100, sizeof(test100), NULL );
4978 ok( hr == S_OK, "got %08x\n", hr );
4980 hr = WsReadNode( reader, NULL );
4981 ok( hr == S_OK, "got %08x\n", hr );
4982 hr = WsGetReaderNode( reader, &node, NULL );
4983 ok( hr == S_OK, "got %08x\n", hr );
4984 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4985 elem = (const WS_XML_ELEMENT_NODE *)node;
4986 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
4987 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4988 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4989 ok( !elem->ns->length, "got %u\n", elem->ns->length );
4990 ok( elem->ns->bytes != NULL, "bytes not set\n" );
4991 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
4992 ok( !elem->isEmpty, "empty\n" );
4993 attr = elem->attributes[0];
4994 ok( !attr->singleQuote, "single quote\n" );
4995 ok( !attr->isXmlNs, "is xmlns\n" );
4996 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
4997 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
4998 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
4999 ok( !attr->ns->length, "got %u\n", attr->ns->length );
5000 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5001 ok( attr->value != NULL, "value not set\n" );
5002 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5003 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5004 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5005 ok( utf8->value.bytes != NULL, "bytes not set\n" );
5007 hr = WsReadNode( reader, NULL );
5008 ok( hr == S_OK, "got %08x\n", hr );
5009 hr = WsGetReaderNode( reader, &node, NULL );
5010 ok( hr == S_OK, "got %08x\n", hr );
5011 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5013 /* single character prefix attribute */
5014 hr = set_input_bin( reader, test101, sizeof(test101), NULL );
5015 ok( hr == S_OK, "got %08x\n", hr );
5017 hr = WsReadNode( reader, NULL );
5018 ok( hr == S_OK, "got %08x\n", hr );
5019 hr = WsGetReaderNode( reader, &node, NULL );
5020 ok( hr == S_OK, "got %08x\n", hr );
5021 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5022 elem = (const WS_XML_ELEMENT_NODE *)node;
5023 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5024 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5025 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5026 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5027 ok( elem->ns->bytes != NULL, "ns not set\n" );
5028 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
5029 ok( !elem->isEmpty, "empty\n" );
5030 attr = elem->attributes[0];
5031 ok( !attr->singleQuote, "single quote\n" );
5032 ok( !attr->isXmlNs, "is xmlns\n" );
5033 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5034 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5035 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5036 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
5037 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5038 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5039 ok( attr->value != NULL, "value not set\n" );
5040 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5041 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5042 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5043 ok( utf8->value.bytes != NULL, "bytes not set\n" );
5044 attr = elem->attributes[1];
5045 ok( !attr->singleQuote, "single quote\n" );
5046 ok( attr->isXmlNs, "not xmlns\n" );
5047 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5048 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5049 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5050 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5052 hr = WsReadNode( reader, NULL );
5053 ok( hr == S_OK, "got %08x\n", hr );
5054 hr = WsGetReaderNode( reader, &node, NULL );
5055 ok( hr == S_OK, "got %08x\n", hr );
5056 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5058 /* attribute */
5059 hr = set_input_bin( reader, test102, sizeof(test102), NULL );
5060 ok( hr == S_OK, "got %08x\n", hr );
5062 hr = WsReadNode( reader, NULL );
5063 ok( hr == S_OK, "got %08x\n", hr );
5064 hr = WsGetReaderNode( reader, &node, NULL );
5065 ok( hr == S_OK, "got %08x\n", hr );
5066 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5067 elem = (const WS_XML_ELEMENT_NODE *)node;
5068 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5069 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5070 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5071 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5072 ok( elem->ns->bytes != NULL, "ns not set\n" );
5073 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
5074 ok( !elem->isEmpty, "empty\n" );
5075 attr = elem->attributes[0];
5076 ok( !attr->singleQuote, "single quote\n" );
5077 ok( !attr->isXmlNs, "is xmlns\n" );
5078 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5079 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5080 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5081 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
5082 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5083 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5084 ok( attr->value != NULL, "value not set\n" );
5085 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5086 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5087 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5088 ok( utf8->value.bytes != NULL, "bytes not set\n" );
5089 attr = elem->attributes[1];
5090 ok( !attr->singleQuote, "single quote\n" );
5091 ok( attr->isXmlNs, "not xmlns\n" );
5092 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5093 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5094 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5095 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5097 hr = WsReadNode( reader, NULL );
5098 ok( hr == S_OK, "got %08x\n", hr );
5099 hr = WsGetReaderNode( reader, &node, NULL );
5100 ok( hr == S_OK, "got %08x\n", hr );
5101 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5103 /* attribute with value */
5104 hr = set_input_bin( reader, test103, sizeof(test103), NULL );
5105 ok( hr == S_OK, "got %08x\n", hr );
5107 hr = WsReadNode( reader, NULL );
5108 ok( hr == S_OK, "got %08x\n", hr );
5109 hr = WsGetReaderNode( reader, &node, NULL );
5110 ok( hr == S_OK, "got %08x\n", hr );
5111 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5112 elem = (const WS_XML_ELEMENT_NODE *)node;
5113 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5114 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5115 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5116 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5117 ok( elem->ns->bytes != NULL, "ns not set\n" );
5118 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
5119 ok( !elem->isEmpty, "empty\n" );
5120 attr = elem->attributes[0];
5121 ok( !attr->singleQuote, "single quote\n" );
5122 ok( !attr->isXmlNs, "is xmlns\n" );
5123 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5124 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5125 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5126 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
5127 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5128 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5129 ok( attr->value != NULL, "value not set\n" );
5130 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5131 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5132 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
5133 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong value\n" );
5134 attr = elem->attributes[1];
5135 ok( !attr->singleQuote, "single quote\n" );
5136 ok( attr->isXmlNs, "not xmlns\n" );
5137 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5138 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5139 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5140 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5142 hr = WsReadNode( reader, NULL );
5143 ok( hr == S_OK, "got %08x\n", hr );
5144 hr = WsGetReaderNode( reader, &node, NULL );
5145 ok( hr == S_OK, "got %08x\n", hr );
5146 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5148 hr = WsReadNode( reader, NULL );
5149 ok( hr == S_OK, "got %08x\n", hr );
5150 hr = WsGetReaderNode( reader, &node, NULL );
5151 ok( hr == S_OK, "got %08x\n", hr );
5152 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
5154 /* comment */
5155 hr = set_input_bin( reader, test200, sizeof(test200), NULL );
5156 ok( hr == S_OK, "got %08x\n", hr );
5158 hr = WsReadNode( reader, NULL );
5159 ok( hr == S_OK, "got %08x\n", hr );
5160 hr = WsGetReaderNode( reader, &node, NULL );
5161 ok( hr == S_OK, "got %08x\n", hr );
5162 ok( node->nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", node->nodeType );
5163 comment = (const WS_XML_COMMENT_NODE *)node;
5164 ok( comment->value.length == 7, "got %u\n", comment->value.length );
5165 ok( !memcmp( comment->value.bytes, "comment", 7 ), "wrong data\n" );
5167 hr = set_input_bin( reader, test, sizeof(test), NULL );
5168 ok( hr == S_OK, "got %08x\n", hr );
5170 found = -1;
5171 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
5172 ok( hr == S_OK, "got %08x\n", hr );
5173 ok( found == TRUE, "got %d\n", found );
5174 hr = WsReadStartElement( reader, NULL );
5175 ok( hr == S_OK, "got %08x\n", hr );
5176 hr = WsReadEndElement( reader, NULL );
5177 ok( hr == S_OK, "got %08x\n", hr );
5179 /* element with different byte record types */
5180 hr = set_input_bin( reader, test5, sizeof(test5), NULL );
5181 ok( hr == S_OK, "got %08x\n", hr );
5183 hr = WsReadNode( reader, NULL );
5184 ok( hr == S_OK, "got %08x\n", hr );
5185 hr = WsReadNode( reader, NULL );
5186 ok( hr == S_OK, "got %08x\n", hr );
5187 hr = WsGetReaderNode( reader, &node, NULL );
5188 ok( hr == S_OK, "got %08x\n", hr );
5189 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
5190 text = (const WS_XML_TEXT_NODE *)node;
5191 ok( text->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text->text->textType );
5192 base64 = (const WS_XML_BASE64_TEXT *)text->text;
5193 ok( base64->length == 1, "got %u\n", base64->length );
5194 ok( base64->bytes[0] == 'a', "wrong data %02x\n", base64->bytes[0] );
5196 hr = WsReadNode( reader, NULL );
5197 ok( hr == S_OK, "got %08x\n", hr );
5198 hr = WsGetReaderNode( reader, &node2, NULL );
5199 ok( hr == S_OK, "got %08x\n", hr );
5200 todo_wine ok( node2 == node, "different node\n" );
5201 ok( node2->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node2->nodeType );
5202 text = (const WS_XML_TEXT_NODE *)node2;
5203 ok( text->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text->text->textType );
5204 base64 = (const WS_XML_BASE64_TEXT *)text->text;
5205 ok( base64->length == 1, "got %u\n", base64->length );
5206 ok( base64->bytes[0] == 'b', "wrong data %02x\n", base64->bytes[0] );
5207 hr = WsReadNode( reader, NULL );
5208 ok( hr == S_OK, "got %08x\n", hr );
5210 /* element with equal byte record types */
5211 hr = set_input_bin( reader, test6, sizeof(test6), NULL );
5212 ok( hr == S_OK, "got %08x\n", hr );
5214 hr = WsReadNode( reader, NULL );
5215 ok( hr == S_OK, "got %08x\n", hr );
5216 hr = WsReadNode( reader, NULL );
5217 ok( hr == S_OK, "got %08x\n", hr );
5218 hr = WsGetReaderNode( reader, &node, NULL );
5219 ok( hr == S_OK, "got %08x\n", hr );
5220 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
5221 text = (const WS_XML_TEXT_NODE *)node;
5222 ok( text->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text->text->textType );
5223 base64 = (const WS_XML_BASE64_TEXT *)text->text;
5224 ok( base64->length == 1, "got %u\n", base64->length );
5225 ok( base64->bytes[0] == 'a', "wrong data %02x\n", base64->bytes[0] );
5227 hr = WsReadNode( reader, NULL );
5228 ok( hr == S_OK, "got %08x\n", hr );
5229 hr = WsGetReaderNode( reader, &node2, NULL );
5230 ok( hr == S_OK, "got %08x\n", hr );
5231 todo_wine ok( node2 == node, "different node\n" );
5232 ok( node2->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node2->nodeType );
5233 text = (const WS_XML_TEXT_NODE *)node2;
5234 ok( text->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text->text->textType );
5235 base64 = (const WS_XML_BASE64_TEXT *)text->text;
5236 ok( base64->length == 1, "got %u\n", base64->length );
5237 ok( base64->bytes[0] == 'b', "wrong data %02x\n", base64->bytes[0] );
5238 hr = WsReadNode( reader, NULL );
5239 ok( hr == S_OK, "got %08x\n", hr );
5241 WsFreeReader( reader );
5244 static void test_dictionary(void)
5246 static const GUID dict_static =
5247 {0xf93578f8,0x5852,0x4eb7,{0xa6,0xfc,0xe7,0x2b,0xb7,0x1d,0xb6,0x22}};
5248 static const char res[] =
5249 {0x42,0x04,0x01};
5250 static const char res2[] =
5251 {0x53,0x06,0x0b,0x01,'p',0x0a,0x01};
5252 static const char res3[] =
5253 {0x43,0x02,'p','2',0x06,0x0b,0x02,'p','2',0x0a,0x01};
5254 static const char res4[] =
5255 {0x42,0x06,0x06,0x06,0x98,0x00,0x01};
5256 static const char res5[] =
5257 {0x42,0x06,0x1b,0x06,0x98,0x00,0x0b,0x01,'p',0x0a,0x01};
5258 static const char res6[] =
5259 {0x42,0x06,0x07,0x02,'p','2',0x06,0x98,0x00,0x0b,0x02,'p','2',0x0a,0x01};
5260 const WS_XML_NODE *node;
5261 const WS_XML_ELEMENT_NODE *elem;
5262 const WS_XML_ATTRIBUTE *attr;
5263 const WS_XML_UTF8_TEXT *utf8;
5264 WS_XML_STRING strings[6];
5265 WS_XML_DICTIONARY dict, *dict2;
5266 WS_XML_READER *reader;
5267 HRESULT hr;
5269 hr = WsCreateReader( NULL, 0, &reader, NULL );
5270 ok( hr == S_OK, "got %08x\n", hr );
5272 strings[0].length = 0;
5273 strings[0].bytes = NULL;
5274 strings[0].dictionary = &dict;
5275 strings[0].id = 0;
5276 strings[1].length = 1;
5277 strings[1].bytes = (BYTE *)"p";
5278 strings[1].dictionary = &dict;
5279 strings[1].id = 1;
5280 strings[2].length = 1;
5281 strings[2].bytes = (BYTE *)"t";
5282 strings[2].dictionary = &dict;
5283 strings[2].id = ~0u;
5284 strings[3].length = 1;
5285 strings[3].bytes = (BYTE *)"u";
5286 strings[3].dictionary = &dict;
5287 strings[3].id = 3;
5288 strings[4].length = 2;
5289 strings[4].bytes = (BYTE *)"p2";
5290 strings[4].dictionary = &dict;
5291 strings[4].id = 4;
5292 strings[5].length = 2;
5293 strings[5].bytes = (BYTE *)"ns";
5294 strings[5].dictionary = &dict;
5295 strings[5].id = 5;
5297 UuidCreate( &dict.guid );
5298 dict.strings = strings;
5299 dict.stringCount = sizeof(strings)/sizeof(strings[0]);
5300 dict.isConst = TRUE;
5302 /* short dictionary element */
5303 hr = set_input_bin( reader, res, sizeof(res), &dict );
5304 ok( hr == S_OK, "got %08x\n", hr );
5306 hr = WsReadNode( reader, NULL );
5307 ok( hr == S_OK, "got %08x\n", hr );
5308 hr = WsGetReaderNode( reader, &node, NULL );
5309 ok( hr == S_OK, "got %08x\n", hr );
5310 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5311 elem = (const WS_XML_ELEMENT_NODE *)node;
5312 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5313 ok( elem->prefix->bytes == NULL, "bytes set\n" );
5314 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5315 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5316 ok( elem->localName->dictionary == &dict, "unexpected dict\n" );
5317 ok( elem->localName->id == ~0u, "unexpected id %08x\n", elem->localName->id );
5318 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5319 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5320 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
5321 ok( !elem->isEmpty, "empty\n" );
5323 hr = WsReadNode( reader, NULL );
5324 ok( hr == S_OK, "got %08x\n", hr );
5325 hr = WsGetReaderNode( reader, &node, NULL );
5326 ok( hr == S_OK, "got %08x\n", hr );
5327 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5329 /* single character prefix dictionary element */
5330 hr = set_input_bin( reader, res2, sizeof(res2), &dict );
5331 ok( hr == S_OK, "got %08x\n", hr );
5333 hr = WsReadNode( reader, NULL );
5334 ok( hr == S_OK, "got %08x\n", hr );
5335 hr = WsGetReaderNode( reader, &node, NULL );
5336 ok( hr == S_OK, "got %08x\n", hr );
5337 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5338 elem = (const WS_XML_ELEMENT_NODE *)node;
5339 ok( elem->prefix->length == 1, "got %u\n", elem->prefix->length );
5340 ok( !memcmp( elem->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5341 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5342 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5343 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
5344 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5345 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5346 ok( !elem->isEmpty, "empty\n" );
5347 attr = elem->attributes[0];
5348 ok( !attr->singleQuote, "single quote\n" );
5349 ok( attr->isXmlNs, "not xmlns\n" );
5350 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5351 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5352 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5353 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5354 ok( attr->ns->dictionary == &dict, "unexpected dict\n" );
5355 ok( attr->ns->id == 5, "unexpected id %08x\n", attr->ns->id );
5357 hr = WsReadNode( reader, NULL );
5358 ok( hr == S_OK, "got %08x\n", hr );
5359 hr = WsGetReaderNode( reader, &node, NULL );
5360 ok( hr == S_OK, "got %08x\n", hr );
5361 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5363 /* dictionary element */
5364 hr = set_input_bin( reader, res3, sizeof(res3), &dict );
5365 ok( hr == S_OK, "got %08x\n", hr );
5367 hr = WsReadNode( reader, NULL );
5368 ok( hr == S_OK, "got %08x\n", hr );
5369 hr = WsGetReaderNode( reader, &node, NULL );
5370 ok( hr == S_OK, "got %08x\n", hr );
5371 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5372 elem = (const WS_XML_ELEMENT_NODE *)node;
5373 ok( elem->prefix->length == 2, "got %u\n", elem->prefix->length );
5374 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5375 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5376 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5377 ok( elem->localName->dictionary == &dict, "unexpected dict\n" );
5378 ok( elem->localName->id == 3, "unexpected id %08x\n", elem->localName->id );
5379 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
5380 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5381 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5382 ok( !elem->isEmpty, "empty\n" );
5383 attr = elem->attributes[0];
5384 ok( !attr->singleQuote, "single quote\n" );
5385 ok( attr->isXmlNs, "not xmlns\n" );
5386 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5387 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5388 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5389 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5391 hr = WsReadNode( reader, NULL );
5392 ok( hr == S_OK, "got %08x\n", hr );
5393 hr = WsGetReaderNode( reader, &node, NULL );
5394 ok( hr == S_OK, "got %08x\n", hr );
5395 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5397 /* short dictionary attribute */
5398 hr = set_input_bin( reader, res4, sizeof(res4), &dict );
5399 ok( hr == S_OK, "got %08x\n", hr );
5401 hr = WsReadNode( reader, NULL );
5402 ok( hr == S_OK, "got %08x\n", hr );
5403 hr = WsGetReaderNode( reader, &node, NULL );
5404 ok( hr == S_OK, "got %08x\n", hr );
5405 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5406 elem = (const WS_XML_ELEMENT_NODE *)node;
5407 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5408 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5409 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5410 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5411 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5412 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5413 ok( !elem->isEmpty, "empty\n" );
5414 attr = elem->attributes[0];
5415 ok( !attr->singleQuote, "single quote\n" );
5416 ok( !attr->isXmlNs, "is xmlns\n" );
5417 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
5418 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5419 ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
5420 ok( attr->localName->id == 3, "unexpected id %08x\n", attr->localName->id );
5421 ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
5422 ok( !attr->ns->length, "got %u\n", attr->ns->length );
5423 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5424 ok( attr->value != NULL, "value not set\n" );
5425 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5426 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5427 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5428 ok( utf8->value.bytes != NULL, "bytes not set\n" );
5430 hr = WsReadNode( reader, NULL );
5431 ok( hr == S_OK, "got %08x\n", hr );
5432 hr = WsGetReaderNode( reader, &node, NULL );
5433 ok( hr == S_OK, "got %08x\n", hr );
5434 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5436 /* single character prefix dictionary attribute */
5437 hr = set_input_bin( reader, res5, sizeof(res5), &dict );
5438 ok( hr == S_OK, "got %08x\n", hr );
5440 hr = WsReadNode( reader, NULL );
5441 ok( hr == S_OK, "got %08x\n", hr );
5442 hr = WsGetReaderNode( reader, &node, NULL );
5443 ok( hr == S_OK, "got %08x\n", hr );
5444 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5445 elem = (const WS_XML_ELEMENT_NODE *)node;
5446 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5447 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5448 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5449 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5450 ok( elem->ns->bytes != NULL, "ns not set\n" );
5451 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
5452 ok( !elem->isEmpty, "empty\n" );
5453 attr = elem->attributes[0];
5454 ok( !attr->singleQuote, "single quote\n" );
5455 ok( !attr->isXmlNs, "is 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->localName->length == 1, "got %u\n", attr->localName->length );
5459 ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
5460 ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
5461 ok( attr->localName->id == 3, "unexpected id %08x\n", attr->localName->id );
5462 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5463 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5464 ok( attr->value != NULL, "value not set\n" );
5465 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5466 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5467 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5468 ok( utf8->value.bytes != NULL, "bytes not set\n" );
5469 attr = elem->attributes[1];
5470 ok( !attr->singleQuote, "single quote\n" );
5471 ok( attr->isXmlNs, "not xmlns\n" );
5472 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5473 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5474 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5475 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5477 hr = WsReadNode( reader, NULL );
5478 ok( hr == S_OK, "got %08x\n", hr );
5479 hr = WsGetReaderNode( reader, &node, NULL );
5480 ok( hr == S_OK, "got %08x\n", hr );
5481 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5483 /* dictionary attribute */
5484 hr = set_input_bin( reader, res6, sizeof(res6), &dict );
5485 ok( hr == S_OK, "got %08x\n", hr );
5487 hr = WsReadNode( reader, NULL );
5488 ok( hr == S_OK, "got %08x\n", hr );
5489 hr = WsGetReaderNode( reader, &node, NULL );
5490 ok( hr == S_OK, "got %08x\n", hr );
5491 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5492 elem = (const WS_XML_ELEMENT_NODE *)node;
5493 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5494 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5495 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5496 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5497 ok( elem->ns->bytes != NULL, "ns not set\n" );
5498 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
5499 ok( !elem->isEmpty, "empty\n" );
5500 attr = elem->attributes[0];
5501 ok( !attr->singleQuote, "single quote\n" );
5502 ok( !attr->isXmlNs, "is xmlns\n" );
5503 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5504 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5505 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5506 ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
5507 ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
5508 ok( attr->localName->id == 3, "unexpected id %08x\n", attr->localName->id );
5509 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5510 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5511 ok( attr->value != NULL, "value not set\n" );
5512 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5513 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5514 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5515 ok( utf8->value.bytes != NULL, "bytes not set\n" );
5516 attr = elem->attributes[1];
5517 ok( !attr->singleQuote, "single quote\n" );
5518 ok( attr->isXmlNs, "not xmlns\n" );
5519 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5520 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5521 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5522 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5524 hr = WsReadNode( reader, NULL );
5525 ok( hr == S_OK, "got %08x\n", hr );
5526 hr = WsGetReaderNode( reader, &node, NULL );
5527 ok( hr == S_OK, "got %08x\n", hr );
5528 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5530 hr = WsGetDictionary( 0, NULL, NULL );
5531 ok( hr == E_INVALIDARG, "got %08x\n", hr );
5533 hr = WsGetDictionary( WS_ENCODING_XML_UTF8, NULL, NULL );
5534 ok( hr == E_INVALIDARG, "got %08x\n", hr );
5536 dict2 = (WS_XML_DICTIONARY *)0xdeadbeef;
5537 hr = WsGetDictionary( WS_ENCODING_XML_UTF8, &dict2, NULL );
5538 ok( hr == S_OK, "got %08x\n", hr );
5539 ok( dict2 == NULL, "got %p\n", dict2 );
5541 dict2 = NULL;
5542 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_1, &dict2, NULL );
5543 ok( hr == S_OK, "got %08x\n", hr );
5544 ok( dict2 != NULL, "dict2 not set\n" );
5545 ok( dict2 != &dict, "got %p\n", dict2 );
5547 dict2 = NULL;
5548 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_SESSION_1, &dict2, NULL );
5549 ok( hr == S_OK, "got %08x\n", hr );
5550 ok( dict2 != NULL, "dict2 not set\n" );
5551 ok( dict2 != &dict, "got %p\n", dict2 );
5552 ok( !memcmp( &dict2->guid, &dict_static, sizeof(dict_static) ),
5553 "got %s\n", wine_dbgstr_guid(&dict2->guid) );
5554 ok( dict2->stringCount == 488 || dict2->stringCount == 487 /* < win10 */, "got %u\n", dict2->stringCount );
5555 ok( dict2->strings[0].length == 14, "got %u\n", dict2->strings[0].length );
5556 ok( !memcmp( dict2->strings[0].bytes, "mustUnderstand", 14 ), "wrong data\n" );
5558 WsFreeReader( reader );
5561 static HRESULT set_output( WS_XML_WRITER *writer )
5563 WS_XML_WRITER_TEXT_ENCODING text = {{WS_XML_WRITER_ENCODING_TYPE_TEXT}, WS_CHARSET_UTF8};
5564 WS_XML_WRITER_BUFFER_OUTPUT buf = {{WS_XML_WRITER_OUTPUT_TYPE_BUFFER}};
5565 return WsSetOutput( writer, &text.encoding, &buf.output, NULL, 0, NULL );
5568 static void check_output_buffer( WS_XML_BUFFER *buffer, const char *expected, unsigned int line )
5570 WS_XML_WRITER *writer;
5571 WS_BYTES bytes;
5572 ULONG size = sizeof(bytes);
5573 int len = strlen(expected);
5574 HRESULT hr;
5576 hr = WsCreateWriter( NULL, 0, &writer, NULL );
5577 ok( hr == S_OK, "got %08x\n", hr );
5579 hr = set_output( writer );
5580 ok( hr == S_OK, "got %08x\n", hr );
5582 hr = WsWriteXmlBuffer( writer, buffer, NULL );
5583 ok( hr == S_OK, "got %08x\n", hr );
5585 memset( &bytes, 0, sizeof(bytes) );
5586 hr = WsGetWriterProperty( writer, WS_XML_WRITER_PROPERTY_BYTES, &bytes, size, NULL );
5587 ok( hr == S_OK, "%u: got %08x\n", line, hr );
5588 ok( bytes.length == len, "%u: got %u expected %u\n", line, bytes.length, len );
5589 if (bytes.length != len) return;
5590 ok( !memcmp( bytes.bytes, expected, len ), "%u: got %s expected %s\n", line, bytes.bytes, expected );
5592 WsFreeWriter( writer );
5595 static HRESULT prepare_xml_buffer_test( WS_XML_READER *reader, WS_HEAP *heap )
5597 WS_XML_STRING localname = {1, (BYTE *)"t"}, localname2 = {1, (BYTE *)"u"}, ns = {0, NULL};
5598 WS_XML_WRITER *writer;
5599 WS_XML_BUFFER *buffer;
5600 HRESULT hr;
5602 hr = WsCreateWriter( NULL, 0, &writer, NULL );
5603 ok( hr == S_OK, "got %08x\n", hr );
5605 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
5606 ok( hr == S_OK, "got %08x\n", hr );
5608 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
5609 ok( hr == S_OK, "got %08x\n", hr );
5611 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
5612 ok( hr == S_OK, "got %08x\n", hr );
5613 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
5614 ok( hr == S_OK, "got %08x\n", hr );
5615 hr = WsWriteEndElement( writer, NULL );
5616 ok( hr == S_OK, "got %08x\n", hr );
5617 hr = WsWriteEndElement( writer, NULL );
5618 ok( hr == S_OK, "got %08x\n", hr );
5620 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
5621 ok( hr == S_OK, "got %08x\n", hr );
5622 WsFreeWriter( writer );
5623 return S_OK;
5626 static void test_WsReadXmlBuffer(void)
5628 const WS_XML_NODE *node;
5629 WS_XML_READER *reader;
5630 WS_XML_BUFFER *buffer;
5631 WS_HEAP *heap;
5632 HRESULT hr;
5634 hr = WsReadXmlBuffer( NULL, NULL, NULL, NULL );
5635 ok( hr == E_INVALIDARG, "got %08x\n", hr );
5637 hr = WsCreateReader( NULL, 0, &reader, NULL );
5638 ok( hr == S_OK, "got %08x\n", hr );
5640 hr = WsReadXmlBuffer( reader, NULL, NULL, NULL );
5641 ok( hr == E_INVALIDARG, "got %08x\n", hr );
5643 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
5644 ok( hr == S_OK, "got %08x\n", hr );
5646 hr = WsReadXmlBuffer( reader, heap, NULL, NULL );
5647 ok( hr == E_FAIL, "got %08x\n", hr );
5649 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
5650 todo_wine ok( hr == E_FAIL, "got %08x\n", hr );
5652 hr = set_input( reader, "<t><u><v/></u></t></w>", sizeof("<t><u><v/></u></t></w>") - 1 );
5653 ok( hr == S_OK, "got %08x\n", hr );
5655 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
5656 ok( hr == S_OK, "got %08x\n", hr );
5658 hr = WsReadStartElement( reader, NULL );
5659 ok( hr == S_OK, "got %08x\n", hr );
5661 hr = WsGetReaderNode( reader, &node, NULL );
5662 ok( hr == S_OK, "got %08x\n", hr );
5663 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5665 /* reader positioned at element */
5666 buffer = NULL;
5667 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
5668 ok( hr == S_OK, "got %08x\n", hr );
5669 ok( buffer != NULL, "buffer not set\n" );
5670 check_output_buffer( buffer, "<u><v/></u>", __LINE__ );
5672 hr = WsGetReaderNode( reader, &node, NULL );
5673 ok( hr == S_OK, "got %08x\n", hr );
5674 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5676 /* reader positioned at end element */
5677 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
5678 ok( hr == E_FAIL, "got %08x\n", hr );
5680 hr = set_input( reader, "<t><u/></t><v/>", sizeof("<t><u/></t><v/>") - 1 );
5681 ok( hr == S_OK, "got %08x\n", hr );
5683 hr = WsGetReaderNode( reader, &node, NULL );
5684 ok( hr == S_OK, "got %08x\n", hr );
5685 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
5687 /* reader positioned at BOF */
5688 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
5689 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
5691 hr = WsGetReaderNode( reader, &node, NULL );
5692 ok( hr == S_OK, "got %08x\n", hr );
5693 todo_wine ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5695 hr = set_input( reader, "<!--comment--><t></t>", sizeof("<!--comment--><t></t>") - 1 );
5696 ok( hr == S_OK, "got %08x\n", hr );
5698 hr = WsReadNode( reader, NULL );
5699 ok( hr == S_OK, "got %08x\n", hr );
5701 hr = WsGetReaderNode( reader, &node, NULL );
5702 ok( hr == S_OK, "got %08x\n", hr );
5703 ok( node->nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", node->nodeType );
5705 /* reader positioned at non-element */
5706 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
5707 ok( hr == E_FAIL, "got %08x\n", hr );
5709 hr = prepare_xml_buffer_test( reader, heap );
5710 ok( hr == S_OK, "got %08x\n", hr );
5712 hr = WsGetReaderNode( reader, &node, NULL );
5713 ok( hr == S_OK, "got %08x\n", hr );
5714 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
5716 /* reader positioned at BOF, input buffer */
5717 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
5718 ok( hr == S_OK, "got %08x\n", hr );
5719 check_output_buffer( buffer, "<t><u/></t>", __LINE__ );
5721 hr = WsGetReaderNode( reader, &node, NULL );
5722 ok( hr == S_OK, "got %08x\n", hr );
5723 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
5725 /* reader positioned at EOF, input buffer */
5726 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
5727 ok( hr == E_FAIL, "got %08x\n", hr );
5729 hr = prepare_xml_buffer_test( reader, heap );
5730 ok( hr == S_OK, "got %08x\n", hr );
5732 hr = WsReadNode( reader, NULL );
5733 ok( hr == S_OK, "got %08x\n", hr );
5734 hr = WsReadNode( reader, NULL );
5735 ok( hr == S_OK, "got %08x\n", hr );
5737 hr = WsGetReaderNode( reader, &node, NULL );
5738 ok( hr == S_OK, "got %08x\n", hr );
5739 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5741 /* reader positioned at element, input buffer */
5742 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
5743 ok( hr == S_OK, "got %08x\n", hr );
5744 check_output_buffer( buffer, "<u/>", __LINE__ );
5746 hr = WsGetReaderNode( reader, &node, NULL );
5747 ok( hr == S_OK, "got %08x\n", hr );
5748 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5750 /* reader positioned at end element, input buffer */
5751 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
5752 ok( hr == E_FAIL, "got %08x\n", hr );
5754 WsFreeReader( reader );
5755 WsFreeHeap( heap );
5758 static void test_union_type(void)
5760 static const WCHAR testW[] = {'t','e','s','t',0};
5761 static WS_XML_STRING str_ns = {0, NULL}, str_a = {1, (BYTE *)"a"}, str_b = {1, (BYTE *)"b"};
5762 static WS_XML_STRING str_s = {1, (BYTE *)"s"};
5763 HRESULT hr;
5764 WS_XML_READER *reader;
5765 WS_HEAP *heap;
5766 WS_UNION_DESCRIPTION u;
5767 WS_UNION_FIELD_DESCRIPTION f, f2, *fields[2];
5768 WS_FIELD_DESCRIPTION f_struct, *fields_struct[1];
5769 WS_STRUCT_DESCRIPTION s;
5770 const WS_XML_NODE *node;
5771 enum choice {CHOICE_A, CHOICE_B, CHOICE_NONE};
5772 struct test
5774 enum choice choice;
5775 union
5777 WCHAR *a;
5778 UINT32 b;
5779 } value;
5780 } *test;
5782 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
5783 ok( hr == S_OK, "got %08x\n", hr );
5785 hr = WsCreateReader( NULL, 0, &reader, NULL );
5786 ok( hr == S_OK, "got %08x\n", hr );
5788 memset( &f, 0, sizeof(f) );
5789 f.value = CHOICE_A;
5790 f.field.mapping = WS_ELEMENT_FIELD_MAPPING;
5791 f.field.localName = &str_a;
5792 f.field.ns = &str_ns;
5793 f.field.type = WS_WSZ_TYPE;
5794 f.field.offset = FIELD_OFFSET(struct test, value.a);
5795 fields[0] = &f;
5797 memset( &f2, 0, sizeof(f2) );
5798 f2.value = CHOICE_B;
5799 f2.field.mapping = WS_ELEMENT_FIELD_MAPPING;
5800 f2.field.localName = &str_b;
5801 f2.field.ns = &str_ns;
5802 f2.field.type = WS_UINT32_TYPE;
5803 f2.field.offset = FIELD_OFFSET(struct test, value.b);
5804 fields[1] = &f2;
5806 memset( &u, 0, sizeof(u) );
5807 u.size = sizeof(struct test);
5808 u.alignment = TYPE_ALIGNMENT(struct test);
5809 u.fields = fields;
5810 u.fieldCount = 2;
5811 u.enumOffset = FIELD_OFFSET(struct test, choice);
5812 u.noneEnumValue = CHOICE_NONE;
5814 memset( &f_struct, 0, sizeof(f_struct) );
5815 f_struct.mapping = WS_ELEMENT_CHOICE_FIELD_MAPPING;
5816 f_struct.type = WS_UNION_TYPE;
5817 f_struct.typeDescription = &u;
5818 fields_struct[0] = &f_struct;
5820 memset( &s, 0, sizeof(s) );
5821 s.size = sizeof(struct test);
5822 s.alignment = TYPE_ALIGNMENT(struct test);
5823 s.fields = fields_struct;
5824 s.fieldCount = 1;
5825 s.typeLocalName = &str_s;
5826 s.typeNs = &str_ns;
5828 test = NULL;
5829 prepare_struct_type_test( reader, "<a>test</a>" );
5830 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
5831 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
5832 ok( hr == S_OK, "got %08x\n", hr );
5833 ok( test != NULL, "test not set\n" );
5834 ok( test->choice == CHOICE_A, "got %d\n", test->choice );
5835 ok( !lstrcmpW(test->value.a, testW), "got %s\n", wine_dbgstr_w(test->value.a) );
5837 test = NULL;
5838 prepare_struct_type_test( reader, "<b>123</b>" );
5839 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
5840 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
5841 ok( hr == S_OK, "got %08x\n", hr );
5842 ok( test != NULL, "test not set\n" );
5843 ok( test->choice == CHOICE_B, "got %d\n", test->choice );
5844 ok( test->value.b == 123, "got %u\n", test->value.b );
5846 prepare_struct_type_test( reader, "<c>456</c>" );
5847 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
5848 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
5849 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
5851 f_struct.options = WS_FIELD_NILLABLE;
5852 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
5853 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
5854 ok( hr == E_INVALIDARG, "got %08x\n", hr );
5856 f_struct.options = WS_FIELD_POINTER|WS_FIELD_NILLABLE;
5857 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
5858 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
5859 ok( hr == E_INVALIDARG, "got %08x\n", hr );
5861 f_struct.options = WS_FIELD_POINTER;
5862 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
5863 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
5864 ok( hr == E_INVALIDARG, "got %08x\n", hr );
5866 test = NULL;
5867 f_struct.options = WS_FIELD_OPTIONAL;
5868 prepare_struct_type_test( reader, "<c>456</c>" );
5869 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
5870 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
5871 todo_wine ok( hr == S_OK, "got %08x\n", hr );
5872 ok( test != NULL, "test not set\n" );
5873 ok( test->choice == CHOICE_NONE, "got %d\n", test->choice );
5874 hr = WsGetReaderNode( reader, &node, NULL );
5875 ok( hr == S_OK, "got %08x\n", hr );
5876 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5878 WsFreeReader( reader );
5879 WsFreeHeap( heap );
5882 START_TEST(reader)
5884 test_WsCreateError();
5885 test_WsCreateHeap();
5886 test_WsCreateReader();
5887 test_WsSetInput();
5888 test_WsSetInputToBuffer();
5889 test_WsFillReader();
5890 test_WsReadToStartElement();
5891 test_WsReadStartElement();
5892 test_WsReadEndElement();
5893 test_WsReadNode();
5894 test_WsReadType();
5895 test_WsGetXmlAttribute();
5896 test_WsXmlStringEquals();
5897 test_WsAlloc();
5898 test_WsMoveReader();
5899 test_simple_struct_type();
5900 test_cdata();
5901 test_WsFindAttribute();
5902 test_WsGetNamespaceFromPrefix();
5903 test_text_field_mapping();
5904 test_complex_struct_type();
5905 test_repeating_element();
5906 test_WsResetHeap();
5907 test_datetime();
5908 test_WsDateTimeToFileTime();
5909 test_WsFileTimeToDateTime();
5910 test_double();
5911 test_WsReadElement();
5912 test_WsReadValue();
5913 test_WsResetError();
5914 test_WsGetReaderPosition();
5915 test_WsSetReaderPosition();
5916 test_entities();
5917 test_field_options();
5918 test_WsReadBytes();
5919 test_WsReadChars();
5920 test_WsReadCharsUtf8();
5921 test_WsReadQualifiedName();
5922 test_WsReadAttribute();
5923 test_WsSkipNode();
5924 test_binary_encoding();
5925 test_dictionary();
5926 test_WsReadXmlBuffer();
5927 test_union_type();