webservices: Add support for reading GUID values.
[wine.git] / dlls / webservices / tests / reader.c
blob4997f7a01b2326e3aeac47f9a0cf6c996ea71f4d
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 "webservices.h"
22 #include "wine/test.h"
24 static const char data1[] =
25 "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
27 static const char data2[] =
28 {0xef,0xbb,0xbf,'<','t','e','x','t','>','t','e','s','t','<','/','t','e','x','t','>',0};
30 static const char data3[] =
31 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
32 "<text>test</TEXT>";
34 static const char data4[] =
35 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
36 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">\r\n"
37 " <o:services o:GenerationTime=\"2015-09-03T18:47:54\">\r\n"
38 " <!--Build: 16.0.6202.6852-->\r\n"
39 " <o:default>\r\n"
40 " <o:ticket o:headerName=\"Authorization\" o:headerValue=\"{}\" />\r\n"
41 " </o:default>\r\n"
42 " <o:service o:name=\"LiveOAuthLoginStart\">\r\n"
43 " <o:url>https://login.[Live.WebHost]/oauth20_authorize.srf</o:url>\r\n"
44 " </o:service>\r\n"
45 "</o:services>\r\n"
46 "</o:OfficeConfig>\r\n";
48 static const char data5[] =
49 "</text>";
51 static const char data6[] =
52 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
53 "<text attr= \"value\" attr2='value2'>test</text>";
55 static const char data7[] =
56 "<!-- comment -->";
58 static const char data8[] =
59 "<node1><node2>test</node2></node1>";
61 static const char data9[] =
62 "<text xml:attr=\"value\">test</text>";
64 static const char data10[] =
65 "<a></b>";
67 static const char data11[] =
68 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
69 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\">"
70 "<!--Build: 16.0.6202.6852-->"
71 "</o:services>"
72 "</o:OfficeConfig>";
74 static const char data12[] =
75 "<services>"
76 "<service><id>1</id></service>"
77 "<service><id>2</id></service>"
78 "</services>";
80 static const char data13[] =
81 "<services></services>";
83 static const char data14[] =
84 "<services>"
85 "<wrapper>"
86 "<service><id>1</id></service>"
87 "<service><id>2</id></service>"
88 "</wrapper>"
89 "</services>";
91 static const char data15[] =
92 "<services>"
93 "<wrapper>"
94 "<service>1</service>"
95 "<service>2</service>"
96 "</wrapper>"
97 "</services>";
99 static const char data16[] =
100 "<services>"
101 "<wrapper>"
102 "<service name='1'>1</service>"
103 "<service name='2'>2</service>"
104 "</wrapper>"
105 "</services>";
107 static void test_WsCreateError(void)
109 HRESULT hr;
110 WS_ERROR *error;
111 WS_ERROR_PROPERTY prop;
112 ULONG size, code, count;
113 LANGID langid;
115 hr = WsCreateError( NULL, 0, NULL );
116 ok( hr == E_INVALIDARG, "got %08x\n", hr );
118 error = NULL;
119 hr = WsCreateError( NULL, 0, &error );
120 ok( hr == S_OK, "got %08x\n", hr );
121 ok( error != NULL, "error not set\n" );
123 count = 0xdeadbeef;
124 size = sizeof(count);
125 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
126 ok( hr == S_OK, "got %08x\n", hr );
127 ok( !count, "got %u\n", count );
129 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
130 ok( hr == E_INVALIDARG, "got %08x\n", hr );
132 code = 0xdeadbeef;
133 size = sizeof(code);
134 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
135 ok( hr == S_OK, "got %08x\n", hr );
136 ok( !code, "got %u\n", code );
138 code = 0xdeadbeef;
139 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
140 ok( hr == S_OK, "got %08x\n", hr );
141 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
142 ok( hr == S_OK, "got %08x\n", hr );
143 ok( code == 0xdeadbeef, "got %u\n", code );
145 langid = 0xdead;
146 size = sizeof(langid);
147 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
148 ok( hr == S_OK, "got %08x\n", hr );
149 ok( langid == GetUserDefaultUILanguage(), "got %u\n", langid );
151 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
152 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
153 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
155 count = 0xdeadbeef;
156 size = sizeof(count);
157 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID + 1, &count, size );
158 ok( hr == E_INVALIDARG, "got %08x\n", hr );
159 ok( count == 0xdeadbeef, "got %u\n", count );
160 WsFreeError( error );
162 count = 1;
163 prop.id = WS_ERROR_PROPERTY_STRING_COUNT;
164 prop.value = &count;
165 prop.valueSize = sizeof(count);
166 hr = WsCreateError( &prop, 1, &error );
167 ok( hr == E_INVALIDARG, "got %08x\n", hr );
169 code = 0xdeadbeef;
170 prop.id = WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE;
171 prop.value = &code;
172 prop.valueSize = sizeof(code);
173 hr = WsCreateError( &prop, 1, &error );
174 ok( hr == E_INVALIDARG, "got %08x\n", hr );
176 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
177 prop.id = WS_ERROR_PROPERTY_LANGID;
178 prop.value = &langid;
179 prop.valueSize = sizeof(langid);
180 hr = WsCreateError( &prop, 1, &error );
181 ok( hr == S_OK, "got %08x\n", hr );
183 langid = 0xdead;
184 size = sizeof(langid);
185 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
186 ok( hr == S_OK, "got %08x\n", hr );
187 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
188 WsFreeError( error );
190 count = 0xdeadbeef;
191 prop.id = WS_ERROR_PROPERTY_LANGID + 1;
192 prop.value = &count;
193 prop.valueSize = sizeof(count);
194 hr = WsCreateError( &prop, 1, &error );
195 ok( hr == E_INVALIDARG, "got %08x\n", hr );
198 static void test_WsCreateHeap(void)
200 HRESULT hr;
201 WS_HEAP *heap;
202 WS_HEAP_PROPERTY prop;
203 SIZE_T max, trim, requested, actual;
204 ULONG size;
206 hr = WsCreateHeap( 0, 0, NULL, 0, NULL, NULL );
207 ok( hr == E_INVALIDARG, "got %08x\n", hr );
209 heap = NULL;
210 hr = WsCreateHeap( 0, 0, NULL, 0, &heap, NULL );
211 ok( hr == S_OK, "got %08x\n", hr );
212 ok( heap != NULL, "heap not set\n" );
213 WsFreeHeap( heap );
215 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, NULL, NULL );
216 ok( hr == E_INVALIDARG, "got %08x\n", hr );
218 heap = NULL;
219 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
220 ok( hr == S_OK, "got %08x\n", hr );
221 ok( heap != NULL, "heap not set\n" );
222 WsFreeHeap( heap );
224 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, &heap, NULL );
225 ok( hr == S_OK, "got %08x\n", hr );
227 max = 0xdeadbeef;
228 size = sizeof(max);
229 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_MAX_SIZE, &max, size, NULL );
230 ok( hr == S_OK, "got %08x\n", hr );
231 ok( max == 1 << 16, "got %u\n", (ULONG)max );
233 trim = 0xdeadbeef;
234 size = sizeof(trim);
235 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_TRIM_SIZE, &trim, size, NULL );
236 ok( hr == S_OK, "got %08x\n", hr );
237 ok( trim == 1 << 6, "got %u\n", (ULONG)trim );
239 requested = 0xdeadbeef;
240 size = sizeof(requested);
241 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
242 ok( hr == S_OK, "got %08x\n", hr );
243 ok( !requested, "got %u\n", (ULONG)requested );
245 actual = 0xdeadbeef;
246 size = sizeof(actual);
247 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
248 ok( hr == S_OK, "got %08x\n", hr );
249 ok( !actual, "got %u\n", (ULONG)actual );
251 actual = 0xdeadbeef;
252 size = sizeof(actual);
253 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE + 1, &actual, size, NULL );
254 ok( hr == E_INVALIDARG, "got %08x\n", hr );
255 ok( actual == 0xdeadbeef, "got %u\n", (ULONG)actual );
256 WsFreeHeap( heap );
258 max = 1 << 16;
259 prop.id = WS_HEAP_PROPERTY_MAX_SIZE;
260 prop.value = &max;
261 prop.valueSize = sizeof(max);
262 hr = WsCreateHeap( 1 << 16, 1 << 6, &prop, 1, &heap, NULL );
263 ok( hr == E_INVALIDARG, "got %08x\n", hr );
265 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 1, &heap, NULL );
266 ok( hr == E_INVALIDARG, "got %08x\n", hr );
269 static HRESULT set_input( WS_XML_READER *reader, const char *data, ULONG size )
271 WS_XML_READER_TEXT_ENCODING encoding;
272 WS_XML_READER_BUFFER_INPUT input;
274 encoding.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
275 encoding.charSet = WS_CHARSET_AUTO;
277 input.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
278 input.encodedData = (void *)data;
279 input.encodedDataSize = size;
281 return WsSetInput( reader, &encoding.encoding, &input.input, NULL, 0, NULL );
284 static void test_WsCreateReader(void)
286 HRESULT hr;
287 WS_XML_READER *reader;
288 WS_XML_READER_PROPERTY prop;
289 ULONG size, max_depth, max_attrs, trim_size, buffer_size, max_ns;
290 BOOL allow_fragment, read_decl, in_attr;
291 ULONGLONG row, column;
292 WS_CHARSET charset;
294 hr = WsCreateReader( NULL, 0, NULL, NULL ) ;
295 ok( hr == E_INVALIDARG, "got %08x\n", hr );
297 reader = NULL;
298 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
299 ok( hr == S_OK, "got %08x\n", hr );
300 ok( reader != NULL, "reader not set\n" );
302 /* can't retrieve properties before input is set */
303 max_depth = 0xdeadbeef;
304 size = sizeof(max_depth);
305 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
306 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
307 ok( max_depth == 0xdeadbeef, "max_depth set\n" );
309 hr = set_input( reader, data1, sizeof(data1) - 1 );
310 ok( hr == S_OK, "got %08x\n", hr );
312 /* check some defaults */
313 max_depth = 0xdeadbeef;
314 size = sizeof(max_depth);
315 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
316 ok( hr == S_OK, "got %08x\n", hr );
317 ok( max_depth == 32, "got %u\n", max_depth );
319 allow_fragment = TRUE;
320 size = sizeof(allow_fragment);
321 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_ALLOW_FRAGMENT, &allow_fragment, size, NULL );
322 ok( hr == S_OK, "got %08x\n", hr );
323 ok( !allow_fragment, "got %d\n", allow_fragment );
325 max_attrs = 0xdeadbeef;
326 size = sizeof(max_attrs);
327 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES, &max_attrs, size, NULL );
328 ok( hr == S_OK, "got %08x\n", hr );
329 ok( max_attrs == 128, "got %u\n", max_attrs );
331 read_decl = FALSE;
332 size = sizeof(read_decl);
333 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_READ_DECLARATION, &read_decl, size, NULL );
334 ok( hr == S_OK, "got %08x\n", hr );
335 ok( read_decl, "got %u\n", read_decl );
337 charset = 0xdeadbeef;
338 size = sizeof(charset);
339 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
340 ok( hr == S_OK, "got %08x\n", hr );
341 ok( charset == WS_CHARSET_UTF8, "got %u\n", charset );
343 size = sizeof(trim_size);
344 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_UTF8_TRIM_SIZE, &trim_size, size, NULL );
345 todo_wine ok( hr == E_INVALIDARG, "got %08x\n", hr );
346 WsFreeReader( reader );
348 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
349 ok( hr == S_OK, "got %08x\n", hr );
351 hr = set_input( reader, data1, sizeof(data1) - 1 );
352 ok( hr == S_OK, "got %08x\n", hr );
354 size = sizeof(buffer_size);
355 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_STREAM_BUFFER_SIZE, &buffer_size, size, NULL );
356 todo_wine ok( hr == E_INVALIDARG, "got %08x\n", hr );
357 WsFreeReader( reader );
359 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
360 ok( hr == S_OK, "got %08x\n", hr );
362 hr = set_input( reader, data1, sizeof(data1) - 1 );
363 ok( hr == S_OK, "got %08x\n", hr );
365 max_ns = 0xdeadbeef;
366 size = sizeof(max_ns);
367 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_NAMESPACES, &max_ns, size, NULL );
368 ok( hr == S_OK, "got %08x\n", hr );
369 ok( max_ns == 32, "got %u\n", max_ns );
370 WsFreeReader( reader );
372 /* change a property */
373 max_depth = 16;
374 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
375 prop.value = &max_depth;
376 prop.valueSize = sizeof(max_depth);
377 hr = WsCreateReader( &prop, 1, &reader, NULL ) ;
378 ok( hr == S_OK, "got %08x\n", hr );
380 hr = set_input( reader, data1, sizeof(data1) - 1 );
381 ok( hr == S_OK, "got %08x\n", hr );
383 max_depth = 0xdeadbeef;
384 size = sizeof(max_depth);
385 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
386 ok( hr == S_OK, "got %08x\n", hr );
387 ok( max_depth == 16, "got %u\n", max_depth );
388 WsFreeReader( reader );
390 /* show that some properties are read-only */
391 row = 1;
392 prop.id = WS_XML_READER_PROPERTY_ROW;
393 prop.value = &row;
394 prop.valueSize = sizeof(row);
395 hr = WsCreateReader( &prop, 1, &reader, NULL ) ;
396 ok( hr == E_INVALIDARG, "got %08x\n", hr );
398 column = 1;
399 prop.id = WS_XML_READER_PROPERTY_COLUMN;
400 prop.value = &column;
401 prop.valueSize = sizeof(column);
402 hr = WsCreateReader( &prop, 1, &reader, NULL ) ;
403 ok( hr == E_INVALIDARG, "got %08x\n", hr );
405 in_attr = TRUE;
406 prop.id = WS_XML_READER_PROPERTY_IN_ATTRIBUTE;
407 prop.value = &in_attr;
408 prop.valueSize = sizeof(in_attr);
409 hr = WsCreateReader( &prop, 1, &reader, NULL ) ;
410 ok( hr == E_INVALIDARG, "got %08x\n", hr );
413 static void test_WsSetInput(void)
415 static char test1[] = {0xef,0xbb,0xbf,'<','a','/','>'};
416 static char test2[] = {'<','a','/','>'};
417 static char test3[] = {'<','!','-','-'};
418 static char test4[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"',
419 ' ','e','n','c','o','d','i','n','g','=','"','u','t','f','-','8','"','?','>'};
420 static char test5[] = {'<','?','x','m','l',' ','e','n','c','o','d','i','n','g','=',
421 '"','u','t','f','-','8','"','?','>'};
422 static char test6[] = {'<','?','x','m','l'};
423 static char test7[] = {'<','?','y','m','l'};
424 static char test8[] = {'<','?'};
425 static char test9[] = {'<','!'};
426 static char test10[] = {0xff,0xfe,'<',0,'a',0,'/',0,'>',0};
427 static char test11[] = {'<',0,'a',0,'/',0,'>',0};
428 static char test12[] = {'<',0,'!',0,'-',0,'-',0};
429 static char test13[] = {'<',0,'?',0};
430 static char test14[] = {'a','b'};
431 static char test15[] = {'a','b','c'};
432 static char test16[] = {'a',0};
433 static char test17[] = {'a',0,'b',0};
434 static char test18[] = {'<',0,'a',0,'b',0};
435 static char test19[] = {'<',0,'a',0};
436 static char test20[] = {0,'a','b'};
437 static char test21[] = {0,0};
438 static char test22[] = {0,0,0};
439 static char test23[] = {'<',0,'?',0,'x',0,'m',0,'l',0};
440 HRESULT hr;
441 WS_XML_READER *reader;
442 WS_XML_READER_PROPERTY prop;
443 WS_XML_READER_TEXT_ENCODING enc;
444 WS_XML_READER_BUFFER_INPUT input;
445 WS_CHARSET charset;
446 const WS_XML_NODE *node;
447 ULONG i, size, max_depth;
448 static const struct
450 void *data;
451 ULONG size;
452 HRESULT hr;
453 WS_CHARSET charset;
454 int todo;
456 tests[] =
458 { test1, sizeof(test1), S_OK, WS_CHARSET_UTF8 },
459 { test2, sizeof(test2), S_OK, WS_CHARSET_UTF8 },
460 { test3, sizeof(test3), S_OK, WS_CHARSET_UTF8 },
461 { test4, sizeof(test4), S_OK, WS_CHARSET_UTF8 },
462 { test5, sizeof(test5), WS_E_INVALID_FORMAT, 0, 1 },
463 { test6, sizeof(test6), WS_E_INVALID_FORMAT, 0, 1 },
464 { test7, sizeof(test7), WS_E_INVALID_FORMAT, 0, 1 },
465 { test8, sizeof(test8), WS_E_INVALID_FORMAT, 0 },
466 { test9, sizeof(test9), WS_E_INVALID_FORMAT, 0 },
467 { test10, sizeof(test10), S_OK, WS_CHARSET_UTF16LE },
468 { test11, sizeof(test11), S_OK, WS_CHARSET_UTF16LE },
469 { test12, sizeof(test12), S_OK, WS_CHARSET_UTF16LE },
470 { test13, sizeof(test13), WS_E_INVALID_FORMAT, 0, 1 },
471 { test14, sizeof(test14), WS_E_INVALID_FORMAT, 0 },
472 { test15, sizeof(test15), S_OK, WS_CHARSET_UTF8 },
473 { test16, sizeof(test16), WS_E_INVALID_FORMAT, 0 },
474 { test17, sizeof(test17), S_OK, WS_CHARSET_UTF8 },
475 { test18, sizeof(test18), S_OK, WS_CHARSET_UTF16LE },
476 { test19, sizeof(test19), S_OK, WS_CHARSET_UTF16LE },
477 { test20, sizeof(test20), S_OK, WS_CHARSET_UTF8 },
478 { test21, sizeof(test21), WS_E_INVALID_FORMAT, 0 },
479 { test22, sizeof(test22), S_OK, WS_CHARSET_UTF8 },
480 { test23, sizeof(test23), WS_E_INVALID_FORMAT, 0, 1 },
483 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
484 ok( hr == S_OK, "got %08x\n", hr );
486 hr = WsSetInput( NULL, NULL, NULL, NULL, 0, NULL );
487 ok( hr == E_INVALIDARG, "got %08x\n", hr );
489 node = NULL;
490 hr = WsGetReaderNode( reader, &node, NULL );
491 ok( hr == S_OK, "got %08x\n", hr );
492 ok( node != NULL, "node not set\n" );
493 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
495 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
496 enc.charSet = WS_CHARSET_UTF8;
498 input.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
499 input.encodedData = (void *)data1;
500 input.encodedDataSize = sizeof(data1) - 1;
502 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
503 ok( hr == S_OK, "got %08x\n", hr );
505 node = NULL;
506 hr = WsGetReaderNode( reader, &node, NULL );
507 ok( hr == S_OK, "got %08x\n", hr );
508 ok( node != NULL, "node not set\n" );
509 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
511 /* multiple calls are allowed */
512 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
513 ok( hr == S_OK, "got %08x\n", hr );
515 /* charset is detected by WsSetInput */
516 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
517 enc.charSet = WS_CHARSET_AUTO;
519 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
521 input.encodedData = tests[i].data;
522 input.encodedDataSize = tests[i].size;
523 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
524 ok( hr == S_OK, "%u: got %08x\n", i, hr );
526 charset = 0xdeadbeef;
527 size = sizeof(charset);
528 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
529 todo_wine_if (tests[i].todo)
531 ok( hr == tests[i].hr, "%u: got %08x expected %08x\n", i, hr, tests[i].hr );
532 if (hr == S_OK)
533 ok( charset == tests[i].charset, "%u: got %u expected %u\n", i, charset, tests[i].charset );
537 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
538 enc.charSet = WS_CHARSET_UTF8;
540 /* reader properties can be set with WsSetInput */
541 max_depth = 16;
542 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
543 prop.value = &max_depth;
544 prop.valueSize = sizeof(max_depth);
545 hr = WsSetInput( reader, &enc.encoding, &input.input, &prop, 1, NULL );
546 ok( hr == S_OK, "got %08x\n", hr );
548 max_depth = 0xdeadbeef;
549 size = sizeof(max_depth);
550 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
551 ok( hr == S_OK, "got %08x\n", hr );
552 ok( max_depth == 16, "got %u\n", max_depth );
553 WsFreeReader( reader );
556 static void test_WsSetInputToBuffer(void)
558 HRESULT hr;
559 WS_HEAP *heap;
560 WS_XML_BUFFER *buffer;
561 WS_XML_READER *reader;
562 WS_XML_READER_PROPERTY prop;
563 const WS_XML_NODE *node;
564 ULONG size, max_depth;
566 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
567 ok( hr == S_OK, "got %08x\n", hr );
569 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
570 ok( hr == S_OK, "got %08x\n", hr );
572 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
573 ok( hr == S_OK, "got %08x\n", hr );
575 hr = WsSetInputToBuffer( NULL, NULL, NULL, 0, NULL );
576 ok( hr == E_INVALIDARG, "got %08x\n", hr );
578 hr = WsSetInputToBuffer( reader, NULL, NULL, 0, NULL );
579 ok( hr == E_INVALIDARG, "got %08x\n", hr );
581 node = NULL;
582 hr = WsGetReaderNode( reader, &node, NULL );
583 ok( hr == S_OK, "got %08x\n", hr );
584 ok( node != NULL, "node not set\n" );
585 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
587 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
588 ok( hr == S_OK, "got %08x\n", hr );
590 node = NULL;
591 hr = WsGetReaderNode( reader, &node, NULL );
592 ok( hr == S_OK, "got %08x\n", hr );
593 ok( node != NULL, "node not set\n" );
594 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
596 /* multiple calls are allowed */
597 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
598 ok( hr == S_OK, "got %08x\n", hr );
600 /* reader properties can be set with WsSetInputToBuffer */
601 max_depth = 16;
602 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
603 prop.value = &max_depth;
604 prop.valueSize = sizeof(max_depth);
605 hr = WsSetInputToBuffer( reader, buffer, &prop, 1, NULL );
606 ok( hr == S_OK, "got %08x\n", hr );
608 max_depth = 0xdeadbeef;
609 size = sizeof(max_depth);
610 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
611 ok( hr == S_OK, "got %08x\n", hr );
612 ok( max_depth == 16, "got %u\n", max_depth );
614 WsFreeReader( reader );
615 WsFreeHeap( heap );
618 static void test_WsFillReader(void)
620 HRESULT hr;
621 WS_XML_READER *reader;
622 const WS_XML_NODE *node;
624 /* what happens of we don't call WsFillReader? */
625 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
626 ok( hr == S_OK, "got %08x\n", hr );
628 node = NULL;
629 hr = WsGetReaderNode( reader, &node, NULL );
630 ok( hr == S_OK, "got %08x\n", hr );
631 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
633 hr = set_input( reader, data1, sizeof(data1) - 1 );
634 ok( hr == S_OK, "got %08x\n", hr );
636 node = NULL;
637 hr = WsGetReaderNode( reader, &node, NULL );
638 ok( hr == S_OK, "got %08x\n", hr );
639 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
641 hr = WsReadNode( reader, NULL );
642 ok( hr == S_OK, "got %08x\n", hr );
644 node = NULL;
645 hr = WsGetReaderNode( reader, &node, NULL );
646 ok( hr == S_OK, "got %08x\n", hr );
647 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
648 WsFreeReader( reader );
650 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
651 ok( hr == S_OK, "got %08x\n", hr );
653 hr = set_input( reader, data1, sizeof(data1) - 1 );
654 ok( hr == S_OK, "got %08x\n", hr );
656 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
657 ok( hr == S_OK, "got %08x\n", hr );
659 hr = set_input( reader, data1, sizeof(data1) - 1 );
660 ok( hr == S_OK, "got %08x\n", hr );
662 node = NULL;
663 hr = WsGetReaderNode( reader, &node, NULL );
664 ok( hr == S_OK, "got %08x\n", hr );
665 ok( node != NULL, "node not set\n" );
666 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
668 hr = WsFillReader( NULL, sizeof(data1) - 1, NULL, NULL );
669 ok( hr == E_INVALIDARG, "got %08x\n", hr );
671 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
672 ok( hr == S_OK, "got %08x\n", hr );
674 node = NULL;
675 hr = WsGetReaderNode( reader, &node, NULL );
676 ok( hr == S_OK, "got %08x\n", hr );
677 ok( node != NULL, "node not set\n" );
678 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
680 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
681 ok( hr == S_OK, "got %08x\n", hr );
683 /* min_size larger than input size */
684 hr = WsFillReader( reader, sizeof(data1), NULL, NULL );
685 ok( hr == S_OK, "got %08x\n", hr );
686 WsFreeReader( reader );
689 static void test_WsReadToStartElement(void)
691 HRESULT hr;
692 WS_XML_READER *reader;
693 const WS_XML_NODE *node, *node2;
694 int found;
696 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
697 ok( hr == S_OK, "got %08x\n", hr );
699 hr = set_input( reader, data1, sizeof(data1) - 1 );
700 ok( hr == S_OK, "got %08x\n", hr );
702 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
703 ok( hr == S_OK, "got %08x\n", hr );
705 hr = WsGetReaderNode( reader, &node, NULL );
706 ok( hr == S_OK, "got %08x\n", hr );
707 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
709 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
710 ok( hr == S_OK, "got %08x\n", hr );
712 hr = WsReadToStartElement( NULL, NULL, NULL, NULL, NULL );
713 ok( hr == E_INVALIDARG, "got %08x\n", hr );
715 found = -1;
716 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
717 ok( hr == S_OK, "got %08x\n", hr );
718 ok( found == FALSE, "got %d\n", found );
720 hr = WsGetReaderNode( reader, &node, NULL );
721 ok( hr == S_OK, "got %08x\n", hr );
722 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
724 hr = set_input( reader, data2, sizeof(data2) - 1 );
725 ok( hr == S_OK, "got %08x\n", hr );
727 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
728 ok( hr == S_OK, "got %08x\n", hr );
730 hr = WsGetReaderNode( reader, &node, NULL );
731 ok( hr == S_OK, "got %08x\n", hr );
732 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
734 found = -1;
735 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
736 ok( hr == S_OK, "got %08x\n", hr );
737 ok( found == TRUE, "got %d\n", found );
739 hr = WsGetReaderNode( reader, &node, NULL );
740 ok( hr == S_OK, "got %08x\n", hr );
741 if (node)
743 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
745 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
746 ok( elem->prefix != NULL, "prefix not set\n" );
747 if (elem->prefix)
749 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
751 ok( elem->localName != NULL, "localName not set\n" );
752 if (elem->localName)
754 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
755 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
757 ok( elem->ns != NULL, "ns not set\n" );
758 if (elem->ns)
760 ok( !elem->ns->length, "got %u\n", elem->ns->length );
762 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
763 ok( elem->attributes == NULL, "attributes set\n" );
764 ok( !elem->isEmpty, "isEmpty not zero\n" );
767 found = -1;
768 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
769 ok( hr == S_OK, "got %08x\n", hr );
770 ok( found == TRUE, "got %d\n", found );
772 node2 = NULL;
773 hr = WsGetReaderNode( reader, &node2, NULL );
774 ok( hr == S_OK, "got %08x\n", hr );
775 ok( node2 == node, "different node\n" );
777 hr = set_input( reader, data3, sizeof(data3) - 1 );
778 ok( hr == S_OK, "got %08x\n", hr );
780 hr = WsFillReader( reader, sizeof(data3) - 1, NULL, NULL );
781 ok( hr == S_OK, "got %08x\n", hr );
783 found = -1;
784 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
785 ok( hr == S_OK, "got %08x\n", hr );
786 ok( found == TRUE, "got %d\n", found );
788 hr = WsGetReaderNode( reader, &node, NULL );
789 ok( hr == S_OK, "got %08x\n", hr );
790 if (node)
792 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
794 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
795 ok( elem->localName != NULL, "localName not set\n" );
796 if (elem->localName)
798 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
799 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
803 hr = set_input( reader, data4, sizeof(data4) - 1 );
804 ok( hr == S_OK, "got %08x\n", hr );
806 hr = WsFillReader( reader, sizeof(data4) - 1, NULL, NULL );
807 ok( hr == S_OK, "got %08x\n", hr );
809 found = -1;
810 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
811 ok( hr == S_OK, "got %08x\n", hr );
812 ok( found == TRUE, "got %d\n", found );
813 WsFreeReader( reader );
816 static void test_WsReadStartElement(void)
818 HRESULT hr;
819 WS_XML_READER *reader;
820 const WS_XML_NODE *node, *node2;
821 int found;
823 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
824 ok( hr == S_OK, "got %08x\n", hr );
826 hr = set_input( reader, data2, sizeof(data2) - 1 );
827 ok( hr == S_OK, "got %08x\n", hr );
829 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
830 ok( hr == S_OK, "got %08x\n", hr );
832 found = -1;
833 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
834 ok( hr == S_OK, "got %08x\n", hr );
835 ok( found == TRUE, "got %d\n", found );
837 hr = WsReadStartElement( NULL, NULL );
838 ok( hr == E_INVALIDARG, "got %08x\n", hr );
840 hr = WsGetReaderNode( reader, &node, NULL );
841 ok( hr == S_OK, "got %08x\n", hr );
842 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
844 hr = WsReadStartElement( reader, NULL );
845 ok( hr == S_OK, "got %08x\n", hr );
847 hr = WsGetReaderNode( reader, &node, NULL );
848 ok( hr == S_OK, "got %08x\n", hr );
849 if (node)
851 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
852 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
853 ok( text->text != NULL, "text not set\n" );
854 if (text->text)
856 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
857 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
858 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
859 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong data\n" );
863 hr = WsReadStartElement( reader, NULL );
864 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
866 node2 = NULL;
867 hr = WsGetReaderNode( reader, &node2, NULL );
868 ok( hr == S_OK, "got %08x\n", hr );
869 ok( node2 == node, "different node\n" );
871 hr = set_input( reader, data8, sizeof(data8) - 1 );
872 ok( hr == S_OK, "got %08x\n", hr );
874 hr = WsFillReader( reader, sizeof(data8) - 1, NULL, NULL );
875 ok( hr == S_OK, "got %08x\n", hr );
877 found = -1;
878 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
879 ok( hr == S_OK, "got %08x\n", hr );
880 ok( found == TRUE, "got %d\n", found );
882 hr = WsGetReaderNode( reader, &node, NULL );
883 ok( hr == S_OK, "got %08x\n", hr );
884 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
886 hr = WsGetReaderNode( reader, &node, NULL );
887 ok( hr == S_OK, "got %08x\n", hr );
888 if (node)
890 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
891 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
892 ok( !memcmp( elem->localName->bytes, "node1", 5), "wrong name\n" );
895 hr = WsReadStartElement( reader, NULL );
896 ok( hr == S_OK, "got %08x\n", hr );
898 hr = WsGetReaderNode( reader, &node, NULL );
899 ok( hr == S_OK, "got %08x\n", hr );
900 if (node)
902 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
903 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
904 ok( !memcmp( elem->localName->bytes, "node2", 5), "wrong name\n" );
907 hr = WsReadNode( reader, NULL );
908 ok( hr == S_OK, "got %08x\n", hr );
910 hr = WsGetReaderNode( reader, &node, NULL );
911 ok( hr == S_OK, "got %08x\n", hr );
912 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
914 hr = WsReadNode( reader, NULL );
915 ok( hr == S_OK, "got %08x\n", hr );
917 hr = WsGetReaderNode( reader, &node, NULL );
918 ok( hr == S_OK, "got %08x\n", hr );
919 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
921 hr = WsReadEndElement( reader, NULL );
922 ok( hr == S_OK, "got %08x\n", hr );
924 hr = WsGetReaderNode( reader, &node, NULL );
925 ok( hr == S_OK, "got %08x\n", hr );
926 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
928 /* WsReadEndElement advances reader to EOF */
929 hr = WsReadEndElement( reader, NULL );
930 ok( hr == S_OK, "got %08x\n", hr );
932 hr = WsGetReaderNode( reader, &node, NULL );
933 ok( hr == S_OK, "got %08x\n", hr );
934 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
936 hr = WsReadEndElement( reader, NULL );
937 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
939 WsFreeReader( reader );
942 static void test_WsReadEndElement(void)
944 HRESULT hr;
945 WS_XML_READER *reader;
946 const WS_XML_NODE *node;
947 int found;
949 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
950 ok( hr == S_OK, "got %08x\n", hr );
952 hr = set_input( reader, data2, sizeof(data2) - 1 );
953 ok( hr == S_OK, "got %08x\n", hr );
955 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
956 ok( hr == S_OK, "got %08x\n", hr );
958 hr = WsReadEndElement( reader, NULL );
959 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
961 hr = set_input( reader, data2, sizeof(data2) - 1 );
962 ok( hr == S_OK, "got %08x\n", hr );
964 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
965 ok( hr == S_OK, "got %08x\n", hr );
967 hr = WsReadNode( reader, NULL );
968 ok( hr == S_OK, "got %08x\n", hr );
970 hr = WsGetReaderNode( reader, &node, NULL );
971 ok( hr == S_OK, "got %08x\n", hr );
972 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
974 hr = WsReadNode( reader, NULL );
975 ok( hr == S_OK, "got %08x\n", hr );
977 hr = WsGetReaderNode( reader, &node, NULL );
978 ok( hr == S_OK, "got %08x\n", hr );
979 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
981 hr = WsReadNode( reader, NULL );
982 ok( hr == S_OK, "got %08x\n", hr );
984 hr = WsGetReaderNode( reader, &node, NULL );
985 ok( hr == S_OK, "got %08x\n", hr );
986 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
988 hr = WsReadNode( reader, NULL );
989 ok( hr == S_OK, "got %08x\n", hr );
991 hr = WsGetReaderNode( reader, &node, NULL );
992 ok( hr == S_OK, "got %08x\n", hr );
993 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
995 hr = set_input( reader, data2, sizeof(data2) - 1 );
996 ok( hr == S_OK, "got %08x\n", hr );
998 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
999 ok( hr == S_OK, "got %08x\n", hr );
1001 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1002 ok( hr == S_OK, "got %08x\n", hr );
1004 hr = WsReadStartElement( reader, NULL );
1005 ok( hr == S_OK, "got %08x\n", hr );
1007 hr = WsGetReaderNode( reader, &node, NULL );
1008 ok( hr == S_OK, "got %08x\n", hr );
1009 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
1011 hr = WsReadNode( reader, NULL );
1012 ok( hr == S_OK, "got %08x\n", hr );
1014 hr = WsGetReaderNode( reader, &node, NULL );
1015 ok( hr == S_OK, "got %08x\n", hr );
1016 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1018 /* WsReadEndElement advances reader to EOF */
1019 hr = WsReadEndElement( reader, NULL );
1020 ok( hr == S_OK, "got %08x\n", hr );
1022 hr = WsGetReaderNode( reader, &node, NULL );
1023 ok( hr == S_OK, "got %08x\n", hr );
1024 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1026 hr = WsReadEndElement( reader, NULL );
1027 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1029 hr = set_input( reader, data5, sizeof(data5) - 1 );
1030 ok( hr == S_OK, "got %08x\n", hr );
1032 hr = WsFillReader( reader, sizeof(data5) - 1, NULL, NULL );
1033 ok( hr == S_OK, "got %08x\n", hr );
1035 hr = WsReadEndElement( reader, NULL );
1036 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1038 hr = set_input( reader, data10, sizeof(data10) - 1 );
1039 ok( hr == S_OK, "got %08x\n", hr );
1041 hr = WsFillReader( reader, sizeof(data10) - 1, NULL, NULL );
1042 ok( hr == S_OK, "got %08x\n", hr );
1044 hr = WsReadNode( reader, NULL );
1045 ok( hr == S_OK, "got %08x\n", hr );
1047 hr = WsGetReaderNode( reader, &node, NULL );
1048 ok( hr == S_OK, "got %08x\n", hr );
1049 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1051 hr = WsReadEndElement( reader, NULL );
1052 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1054 hr = set_input( reader, "<a></A>", sizeof("<a></A>") - 1 );
1055 ok( hr == S_OK, "got %08x\n", hr );
1057 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1058 ok( hr == S_OK, "got %08x\n", hr );
1060 found = -1;
1061 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1062 ok( hr == S_OK, "got %08x\n", hr );
1063 ok( found == TRUE, "got %d\n", found );
1065 hr = WsGetReaderNode( reader, &node, NULL );
1066 ok( hr == S_OK, "got %08x\n", hr );
1067 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1069 hr = WsReadEndElement( reader, NULL );
1070 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1072 hr = set_input( reader, "<a></a>", sizeof("<a></a>") - 1 );
1073 ok( hr == S_OK, "got %08x\n", hr );
1075 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1076 ok( hr == S_OK, "got %08x\n", hr );
1078 found = -1;
1079 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1080 ok( hr == S_OK, "got %08x\n", hr );
1081 ok( found == TRUE, "got %d\n", found );
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 = WsReadStartElement( reader, NULL );
1088 ok( hr == S_OK, "got %08x\n", hr );
1090 hr = WsGetReaderNode( reader, &node, NULL );
1091 ok( hr == S_OK, "got %08x\n", hr );
1092 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1094 hr = WsReadEndElement( reader, NULL );
1095 ok( hr == S_OK, "got %08x\n", hr );
1097 hr = WsGetReaderNode( reader, &node, NULL );
1098 ok( hr == S_OK, "got %08x\n", hr );
1099 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1101 hr = set_input( reader, "<a/>", sizeof("<a/>") - 1 );
1102 ok( hr == S_OK, "got %08x\n", hr );
1104 hr = WsFillReader( reader, sizeof("<a/>") - 1, NULL, NULL );
1105 ok( hr == S_OK, "got %08x\n", hr );
1107 found = -1;
1108 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1109 ok( hr == S_OK, "got %08x\n", hr );
1110 ok( found == TRUE, "got %d\n", found );
1112 hr = WsGetReaderNode( reader, &node, NULL );
1113 ok( hr == S_OK, "got %08x\n", hr );
1114 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1116 hr = WsReadStartElement( reader, NULL );
1117 ok( hr == S_OK, "got %08x\n", hr );
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_END_ELEMENT, "got %u\n", node->nodeType );
1123 hr = WsReadEndElement( reader, NULL );
1124 ok( hr == S_OK, "got %08x\n", hr );
1126 WsFreeReader( reader );
1129 static void test_WsReadNode(void)
1131 static const char str1[] = "<a>";
1132 static const char str2[] = "< a>";
1133 static const char str3[] = "<a >";
1134 static const char str4[] = "<<a>>";
1135 static const char str5[] = "<>";
1136 static const char str6[] = "</a>";
1137 static const char str7[] = " <a>";
1138 static const char str8[] = "<?xml>";
1139 static const char str9[] = "<?xml?>";
1140 static const char str10[] = "<?xml ?>";
1141 static const char str11[] = "<?xml version=\"1.0\"?>";
1142 static const char str12[] = "<text>test</text>";
1143 static const char str13[] = "<?xml version=\"1.0\"?><text>test</text>";
1144 static const char str14[] = "";
1145 static const char str15[] = "<!--";
1146 static const char str16[] = "<!---->";
1147 static const char str17[] = "<!--comment-->";
1148 HRESULT hr;
1149 WS_XML_READER *reader;
1150 const WS_XML_NODE *node;
1151 unsigned int i;
1152 int found;
1153 static const struct
1155 const char *text;
1156 HRESULT hr;
1157 WS_XML_NODE_TYPE type;
1158 int todo;
1160 tests[] =
1162 { str1, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1163 { str2, WS_E_INVALID_FORMAT, 0 },
1164 { str3, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1165 { str4, WS_E_INVALID_FORMAT, 0 },
1166 { str5, WS_E_INVALID_FORMAT, 0 },
1167 { str6, WS_E_INVALID_FORMAT, 0 },
1168 { str7, S_OK, WS_XML_NODE_TYPE_TEXT },
1169 { str8, WS_E_INVALID_FORMAT, 0 },
1170 { str9, WS_E_INVALID_FORMAT, 0 },
1171 { str10, WS_E_INVALID_FORMAT, 0, 1 },
1172 { str11, S_OK, WS_XML_NODE_TYPE_EOF },
1173 { str12, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1174 { str13, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1175 { str14, WS_E_INVALID_FORMAT, 0, 1 },
1176 { str15, WS_E_INVALID_FORMAT, 0 },
1177 { str16, S_OK, WS_XML_NODE_TYPE_COMMENT },
1178 { str17, S_OK, WS_XML_NODE_TYPE_COMMENT },
1181 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
1182 ok( hr == S_OK, "got %08x\n", hr );
1184 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
1186 hr = set_input( reader, tests[i].text, strlen(tests[i].text) );
1187 ok( hr == S_OK, "got %08x\n", hr );
1189 hr = WsFillReader( reader, strlen(tests[i].text), NULL, NULL );
1190 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1192 hr = WsReadNode( reader, NULL );
1193 todo_wine_if (tests[i].todo)
1194 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
1195 if (hr == S_OK)
1197 node = NULL;
1198 hr = WsGetReaderNode( reader, &node, NULL );
1199 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1200 ok( node != NULL, "%u: node not set\n", i );
1201 if (node)
1203 todo_wine_if (tests[i].todo)
1204 ok( node->nodeType == tests[i].type, "%u: got %u\n", i, node->nodeType );
1209 hr = set_input( reader, data6, sizeof(data6) - 1 );
1210 ok( hr == S_OK, "got %08x\n", hr );
1212 hr = WsFillReader( reader, sizeof(data6) - 1, NULL, NULL );
1213 ok( hr == S_OK, "got %08x\n", hr );
1215 found = -1;
1216 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1217 ok( hr == S_OK, "got %08x\n", hr );
1218 ok( found == TRUE, "got %d\n", found );
1220 hr = WsGetReaderNode( reader, &node, NULL );
1221 ok( hr == S_OK, "got %08x\n", hr );
1222 if (node)
1224 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
1225 WS_XML_ATTRIBUTE *attr;
1226 WS_XML_UTF8_TEXT *text;
1228 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1229 ok( elem->prefix != NULL, "prefix not set\n" );
1230 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
1231 ok( elem->prefix->bytes == NULL, "bytes set\n" );
1232 ok( elem->localName != NULL, "localName not set\n" );
1233 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
1234 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
1235 ok( elem->ns != NULL, "ns not set\n" );
1236 ok( !elem->ns->length, "got %u\n", elem->ns->length );
1237 ok( elem->ns->bytes != NULL, "bytes not set\n" );
1238 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
1239 ok( elem->attributes != NULL, "attributes not set\n" );
1240 ok( !elem->isEmpty, "isEmpty not zero\n" );
1242 attr = elem->attributes[0];
1243 ok( !attr->singleQuote, "got %u\n", attr->singleQuote );
1244 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1245 ok( attr->prefix != NULL, "prefix not set\n" );
1246 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1247 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1248 ok( attr->localName != NULL, "localName not set\n" );
1249 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
1250 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
1251 ok( attr->ns != NULL, "ns not set\n" );
1252 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1253 ok( attr->ns->bytes == NULL, "bytes set\n" );
1254 ok( attr->value != NULL, "value not set\n" );
1256 text = (WS_XML_UTF8_TEXT *)attr->value;
1257 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1258 ok( text->value.length == 5, "got %u\n", text->value.length );
1259 ok( !memcmp( text->value.bytes, "value", 5 ), "wrong data\n" );
1261 attr = elem->attributes[1];
1262 ok( attr->singleQuote == 1, "got %u\n", attr->singleQuote );
1263 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1264 ok( attr->prefix != NULL, "prefix not set\n" );
1265 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1266 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1267 ok( attr->localName != NULL, "localName not set\n" );
1268 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
1269 ok( !memcmp( attr->localName->bytes, "attr2", 5 ), "wrong data\n" );
1270 ok( attr->ns != NULL, "ns not set\n" );
1271 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1272 ok( attr->ns->bytes == NULL, "bytes set\n" );
1273 ok( attr->value != NULL, "value not set\n" );
1275 text = (WS_XML_UTF8_TEXT *)attr->value;
1276 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1277 ok( text->value.length == 6, "got %u\n", text->value.length );
1278 ok( !memcmp( text->value.bytes, "value2", 6 ), "wrong data\n" );
1281 hr = set_input( reader, data7, sizeof(data7) - 1 );
1282 ok( hr == S_OK, "got %08x\n", hr );
1284 hr = WsFillReader( reader, sizeof(data7) - 1, NULL, NULL );
1285 ok( hr == S_OK, "got %08x\n", hr );
1287 hr = WsReadNode( reader, NULL );
1288 ok( hr == S_OK, "got %08x\n", hr );
1290 hr = WsGetReaderNode( reader, &node, NULL );
1291 ok( hr == S_OK, "got %08x\n", hr );
1292 if (node)
1294 WS_XML_COMMENT_NODE *comment = (WS_XML_COMMENT_NODE *)node;
1296 ok( comment->node.nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", comment->node.nodeType );
1297 ok( comment->value.length == 9, "got %u\n", comment->value.length );
1298 ok( !memcmp( comment->value.bytes, " comment ", 9 ), "wrong data\n" );
1301 WsFreeReader( reader );
1304 static void prepare_type_test( WS_XML_READER *reader, const char *data, ULONG size )
1306 HRESULT hr;
1308 hr = set_input( reader, data, size );
1309 ok( hr == S_OK, "got %08x\n", hr );
1311 hr = WsFillReader( reader, size, NULL, NULL );
1312 ok( hr == S_OK, "got %08x\n", hr );
1314 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1315 ok( hr == S_OK, "got %08x\n", hr );
1317 hr = WsReadStartElement( reader, NULL );
1318 ok( hr == S_OK, "got %08x\n", hr );
1321 static void test_WsReadType(void)
1323 static const WCHAR testW[] = {'t','e','s','t',0};
1324 static const GUID guid1 = {0,0,0,{0,0,0,0,0,0,0,0}};
1325 static const GUID guid2 = {0,0,0,{0,0,0,0,0,0,0,0xa1}};
1326 HRESULT hr;
1327 WS_XML_READER *reader;
1328 WS_HEAP *heap;
1329 enum { ONE = 1, TWO = 2 };
1330 WS_XML_STRING one = { 3, (BYTE *)"ONE" };
1331 WS_XML_STRING two = { 3, (BYTE *)"TWO" };
1332 WS_ENUM_VALUE enum_values[] = { { ONE, &one }, { TWO, &two } };
1333 WS_ENUM_DESCRIPTION enum_desc;
1334 int val_enum;
1335 WCHAR *val_str;
1336 BOOL val_bool;
1337 INT8 val_int8;
1338 INT16 val_int16;
1339 INT32 val_int32;
1340 INT64 val_int64;
1341 UINT8 val_uint8;
1342 UINT16 val_uint16;
1343 UINT32 val_uint32;
1344 UINT64 val_uint64;
1345 GUID val_guid;
1347 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1348 ok( hr == S_OK, "got %08x\n", hr );
1350 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
1351 ok( hr == S_OK, "got %08x\n", hr );
1353 prepare_type_test( reader, data2, sizeof(data2) - 1 );
1354 hr = WsReadType( NULL, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1355 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1356 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1358 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1359 WS_READ_REQUIRED_POINTER, heap, &val_str, 0, NULL );
1360 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1362 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1363 WS_READ_REQUIRED_POINTER, heap, NULL, sizeof(val_str), NULL );
1364 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1366 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1367 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str) + 1, NULL );
1368 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1370 val_str = NULL;
1371 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1372 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1373 ok( hr == S_OK, "got %08x\n", hr );
1374 ok( val_str != NULL, "pointer not set\n" );
1375 if (val_str) ok( !lstrcmpW( val_str, testW ), "wrong data\n" );
1377 val_bool = -1;
1378 prepare_type_test( reader, "<t>true</t>", sizeof("<t>true</t>") - 1 );
1379 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1380 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1381 ok( hr == S_OK, "got %08x\n", hr );
1382 ok( val_bool == TRUE, "got %d\n", val_bool );
1384 val_bool = -1;
1385 prepare_type_test( reader, "<t>false</t>", sizeof("<t>false</t>") - 1 );
1386 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1387 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1388 ok( hr == S_OK, "got %08x\n", hr );
1389 ok( val_bool == FALSE, "got %d\n", val_bool );
1391 val_bool = -1;
1392 prepare_type_test( reader, "<t>FALSE</t>", sizeof("<t>FALSE</t>") - 1 );
1393 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1394 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1395 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1396 ok( val_bool == -1, "got %d\n", val_bool );
1398 val_bool = -1;
1399 prepare_type_test( reader, "<t>1</t>", sizeof("<t>1</t>") - 1 );
1400 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1401 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1402 ok( hr == S_OK, "got %08x\n", hr );
1403 ok( val_bool == TRUE, "got %d\n", val_bool );
1405 val_bool = -1;
1406 prepare_type_test( reader, "<t>2</t>", sizeof("<t>2</t>") - 1 );
1407 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1408 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1409 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1410 ok( val_bool == -1, "got %d\n", val_bool );
1412 val_bool = -1;
1413 prepare_type_test( reader, "<t>0</t>", sizeof("<t>0</t>") - 1 );
1414 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1415 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1416 ok( hr == S_OK, "got %08x\n", hr );
1417 ok( val_bool == FALSE, "got %d\n", val_bool );
1419 val_int8 = 0;
1420 prepare_type_test( reader, "<t>-128</t>", sizeof("<t>-128</t>") - 1 );
1421 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1422 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1423 ok( hr == S_OK, "got %08x\n", hr );
1424 ok( val_int8 == -128, "got %d\n", val_int8 );
1426 val_int8 = 0;
1427 prepare_type_test( reader, "<t> </t>", sizeof("<t> </t>") - 1 );
1428 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1429 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1430 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1431 ok( !val_int8, "got %d\n", val_int8 );
1433 val_int8 = 0;
1434 prepare_type_test( reader, "<t>-</t>", sizeof("<t>-</t>") - 1 );
1435 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1436 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1437 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1438 ok( !val_int8, "got %d\n", val_int8 );
1440 val_int8 = -1;
1441 prepare_type_test( reader, "<t>-0</t>", sizeof("<t>-0</t>") - 1 );
1442 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1443 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1444 ok( hr == S_OK, "got %08x\n", hr );
1445 ok( !val_int8, "got %d\n", val_int8 );
1447 val_int8 = 0;
1448 prepare_type_test( reader, "<t>-129</t>", sizeof("<t>-129</t>") - 1 );
1449 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1450 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1451 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1452 ok( !val_int8, "got %d\n", val_int8 );
1454 val_int16 = 0;
1455 prepare_type_test( reader, "<t>-32768</t>", sizeof("<t>-32768</t>") - 1 );
1456 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1457 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1458 ok( hr == S_OK, "got %08x\n", hr );
1459 ok( val_int16 == -32768, "got %d\n", val_int16 );
1461 val_int16 = 0;
1462 prepare_type_test( reader, "<t>-32769</t>", sizeof("<t>-32769</t>") - 1 );
1463 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1464 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1465 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1466 ok( !val_int16, "got %d\n", val_int16 );
1468 val_int32 = 0;
1469 prepare_type_test( reader, "<t>-2147483648</t>", sizeof("<t>-2147483648</t>") - 1 );
1470 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1471 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1472 ok( hr == S_OK, "got %08x\n", hr );
1473 ok( val_int32 == -2147483647 - 1, "got %d\n", val_int32 );
1475 val_int32 = 0;
1476 prepare_type_test( reader, "<t>-2147483649</t>", sizeof("<t>-2147483649</t>") - 1 );
1477 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1478 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1479 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1480 ok( !val_int32, "got %d\n", val_int32 );
1482 val_int64 = 0;
1483 prepare_type_test( reader, "<t>-9223372036854775808</t>", sizeof("<t>-9223372036854775808</t>") - 1 );
1484 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1485 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1486 ok( hr == S_OK, "got %08x\n", hr );
1487 ok( val_int64 == -9223372036854775807 - 1, "wrong value\n" );
1489 val_int64 = 0;
1490 prepare_type_test( reader, "<t>-9223372036854775809</t>", sizeof("<t>-9223372036854775809</t>") - 1 );
1491 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1492 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1493 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1494 ok( !val_int64, "wrong value\n" );
1496 val_uint8 = 0;
1497 prepare_type_test( reader, "<t> 255 </t>", sizeof("<t> 255 </t>") - 1 );
1498 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1499 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1500 ok( hr == S_OK, "got %08x\n", hr );
1501 ok( val_uint8 == 255, "got %u\n", val_uint8 );
1503 val_uint8 = 0;
1504 prepare_type_test( reader, "<t>+255</t>", sizeof("<t>+255</t>") - 1 );
1505 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1506 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1507 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1508 ok( !val_uint8, "got %u\n", val_uint8 );
1510 val_uint8 = 0;
1511 prepare_type_test( reader, "<t>-255</t>", sizeof("<t>-255</t>") - 1 );
1512 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1513 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1514 todo_wine ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1515 ok( !val_uint8, "got %u\n", val_uint8 );
1517 val_uint8 = 0;
1518 prepare_type_test( reader, "<t>0xff</t>", sizeof("<t>0xff</t>") - 1 );
1519 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1520 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1521 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1522 ok( !val_uint8, "got %u\n", val_uint8 );
1524 val_uint8 = 0;
1525 prepare_type_test( reader, "<t>256</t>", sizeof("<t>256</t>") - 1 );
1526 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1527 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1528 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1529 ok( !val_uint8, "got %u\n", val_uint8 );
1531 val_uint16 = 0;
1532 prepare_type_test( reader, "<t>65535</t>", sizeof("<t>65535</t>") - 1 );
1533 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1534 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1535 ok( hr == S_OK, "got %08x\n", hr );
1536 ok( val_uint16 == 65535, "got %u\n", val_uint16 );
1538 val_uint16 = 0;
1539 prepare_type_test( reader, "<t>65536</t>", sizeof("<t>65536</t>") - 1 );
1540 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1541 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1542 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1543 ok( !val_uint16, "got %u\n", val_uint16 );
1545 val_uint32 = 0;
1546 prepare_type_test( reader, "<t>4294967295</t>", sizeof("<t>4294967295</t>") - 1 );
1547 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1548 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1549 ok( hr == S_OK, "got %08x\n", hr );
1550 ok( val_uint32 == ~0, "got %u\n", val_uint32 );
1552 val_uint32 = 0;
1553 prepare_type_test( reader, "<t>4294967296</t>", sizeof("<t>4294967296</t>") - 1 );
1554 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1555 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1556 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1557 ok( !val_uint32, "got %u\n", val_uint32 );
1559 val_uint64 = 0;
1560 prepare_type_test( reader, "<t>18446744073709551615</t>", sizeof("<t>18446744073709551615</t>") - 1 );
1561 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1562 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1563 ok( hr == S_OK, "got %08x\n", hr );
1564 ok( val_uint64 == ~0, "wrong value\n" );
1566 val_uint64 = 0;
1567 prepare_type_test( reader, "<t>18446744073709551616</t>", sizeof("<t>18446744073709551616</t>") - 1 );
1568 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1569 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1570 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1571 ok( !val_uint64, "wrong value\n" );
1573 enum_desc.values = enum_values;
1574 enum_desc.valueCount = sizeof(enum_values)/sizeof(enum_values[0]);
1575 enum_desc.maxByteCount = 3;
1576 enum_desc.nameIndices = NULL;
1578 val_enum = 0;
1579 prepare_type_test( reader, "<t>ONE</t>", sizeof("<t>ONE</t>") - 1 );
1580 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1581 WS_READ_REQUIRED_VALUE, heap, &val_enum, sizeof(val_enum), NULL );
1582 ok( hr == S_OK, "got %08x\n", hr );
1583 ok( val_enum == 1, "got %d\n", val_enum );
1585 prepare_type_test( reader, "<t>{00000000-0000-0000-0000-000000000000}</t>",
1586 sizeof("<t>{00000000-0000-0000-0000-000000000000}</t>") - 1 );
1587 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1588 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1589 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1591 memset( &val_guid, 0xff, sizeof(val_guid) );
1592 prepare_type_test( reader, "<t> 00000000-0000-0000-0000-000000000000 </t>",
1593 sizeof("<t> 00000000-0000-0000-0000-000000000000 </t>") - 1 );
1594 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1595 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1596 ok( hr == S_OK, "got %08x\n", hr );
1597 ok( !memcmp( &val_guid, &guid1, sizeof(val_guid) ), "wrong guid\n" );
1599 memset( &val_guid, 0, sizeof(val_guid) );
1600 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000a1</t>",
1601 sizeof("<t>00000000-0000-0000-0000-0000000000a1</t>") - 1 );
1602 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1603 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1604 ok( hr == S_OK, "got %08x\n", hr );
1605 ok( !memcmp( &val_guid, &guid2, sizeof(val_guid) ), "wrong guid\n" );
1607 memset( &val_guid, 0, sizeof(val_guid) );
1608 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000A1</t>",
1609 sizeof("<t>00000000-0000-0000-0000-0000000000A1</t>") - 1 );
1610 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1611 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1612 ok( hr == S_OK, "got %08x\n", hr );
1613 ok( !memcmp( &val_guid, &guid2, sizeof(val_guid) ), "wrong guid\n" );
1615 WsFreeReader( reader );
1616 WsFreeHeap( heap );
1619 static void test_WsGetXmlAttribute(void)
1621 static const WCHAR valueW[] = {'v','a','l','u','e',0};
1622 HRESULT hr;
1623 WS_XML_READER *reader;
1624 WS_XML_STRING xmlstr;
1625 WS_HEAP *heap;
1626 WCHAR *str;
1627 ULONG count;
1628 int found;
1630 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1631 ok( hr == S_OK, "got %08x\n", hr );
1633 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
1634 ok( hr == S_OK, "got %08x\n", hr );
1636 hr = set_input( reader, data9, sizeof(data9) - 1 );
1637 ok( hr == S_OK, "got %08x\n", hr );
1639 hr = WsFillReader( reader, sizeof(data9) - 1, NULL, NULL );
1640 ok( hr == S_OK, "got %08x\n", hr );
1642 found = -1;
1643 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1644 ok( hr == S_OK, "got %08x\n", hr );
1645 ok( found == TRUE, "got %d\n", found );
1647 xmlstr.bytes = (BYTE *)"attr";
1648 xmlstr.length = sizeof("attr") - 1;
1649 xmlstr.dictionary = NULL;
1650 xmlstr.id = 0;
1651 str = NULL;
1652 count = 0;
1653 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1654 todo_wine ok( hr == S_OK, "got %08x\n", hr );
1655 todo_wine ok( str != NULL, "str not set\n" );
1656 todo_wine ok( count == 5, "got %u\n", count );
1657 /* string is not null-terminated */
1658 if (str) ok( !memcmp( str, valueW, count * sizeof(WCHAR) ), "wrong data\n" );
1660 xmlstr.bytes = (BYTE *)"none";
1661 xmlstr.length = sizeof("none") - 1;
1662 xmlstr.dictionary = NULL;
1663 xmlstr.id = 0;
1664 str = (WCHAR *)0xdeadbeef;
1665 count = 0xdeadbeef;
1666 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1667 todo_wine ok( hr == S_FALSE, "got %08x\n", hr );
1668 todo_wine ok( str == NULL, "str not set\n" );
1669 todo_wine ok( !count, "got %u\n", count );
1671 WsFreeReader( reader );
1672 WsFreeHeap( heap );
1675 static void test_WsXmlStringEquals(void)
1677 BYTE bom[] = {0xef,0xbb,0xbf};
1678 WS_XML_STRING str1 = {0, NULL}, str2 = {0, NULL};
1679 HRESULT hr;
1681 hr = WsXmlStringEquals( NULL, NULL, NULL );
1682 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1684 hr = WsXmlStringEquals( &str1, NULL, NULL );
1685 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1687 hr = WsXmlStringEquals( NULL, &str2, NULL );
1688 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1690 hr = WsXmlStringEquals( &str1, &str2, NULL );
1691 ok( hr == S_OK, "got %08x\n", hr );
1693 str1.length = 1;
1694 str1.bytes = (BYTE *)"a";
1695 hr = WsXmlStringEquals( &str1, &str1, NULL );
1696 ok( hr == S_OK, "got %08x\n", hr );
1698 str2.length = 1;
1699 str2.bytes = (BYTE *)"b";
1700 hr = WsXmlStringEquals( &str1, &str2, NULL );
1701 ok( hr == S_FALSE, "got %08x\n", hr );
1703 str2.length = 1;
1704 str2.bytes = bom;
1705 hr = WsXmlStringEquals( &str1, &str2, NULL );
1706 ok( hr == S_FALSE, "got %08x\n", hr );
1708 str1.length = 3;
1709 hr = WsXmlStringEquals( &str1, &str2, NULL );
1710 ok( hr == S_FALSE, "got %08x\n", hr );
1712 str2.length = 3;
1713 hr = WsXmlStringEquals( &str1, &str2, NULL );
1714 ok( hr == S_FALSE, "got %08x\n", hr );
1716 str1.length = 3;
1717 str1.bytes = bom;
1718 hr = WsXmlStringEquals( &str1, &str2, NULL );
1719 ok( hr == S_OK, "got %08x\n", hr );
1722 static void test_WsAlloc(void)
1724 HRESULT hr;
1725 WS_HEAP *heap;
1726 void *ptr;
1728 hr = WsCreateHeap( 256, 0, NULL, 0, &heap, NULL );
1729 ok( hr == S_OK, "got %08x\n", hr );
1731 ptr = NULL;
1732 hr = WsAlloc( NULL, 16, &ptr, NULL );
1733 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1734 ok( ptr == NULL, "ptr set\n" );
1736 ptr = NULL;
1737 hr = WsAlloc( heap, 512, &ptr, NULL );
1738 todo_wine ok( hr == WS_E_QUOTA_EXCEEDED, "got %08x\n", hr );
1739 todo_wine ok( ptr == NULL, "ptr not set\n" );
1741 ptr = NULL;
1742 hr = WsAlloc( heap, 16, &ptr, NULL );
1743 ok( hr == S_OK, "got %08x\n", hr );
1744 ok( ptr != NULL, "ptr not set\n" );
1745 WsFreeHeap( heap );
1748 static void test_WsMoveReader(void)
1750 HRESULT hr;
1751 WS_HEAP *heap;
1752 WS_XML_READER *reader;
1753 WS_XML_WRITER *writer;
1754 WS_XML_BUFFER *buffer;
1755 WS_XML_STRING localname = {1, (BYTE *)"a"}, localname2 = {1, (BYTE *)"b"}, ns = {0, NULL};
1756 const WS_XML_NODE *node;
1757 WS_XML_ELEMENT_NODE *elem;
1758 WS_XML_UTF8_TEXT utf8;
1760 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
1761 ok( hr == S_OK, "got %08x\n", hr );
1763 hr = WsMoveReader( NULL, WS_MOVE_TO_EOF, NULL, NULL );
1764 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1766 /* reader must be set to an XML buffer */
1767 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1768 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1770 hr = set_input( reader, data8, sizeof(data8) - 1 );
1771 ok( hr == S_OK, "got %08x\n", hr );
1773 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1774 todo_wine ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1775 WsFreeReader( reader );
1777 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1778 ok( hr == S_OK, "got %08x\n", hr );
1780 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
1781 ok( hr == S_OK, "got %08x\n", hr );
1783 hr = WsCreateWriter( NULL, 0, &writer, NULL ) ;
1784 ok( hr == S_OK, "got %08x\n", hr );
1786 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
1787 ok( hr == S_OK, "got %08x\n", hr );
1789 /* <a><b/></a> */
1790 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
1791 ok( hr == S_OK, "got %08x\n", hr );
1793 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
1794 ok( hr == S_OK, "got %08x\n", hr );
1796 hr = WsWriteEndElement( writer, NULL );
1797 ok( hr == S_OK, "got %08x\n", hr );
1799 hr = WsWriteEndElement( writer, NULL );
1800 ok( hr == S_OK, "got %08x\n", hr );
1802 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
1803 ok( hr == S_OK, "got %08x\n", hr );
1805 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1806 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1808 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
1809 ok( hr == S_OK, "got %08x\n", hr );
1811 /* first element is child node of BOF node */
1812 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
1813 ok( hr == S_OK, "got %08x\n", hr );
1815 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1816 ok( hr == S_OK, "got %08x\n", hr );
1818 hr = WsGetReaderNode( reader, &node, NULL );
1819 ok( hr == S_OK, "got %08x\n", hr );
1820 elem = (WS_XML_ELEMENT_NODE *)node;
1821 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1822 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1823 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1825 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1826 ok( hr == S_OK, "got %08x\n", hr );
1828 hr = WsGetReaderNode( reader, &node, NULL );
1829 ok( hr == S_OK, "got %08x\n", hr );
1830 elem = (WS_XML_ELEMENT_NODE *)node;
1831 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1832 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1833 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1835 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1836 ok( hr == S_OK, "got %08x\n", hr );
1838 hr = WsGetReaderNode( reader, &node, NULL );
1839 ok( hr == S_OK, "got %08x\n", hr );
1840 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1842 /* EOF node is last child of BOF node */
1843 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
1844 ok( hr == S_OK, "got %08x\n", hr );
1846 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1847 ok( hr == S_OK, "got %08x\n", hr );
1849 hr = WsGetReaderNode( reader, &node, NULL );
1850 ok( hr == S_OK, "got %08x\n", hr );
1851 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1853 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1854 ok( hr == S_OK, "got %08x\n", hr );
1856 hr = WsGetReaderNode( reader, &node, NULL );
1857 ok( hr == S_OK, "got %08x\n", hr );
1858 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1860 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
1861 ok( hr == S_OK, "got %08x\n", hr );
1863 hr = WsGetReaderNode( reader, &node, NULL );
1864 ok( hr == S_OK, "got %08x\n", hr );
1865 elem = (WS_XML_ELEMENT_NODE *)node;
1866 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1867 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1868 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1870 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_ELEMENT, NULL, NULL );
1871 ok( hr == S_OK, "got %08x\n", hr );
1873 hr = WsGetReaderNode( reader, &node, NULL );
1874 ok( hr == S_OK, "got %08x\n", hr );
1875 elem = (WS_XML_ELEMENT_NODE *)node;
1876 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1877 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1878 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1880 hr = WsMoveReader( reader, WS_MOVE_TO_END_ELEMENT, NULL, NULL );
1881 ok( hr == S_OK, "got %08x\n", hr );
1883 hr = WsGetReaderNode( reader, &node, NULL );
1884 ok( hr == S_OK, "got %08x\n", hr );
1885 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1887 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1888 ok( hr == S_OK, "got %08x\n", hr );
1890 hr = WsGetReaderNode( reader, &node, NULL );
1891 ok( hr == S_OK, "got %08x\n", hr );
1892 elem = (WS_XML_ELEMENT_NODE *)node;
1893 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1894 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1895 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1897 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1898 ok( hr == S_OK, "got %08x\n", hr );
1900 hr = WsGetReaderNode( reader, &node, NULL );
1901 ok( hr == S_OK, "got %08x\n", hr );
1902 elem = (WS_XML_ELEMENT_NODE *)node;
1903 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1904 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1905 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1907 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1908 ok( hr == S_OK, "got %08x\n", hr );
1910 hr = WsGetReaderNode( reader, &node, NULL );
1911 ok( hr == S_OK, "got %08x\n", hr );
1912 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
1914 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1915 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1917 WsFreeWriter( writer );
1918 WsFreeHeap( heap );
1920 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1921 ok( hr == S_OK, "got %08x\n", hr );
1923 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
1924 ok( hr == S_OK, "got %08x\n", hr );
1926 hr = WsCreateWriter( NULL, 0, &writer, NULL ) ;
1927 ok( hr == S_OK, "got %08x\n", hr );
1929 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
1930 ok( hr == S_OK, "got %08x\n", hr );
1932 /* <a><b>test</b></a> */
1933 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
1934 ok( hr == S_OK, "got %08x\n", hr );
1936 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
1937 ok( hr == S_OK, "got %08x\n", hr );
1939 utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
1940 utf8.value.bytes = (BYTE *)"test";
1941 utf8.value.length = sizeof("test") - 1;
1942 hr = WsWriteText( writer, &utf8.text, NULL );
1943 ok( hr == S_OK, "got %08x\n", hr );
1945 hr = WsWriteEndElement( writer, NULL );
1946 ok( hr == S_OK, "got %08x\n", hr );
1948 hr = WsWriteEndElement( writer, NULL );
1949 ok( hr == S_OK, "got %08x\n", hr );
1951 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
1952 ok( hr == S_OK, "got %08x\n", hr );
1954 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
1955 ok( hr == S_OK, "got %08x\n", hr );
1957 hr = WsGetReaderNode( reader, &node, NULL );
1958 ok( hr == S_OK, "got %08x\n", hr );
1959 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1961 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1962 ok( hr == S_OK, "got %08x\n", hr );
1964 hr = WsGetReaderNode( reader, &node, NULL );
1965 ok( hr == S_OK, "got %08x\n", hr );
1966 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1968 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
1969 ok( hr == S_OK, "got %08x\n", hr );
1971 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1972 ok( hr == S_OK, "got %08x\n", hr );
1974 hr = WsGetReaderNode( reader, &node, NULL );
1975 ok( hr == S_OK, "got %08x\n", hr );
1976 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1978 hr = WsGetReaderNode( reader, &node, NULL );
1979 ok( hr == S_OK, "got %08x\n", hr );
1980 elem = (WS_XML_ELEMENT_NODE *)node;
1981 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1982 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1983 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1985 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1986 ok( hr == S_OK, "got %08x\n", hr );
1988 hr = WsGetReaderNode( reader, &node, NULL );
1989 ok( hr == S_OK, "got %08x\n", hr );
1990 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1992 WsFreeReader( reader );
1993 WsFreeWriter( writer );
1994 WsFreeHeap( heap );
1997 static void prepare_struct_type_test( WS_XML_READER *reader, const char *data )
1999 HRESULT hr;
2000 ULONG size = strlen( data );
2002 hr = set_input( reader, data, size );
2003 ok( hr == S_OK, "got %08x\n", hr );
2005 hr = WsFillReader( reader, size, NULL, NULL );
2006 ok( hr == S_OK, "got %08x\n", hr );
2009 static void test_simple_struct_type(void)
2011 static const WCHAR testW[] = {'t','e','s','t',0};
2012 HRESULT hr;
2013 WS_XML_READER *reader;
2014 WS_HEAP *heap;
2015 WS_STRUCT_DESCRIPTION s;
2016 WS_FIELD_DESCRIPTION f, *fields[1];
2017 WS_XML_STRING ns = {0, NULL}, localname = {3, (BYTE *)"str"};
2018 WS_XML_STRING localname2 = {4, (BYTE *)"test"};
2019 const WS_XML_NODE *node;
2020 const WS_XML_ELEMENT_NODE *elem;
2021 struct test { WCHAR *str; } *test;
2023 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2024 ok( hr == S_OK, "got %08x\n", hr );
2026 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
2027 ok( hr == S_OK, "got %08x\n", hr );
2029 prepare_struct_type_test( reader, "<str>test</str>" );
2030 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL,
2031 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2032 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2034 hr = WsGetReaderNode( reader, &node, NULL );
2035 ok( hr == S_OK, "got %08x\n", hr );
2036 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
2038 /* element field mapping */
2039 memset( &f, 0, sizeof(f) );
2040 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2041 f.localName = &localname;
2042 f.ns = &ns;
2043 f.type = WS_WSZ_TYPE;
2044 fields[0] = &f;
2046 memset( &s, 0, sizeof(s) );
2047 s.size = sizeof(struct test);
2048 s.alignment = TYPE_ALIGNMENT(struct test);
2049 s.fields = fields;
2050 s.fieldCount = 1;
2051 s.typeLocalName = &localname2;
2052 s.typeNs = &ns;
2054 test = NULL;
2055 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2056 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2057 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2058 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2060 test = NULL;
2061 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str>" );
2062 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2063 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2064 ok( hr == S_OK, "got %08x\n", hr );
2065 ok( test != NULL, "test not set\n" );
2066 if (test)
2068 ok( test->str != NULL, "str not set\n" );
2069 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2072 hr = WsGetReaderNode( reader, &node, NULL );
2073 ok( hr == S_OK, "got %08x\n", hr );
2074 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2076 test = NULL;
2077 prepare_struct_type_test( reader, "<str>test</str>" );
2078 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2079 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2080 ok( hr == S_OK, "got %08x\n", hr );
2081 ok( test != NULL, "test not set\n" );
2082 if (test)
2084 ok( test->str != NULL, "str not set\n" );
2085 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2088 hr = WsGetReaderNode( reader, &node, NULL );
2089 ok( hr == S_OK, "got %08x\n", hr );
2090 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2092 test = NULL;
2093 prepare_struct_type_test( reader, "<str>test</str>" );
2094 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2095 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2096 ok( hr == S_OK, "got %08x\n", hr );
2097 ok( test != NULL, "test not set\n" );
2098 if (test)
2100 ok( test->str != NULL, "str not set\n" );
2101 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2104 hr = WsGetReaderNode( reader, &node, NULL );
2105 ok( hr == S_OK, "got %08x\n", hr );
2106 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2108 prepare_struct_type_test( reader, "<str>test</str>" );
2109 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2110 ok( hr == S_OK, "got %08x\n", hr );
2112 hr = WsGetReaderNode( reader, &node, NULL );
2113 ok( hr == S_OK, "got %08x\n", hr );
2114 elem = (const WS_XML_ELEMENT_NODE *)node;
2115 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2116 ok( elem->localName->length == 3, "got %u\n", elem->localName->length );
2117 ok( !memcmp( elem->localName->bytes, "str", 3 ), "wrong data\n" );
2119 test = NULL;
2120 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2121 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2122 ok( hr == S_OK, "got %08x\n", hr );
2123 ok( test != NULL, "test not set\n" );
2124 if (test)
2126 ok( test->str != NULL, "str not set\n" );
2127 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2130 hr = WsGetReaderNode( reader, &node, NULL );
2131 ok( hr == S_OK, "got %08x\n", hr );
2132 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2134 /* attribute field mapping */
2135 f.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2137 test = NULL;
2138 prepare_struct_type_test( reader, "<test str=\"test\"/>" );
2139 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2140 ok( hr == S_OK, "got %08x\n", hr );
2142 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2143 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2144 ok( hr == S_OK, "got %08x\n", hr );
2145 ok( test != NULL, "test not set\n" );
2146 if (test)
2148 ok( test->str != NULL, "str not set\n" );
2149 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data test %p test->str %p\n", test, test->str );
2152 hr = WsGetReaderNode( reader, &node, NULL );
2153 ok( hr == S_OK, "got %08x\n", hr );
2154 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2156 WsFreeReader( reader );
2157 WsFreeHeap( heap );
2160 static void test_cdata(void)
2162 static const char test[] = "<t><![CDATA[<data>]]></t>";
2163 HRESULT hr;
2164 WS_XML_READER *reader;
2165 const WS_XML_NODE *node;
2167 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
2168 ok( hr == S_OK, "got %08x\n", hr );
2170 hr = set_input( reader, test, sizeof(test) - 1 );
2171 ok( hr == S_OK, "got %08x\n", hr );
2173 hr = WsFillReader( reader, sizeof(test) - 1, NULL, NULL );
2174 ok( hr == S_OK, "got %08x\n", hr );
2176 hr = WsReadNode( reader, NULL );
2177 ok( hr == S_OK, "got %08x\n", hr );
2179 hr = WsGetReaderNode( reader, &node, NULL );
2180 ok( hr == S_OK, "got %08x\n", hr );
2181 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2183 hr = WsReadNode( reader, NULL );
2184 ok( hr == S_OK, "got %08x\n", hr );
2186 hr = WsGetReaderNode( reader, &node, NULL );
2187 ok( hr == S_OK, "got %08x\n", hr );
2188 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_CDATA, "got %u\n", node->nodeType );
2190 hr = WsReadNode( reader, NULL );
2191 ok( hr == S_OK, "got %08x\n", hr );
2193 hr = WsGetReaderNode( reader, &node, NULL );
2194 ok( hr == S_OK, "got %08x\n", hr );
2195 if (node)
2197 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
2198 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
2199 ok( text->text != NULL, "text not set\n" );
2200 if (text->text)
2202 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
2203 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
2204 ok( utf8->value.length == 6, "got %u\n", utf8->value.length );
2205 ok( !memcmp( utf8->value.bytes, "<data>", 6 ), "wrong data\n" );
2209 hr = WsReadNode( reader, NULL );
2210 ok( hr == S_OK, "got %08x\n", hr );
2212 hr = WsGetReaderNode( reader, &node, NULL );
2213 ok( hr == S_OK, "got %08x\n", hr );
2214 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_CDATA, "got %u\n", node->nodeType );
2216 hr = WsReadNode( reader, NULL );
2217 ok( hr == S_OK, "got %08x\n", hr );
2219 hr = WsGetReaderNode( reader, &node, NULL );
2220 ok( hr == S_OK, "got %08x\n", hr );
2221 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2223 WsFreeReader( reader );
2226 static void test_WsFindAttribute(void)
2228 static const char test[] = "<t attr='value' attr2='value2'></t>";
2229 WS_XML_STRING ns = {0, NULL}, localname = {4, (BYTE *)"attr"};
2230 WS_XML_STRING localname2 = {5, (BYTE *)"attr2"}, localname3 = {5, (BYTE *)"attr3"};
2231 WS_XML_READER *reader;
2232 ULONG index;
2233 HRESULT hr;
2235 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
2236 ok( hr == S_OK, "got %08x\n", hr );
2238 hr = set_input( reader, test, sizeof(test) - 1 );
2239 ok( hr == S_OK, "got %08x\n", hr );
2241 hr = WsReadNode( reader, NULL );
2242 ok( hr == S_OK, "got %08x\n", hr );
2244 hr = WsFindAttribute( reader, &localname, &ns, TRUE, NULL, NULL );
2245 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2247 hr = set_input( reader, test, sizeof(test) - 1 );
2248 ok( hr == S_OK, "got %08x\n", hr );
2250 hr = WsReadNode( reader, NULL );
2251 ok( hr == S_OK, "got %08x\n", hr );
2253 hr = WsFindAttribute( reader, &localname, NULL, TRUE, &index, NULL );
2254 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2256 hr = set_input( reader, test, sizeof(test) - 1 );
2257 ok( hr == S_OK, "got %08x\n", hr );
2259 hr = WsReadNode( reader, NULL );
2260 ok( hr == S_OK, "got %08x\n", hr );
2262 hr = WsFindAttribute( reader, NULL, &ns, TRUE, &index, NULL );
2263 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2265 hr = set_input( reader, test, sizeof(test) - 1 );
2266 ok( hr == S_OK, "got %08x\n", hr );
2268 hr = WsReadNode( reader, NULL );
2269 ok( hr == S_OK, "got %08x\n", hr );
2271 index = 0xdeadbeef;
2272 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2273 ok( hr == S_OK, "got %08x\n", hr );
2274 ok( !index, "got %u\n", index );
2276 index = 0xdeadbeef;
2277 hr = WsFindAttribute( reader, &localname2, &ns, TRUE, &index, NULL );
2278 ok( hr == S_OK, "got %08x\n", hr );
2279 ok( index == 1, "got %u\n", index );
2281 hr = WsReadNode( reader, NULL );
2282 ok( hr == S_OK, "got %08x\n", hr );
2284 index = 0xdeadbeef;
2285 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2286 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2287 ok( index == 0xdeadbeef, "got %u\n", index );
2289 hr = set_input( reader, test, sizeof(test) - 1 );
2290 ok( hr == S_OK, "got %08x\n", hr );
2292 hr = WsReadNode( reader, NULL );
2293 ok( hr == S_OK, "got %08x\n", hr );
2295 index = 0xdeadbeef;
2296 hr = WsFindAttribute( reader, &localname3, &ns, TRUE, &index, NULL );
2297 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2298 ok( index == 0xdeadbeef, "got %u\n", index );
2300 hr = set_input( reader, test, sizeof(test) - 1 );
2301 ok( hr == S_OK, "got %08x\n", hr );
2303 hr = WsReadNode( reader, NULL );
2304 ok( hr == S_OK, "got %08x\n", hr );
2306 index = 0xdeadbeef;
2307 hr = WsFindAttribute( reader, &localname3, &ns, FALSE, &index, NULL );
2308 ok( hr == S_FALSE, "got %08x\n", hr );
2309 ok( index == ~0u, "got %u\n", index );
2311 WsFreeReader( reader );
2314 static void prepare_namespace_test( WS_XML_READER *reader, const char *data )
2316 HRESULT hr;
2317 ULONG size = strlen( data );
2319 hr = set_input( reader, data, size );
2320 ok( hr == S_OK, "got %08x\n", hr );
2322 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2323 ok( hr == S_OK, "got %08x\n", hr );
2326 static void test_WsGetNamespaceFromPrefix(void)
2328 WS_XML_STRING prefix = {0, NULL};
2329 const WS_XML_STRING *ns;
2330 const WS_XML_NODE *node;
2331 WS_XML_READER *reader;
2332 HRESULT hr;
2334 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
2335 ok( hr == S_OK, "got %08x\n", hr );
2337 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, NULL, NULL );
2338 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2340 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, &ns, NULL );
2341 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2343 hr = WsGetNamespaceFromPrefix( NULL, &prefix, FALSE, &ns, NULL );
2344 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2346 ns = (const WS_XML_STRING *)0xdeadbeef;
2347 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2348 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2349 ok( ns == (const WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2351 hr = set_input( reader, "<prefix:t xmlns:prefix2='ns'/>", sizeof("<prefix:t xmlns:prefix2='ns'/>") - 1 );
2352 ok( hr == S_OK, "got %08x\n", hr );
2353 hr = WsReadStartElement( reader, NULL );
2354 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2356 prepare_namespace_test( reader, "<t></t>" );
2357 ns = NULL;
2358 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2359 ok( hr == S_OK, "got %08x\n", hr );
2360 ok( ns != NULL, "ns not set\n" );
2361 if (ns) ok( !ns->length, "got %u\n", ns->length );
2363 prepare_namespace_test( reader, "<t xmls='ns'></t>" );
2364 ns = NULL;
2365 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2366 ok( hr == S_OK, "got %08x\n", hr );
2367 ok( ns != NULL, "ns not set\n" );
2368 if (ns) ok( !ns->length, "got %u\n", ns->length );
2370 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2371 ns = NULL;
2372 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2373 ok( hr == S_OK, "got %08x\n", hr );
2374 ok( ns != NULL, "ns not set\n" );
2375 if (ns) ok( !ns->length, "got %u\n", ns->length );
2377 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2378 prefix.bytes = (BYTE *)"prefix";
2379 prefix.length = 6;
2380 ns = NULL;
2381 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2382 ok( hr == S_OK, "got %08x\n", hr );
2383 ok( ns != NULL, "ns not set\n" );
2384 if (ns)
2386 ok( ns->length == 2, "got %u\n", ns->length );
2387 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2390 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2391 ns = NULL;
2392 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2393 ok( hr == S_OK, "got %08x\n", hr );
2394 ok( ns != NULL, "ns not set\n" );
2395 if (ns)
2397 ok( ns->length == 2, "got %u\n", ns->length );
2398 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2401 hr = set_input( reader, "<t xmlns:prefix='ns'></t>", sizeof("<t xmlns:prefix='ns'></t>") - 1 );
2402 ok( hr == S_OK, "got %08x\n", hr );
2403 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2404 ok( hr == S_OK, "got %08x\n", hr );
2405 hr = WsGetReaderNode( reader, &node, NULL );
2406 ok( hr == S_OK, "got %08x\n", hr );
2407 if (node)
2409 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2410 WS_XML_ATTRIBUTE *attr;
2411 WS_XML_UTF8_TEXT *text;
2413 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2414 ok( elem->prefix != NULL, "prefix not set\n" );
2415 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2416 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2417 ok( elem->ns != NULL, "ns not set\n" );
2418 ok( !elem->ns->length, "got %u\n", elem->ns->length );
2419 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2420 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2421 ok( elem->attributes != NULL, "attributes not set\n" );
2423 attr = elem->attributes[0];
2424 ok( attr->singleQuote, "singleQuote not set\n" );
2425 ok( attr->isXmlNs, "isXmlNs not set\n" );
2426 ok( attr->prefix != NULL, "prefix not set\n" );
2427 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2428 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2429 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2430 ok( attr->localName != NULL, "localName not set\n" );
2431 ok( attr->localName->length == 6, "got %u\n", attr->localName->length );
2432 ok( !memcmp( attr->localName->bytes, "prefix", 6 ), "wrong data\n" );
2433 ok( attr->ns != NULL, "ns not set\n" );
2434 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2435 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2436 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2437 ok( attr->value != NULL, "value not set\n" );
2439 text = (WS_XML_UTF8_TEXT *)attr->value;
2440 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
2441 ok( !text->value.length, "got %u\n", text->value.length );
2442 ok( text->value.bytes == NULL, "bytes set\n" );
2445 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2446 hr = WsReadStartElement( reader, NULL );
2447 ok( hr == S_OK, "got %08x\n", hr );
2448 hr = WsReadEndElement( reader, NULL );
2449 ok( hr == S_OK, "got %08x\n", hr );
2450 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2451 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2453 prepare_namespace_test( reader, "<t></t>" );
2454 ns = NULL;
2455 prefix.bytes = (BYTE *)"xml";
2456 prefix.length = 3;
2457 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2458 ok( hr == S_OK, "got %08x\n", hr );
2459 ok( ns != NULL, "ns not set\n" );
2460 if (ns)
2462 ok( ns->length == 36, "got %u\n", ns->length );
2463 ok( !memcmp( ns->bytes, "http://www.w3.org/XML/1998/namespace", 36 ), "wrong data\n" );
2466 prepare_namespace_test( reader, "<t></t>" );
2467 ns = NULL;
2468 prefix.bytes = (BYTE *)"xmlns";
2469 prefix.length = 5;
2470 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2471 ok( hr == S_OK, "got %08x\n", hr );
2472 ok( ns != NULL, "ns not set\n" );
2473 if (ns)
2475 ok( ns->length == 29, "got %u\n", ns->length );
2476 ok( !memcmp( ns->bytes, "http://www.w3.org/2000/xmlns/", 29 ), "wrong data\n" );
2479 prepare_namespace_test( reader, "<t></t>" );
2480 ns = (WS_XML_STRING *)0xdeadbeef;
2481 prefix.bytes = (BYTE *)"prefix2";
2482 prefix.length = 7;
2483 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2484 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2485 ok( ns == (WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2487 prepare_namespace_test( reader, "<t></t>" );
2488 ns = (WS_XML_STRING *)0xdeadbeef;
2489 prefix.bytes = (BYTE *)"prefix2";
2490 prefix.length = 7;
2491 hr = WsGetNamespaceFromPrefix( reader, &prefix, FALSE, &ns, NULL );
2492 ok( hr == S_FALSE, "got %08x\n", hr );
2493 ok( ns == NULL, "ns not set\n" );
2495 hr = set_input( reader, "<t prefix:attr='' xmlns:prefix='ns'></t>", sizeof("<t prefix:attr='' xmlns:prefix='ns'></t>") - 1 );
2496 ok( hr == S_OK, "got %08x\n", hr );
2497 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2498 ok( hr == S_OK, "got %08x\n", hr );
2499 hr = WsGetReaderNode( reader, &node, NULL );
2500 ok( hr == S_OK, "got %08x\n", hr );
2501 if (node)
2503 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2504 WS_XML_ATTRIBUTE *attr;
2506 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2507 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
2508 ok( elem->attributes != NULL, "attributes not set\n" );
2510 attr = elem->attributes[0];
2511 ok( attr->singleQuote, "singleQuote not set\n" );
2512 ok( !attr->isXmlNs, "isXmlNs is set\n" );
2513 ok( attr->prefix != NULL, "prefix not set\n" );
2514 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2515 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2516 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2517 ok( attr->localName != NULL, "localName not set\n" );
2518 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
2519 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
2520 ok( attr->ns != NULL, "ns not set\n" );
2521 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2522 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2523 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2526 hr = set_input( reader, "<t xmlns:p='ns'><u xmlns:p='ns2'/></t>", sizeof("<t xmlns:p='ns'><u xmlns:p='ns2'/></t>") - 1 );
2527 ok( hr == S_OK, "got %08x\n", hr );
2528 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2529 ok( hr == S_OK, "got %08x\n", hr );
2530 hr = WsReadStartElement( reader, NULL );
2531 ok( hr == S_OK, "got %08x\n", hr );
2533 hr = set_input( reader, "<t xmlns:p='ns'><p:u p:a=''/></t>", sizeof("<t xmlns:p='ns'><p:u p:a=''/></t>") - 1 );
2534 ok( hr == S_OK, "got %08x\n", hr );
2535 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2536 ok( hr == S_OK, "got %08x\n", hr );
2537 hr = WsReadStartElement( reader, NULL );
2538 ok( hr == S_OK, "got %08x\n", hr );
2539 hr = WsGetReaderNode( reader, &node, NULL );
2540 ok( hr == S_OK, "got %08x\n", hr );
2541 if (node)
2543 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2544 WS_XML_ATTRIBUTE *attr;
2546 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2547 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2548 ok( elem->attributes != NULL, "attributes not set\n" );
2550 attr = elem->attributes[0];
2551 ok( attr->prefix != NULL, "prefix not set\n" );
2552 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
2553 ok( attr->prefix->bytes != NULL, "bytes set\n" );
2554 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong data\n" );
2555 ok( attr->localName != NULL, "localName not set\n" );
2556 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
2557 ok( !memcmp( attr->localName->bytes, "a", 1 ), "wrong data\n" );
2558 ok( attr->ns != NULL, "ns not set\n" );
2559 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2560 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2561 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2564 hr = set_input( reader, "<t xmlns='ns'></t>", sizeof("<t xmlns='ns'></t>") - 1 );
2565 ok( hr == S_OK, "got %08x\n", hr );
2566 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2567 ok( hr == S_OK, "got %08x\n", hr );
2568 hr = WsGetReaderNode( reader, &node, NULL );
2569 ok( hr == S_OK, "got %08x\n", hr );
2570 if (node)
2572 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2573 WS_XML_ATTRIBUTE *attr;
2575 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2576 ok( elem->prefix != NULL, "prefix not set\n" );
2577 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2578 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2579 ok( elem->ns != NULL, "ns not set\n" );
2580 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
2581 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2582 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong data\n" );
2584 attr = elem->attributes[0];
2585 ok( attr->isXmlNs, "isXmlNs is not set\n" );
2586 ok( attr->prefix != NULL, "prefix not set\n" );
2587 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
2588 ok( attr->prefix->bytes == NULL, "bytes set\n" );
2589 ok( attr->localName != NULL, "localName not set\n" );
2590 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
2591 ok( !memcmp( attr->localName->bytes, "xmlns", 5 ), "wrong data\n" );
2592 ok( attr->ns != NULL, "ns not set\n" );
2593 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2594 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2595 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2598 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns2'></t>") - 1 );
2599 ok( hr == S_OK, "got %08x\n", hr );
2600 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2601 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2603 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns'></t>") - 1 );
2604 ok( hr == S_OK, "got %08x\n", hr );
2605 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2606 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2608 hr = set_input( reader, "<t xmlns:p='ns' xmlns:P='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:P='ns2'></t>") - 1 );
2609 ok( hr == S_OK, "got %08x\n", hr );
2610 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2611 ok( hr == S_OK, "got %08x\n", hr );
2613 WsFreeReader( reader );
2616 static void test_text_field_mapping(void)
2618 static const WCHAR testW[] = {'t','e','s','t',0};
2619 HRESULT hr;
2620 WS_XML_READER *reader;
2621 WS_HEAP *heap;
2622 WS_STRUCT_DESCRIPTION s;
2623 WS_FIELD_DESCRIPTION f, *fields[1];
2624 struct test
2626 WCHAR *str;
2627 } *test;
2629 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2630 ok( hr == S_OK, "got %08x\n", hr );
2632 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
2633 ok( hr == S_OK, "got %08x\n", hr );
2635 prepare_struct_type_test( reader, "<a>test</a>" );
2637 memset( &f, 0, sizeof(f) );
2638 f.mapping = WS_TEXT_FIELD_MAPPING;
2639 f.type = WS_WSZ_TYPE;
2640 fields[0] = &f;
2642 memset( &s, 0, sizeof(s) );
2643 s.size = sizeof(struct test);
2644 s.alignment = TYPE_ALIGNMENT(struct test);
2645 s.fields = fields;
2646 s.fieldCount = 1;
2648 test = NULL;
2649 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2650 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2651 ok( hr == S_OK, "got %08x\n", hr );
2652 ok( test != NULL, "test not set\n" );
2653 ok( test->str != NULL, "str not set\n" );
2654 ok( !lstrcmpW( test->str, testW ), "got %s\n", wine_dbgstr_w(test->str) );
2656 WsFreeReader( reader );
2657 WsFreeHeap( heap );
2660 static void test_complex_struct_type(void)
2662 static const WCHAR timestampW[] =
2663 {'2','0','1','5','-','0','9','-','0','3','T','1','8',':','4','7',':','5','4',0};
2664 HRESULT hr;
2665 WS_ERROR *error;
2666 WS_ERROR_PROPERTY prop;
2667 WS_XML_READER *reader;
2668 WS_HEAP *heap;
2669 WS_STRUCT_DESCRIPTION s, s2;
2670 WS_FIELD_DESCRIPTION f, f2, *fields[1], *fields2[1];
2671 WS_XML_STRING str_officeconfig = {12, (BYTE *)"OfficeConfig"};
2672 WS_XML_STRING str_services = {8, (BYTE *)"services"};
2673 WS_XML_STRING str_generationtime = {14, (BYTE *)"GenerationTime"};
2674 WS_XML_STRING ns = {39, (BYTE *)"urn:schemas-microsoft-com:office:office"};
2675 LANGID langid = MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT );
2676 const WS_XML_NODE *node;
2677 const WS_XML_ELEMENT_NODE *elem;
2678 struct services
2680 WCHAR *generationtime;
2682 struct officeconfig
2684 struct services *services;
2685 } *test;
2687 prop.id = WS_ERROR_PROPERTY_LANGID;
2688 prop.value = &langid;
2689 prop.valueSize = sizeof(langid);
2690 hr = WsCreateError( &prop, 1, &error );
2691 ok( hr == S_OK, "got %08x\n", hr );
2693 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2694 ok( hr == S_OK, "got %08x\n", hr );
2696 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
2697 ok( hr == S_OK, "got %08x\n", hr );
2699 /* element content type mapping */
2700 prepare_struct_type_test( reader, data11 );
2702 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2703 ok( hr == S_OK, "got %08x\n", hr );
2705 hr = WsGetReaderNode( reader, &node, NULL );
2706 ok( hr == S_OK, "got %08x\n", hr );
2707 elem = (const WS_XML_ELEMENT_NODE *)node;
2708 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2709 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
2710 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
2712 hr = WsReadStartElement( reader, NULL );
2713 ok( hr == S_OK, "got %08x\n", hr );
2715 hr = WsGetReaderNode( reader, &node, NULL );
2716 ok( hr == S_OK, "got %08x\n", hr );
2717 elem = (const WS_XML_ELEMENT_NODE *)node;
2718 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2719 ok( elem->localName->length == 8, "got %u\n", elem->localName->length );
2720 ok( !memcmp( elem->localName->bytes, "services", 8 ), "wrong data\n" );
2722 memset( &f2, 0, sizeof(f2) );
2723 f2.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2724 f2.localName = &str_generationtime;
2725 f2.ns = &ns;
2726 f2.type = WS_WSZ_TYPE;
2727 f2.options = WS_FIELD_OPTIONAL;
2728 fields2[0] = &f2;
2730 memset( &s2, 0, sizeof(s2) );
2731 s2.size = sizeof(*test->services);
2732 s2.alignment = TYPE_ALIGNMENT(struct services);
2733 s2.fields = fields2;
2734 s2.fieldCount = 1;
2735 s2.typeLocalName = &str_services;
2736 s2.typeNs = &ns;
2738 memset( &f, 0, sizeof(f) );
2739 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2740 f.localName = &str_services;
2741 f.ns = &ns;
2742 f.type = WS_STRUCT_TYPE;
2743 f.typeDescription = &s2;
2744 f.options = WS_FIELD_POINTER;
2745 fields[0] = &f;
2747 memset( &s, 0, sizeof(s) );
2748 s.size = sizeof(*test);
2749 s.alignment = TYPE_ALIGNMENT(struct officeconfig);
2750 s.fields = fields;
2751 s.fieldCount = 1;
2752 s.typeLocalName = &str_officeconfig;
2753 s.typeNs = &ns;
2755 test = NULL;
2756 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2757 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2758 ok( hr == S_OK, "got %08x\n", hr );
2759 ok( test != NULL, "test not set\n" );
2760 ok( !lstrcmpW( test->services->generationtime, timestampW ), "wrong data\n" );
2762 hr = WsGetReaderNode( reader, &node, NULL );
2763 ok( hr == S_OK, "got %08x\n", hr );
2764 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2766 hr = WsReadEndElement( reader, NULL );
2767 ok( hr == S_OK, "got %08x\n", hr );
2769 hr = WsGetReaderNode( reader, &node, NULL );
2770 ok( hr == S_OK, "got %08x\n", hr );
2771 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2773 hr = WsReadEndElement( reader, NULL );
2774 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2776 /* element type mapping */
2777 prepare_struct_type_test( reader, data11 );
2779 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2780 ok( hr == S_OK, "got %08x\n", hr );
2782 hr = WsGetReaderNode( reader, &node, NULL );
2783 ok( hr == S_OK, "got %08x\n", hr );
2784 elem = (const WS_XML_ELEMENT_NODE *)node;
2785 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2786 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
2787 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
2789 test = NULL;
2790 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2791 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2792 ok( hr == S_OK, "got %08x\n", hr );
2793 ok( test != NULL, "test not set\n" );
2794 if (test) ok( !lstrcmpW( test->services->generationtime, timestampW ), "wrong data\n" );
2796 hr = WsGetReaderNode( reader, &node, NULL );
2797 ok( hr == S_OK, "got %08x\n", hr );
2798 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2800 WsFreeReader( reader );
2801 WsFreeHeap( heap );
2802 WsFreeError( error );
2805 static void test_repeating_element(void)
2807 static const WCHAR oneW[] = {'1',0}, twoW[] = {'2',0};
2808 WS_XML_STRING str_name = {4, (BYTE *)"name"};
2809 WS_XML_STRING str_services = {8, (BYTE *)"services"};
2810 WS_XML_STRING str_service = {7, (BYTE *)"service"};
2811 WS_XML_STRING str_wrapper = {7, (BYTE *)"wrapper"};
2812 WS_XML_STRING str_id = {2, (BYTE *)"id"};
2813 WS_XML_STRING str_ns = {0, NULL};
2814 HRESULT hr;
2815 WS_XML_READER *reader;
2816 WS_HEAP *heap;
2817 WS_STRUCT_DESCRIPTION s, s2;
2818 WS_FIELD_DESCRIPTION f, f2, f3, *fields[1], *fields2[2];
2819 WS_ITEM_RANGE range;
2820 struct service { UINT32 id; };
2821 struct service2 { WCHAR *id; };
2822 struct service3 { WCHAR *name; WCHAR *id; };
2823 struct services
2825 struct service *service;
2826 ULONG service_count;
2827 } *test;
2828 struct services2
2830 struct service2 *service;
2831 ULONG service_count;
2832 } *test2;
2833 struct services3
2835 struct service3 *service;
2836 ULONG service_count;
2837 } *test3;
2839 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2840 ok( hr == S_OK, "got %08x\n", hr );
2842 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
2843 ok( hr == S_OK, "got %08x\n", hr );
2845 prepare_struct_type_test( reader, data12 );
2847 memset( &f2, 0, sizeof(f2) );
2848 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
2849 f2.localName = &str_id;
2850 f2.ns = &str_ns;
2851 f2.type = WS_UINT32_TYPE;
2852 fields2[0] = &f2;
2854 memset( &s2, 0, sizeof(s2) );
2855 s2.size = sizeof(struct service);
2856 s2.alignment = TYPE_ALIGNMENT(struct service);
2857 s2.fields = fields2;
2858 s2.fieldCount = 1;
2859 s2.typeLocalName = &str_service;
2861 memset( &f, 0, sizeof(f) );
2862 f.mapping = WS_REPEATING_ELEMENT_FIELD_MAPPING;
2863 f.countOffset = FIELD_OFFSET(struct services, service_count);
2864 f.type = WS_STRUCT_TYPE;
2865 f.typeDescription = &s2;
2866 f.itemLocalName = &str_service;
2867 f.itemNs = &str_ns;
2868 fields[0] = &f;
2870 memset( &s, 0, sizeof(s) );
2871 s.size = sizeof(struct services);
2872 s.alignment = TYPE_ALIGNMENT(struct services);
2873 s.fields = fields;
2874 s.fieldCount = 1;
2875 s.typeLocalName = &str_services;
2877 test = NULL;
2878 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2879 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2880 ok( hr == S_OK, "got %08x\n", hr );
2881 ok( test != NULL, "test not set\n" );
2882 ok( test->service != NULL, "service not set\n" );
2883 ok( test->service_count == 2, "got %u\n", test->service_count );
2884 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
2885 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
2887 /* item range */
2888 prepare_struct_type_test( reader, data13 );
2889 range.minItemCount = 0;
2890 range.maxItemCount = 1;
2891 f.itemRange = &range;
2892 test = NULL;
2893 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2894 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2895 ok( hr == S_OK, "got %08x\n", hr );
2896 ok( test != NULL, "test not set\n" );
2897 ok( test->service != NULL, "service not set\n" );
2898 ok( !test->service_count, "got %u\n", test->service_count );
2900 /* wrapper element */
2901 prepare_struct_type_test( reader, data14 );
2902 f.itemRange = NULL;
2903 f.localName = &str_wrapper;
2904 f.ns = &str_ns;
2905 test = NULL;
2906 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2907 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2908 ok( hr == S_OK, "got %08x\n", hr );
2909 ok( test != NULL, "test not set\n" );
2910 ok( test->service != NULL, "service not set\n" );
2911 ok( test->service_count == 2, "got %u\n", test->service_count );
2912 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
2913 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
2915 /* repeating text field mapping */
2916 prepare_struct_type_test( reader, data15 );
2917 f2.mapping = WS_TEXT_FIELD_MAPPING;
2918 f2.localName = NULL;
2919 f2.ns = NULL;
2920 f2.type = WS_WSZ_TYPE;
2921 s2.size = sizeof(struct service2);
2922 s2.alignment = TYPE_ALIGNMENT(struct service2);
2923 test2 = NULL;
2924 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2925 WS_READ_REQUIRED_POINTER, heap, &test2, sizeof(test2), NULL );
2926 ok( hr == S_OK, "got %08x\n", hr );
2927 ok( test2 != NULL, "test2 not set\n" );
2928 ok( test2->service != NULL, "service not set\n" );
2929 ok( test2->service_count == 2, "got %u\n", test2->service_count );
2930 ok( !lstrcmpW( test2->service[0].id, oneW ), "wrong data\n" );
2931 ok( !lstrcmpW( test2->service[1].id, twoW ), "wrong data\n" );
2933 /* repeating attribute field + text field mapping */
2934 prepare_struct_type_test( reader, data16 );
2935 f2.offset = FIELD_OFFSET(struct service3, id);
2936 memset( &f3, 0, sizeof(f3) );
2937 f3.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2938 f3.localName = &str_name;
2939 f3.ns = &str_ns;
2940 f3.type = WS_WSZ_TYPE;
2941 fields2[0] = &f3;
2942 fields2[1] = &f2;
2943 s2.size = sizeof(struct service3);
2944 s2.alignment = TYPE_ALIGNMENT(struct service3);
2945 s2.fieldCount = 2;
2946 test3 = NULL;
2947 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2948 WS_READ_REQUIRED_POINTER, heap, &test3, sizeof(test3), NULL );
2949 ok( hr == S_OK, "got %08x\n", hr );
2950 ok( test3 != NULL, "test3 not set\n" );
2951 ok( test3->service != NULL, "service not set\n" );
2952 ok( test3->service_count == 2, "got %u\n", test3->service_count );
2953 ok( !lstrcmpW( test3->service[0].name, oneW ), "wrong data\n" );
2954 ok( !lstrcmpW( test3->service[0].id, oneW ), "wrong data\n" );
2955 ok( !lstrcmpW( test3->service[1].name, twoW ), "wrong data\n" );
2956 ok( !lstrcmpW( test3->service[1].id, twoW ), "wrong data\n" );
2958 WsFreeReader( reader );
2959 WsFreeHeap( heap );
2962 static void test_WsResetHeap(void)
2964 HRESULT hr;
2965 WS_HEAP *heap;
2966 SIZE_T requested, actual;
2967 ULONG size;
2968 void *ptr;
2970 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2971 ok( hr == S_OK, "got %08x\n", hr );
2973 requested = 0xdeadbeef;
2974 size = sizeof(requested);
2975 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
2976 ok( hr == S_OK, "got %08x\n", hr );
2977 ok( !requested, "got %u\n", (ULONG)requested );
2979 actual = 0xdeadbeef;
2980 size = sizeof(actual);
2981 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
2982 ok( hr == S_OK, "got %08x\n", hr );
2983 ok( !actual, "got %u\n", (ULONG)actual );
2985 hr = WsAlloc( heap, 128, &ptr, NULL );
2986 ok( hr == S_OK, "got %08x\n", hr );
2988 requested = 0xdeadbeef;
2989 size = sizeof(requested);
2990 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
2991 ok( hr == S_OK, "got %08x\n", hr );
2992 todo_wine ok( requested == 128, "got %u\n", (ULONG)requested );
2994 actual = 0xdeadbeef;
2995 size = sizeof(actual);
2996 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
2997 ok( hr == S_OK, "got %08x\n", hr );
2998 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
3000 hr = WsAlloc( heap, 1, &ptr, NULL );
3001 ok( hr == S_OK, "got %08x\n", hr );
3003 requested = 0xdeadbeef;
3004 size = sizeof(requested);
3005 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3006 ok( hr == S_OK, "got %08x\n", hr );
3007 todo_wine ok( requested == 129, "got %u\n", (ULONG)requested );
3009 actual = 0xdeadbeef;
3010 size = sizeof(actual);
3011 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3012 ok( hr == S_OK, "got %08x\n", hr );
3013 todo_wine ok( actual == 384, "got %u\n", (ULONG)actual );
3015 hr = WsResetHeap( NULL, NULL );
3016 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3018 hr = WsResetHeap( heap, NULL );
3019 ok( hr == S_OK, "got %08x\n", hr );
3021 requested = 0xdeadbeef;
3022 size = sizeof(requested);
3023 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3024 ok( hr == S_OK, "got %08x\n", hr );
3025 ok( !requested, "got %u\n", (ULONG)requested );
3027 actual = 0xdeadbeef;
3028 size = sizeof(actual);
3029 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3030 ok( hr == S_OK, "got %08x\n", hr );
3031 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
3033 WsFreeHeap( heap );
3036 static void test_datetime(void)
3038 static const struct
3040 const char *str;
3041 HRESULT hr;
3042 __int64 ticks;
3043 WS_DATETIME_FORMAT format;
3045 tests[] =
3047 {"<t>0000-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3048 {"<t>0001-01-01T00:00:00Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3049 {"<t>0001-01-01T00:00:00.Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3050 {"<t>0001-01-01T00:00:00.0Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3051 {"<t>0001-01-01T00:00:00.1Z</t>", S_OK, 0x0000f4240, WS_DATETIME_FORMAT_UTC},
3052 {"<t>0001-01-01T00:00:00.01Z</t>", S_OK, 0x0000186a0, WS_DATETIME_FORMAT_UTC},
3053 {"<t>0001-01-01T00:00:00.0000001Z</t>", S_OK, 1, WS_DATETIME_FORMAT_UTC},
3054 {"<t>0001-01-01T00:00:00.9999999Z</t>", S_OK, 0x00098967f, WS_DATETIME_FORMAT_UTC},
3055 {"<t>0001-01-01T00:00:00.0000000Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3056 {"<t>0001-01-01T00:00:00.00000001Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3057 {"<t>0001-01-01T00:00:00Z-</t>", WS_E_INVALID_FORMAT, 0},
3058 {"<t>-0001-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3059 {"<t>0001-00-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3060 {"<t>0001-13-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3061 {"<t>0001-12-01T00:00:00Z</t>", S_OK, 0x1067555f88000, WS_DATETIME_FORMAT_UTC},
3062 {"<t>0001-01-00T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3063 {"<t>2001-01-32T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3064 {"<t>2001-01-31T00:00:00Z</t>", S_OK, 0x8c2592fe3794000, WS_DATETIME_FORMAT_UTC},
3065 {"<t>1900-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3066 {"<t>2000-02-29T00:00:00Z</t>", S_OK, 0x8c1505f0e438000, 0},
3067 {"<t>2001-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3068 {"<t>2001-02-28T00:00:00Z</t>", S_OK, 0x8c26f30870a4000, WS_DATETIME_FORMAT_UTC},
3069 {"<t>0001-00-01U00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3070 {"<t>0001-01-01T24:00:00Z</t>", S_OK, 0xc92a69c000, WS_DATETIME_FORMAT_UTC},
3071 {"<t>0001-01-01T24:00:01Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3072 {"<t>0001-01-01T00:60:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3073 {"<t>0001-01-01T00:00:60Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3074 {"<t>0001-01-01T00:00:00Y</t>", WS_E_INVALID_FORMAT, 0, 0},
3075 {"<t>0001-01-01T00:00:00+00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3076 {"<t>0001-01-01T00:00:00-00:01</t>", S_OK, 0x023c34600, WS_DATETIME_FORMAT_LOCAL},
3077 {"<t>9999-12-31T24:00:00+00:01</t>", S_OK, 0x2bca2875d073fa00, WS_DATETIME_FORMAT_LOCAL},
3078 {"<t>9999-12-31T24:00:00-00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3079 {"<t>0002-01-01T00:00:00+14:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3080 {"<t>0002-01-01T00:00:00+15:00</t>", WS_E_INVALID_FORMAT, 0, 0},
3081 {"<t>0002-01-01T00:00:00+13:60</t>", WS_E_INVALID_FORMAT, 0, 0},
3082 {"<t>0002-01-01T00:00:00+13:59</t>", S_OK, 0x11e5c43cc5600, WS_DATETIME_FORMAT_LOCAL},
3083 {"<t>0002-01-01T00:00:00+01:00</t>", S_OK, 0x11ec917025800, WS_DATETIME_FORMAT_LOCAL},
3084 {"<t>2016-01-01T00:00:00-01:00</t>", S_OK, 0x8d31246dfbba800, WS_DATETIME_FORMAT_LOCAL},
3085 {"<t>2016-01-01T00:00:00Z</t>", S_OK, 0x8d3123e7df74000, WS_DATETIME_FORMAT_UTC},
3086 {"<t> 2016-01-02T03:04:05Z </t>", S_OK, 0x8d313215fb64080, WS_DATETIME_FORMAT_UTC},
3087 {"<t>+2016-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3088 {"<t></t>", WS_E_INVALID_FORMAT, 0, 0},
3089 {"<t>01-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3090 {"<t>1601-01-01T00:00:00Z</t>", S_OK, 0x701ce1722770000, WS_DATETIME_FORMAT_UTC},
3092 HRESULT hr;
3093 WS_XML_READER *reader;
3094 WS_HEAP *heap;
3095 WS_DATETIME date;
3096 ULONG i;
3098 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3099 ok( hr == S_OK, "got %08x\n", hr );
3101 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
3102 ok( hr == S_OK, "got %08x\n", hr );
3103 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3105 memset( &date, 0, sizeof(date) );
3106 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3107 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DATETIME_TYPE, NULL,
3108 WS_READ_REQUIRED_VALUE, heap, &date, sizeof(date), NULL );
3109 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3110 if (hr == S_OK)
3112 ok( date.ticks == tests[i].ticks, "%u: got %x%08x\n", i, (ULONG)(date.ticks >> 32), (ULONG)date.ticks );
3113 ok( date.format == tests[i].format, "%u: got %u\n", i, date.format );
3117 WsFreeReader( reader );
3118 WsFreeHeap( heap );
3121 static void test_WsDateTimeToFileTime(void)
3123 static const struct
3125 WS_DATETIME dt;
3126 HRESULT hr;
3127 FILETIME ft;
3129 tests[] =
3131 { {0, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3132 { {0x701ce172276ffff, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3133 { {0x701ce1722770000, WS_DATETIME_FORMAT_UTC}, S_OK, {0, 0} },
3134 { {0x2bca2875f4373fff, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c03fff, 0x24c85a5e} },
3135 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c04000, 0x24c85a5e} },
3136 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_LOCAL}, S_OK, {0xd1c04000, 0x24c85a5e} },
3137 { {~0, WS_DATETIME_FORMAT_UTC}, S_OK, {0xdd88ffff, 0xf8fe31e8} },
3139 WS_DATETIME dt;
3140 FILETIME ft;
3141 HRESULT hr;
3142 ULONG i;
3144 hr = WsDateTimeToFileTime( NULL, NULL, NULL );
3145 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3147 dt.ticks = 0x701ce172277000;
3148 dt.format = WS_DATETIME_FORMAT_UTC;
3149 hr = WsDateTimeToFileTime( &dt, NULL, NULL );
3150 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3152 hr = WsDateTimeToFileTime( NULL, &ft, NULL );
3153 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3155 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3157 memset( &ft, 0, sizeof(ft) );
3158 hr = WsDateTimeToFileTime( &tests[i].dt, &ft, NULL );
3159 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3160 if (hr == S_OK)
3162 ok( ft.dwLowDateTime == tests[i].ft.dwLowDateTime, "%u: got %08x\n", i, ft.dwLowDateTime );
3163 ok( ft.dwHighDateTime == tests[i].ft.dwHighDateTime, "%u: got %08x\n", i, ft.dwHighDateTime );
3168 static void test_WsFileTimeToDateTime(void)
3170 WS_DATETIME dt;
3171 FILETIME ft;
3172 HRESULT hr;
3174 hr = WsFileTimeToDateTime( NULL, NULL, NULL );
3175 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3177 ft.dwLowDateTime = ft.dwHighDateTime = 0;
3178 hr = WsFileTimeToDateTime( &ft, NULL, NULL );
3179 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3181 hr = WsFileTimeToDateTime( NULL, &dt, NULL );
3182 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3184 dt.ticks = 0xdeadbeef;
3185 dt.format = 0xdeadbeef;
3186 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3187 ok( hr == S_OK, "got %08x\n", hr );
3188 ok( dt.ticks == 0x701ce1722770000, "got %x%08x\n", (ULONG)(dt.ticks >> 32), (ULONG)dt.ticks );
3189 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3191 ft.dwLowDateTime = 0xd1c03fff;
3192 ft.dwHighDateTime = 0x24c85a5e;
3193 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3194 ok( hr == S_OK, "got %08x\n", hr );
3195 ok( dt.ticks == 0x2bca2875f4373fff, "got %x%08x\n", (ULONG)(dt.ticks >> 32), (ULONG)dt.ticks );
3196 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3198 ft.dwLowDateTime++;
3199 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3200 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3202 ft.dwLowDateTime = 0xdd88ffff;
3203 ft.dwHighDateTime = 0xf8fe31e8;
3204 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3205 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3207 ft.dwLowDateTime++;
3208 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3209 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
3212 static void test_double(void)
3214 static const struct
3216 const char *str;
3217 HRESULT hr;
3218 ULONGLONG val;
3220 tests[] =
3222 {"<t>0.0</t>", S_OK, 0},
3223 {"<t>-0.0</t>", S_OK, 0x8000000000000000},
3224 {"<t>+0.0</t>", S_OK, 0},
3225 {"<t>-</t>", S_OK, 0},
3226 {"<t>+</t>", S_OK, 0},
3227 {"<t>.0</t>", S_OK, 0},
3228 {"<t>0.</t>", S_OK, 0},
3229 {"<t>0</t>", S_OK, 0},
3230 {"<t> 0 </t>", S_OK, 0},
3231 {"<t></t>", WS_E_INVALID_FORMAT, 0},
3232 {"<t>0,1</t>", WS_E_INVALID_FORMAT, 0},
3233 {"<t>1.1.</t>", WS_E_INVALID_FORMAT, 0},
3234 {"<t>1</t>", S_OK, 0x3ff0000000000000},
3235 {"<t>1.0000000000000002</t>", S_OK, 0x3ff0000000000001},
3236 {"<t>1.0000000000000004</t>", S_OK, 0x3ff0000000000002},
3237 {"<t>10000000000000000000</t>", S_OK, 0x43e158e460913d00},
3238 {"<t>100000000000000000000</t>", S_OK, 0x4415af1d78b58c40},
3239 {"<t>2</t>", S_OK, 0x4000000000000000},
3240 {"<t>-2</t>", S_OK, 0xc000000000000000},
3241 {"<t>nodouble</t>", WS_E_INVALID_FORMAT, 0},
3242 {"<t>INF</t>", S_OK, 0x7ff0000000000000},
3243 {"<t>-INF</t>", S_OK, 0xfff0000000000000},
3244 {"<t>+INF</t>", WS_E_INVALID_FORMAT, 0},
3245 {"<t>Infinity</t>", WS_E_INVALID_FORMAT, 0},
3246 {"<t>-Infinity</t>", WS_E_INVALID_FORMAT, 0},
3247 {"<t>inf</t>", WS_E_INVALID_FORMAT, 0},
3248 {"<t>NaN</t>", S_OK, 0xfff8000000000000},
3249 {"<t>-NaN</t>", WS_E_INVALID_FORMAT, 0},
3250 {"<t>NAN</t>", WS_E_INVALID_FORMAT, 0},
3251 {"<t>0.3</t>", S_OK, 0x3fd3333333333333},
3252 {"<t>0.33</t>", S_OK, 0x3fd51eb851eb851f},
3253 {"<t>0.333</t>", S_OK, 0x3fd54fdf3b645a1d},
3254 {"<t>0.3333</t>", S_OK, 0x3fd554c985f06f69},
3255 {"<t>0.33333</t>", S_OK, 0x3fd555475a31a4be},
3256 {"<t>0.333333</t>", S_OK, 0x3fd55553ef6b5d46},
3257 {"<t>0.3333333</t>", S_OK, 0x3fd55555318abc87},
3258 {"<t>0.33333333</t>", S_OK, 0x3fd5555551c112da},
3259 {"<t>0.333333333</t>", S_OK, 0x3fd5555554f9b516},
3260 {"<t>0.3333333333</t>", S_OK, 0x3fd55555554c2bb5},
3261 {"<t>0.33333333333</t>", S_OK, 0x3fd5555555546ac5},
3262 {"<t>0.3333333333333</t>", S_OK, 0x3fd55555555552fd},
3263 {"<t>0.33333333333333</t>", S_OK, 0x3fd5555555555519},
3264 {"<t>0.333333333333333</t>", S_OK, 0x3fd555555555554f},
3265 {"<t>0.3333333333333333</t>", S_OK, 0x3fd5555555555555},
3266 {"<t>0.33333333333333333</t>", S_OK, 0x3fd5555555555555},
3267 {"<t>0.1e10</t>", S_OK, 0x41cdcd6500000000},
3268 {"<t>1e</t>", WS_E_INVALID_FORMAT, 0},
3269 {"<t>1e0</t>", S_OK, 0x3ff0000000000000},
3270 {"<t>1e+1</t>", S_OK, 0x4024000000000000},
3271 {"<t>1e-1</t>", S_OK, 0x3fb999999999999a},
3272 {"<t>e10</t>", WS_E_INVALID_FORMAT, 0},
3273 {"<t>1e10.</t>", WS_E_INVALID_FORMAT, 0},
3274 {"<t>1E10</t>", S_OK, 0x4202a05f20000000},
3275 {"<t>1e10</t>", S_OK, 0x4202a05f20000000},
3276 {"<t>1e-10</t>", S_OK, 0x3ddb7cdfd9d7bdbb},
3277 {"<t>1.7976931348623158e308</t>", S_OK, 0x7fefffffffffffff},
3278 {"<t>1.7976931348623159e308</t>", S_OK, 0x7ff0000000000000},
3279 {"<t>4.94065645841247e-324</t>", S_OK, 0x1},
3281 HRESULT hr;
3282 WS_XML_READER *reader;
3283 WS_HEAP *heap;
3284 ULONGLONG val;
3285 ULONG i;
3287 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3288 ok( hr == S_OK, "got %08x\n", hr );
3290 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
3291 ok( hr == S_OK, "got %08x\n", hr );
3293 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3295 val = 0;
3296 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3297 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DOUBLE_TYPE, NULL,
3298 WS_READ_REQUIRED_VALUE, heap, &val, sizeof(val), NULL );
3299 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3300 if (hr == tests[i].hr) ok( val == tests[i].val, "%u: got %x%08x\n", i, (ULONG)(val >> 32), (ULONG)val );
3303 WsFreeReader( reader );
3304 WsFreeHeap( heap );
3307 static void test_WsReadElement(void)
3309 WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
3310 HRESULT hr;
3311 WS_XML_READER *reader;
3312 WS_ELEMENT_DESCRIPTION desc;
3313 UINT32 val;
3315 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
3316 ok( hr == S_OK, "got %08x\n", hr );
3318 desc.elementLocalName = &localname;
3319 desc.elementNs = &ns;
3320 desc.type = WS_UINT32_TYPE;
3321 desc.typeDescription = NULL;
3323 prepare_struct_type_test( reader, "<t>1</t>" );
3324 hr = WsReadElement( NULL, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3325 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3327 prepare_struct_type_test( reader, "<t>1</t>" );
3328 hr = WsReadElement( reader, NULL, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3329 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3331 prepare_struct_type_test( reader, "<t>1</t>" );
3332 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, NULL, sizeof(val), NULL );
3333 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3335 prepare_struct_type_test( reader, "<t>1</t>" );
3336 val = 0xdeadbeef;
3337 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3338 ok( hr == S_OK, "got %08x\n", hr );
3339 ok( val == 1, "got %u\n", val );
3341 WsFreeReader( reader );
3344 static void test_WsReadValue(void)
3346 HRESULT hr;
3347 WS_XML_READER *reader;
3348 UINT32 val;
3350 hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
3351 ok( hr == S_OK, "got %08x\n", hr );
3353 prepare_struct_type_test( reader, "<t>1</t>" );
3354 hr = WsReadValue( NULL, WS_UINT32_TYPE, &val, sizeof(val), NULL );
3355 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3357 prepare_struct_type_test( reader, "<t>1</t>" );
3358 hr = WsReadValue( reader, WS_UINT32_TYPE, NULL, sizeof(val), NULL );
3359 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3361 /* reader must be positioned correctly */
3362 prepare_struct_type_test( reader, "<t>1</t>" );
3363 hr = WsReadValue( reader, WS_UINT32_TYPE, &val, sizeof(val), NULL );
3364 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3366 prepare_struct_type_test( reader, "<t>1</t>" );
3367 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3368 ok( hr == S_OK, "got %08x\n", hr );
3370 hr = WsReadValue( reader, WS_UINT32_TYPE, &val, sizeof(val), NULL );
3371 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3373 prepare_struct_type_test( reader, "<t>1</t>" );
3374 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3375 ok( hr == S_OK, "got %08x\n", hr );
3377 hr = WsReadStartElement( reader, NULL );
3378 ok( hr == S_OK, "got %08x\n", hr );
3380 val = 0xdeadbeef;
3381 hr = WsReadValue( reader, WS_UINT32_TYPE, &val, sizeof(val), NULL );
3382 ok( hr == S_OK, "got %08x\n", hr );
3383 ok( val == 1, "got %u\n", val );
3385 prepare_struct_type_test( reader, "<u t='1'></u>" );
3386 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3387 ok( hr == S_OK, "got %08x\n", hr );
3389 hr = WsReadValue( reader, WS_UINT32_TYPE, &val, sizeof(val), NULL );
3390 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3392 WsFreeReader( reader );
3395 static void test_WsResetError(void)
3397 WS_ERROR_PROPERTY prop;
3398 ULONG size, code;
3399 WS_ERROR *error;
3400 LANGID langid;
3401 HRESULT hr;
3403 hr = WsResetError( NULL );
3404 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3406 error = NULL;
3407 hr = WsCreateError( NULL, 0, &error );
3408 ok( hr == S_OK, "got %08x\n", hr );
3409 ok( error != NULL, "error not set\n" );
3411 code = 0xdeadbeef;
3412 size = sizeof(code);
3413 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3414 ok( hr == S_OK, "got %08x\n", hr );
3416 hr = WsResetError( error );
3417 ok( hr == S_OK, "got %08x\n", hr );
3419 code = 0xdeadbeef;
3420 size = sizeof(code);
3421 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3422 ok( hr == S_OK, "got %08x\n", hr );
3423 ok( !code, "got %u\n", code );
3425 WsFreeError( error );
3427 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
3428 prop.id = WS_ERROR_PROPERTY_LANGID;
3429 prop.value = &langid;
3430 prop.valueSize = sizeof(langid);
3431 hr = WsCreateError( &prop, 1, &error );
3432 ok( hr == S_OK, "got %08x\n", hr );
3434 langid = 0xdead;
3435 size = sizeof(langid);
3436 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3437 ok( hr == S_OK, "got %08x\n", hr );
3438 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3440 hr = WsResetError( error );
3441 ok( hr == S_OK, "got %08x\n", hr );
3443 langid = 0xdead;
3444 size = sizeof(langid);
3445 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3446 ok( hr == S_OK, "got %08x\n", hr );
3447 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3449 WsFreeError( error );
3452 START_TEST(reader)
3454 test_WsCreateError();
3455 test_WsCreateHeap();
3456 test_WsCreateReader();
3457 test_WsSetInput();
3458 test_WsSetInputToBuffer();
3459 test_WsFillReader();
3460 test_WsReadToStartElement();
3461 test_WsReadStartElement();
3462 test_WsReadEndElement();
3463 test_WsReadNode();
3464 test_WsReadType();
3465 test_WsGetXmlAttribute();
3466 test_WsXmlStringEquals();
3467 test_WsAlloc();
3468 test_WsMoveReader();
3469 test_simple_struct_type();
3470 test_cdata();
3471 test_WsFindAttribute();
3472 test_WsGetNamespaceFromPrefix();
3473 test_text_field_mapping();
3474 test_complex_struct_type();
3475 test_repeating_element();
3476 test_WsResetHeap();
3477 test_datetime();
3478 test_WsDateTimeToFileTime();
3479 test_WsFileTimeToDateTime();
3480 test_double();
3481 test_WsReadElement();
3482 test_WsReadValue();
3483 test_WsResetError();