webservices: Implement WsGetDictionary.
[wine.git] / dlls / webservices / tests / reader.c
blob87f593f63053a965444954d257680c46dedfe8d5
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 char data1[] =
26 "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
28 static const char data2[] =
29 {0xef,0xbb,0xbf,'<','t','e','x','t','>','t','e','s','t','<','/','t','e','x','t','>',0};
31 static const char data3[] =
32 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
33 "<text>test</TEXT>";
35 static const char data4[] =
36 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
37 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">\r\n"
38 " <o:services o:GenerationTime=\"2015-09-03T18:47:54\">\r\n"
39 " <!--Build: 16.0.6202.6852-->\r\n"
40 " <o:default>\r\n"
41 " <o:ticket o:headerName=\"Authorization\" o:headerValue=\"{}\" />\r\n"
42 " </o:default>\r\n"
43 " <o:service o:name=\"LiveOAuthLoginStart\">\r\n"
44 " <o:url>https://login.[Live.WebHost]/oauth20_authorize.srf</o:url>\r\n"
45 " </o:service>\r\n"
46 "</o:services>\r\n"
47 "</o:OfficeConfig>\r\n";
49 static const char data5[] =
50 "</text>";
52 static const char data6[] =
53 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
54 "<text attr= \"value\" attr2='value2'>test</text>";
56 static const char data7[] =
57 "<!-- comment -->";
59 static const char data8[] =
60 "<node1><node2>test</node2></node1>";
62 static const char data9[] =
63 "<text xml:attr=\"value\">test</text>";
65 static const char data10[] =
66 "<a></b>";
68 static const char data11[] =
69 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
70 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\">"
71 "<!--Build: 16.0.6202.6852-->"
72 "</o:services>"
73 "</o:OfficeConfig>";
75 static const char data11b[] =
76 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
77 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\"></o:services>"
78 "<trailing>content</trailing>"
79 "</o:OfficeConfig>";
81 static const char data12[] =
82 "<services>"
83 "<service><id>1</id></service>"
84 "<service><id>2</id></service>"
85 "</services>";
87 static const char data13[] =
88 "<services></services>";
90 static const char data14[] =
91 "<services>"
92 "<wrapper>"
93 "<service><id>1</id></service>"
94 "<service><id>2</id></service>"
95 "</wrapper>"
96 "</services>";
98 static const char data15[] =
99 "<services>"
100 "<wrapper>"
101 "<service>1</service>"
102 "<service>2</service>"
103 "</wrapper>"
104 "</services>";
106 static const char data16[] =
107 "<services>"
108 "<wrapper>"
109 "<service name='1'>1</service>"
110 "<service name='2'>2</service>"
111 "</wrapper>"
112 "</services>";
114 static void test_WsCreateError(void)
116 HRESULT hr;
117 WS_ERROR *error;
118 WS_ERROR_PROPERTY prop;
119 ULONG size, code, count;
120 LANGID langid;
122 hr = WsCreateError( NULL, 0, NULL );
123 ok( hr == E_INVALIDARG, "got %08x\n", hr );
125 error = NULL;
126 hr = WsCreateError( NULL, 0, &error );
127 ok( hr == S_OK, "got %08x\n", hr );
128 ok( error != NULL, "error not set\n" );
130 count = 0xdeadbeef;
131 size = sizeof(count);
132 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
133 ok( hr == S_OK, "got %08x\n", hr );
134 ok( !count, "got %u\n", count );
136 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
137 ok( hr == E_INVALIDARG, "got %08x\n", hr );
139 code = 0xdeadbeef;
140 size = sizeof(code);
141 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
142 ok( hr == S_OK, "got %08x\n", hr );
143 ok( !code, "got %u\n", code );
145 code = 0xdeadbeef;
146 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
147 ok( hr == S_OK, "got %08x\n", hr );
148 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
149 ok( hr == S_OK, "got %08x\n", hr );
150 ok( code == 0xdeadbeef, "got %u\n", code );
152 langid = 0xdead;
153 size = sizeof(langid);
154 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
155 ok( hr == S_OK, "got %08x\n", hr );
156 ok( langid == GetUserDefaultUILanguage(), "got %u\n", langid );
158 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
159 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
160 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
162 count = 0xdeadbeef;
163 size = sizeof(count);
164 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID + 1, &count, size );
165 ok( hr == E_INVALIDARG, "got %08x\n", hr );
166 ok( count == 0xdeadbeef, "got %u\n", count );
167 WsFreeError( error );
169 count = 1;
170 prop.id = WS_ERROR_PROPERTY_STRING_COUNT;
171 prop.value = &count;
172 prop.valueSize = sizeof(count);
173 hr = WsCreateError( &prop, 1, &error );
174 ok( hr == E_INVALIDARG, "got %08x\n", hr );
176 code = 0xdeadbeef;
177 prop.id = WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE;
178 prop.value = &code;
179 prop.valueSize = sizeof(code);
180 hr = WsCreateError( &prop, 1, &error );
181 ok( hr == E_INVALIDARG, "got %08x\n", hr );
183 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
184 prop.id = WS_ERROR_PROPERTY_LANGID;
185 prop.value = &langid;
186 prop.valueSize = sizeof(langid);
187 hr = WsCreateError( &prop, 1, &error );
188 ok( hr == S_OK, "got %08x\n", hr );
190 langid = 0xdead;
191 size = sizeof(langid);
192 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
193 ok( hr == S_OK, "got %08x\n", hr );
194 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
195 WsFreeError( error );
197 count = 0xdeadbeef;
198 prop.id = WS_ERROR_PROPERTY_LANGID + 1;
199 prop.value = &count;
200 prop.valueSize = sizeof(count);
201 hr = WsCreateError( &prop, 1, &error );
202 ok( hr == E_INVALIDARG, "got %08x\n", hr );
205 static void test_WsCreateHeap(void)
207 HRESULT hr;
208 WS_HEAP *heap;
209 WS_HEAP_PROPERTY prop;
210 SIZE_T max, trim, requested, actual;
211 ULONG size;
213 hr = WsCreateHeap( 0, 0, NULL, 0, NULL, NULL );
214 ok( hr == E_INVALIDARG, "got %08x\n", hr );
216 heap = NULL;
217 hr = WsCreateHeap( 0, 0, NULL, 0, &heap, NULL );
218 ok( hr == S_OK, "got %08x\n", hr );
219 ok( heap != NULL, "heap not set\n" );
220 WsFreeHeap( heap );
222 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, NULL, NULL );
223 ok( hr == E_INVALIDARG, "got %08x\n", hr );
225 heap = NULL;
226 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
227 ok( hr == S_OK, "got %08x\n", hr );
228 ok( heap != NULL, "heap not set\n" );
229 WsFreeHeap( heap );
231 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, &heap, NULL );
232 ok( hr == S_OK, "got %08x\n", hr );
234 max = 0xdeadbeef;
235 size = sizeof(max);
236 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_MAX_SIZE, &max, size, NULL );
237 ok( hr == S_OK, "got %08x\n", hr );
238 ok( max == 1 << 16, "got %u\n", (ULONG)max );
240 trim = 0xdeadbeef;
241 size = sizeof(trim);
242 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_TRIM_SIZE, &trim, size, NULL );
243 ok( hr == S_OK, "got %08x\n", hr );
244 ok( trim == 1 << 6, "got %u\n", (ULONG)trim );
246 requested = 0xdeadbeef;
247 size = sizeof(requested);
248 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
249 ok( hr == S_OK, "got %08x\n", hr );
250 ok( !requested, "got %u\n", (ULONG)requested );
252 actual = 0xdeadbeef;
253 size = sizeof(actual);
254 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
255 ok( hr == S_OK, "got %08x\n", hr );
256 ok( !actual, "got %u\n", (ULONG)actual );
258 actual = 0xdeadbeef;
259 size = sizeof(actual);
260 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE + 1, &actual, size, NULL );
261 ok( hr == E_INVALIDARG, "got %08x\n", hr );
262 ok( actual == 0xdeadbeef, "got %u\n", (ULONG)actual );
263 WsFreeHeap( heap );
265 max = 1 << 16;
266 prop.id = WS_HEAP_PROPERTY_MAX_SIZE;
267 prop.value = &max;
268 prop.valueSize = sizeof(max);
269 hr = WsCreateHeap( 1 << 16, 1 << 6, &prop, 1, &heap, NULL );
270 ok( hr == E_INVALIDARG, "got %08x\n", hr );
272 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 1, &heap, NULL );
273 ok( hr == E_INVALIDARG, "got %08x\n", hr );
276 static HRESULT set_input( WS_XML_READER *reader, const char *data, ULONG size )
278 WS_XML_READER_TEXT_ENCODING text = {{WS_XML_READER_ENCODING_TYPE_TEXT}, WS_CHARSET_AUTO};
279 WS_XML_READER_BUFFER_INPUT buf;
281 buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
282 buf.encodedData = (void *)data;
283 buf.encodedDataSize = size;
284 return WsSetInput( reader, &text.encoding, &buf.input, NULL, 0, NULL );
287 static void test_WsCreateReader(void)
289 HRESULT hr;
290 WS_XML_READER *reader;
291 WS_XML_READER_PROPERTY prop;
292 ULONG size, max_depth, max_attrs, trim_size, buffer_size, max_ns;
293 BOOL allow_fragment, read_decl, in_attr;
294 ULONGLONG row, column;
295 WS_CHARSET charset;
297 hr = WsCreateReader( NULL, 0, NULL, NULL );
298 ok( hr == E_INVALIDARG, "got %08x\n", hr );
300 reader = NULL;
301 hr = WsCreateReader( NULL, 0, &reader, NULL );
302 ok( hr == S_OK, "got %08x\n", hr );
303 ok( reader != NULL, "reader not set\n" );
305 /* can't retrieve properties before input is set */
306 max_depth = 0xdeadbeef;
307 size = sizeof(max_depth);
308 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
309 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
310 ok( max_depth == 0xdeadbeef, "max_depth set\n" );
312 hr = set_input( reader, data1, sizeof(data1) - 1 );
313 ok( hr == S_OK, "got %08x\n", hr );
315 /* check some defaults */
316 max_depth = 0xdeadbeef;
317 size = sizeof(max_depth);
318 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
319 ok( hr == S_OK, "got %08x\n", hr );
320 ok( max_depth == 32, "got %u\n", max_depth );
322 allow_fragment = TRUE;
323 size = sizeof(allow_fragment);
324 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_ALLOW_FRAGMENT, &allow_fragment, size, NULL );
325 ok( hr == S_OK, "got %08x\n", hr );
326 ok( !allow_fragment, "got %d\n", allow_fragment );
328 max_attrs = 0xdeadbeef;
329 size = sizeof(max_attrs);
330 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES, &max_attrs, size, NULL );
331 ok( hr == S_OK, "got %08x\n", hr );
332 ok( max_attrs == 128, "got %u\n", max_attrs );
334 read_decl = FALSE;
335 size = sizeof(read_decl);
336 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_READ_DECLARATION, &read_decl, size, NULL );
337 ok( hr == S_OK, "got %08x\n", hr );
338 ok( read_decl, "got %u\n", read_decl );
340 charset = 0xdeadbeef;
341 size = sizeof(charset);
342 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
343 ok( hr == S_OK, "got %08x\n", hr );
344 ok( charset == WS_CHARSET_UTF8, "got %u\n", charset );
346 size = sizeof(trim_size);
347 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_UTF8_TRIM_SIZE, &trim_size, size, NULL );
348 todo_wine ok( hr == E_INVALIDARG, "got %08x\n", hr );
349 WsFreeReader( reader );
351 hr = WsCreateReader( NULL, 0, &reader, NULL );
352 ok( hr == S_OK, "got %08x\n", hr );
354 hr = set_input( reader, data1, sizeof(data1) - 1 );
355 ok( hr == S_OK, "got %08x\n", hr );
357 size = sizeof(buffer_size);
358 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_STREAM_BUFFER_SIZE, &buffer_size, size, NULL );
359 todo_wine ok( hr == E_INVALIDARG, "got %08x\n", hr );
360 WsFreeReader( reader );
362 hr = WsCreateReader( NULL, 0, &reader, NULL );
363 ok( hr == S_OK, "got %08x\n", hr );
365 hr = set_input( reader, data1, sizeof(data1) - 1 );
366 ok( hr == S_OK, "got %08x\n", hr );
368 max_ns = 0xdeadbeef;
369 size = sizeof(max_ns);
370 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_NAMESPACES, &max_ns, size, NULL );
371 ok( hr == S_OK, "got %08x\n", hr );
372 ok( max_ns == 32, "got %u\n", max_ns );
373 WsFreeReader( reader );
375 /* change a property */
376 max_depth = 16;
377 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
378 prop.value = &max_depth;
379 prop.valueSize = sizeof(max_depth);
380 hr = WsCreateReader( &prop, 1, &reader, NULL );
381 ok( hr == S_OK, "got %08x\n", hr );
383 hr = set_input( reader, data1, sizeof(data1) - 1 );
384 ok( hr == S_OK, "got %08x\n", hr );
386 max_depth = 0xdeadbeef;
387 size = sizeof(max_depth);
388 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
389 ok( hr == S_OK, "got %08x\n", hr );
390 ok( max_depth == 16, "got %u\n", max_depth );
391 WsFreeReader( reader );
393 /* show that some properties are read-only */
394 row = 1;
395 prop.id = WS_XML_READER_PROPERTY_ROW;
396 prop.value = &row;
397 prop.valueSize = sizeof(row);
398 hr = WsCreateReader( &prop, 1, &reader, NULL );
399 ok( hr == E_INVALIDARG, "got %08x\n", hr );
401 column = 1;
402 prop.id = WS_XML_READER_PROPERTY_COLUMN;
403 prop.value = &column;
404 prop.valueSize = sizeof(column);
405 hr = WsCreateReader( &prop, 1, &reader, NULL );
406 ok( hr == E_INVALIDARG, "got %08x\n", hr );
408 in_attr = TRUE;
409 prop.id = WS_XML_READER_PROPERTY_IN_ATTRIBUTE;
410 prop.value = &in_attr;
411 prop.valueSize = sizeof(in_attr);
412 hr = WsCreateReader( &prop, 1, &reader, NULL );
413 ok( hr == E_INVALIDARG, "got %08x\n", hr );
416 static void test_WsSetInput(void)
418 static char test1[] = {0xef,0xbb,0xbf,'<','a','/','>'};
419 static char test2[] = {'<','a','/','>'};
420 static char test3[] = {'<','!','-','-'};
421 static char test4[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"',
422 ' ','e','n','c','o','d','i','n','g','=','"','u','t','f','-','8','"','?','>'};
423 static char test5[] = {'<','?','x','m','l',' ','e','n','c','o','d','i','n','g','=',
424 '"','u','t','f','-','8','"','?','>'};
425 static char test6[] = {'<','?','x','m','l'};
426 static char test7[] = {'<','?','y','m','l'};
427 static char test8[] = {'<','?'};
428 static char test9[] = {'<','!'};
429 static char test10[] = {0xff,0xfe,'<',0,'a',0,'/',0,'>',0};
430 static char test11[] = {'<',0,'a',0,'/',0,'>',0};
431 static char test12[] = {'<',0,'!',0,'-',0,'-',0};
432 static char test13[] = {'<',0,'?',0};
433 static char test14[] = {'a','b'};
434 static char test15[] = {'a','b','c'};
435 static char test16[] = {'a',0};
436 static char test17[] = {'a',0,'b',0};
437 static char test18[] = {'<',0,'a',0,'b',0};
438 static char test19[] = {'<',0,'a',0};
439 static char test20[] = {0,'a','b'};
440 static char test21[] = {0,0};
441 static char test22[] = {0,0,0};
442 static char test23[] = {'<',0,'?',0,'x',0,'m',0,'l',0};
443 static char test24[] = {'<',0,'a',0,'>',0,'b',0,'<',0,'/',0,'>',0};
444 HRESULT hr;
445 WS_XML_READER *reader;
446 WS_XML_READER_PROPERTY prop;
447 WS_XML_READER_TEXT_ENCODING enc;
448 WS_XML_READER_BUFFER_INPUT input;
449 WS_XML_TEXT_NODE *text;
450 WS_XML_UTF8_TEXT *utf8;
451 WS_CHARSET charset;
452 const WS_XML_NODE *node;
453 ULONG i, size, max_depth;
454 BOOL found;
455 static const struct
457 void *data;
458 ULONG size;
459 HRESULT hr;
460 WS_CHARSET charset;
461 int todo;
463 tests[] =
465 { test1, sizeof(test1), S_OK, WS_CHARSET_UTF8 },
466 { test2, sizeof(test2), S_OK, WS_CHARSET_UTF8 },
467 { test3, sizeof(test3), S_OK, WS_CHARSET_UTF8 },
468 { test4, sizeof(test4), S_OK, WS_CHARSET_UTF8 },
469 { test5, sizeof(test5), WS_E_INVALID_FORMAT, 0, 1 },
470 { test6, sizeof(test6), WS_E_INVALID_FORMAT, 0, 1 },
471 { test7, sizeof(test7), WS_E_INVALID_FORMAT, 0, 1 },
472 { test8, sizeof(test8), WS_E_INVALID_FORMAT, 0 },
473 { test9, sizeof(test9), WS_E_INVALID_FORMAT, 0 },
474 { test10, sizeof(test10), S_OK, WS_CHARSET_UTF16LE },
475 { test11, sizeof(test11), S_OK, WS_CHARSET_UTF16LE },
476 { test12, sizeof(test12), S_OK, WS_CHARSET_UTF16LE },
477 { test13, sizeof(test13), WS_E_INVALID_FORMAT, 0, 1 },
478 { test14, sizeof(test14), WS_E_INVALID_FORMAT, 0 },
479 { test15, sizeof(test15), S_OK, WS_CHARSET_UTF8 },
480 { test16, sizeof(test16), WS_E_INVALID_FORMAT, 0 },
481 { test17, sizeof(test17), S_OK, WS_CHARSET_UTF8 },
482 { test18, sizeof(test18), S_OK, WS_CHARSET_UTF16LE },
483 { test19, sizeof(test19), S_OK, WS_CHARSET_UTF16LE },
484 { test20, sizeof(test20), S_OK, WS_CHARSET_UTF8 },
485 { test21, sizeof(test21), WS_E_INVALID_FORMAT, 0 },
486 { test22, sizeof(test22), S_OK, WS_CHARSET_UTF8 },
487 { test23, sizeof(test23), WS_E_INVALID_FORMAT, 0, 1 },
490 hr = WsCreateReader( NULL, 0, &reader, NULL );
491 ok( hr == S_OK, "got %08x\n", hr );
493 hr = WsSetInput( NULL, NULL, NULL, NULL, 0, NULL );
494 ok( hr == E_INVALIDARG, "got %08x\n", hr );
496 node = NULL;
497 hr = WsGetReaderNode( reader, &node, NULL );
498 ok( hr == S_OK, "got %08x\n", hr );
499 ok( node != NULL, "node not set\n" );
500 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
502 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
503 enc.charSet = WS_CHARSET_UTF8;
505 input.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
506 input.encodedData = (void *)data1;
507 input.encodedDataSize = sizeof(data1) - 1;
509 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
510 ok( hr == S_OK, "got %08x\n", hr );
512 node = NULL;
513 hr = WsGetReaderNode( reader, &node, NULL );
514 ok( hr == S_OK, "got %08x\n", hr );
515 ok( node != NULL, "node not set\n" );
516 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
518 /* multiple calls are allowed */
519 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
520 ok( hr == S_OK, "got %08x\n", hr );
522 /* charset is detected by WsSetInput */
523 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
524 enc.charSet = WS_CHARSET_AUTO;
526 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
528 input.encodedData = tests[i].data;
529 input.encodedDataSize = tests[i].size;
530 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
531 ok( hr == S_OK, "%u: got %08x\n", i, hr );
533 charset = 0xdeadbeef;
534 size = sizeof(charset);
535 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
536 todo_wine_if (tests[i].todo)
538 ok( hr == tests[i].hr, "%u: got %08x expected %08x\n", i, hr, tests[i].hr );
539 if (hr == S_OK)
540 ok( charset == tests[i].charset, "%u: got %u expected %u\n", i, charset, tests[i].charset );
544 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
545 enc.charSet = WS_CHARSET_UTF8;
547 /* reader properties can be set with WsSetInput */
548 max_depth = 16;
549 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
550 prop.value = &max_depth;
551 prop.valueSize = sizeof(max_depth);
552 hr = WsSetInput( reader, &enc.encoding, &input.input, &prop, 1, NULL );
553 ok( hr == S_OK, "got %08x\n", hr );
555 max_depth = 0xdeadbeef;
556 size = sizeof(max_depth);
557 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
558 ok( hr == S_OK, "got %08x\n", hr );
559 ok( max_depth == 16, "got %u\n", max_depth );
561 /* show that the reader converts text to UTF-8 */
562 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
563 enc.charSet = WS_CHARSET_UTF16LE;
564 input.encodedData = (void *)test24;
565 input.encodedDataSize = sizeof(test24);
566 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
567 ok( hr == S_OK, "got %08x\n", hr );
569 found = -1;
570 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
571 todo_wine ok( hr == S_OK, "got %08x\n", hr );
572 if (hr == S_OK)
574 ok( found == TRUE, "got %d\n", found );
576 hr = WsReadStartElement( reader, NULL );
577 ok( hr == S_OK, "got %08x\n", hr );
579 hr = WsGetReaderNode( reader, &node, NULL );
580 ok( hr == S_OK, "got %08x\n", hr );
581 text = (WS_XML_TEXT_NODE *)node;
582 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
583 ok( text->text != NULL, "text not set\n" );
584 utf8 = (WS_XML_UTF8_TEXT *)text->text;
585 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
586 ok( utf8->value.length == 1, "got %u\n", utf8->value.length );
587 ok( utf8->value.bytes[0] == 'b', "wrong data\n" );
589 WsFreeReader( reader );
592 static void test_WsSetInputToBuffer(void)
594 HRESULT hr;
595 WS_HEAP *heap;
596 WS_XML_BUFFER *buffer;
597 WS_XML_READER *reader;
598 WS_XML_READER_PROPERTY prop;
599 const WS_XML_NODE *node;
600 ULONG size, max_depth;
602 hr = WsCreateReader( NULL, 0, &reader, NULL );
603 ok( hr == S_OK, "got %08x\n", hr );
605 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
606 ok( hr == S_OK, "got %08x\n", hr );
608 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
609 ok( hr == S_OK, "got %08x\n", hr );
611 hr = WsSetInputToBuffer( NULL, NULL, NULL, 0, NULL );
612 ok( hr == E_INVALIDARG, "got %08x\n", hr );
614 hr = WsSetInputToBuffer( reader, NULL, NULL, 0, NULL );
615 ok( hr == E_INVALIDARG, "got %08x\n", hr );
617 node = NULL;
618 hr = WsGetReaderNode( reader, &node, NULL );
619 ok( hr == S_OK, "got %08x\n", hr );
620 ok( node != NULL, "node not set\n" );
621 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
623 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
624 ok( hr == S_OK, "got %08x\n", hr );
626 node = NULL;
627 hr = WsGetReaderNode( reader, &node, NULL );
628 ok( hr == S_OK, "got %08x\n", hr );
629 ok( node != NULL, "node not set\n" );
630 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
632 /* multiple calls are allowed */
633 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
634 ok( hr == S_OK, "got %08x\n", hr );
636 /* reader properties can be set with WsSetInputToBuffer */
637 max_depth = 16;
638 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
639 prop.value = &max_depth;
640 prop.valueSize = sizeof(max_depth);
641 hr = WsSetInputToBuffer( reader, buffer, &prop, 1, NULL );
642 ok( hr == S_OK, "got %08x\n", hr );
644 max_depth = 0xdeadbeef;
645 size = sizeof(max_depth);
646 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
647 ok( hr == S_OK, "got %08x\n", hr );
648 ok( max_depth == 16, "got %u\n", max_depth );
650 WsFreeReader( reader );
651 WsFreeHeap( heap );
654 static void test_WsFillReader(void)
656 HRESULT hr;
657 WS_XML_READER *reader;
658 const WS_XML_NODE *node;
660 /* what happens of we don't call WsFillReader? */
661 hr = WsCreateReader( NULL, 0, &reader, NULL );
662 ok( hr == S_OK, "got %08x\n", hr );
664 node = NULL;
665 hr = WsGetReaderNode( reader, &node, NULL );
666 ok( hr == S_OK, "got %08x\n", hr );
667 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
669 hr = set_input( reader, data1, sizeof(data1) - 1 );
670 ok( hr == S_OK, "got %08x\n", hr );
672 node = NULL;
673 hr = WsGetReaderNode( reader, &node, NULL );
674 ok( hr == S_OK, "got %08x\n", hr );
675 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
677 hr = WsReadNode( reader, NULL );
678 ok( hr == S_OK, "got %08x\n", hr );
680 node = NULL;
681 hr = WsGetReaderNode( reader, &node, NULL );
682 ok( hr == S_OK, "got %08x\n", hr );
683 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
684 WsFreeReader( reader );
686 hr = WsCreateReader( NULL, 0, &reader, NULL );
687 ok( hr == S_OK, "got %08x\n", hr );
689 hr = set_input( reader, data1, sizeof(data1) - 1 );
690 ok( hr == S_OK, "got %08x\n", hr );
692 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
693 ok( hr == S_OK, "got %08x\n", hr );
695 hr = set_input( reader, data1, sizeof(data1) - 1 );
696 ok( hr == S_OK, "got %08x\n", hr );
698 node = NULL;
699 hr = WsGetReaderNode( reader, &node, NULL );
700 ok( hr == S_OK, "got %08x\n", hr );
701 ok( node != NULL, "node not set\n" );
702 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
704 hr = WsFillReader( NULL, sizeof(data1) - 1, NULL, NULL );
705 ok( hr == E_INVALIDARG, "got %08x\n", hr );
707 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
708 ok( hr == S_OK, "got %08x\n", hr );
710 node = NULL;
711 hr = WsGetReaderNode( reader, &node, NULL );
712 ok( hr == S_OK, "got %08x\n", hr );
713 ok( node != NULL, "node not set\n" );
714 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
716 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
717 ok( hr == S_OK, "got %08x\n", hr );
719 /* min_size larger than input size */
720 hr = WsFillReader( reader, sizeof(data1), NULL, NULL );
721 ok( hr == S_OK, "got %08x\n", hr );
722 WsFreeReader( reader );
725 static void test_WsReadToStartElement(void)
727 HRESULT hr;
728 WS_XML_READER *reader;
729 const WS_XML_NODE *node, *node2;
730 int found;
732 hr = WsCreateReader( NULL, 0, &reader, NULL );
733 ok( hr == S_OK, "got %08x\n", hr );
735 hr = set_input( reader, data1, sizeof(data1) - 1 );
736 ok( hr == S_OK, "got %08x\n", hr );
738 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
739 ok( hr == S_OK, "got %08x\n", hr );
741 hr = WsGetReaderNode( reader, &node, NULL );
742 ok( hr == S_OK, "got %08x\n", hr );
743 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
745 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
746 ok( hr == S_OK, "got %08x\n", hr );
748 hr = WsReadToStartElement( NULL, NULL, NULL, NULL, NULL );
749 ok( hr == E_INVALIDARG, "got %08x\n", hr );
751 found = -1;
752 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
753 ok( hr == S_OK, "got %08x\n", hr );
754 ok( found == FALSE, "got %d\n", found );
756 hr = WsGetReaderNode( reader, &node, NULL );
757 ok( hr == S_OK, "got %08x\n", hr );
758 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
760 hr = set_input( reader, data2, sizeof(data2) - 1 );
761 ok( hr == S_OK, "got %08x\n", hr );
763 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
764 ok( hr == S_OK, "got %08x\n", hr );
766 hr = WsGetReaderNode( reader, &node, NULL );
767 ok( hr == S_OK, "got %08x\n", hr );
768 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
770 found = -1;
771 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
772 ok( hr == S_OK, "got %08x\n", hr );
773 ok( found == TRUE, "got %d\n", found );
775 hr = WsGetReaderNode( reader, &node, NULL );
776 ok( hr == S_OK, "got %08x\n", hr );
777 if (node)
779 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
781 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
782 ok( elem->prefix != NULL, "prefix not set\n" );
783 if (elem->prefix)
785 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
787 ok( elem->localName != NULL, "localName not set\n" );
788 if (elem->localName)
790 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
791 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
793 ok( elem->ns != NULL, "ns not set\n" );
794 if (elem->ns)
796 ok( !elem->ns->length, "got %u\n", elem->ns->length );
798 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
799 ok( elem->attributes == NULL, "attributes set\n" );
800 ok( !elem->isEmpty, "isEmpty not zero\n" );
803 found = -1;
804 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
805 ok( hr == S_OK, "got %08x\n", hr );
806 ok( found == TRUE, "got %d\n", found );
808 node2 = NULL;
809 hr = WsGetReaderNode( reader, &node2, NULL );
810 ok( hr == S_OK, "got %08x\n", hr );
811 ok( node2 == node, "different node\n" );
813 hr = set_input( reader, data3, sizeof(data3) - 1 );
814 ok( hr == S_OK, "got %08x\n", hr );
816 hr = WsFillReader( reader, sizeof(data3) - 1, NULL, NULL );
817 ok( hr == S_OK, "got %08x\n", hr );
819 found = -1;
820 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
821 ok( hr == S_OK, "got %08x\n", hr );
822 ok( found == TRUE, "got %d\n", found );
824 hr = WsGetReaderNode( reader, &node, NULL );
825 ok( hr == S_OK, "got %08x\n", hr );
826 if (node)
828 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
830 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
831 ok( elem->localName != NULL, "localName not set\n" );
832 if (elem->localName)
834 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
835 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
839 hr = set_input( reader, data4, sizeof(data4) - 1 );
840 ok( hr == S_OK, "got %08x\n", hr );
842 hr = WsFillReader( reader, sizeof(data4) - 1, NULL, NULL );
843 ok( hr == S_OK, "got %08x\n", hr );
845 found = -1;
846 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
847 ok( hr == S_OK, "got %08x\n", hr );
848 ok( found == TRUE, "got %d\n", found );
849 WsFreeReader( reader );
852 static void test_WsReadStartElement(void)
854 HRESULT hr;
855 WS_XML_READER *reader;
856 const WS_XML_NODE *node, *node2;
857 int found;
859 hr = WsCreateReader( NULL, 0, &reader, NULL );
860 ok( hr == S_OK, "got %08x\n", hr );
862 hr = set_input( reader, data2, sizeof(data2) - 1 );
863 ok( hr == S_OK, "got %08x\n", hr );
865 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
866 ok( hr == S_OK, "got %08x\n", hr );
868 found = -1;
869 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
870 ok( hr == S_OK, "got %08x\n", hr );
871 ok( found == TRUE, "got %d\n", found );
873 hr = WsReadStartElement( NULL, NULL );
874 ok( hr == E_INVALIDARG, "got %08x\n", hr );
876 hr = WsGetReaderNode( reader, &node, NULL );
877 ok( hr == S_OK, "got %08x\n", hr );
878 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
880 hr = WsReadStartElement( reader, NULL );
881 ok( hr == S_OK, "got %08x\n", hr );
883 hr = WsGetReaderNode( reader, &node, NULL );
884 ok( hr == S_OK, "got %08x\n", hr );
885 if (node)
887 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
888 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
889 ok( text->text != NULL, "text not set\n" );
890 if (text->text)
892 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
893 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
894 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
895 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong data\n" );
899 hr = WsReadStartElement( reader, NULL );
900 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
902 node2 = NULL;
903 hr = WsGetReaderNode( reader, &node2, NULL );
904 ok( hr == S_OK, "got %08x\n", hr );
905 ok( node2 == node, "different node\n" );
907 hr = set_input( reader, data8, sizeof(data8) - 1 );
908 ok( hr == S_OK, "got %08x\n", hr );
910 hr = WsFillReader( reader, sizeof(data8) - 1, NULL, NULL );
911 ok( hr == S_OK, "got %08x\n", hr );
913 found = -1;
914 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
915 ok( hr == S_OK, "got %08x\n", hr );
916 ok( found == TRUE, "got %d\n", found );
918 hr = WsGetReaderNode( reader, &node, NULL );
919 ok( hr == S_OK, "got %08x\n", hr );
920 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
922 hr = WsGetReaderNode( reader, &node, NULL );
923 ok( hr == S_OK, "got %08x\n", hr );
924 if (node)
926 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
927 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
928 ok( !memcmp( elem->localName->bytes, "node1", 5), "wrong name\n" );
931 hr = WsReadStartElement( reader, NULL );
932 ok( hr == S_OK, "got %08x\n", hr );
934 hr = WsGetReaderNode( reader, &node, NULL );
935 ok( hr == S_OK, "got %08x\n", hr );
936 if (node)
938 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
939 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
940 ok( !memcmp( elem->localName->bytes, "node2", 5), "wrong name\n" );
943 hr = WsReadNode( reader, NULL );
944 ok( hr == S_OK, "got %08x\n", hr );
946 hr = WsGetReaderNode( reader, &node, NULL );
947 ok( hr == S_OK, "got %08x\n", hr );
948 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
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_END_ELEMENT, "got %u\n", node->nodeType );
957 hr = WsReadEndElement( 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 /* WsReadEndElement advances reader to EOF */
965 hr = WsReadEndElement( reader, NULL );
966 ok( hr == S_OK, "got %08x\n", hr );
968 hr = WsGetReaderNode( reader, &node, NULL );
969 ok( hr == S_OK, "got %08x\n", hr );
970 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
972 hr = WsReadEndElement( reader, NULL );
973 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
975 WsFreeReader( reader );
978 static void test_WsReadEndElement(void)
980 HRESULT hr;
981 WS_XML_READER *reader;
982 const WS_XML_NODE *node;
983 int found;
985 hr = WsCreateReader( NULL, 0, &reader, NULL );
986 ok( hr == S_OK, "got %08x\n", hr );
988 hr = set_input( reader, data2, sizeof(data2) - 1 );
989 ok( hr == S_OK, "got %08x\n", hr );
991 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
992 ok( hr == S_OK, "got %08x\n", hr );
994 hr = WsReadEndElement( reader, NULL );
995 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
997 hr = set_input( reader, data2, sizeof(data2) - 1 );
998 ok( hr == S_OK, "got %08x\n", hr );
1000 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
1001 ok( hr == S_OK, "got %08x\n", hr );
1003 hr = WsReadNode( reader, NULL );
1004 ok( hr == S_OK, "got %08x\n", hr );
1006 hr = WsGetReaderNode( reader, &node, NULL );
1007 ok( hr == S_OK, "got %08x\n", hr );
1008 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
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_TEXT, "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_END_ELEMENT, "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_EOF, "got %u\n", node->nodeType );
1031 hr = set_input( reader, data2, sizeof(data2) - 1 );
1032 ok( hr == S_OK, "got %08x\n", hr );
1034 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
1035 ok( hr == S_OK, "got %08x\n", hr );
1037 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1038 ok( hr == S_OK, "got %08x\n", hr );
1040 hr = WsReadStartElement( reader, NULL );
1041 ok( hr == S_OK, "got %08x\n", hr );
1043 hr = WsGetReaderNode( reader, &node, NULL );
1044 ok( hr == S_OK, "got %08x\n", hr );
1045 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
1047 hr = WsReadNode( 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_END_ELEMENT, "got %u\n", node->nodeType );
1054 /* WsReadEndElement advances reader to EOF */
1055 hr = WsReadEndElement( reader, NULL );
1056 ok( hr == S_OK, "got %08x\n", hr );
1058 hr = WsGetReaderNode( reader, &node, NULL );
1059 ok( hr == S_OK, "got %08x\n", hr );
1060 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1062 hr = WsReadEndElement( reader, NULL );
1063 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1065 hr = set_input( reader, data5, sizeof(data5) - 1 );
1066 ok( hr == S_OK, "got %08x\n", hr );
1068 hr = WsFillReader( reader, sizeof(data5) - 1, NULL, NULL );
1069 ok( hr == S_OK, "got %08x\n", hr );
1071 hr = WsReadEndElement( reader, NULL );
1072 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1074 hr = set_input( reader, data10, sizeof(data10) - 1 );
1075 ok( hr == S_OK, "got %08x\n", hr );
1077 hr = WsFillReader( reader, sizeof(data10) - 1, NULL, NULL );
1078 ok( hr == S_OK, "got %08x\n", hr );
1080 hr = WsReadNode( reader, NULL );
1081 ok( hr == S_OK, "got %08x\n", hr );
1083 hr = WsGetReaderNode( reader, &node, NULL );
1084 ok( hr == S_OK, "got %08x\n", hr );
1085 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1087 hr = WsReadEndElement( reader, NULL );
1088 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1090 hr = set_input( reader, "<a></A>", sizeof("<a></A>") - 1 );
1091 ok( hr == S_OK, "got %08x\n", hr );
1093 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1094 ok( hr == S_OK, "got %08x\n", hr );
1096 found = -1;
1097 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1098 ok( hr == S_OK, "got %08x\n", hr );
1099 ok( found == TRUE, "got %d\n", found );
1101 hr = WsGetReaderNode( reader, &node, NULL );
1102 ok( hr == S_OK, "got %08x\n", hr );
1103 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1105 hr = WsReadEndElement( reader, NULL );
1106 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1108 hr = set_input( reader, "<a></a>", sizeof("<a></a>") - 1 );
1109 ok( hr == S_OK, "got %08x\n", hr );
1111 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1112 ok( hr == S_OK, "got %08x\n", hr );
1114 found = -1;
1115 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1116 ok( hr == S_OK, "got %08x\n", hr );
1117 ok( found == TRUE, "got %d\n", found );
1119 hr = WsGetReaderNode( reader, &node, NULL );
1120 ok( hr == S_OK, "got %08x\n", hr );
1121 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1123 hr = WsReadStartElement( reader, NULL );
1124 ok( hr == S_OK, "got %08x\n", hr );
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_END_ELEMENT, "got %u\n", node->nodeType );
1130 hr = WsReadEndElement( 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_EOF, "got %u\n", node->nodeType );
1137 hr = set_input( reader, "<a/>", sizeof("<a/>") - 1 );
1138 ok( hr == S_OK, "got %08x\n", hr );
1140 hr = WsFillReader( reader, sizeof("<a/>") - 1, NULL, NULL );
1141 ok( hr == S_OK, "got %08x\n", hr );
1143 found = -1;
1144 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1145 ok( hr == S_OK, "got %08x\n", hr );
1146 ok( found == TRUE, "got %d\n", found );
1148 hr = WsGetReaderNode( reader, &node, NULL );
1149 ok( hr == S_OK, "got %08x\n", hr );
1150 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1152 hr = WsReadStartElement( reader, NULL );
1153 ok( hr == S_OK, "got %08x\n", hr );
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_END_ELEMENT, "got %u\n", node->nodeType );
1159 hr = WsReadEndElement( reader, NULL );
1160 ok( hr == S_OK, "got %08x\n", hr );
1162 WsFreeReader( reader );
1165 static void test_WsReadNode(void)
1167 static const char str1[] = "<a>";
1168 static const char str2[] = "< a>";
1169 static const char str3[] = "<a >";
1170 static const char str4[] = "<<a>>";
1171 static const char str5[] = "<>";
1172 static const char str6[] = "</a>";
1173 static const char str7[] = " <a>";
1174 static const char str8[] = "<?xml>";
1175 static const char str9[] = "<?xml?>";
1176 static const char str10[] = "<?xml ?>";
1177 static const char str11[] = "<?xml version=\"1.0\"?>";
1178 static const char str12[] = "<text>test</text>";
1179 static const char str13[] = "<?xml version=\"1.0\"?><text>test</text>";
1180 static const char str14[] = "";
1181 static const char str15[] = "<!--";
1182 static const char str16[] = "<!---->";
1183 static const char str17[] = "<!--comment-->";
1184 HRESULT hr;
1185 WS_XML_READER *reader;
1186 WS_XML_DICTIONARY *dict;
1187 const WS_XML_NODE *node;
1188 unsigned int i;
1189 int found;
1190 static const struct
1192 const char *text;
1193 HRESULT hr;
1194 WS_XML_NODE_TYPE type;
1195 int todo;
1197 tests[] =
1199 { str1, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1200 { str2, WS_E_INVALID_FORMAT, 0 },
1201 { str3, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1202 { str4, WS_E_INVALID_FORMAT, 0 },
1203 { str5, WS_E_INVALID_FORMAT, 0 },
1204 { str6, WS_E_INVALID_FORMAT, 0 },
1205 { str7, S_OK, WS_XML_NODE_TYPE_TEXT },
1206 { str8, WS_E_INVALID_FORMAT, 0 },
1207 { str9, WS_E_INVALID_FORMAT, 0 },
1208 { str10, WS_E_INVALID_FORMAT, 0, 1 },
1209 { str11, S_OK, WS_XML_NODE_TYPE_EOF },
1210 { str12, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1211 { str13, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1212 { str14, WS_E_INVALID_FORMAT, 0, 1 },
1213 { str15, WS_E_INVALID_FORMAT, 0 },
1214 { str16, S_OK, WS_XML_NODE_TYPE_COMMENT },
1215 { str17, S_OK, WS_XML_NODE_TYPE_COMMENT },
1218 hr = WsCreateReader( NULL, 0, &reader, NULL );
1219 ok( hr == S_OK, "got %08x\n", hr );
1221 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
1223 hr = set_input( reader, tests[i].text, strlen(tests[i].text) );
1224 ok( hr == S_OK, "got %08x\n", hr );
1226 hr = WsFillReader( reader, strlen(tests[i].text), NULL, NULL );
1227 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1229 hr = WsReadNode( reader, NULL );
1230 todo_wine_if (tests[i].todo)
1231 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
1232 if (hr == S_OK)
1234 node = NULL;
1235 hr = WsGetReaderNode( reader, &node, NULL );
1236 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1237 ok( node != NULL, "%u: node not set\n", i );
1238 if (node)
1240 todo_wine_if (tests[i].todo)
1241 ok( node->nodeType == tests[i].type, "%u: got %u\n", i, node->nodeType );
1246 hr = set_input( reader, data6, sizeof(data6) - 1 );
1247 ok( hr == S_OK, "got %08x\n", hr );
1249 hr = WsFillReader( reader, sizeof(data6) - 1, NULL, NULL );
1250 ok( hr == S_OK, "got %08x\n", hr );
1252 found = -1;
1253 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1254 ok( hr == S_OK, "got %08x\n", hr );
1255 ok( found == TRUE, "got %d\n", found );
1257 hr = WsGetReaderNode( reader, &node, NULL );
1258 ok( hr == S_OK, "got %08x\n", hr );
1259 if (node)
1261 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
1262 WS_XML_ATTRIBUTE *attr;
1263 WS_XML_UTF8_TEXT *text;
1265 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1266 ok( elem->prefix != NULL, "prefix not set\n" );
1267 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
1268 ok( elem->prefix->bytes == NULL, "bytes set\n" );
1269 ok( elem->localName != NULL, "localName not set\n" );
1270 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
1271 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
1272 ok( elem->ns != NULL, "ns not set\n" );
1273 ok( !elem->ns->length, "got %u\n", elem->ns->length );
1274 ok( elem->ns->bytes != NULL, "bytes not set\n" );
1275 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
1276 ok( elem->attributes != NULL, "attributes not set\n" );
1277 ok( !elem->isEmpty, "isEmpty not zero\n" );
1279 attr = elem->attributes[0];
1280 ok( !attr->singleQuote, "got %u\n", attr->singleQuote );
1281 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1282 ok( attr->prefix != NULL, "prefix not set\n" );
1283 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1284 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1285 ok( attr->localName != NULL, "localName not set\n" );
1286 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
1287 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
1288 ok( attr->ns != NULL, "ns not set\n" );
1289 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1290 ok( attr->ns->bytes == NULL, "bytes set\n" );
1291 ok( attr->value != NULL, "value not set\n" );
1293 text = (WS_XML_UTF8_TEXT *)attr->value;
1294 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1295 ok( text->value.length == 5, "got %u\n", text->value.length );
1296 ok( !memcmp( text->value.bytes, "value", 5 ), "wrong data\n" );
1298 attr = elem->attributes[1];
1299 ok( attr->singleQuote == 1, "got %u\n", attr->singleQuote );
1300 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1301 ok( attr->prefix != NULL, "prefix not set\n" );
1302 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1303 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1304 ok( attr->localName != NULL, "localName not set\n" );
1305 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
1306 ok( !memcmp( attr->localName->bytes, "attr2", 5 ), "wrong data\n" );
1307 ok( attr->ns != NULL, "ns not set\n" );
1308 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1309 ok( attr->ns->bytes == NULL, "bytes set\n" );
1310 ok( attr->value != NULL, "value not set\n" );
1312 text = (WS_XML_UTF8_TEXT *)attr->value;
1313 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1314 ok( text->value.length == 6, "got %u\n", text->value.length );
1315 ok( !memcmp( text->value.bytes, "value2", 6 ), "wrong data\n" );
1318 hr = set_input( reader, data7, sizeof(data7) - 1 );
1319 ok( hr == S_OK, "got %08x\n", hr );
1321 hr = WsFillReader( reader, sizeof(data7) - 1, NULL, NULL );
1322 ok( hr == S_OK, "got %08x\n", hr );
1324 hr = WsReadNode( reader, NULL );
1325 ok( hr == S_OK, "got %08x\n", hr );
1327 hr = WsGetReaderNode( reader, &node, NULL );
1328 ok( hr == S_OK, "got %08x\n", hr );
1329 if (node)
1331 WS_XML_COMMENT_NODE *comment = (WS_XML_COMMENT_NODE *)node;
1333 ok( comment->node.nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", comment->node.nodeType );
1334 ok( comment->value.length == 9, "got %u\n", comment->value.length );
1335 ok( !memcmp( comment->value.bytes, " comment ", 9 ), "wrong data\n" );
1338 dict = (WS_XML_DICTIONARY *)0xdeadbeef;
1339 hr = WsGetDictionary( WS_ENCODING_XML_UTF8, &dict, NULL );
1340 ok( hr == S_OK, "got %08x\n", hr );
1341 ok( dict == NULL, "got %p\n", dict );
1343 dict = (WS_XML_DICTIONARY *)0xdeadbeef;
1344 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_1, &dict, NULL );
1345 ok( hr == S_OK, "got %08x\n", hr );
1346 ok( dict != NULL, "dict not set\n" );
1348 dict = (WS_XML_DICTIONARY *)0xdeadbeef;
1349 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_SESSION_1, &dict, NULL );
1350 ok( hr == S_OK, "got %08x\n", hr );
1351 ok( dict != NULL, "dict not set\n" );
1353 WsFreeReader( reader );
1356 static void prepare_type_test( WS_XML_READER *reader, const char *data, ULONG size )
1358 HRESULT hr;
1360 hr = set_input( reader, data, size );
1361 ok( hr == S_OK, "got %08x\n", hr );
1363 hr = WsFillReader( reader, size, NULL, NULL );
1364 ok( hr == S_OK, "got %08x\n", hr );
1366 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1367 ok( hr == S_OK, "got %08x\n", hr );
1369 hr = WsReadStartElement( reader, NULL );
1370 ok( hr == S_OK, "got %08x\n", hr );
1373 static void test_WsReadType(void)
1375 static const WCHAR testW[] = {'t','e','s','t',0};
1376 static const GUID guid1 = {0,0,0,{0,0,0,0,0,0,0,0}};
1377 static const GUID guid2 = {0,0,0,{0,0,0,0,0,0,0,0xa1}};
1378 static const char utf8[] = {'<','t','>',0xe2,0x80,0x99,'<','/','t','>'};
1379 static const WCHAR utf8W[] = {0x2019,0};
1380 HRESULT hr;
1381 WS_XML_READER *reader;
1382 WS_HEAP *heap;
1383 enum { ONE = 1, TWO = 2 };
1384 WS_XML_STRING one = { 3, (BYTE *)"ONE" };
1385 WS_XML_STRING two = { 3, (BYTE *)"TWO" };
1386 WS_ENUM_VALUE enum_values[] = { { ONE, &one }, { TWO, &two } };
1387 WS_ENUM_DESCRIPTION enum_desc;
1388 int val_enum;
1389 WCHAR *val_str;
1390 BOOL val_bool;
1391 INT8 val_int8;
1392 INT16 val_int16;
1393 INT32 val_int32;
1394 INT64 val_int64;
1395 UINT8 val_uint8;
1396 UINT16 val_uint16;
1397 UINT32 val_uint32;
1398 UINT64 val_uint64;
1399 GUID val_guid;
1400 WS_BYTES val_bytes;
1402 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1403 ok( hr == S_OK, "got %08x\n", hr );
1405 hr = WsCreateReader( NULL, 0, &reader, NULL );
1406 ok( hr == S_OK, "got %08x\n", hr );
1408 prepare_type_test( reader, data2, sizeof(data2) - 1 );
1409 hr = WsReadType( NULL, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1410 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1411 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1413 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1414 WS_READ_REQUIRED_POINTER, heap, &val_str, 0, NULL );
1415 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1417 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1418 WS_READ_REQUIRED_POINTER, heap, NULL, sizeof(val_str), NULL );
1419 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1421 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1422 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str) + 1, NULL );
1423 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1425 val_str = NULL;
1426 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1427 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1428 ok( hr == S_OK, "got %08x\n", hr );
1429 ok( val_str != NULL, "pointer not set\n" );
1430 if (val_str) ok( !lstrcmpW( val_str, testW ), "wrong data\n" );
1432 val_bool = -1;
1433 prepare_type_test( reader, "<t>true</t>", sizeof("<t>true</t>") - 1 );
1434 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1435 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1436 ok( hr == S_OK, "got %08x\n", hr );
1437 ok( val_bool == TRUE, "got %d\n", val_bool );
1439 val_bool = -1;
1440 prepare_type_test( reader, "<t>false</t>", sizeof("<t>false</t>") - 1 );
1441 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1442 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1443 ok( hr == S_OK, "got %08x\n", hr );
1444 ok( val_bool == FALSE, "got %d\n", val_bool );
1446 val_bool = -1;
1447 prepare_type_test( reader, "<t>FALSE</t>", sizeof("<t>FALSE</t>") - 1 );
1448 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1449 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1450 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1451 ok( val_bool == -1, "got %d\n", val_bool );
1453 val_bool = -1;
1454 prepare_type_test( reader, "<t>1</t>", sizeof("<t>1</t>") - 1 );
1455 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1456 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1457 ok( hr == S_OK, "got %08x\n", hr );
1458 ok( val_bool == TRUE, "got %d\n", val_bool );
1460 val_bool = -1;
1461 prepare_type_test( reader, "<t>2</t>", sizeof("<t>2</t>") - 1 );
1462 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1463 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1464 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1465 ok( val_bool == -1, "got %d\n", val_bool );
1467 val_bool = -1;
1468 prepare_type_test( reader, "<t>0</t>", sizeof("<t>0</t>") - 1 );
1469 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1470 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1471 ok( hr == S_OK, "got %08x\n", hr );
1472 ok( val_bool == FALSE, "got %d\n", val_bool );
1474 val_int8 = 0;
1475 prepare_type_test( reader, "<t>-128</t>", sizeof("<t>-128</t>") - 1 );
1476 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1477 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1478 ok( hr == S_OK, "got %08x\n", hr );
1479 ok( val_int8 == -128, "got %d\n", val_int8 );
1481 val_int8 = 0;
1482 prepare_type_test( reader, "<t> </t>", sizeof("<t> </t>") - 1 );
1483 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1484 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1485 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1486 ok( !val_int8, "got %d\n", val_int8 );
1488 val_int8 = 0;
1489 prepare_type_test( reader, "<t>-</t>", sizeof("<t>-</t>") - 1 );
1490 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1491 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1492 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1493 ok( !val_int8, "got %d\n", val_int8 );
1495 val_int8 = -1;
1496 prepare_type_test( reader, "<t>-0</t>", sizeof("<t>-0</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 == S_OK, "got %08x\n", hr );
1500 ok( !val_int8, "got %d\n", val_int8 );
1502 val_int8 = 0;
1503 prepare_type_test( reader, "<t>-129</t>", sizeof("<t>-129</t>") - 1 );
1504 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1505 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1506 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1507 ok( !val_int8, "got %d\n", val_int8 );
1509 val_int16 = 0;
1510 prepare_type_test( reader, "<t>-32768</t>", sizeof("<t>-32768</t>") - 1 );
1511 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1512 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1513 ok( hr == S_OK, "got %08x\n", hr );
1514 ok( val_int16 == -32768, "got %d\n", val_int16 );
1516 val_int16 = 0;
1517 prepare_type_test( reader, "<t>-32769</t>", sizeof("<t>-32769</t>") - 1 );
1518 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1519 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1520 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1521 ok( !val_int16, "got %d\n", val_int16 );
1523 val_int32 = 0;
1524 prepare_type_test( reader, "<t>-2147483648</t>", sizeof("<t>-2147483648</t>") - 1 );
1525 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1526 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1527 ok( hr == S_OK, "got %08x\n", hr );
1528 ok( val_int32 == -2147483647 - 1, "got %d\n", val_int32 );
1530 val_int32 = 0;
1531 prepare_type_test( reader, "<t>-2147483649</t>", sizeof("<t>-2147483649</t>") - 1 );
1532 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1533 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1534 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1535 ok( !val_int32, "got %d\n", val_int32 );
1537 val_int64 = 0;
1538 prepare_type_test( reader, "<t>-9223372036854775808</t>", sizeof("<t>-9223372036854775808</t>") - 1 );
1539 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1540 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1541 ok( hr == S_OK, "got %08x\n", hr );
1542 ok( val_int64 == -9223372036854775807 - 1, "wrong value\n" );
1544 val_int64 = 0;
1545 prepare_type_test( reader, "<t>-9223372036854775809</t>", sizeof("<t>-9223372036854775809</t>") - 1 );
1546 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1547 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1548 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1549 ok( !val_int64, "wrong value\n" );
1551 val_uint8 = 0;
1552 prepare_type_test( reader, "<t> 255 </t>", sizeof("<t> 255 </t>") - 1 );
1553 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1554 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1555 ok( hr == S_OK, "got %08x\n", hr );
1556 ok( val_uint8 == 255, "got %u\n", val_uint8 );
1558 val_uint8 = 0;
1559 prepare_type_test( reader, "<t>+255</t>", sizeof("<t>+255</t>") - 1 );
1560 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1561 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1562 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1563 ok( !val_uint8, "got %u\n", val_uint8 );
1565 val_uint8 = 0;
1566 prepare_type_test( reader, "<t>-255</t>", sizeof("<t>-255</t>") - 1 );
1567 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1568 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1569 todo_wine ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1570 ok( !val_uint8, "got %u\n", val_uint8 );
1572 val_uint8 = 0;
1573 prepare_type_test( reader, "<t>0xff</t>", sizeof("<t>0xff</t>") - 1 );
1574 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1575 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1576 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1577 ok( !val_uint8, "got %u\n", val_uint8 );
1579 val_uint8 = 0;
1580 prepare_type_test( reader, "<t>256</t>", sizeof("<t>256</t>") - 1 );
1581 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1582 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1583 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1584 ok( !val_uint8, "got %u\n", val_uint8 );
1586 val_uint16 = 0;
1587 prepare_type_test( reader, "<t>65535</t>", sizeof("<t>65535</t>") - 1 );
1588 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1589 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1590 ok( hr == S_OK, "got %08x\n", hr );
1591 ok( val_uint16 == 65535, "got %u\n", val_uint16 );
1593 val_uint16 = 0;
1594 prepare_type_test( reader, "<t>65536</t>", sizeof("<t>65536</t>") - 1 );
1595 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1596 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1597 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1598 ok( !val_uint16, "got %u\n", val_uint16 );
1600 val_uint32 = 0;
1601 prepare_type_test( reader, "<t>4294967295</t>", sizeof("<t>4294967295</t>") - 1 );
1602 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1603 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1604 ok( hr == S_OK, "got %08x\n", hr );
1605 ok( val_uint32 == ~0, "got %u\n", val_uint32 );
1607 val_uint32 = 0;
1608 prepare_type_test( reader, "<t>4294967296</t>", sizeof("<t>4294967296</t>") - 1 );
1609 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1610 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1611 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1612 ok( !val_uint32, "got %u\n", val_uint32 );
1614 val_uint64 = 0;
1615 prepare_type_test( reader, "<t>18446744073709551615</t>", sizeof("<t>18446744073709551615</t>") - 1 );
1616 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1617 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1618 ok( hr == S_OK, "got %08x\n", hr );
1619 ok( val_uint64 == ~0, "wrong value\n" );
1621 val_uint64 = 0;
1622 prepare_type_test( reader, "<t>18446744073709551616</t>", sizeof("<t>18446744073709551616</t>") - 1 );
1623 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1624 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1625 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1626 ok( !val_uint64, "wrong value\n" );
1628 enum_desc.values = enum_values;
1629 enum_desc.valueCount = sizeof(enum_values)/sizeof(enum_values[0]);
1630 enum_desc.maxByteCount = 3;
1631 enum_desc.nameIndices = NULL;
1633 val_enum = 0;
1634 prepare_type_test( reader, "<t>ONE</t>", sizeof("<t>ONE</t>") - 1 );
1635 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1636 WS_READ_REQUIRED_VALUE, heap, &val_enum, sizeof(val_enum), NULL );
1637 ok( hr == S_OK, "got %08x\n", hr );
1638 ok( val_enum == 1, "got %d\n", val_enum );
1640 prepare_type_test( reader, "<t>{00000000-0000-0000-0000-000000000000}</t>",
1641 sizeof("<t>{00000000-0000-0000-0000-000000000000}</t>") - 1 );
1642 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1643 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1644 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1646 memset( &val_guid, 0xff, sizeof(val_guid) );
1647 prepare_type_test( reader, "<t> 00000000-0000-0000-0000-000000000000 </t>",
1648 sizeof("<t> 00000000-0000-0000-0000-000000000000 </t>") - 1 );
1649 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1650 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1651 ok( hr == S_OK, "got %08x\n", hr );
1652 ok( IsEqualGUID( &val_guid, &guid1 ), "wrong guid\n" );
1654 memset( &val_guid, 0, sizeof(val_guid) );
1655 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000a1</t>",
1656 sizeof("<t>00000000-0000-0000-0000-0000000000a1</t>") - 1 );
1657 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1658 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1659 ok( hr == S_OK, "got %08x\n", hr );
1660 ok( IsEqualGUID( &val_guid, &guid2 ), "wrong guid\n" );
1662 memset( &val_guid, 0, sizeof(val_guid) );
1663 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000A1</t>",
1664 sizeof("<t>00000000-0000-0000-0000-0000000000A1</t>") - 1 );
1665 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1666 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1667 ok( hr == S_OK, "got %08x\n", hr );
1668 ok( IsEqualGUID( &val_guid, &guid2 ), "wrong guid\n" );
1670 memset( &val_bytes, 0, sizeof(val_bytes) );
1671 prepare_type_test( reader, "<t>dGVzdA==</t>", sizeof("<t>dGVzdA==</t>") - 1 );
1672 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1673 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1674 ok( hr == S_OK, "got %08x\n", hr );
1675 ok( val_bytes.length == 4, "got %u\n", val_bytes.length );
1676 ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" );
1678 memset( &val_bytes, 0, sizeof(val_bytes) );
1679 prepare_type_test( reader, "<t> dGVzdA== </t>", sizeof("<t> dGVzdA== </t>") - 1 );
1680 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1681 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1682 ok( hr == S_OK, "got %08x\n", hr );
1683 ok( val_bytes.length == 4, "got %u\n", val_bytes.length );
1684 ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" );
1686 prepare_type_test( reader, "<t>dGVzdA===</t>", sizeof("<t>dGVzdA===</t>") - 1 );
1687 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1688 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1689 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1691 val_str = NULL;
1692 prepare_type_test( reader, utf8, sizeof(utf8) );
1693 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1694 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1695 ok( hr == S_OK, "got %08x\n", hr );
1696 ok( val_str != NULL, "pointer not set\n" );
1697 if (val_str) ok( !lstrcmpW( val_str, utf8W ), "wrong data %s\n", wine_dbgstr_w(val_str) );
1699 WsFreeReader( reader );
1700 WsFreeHeap( heap );
1703 static void test_WsGetXmlAttribute(void)
1705 static const WCHAR valueW[] = {'v','a','l','u','e',0};
1706 HRESULT hr;
1707 WS_XML_READER *reader;
1708 WS_XML_STRING xmlstr;
1709 WS_HEAP *heap;
1710 WCHAR *str;
1711 ULONG count;
1712 int found;
1714 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1715 ok( hr == S_OK, "got %08x\n", hr );
1717 hr = WsCreateReader( NULL, 0, &reader, NULL );
1718 ok( hr == S_OK, "got %08x\n", hr );
1720 hr = set_input( reader, data9, sizeof(data9) - 1 );
1721 ok( hr == S_OK, "got %08x\n", hr );
1723 hr = WsFillReader( reader, sizeof(data9) - 1, NULL, NULL );
1724 ok( hr == S_OK, "got %08x\n", hr );
1726 found = -1;
1727 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1728 ok( hr == S_OK, "got %08x\n", hr );
1729 ok( found == TRUE, "got %d\n", found );
1731 xmlstr.bytes = (BYTE *)"attr";
1732 xmlstr.length = sizeof("attr") - 1;
1733 xmlstr.dictionary = NULL;
1734 xmlstr.id = 0;
1735 str = NULL;
1736 count = 0;
1737 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1738 todo_wine ok( hr == S_OK, "got %08x\n", hr );
1739 todo_wine ok( str != NULL, "str not set\n" );
1740 todo_wine ok( count == 5, "got %u\n", count );
1741 /* string is not null-terminated */
1742 if (str) ok( !memcmp( str, valueW, count * sizeof(WCHAR) ), "wrong data\n" );
1744 xmlstr.bytes = (BYTE *)"none";
1745 xmlstr.length = sizeof("none") - 1;
1746 xmlstr.dictionary = NULL;
1747 xmlstr.id = 0;
1748 str = (WCHAR *)0xdeadbeef;
1749 count = 0xdeadbeef;
1750 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1751 todo_wine ok( hr == S_FALSE, "got %08x\n", hr );
1752 todo_wine ok( str == NULL, "str not set\n" );
1753 todo_wine ok( !count, "got %u\n", count );
1755 WsFreeReader( reader );
1756 WsFreeHeap( heap );
1759 static void test_WsXmlStringEquals(void)
1761 BYTE bom[] = {0xef,0xbb,0xbf};
1762 WS_XML_STRING str1 = {0, NULL}, str2 = {0, NULL};
1763 HRESULT hr;
1765 hr = WsXmlStringEquals( NULL, NULL, NULL );
1766 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1768 hr = WsXmlStringEquals( &str1, NULL, NULL );
1769 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1771 hr = WsXmlStringEquals( NULL, &str2, NULL );
1772 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1774 hr = WsXmlStringEquals( &str1, &str2, NULL );
1775 ok( hr == S_OK, "got %08x\n", hr );
1777 str1.length = 1;
1778 str1.bytes = (BYTE *)"a";
1779 hr = WsXmlStringEquals( &str1, &str1, NULL );
1780 ok( hr == S_OK, "got %08x\n", hr );
1782 str2.length = 1;
1783 str2.bytes = (BYTE *)"b";
1784 hr = WsXmlStringEquals( &str1, &str2, NULL );
1785 ok( hr == S_FALSE, "got %08x\n", hr );
1787 str2.length = 1;
1788 str2.bytes = bom;
1789 hr = WsXmlStringEquals( &str1, &str2, NULL );
1790 ok( hr == S_FALSE, "got %08x\n", hr );
1792 str1.length = 3;
1793 hr = WsXmlStringEquals( &str1, &str2, NULL );
1794 ok( hr == S_FALSE, "got %08x\n", hr );
1796 str2.length = 3;
1797 hr = WsXmlStringEquals( &str1, &str2, NULL );
1798 ok( hr == S_FALSE, "got %08x\n", hr );
1800 str1.length = 3;
1801 str1.bytes = bom;
1802 hr = WsXmlStringEquals( &str1, &str2, NULL );
1803 ok( hr == S_OK, "got %08x\n", hr );
1806 static void test_WsAlloc(void)
1808 HRESULT hr;
1809 WS_HEAP *heap;
1810 void *ptr;
1811 SIZE_T requested, actual;
1812 ULONG size;
1814 hr = WsCreateHeap( 256, 0, NULL, 0, &heap, NULL );
1815 ok( hr == S_OK, "got %08x\n", hr );
1817 ptr = (void *)0xdeadbeef;
1818 hr = WsAlloc( NULL, 16, &ptr, NULL );
1819 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1820 ok( ptr == (void *)0xdeadbeef, "ptr set\n" );
1822 ptr = (void *)0xdeadbeef;
1823 hr = WsAlloc( heap, 512, &ptr, NULL );
1824 ok( hr == WS_E_QUOTA_EXCEEDED, "got %08x\n", hr );
1825 ok( ptr == (void *)0xdeadbeef, "ptr set\n" );
1827 ptr = NULL;
1828 hr = WsAlloc( heap, 16, &ptr, NULL );
1829 ok( hr == S_OK, "got %08x\n", hr );
1830 ok( ptr != NULL, "ptr not set\n" );
1832 requested = 0xdeadbeef;
1833 size = sizeof(requested);
1834 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
1835 ok( hr == S_OK, "got %08x\n", hr );
1836 ok( requested == 16, "got %u\n", (ULONG)requested );
1838 actual = 0xdeadbeef;
1839 size = sizeof(actual);
1840 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
1841 ok( hr == S_OK, "got %08x\n", hr );
1842 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
1844 WsFreeHeap( heap );
1847 static void test_WsMoveReader(void)
1849 HRESULT hr;
1850 WS_HEAP *heap;
1851 WS_XML_READER *reader;
1852 WS_XML_WRITER *writer;
1853 WS_XML_BUFFER *buffer;
1854 WS_XML_STRING localname = {1, (BYTE *)"a"}, localname2 = {1, (BYTE *)"b"}, ns = {0, NULL};
1855 const WS_XML_NODE *node;
1856 WS_XML_ELEMENT_NODE *elem;
1857 WS_XML_UTF8_TEXT utf8;
1859 hr = WsCreateReader( NULL, 0, &reader, NULL );
1860 ok( hr == S_OK, "got %08x\n", hr );
1862 hr = WsMoveReader( NULL, WS_MOVE_TO_EOF, NULL, NULL );
1863 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1865 /* reader must be set to an XML buffer */
1866 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1867 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1869 hr = set_input( reader, data8, sizeof(data8) - 1 );
1870 ok( hr == S_OK, "got %08x\n", hr );
1872 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1873 todo_wine ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1874 WsFreeReader( reader );
1876 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1877 ok( hr == S_OK, "got %08x\n", hr );
1879 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
1880 ok( hr == S_OK, "got %08x\n", hr );
1882 hr = WsCreateWriter( NULL, 0, &writer, NULL );
1883 ok( hr == S_OK, "got %08x\n", hr );
1885 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
1886 ok( hr == S_OK, "got %08x\n", hr );
1888 /* <a><b/></a> */
1889 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
1890 ok( hr == S_OK, "got %08x\n", hr );
1892 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
1893 ok( hr == S_OK, "got %08x\n", hr );
1895 hr = WsWriteEndElement( writer, NULL );
1896 ok( hr == S_OK, "got %08x\n", hr );
1898 hr = WsWriteEndElement( writer, NULL );
1899 ok( hr == S_OK, "got %08x\n", hr );
1901 hr = WsCreateReader( NULL, 0, &reader, NULL );
1902 ok( hr == S_OK, "got %08x\n", hr );
1904 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1905 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1907 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
1908 ok( hr == S_OK, "got %08x\n", hr );
1910 /* first element is child node of BOF node */
1911 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
1912 ok( hr == S_OK, "got %08x\n", hr );
1914 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1915 ok( hr == S_OK, "got %08x\n", hr );
1917 hr = WsGetReaderNode( reader, &node, NULL );
1918 ok( hr == S_OK, "got %08x\n", hr );
1919 elem = (WS_XML_ELEMENT_NODE *)node;
1920 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1921 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1922 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1924 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1925 ok( hr == S_OK, "got %08x\n", hr );
1927 hr = WsGetReaderNode( reader, &node, NULL );
1928 ok( hr == S_OK, "got %08x\n", hr );
1929 elem = (WS_XML_ELEMENT_NODE *)node;
1930 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1931 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1932 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1934 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1935 ok( hr == S_OK, "got %08x\n", hr );
1937 hr = WsGetReaderNode( reader, &node, NULL );
1938 ok( hr == S_OK, "got %08x\n", hr );
1939 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1941 /* EOF node is last child of BOF node */
1942 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
1943 ok( hr == S_OK, "got %08x\n", hr );
1945 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1946 ok( hr == S_OK, "got %08x\n", hr );
1948 hr = WsGetReaderNode( reader, &node, NULL );
1949 ok( hr == S_OK, "got %08x\n", hr );
1950 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1952 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1953 ok( hr == S_OK, "got %08x\n", hr );
1955 hr = WsGetReaderNode( reader, &node, NULL );
1956 ok( hr == S_OK, "got %08x\n", hr );
1957 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1959 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
1960 ok( hr == S_OK, "got %08x\n", hr );
1962 hr = WsGetReaderNode( reader, &node, NULL );
1963 ok( hr == S_OK, "got %08x\n", hr );
1964 elem = (WS_XML_ELEMENT_NODE *)node;
1965 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1966 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1967 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1969 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_ELEMENT, NULL, NULL );
1970 ok( hr == S_OK, "got %08x\n", hr );
1972 hr = WsGetReaderNode( reader, &node, NULL );
1973 ok( hr == S_OK, "got %08x\n", hr );
1974 elem = (WS_XML_ELEMENT_NODE *)node;
1975 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1976 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1977 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1979 hr = WsMoveReader( reader, WS_MOVE_TO_END_ELEMENT, NULL, NULL );
1980 ok( hr == S_OK, "got %08x\n", hr );
1982 hr = WsGetReaderNode( reader, &node, NULL );
1983 ok( hr == S_OK, "got %08x\n", hr );
1984 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1986 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1987 ok( hr == S_OK, "got %08x\n", hr );
1989 hr = WsGetReaderNode( reader, &node, NULL );
1990 ok( hr == S_OK, "got %08x\n", hr );
1991 elem = (WS_XML_ELEMENT_NODE *)node;
1992 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1993 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1994 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1996 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1997 ok( hr == S_OK, "got %08x\n", hr );
1999 hr = WsGetReaderNode( reader, &node, NULL );
2000 ok( hr == S_OK, "got %08x\n", hr );
2001 elem = (WS_XML_ELEMENT_NODE *)node;
2002 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2003 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2004 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
2006 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2007 ok( hr == S_OK, "got %08x\n", hr );
2009 hr = WsGetReaderNode( reader, &node, NULL );
2010 ok( hr == S_OK, "got %08x\n", hr );
2011 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
2013 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2014 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2016 WsFreeWriter( writer );
2017 WsFreeHeap( heap );
2019 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2020 ok( hr == S_OK, "got %08x\n", hr );
2022 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
2023 ok( hr == S_OK, "got %08x\n", hr );
2025 hr = WsCreateWriter( NULL, 0, &writer, NULL );
2026 ok( hr == S_OK, "got %08x\n", hr );
2028 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
2029 ok( hr == S_OK, "got %08x\n", hr );
2031 /* <a><b>test</b></a> */
2032 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
2033 ok( hr == S_OK, "got %08x\n", hr );
2035 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
2036 ok( hr == S_OK, "got %08x\n", hr );
2038 utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
2039 utf8.value.bytes = (BYTE *)"test";
2040 utf8.value.length = sizeof("test") - 1;
2041 hr = WsWriteText( writer, &utf8.text, NULL );
2042 ok( hr == S_OK, "got %08x\n", hr );
2044 hr = WsWriteEndElement( writer, NULL );
2045 ok( hr == S_OK, "got %08x\n", hr );
2047 hr = WsWriteEndElement( writer, NULL );
2048 ok( hr == S_OK, "got %08x\n", hr );
2050 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
2051 ok( hr == S_OK, "got %08x\n", hr );
2053 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2054 ok( hr == S_OK, "got %08x\n", hr );
2056 hr = WsGetReaderNode( reader, &node, NULL );
2057 ok( hr == S_OK, "got %08x\n", hr );
2058 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2060 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2061 ok( hr == S_OK, "got %08x\n", hr );
2063 hr = WsGetReaderNode( reader, &node, NULL );
2064 ok( hr == S_OK, "got %08x\n", hr );
2065 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2067 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2068 ok( hr == S_OK, "got %08x\n", hr );
2070 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2071 ok( hr == S_OK, "got %08x\n", hr );
2073 hr = WsGetReaderNode( reader, &node, NULL );
2074 ok( hr == S_OK, "got %08x\n", hr );
2075 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2077 hr = WsGetReaderNode( reader, &node, NULL );
2078 ok( hr == S_OK, "got %08x\n", hr );
2079 elem = (WS_XML_ELEMENT_NODE *)node;
2080 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2081 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2082 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2084 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2085 ok( hr == S_OK, "got %08x\n", hr );
2087 hr = WsGetReaderNode( reader, &node, NULL );
2088 ok( hr == S_OK, "got %08x\n", hr );
2089 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2091 WsFreeReader( reader );
2092 WsFreeWriter( writer );
2093 WsFreeHeap( heap );
2096 static void prepare_struct_type_test( WS_XML_READER *reader, const char *data )
2098 HRESULT hr;
2099 ULONG size = strlen( data );
2101 hr = set_input( reader, data, size );
2102 ok( hr == S_OK, "got %08x\n", hr );
2104 hr = WsFillReader( reader, size, NULL, NULL );
2105 ok( hr == S_OK, "got %08x\n", hr );
2108 static void test_simple_struct_type(void)
2110 static const WCHAR testW[] = {'t','e','s','t',0};
2111 HRESULT hr;
2112 WS_XML_READER *reader;
2113 WS_HEAP *heap;
2114 WS_STRUCT_DESCRIPTION s;
2115 WS_FIELD_DESCRIPTION f, *fields[1];
2116 WS_XML_STRING ns = {0, NULL}, localname = {3, (BYTE *)"str"};
2117 WS_XML_STRING localname2 = {4, (BYTE *)"test"};
2118 const WS_XML_NODE *node;
2119 const WS_XML_ELEMENT_NODE *elem;
2120 struct test { WCHAR *str; } *test;
2122 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2123 ok( hr == S_OK, "got %08x\n", hr );
2125 hr = WsCreateReader( NULL, 0, &reader, NULL );
2126 ok( hr == S_OK, "got %08x\n", hr );
2128 prepare_struct_type_test( reader, "<str>test</str>" );
2129 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL,
2130 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2131 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2133 hr = WsGetReaderNode( reader, &node, NULL );
2134 ok( hr == S_OK, "got %08x\n", hr );
2135 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
2137 /* element field mapping */
2138 memset( &f, 0, sizeof(f) );
2139 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2140 f.localName = &localname;
2141 f.ns = &ns;
2142 f.type = WS_WSZ_TYPE;
2143 fields[0] = &f;
2145 memset( &s, 0, sizeof(s) );
2146 s.size = sizeof(struct test);
2147 s.alignment = TYPE_ALIGNMENT(struct test);
2148 s.fields = fields;
2149 s.fieldCount = 1;
2150 s.typeLocalName = &localname2;
2151 s.typeNs = &ns;
2153 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2154 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2155 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2156 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2158 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2159 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2160 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2161 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2163 s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
2164 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2165 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2166 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2167 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2168 s.structOptions = 0;
2170 test = NULL;
2171 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str>" );
2172 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2173 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2174 ok( hr == S_OK, "got %08x\n", hr );
2175 ok( test != NULL, "test not set\n" );
2176 if (test)
2178 ok( test->str != NULL, "str not set\n" );
2179 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2182 hr = WsGetReaderNode( reader, &node, NULL );
2183 ok( hr == S_OK, "got %08x\n", hr );
2184 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2186 test = NULL;
2187 prepare_struct_type_test( reader, "<str>test</str>" );
2188 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2189 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2190 ok( hr == S_OK, "got %08x\n", hr );
2191 ok( test != NULL, "test not set\n" );
2192 if (test)
2194 ok( test->str != NULL, "str not set\n" );
2195 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2198 hr = WsGetReaderNode( reader, &node, NULL );
2199 ok( hr == S_OK, "got %08x\n", hr );
2200 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2202 test = NULL;
2203 prepare_struct_type_test( reader, "<str>test</str>" );
2204 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2205 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2206 ok( hr == S_OK, "got %08x\n", hr );
2207 ok( test != NULL, "test not set\n" );
2208 if (test)
2210 ok( test->str != NULL, "str not set\n" );
2211 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2214 hr = WsGetReaderNode( reader, &node, NULL );
2215 ok( hr == S_OK, "got %08x\n", hr );
2216 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2218 prepare_struct_type_test( reader, "<str>test</str>" );
2219 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2220 ok( hr == S_OK, "got %08x\n", hr );
2222 hr = WsGetReaderNode( reader, &node, NULL );
2223 ok( hr == S_OK, "got %08x\n", hr );
2224 elem = (const WS_XML_ELEMENT_NODE *)node;
2225 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2226 ok( elem->localName->length == 3, "got %u\n", elem->localName->length );
2227 ok( !memcmp( elem->localName->bytes, "str", 3 ), "wrong data\n" );
2229 test = NULL;
2230 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2231 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2232 ok( hr == S_OK, "got %08x\n", hr );
2233 ok( test != NULL, "test not set\n" );
2234 if (test)
2236 ok( test->str != NULL, "str not set\n" );
2237 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2240 hr = WsGetReaderNode( reader, &node, NULL );
2241 ok( hr == S_OK, "got %08x\n", hr );
2242 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2244 /* attribute field mapping */
2245 f.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2247 test = NULL;
2248 prepare_struct_type_test( reader, "<test str=\"test\"/>" );
2249 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2250 ok( hr == S_OK, "got %08x\n", hr );
2252 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2253 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2254 ok( hr == S_OK, "got %08x\n", hr );
2255 ok( test != NULL, "test not set\n" );
2256 if (test)
2258 ok( test->str != NULL, "str not set\n" );
2259 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data test %p test->str %p\n", test, test->str );
2262 hr = WsGetReaderNode( reader, &node, NULL );
2263 ok( hr == S_OK, "got %08x\n", hr );
2264 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2266 WsFreeReader( reader );
2267 WsFreeHeap( heap );
2270 static void test_cdata(void)
2272 static const char test[] = "<t><![CDATA[<data>]]></t>";
2273 HRESULT hr;
2274 WS_XML_READER *reader;
2275 const WS_XML_NODE *node;
2277 hr = WsCreateReader( NULL, 0, &reader, NULL );
2278 ok( hr == S_OK, "got %08x\n", hr );
2280 hr = set_input( reader, test, sizeof(test) - 1 );
2281 ok( hr == S_OK, "got %08x\n", hr );
2283 hr = WsFillReader( reader, sizeof(test) - 1, NULL, NULL );
2284 ok( hr == S_OK, "got %08x\n", hr );
2286 hr = WsReadNode( reader, NULL );
2287 ok( hr == S_OK, "got %08x\n", hr );
2289 hr = WsGetReaderNode( reader, &node, NULL );
2290 ok( hr == S_OK, "got %08x\n", hr );
2291 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2293 hr = WsReadNode( reader, NULL );
2294 ok( hr == S_OK, "got %08x\n", hr );
2296 hr = WsGetReaderNode( reader, &node, NULL );
2297 ok( hr == S_OK, "got %08x\n", hr );
2298 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_CDATA, "got %u\n", node->nodeType );
2300 hr = WsReadNode( reader, NULL );
2301 ok( hr == S_OK, "got %08x\n", hr );
2303 hr = WsGetReaderNode( reader, &node, NULL );
2304 ok( hr == S_OK, "got %08x\n", hr );
2305 if (node)
2307 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
2308 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
2309 ok( text->text != NULL, "text not set\n" );
2310 if (text->text)
2312 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
2313 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
2314 ok( utf8->value.length == 6, "got %u\n", utf8->value.length );
2315 ok( !memcmp( utf8->value.bytes, "<data>", 6 ), "wrong data\n" );
2319 hr = WsReadNode( reader, NULL );
2320 ok( hr == S_OK, "got %08x\n", hr );
2322 hr = WsGetReaderNode( reader, &node, NULL );
2323 ok( hr == S_OK, "got %08x\n", hr );
2324 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_CDATA, "got %u\n", node->nodeType );
2326 hr = WsReadNode( reader, NULL );
2327 ok( hr == S_OK, "got %08x\n", hr );
2329 hr = WsGetReaderNode( reader, &node, NULL );
2330 ok( hr == S_OK, "got %08x\n", hr );
2331 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2333 WsFreeReader( reader );
2336 static void test_WsFindAttribute(void)
2338 static const char test[] = "<t attr='value' attr2='value2'></t>";
2339 WS_XML_STRING ns = {0, NULL}, localname = {4, (BYTE *)"attr"};
2340 WS_XML_STRING localname2 = {5, (BYTE *)"attr2"}, localname3 = {5, (BYTE *)"attr3"};
2341 WS_XML_READER *reader;
2342 ULONG index;
2343 HRESULT hr;
2345 hr = WsCreateReader( NULL, 0, &reader, NULL );
2346 ok( hr == S_OK, "got %08x\n", hr );
2348 hr = set_input( reader, test, sizeof(test) - 1 );
2349 ok( hr == S_OK, "got %08x\n", hr );
2351 hr = WsReadNode( reader, NULL );
2352 ok( hr == S_OK, "got %08x\n", hr );
2354 hr = WsFindAttribute( reader, &localname, &ns, TRUE, NULL, NULL );
2355 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2357 hr = set_input( reader, test, sizeof(test) - 1 );
2358 ok( hr == S_OK, "got %08x\n", hr );
2360 hr = WsReadNode( reader, NULL );
2361 ok( hr == S_OK, "got %08x\n", hr );
2363 hr = WsFindAttribute( reader, &localname, NULL, TRUE, &index, NULL );
2364 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2366 hr = set_input( reader, test, sizeof(test) - 1 );
2367 ok( hr == S_OK, "got %08x\n", hr );
2369 hr = WsReadNode( reader, NULL );
2370 ok( hr == S_OK, "got %08x\n", hr );
2372 hr = WsFindAttribute( reader, NULL, &ns, TRUE, &index, NULL );
2373 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2375 hr = set_input( reader, test, sizeof(test) - 1 );
2376 ok( hr == S_OK, "got %08x\n", hr );
2378 hr = WsReadNode( reader, NULL );
2379 ok( hr == S_OK, "got %08x\n", hr );
2381 index = 0xdeadbeef;
2382 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2383 ok( hr == S_OK, "got %08x\n", hr );
2384 ok( !index, "got %u\n", index );
2386 index = 0xdeadbeef;
2387 hr = WsFindAttribute( reader, &localname2, &ns, TRUE, &index, NULL );
2388 ok( hr == S_OK, "got %08x\n", hr );
2389 ok( index == 1, "got %u\n", index );
2391 hr = WsReadNode( reader, NULL );
2392 ok( hr == S_OK, "got %08x\n", hr );
2394 index = 0xdeadbeef;
2395 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2396 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2397 ok( index == 0xdeadbeef, "got %u\n", index );
2399 hr = set_input( reader, test, sizeof(test) - 1 );
2400 ok( hr == S_OK, "got %08x\n", hr );
2402 hr = WsReadNode( reader, NULL );
2403 ok( hr == S_OK, "got %08x\n", hr );
2405 index = 0xdeadbeef;
2406 hr = WsFindAttribute( reader, &localname3, &ns, TRUE, &index, NULL );
2407 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2408 ok( index == 0xdeadbeef, "got %u\n", index );
2410 hr = set_input( reader, test, sizeof(test) - 1 );
2411 ok( hr == S_OK, "got %08x\n", hr );
2413 hr = WsReadNode( reader, NULL );
2414 ok( hr == S_OK, "got %08x\n", hr );
2416 index = 0xdeadbeef;
2417 hr = WsFindAttribute( reader, &localname3, &ns, FALSE, &index, NULL );
2418 ok( hr == S_FALSE, "got %08x\n", hr );
2419 ok( index == ~0u, "got %u\n", index );
2421 WsFreeReader( reader );
2424 static void prepare_namespace_test( WS_XML_READER *reader, const char *data )
2426 HRESULT hr;
2427 ULONG size = strlen( data );
2429 hr = set_input( reader, data, size );
2430 ok( hr == S_OK, "got %08x\n", hr );
2432 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2433 ok( hr == S_OK, "got %08x\n", hr );
2436 static void test_WsGetNamespaceFromPrefix(void)
2438 WS_XML_STRING prefix = {0, NULL};
2439 const WS_XML_STRING *ns;
2440 const WS_XML_NODE *node;
2441 WS_XML_READER *reader;
2442 HRESULT hr;
2444 hr = WsCreateReader( NULL, 0, &reader, NULL );
2445 ok( hr == S_OK, "got %08x\n", hr );
2447 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, NULL, NULL );
2448 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2450 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, &ns, NULL );
2451 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2453 hr = WsGetNamespaceFromPrefix( NULL, &prefix, FALSE, &ns, NULL );
2454 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2456 ns = (const WS_XML_STRING *)0xdeadbeef;
2457 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2458 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2459 ok( ns == (const WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2461 hr = set_input( reader, "<prefix:t xmlns:prefix2='ns'/>", sizeof("<prefix:t xmlns:prefix2='ns'/>") - 1 );
2462 ok( hr == S_OK, "got %08x\n", hr );
2463 hr = WsReadStartElement( reader, NULL );
2464 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2466 prepare_namespace_test( reader, "<t></t>" );
2467 ns = NULL;
2468 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2469 ok( hr == S_OK, "got %08x\n", hr );
2470 ok( ns != NULL, "ns not set\n" );
2471 if (ns) ok( !ns->length, "got %u\n", ns->length );
2473 prepare_namespace_test( reader, "<t xmls='ns'></t>" );
2474 ns = NULL;
2475 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2476 ok( hr == S_OK, "got %08x\n", hr );
2477 ok( ns != NULL, "ns not set\n" );
2478 if (ns) ok( !ns->length, "got %u\n", ns->length );
2480 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2481 ns = NULL;
2482 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2483 ok( hr == S_OK, "got %08x\n", hr );
2484 ok( ns != NULL, "ns not set\n" );
2485 if (ns) ok( !ns->length, "got %u\n", ns->length );
2487 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2488 prefix.bytes = (BYTE *)"prefix";
2489 prefix.length = 6;
2490 ns = NULL;
2491 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2492 ok( hr == S_OK, "got %08x\n", hr );
2493 ok( ns != NULL, "ns not set\n" );
2494 if (ns)
2496 ok( ns->length == 2, "got %u\n", ns->length );
2497 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2500 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2501 ns = NULL;
2502 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2503 ok( hr == S_OK, "got %08x\n", hr );
2504 ok( ns != NULL, "ns not set\n" );
2505 if (ns)
2507 ok( ns->length == 2, "got %u\n", ns->length );
2508 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2511 hr = set_input( reader, "<t xmlns:prefix='ns'></t>", sizeof("<t xmlns:prefix='ns'></t>") - 1 );
2512 ok( hr == S_OK, "got %08x\n", hr );
2513 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2514 ok( hr == S_OK, "got %08x\n", hr );
2515 hr = WsGetReaderNode( reader, &node, NULL );
2516 ok( hr == S_OK, "got %08x\n", hr );
2517 if (node)
2519 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2520 WS_XML_ATTRIBUTE *attr;
2521 WS_XML_UTF8_TEXT *text;
2523 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2524 ok( elem->prefix != NULL, "prefix not set\n" );
2525 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2526 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2527 ok( elem->ns != NULL, "ns not set\n" );
2528 ok( !elem->ns->length, "got %u\n", elem->ns->length );
2529 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2530 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2531 ok( elem->attributes != NULL, "attributes not set\n" );
2533 attr = elem->attributes[0];
2534 ok( attr->singleQuote, "singleQuote not set\n" );
2535 ok( attr->isXmlNs, "isXmlNs not set\n" );
2536 ok( attr->prefix != NULL, "prefix not set\n" );
2537 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2538 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2539 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2540 ok( attr->localName != NULL, "localName not set\n" );
2541 ok( attr->localName->length == 6, "got %u\n", attr->localName->length );
2542 ok( !memcmp( attr->localName->bytes, "prefix", 6 ), "wrong data\n" );
2543 ok( attr->ns != NULL, "ns not set\n" );
2544 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2545 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2546 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2547 ok( attr->value != NULL, "value not set\n" );
2549 text = (WS_XML_UTF8_TEXT *)attr->value;
2550 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
2551 ok( !text->value.length, "got %u\n", text->value.length );
2552 ok( text->value.bytes == NULL, "bytes set\n" );
2555 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2556 hr = WsReadStartElement( reader, NULL );
2557 ok( hr == S_OK, "got %08x\n", hr );
2558 hr = WsReadEndElement( reader, NULL );
2559 ok( hr == S_OK, "got %08x\n", hr );
2560 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2561 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2563 prepare_namespace_test( reader, "<t></t>" );
2564 ns = NULL;
2565 prefix.bytes = (BYTE *)"xml";
2566 prefix.length = 3;
2567 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2568 ok( hr == S_OK, "got %08x\n", hr );
2569 ok( ns != NULL, "ns not set\n" );
2570 if (ns)
2572 ok( ns->length == 36, "got %u\n", ns->length );
2573 ok( !memcmp( ns->bytes, "http://www.w3.org/XML/1998/namespace", 36 ), "wrong data\n" );
2576 prepare_namespace_test( reader, "<t></t>" );
2577 ns = NULL;
2578 prefix.bytes = (BYTE *)"xmlns";
2579 prefix.length = 5;
2580 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2581 ok( hr == S_OK, "got %08x\n", hr );
2582 ok( ns != NULL, "ns not set\n" );
2583 if (ns)
2585 ok( ns->length == 29, "got %u\n", ns->length );
2586 ok( !memcmp( ns->bytes, "http://www.w3.org/2000/xmlns/", 29 ), "wrong data\n" );
2589 prepare_namespace_test( reader, "<t></t>" );
2590 ns = (WS_XML_STRING *)0xdeadbeef;
2591 prefix.bytes = (BYTE *)"prefix2";
2592 prefix.length = 7;
2593 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2594 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2595 ok( ns == (WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2597 prepare_namespace_test( reader, "<t></t>" );
2598 ns = (WS_XML_STRING *)0xdeadbeef;
2599 prefix.bytes = (BYTE *)"prefix2";
2600 prefix.length = 7;
2601 hr = WsGetNamespaceFromPrefix( reader, &prefix, FALSE, &ns, NULL );
2602 ok( hr == S_FALSE, "got %08x\n", hr );
2603 ok( ns == NULL, "ns not set\n" );
2605 hr = set_input( reader, "<t prefix:attr='' xmlns:prefix='ns'></t>", sizeof("<t prefix:attr='' xmlns:prefix='ns'></t>") - 1 );
2606 ok( hr == S_OK, "got %08x\n", hr );
2607 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2608 ok( hr == S_OK, "got %08x\n", hr );
2609 hr = WsGetReaderNode( reader, &node, NULL );
2610 ok( hr == S_OK, "got %08x\n", hr );
2611 if (node)
2613 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2614 WS_XML_ATTRIBUTE *attr;
2616 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2617 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
2618 ok( elem->attributes != NULL, "attributes not set\n" );
2620 attr = elem->attributes[0];
2621 ok( attr->singleQuote, "singleQuote not set\n" );
2622 ok( !attr->isXmlNs, "isXmlNs is set\n" );
2623 ok( attr->prefix != NULL, "prefix not set\n" );
2624 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2625 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2626 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2627 ok( attr->localName != NULL, "localName not set\n" );
2628 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
2629 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
2630 ok( attr->ns != NULL, "ns not set\n" );
2631 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2632 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2633 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2636 hr = set_input( reader, "<t xmlns:p='ns'><u xmlns:p='ns2'/></t>", sizeof("<t xmlns:p='ns'><u xmlns:p='ns2'/></t>") - 1 );
2637 ok( hr == S_OK, "got %08x\n", hr );
2638 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2639 ok( hr == S_OK, "got %08x\n", hr );
2640 hr = WsReadStartElement( reader, NULL );
2641 ok( hr == S_OK, "got %08x\n", hr );
2643 hr = set_input( reader, "<t xmlns:p='ns'><p:u p:a=''/></t>", sizeof("<t xmlns:p='ns'><p:u p:a=''/></t>") - 1 );
2644 ok( hr == S_OK, "got %08x\n", hr );
2645 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2646 ok( hr == S_OK, "got %08x\n", hr );
2647 hr = WsReadStartElement( reader, NULL );
2648 ok( hr == S_OK, "got %08x\n", hr );
2649 hr = WsGetReaderNode( reader, &node, NULL );
2650 ok( hr == S_OK, "got %08x\n", hr );
2651 if (node)
2653 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2654 WS_XML_ATTRIBUTE *attr;
2656 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2657 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2658 ok( elem->attributes != NULL, "attributes not set\n" );
2660 attr = elem->attributes[0];
2661 ok( attr->prefix != NULL, "prefix not set\n" );
2662 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
2663 ok( attr->prefix->bytes != NULL, "bytes set\n" );
2664 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong data\n" );
2665 ok( attr->localName != NULL, "localName not set\n" );
2666 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
2667 ok( !memcmp( attr->localName->bytes, "a", 1 ), "wrong data\n" );
2668 ok( attr->ns != NULL, "ns not set\n" );
2669 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2670 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2671 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2674 hr = set_input( reader, "<t xmlns='ns'></t>", sizeof("<t xmlns='ns'></t>") - 1 );
2675 ok( hr == S_OK, "got %08x\n", hr );
2676 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2677 ok( hr == S_OK, "got %08x\n", hr );
2678 hr = WsGetReaderNode( reader, &node, NULL );
2679 ok( hr == S_OK, "got %08x\n", hr );
2680 if (node)
2682 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2683 WS_XML_ATTRIBUTE *attr;
2685 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2686 ok( elem->prefix != NULL, "prefix not set\n" );
2687 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2688 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2689 ok( elem->ns != NULL, "ns not set\n" );
2690 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
2691 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2692 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong data\n" );
2694 attr = elem->attributes[0];
2695 ok( attr->isXmlNs, "isXmlNs is not set\n" );
2696 ok( attr->prefix != NULL, "prefix not set\n" );
2697 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
2698 ok( attr->prefix->bytes == NULL, "bytes set\n" );
2699 ok( attr->localName != NULL, "localName not set\n" );
2700 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
2701 ok( !memcmp( attr->localName->bytes, "xmlns", 5 ), "wrong data\n" );
2702 ok( attr->ns != NULL, "ns not set\n" );
2703 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2704 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2705 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2708 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns2'></t>") - 1 );
2709 ok( hr == S_OK, "got %08x\n", hr );
2710 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2711 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2713 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns'></t>") - 1 );
2714 ok( hr == S_OK, "got %08x\n", hr );
2715 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2716 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2718 hr = set_input( reader, "<t xmlns:p='ns' xmlns:P='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:P='ns2'></t>") - 1 );
2719 ok( hr == S_OK, "got %08x\n", hr );
2720 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2721 ok( hr == S_OK, "got %08x\n", hr );
2723 WsFreeReader( reader );
2726 static void test_text_field_mapping(void)
2728 static const WCHAR testW[] = {'t','e','s','t',0};
2729 HRESULT hr;
2730 WS_XML_READER *reader;
2731 WS_HEAP *heap;
2732 WS_STRUCT_DESCRIPTION s;
2733 WS_FIELD_DESCRIPTION f, *fields[1];
2734 struct test
2736 WCHAR *str;
2737 } *test;
2739 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2740 ok( hr == S_OK, "got %08x\n", hr );
2742 hr = WsCreateReader( NULL, 0, &reader, NULL );
2743 ok( hr == S_OK, "got %08x\n", hr );
2745 prepare_struct_type_test( reader, "<a>test</a>" );
2747 memset( &f, 0, sizeof(f) );
2748 f.mapping = WS_TEXT_FIELD_MAPPING;
2749 f.type = WS_WSZ_TYPE;
2750 fields[0] = &f;
2752 memset( &s, 0, sizeof(s) );
2753 s.size = sizeof(struct test);
2754 s.alignment = TYPE_ALIGNMENT(struct test);
2755 s.fields = fields;
2756 s.fieldCount = 1;
2758 test = NULL;
2759 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2760 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2761 ok( hr == S_OK, "got %08x\n", hr );
2762 ok( test != NULL, "test not set\n" );
2763 ok( test->str != NULL, "str not set\n" );
2764 ok( !lstrcmpW( test->str, testW ), "got %s\n", wine_dbgstr_w(test->str) );
2766 WsFreeReader( reader );
2767 WsFreeHeap( heap );
2770 static void test_complex_struct_type(void)
2772 static const WCHAR timestampW[] =
2773 {'2','0','1','5','-','0','9','-','0','3','T','1','8',':','4','7',':','5','4',0};
2774 HRESULT hr;
2775 WS_ERROR *error;
2776 WS_ERROR_PROPERTY prop;
2777 WS_XML_READER *reader;
2778 WS_HEAP *heap;
2779 WS_STRUCT_DESCRIPTION s, s2;
2780 WS_FIELD_DESCRIPTION f, f2, *fields[1], *fields2[1];
2781 WS_XML_STRING str_officeconfig = {12, (BYTE *)"OfficeConfig"};
2782 WS_XML_STRING str_services = {8, (BYTE *)"services"};
2783 WS_XML_STRING str_generationtime = {14, (BYTE *)"GenerationTime"};
2784 WS_XML_STRING ns = {39, (BYTE *)"urn:schemas-microsoft-com:office:office"};
2785 LANGID langid = MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT );
2786 const WS_XML_NODE *node;
2787 const WS_XML_ELEMENT_NODE *elem;
2788 struct services
2790 WCHAR *generationtime;
2792 struct officeconfig
2794 struct services *services;
2795 } *test;
2797 prop.id = WS_ERROR_PROPERTY_LANGID;
2798 prop.value = &langid;
2799 prop.valueSize = sizeof(langid);
2800 hr = WsCreateError( &prop, 1, &error );
2801 ok( hr == S_OK, "got %08x\n", hr );
2803 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2804 ok( hr == S_OK, "got %08x\n", hr );
2806 hr = WsCreateReader( NULL, 0, &reader, NULL );
2807 ok( hr == S_OK, "got %08x\n", hr );
2809 /* element content type mapping */
2810 prepare_struct_type_test( reader, data11 );
2812 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2813 ok( hr == S_OK, "got %08x\n", hr );
2815 hr = WsGetReaderNode( reader, &node, NULL );
2816 ok( hr == S_OK, "got %08x\n", hr );
2817 elem = (const WS_XML_ELEMENT_NODE *)node;
2818 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2819 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
2820 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
2822 hr = WsReadStartElement( reader, NULL );
2823 ok( hr == S_OK, "got %08x\n", hr );
2825 hr = WsGetReaderNode( reader, &node, NULL );
2826 ok( hr == S_OK, "got %08x\n", hr );
2827 elem = (const WS_XML_ELEMENT_NODE *)node;
2828 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2829 ok( elem->localName->length == 8, "got %u\n", elem->localName->length );
2830 ok( !memcmp( elem->localName->bytes, "services", 8 ), "wrong data\n" );
2832 memset( &f2, 0, sizeof(f2) );
2833 f2.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2834 f2.localName = &str_generationtime;
2835 f2.ns = &ns;
2836 f2.type = WS_WSZ_TYPE;
2837 f2.options = WS_FIELD_OPTIONAL;
2838 fields2[0] = &f2;
2840 memset( &s2, 0, sizeof(s2) );
2841 s2.size = sizeof(*test->services);
2842 s2.alignment = TYPE_ALIGNMENT(struct services);
2843 s2.fields = fields2;
2844 s2.fieldCount = 1;
2845 s2.typeLocalName = &str_services;
2846 s2.typeNs = &ns;
2848 memset( &f, 0, sizeof(f) );
2849 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2850 f.localName = &str_services;
2851 f.ns = &ns;
2852 f.type = WS_STRUCT_TYPE;
2853 f.typeDescription = &s2;
2854 f.options = WS_FIELD_POINTER;
2855 fields[0] = &f;
2857 memset( &s, 0, sizeof(s) );
2858 s.size = sizeof(*test);
2859 s.alignment = TYPE_ALIGNMENT(struct officeconfig);
2860 s.fields = fields;
2861 s.fieldCount = 1;
2862 s.typeLocalName = &str_officeconfig;
2863 s.typeNs = &ns;
2865 test = NULL;
2866 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2867 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2868 ok( hr == S_OK, "got %08x\n", hr );
2869 ok( test != NULL, "test not set\n" );
2870 ok( !lstrcmpW( test->services->generationtime, timestampW ), "wrong data\n" );
2872 hr = WsGetReaderNode( reader, &node, NULL );
2873 ok( hr == S_OK, "got %08x\n", hr );
2874 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2876 hr = WsReadEndElement( reader, NULL );
2877 ok( hr == S_OK, "got %08x\n", hr );
2879 hr = WsGetReaderNode( reader, &node, NULL );
2880 ok( hr == S_OK, "got %08x\n", hr );
2881 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2883 hr = WsReadEndElement( reader, NULL );
2884 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2886 /* element type mapping */
2887 prepare_struct_type_test( reader, data11 );
2889 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2890 ok( hr == S_OK, "got %08x\n", hr );
2892 hr = WsGetReaderNode( reader, &node, NULL );
2893 ok( hr == S_OK, "got %08x\n", hr );
2894 elem = (const WS_XML_ELEMENT_NODE *)node;
2895 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2896 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
2897 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
2899 test = NULL;
2900 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2901 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2902 ok( hr == S_OK, "got %08x\n", hr );
2903 ok( test != NULL, "test not set\n" );
2904 if (test) ok( !lstrcmpW( test->services->generationtime, timestampW ), "wrong data\n" );
2906 hr = WsGetReaderNode( reader, &node, NULL );
2907 ok( hr == S_OK, "got %08x\n", hr );
2908 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2910 /* trailing content */
2911 prepare_struct_type_test( reader, data11b );
2912 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2913 ok( hr == S_OK, "got %08x\n", hr );
2915 s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
2916 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2917 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2918 ok( hr == S_OK, "got %08x\n", hr );
2920 hr = WsGetReaderNode( reader, &node, NULL );
2921 ok( hr == S_OK, "got %08x\n", hr );
2922 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2924 prepare_struct_type_test( reader, data11b );
2925 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2926 ok( hr == S_OK, "got %08x\n", hr );
2928 s.structOptions = 0;
2929 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2930 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2931 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2933 WsFreeReader( reader );
2934 WsFreeHeap( heap );
2935 WsFreeError( error );
2938 static void test_repeating_element(void)
2940 static const WCHAR oneW[] = {'1',0}, twoW[] = {'2',0};
2941 WS_XML_STRING str_name = {4, (BYTE *)"name"};
2942 WS_XML_STRING str_services = {8, (BYTE *)"services"};
2943 WS_XML_STRING str_service = {7, (BYTE *)"service"};
2944 WS_XML_STRING str_wrapper = {7, (BYTE *)"wrapper"};
2945 WS_XML_STRING str_id = {2, (BYTE *)"id"};
2946 WS_XML_STRING str_ns = {0, NULL};
2947 HRESULT hr;
2948 WS_XML_READER *reader;
2949 WS_HEAP *heap;
2950 WS_STRUCT_DESCRIPTION s, s2;
2951 WS_FIELD_DESCRIPTION f, f2, f3, *fields[1], *fields2[2];
2952 WS_ITEM_RANGE range;
2953 struct service { UINT32 id; };
2954 struct service2 { WCHAR *id; };
2955 struct service3 { WCHAR *name; WCHAR *id; };
2956 struct services
2958 struct service *service;
2959 ULONG service_count;
2960 } *test;
2961 struct services2
2963 struct service2 *service;
2964 ULONG service_count;
2965 } *test2;
2966 struct services3
2968 struct service3 *service;
2969 ULONG service_count;
2970 } *test3;
2971 struct services4
2973 struct service **service;
2974 ULONG service_count;
2975 } *test4;
2977 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2978 ok( hr == S_OK, "got %08x\n", hr );
2980 hr = WsCreateReader( NULL, 0, &reader, NULL );
2981 ok( hr == S_OK, "got %08x\n", hr );
2983 prepare_struct_type_test( reader, data12 );
2985 memset( &f2, 0, sizeof(f2) );
2986 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
2987 f2.localName = &str_id;
2988 f2.ns = &str_ns;
2989 f2.type = WS_UINT32_TYPE;
2990 fields2[0] = &f2;
2992 memset( &s2, 0, sizeof(s2) );
2993 s2.size = sizeof(struct service);
2994 s2.alignment = TYPE_ALIGNMENT(struct service);
2995 s2.fields = fields2;
2996 s2.fieldCount = 1;
2997 s2.typeLocalName = &str_service;
2999 memset( &f, 0, sizeof(f) );
3000 f.mapping = WS_REPEATING_ELEMENT_FIELD_MAPPING;
3001 f.countOffset = FIELD_OFFSET(struct services, service_count);
3002 f.type = WS_STRUCT_TYPE;
3003 f.typeDescription = &s2;
3004 f.itemLocalName = &str_service;
3005 f.itemNs = &str_ns;
3006 fields[0] = &f;
3008 memset( &s, 0, sizeof(s) );
3009 s.size = sizeof(struct services);
3010 s.alignment = TYPE_ALIGNMENT(struct services);
3011 s.fields = fields;
3012 s.fieldCount = 1;
3013 s.typeLocalName = &str_services;
3015 test = NULL;
3016 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3017 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3018 ok( hr == S_OK, "got %08x\n", hr );
3019 ok( test != NULL, "test not set\n" );
3020 ok( test->service != NULL, "service not set\n" );
3021 ok( test->service_count == 2, "got %u\n", test->service_count );
3022 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
3023 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
3025 /* array of pointers */
3026 prepare_struct_type_test( reader, data12 );
3027 f.options = WS_FIELD_POINTER;
3028 test4 = NULL;
3029 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3030 WS_READ_REQUIRED_POINTER, heap, &test4, sizeof(test4), NULL );
3031 ok( hr == S_OK || broken(hr == E_INVALIDARG) /* win7 */, "got %08x\n", hr );
3032 if (test4)
3034 ok( test4->service != NULL, "service not set\n" );
3035 ok( test4->service_count == 2, "got %u\n", test4->service_count );
3036 ok( test4->service[0]->id == 1, "got %u\n", test4->service[0]->id );
3037 ok( test4->service[1]->id == 2, "got %u\n", test4->service[1]->id );
3040 /* item range */
3041 prepare_struct_type_test( reader, data13 );
3042 f.options = 0;
3043 range.minItemCount = 0;
3044 range.maxItemCount = 1;
3045 f.itemRange = &range;
3046 test = NULL;
3047 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3048 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3049 ok( hr == S_OK, "got %08x\n", hr );
3050 ok( test != NULL, "test not set\n" );
3051 ok( test->service != NULL, "service not set\n" );
3052 ok( !test->service_count, "got %u\n", test->service_count );
3054 /* wrapper element */
3055 prepare_struct_type_test( reader, data14 );
3056 f.itemRange = NULL;
3057 f.localName = &str_wrapper;
3058 f.ns = &str_ns;
3059 test = NULL;
3060 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3061 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3062 ok( hr == S_OK, "got %08x\n", hr );
3063 ok( test != NULL, "test not set\n" );
3064 ok( test->service != NULL, "service not set\n" );
3065 ok( test->service_count == 2, "got %u\n", test->service_count );
3066 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
3067 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
3069 /* repeating text field mapping */
3070 prepare_struct_type_test( reader, data15 );
3071 f2.mapping = WS_TEXT_FIELD_MAPPING;
3072 f2.localName = NULL;
3073 f2.ns = NULL;
3074 f2.type = WS_WSZ_TYPE;
3075 s2.size = sizeof(struct service2);
3076 s2.alignment = TYPE_ALIGNMENT(struct service2);
3077 test2 = NULL;
3078 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3079 WS_READ_REQUIRED_POINTER, heap, &test2, sizeof(test2), NULL );
3080 ok( hr == S_OK, "got %08x\n", hr );
3081 ok( test2 != NULL, "test2 not set\n" );
3082 ok( test2->service != NULL, "service not set\n" );
3083 ok( test2->service_count == 2, "got %u\n", test2->service_count );
3084 ok( !lstrcmpW( test2->service[0].id, oneW ), "wrong data\n" );
3085 ok( !lstrcmpW( test2->service[1].id, twoW ), "wrong data\n" );
3087 /* repeating attribute field + text field mapping */
3088 prepare_struct_type_test( reader, data16 );
3089 f2.offset = FIELD_OFFSET(struct service3, id);
3090 memset( &f3, 0, sizeof(f3) );
3091 f3.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
3092 f3.localName = &str_name;
3093 f3.ns = &str_ns;
3094 f3.type = WS_WSZ_TYPE;
3095 fields2[0] = &f3;
3096 fields2[1] = &f2;
3097 s2.size = sizeof(struct service3);
3098 s2.alignment = TYPE_ALIGNMENT(struct service3);
3099 s2.fieldCount = 2;
3100 test3 = NULL;
3101 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3102 WS_READ_REQUIRED_POINTER, heap, &test3, sizeof(test3), NULL );
3103 ok( hr == S_OK, "got %08x\n", hr );
3104 ok( test3 != NULL, "test3 not set\n" );
3105 ok( test3->service != NULL, "service not set\n" );
3106 ok( test3->service_count == 2, "got %u\n", test3->service_count );
3107 ok( !lstrcmpW( test3->service[0].name, oneW ), "wrong data\n" );
3108 ok( !lstrcmpW( test3->service[0].id, oneW ), "wrong data\n" );
3109 ok( !lstrcmpW( test3->service[1].name, twoW ), "wrong data\n" );
3110 ok( !lstrcmpW( test3->service[1].id, twoW ), "wrong data\n" );
3112 WsFreeReader( reader );
3113 WsFreeHeap( heap );
3116 static void test_WsResetHeap(void)
3118 HRESULT hr;
3119 WS_HEAP *heap;
3120 SIZE_T requested, actual;
3121 ULONG size;
3122 void *ptr;
3124 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3125 ok( hr == S_OK, "got %08x\n", hr );
3127 requested = 0xdeadbeef;
3128 size = sizeof(requested);
3129 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3130 ok( hr == S_OK, "got %08x\n", hr );
3131 ok( !requested, "got %u\n", (ULONG)requested );
3133 actual = 0xdeadbeef;
3134 size = sizeof(actual);
3135 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3136 ok( hr == S_OK, "got %08x\n", hr );
3137 ok( !actual, "got %u\n", (ULONG)actual );
3139 hr = WsAlloc( heap, 128, &ptr, NULL );
3140 ok( hr == S_OK, "got %08x\n", hr );
3142 requested = 0xdeadbeef;
3143 size = sizeof(requested);
3144 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3145 ok( hr == S_OK, "got %08x\n", hr );
3146 ok( requested == 128, "got %u\n", (ULONG)requested );
3148 actual = 0xdeadbeef;
3149 size = sizeof(actual);
3150 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3151 ok( hr == S_OK, "got %08x\n", hr );
3152 ok( actual == 128, "got %u\n", (ULONG)actual );
3154 hr = WsAlloc( heap, 1, &ptr, NULL );
3155 ok( hr == S_OK, "got %08x\n", hr );
3157 requested = 0xdeadbeef;
3158 size = sizeof(requested);
3159 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3160 ok( hr == S_OK, "got %08x\n", hr );
3161 ok( requested == 129, "got %u\n", (ULONG)requested );
3163 actual = 0xdeadbeef;
3164 size = sizeof(actual);
3165 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3166 ok( hr == S_OK, "got %08x\n", hr );
3167 todo_wine ok( actual == 384, "got %u\n", (ULONG)actual );
3169 hr = WsResetHeap( NULL, NULL );
3170 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3172 hr = WsResetHeap( heap, NULL );
3173 ok( hr == S_OK, "got %08x\n", hr );
3175 requested = 0xdeadbeef;
3176 size = sizeof(requested);
3177 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3178 ok( hr == S_OK, "got %08x\n", hr );
3179 ok( !requested, "got %u\n", (ULONG)requested );
3181 actual = 0xdeadbeef;
3182 size = sizeof(actual);
3183 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3184 ok( hr == S_OK, "got %08x\n", hr );
3185 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
3187 WsFreeHeap( heap );
3190 static void test_datetime(void)
3192 static const struct
3194 const char *str;
3195 HRESULT hr;
3196 __int64 ticks;
3197 WS_DATETIME_FORMAT format;
3199 tests[] =
3201 {"<t>0000-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3202 {"<t>0001-01-01T00:00:00Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3203 {"<t>0001-01-01T00:00:00.Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3204 {"<t>0001-01-01T00:00:00.0Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3205 {"<t>0001-01-01T00:00:00.1Z</t>", S_OK, 0x0000f4240, WS_DATETIME_FORMAT_UTC},
3206 {"<t>0001-01-01T00:00:00.01Z</t>", S_OK, 0x0000186a0, WS_DATETIME_FORMAT_UTC},
3207 {"<t>0001-01-01T00:00:00.0000001Z</t>", S_OK, 1, WS_DATETIME_FORMAT_UTC},
3208 {"<t>0001-01-01T00:00:00.9999999Z</t>", S_OK, 0x00098967f, WS_DATETIME_FORMAT_UTC},
3209 {"<t>0001-01-01T00:00:00.0000000Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3210 {"<t>0001-01-01T00:00:00.00000001Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3211 {"<t>0001-01-01T00:00:00Z-</t>", WS_E_INVALID_FORMAT, 0},
3212 {"<t>-0001-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3213 {"<t>0001-00-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3214 {"<t>0001-13-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3215 {"<t>0001-12-01T00:00:00Z</t>", S_OK, 0x1067555f88000, WS_DATETIME_FORMAT_UTC},
3216 {"<t>0001-01-00T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3217 {"<t>2001-01-32T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3218 {"<t>2001-01-31T00:00:00Z</t>", S_OK, 0x8c2592fe3794000, WS_DATETIME_FORMAT_UTC},
3219 {"<t>1900-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3220 {"<t>2000-02-29T00:00:00Z</t>", S_OK, 0x8c1505f0e438000, 0},
3221 {"<t>2001-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3222 {"<t>2001-02-28T00:00:00Z</t>", S_OK, 0x8c26f30870a4000, WS_DATETIME_FORMAT_UTC},
3223 {"<t>0001-00-01U00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3224 {"<t>0001-01-01T24:00:00Z</t>", S_OK, 0xc92a69c000, WS_DATETIME_FORMAT_UTC},
3225 {"<t>0001-01-01T24:00:01Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3226 {"<t>0001-01-01T00:60:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3227 {"<t>0001-01-01T00:00:60Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3228 {"<t>0001-01-01T00:00:00Y</t>", WS_E_INVALID_FORMAT, 0, 0},
3229 {"<t>0001-01-01T00:00:00+00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3230 {"<t>0001-01-01T00:00:00-00:01</t>", S_OK, 0x023c34600, WS_DATETIME_FORMAT_LOCAL},
3231 {"<t>9999-12-31T24:00:00+00:01</t>", S_OK, 0x2bca2875d073fa00, WS_DATETIME_FORMAT_LOCAL},
3232 {"<t>9999-12-31T24:00:00-00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3233 {"<t>0002-01-01T00:00:00+14:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3234 {"<t>0002-01-01T00:00:00+15:00</t>", WS_E_INVALID_FORMAT, 0, 0},
3235 {"<t>0002-01-01T00:00:00+13:60</t>", WS_E_INVALID_FORMAT, 0, 0},
3236 {"<t>0002-01-01T00:00:00+13:59</t>", S_OK, 0x11e5c43cc5600, WS_DATETIME_FORMAT_LOCAL},
3237 {"<t>0002-01-01T00:00:00+01:00</t>", S_OK, 0x11ec917025800, WS_DATETIME_FORMAT_LOCAL},
3238 {"<t>2016-01-01T00:00:00-01:00</t>", S_OK, 0x8d31246dfbba800, WS_DATETIME_FORMAT_LOCAL},
3239 {"<t>2016-01-01T00:00:00Z</t>", S_OK, 0x8d3123e7df74000, WS_DATETIME_FORMAT_UTC},
3240 {"<t> 2016-01-02T03:04:05Z </t>", S_OK, 0x8d313215fb64080, WS_DATETIME_FORMAT_UTC},
3241 {"<t>+2016-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3242 {"<t></t>", WS_E_INVALID_FORMAT, 0, 0},
3243 {"<t>01-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3244 {"<t>1601-01-01T00:00:00Z</t>", S_OK, 0x701ce1722770000, WS_DATETIME_FORMAT_UTC},
3246 HRESULT hr;
3247 WS_XML_READER *reader;
3248 WS_HEAP *heap;
3249 WS_DATETIME date;
3250 ULONG i;
3252 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3253 ok( hr == S_OK, "got %08x\n", hr );
3255 hr = WsCreateReader( NULL, 0, &reader, NULL );
3256 ok( hr == S_OK, "got %08x\n", hr );
3257 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3259 memset( &date, 0, sizeof(date) );
3260 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3261 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DATETIME_TYPE, NULL,
3262 WS_READ_REQUIRED_VALUE, heap, &date, sizeof(date), NULL );
3263 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3264 if (hr == S_OK)
3266 ok( date.ticks == tests[i].ticks, "%u: got %x%08x\n", i, (ULONG)(date.ticks >> 32), (ULONG)date.ticks );
3267 ok( date.format == tests[i].format, "%u: got %u\n", i, date.format );
3271 WsFreeReader( reader );
3272 WsFreeHeap( heap );
3275 static void test_WsDateTimeToFileTime(void)
3277 static const struct
3279 WS_DATETIME dt;
3280 HRESULT hr;
3281 FILETIME ft;
3283 tests[] =
3285 { {0, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3286 { {0x701ce172276ffff, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3287 { {0x701ce1722770000, WS_DATETIME_FORMAT_UTC}, S_OK, {0, 0} },
3288 { {0x2bca2875f4373fff, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c03fff, 0x24c85a5e} },
3289 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c04000, 0x24c85a5e} },
3290 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_LOCAL}, S_OK, {0xd1c04000, 0x24c85a5e} },
3291 { {~0, WS_DATETIME_FORMAT_UTC}, S_OK, {0xdd88ffff, 0xf8fe31e8} },
3293 WS_DATETIME dt;
3294 FILETIME ft;
3295 HRESULT hr;
3296 ULONG i;
3298 hr = WsDateTimeToFileTime( NULL, NULL, NULL );
3299 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3301 dt.ticks = 0x701ce172277000;
3302 dt.format = WS_DATETIME_FORMAT_UTC;
3303 hr = WsDateTimeToFileTime( &dt, NULL, NULL );
3304 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3306 hr = WsDateTimeToFileTime( NULL, &ft, NULL );
3307 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3309 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3311 memset( &ft, 0, sizeof(ft) );
3312 hr = WsDateTimeToFileTime( &tests[i].dt, &ft, NULL );
3313 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3314 if (hr == S_OK)
3316 ok( ft.dwLowDateTime == tests[i].ft.dwLowDateTime, "%u: got %08x\n", i, ft.dwLowDateTime );
3317 ok( ft.dwHighDateTime == tests[i].ft.dwHighDateTime, "%u: got %08x\n", i, ft.dwHighDateTime );
3322 static void test_WsFileTimeToDateTime(void)
3324 WS_DATETIME dt;
3325 FILETIME ft;
3326 HRESULT hr;
3328 hr = WsFileTimeToDateTime( NULL, NULL, NULL );
3329 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3331 ft.dwLowDateTime = ft.dwHighDateTime = 0;
3332 hr = WsFileTimeToDateTime( &ft, NULL, NULL );
3333 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3335 hr = WsFileTimeToDateTime( NULL, &dt, NULL );
3336 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3338 dt.ticks = 0xdeadbeef;
3339 dt.format = 0xdeadbeef;
3340 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3341 ok( hr == S_OK, "got %08x\n", hr );
3342 ok( dt.ticks == 0x701ce1722770000, "got %x%08x\n", (ULONG)(dt.ticks >> 32), (ULONG)dt.ticks );
3343 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3345 ft.dwLowDateTime = 0xd1c03fff;
3346 ft.dwHighDateTime = 0x24c85a5e;
3347 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3348 ok( hr == S_OK, "got %08x\n", hr );
3349 ok( dt.ticks == 0x2bca2875f4373fff, "got %x%08x\n", (ULONG)(dt.ticks >> 32), (ULONG)dt.ticks );
3350 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3352 ft.dwLowDateTime++;
3353 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3354 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3356 ft.dwLowDateTime = 0xdd88ffff;
3357 ft.dwHighDateTime = 0xf8fe31e8;
3358 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3359 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3361 ft.dwLowDateTime++;
3362 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3363 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
3366 static void test_double(void)
3368 static const struct
3370 const char *str;
3371 HRESULT hr;
3372 ULONGLONG val;
3374 tests[] =
3376 {"<t>0.0</t>", S_OK, 0},
3377 {"<t>-0.0</t>", S_OK, 0x8000000000000000},
3378 {"<t>+0.0</t>", S_OK, 0},
3379 {"<t>-</t>", S_OK, 0},
3380 {"<t>+</t>", S_OK, 0},
3381 {"<t>.0</t>", S_OK, 0},
3382 {"<t>0.</t>", S_OK, 0},
3383 {"<t>0</t>", S_OK, 0},
3384 {"<t> 0 </t>", S_OK, 0},
3385 {"<t></t>", WS_E_INVALID_FORMAT, 0},
3386 {"<t>0,1</t>", WS_E_INVALID_FORMAT, 0},
3387 {"<t>1.1.</t>", WS_E_INVALID_FORMAT, 0},
3388 {"<t>1</t>", S_OK, 0x3ff0000000000000},
3389 {"<t>1.0000000000000002</t>", S_OK, 0x3ff0000000000001},
3390 {"<t>1.0000000000000004</t>", S_OK, 0x3ff0000000000002},
3391 {"<t>10000000000000000000</t>", S_OK, 0x43e158e460913d00},
3392 {"<t>100000000000000000000</t>", S_OK, 0x4415af1d78b58c40},
3393 {"<t>2</t>", S_OK, 0x4000000000000000},
3394 {"<t>-2</t>", S_OK, 0xc000000000000000},
3395 {"<t>nodouble</t>", WS_E_INVALID_FORMAT, 0},
3396 {"<t>INF</t>", S_OK, 0x7ff0000000000000},
3397 {"<t>-INF</t>", S_OK, 0xfff0000000000000},
3398 {"<t>+INF</t>", WS_E_INVALID_FORMAT, 0},
3399 {"<t>Infinity</t>", WS_E_INVALID_FORMAT, 0},
3400 {"<t>-Infinity</t>", WS_E_INVALID_FORMAT, 0},
3401 {"<t>inf</t>", WS_E_INVALID_FORMAT, 0},
3402 {"<t>NaN</t>", S_OK, 0xfff8000000000000},
3403 {"<t>-NaN</t>", WS_E_INVALID_FORMAT, 0},
3404 {"<t>NAN</t>", WS_E_INVALID_FORMAT, 0},
3405 {"<t>0.3</t>", S_OK, 0x3fd3333333333333},
3406 {"<t>0.33</t>", S_OK, 0x3fd51eb851eb851f},
3407 {"<t>0.333</t>", S_OK, 0x3fd54fdf3b645a1d},
3408 {"<t>0.3333</t>", S_OK, 0x3fd554c985f06f69},
3409 {"<t>0.33333</t>", S_OK, 0x3fd555475a31a4be},
3410 {"<t>0.333333</t>", S_OK, 0x3fd55553ef6b5d46},
3411 {"<t>0.3333333</t>", S_OK, 0x3fd55555318abc87},
3412 {"<t>0.33333333</t>", S_OK, 0x3fd5555551c112da},
3413 {"<t>0.333333333</t>", S_OK, 0x3fd5555554f9b516},
3414 {"<t>0.3333333333</t>", S_OK, 0x3fd55555554c2bb5},
3415 {"<t>0.33333333333</t>", S_OK, 0x3fd5555555546ac5},
3416 {"<t>0.3333333333333</t>", S_OK, 0x3fd55555555552fd},
3417 {"<t>0.33333333333333</t>", S_OK, 0x3fd5555555555519},
3418 {"<t>0.333333333333333</t>", S_OK, 0x3fd555555555554f},
3419 {"<t>0.3333333333333333</t>", S_OK, 0x3fd5555555555555},
3420 {"<t>0.33333333333333333</t>", S_OK, 0x3fd5555555555555},
3421 {"<t>0.1e10</t>", S_OK, 0x41cdcd6500000000},
3422 {"<t>1e</t>", WS_E_INVALID_FORMAT, 0},
3423 {"<t>1e0</t>", S_OK, 0x3ff0000000000000},
3424 {"<t>1e+1</t>", S_OK, 0x4024000000000000},
3425 {"<t>1e-1</t>", S_OK, 0x3fb999999999999a},
3426 {"<t>e10</t>", WS_E_INVALID_FORMAT, 0},
3427 {"<t>1e10.</t>", WS_E_INVALID_FORMAT, 0},
3428 {"<t>1E10</t>", S_OK, 0x4202a05f20000000},
3429 {"<t>1e10</t>", S_OK, 0x4202a05f20000000},
3430 {"<t>1e-10</t>", S_OK, 0x3ddb7cdfd9d7bdbb},
3431 {"<t>1.7976931348623158e308</t>", S_OK, 0x7fefffffffffffff},
3432 {"<t>1.7976931348623159e308</t>", S_OK, 0x7ff0000000000000},
3433 {"<t>4.94065645841247e-324</t>", S_OK, 0x1},
3435 HRESULT hr;
3436 WS_XML_READER *reader;
3437 WS_HEAP *heap;
3438 ULONGLONG val;
3439 ULONG i;
3441 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3442 ok( hr == S_OK, "got %08x\n", hr );
3444 hr = WsCreateReader( NULL, 0, &reader, NULL );
3445 ok( hr == S_OK, "got %08x\n", hr );
3447 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3449 val = 0;
3450 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3451 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DOUBLE_TYPE, NULL,
3452 WS_READ_REQUIRED_VALUE, heap, &val, sizeof(val), NULL );
3453 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3454 if (hr == tests[i].hr) ok( val == tests[i].val, "%u: got %x%08x\n", i, (ULONG)(val >> 32), (ULONG)val );
3457 WsFreeReader( reader );
3458 WsFreeHeap( heap );
3461 static void test_WsReadElement(void)
3463 WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
3464 HRESULT hr;
3465 WS_XML_READER *reader;
3466 WS_ELEMENT_DESCRIPTION desc;
3467 UINT32 val;
3469 hr = WsCreateReader( NULL, 0, &reader, NULL );
3470 ok( hr == S_OK, "got %08x\n", hr );
3472 desc.elementLocalName = &localname;
3473 desc.elementNs = &ns;
3474 desc.type = WS_UINT32_TYPE;
3475 desc.typeDescription = NULL;
3477 prepare_struct_type_test( reader, "<t>1</t>" );
3478 hr = WsReadElement( NULL, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3479 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3481 prepare_struct_type_test( reader, "<t>1</t>" );
3482 hr = WsReadElement( reader, NULL, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3483 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3485 prepare_struct_type_test( reader, "<t>1</t>" );
3486 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, NULL, sizeof(val), NULL );
3487 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3489 prepare_struct_type_test( reader, "<t>1</t>" );
3490 val = 0xdeadbeef;
3491 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3492 ok( hr == S_OK, "got %08x\n", hr );
3493 ok( val == 1, "got %u\n", val );
3495 WsFreeReader( reader );
3498 static void test_WsReadValue(void)
3500 HRESULT hr;
3501 WS_XML_READER *reader;
3502 UINT32 val;
3504 hr = WsCreateReader( NULL, 0, &reader, NULL );
3505 ok( hr == S_OK, "got %08x\n", hr );
3507 prepare_struct_type_test( reader, "<t>1</t>" );
3508 hr = WsReadValue( NULL, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3509 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3511 prepare_struct_type_test( reader, "<t>1</t>" );
3512 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, NULL, sizeof(val), NULL );
3513 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3515 /* reader must be positioned correctly */
3516 prepare_struct_type_test( reader, "<t>1</t>" );
3517 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3518 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3520 prepare_struct_type_test( reader, "<t>1</t>" );
3521 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3522 ok( hr == S_OK, "got %08x\n", hr );
3524 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3525 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3527 prepare_struct_type_test( reader, "<t>1</t>" );
3528 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3529 ok( hr == S_OK, "got %08x\n", hr );
3531 hr = WsReadStartElement( reader, NULL );
3532 ok( hr == S_OK, "got %08x\n", hr );
3534 val = 0xdeadbeef;
3535 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3536 ok( hr == S_OK, "got %08x\n", hr );
3537 ok( val == 1, "got %u\n", val );
3539 prepare_struct_type_test( reader, "<u t='1'></u>" );
3540 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3541 ok( hr == S_OK, "got %08x\n", hr );
3543 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3544 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3546 WsFreeReader( reader );
3549 static void test_WsResetError(void)
3551 WS_ERROR_PROPERTY prop;
3552 ULONG size, code;
3553 WS_ERROR *error;
3554 LANGID langid;
3555 HRESULT hr;
3557 hr = WsResetError( NULL );
3558 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3560 error = NULL;
3561 hr = WsCreateError( NULL, 0, &error );
3562 ok( hr == S_OK, "got %08x\n", hr );
3563 ok( error != NULL, "error not set\n" );
3565 code = 0xdeadbeef;
3566 size = sizeof(code);
3567 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3568 ok( hr == S_OK, "got %08x\n", hr );
3570 hr = WsResetError( error );
3571 ok( hr == S_OK, "got %08x\n", hr );
3573 code = 0xdeadbeef;
3574 size = sizeof(code);
3575 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3576 ok( hr == S_OK, "got %08x\n", hr );
3577 ok( !code, "got %u\n", code );
3579 WsFreeError( error );
3581 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
3582 prop.id = WS_ERROR_PROPERTY_LANGID;
3583 prop.value = &langid;
3584 prop.valueSize = sizeof(langid);
3585 hr = WsCreateError( &prop, 1, &error );
3586 ok( hr == S_OK, "got %08x\n", hr );
3588 langid = 0xdead;
3589 size = sizeof(langid);
3590 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3591 ok( hr == S_OK, "got %08x\n", hr );
3592 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3594 hr = WsResetError( error );
3595 ok( hr == S_OK, "got %08x\n", hr );
3597 langid = 0xdead;
3598 size = sizeof(langid);
3599 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3600 ok( hr == S_OK, "got %08x\n", hr );
3601 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3603 WsFreeError( error );
3606 static void test_WsGetReaderPosition(void)
3608 WS_HEAP *heap;
3609 WS_XML_READER *reader;
3610 WS_XML_BUFFER *buffer;
3611 WS_XML_NODE_POSITION pos;
3612 HRESULT hr;
3614 hr = WsGetReaderPosition( NULL, NULL, NULL );
3615 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3617 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3618 ok( hr == S_OK, "got %08x\n", hr );
3620 hr = WsCreateReader( NULL, 0, &reader, NULL );
3621 ok( hr == S_OK, "got %08x\n", hr );
3623 /* reader must be set to an XML buffer */
3624 hr = WsGetReaderPosition( reader, &pos, NULL );
3625 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3627 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
3628 ok( hr == S_OK, "got %08x\n", hr );
3630 hr = WsGetReaderPosition( reader, &pos, NULL );
3631 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3633 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
3634 ok( hr == S_OK, "got %08x\n", hr );
3636 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
3637 ok( hr == S_OK, "got %08x\n", hr );
3639 hr = WsGetReaderPosition( reader, NULL, NULL );
3640 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3642 pos.buffer = pos.node = NULL;
3643 hr = WsGetReaderPosition( reader, &pos, NULL );
3644 ok( hr == S_OK, "got %08x\n", hr );
3645 ok( pos.buffer != NULL, "buffer not set\n" );
3646 ok( pos.node != NULL, "node not set\n" );
3648 WsFreeReader( reader );
3649 WsFreeHeap( heap );
3652 static void test_WsSetReaderPosition(void)
3654 WS_HEAP *heap;
3655 WS_XML_READER *reader;
3656 WS_XML_BUFFER *buf1, *buf2;
3657 WS_XML_NODE_POSITION pos;
3658 HRESULT hr;
3660 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3661 ok( hr == S_OK, "got %08x\n", hr );
3663 hr = WsSetReaderPosition( NULL, NULL, NULL );
3664 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3666 hr = WsCreateReader( NULL, 0, &reader, NULL );
3667 ok( hr == S_OK, "got %08x\n", hr );
3669 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf1, NULL );
3670 ok( hr == S_OK, "got %08x\n", hr );
3672 hr = WsSetInputToBuffer( reader, buf1, NULL, 0, NULL );
3673 ok( hr == S_OK, "got %08x\n", hr );
3675 hr = WsSetReaderPosition( reader, NULL, NULL );
3676 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3678 pos.buffer = pos.node = NULL;
3679 hr = WsGetReaderPosition( reader, &pos, NULL );
3680 ok( hr == S_OK, "got %08x\n", hr );
3681 ok( pos.buffer == buf1, "wrong buffer\n" );
3682 ok( pos.node != NULL, "node not set\n" );
3684 hr = WsSetReaderPosition( reader, &pos, NULL );
3685 ok( hr == S_OK, "got %08x\n", hr );
3687 /* different buffer */
3688 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf2, NULL );
3689 ok( hr == S_OK, "got %08x\n", hr );
3691 pos.buffer = buf2;
3692 hr = WsSetReaderPosition( reader, &pos, NULL );
3693 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3695 WsFreeReader( reader );
3696 WsFreeHeap( heap );
3699 static void test_entities(void)
3701 static const char str1[] = "<t>&#xA</t>";
3702 static const char str2[] = "<t>&#xA;</t>";
3703 static const char str3[] = "<t>&#xa;</t>";
3704 static const char str4[] = "<t>&#xaaaa;</t>";
3705 static const char str5[] = "<t>&#xaaaaa;</t>";
3706 static const char str6[] = "<t>&1</t>";
3707 static const char str7[] = "<t>&1;</t>";
3708 static const char str8[] = "<t>&1111;</t>";
3709 static const char str9[] = "<t>&11111;</t>";
3710 static const char str10[] = "<t>&lt;</t>";
3711 static const char str11[] = "<t>&gt;</t>";
3712 static const char str12[] = "<t>&quot;</t>";
3713 static const char str13[] = "<t>&amp;</t>";
3714 static const char str14[] = "<t>&apos;</t>";
3715 static const char str15[] = "<t>&sopa;</t>";
3716 static const char str16[] = "<t>&#;</t>";
3717 static const char str17[] = "<t>&;</t>";
3718 static const char str18[] = "<t>&&</t>";
3719 static const char str19[] = "<t>&</t>";
3720 static const char str20[] = "<t>&#xaaaaaa;</t>";
3721 static const char str21[] = "<t>&#xd7ff;</t>";
3722 static const char str22[] = "<t>&#xd800;</t>";
3723 static const char str23[] = "<t>&#xdfff;</t>";
3724 static const char str24[] = "<t>&#xe000;</t>";
3725 static const char str25[] = "<t>&#xfffe;</t>";
3726 static const char str26[] = "<t>&#xffff;</t>";
3727 static const char str27[] = "<t>&LT;</t>";
3728 static const char str28[] = "<t>&#x0;</t>";
3729 static const char str29[] = "<t>&#0;</t>";
3730 static const char str30[] = "<t>&#65;</t>";
3731 static const char str31[] = "<t>&#65393;</t>";
3732 static const char str32[] = "<t>&#x10ffff;</t>";
3733 static const char str33[] = "<t>&#x110000;</t>";
3734 static const char str34[] = "<t>&#1114111;</t>";
3735 static const char str35[] = "<t>&#1114112;</t>";
3736 static const char res4[] = {0xea, 0xaa, 0xaa, 0x00};
3737 static const char res5[] = {0xf2, 0xaa, 0xaa, 0xaa, 0x00};
3738 static const char res21[] = {0xed, 0x9f, 0xbf, 0x00};
3739 static const char res24[] = {0xee, 0x80, 0x80, 0x00};
3740 static const char res31[] = {0xef, 0xbd, 0xb1, 0x00};
3741 static const char res32[] = {0xf4, 0x8f, 0xbf, 0xbf, 0x00};
3742 static const struct
3744 const char *str;
3745 HRESULT hr;
3746 const char *res;
3748 tests[] =
3750 { str1, WS_E_INVALID_FORMAT },
3751 { str2, S_OK, "\n" },
3752 { str3, S_OK, "\n" },
3753 { str4, S_OK, res4 },
3754 { str5, S_OK, res5 },
3755 { str6, WS_E_INVALID_FORMAT },
3756 { str7, WS_E_INVALID_FORMAT },
3757 { str8, WS_E_INVALID_FORMAT },
3758 { str9, WS_E_INVALID_FORMAT },
3759 { str10, S_OK, "<" },
3760 { str11, S_OK, ">" },
3761 { str12, S_OK, "\"" },
3762 { str13, S_OK, "&" },
3763 { str14, S_OK, "'" },
3764 { str15, WS_E_INVALID_FORMAT },
3765 { str16, WS_E_INVALID_FORMAT },
3766 { str17, WS_E_INVALID_FORMAT },
3767 { str18, WS_E_INVALID_FORMAT },
3768 { str19, WS_E_INVALID_FORMAT },
3769 { str20, WS_E_INVALID_FORMAT },
3770 { str21, S_OK, res21 },
3771 { str22, WS_E_INVALID_FORMAT },
3772 { str23, WS_E_INVALID_FORMAT },
3773 { str24, S_OK, res24 },
3774 { str25, WS_E_INVALID_FORMAT },
3775 { str26, WS_E_INVALID_FORMAT },
3776 { str27, WS_E_INVALID_FORMAT },
3777 { str28, WS_E_INVALID_FORMAT },
3778 { str29, WS_E_INVALID_FORMAT },
3779 { str30, S_OK, "A" },
3780 { str31, S_OK, res31 },
3781 { str32, S_OK, res32 },
3782 { str33, WS_E_INVALID_FORMAT },
3783 { str34, S_OK, res32 },
3784 { str35, WS_E_INVALID_FORMAT },
3786 HRESULT hr;
3787 WS_XML_READER *reader;
3788 const WS_XML_NODE *node;
3789 const WS_XML_UTF8_TEXT *utf8;
3790 ULONG i;
3792 hr = WsCreateReader( NULL, 0, &reader, NULL );
3793 ok( hr == S_OK, "got %08x\n", hr );
3795 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3797 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
3798 ok( hr == S_OK, "%u: got %08x\n", i, hr );
3800 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3801 ok( hr == S_OK, "%u: got %08x\n", i, hr );
3803 hr = WsReadNode( reader, NULL );
3804 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3805 if (hr != S_OK) continue;
3807 hr = WsGetReaderNode( reader, &node, NULL );
3808 ok( hr == S_OK, "%u: got %08x\n", i, hr );
3810 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_TEXT_NODE *)node)->text;
3811 ok( utf8->value.length == strlen(tests[i].res), "%u: got %u\n", i, utf8->value.length );
3812 ok( !memcmp( utf8->value.bytes, tests[i].res, strlen(tests[i].res) ), "%u: wrong data\n", i );
3815 hr = set_input( reader, "<t a='&#xA;&#xA;'/>", sizeof("<t a='&#xA;&#xA;'/>") - 1 );
3816 ok( hr == S_OK, "got %08x\n", hr );
3818 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3819 ok( hr == S_OK, "got %08x\n", hr );
3821 hr = WsGetReaderNode( reader, &node, NULL );
3822 ok( hr == S_OK, "got %08x\n", hr );
3824 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_ELEMENT_NODE *)node)->attributes[0]->value;
3825 ok( utf8->value.length == 2, "got %u\n", utf8->value.length );
3826 ok( !memcmp( utf8->value.bytes, "\n\n", 2 ), "wrong data\n" );
3828 WsFreeReader( reader );
3831 static void test_field_options(void)
3833 static const char xml[] =
3834 "<t xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><wsz i:nil=\"true\"/>"
3835 "<s i:nil=\"true\"/></t>";
3836 static const GUID guid_null = {0};
3837 HRESULT hr;
3838 WS_HEAP *heap;
3839 WS_XML_READER *reader;
3840 WS_STRUCT_DESCRIPTION s, s2;
3841 WS_FIELD_DESCRIPTION f, f2, f3, f4, f5, *fields[4], *fields2[1];
3842 WS_XML_STRING ns = {0, NULL}, str_wsz = {3, (BYTE *)"wsz"}, str_s = {1, (BYTE *)"s"};
3843 WS_XML_STRING str_int32 = {5, (BYTE *)"int32"}, str_guid = {4, (BYTE *)"guid"};
3844 WS_DEFAULT_VALUE def_val;
3845 INT32 val_int32;
3846 struct s
3848 INT32 int32;
3850 struct test
3852 WCHAR *wsz;
3853 struct s *s;
3854 INT32 int32;
3855 GUID guid;
3856 } *test;
3858 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3859 ok( hr == S_OK, "got %08x\n", hr );
3861 hr = WsCreateReader( NULL, 0, &reader, NULL );
3862 ok( hr == S_OK, "got %08x\n", hr );
3864 hr = set_input( reader, xml, sizeof(xml) - 1 );
3865 ok( hr == S_OK, "got %08x\n", hr );
3867 memset( &f, 0, sizeof(f) );
3868 f.mapping = WS_ELEMENT_FIELD_MAPPING;
3869 f.localName = &str_wsz;
3870 f.ns = &ns;
3871 f.type = WS_WSZ_TYPE;
3872 f.options = WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
3873 fields[0] = &f;
3875 memset( &f3, 0, sizeof(f3) );
3876 f3.mapping = WS_ELEMENT_FIELD_MAPPING;
3877 f3.localName = &str_int32;
3878 f3.ns = &ns;
3879 f3.type = WS_INT32_TYPE;
3880 fields2[0] = &f3;
3882 memset( &s2, 0, sizeof(s2) );
3883 s2.size = sizeof(struct s);
3884 s2.alignment = TYPE_ALIGNMENT(struct s);
3885 s2.fields = fields2;
3886 s2.fieldCount = 1;
3888 memset( &f2, 0, sizeof(f2) );
3889 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
3890 f2.localName = &str_s;
3891 f2.ns = &ns;
3892 f2.type = WS_STRUCT_TYPE;
3893 f2.typeDescription = &s2;
3894 f2.offset = FIELD_OFFSET(struct test, s);
3895 f2.options = WS_FIELD_POINTER|WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
3896 fields[1] = &f2;
3898 val_int32 = -1;
3899 def_val.value = &val_int32;
3900 def_val.valueSize = sizeof(val_int32);
3902 memset( &f4, 0, sizeof(f4) );
3903 f4.mapping = WS_ELEMENT_FIELD_MAPPING;
3904 f4.localName = &str_int32;
3905 f4.ns = &ns;
3906 f4.type = WS_INT32_TYPE;
3907 f4.offset = FIELD_OFFSET(struct test, int32);
3908 f4.options = WS_FIELD_OPTIONAL;
3909 f4.defaultValue = &def_val;
3910 fields[2] = &f4;
3912 memset( &f5, 0, sizeof(f5) );
3913 f5.mapping = WS_ELEMENT_FIELD_MAPPING;
3914 f5.localName = &str_guid;
3915 f5.ns = &ns;
3916 f5.type = WS_GUID_TYPE;
3917 f5.offset = FIELD_OFFSET(struct test, guid);
3918 f5.options = WS_FIELD_OPTIONAL;
3919 fields[3] = &f5;
3921 memset( &s, 0, sizeof(s) );
3922 s.size = sizeof(struct test);
3923 s.alignment = TYPE_ALIGNMENT(struct test);
3924 s.fields = fields;
3925 s.fieldCount = 4;
3927 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3928 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3929 ok( hr == S_OK, "got %08x\n", hr );
3930 ok( !test->wsz, "wsz is set\n" );
3931 ok( !test->s, "s is set\n" );
3932 ok( test->int32 == -1, "got %d\n", test->int32 );
3933 ok( IsEqualGUID( &test->guid, &guid_null ), "wrong guid\n" );
3935 WsFreeReader( reader );
3936 WsFreeHeap( heap );
3939 static void test_WsReadBytes(void)
3941 HRESULT hr;
3942 WS_XML_READER *reader;
3943 const WS_XML_NODE *node;
3944 const WS_XML_TEXT_NODE *text;
3945 const WS_XML_UTF8_TEXT *utf8;
3946 BYTE buf[4];
3947 ULONG count;
3949 hr = WsCreateReader( NULL, 0, &reader, NULL );
3950 ok( hr == S_OK, "got %08x\n", hr );
3952 hr = WsReadBytes( NULL, NULL, 0, NULL, NULL );
3953 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3955 hr = WsReadBytes( reader, NULL, 0, NULL, NULL );
3956 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3958 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
3959 ok( hr == S_OK, "got %08x\n", hr );
3961 hr = WsReadBytes( reader, NULL, 0, NULL, NULL );
3962 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3964 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
3965 ok( hr == S_OK, "got %08x\n", hr );
3967 hr = WsReadBytes( reader, buf, 0, NULL, NULL );
3968 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3970 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
3971 ok( hr == S_OK, "got %08x\n", hr );
3973 count = 0xdeadbeef;
3974 hr = WsReadBytes( reader, NULL, 0, &count, NULL );
3975 ok( hr == S_OK, "got %08x\n", hr );
3976 ok( !count, "got %u\n", count );
3978 count = 0xdeadbeef;
3979 hr = WsReadBytes( reader, NULL, 1, &count, NULL );
3980 ok( hr == S_OK, "got %08x\n", hr );
3981 ok( !count, "got %u\n", count );
3983 buf[0] = 0;
3984 count = 0xdeadbeef;
3985 hr = WsReadBytes( reader, buf, 0, &count, NULL );
3986 ok( hr == S_OK, "got %08x\n", hr );
3987 ok( !count, "got %u\n", count );
3988 ok( !buf[0], "wrong data\n" );
3990 buf[0] = 0;
3991 count = 0xdeadbeef;
3992 hr = WsReadBytes( reader, buf, 2, &count, NULL );
3993 ok( hr == S_OK, "got %08x\n", hr );
3994 ok( !count, "got %u\n", count );
3995 ok( !buf[0], "wrong data\n" );
3997 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3998 ok( hr == S_OK, "got %08x\n", hr );
4000 buf[0] = 0;
4001 count = 0xdeadbeef;
4002 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4003 ok( hr == S_OK, "got %08x\n", hr );
4004 ok( !count, "got %u\n", count );
4005 ok( !buf[0], "wrong data\n" );
4007 hr = WsReadStartElement( reader, NULL );
4008 ok( hr == S_OK, "got %08x\n", hr );
4010 count = 0xdeadbeef;
4011 hr = WsReadBytes( reader, NULL, 0, &count, NULL );
4012 ok( hr == S_OK, "got %08x\n", hr );
4013 ok( !count, "got %u\n", count );
4015 buf[0] = 0;
4016 count = 0xdeadbeef;
4017 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4018 ok( hr == S_OK, "got %08x\n", hr );
4019 ok( count == 2, "got %u\n", count );
4020 ok( !memcmp( buf, "te", 2 ), "wrong data\n" );
4022 hr = WsGetReaderNode( reader, &node, NULL );
4023 ok( hr == S_OK, "got %08x\n", hr );
4024 text = (const WS_XML_TEXT_NODE *)node;
4025 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4026 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4027 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4028 ok( utf8->value.length == 8, "got %u\n", utf8->value.length );
4029 ok( !memcmp( utf8->value.bytes, "dGV4dA==", 8 ), "wrong data\n" );
4031 buf[0] = 0;
4032 count = 0xdeadbeef;
4033 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4034 ok( hr == S_OK, "got %08x\n", hr );
4035 ok( count == 2, "got %u\n", count );
4036 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4038 hr = WsGetReaderNode( reader, &node, NULL );
4039 ok( hr == S_OK, "got %08x\n", hr );
4040 text = (const WS_XML_TEXT_NODE *)node;
4041 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4043 count = 0xdeadbeef;
4044 hr = WsReadBytes( reader, buf, 1, &count, NULL );
4045 ok( hr == S_OK, "got %08x\n", hr );
4046 ok( !count, "got %u\n", count );
4048 hr = WsGetReaderNode( reader, &node, NULL );
4049 ok( hr == S_OK, "got %08x\n", hr );
4050 text = (const WS_XML_TEXT_NODE *)node;
4051 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4053 WsFreeReader( reader );
4056 static void test_WsReadChars(void)
4058 static const WCHAR textW[] = {'t','e','x','t'};
4059 HRESULT hr;
4060 WS_XML_READER *reader;
4061 const WS_XML_NODE *node;
4062 const WS_XML_TEXT_NODE *text;
4063 const WS_XML_UTF8_TEXT *utf8;
4064 unsigned char buf[4];
4065 WCHAR bufW[4];
4066 ULONG count;
4068 hr = WsCreateReader( NULL, 0, &reader, NULL );
4069 ok( hr == S_OK, "got %08x\n", hr );
4071 hr = WsReadChars( NULL, NULL, 0, NULL, NULL );
4072 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4074 hr = WsReadChars( reader, NULL, 0, NULL, NULL );
4075 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4077 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4078 ok( hr == S_OK, "got %08x\n", hr );
4080 hr = WsReadChars( reader, NULL, 0, NULL, NULL );
4081 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4083 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4084 ok( hr == S_OK, "got %08x\n", hr );
4086 hr = WsReadChars( reader, bufW, 0, NULL, NULL );
4087 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4089 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4090 ok( hr == S_OK, "got %08x\n", hr );
4092 count = 0xdeadbeef;
4093 hr = WsReadChars( reader, NULL, 0, &count, NULL );
4094 ok( hr == S_OK, "got %08x\n", hr );
4095 ok( !count, "got %u\n", count );
4097 count = 0xdeadbeef;
4098 hr = WsReadChars( reader, NULL, 1, &count, NULL );
4099 ok( hr == S_OK, "got %08x\n", hr );
4100 ok( !count, "got %u\n", count );
4102 buf[0] = 0;
4103 count = 0xdeadbeef;
4104 hr = WsReadChars( reader, bufW, 0, &count, NULL );
4105 ok( hr == S_OK, "got %08x\n", hr );
4106 ok( !count, "got %u\n", count );
4107 ok( !buf[0], "wrong data\n" );
4109 buf[0] = 0;
4110 count = 0xdeadbeef;
4111 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4112 ok( hr == S_OK, "got %08x\n", hr );
4113 ok( !count, "got %u\n", count );
4114 ok( !buf[0], "wrong data\n" );
4116 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4117 ok( hr == S_OK, "got %08x\n", hr );
4119 buf[0] = 0;
4120 count = 0xdeadbeef;
4121 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4122 ok( hr == S_OK, "got %08x\n", hr );
4123 ok( !count, "got %u\n", count );
4124 ok( !buf[0], "wrong data\n" );
4126 hr = WsReadStartElement( reader, NULL );
4127 ok( hr == S_OK, "got %08x\n", hr );
4129 count = 0xdeadbeef;
4130 hr = WsReadChars( reader, NULL, 0, &count, NULL );
4131 ok( hr == S_OK, "got %08x\n", hr );
4132 ok( !count, "got %u\n", count );
4134 buf[0] = 0;
4135 count = 0xdeadbeef;
4136 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4137 ok( hr == S_OK, "got %08x\n", hr );
4138 ok( count == 2, "got %u\n", count );
4139 ok( !memcmp( bufW, textW, 2 * sizeof(WCHAR) ), "wrong data\n" );
4141 hr = WsGetReaderNode( reader, &node, NULL );
4142 ok( hr == S_OK, "got %08x\n", hr );
4143 text = (const WS_XML_TEXT_NODE *)node;
4144 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4145 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4146 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4147 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4148 ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" );
4150 /* continue reading in a different encoding */
4151 buf[0] = 0;
4152 count = 0xdeadbeef;
4153 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4154 ok( hr == S_OK, "got %08x\n", hr );
4155 ok( count == 2, "got %u\n", count );
4156 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4158 hr = WsGetReaderNode( reader, &node, NULL );
4159 ok( hr == S_OK, "got %08x\n", hr );
4160 text = (const WS_XML_TEXT_NODE *)node;
4161 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4163 count = 0xdeadbeef;
4164 hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL );
4165 ok( hr == S_OK, "got %08x\n", hr );
4166 ok( !count, "got %u\n", count );
4168 hr = WsGetReaderNode( reader, &node, NULL );
4169 ok( hr == S_OK, "got %08x\n", hr );
4170 text = (const WS_XML_TEXT_NODE *)node;
4171 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4173 WsFreeReader( reader );
4176 static void test_WsReadCharsUtf8(void)
4178 HRESULT hr;
4179 WS_XML_READER *reader;
4180 const WS_XML_NODE *node;
4181 const WS_XML_TEXT_NODE *text;
4182 const WS_XML_UTF8_TEXT *utf8;
4183 BYTE buf[4];
4184 ULONG count;
4186 hr = WsCreateReader( NULL, 0, &reader, NULL );
4187 ok( hr == S_OK, "got %08x\n", hr );
4189 hr = WsReadCharsUtf8( NULL, NULL, 0, NULL, NULL );
4190 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4192 hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL );
4193 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4195 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4196 ok( hr == S_OK, "got %08x\n", hr );
4198 hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL );
4199 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4201 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4202 ok( hr == S_OK, "got %08x\n", hr );
4204 hr = WsReadCharsUtf8( reader, buf, 0, NULL, NULL );
4205 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4207 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4208 ok( hr == S_OK, "got %08x\n", hr );
4210 count = 0xdeadbeef;
4211 hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL );
4212 ok( hr == S_OK, "got %08x\n", hr );
4213 ok( !count, "got %u\n", count );
4215 count = 0xdeadbeef;
4216 hr = WsReadCharsUtf8( reader, NULL, 1, &count, NULL );
4217 ok( hr == S_OK, "got %08x\n", hr );
4218 ok( !count, "got %u\n", count );
4220 buf[0] = 0;
4221 count = 0xdeadbeef;
4222 hr = WsReadCharsUtf8( reader, buf, 0, &count, NULL );
4223 ok( hr == S_OK, "got %08x\n", hr );
4224 ok( !count, "got %u\n", count );
4225 ok( !buf[0], "wrong data\n" );
4227 buf[0] = 0;
4228 count = 0xdeadbeef;
4229 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4230 ok( hr == S_OK, "got %08x\n", hr );
4231 ok( !count, "got %u\n", count );
4232 ok( !buf[0], "wrong data\n" );
4234 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4235 ok( hr == S_OK, "got %08x\n", hr );
4237 buf[0] = 0;
4238 count = 0xdeadbeef;
4239 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4240 ok( hr == S_OK, "got %08x\n", hr );
4241 ok( !count, "got %u\n", count );
4242 ok( !buf[0], "wrong data\n" );
4244 hr = WsReadStartElement( reader, NULL );
4245 ok( hr == S_OK, "got %08x\n", hr );
4247 count = 0xdeadbeef;
4248 hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL );
4249 ok( hr == S_OK, "got %08x\n", hr );
4250 ok( !count, "got %u\n", count );
4252 buf[0] = 0;
4253 count = 0xdeadbeef;
4254 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4255 ok( hr == S_OK, "got %08x\n", hr );
4256 ok( count == 2, "got %u\n", count );
4257 ok( !memcmp( buf, "te", 2 ), "wrong data\n" );
4259 hr = WsGetReaderNode( reader, &node, NULL );
4260 ok( hr == S_OK, "got %08x\n", hr );
4261 text = (const WS_XML_TEXT_NODE *)node;
4262 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4263 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4264 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4265 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4266 ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" );
4268 buf[0] = 0;
4269 count = 0xdeadbeef;
4270 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4271 ok( hr == S_OK, "got %08x\n", hr );
4272 ok( count == 2, "got %u\n", count );
4273 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4275 hr = WsGetReaderNode( reader, &node, NULL );
4276 ok( hr == S_OK, "got %08x\n", hr );
4277 text = (const WS_XML_TEXT_NODE *)node;
4278 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4280 count = 0xdeadbeef;
4281 hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL );
4282 ok( hr == S_OK, "got %08x\n", hr );
4283 ok( !count, "got %u\n", count );
4285 hr = WsGetReaderNode( reader, &node, NULL );
4286 ok( hr == S_OK, "got %08x\n", hr );
4287 text = (const WS_XML_TEXT_NODE *)node;
4288 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4290 WsFreeReader( reader );
4293 static void test_WsReadQualifiedName(void)
4295 static const char utf8[] = {'<','a','>',0xc3,0xab,'<','/','a','>',0};
4296 static const char localname_utf8[] = {0xc3,0xab,0};
4297 WS_XML_STRING prefix, localname, ns;
4298 WS_XML_READER *reader;
4299 WS_HEAP *heap;
4300 HRESULT hr;
4301 BOOL found;
4302 ULONG i;
4303 static const struct
4305 const char *str;
4306 HRESULT hr;
4307 const char *prefix;
4308 const char *localname;
4309 const char *ns;
4310 } tests[] =
4312 { "<a></a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4313 { "<a> </a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4314 { "<a>:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4315 { "<a>t</a>", S_OK, "", "t", "" },
4316 { "<a>p:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4317 { "<a>p:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4318 { "<a>:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4319 { "<a xmlns:p=\"ns\">p:t</a>", S_OK, "p", "t", "ns" },
4320 { "<a xmlns:p=\"ns\">p:t:</a>", S_OK, "p", "t:", "ns" },
4321 { "<a xmlns:p=\"ns\">p:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4322 { "<a xmlns:p=\"ns\">:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4323 { "<a xmlns:p=\"ns\">:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4324 { "<a xmlns:p=\"ns\">t</a>", S_OK, "", "t", "" },
4325 { "<a xmlns:p=\"ns\"> </a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4326 { "<a xmlns:p=\"ns\"></a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4327 { "<a xmlns:p=\"ns\">p:t u</a>", S_OK, "p", "t u", "ns" },
4328 { utf8, S_OK, "", localname_utf8, "" },
4329 { "<a> t </a>", S_OK, "", "t", "" },
4330 { "<a xmlns:p=\"ns\"> p:t</a>", S_OK, "p", "t", "ns" },
4331 { "<a xmlns:p=\"ns\">p :t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4332 { "<a xmlns:p=\"ns\">p: t</a>", S_OK, "p", " t", "ns" },
4335 hr = WsReadQualifiedName( NULL, NULL, NULL, NULL, NULL, NULL );
4336 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4338 hr = WsCreateReader( NULL, 0, &reader, NULL );
4339 ok( hr == S_OK, "got %08x\n", hr );
4341 hr = WsReadQualifiedName( reader, NULL, NULL, NULL, NULL, NULL );
4342 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4344 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
4345 ok( hr == S_OK, "got %08x\n", hr );
4347 hr = WsReadQualifiedName( reader, heap, NULL, NULL, NULL, NULL );
4348 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4350 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4351 ok( hr == S_OK, "got %08x\n", hr );
4352 hr = WsReadQualifiedName( reader, heap, NULL, NULL, NULL, NULL );
4353 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4355 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4356 ok( hr == S_OK, "got %08x\n", hr );
4357 hr = WsReadQualifiedName( reader, heap, NULL, &localname, NULL, NULL );
4358 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
4360 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
4362 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
4363 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4365 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4366 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4368 hr = WsReadStartElement( reader, NULL );
4369 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4371 prefix.length = localname.length = ns.length = 0xdeadbeef;
4372 prefix.bytes = localname.bytes = ns.bytes = (BYTE *)0xdeadbeef;
4374 hr = WsReadQualifiedName( reader, heap, &prefix, &localname, &ns, NULL );
4375 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
4376 if (tests[i].hr == S_OK && hr == S_OK)
4378 ok( prefix.length == strlen( tests[i].prefix ), "%u: got %u\n", i, prefix.length );
4379 ok( !memcmp( prefix.bytes, tests[i].prefix, prefix.length ), "%u: wrong data\n", i );
4381 ok( localname.length == strlen( tests[i].localname ), "%u: got %u\n", i, localname.length );
4382 ok( !memcmp( localname.bytes, tests[i].localname, localname.length ), "%u: wrong data\n", i );
4384 ok( ns.length == strlen( tests[i].ns ), "%u: got %u\n", i, ns.length );
4385 ok( !memcmp( ns.bytes, tests[i].ns, ns.length ), "%u: wrong data\n", i );
4387 else if (tests[i].hr != S_OK)
4389 ok( prefix.length == 0xdeadbeef, "got %u\n", prefix.length );
4390 ok( prefix.bytes == (BYTE *)0xdeadbeef, "got %p\n", prefix.bytes );
4392 ok( localname.length == 0xdeadbeef, "got %u\n", localname.length );
4393 ok( localname.bytes == (BYTE *)0xdeadbeef, "got %p\n", localname.bytes );
4395 ok( ns.length == 0xdeadbeef, "got %u\n", ns.length );
4396 ok( ns.bytes == (BYTE *)0xdeadbeef, "got %p\n", ns.bytes );
4400 WsFreeHeap( heap );
4401 WsFreeReader( reader );
4404 static void test_WsReadAttribute(void)
4406 WS_XML_STRING localname = {1, (BYTE *)"a"}, ns = {0, NULL};
4407 WS_XML_READER *reader;
4408 WS_ATTRIBUTE_DESCRIPTION desc;
4409 WS_HEAP *heap;
4410 UINT32 *val;
4411 BOOL found;
4412 HRESULT hr;
4414 hr = WsReadAttribute( NULL, NULL, 0, NULL, NULL, 0, NULL );
4415 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4417 hr = WsCreateReader( NULL, 0, &reader, NULL );
4418 ok( hr == S_OK, "got %08x\n", hr );
4420 hr = WsReadAttribute( reader, NULL, 0, NULL, NULL, 0, NULL );
4421 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4423 desc.attributeLocalName = &localname;
4424 desc.attributeNs = &ns;
4425 desc.type = WS_UINT32_TYPE;
4426 desc.typeDescription = NULL;
4427 hr = WsReadAttribute( reader, &desc, 0, NULL, NULL, 0, NULL );
4428 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4430 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, NULL, NULL, 0, NULL );
4431 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4433 hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL );
4434 ok( hr == S_OK, "got %08x\n", hr );
4436 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, NULL, 0, NULL );
4437 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4439 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, &val, sizeof(val), NULL );
4440 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4442 prepare_struct_type_test( reader, "<t a='1'>" );
4443 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4444 ok( hr == S_OK, "got %08x\n", hr );
4446 val = NULL;
4447 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, &val, sizeof(val), NULL );
4448 ok( hr == S_OK, "got %08x\n", hr );
4449 ok( val != NULL, "val not set\n" );
4450 ok( *val == 1, "got %u\n", *val );
4452 WsFreeHeap( heap );
4453 WsFreeReader( reader );
4456 static void test_WsSkipNode(void)
4458 const WS_XML_NODE *node;
4459 WS_XML_READER *reader;
4460 HRESULT hr;
4462 hr = WsSkipNode( NULL, NULL );
4463 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4465 hr = WsCreateReader( NULL, 0, &reader, NULL );
4466 ok( hr == S_OK, "got %08x\n", hr );
4468 hr = WsSkipNode( reader, NULL );
4469 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4471 hr = set_input( reader, "<t><u></u></t>", sizeof("<t><u></u></t>") - 1 );
4472 ok( hr == S_OK, "got %08x\n", hr );
4474 hr = WsGetReaderNode( reader, &node, NULL );
4475 ok( hr == S_OK, "got %08x\n", hr );
4476 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
4478 /* BOF */
4479 hr = WsSkipNode( reader, NULL );
4480 ok( hr == S_OK, "got %08x\n", hr );
4481 hr = WsGetReaderNode( reader, &node, NULL );
4482 ok( hr == S_OK, "got %08x\n", hr );
4483 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4485 /* element */
4486 hr = WsSkipNode( reader, NULL );
4487 ok( hr == S_OK, "got %08x\n", hr );
4488 hr = WsGetReaderNode( reader, &node, NULL );
4489 ok( hr == S_OK, "got %08x\n", hr );
4490 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
4492 /* EOF */
4493 hr = WsSkipNode( reader, NULL );
4494 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4496 hr = set_input( reader, "<!--comment--><t></t>", sizeof("<!--comment--><t></t>") - 1 );
4497 ok( hr == S_OK, "got %08x\n", hr );
4499 /* non-element */
4500 hr = WsSkipNode( reader, NULL );
4501 ok( hr == S_OK, "got %08x\n", hr );
4502 hr = WsGetReaderNode( reader, &node, NULL );
4503 ok( hr == S_OK, "got %08x\n", hr );
4504 ok( node->nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", node->nodeType );
4506 hr = WsSkipNode( reader, NULL );
4507 ok( hr == S_OK, "got %08x\n", hr );
4508 hr = WsGetReaderNode( reader, &node, NULL );
4509 ok( hr == S_OK, "got %08x\n", hr );
4510 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4512 WsFreeReader( reader );
4515 static HRESULT set_input_bin( WS_XML_READER *reader, const char *data, ULONG size, WS_XML_DICTIONARY *dict )
4517 WS_XML_READER_BINARY_ENCODING bin = {{WS_XML_READER_ENCODING_TYPE_BINARY}, dict};
4518 WS_XML_READER_BUFFER_INPUT buf;
4520 buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
4521 buf.encodedData = (void *)data;
4522 buf.encodedDataSize = size;
4523 return WsSetInput( reader, &bin.encoding, &buf.input, NULL, 0, NULL );
4526 static void test_binary_encoding(void)
4528 static const char res[] =
4529 {0x40,0x01,'t',0x01};
4530 static const char res2[] =
4531 {0x6d,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01};
4532 static const char res3[] =
4533 {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x01};
4534 static const char res4[] =
4535 {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x99,0x04,'t','e','s','t'};
4536 static const char res100[] =
4537 {0x40,0x01,'t',0x04,0x01,'t',0x98,0x00,0x01};
4538 static const char res101[] =
4539 {0x40,0x01,'t',0x35,0x01,'t',0x98,0x00,0x09,0x01,'p',0x02,'n','s',0x01};
4540 static const char res102[] =
4541 {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x00,0x09,0x02,'p','2',0x02,'n','s',0x01};
4542 static const char res103[] =
4543 {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x04,'t','e','s','t',0x09,0x02,'p','2',0x02,'n','s',0x01};
4544 static const char res200[] =
4545 {0x02,0x07,'c','o','m','m','e','n','t'};
4546 const WS_XML_NODE *node;
4547 const WS_XML_ELEMENT_NODE *elem;
4548 const WS_XML_ATTRIBUTE *attr;
4549 const WS_XML_TEXT_NODE *text;
4550 const WS_XML_UTF8_TEXT *utf8;
4551 const WS_XML_COMMENT_NODE *comment;
4552 WS_XML_READER *reader;
4553 BOOL found;
4554 HRESULT hr;
4556 hr = WsCreateReader( NULL, 0, &reader, NULL );
4557 ok( hr == S_OK, "got %08x\n", hr );
4559 /* short element */
4560 hr = set_input_bin( reader, res, sizeof(res), NULL );
4561 ok( hr == S_OK, "got %08x\n", hr );
4563 hr = WsReadNode( reader, NULL );
4564 ok( hr == S_OK, "got %08x\n", hr );
4565 hr = WsGetReaderNode( reader, &node, NULL );
4566 ok( hr == S_OK, "got %08x\n", hr );
4567 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4568 elem = (const WS_XML_ELEMENT_NODE *)node;
4569 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
4570 ok( elem->prefix->bytes == NULL, "bytes set\n" );
4571 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4572 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4573 ok( elem->localName->dictionary != NULL, "dictionary not set\n" );
4574 ok( !elem->ns->length, "got %u\n", elem->ns->length );
4575 ok( elem->ns->bytes != NULL, "bytes not set\n" );
4576 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
4577 ok( !elem->isEmpty, "empty\n" );
4579 hr = WsReadNode( reader, NULL );
4580 ok( hr == S_OK, "got %08x\n", hr );
4581 hr = WsGetReaderNode( reader, &node, NULL );
4582 ok( hr == S_OK, "got %08x\n", hr );
4583 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4585 /* single character prefix element */
4586 hr = set_input_bin( reader, res2, sizeof(res2), NULL );
4587 ok( hr == S_OK, "got %08x\n", hr );
4589 hr = WsReadNode( reader, NULL );
4590 ok( hr == S_OK, "got %08x\n", hr );
4591 hr = WsGetReaderNode( reader, &node, NULL );
4592 ok( hr == S_OK, "got %08x\n", hr );
4593 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4594 elem = (const WS_XML_ELEMENT_NODE *)node;
4595 ok( elem->prefix->length == 1, "got %u\n", elem->prefix->length );
4596 ok( !memcmp( elem->prefix->bytes, "p", 1 ), "wrong prefix\n" );
4597 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4598 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4599 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
4600 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4601 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
4602 ok( !elem->isEmpty, "empty\n" );
4603 attr = elem->attributes[0];
4604 ok( !attr->singleQuote, "single quote\n" );
4605 ok( attr->isXmlNs, "not xmlns\n" );
4606 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
4607 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
4608 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4609 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4611 hr = WsReadNode( reader, NULL );
4612 ok( hr == S_OK, "got %08x\n", hr );
4613 hr = WsGetReaderNode( reader, &node, NULL );
4614 ok( hr == S_OK, "got %08x\n", hr );
4615 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4617 /* element */
4618 hr = set_input_bin( reader, res3, sizeof(res3), NULL );
4619 ok( hr == S_OK, "got %08x\n", hr );
4621 hr = WsReadNode( reader, NULL );
4622 ok( hr == S_OK, "got %08x\n", hr );
4623 hr = WsGetReaderNode( reader, &node, NULL );
4624 ok( hr == S_OK, "got %08x\n", hr );
4625 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4626 elem = (const WS_XML_ELEMENT_NODE *)node;
4627 ok( elem->prefix->length == 2, "got %u\n", elem->prefix->length );
4628 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4629 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4630 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4631 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
4632 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4633 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
4634 ok( !elem->isEmpty, "empty\n" );
4635 attr = elem->attributes[0];
4636 ok( !attr->singleQuote, "single quote\n" );
4637 ok( attr->isXmlNs, "not xmlns\n" );
4638 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
4639 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4640 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4641 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4643 hr = WsReadNode( reader, NULL );
4644 ok( hr == S_OK, "got %08x\n", hr );
4645 hr = WsGetReaderNode( reader, &node, NULL );
4646 ok( hr == S_OK, "got %08x\n", hr );
4647 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4649 /* element with text */
4650 hr = set_input_bin( reader, res4, sizeof(res4), NULL );
4651 ok( hr == S_OK, "got %08x\n", hr );
4653 hr = WsReadNode( reader, NULL );
4654 ok( hr == S_OK, "got %08x\n", hr );
4655 hr = WsGetReaderNode( reader, &node, NULL );
4656 ok( hr == S_OK, "got %08x\n", hr );
4657 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4658 elem = (const WS_XML_ELEMENT_NODE *)node;
4659 ok( elem->prefix->length == 2, "got %u\n", elem->prefix->length );
4660 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4661 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4662 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4663 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
4664 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4665 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
4666 ok( !elem->isEmpty, "empty\n" );
4667 attr = elem->attributes[0];
4668 ok( !attr->singleQuote, "single quote\n" );
4669 ok( attr->isXmlNs, "not xmlns\n" );
4670 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
4671 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4672 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4673 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4675 hr = WsReadNode( reader, NULL );
4676 ok( hr == S_OK, "got %08x\n", hr );
4677 hr = WsGetReaderNode( reader, &node, NULL );
4678 ok( hr == S_OK, "got %08x\n", hr );
4679 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
4680 text = (const WS_XML_TEXT_NODE *)node;
4681 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4682 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4683 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4684 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong text\n" );
4686 hr = WsReadNode( reader, NULL );
4687 ok( hr == S_OK, "got %08x\n", hr );
4688 hr = WsGetReaderNode( reader, &node, NULL );
4689 ok( hr == S_OK, "got %08x\n", hr );
4690 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4692 /* short attribute */
4693 hr = set_input_bin( reader, res100, sizeof(res100), NULL );
4694 ok( hr == S_OK, "got %08x\n", hr );
4696 hr = WsReadNode( reader, NULL );
4697 ok( hr == S_OK, "got %08x\n", hr );
4698 hr = WsGetReaderNode( reader, &node, NULL );
4699 ok( hr == S_OK, "got %08x\n", hr );
4700 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4701 elem = (const WS_XML_ELEMENT_NODE *)node;
4702 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
4703 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4704 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4705 ok( !elem->ns->length, "got %u\n", elem->ns->length );
4706 ok( elem->ns->bytes != NULL, "bytes not set\n" );
4707 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
4708 ok( !elem->isEmpty, "empty\n" );
4709 attr = elem->attributes[0];
4710 ok( !attr->singleQuote, "single quote\n" );
4711 ok( !attr->isXmlNs, "is xmlns\n" );
4712 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
4713 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
4714 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
4715 ok( !attr->ns->length, "got %u\n", attr->ns->length );
4716 ok( elem->ns->bytes != NULL, "bytes not set\n" );
4717 ok( attr->value != NULL, "value not set\n" );
4718 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
4719 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
4720 ok( !utf8->value.length, "got %u\n", utf8->value.length );
4721 ok( utf8->value.bytes != NULL, "bytes not set\n" );
4723 hr = WsReadNode( reader, NULL );
4724 ok( hr == S_OK, "got %08x\n", hr );
4725 hr = WsGetReaderNode( reader, &node, NULL );
4726 ok( hr == S_OK, "got %08x\n", hr );
4727 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4729 /* single character prefix attribute */
4730 hr = set_input_bin( reader, res101, sizeof(res101), NULL );
4731 ok( hr == S_OK, "got %08x\n", hr );
4733 hr = WsReadNode( reader, NULL );
4734 ok( hr == S_OK, "got %08x\n", hr );
4735 hr = WsGetReaderNode( reader, &node, NULL );
4736 ok( hr == S_OK, "got %08x\n", hr );
4737 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4738 elem = (const WS_XML_ELEMENT_NODE *)node;
4739 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
4740 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4741 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4742 ok( !elem->ns->length, "got %u\n", elem->ns->length );
4743 ok( elem->ns->bytes != NULL, "ns not set\n" );
4744 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
4745 ok( !elem->isEmpty, "empty\n" );
4746 attr = elem->attributes[0];
4747 ok( !attr->singleQuote, "single quote\n" );
4748 ok( !attr->isXmlNs, "is xmlns\n" );
4749 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
4750 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
4751 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
4752 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
4753 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4754 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4755 ok( attr->value != NULL, "value not set\n" );
4756 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
4757 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
4758 ok( !utf8->value.length, "got %u\n", utf8->value.length );
4759 ok( utf8->value.bytes != NULL, "bytes not set\n" );
4760 attr = elem->attributes[1];
4761 ok( !attr->singleQuote, "single quote\n" );
4762 ok( attr->isXmlNs, "not xmlns\n" );
4763 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
4764 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
4765 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4766 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4768 hr = WsReadNode( reader, NULL );
4769 ok( hr == S_OK, "got %08x\n", hr );
4770 hr = WsGetReaderNode( reader, &node, NULL );
4771 ok( hr == S_OK, "got %08x\n", hr );
4772 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4774 /* attribute */
4775 hr = set_input_bin( reader, res102, sizeof(res102), NULL );
4776 ok( hr == S_OK, "got %08x\n", hr );
4778 hr = WsReadNode( reader, NULL );
4779 ok( hr == S_OK, "got %08x\n", hr );
4780 hr = WsGetReaderNode( reader, &node, NULL );
4781 ok( hr == S_OK, "got %08x\n", hr );
4782 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4783 elem = (const WS_XML_ELEMENT_NODE *)node;
4784 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
4785 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4786 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4787 ok( !elem->ns->length, "got %u\n", elem->ns->length );
4788 ok( elem->ns->bytes != NULL, "ns not set\n" );
4789 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
4790 ok( !elem->isEmpty, "empty\n" );
4791 attr = elem->attributes[0];
4792 ok( !attr->singleQuote, "single quote\n" );
4793 ok( !attr->isXmlNs, "is xmlns\n" );
4794 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
4795 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4796 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
4797 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
4798 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4799 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4800 ok( attr->value != NULL, "value not set\n" );
4801 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
4802 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
4803 ok( !utf8->value.length, "got %u\n", utf8->value.length );
4804 ok( utf8->value.bytes != NULL, "bytes not set\n" );
4805 attr = elem->attributes[1];
4806 ok( !attr->singleQuote, "single quote\n" );
4807 ok( attr->isXmlNs, "not xmlns\n" );
4808 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
4809 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4810 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4811 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4813 hr = WsReadNode( reader, NULL );
4814 ok( hr == S_OK, "got %08x\n", hr );
4815 hr = WsGetReaderNode( reader, &node, NULL );
4816 ok( hr == S_OK, "got %08x\n", hr );
4817 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4819 /* attribute with value */
4820 hr = set_input_bin( reader, res103, sizeof(res103), NULL );
4821 ok( hr == S_OK, "got %08x\n", hr );
4823 hr = WsReadNode( reader, NULL );
4824 ok( hr == S_OK, "got %08x\n", hr );
4825 hr = WsGetReaderNode( reader, &node, NULL );
4826 ok( hr == S_OK, "got %08x\n", hr );
4827 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4828 elem = (const WS_XML_ELEMENT_NODE *)node;
4829 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
4830 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4831 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4832 ok( !elem->ns->length, "got %u\n", elem->ns->length );
4833 ok( elem->ns->bytes != NULL, "ns not set\n" );
4834 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
4835 ok( !elem->isEmpty, "empty\n" );
4836 attr = elem->attributes[0];
4837 ok( !attr->singleQuote, "single quote\n" );
4838 ok( !attr->isXmlNs, "is xmlns\n" );
4839 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
4840 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4841 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
4842 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
4843 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4844 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4845 ok( attr->value != NULL, "value not set\n" );
4846 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
4847 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
4848 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4849 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong value\n" );
4850 attr = elem->attributes[1];
4851 ok( !attr->singleQuote, "single quote\n" );
4852 ok( attr->isXmlNs, "not xmlns\n" );
4853 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
4854 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4855 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4856 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4858 hr = WsReadNode( reader, NULL );
4859 ok( hr == S_OK, "got %08x\n", hr );
4860 hr = WsGetReaderNode( reader, &node, NULL );
4861 ok( hr == S_OK, "got %08x\n", hr );
4862 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4864 hr = WsReadNode( reader, NULL );
4865 ok( hr == S_OK, "got %08x\n", hr );
4866 hr = WsGetReaderNode( reader, &node, NULL );
4867 ok( hr == S_OK, "got %08x\n", hr );
4868 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
4870 /* comment */
4871 hr = set_input_bin( reader, res200, sizeof(res200), NULL );
4872 ok( hr == S_OK, "got %08x\n", hr );
4874 hr = WsReadNode( reader, NULL );
4875 ok( hr == S_OK, "got %08x\n", hr );
4876 hr = WsGetReaderNode( reader, &node, NULL );
4877 ok( hr == S_OK, "got %08x\n", hr );
4878 ok( node->nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", node->nodeType );
4879 comment = (const WS_XML_COMMENT_NODE *)node;
4880 ok( comment->value.length == 7, "got %u\n", comment->value.length );
4881 ok( !memcmp( comment->value.bytes, "comment", 7 ), "wrong data\n" );
4883 hr = set_input_bin( reader, res, sizeof(res), NULL );
4884 ok( hr == S_OK, "got %08x\n", hr );
4886 found = -1;
4887 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4888 ok( hr == S_OK, "got %08x\n", hr );
4889 ok( found == TRUE, "got %d\n", found );
4890 hr = WsReadStartElement( reader, NULL );
4891 ok( hr == S_OK, "got %08x\n", hr );
4892 hr = WsReadEndElement( reader, NULL );
4893 ok( hr == S_OK, "got %08x\n", hr );
4895 WsFreeReader( reader );
4898 static void test_dictionary(void)
4900 static const char res[] =
4901 {0x42,0x04,0x01};
4902 static const char res2[] =
4903 {0x53,0x06,0x0b,0x01,'p',0x0a,0x01};
4904 static const char res3[] =
4905 {0x43,0x02,'p','2',0x06,0x0b,0x02,'p','2',0x0a,0x01};
4906 static const char res4[] =
4907 {0x42,0x06,0x06,0x06,0x98,0x00,0x01};
4908 static const char res5[] =
4909 {0x42,0x06,0x1b,0x06,0x98,0x00,0x0b,0x01,'p',0x0a,0x01};
4910 static const char res6[] =
4911 {0x42,0x06,0x07,0x02,'p','2',0x06,0x98,0x00,0x0b,0x02,'p','2',0x0a,0x01};
4912 const WS_XML_NODE *node;
4913 const WS_XML_ELEMENT_NODE *elem;
4914 const WS_XML_ATTRIBUTE *attr;
4915 const WS_XML_UTF8_TEXT *utf8;
4916 WS_XML_STRING strings[6];
4917 WS_XML_DICTIONARY dict, *dict2;
4918 WS_XML_READER *reader;
4919 HRESULT hr;
4921 hr = WsCreateReader( NULL, 0, &reader, NULL );
4922 ok( hr == S_OK, "got %08x\n", hr );
4924 strings[0].length = 0;
4925 strings[0].bytes = NULL;
4926 strings[0].dictionary = &dict;
4927 strings[0].id = 0;
4928 strings[1].length = 1;
4929 strings[1].bytes = (BYTE *)"p";
4930 strings[1].dictionary = &dict;
4931 strings[1].id = 1;
4932 strings[2].length = 1;
4933 strings[2].bytes = (BYTE *)"t";
4934 strings[2].dictionary = &dict;
4935 strings[2].id = ~0u;
4936 strings[3].length = 1;
4937 strings[3].bytes = (BYTE *)"u";
4938 strings[3].dictionary = &dict;
4939 strings[3].id = 3;
4940 strings[4].length = 2;
4941 strings[4].bytes = (BYTE *)"p2";
4942 strings[4].dictionary = &dict;
4943 strings[4].id = 4;
4944 strings[5].length = 2;
4945 strings[5].bytes = (BYTE *)"ns";
4946 strings[5].dictionary = &dict;
4947 strings[5].id = 5;
4949 UuidCreate( &dict.guid );
4950 dict.strings = strings;
4951 dict.stringCount = sizeof(strings)/sizeof(strings[0]);
4952 dict.isConst = TRUE;
4954 /* short dictionary element */
4955 hr = set_input_bin( reader, res, sizeof(res), &dict );
4956 ok( hr == S_OK, "got %08x\n", hr );
4958 hr = WsReadNode( reader, NULL );
4959 ok( hr == S_OK, "got %08x\n", hr );
4960 hr = WsGetReaderNode( reader, &node, NULL );
4961 ok( hr == S_OK, "got %08x\n", hr );
4962 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4963 elem = (const WS_XML_ELEMENT_NODE *)node;
4964 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
4965 ok( elem->prefix->bytes == NULL, "bytes set\n" );
4966 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4967 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4968 ok( elem->localName->dictionary == &dict, "unexpected dict\n" );
4969 ok( elem->localName->id == ~0u, "unexpected id %08x\n", elem->localName->id );
4970 ok( !elem->ns->length, "got %u\n", elem->ns->length );
4971 ok( elem->ns->bytes != NULL, "bytes not set\n" );
4972 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
4973 ok( !elem->isEmpty, "empty\n" );
4975 hr = WsReadNode( reader, NULL );
4976 ok( hr == S_OK, "got %08x\n", hr );
4977 hr = WsGetReaderNode( reader, &node, NULL );
4978 ok( hr == S_OK, "got %08x\n", hr );
4979 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4981 /* single character prefix dictionary element */
4982 hr = set_input_bin( reader, res2, sizeof(res2), &dict );
4983 ok( hr == S_OK, "got %08x\n", hr );
4985 hr = WsReadNode( reader, NULL );
4986 ok( hr == S_OK, "got %08x\n", hr );
4987 hr = WsGetReaderNode( reader, &node, NULL );
4988 ok( hr == S_OK, "got %08x\n", hr );
4989 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4990 elem = (const WS_XML_ELEMENT_NODE *)node;
4991 ok( elem->prefix->length == 1, "got %u\n", elem->prefix->length );
4992 ok( !memcmp( elem->prefix->bytes, "p", 1 ), "wrong prefix\n" );
4993 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4994 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
4995 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
4996 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4997 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
4998 ok( !elem->isEmpty, "empty\n" );
4999 attr = elem->attributes[0];
5000 ok( !attr->singleQuote, "single quote\n" );
5001 ok( attr->isXmlNs, "not xmlns\n" );
5002 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5003 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5004 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5005 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5006 ok( attr->ns->dictionary == &dict, "unexpected dict\n" );
5007 ok( attr->ns->id == 5, "unexpected id %08x\n", attr->ns->id );
5009 hr = WsReadNode( reader, NULL );
5010 ok( hr == S_OK, "got %08x\n", hr );
5011 hr = WsGetReaderNode( reader, &node, NULL );
5012 ok( hr == S_OK, "got %08x\n", hr );
5013 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5015 /* dictionary element */
5016 hr = set_input_bin( reader, res3, sizeof(res3), &dict );
5017 ok( hr == S_OK, "got %08x\n", hr );
5019 hr = WsReadNode( reader, NULL );
5020 ok( hr == S_OK, "got %08x\n", hr );
5021 hr = WsGetReaderNode( reader, &node, NULL );
5022 ok( hr == S_OK, "got %08x\n", hr );
5023 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5024 elem = (const WS_XML_ELEMENT_NODE *)node;
5025 ok( elem->prefix->length == 2, "got %u\n", elem->prefix->length );
5026 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5027 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5028 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5029 ok( elem->localName->dictionary == &dict, "unexpected dict\n" );
5030 ok( elem->localName->id == 3, "unexpected id %08x\n", elem->localName->id );
5031 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
5032 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5033 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5034 ok( !elem->isEmpty, "empty\n" );
5035 attr = elem->attributes[0];
5036 ok( !attr->singleQuote, "single quote\n" );
5037 ok( attr->isXmlNs, "not xmlns\n" );
5038 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5039 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5040 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5041 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5043 hr = WsReadNode( reader, NULL );
5044 ok( hr == S_OK, "got %08x\n", hr );
5045 hr = WsGetReaderNode( reader, &node, NULL );
5046 ok( hr == S_OK, "got %08x\n", hr );
5047 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5049 /* short dictionary attribute */
5050 hr = set_input_bin( reader, res4, sizeof(res4), &dict );
5051 ok( hr == S_OK, "got %08x\n", hr );
5053 hr = WsReadNode( reader, NULL );
5054 ok( hr == S_OK, "got %08x\n", hr );
5055 hr = WsGetReaderNode( reader, &node, NULL );
5056 ok( hr == S_OK, "got %08x\n", hr );
5057 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5058 elem = (const WS_XML_ELEMENT_NODE *)node;
5059 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5060 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5061 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5062 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5063 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5064 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
5065 ok( !elem->isEmpty, "empty\n" );
5066 attr = elem->attributes[0];
5067 ok( !attr->singleQuote, "single quote\n" );
5068 ok( !attr->isXmlNs, "is xmlns\n" );
5069 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
5070 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5071 ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
5072 ok( attr->localName->id == 3, "unexpected id %08x\n", attr->localName->id );
5073 ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
5074 ok( !attr->ns->length, "got %u\n", attr->ns->length );
5075 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5076 ok( attr->value != NULL, "value not set\n" );
5077 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5078 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5079 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5080 ok( utf8->value.bytes != NULL, "bytes not set\n" );
5082 hr = WsReadNode( reader, NULL );
5083 ok( hr == S_OK, "got %08x\n", hr );
5084 hr = WsGetReaderNode( reader, &node, NULL );
5085 ok( hr == S_OK, "got %08x\n", hr );
5086 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5088 /* single character prefix dictionary attribute */
5089 hr = set_input_bin( reader, res5, sizeof(res5), &dict );
5090 ok( hr == S_OK, "got %08x\n", hr );
5092 hr = WsReadNode( reader, NULL );
5093 ok( hr == S_OK, "got %08x\n", hr );
5094 hr = WsGetReaderNode( reader, &node, NULL );
5095 ok( hr == S_OK, "got %08x\n", hr );
5096 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5097 elem = (const WS_XML_ELEMENT_NODE *)node;
5098 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5099 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5100 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5101 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5102 ok( elem->ns->bytes != NULL, "ns not set\n" );
5103 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
5104 ok( !elem->isEmpty, "empty\n" );
5105 attr = elem->attributes[0];
5106 ok( !attr->singleQuote, "single quote\n" );
5107 ok( !attr->isXmlNs, "is xmlns\n" );
5108 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5109 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5110 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5111 ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
5112 ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
5113 ok( attr->localName->id == 3, "unexpected id %08x\n", attr->localName->id );
5114 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5115 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5116 ok( attr->value != NULL, "value not set\n" );
5117 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5118 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5119 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5120 ok( utf8->value.bytes != NULL, "bytes not set\n" );
5121 attr = elem->attributes[1];
5122 ok( !attr->singleQuote, "single quote\n" );
5123 ok( attr->isXmlNs, "not xmlns\n" );
5124 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
5125 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5126 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5127 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5129 hr = WsReadNode( reader, NULL );
5130 ok( hr == S_OK, "got %08x\n", hr );
5131 hr = WsGetReaderNode( reader, &node, NULL );
5132 ok( hr == S_OK, "got %08x\n", hr );
5133 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5135 /* dictionary attribute */
5136 hr = set_input_bin( reader, res6, sizeof(res6), &dict );
5137 ok( hr == S_OK, "got %08x\n", hr );
5139 hr = WsReadNode( reader, NULL );
5140 ok( hr == S_OK, "got %08x\n", hr );
5141 hr = WsGetReaderNode( reader, &node, NULL );
5142 ok( hr == S_OK, "got %08x\n", hr );
5143 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5144 elem = (const WS_XML_ELEMENT_NODE *)node;
5145 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
5146 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
5147 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
5148 ok( !elem->ns->length, "got %u\n", elem->ns->length );
5149 ok( elem->ns->bytes != NULL, "ns not set\n" );
5150 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
5151 ok( !elem->isEmpty, "empty\n" );
5152 attr = elem->attributes[0];
5153 ok( !attr->singleQuote, "single quote\n" );
5154 ok( !attr->isXmlNs, "is xmlns\n" );
5155 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5156 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5157 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
5158 ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
5159 ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
5160 ok( attr->localName->id == 3, "unexpected id %08x\n", attr->localName->id );
5161 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5162 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5163 ok( attr->value != NULL, "value not set\n" );
5164 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
5165 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
5166 ok( !utf8->value.length, "got %u\n", utf8->value.length );
5167 ok( utf8->value.bytes != NULL, "bytes not set\n" );
5168 attr = elem->attributes[1];
5169 ok( !attr->singleQuote, "single quote\n" );
5170 ok( attr->isXmlNs, "not xmlns\n" );
5171 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
5172 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5173 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
5174 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5176 hr = WsReadNode( reader, NULL );
5177 ok( hr == S_OK, "got %08x\n", hr );
5178 hr = WsGetReaderNode( reader, &node, NULL );
5179 ok( hr == S_OK, "got %08x\n", hr );
5180 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5182 hr = WsGetDictionary( 0, NULL, NULL );
5183 ok( hr == E_INVALIDARG, "got %08x\n", hr );
5185 hr = WsGetDictionary( WS_ENCODING_XML_UTF8, NULL, NULL );
5186 ok( hr == E_INVALIDARG, "got %08x\n", hr );
5188 dict2 = (WS_XML_DICTIONARY *)0xdeadbeef;
5189 hr = WsGetDictionary( WS_ENCODING_XML_UTF8, &dict2, NULL );
5190 ok( hr == S_OK, "got %08x\n", hr );
5191 ok( dict2 == NULL, "got %p\n", dict2 );
5193 dict2 = (WS_XML_DICTIONARY *)0xdeadbeef;
5194 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_1, &dict2, NULL );
5195 ok( hr == S_OK, "got %08x\n", hr );
5196 ok( dict2 != NULL, "dict2 not set\n" );
5197 ok( dict2 != &dict, "got %p\n", dict2 );
5199 dict2 = (WS_XML_DICTIONARY *)0xdeadbeef;
5200 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_SESSION_1, &dict2, NULL );
5201 ok( hr == S_OK, "got %08x\n", hr );
5202 ok( dict2 != NULL, "dict2 not set\n" );
5203 ok( dict2 != &dict, "got %p\n", dict2 );
5205 WsFreeReader( reader );
5208 START_TEST(reader)
5210 test_WsCreateError();
5211 test_WsCreateHeap();
5212 test_WsCreateReader();
5213 test_WsSetInput();
5214 test_WsSetInputToBuffer();
5215 test_WsFillReader();
5216 test_WsReadToStartElement();
5217 test_WsReadStartElement();
5218 test_WsReadEndElement();
5219 test_WsReadNode();
5220 test_WsReadType();
5221 test_WsGetXmlAttribute();
5222 test_WsXmlStringEquals();
5223 test_WsAlloc();
5224 test_WsMoveReader();
5225 test_simple_struct_type();
5226 test_cdata();
5227 test_WsFindAttribute();
5228 test_WsGetNamespaceFromPrefix();
5229 test_text_field_mapping();
5230 test_complex_struct_type();
5231 test_repeating_element();
5232 test_WsResetHeap();
5233 test_datetime();
5234 test_WsDateTimeToFileTime();
5235 test_WsFileTimeToDateTime();
5236 test_double();
5237 test_WsReadElement();
5238 test_WsReadValue();
5239 test_WsResetError();
5240 test_WsGetReaderPosition();
5241 test_WsSetReaderPosition();
5242 test_entities();
5243 test_field_options();
5244 test_WsReadBytes();
5245 test_WsReadChars();
5246 test_WsReadCharsUtf8();
5247 test_WsReadQualifiedName();
5248 test_WsReadAttribute();
5249 test_WsSkipNode();
5250 test_binary_encoding();
5251 test_dictionary();