webservices: Implement WsReadAttribute.
[wine.git] / dlls / webservices / tests / reader.c
blob1598cb25508d22bc336944ad76dc7370da44a7e1
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 data11b[] =
75 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
76 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\"></o:services>"
77 "<trailing>content</trailing>"
78 "</o:OfficeConfig>";
80 static const char data12[] =
81 "<services>"
82 "<service><id>1</id></service>"
83 "<service><id>2</id></service>"
84 "</services>";
86 static const char data13[] =
87 "<services></services>";
89 static const char data14[] =
90 "<services>"
91 "<wrapper>"
92 "<service><id>1</id></service>"
93 "<service><id>2</id></service>"
94 "</wrapper>"
95 "</services>";
97 static const char data15[] =
98 "<services>"
99 "<wrapper>"
100 "<service>1</service>"
101 "<service>2</service>"
102 "</wrapper>"
103 "</services>";
105 static const char data16[] =
106 "<services>"
107 "<wrapper>"
108 "<service name='1'>1</service>"
109 "<service name='2'>2</service>"
110 "</wrapper>"
111 "</services>";
113 static void test_WsCreateError(void)
115 HRESULT hr;
116 WS_ERROR *error;
117 WS_ERROR_PROPERTY prop;
118 ULONG size, code, count;
119 LANGID langid;
121 hr = WsCreateError( NULL, 0, NULL );
122 ok( hr == E_INVALIDARG, "got %08x\n", hr );
124 error = NULL;
125 hr = WsCreateError( NULL, 0, &error );
126 ok( hr == S_OK, "got %08x\n", hr );
127 ok( error != NULL, "error not set\n" );
129 count = 0xdeadbeef;
130 size = sizeof(count);
131 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
132 ok( hr == S_OK, "got %08x\n", hr );
133 ok( !count, "got %u\n", count );
135 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
136 ok( hr == E_INVALIDARG, "got %08x\n", hr );
138 code = 0xdeadbeef;
139 size = sizeof(code);
140 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
141 ok( hr == S_OK, "got %08x\n", hr );
142 ok( !code, "got %u\n", code );
144 code = 0xdeadbeef;
145 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
146 ok( hr == S_OK, "got %08x\n", hr );
147 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
148 ok( hr == S_OK, "got %08x\n", hr );
149 ok( code == 0xdeadbeef, "got %u\n", code );
151 langid = 0xdead;
152 size = sizeof(langid);
153 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
154 ok( hr == S_OK, "got %08x\n", hr );
155 ok( langid == GetUserDefaultUILanguage(), "got %u\n", langid );
157 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
158 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
159 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
161 count = 0xdeadbeef;
162 size = sizeof(count);
163 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID + 1, &count, size );
164 ok( hr == E_INVALIDARG, "got %08x\n", hr );
165 ok( count == 0xdeadbeef, "got %u\n", count );
166 WsFreeError( error );
168 count = 1;
169 prop.id = WS_ERROR_PROPERTY_STRING_COUNT;
170 prop.value = &count;
171 prop.valueSize = sizeof(count);
172 hr = WsCreateError( &prop, 1, &error );
173 ok( hr == E_INVALIDARG, "got %08x\n", hr );
175 code = 0xdeadbeef;
176 prop.id = WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE;
177 prop.value = &code;
178 prop.valueSize = sizeof(code);
179 hr = WsCreateError( &prop, 1, &error );
180 ok( hr == E_INVALIDARG, "got %08x\n", hr );
182 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
183 prop.id = WS_ERROR_PROPERTY_LANGID;
184 prop.value = &langid;
185 prop.valueSize = sizeof(langid);
186 hr = WsCreateError( &prop, 1, &error );
187 ok( hr == S_OK, "got %08x\n", hr );
189 langid = 0xdead;
190 size = sizeof(langid);
191 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
192 ok( hr == S_OK, "got %08x\n", hr );
193 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
194 WsFreeError( error );
196 count = 0xdeadbeef;
197 prop.id = WS_ERROR_PROPERTY_LANGID + 1;
198 prop.value = &count;
199 prop.valueSize = sizeof(count);
200 hr = WsCreateError( &prop, 1, &error );
201 ok( hr == E_INVALIDARG, "got %08x\n", hr );
204 static void test_WsCreateHeap(void)
206 HRESULT hr;
207 WS_HEAP *heap;
208 WS_HEAP_PROPERTY prop;
209 SIZE_T max, trim, requested, actual;
210 ULONG size;
212 hr = WsCreateHeap( 0, 0, NULL, 0, NULL, NULL );
213 ok( hr == E_INVALIDARG, "got %08x\n", hr );
215 heap = NULL;
216 hr = WsCreateHeap( 0, 0, NULL, 0, &heap, NULL );
217 ok( hr == S_OK, "got %08x\n", hr );
218 ok( heap != NULL, "heap not set\n" );
219 WsFreeHeap( heap );
221 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, NULL, NULL );
222 ok( hr == E_INVALIDARG, "got %08x\n", hr );
224 heap = NULL;
225 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
226 ok( hr == S_OK, "got %08x\n", hr );
227 ok( heap != NULL, "heap not set\n" );
228 WsFreeHeap( heap );
230 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, &heap, NULL );
231 ok( hr == S_OK, "got %08x\n", hr );
233 max = 0xdeadbeef;
234 size = sizeof(max);
235 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_MAX_SIZE, &max, size, NULL );
236 ok( hr == S_OK, "got %08x\n", hr );
237 ok( max == 1 << 16, "got %u\n", (ULONG)max );
239 trim = 0xdeadbeef;
240 size = sizeof(trim);
241 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_TRIM_SIZE, &trim, size, NULL );
242 ok( hr == S_OK, "got %08x\n", hr );
243 ok( trim == 1 << 6, "got %u\n", (ULONG)trim );
245 requested = 0xdeadbeef;
246 size = sizeof(requested);
247 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
248 ok( hr == S_OK, "got %08x\n", hr );
249 ok( !requested, "got %u\n", (ULONG)requested );
251 actual = 0xdeadbeef;
252 size = sizeof(actual);
253 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
254 ok( hr == S_OK, "got %08x\n", hr );
255 ok( !actual, "got %u\n", (ULONG)actual );
257 actual = 0xdeadbeef;
258 size = sizeof(actual);
259 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE + 1, &actual, size, NULL );
260 ok( hr == E_INVALIDARG, "got %08x\n", hr );
261 ok( actual == 0xdeadbeef, "got %u\n", (ULONG)actual );
262 WsFreeHeap( heap );
264 max = 1 << 16;
265 prop.id = WS_HEAP_PROPERTY_MAX_SIZE;
266 prop.value = &max;
267 prop.valueSize = sizeof(max);
268 hr = WsCreateHeap( 1 << 16, 1 << 6, &prop, 1, &heap, NULL );
269 ok( hr == E_INVALIDARG, "got %08x\n", hr );
271 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 1, &heap, NULL );
272 ok( hr == E_INVALIDARG, "got %08x\n", hr );
275 static HRESULT set_input( WS_XML_READER *reader, const char *data, ULONG size )
277 WS_XML_READER_TEXT_ENCODING text = {{WS_XML_READER_ENCODING_TYPE_TEXT}, WS_CHARSET_AUTO};
278 WS_XML_READER_BUFFER_INPUT buf;
280 buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
281 buf.encodedData = (void *)data;
282 buf.encodedDataSize = size;
283 return WsSetInput( reader, &text.encoding, &buf.input, NULL, 0, NULL );
286 static void test_WsCreateReader(void)
288 HRESULT hr;
289 WS_XML_READER *reader;
290 WS_XML_READER_PROPERTY prop;
291 ULONG size, max_depth, max_attrs, trim_size, buffer_size, max_ns;
292 BOOL allow_fragment, read_decl, in_attr;
293 ULONGLONG row, column;
294 WS_CHARSET charset;
296 hr = WsCreateReader( NULL, 0, NULL, NULL );
297 ok( hr == E_INVALIDARG, "got %08x\n", hr );
299 reader = NULL;
300 hr = WsCreateReader( NULL, 0, &reader, NULL );
301 ok( hr == S_OK, "got %08x\n", hr );
302 ok( reader != NULL, "reader not set\n" );
304 /* can't retrieve properties before input is set */
305 max_depth = 0xdeadbeef;
306 size = sizeof(max_depth);
307 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
308 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
309 ok( max_depth == 0xdeadbeef, "max_depth set\n" );
311 hr = set_input( reader, data1, sizeof(data1) - 1 );
312 ok( hr == S_OK, "got %08x\n", hr );
314 /* check some defaults */
315 max_depth = 0xdeadbeef;
316 size = sizeof(max_depth);
317 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
318 ok( hr == S_OK, "got %08x\n", hr );
319 ok( max_depth == 32, "got %u\n", max_depth );
321 allow_fragment = TRUE;
322 size = sizeof(allow_fragment);
323 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_ALLOW_FRAGMENT, &allow_fragment, size, NULL );
324 ok( hr == S_OK, "got %08x\n", hr );
325 ok( !allow_fragment, "got %d\n", allow_fragment );
327 max_attrs = 0xdeadbeef;
328 size = sizeof(max_attrs);
329 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES, &max_attrs, size, NULL );
330 ok( hr == S_OK, "got %08x\n", hr );
331 ok( max_attrs == 128, "got %u\n", max_attrs );
333 read_decl = FALSE;
334 size = sizeof(read_decl);
335 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_READ_DECLARATION, &read_decl, size, NULL );
336 ok( hr == S_OK, "got %08x\n", hr );
337 ok( read_decl, "got %u\n", read_decl );
339 charset = 0xdeadbeef;
340 size = sizeof(charset);
341 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
342 ok( hr == S_OK, "got %08x\n", hr );
343 ok( charset == WS_CHARSET_UTF8, "got %u\n", charset );
345 size = sizeof(trim_size);
346 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_UTF8_TRIM_SIZE, &trim_size, size, NULL );
347 todo_wine ok( hr == E_INVALIDARG, "got %08x\n", hr );
348 WsFreeReader( reader );
350 hr = WsCreateReader( NULL, 0, &reader, NULL );
351 ok( hr == S_OK, "got %08x\n", hr );
353 hr = set_input( reader, data1, sizeof(data1) - 1 );
354 ok( hr == S_OK, "got %08x\n", hr );
356 size = sizeof(buffer_size);
357 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_STREAM_BUFFER_SIZE, &buffer_size, size, NULL );
358 todo_wine ok( hr == E_INVALIDARG, "got %08x\n", hr );
359 WsFreeReader( reader );
361 hr = WsCreateReader( NULL, 0, &reader, NULL );
362 ok( hr == S_OK, "got %08x\n", hr );
364 hr = set_input( reader, data1, sizeof(data1) - 1 );
365 ok( hr == S_OK, "got %08x\n", hr );
367 max_ns = 0xdeadbeef;
368 size = sizeof(max_ns);
369 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_NAMESPACES, &max_ns, size, NULL );
370 ok( hr == S_OK, "got %08x\n", hr );
371 ok( max_ns == 32, "got %u\n", max_ns );
372 WsFreeReader( reader );
374 /* change a property */
375 max_depth = 16;
376 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
377 prop.value = &max_depth;
378 prop.valueSize = sizeof(max_depth);
379 hr = WsCreateReader( &prop, 1, &reader, NULL );
380 ok( hr == S_OK, "got %08x\n", hr );
382 hr = set_input( reader, data1, sizeof(data1) - 1 );
383 ok( hr == S_OK, "got %08x\n", hr );
385 max_depth = 0xdeadbeef;
386 size = sizeof(max_depth);
387 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
388 ok( hr == S_OK, "got %08x\n", hr );
389 ok( max_depth == 16, "got %u\n", max_depth );
390 WsFreeReader( reader );
392 /* show that some properties are read-only */
393 row = 1;
394 prop.id = WS_XML_READER_PROPERTY_ROW;
395 prop.value = &row;
396 prop.valueSize = sizeof(row);
397 hr = WsCreateReader( &prop, 1, &reader, NULL );
398 ok( hr == E_INVALIDARG, "got %08x\n", hr );
400 column = 1;
401 prop.id = WS_XML_READER_PROPERTY_COLUMN;
402 prop.value = &column;
403 prop.valueSize = sizeof(column);
404 hr = WsCreateReader( &prop, 1, &reader, NULL );
405 ok( hr == E_INVALIDARG, "got %08x\n", hr );
407 in_attr = TRUE;
408 prop.id = WS_XML_READER_PROPERTY_IN_ATTRIBUTE;
409 prop.value = &in_attr;
410 prop.valueSize = sizeof(in_attr);
411 hr = WsCreateReader( &prop, 1, &reader, NULL );
412 ok( hr == E_INVALIDARG, "got %08x\n", hr );
415 static void test_WsSetInput(void)
417 static char test1[] = {0xef,0xbb,0xbf,'<','a','/','>'};
418 static char test2[] = {'<','a','/','>'};
419 static char test3[] = {'<','!','-','-'};
420 static char test4[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"',
421 ' ','e','n','c','o','d','i','n','g','=','"','u','t','f','-','8','"','?','>'};
422 static char test5[] = {'<','?','x','m','l',' ','e','n','c','o','d','i','n','g','=',
423 '"','u','t','f','-','8','"','?','>'};
424 static char test6[] = {'<','?','x','m','l'};
425 static char test7[] = {'<','?','y','m','l'};
426 static char test8[] = {'<','?'};
427 static char test9[] = {'<','!'};
428 static char test10[] = {0xff,0xfe,'<',0,'a',0,'/',0,'>',0};
429 static char test11[] = {'<',0,'a',0,'/',0,'>',0};
430 static char test12[] = {'<',0,'!',0,'-',0,'-',0};
431 static char test13[] = {'<',0,'?',0};
432 static char test14[] = {'a','b'};
433 static char test15[] = {'a','b','c'};
434 static char test16[] = {'a',0};
435 static char test17[] = {'a',0,'b',0};
436 static char test18[] = {'<',0,'a',0,'b',0};
437 static char test19[] = {'<',0,'a',0};
438 static char test20[] = {0,'a','b'};
439 static char test21[] = {0,0};
440 static char test22[] = {0,0,0};
441 static char test23[] = {'<',0,'?',0,'x',0,'m',0,'l',0};
442 HRESULT hr;
443 WS_XML_READER *reader;
444 WS_XML_READER_PROPERTY prop;
445 WS_XML_READER_TEXT_ENCODING enc;
446 WS_XML_READER_BUFFER_INPUT input;
447 WS_CHARSET charset;
448 const WS_XML_NODE *node;
449 ULONG i, size, max_depth;
450 static const struct
452 void *data;
453 ULONG size;
454 HRESULT hr;
455 WS_CHARSET charset;
456 int todo;
458 tests[] =
460 { test1, sizeof(test1), S_OK, WS_CHARSET_UTF8 },
461 { test2, sizeof(test2), S_OK, WS_CHARSET_UTF8 },
462 { test3, sizeof(test3), S_OK, WS_CHARSET_UTF8 },
463 { test4, sizeof(test4), S_OK, WS_CHARSET_UTF8 },
464 { test5, sizeof(test5), WS_E_INVALID_FORMAT, 0, 1 },
465 { test6, sizeof(test6), WS_E_INVALID_FORMAT, 0, 1 },
466 { test7, sizeof(test7), WS_E_INVALID_FORMAT, 0, 1 },
467 { test8, sizeof(test8), WS_E_INVALID_FORMAT, 0 },
468 { test9, sizeof(test9), WS_E_INVALID_FORMAT, 0 },
469 { test10, sizeof(test10), S_OK, WS_CHARSET_UTF16LE },
470 { test11, sizeof(test11), S_OK, WS_CHARSET_UTF16LE },
471 { test12, sizeof(test12), S_OK, WS_CHARSET_UTF16LE },
472 { test13, sizeof(test13), WS_E_INVALID_FORMAT, 0, 1 },
473 { test14, sizeof(test14), WS_E_INVALID_FORMAT, 0 },
474 { test15, sizeof(test15), S_OK, WS_CHARSET_UTF8 },
475 { test16, sizeof(test16), WS_E_INVALID_FORMAT, 0 },
476 { test17, sizeof(test17), S_OK, WS_CHARSET_UTF8 },
477 { test18, sizeof(test18), S_OK, WS_CHARSET_UTF16LE },
478 { test19, sizeof(test19), S_OK, WS_CHARSET_UTF16LE },
479 { test20, sizeof(test20), S_OK, WS_CHARSET_UTF8 },
480 { test21, sizeof(test21), WS_E_INVALID_FORMAT, 0 },
481 { test22, sizeof(test22), S_OK, WS_CHARSET_UTF8 },
482 { test23, sizeof(test23), WS_E_INVALID_FORMAT, 0, 1 },
485 hr = WsCreateReader( NULL, 0, &reader, NULL );
486 ok( hr == S_OK, "got %08x\n", hr );
488 hr = WsSetInput( NULL, NULL, NULL, NULL, 0, NULL );
489 ok( hr == E_INVALIDARG, "got %08x\n", hr );
491 node = NULL;
492 hr = WsGetReaderNode( reader, &node, NULL );
493 ok( hr == S_OK, "got %08x\n", hr );
494 ok( node != NULL, "node not set\n" );
495 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
497 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
498 enc.charSet = WS_CHARSET_UTF8;
500 input.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
501 input.encodedData = (void *)data1;
502 input.encodedDataSize = sizeof(data1) - 1;
504 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
505 ok( hr == S_OK, "got %08x\n", hr );
507 node = NULL;
508 hr = WsGetReaderNode( reader, &node, NULL );
509 ok( hr == S_OK, "got %08x\n", hr );
510 ok( node != NULL, "node not set\n" );
511 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
513 /* multiple calls are allowed */
514 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
515 ok( hr == S_OK, "got %08x\n", hr );
517 /* charset is detected by WsSetInput */
518 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
519 enc.charSet = WS_CHARSET_AUTO;
521 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
523 input.encodedData = tests[i].data;
524 input.encodedDataSize = tests[i].size;
525 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
526 ok( hr == S_OK, "%u: got %08x\n", i, hr );
528 charset = 0xdeadbeef;
529 size = sizeof(charset);
530 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
531 todo_wine_if (tests[i].todo)
533 ok( hr == tests[i].hr, "%u: got %08x expected %08x\n", i, hr, tests[i].hr );
534 if (hr == S_OK)
535 ok( charset == tests[i].charset, "%u: got %u expected %u\n", i, charset, tests[i].charset );
539 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
540 enc.charSet = WS_CHARSET_UTF8;
542 /* reader properties can be set with WsSetInput */
543 max_depth = 16;
544 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
545 prop.value = &max_depth;
546 prop.valueSize = sizeof(max_depth);
547 hr = WsSetInput( reader, &enc.encoding, &input.input, &prop, 1, NULL );
548 ok( hr == S_OK, "got %08x\n", hr );
550 max_depth = 0xdeadbeef;
551 size = sizeof(max_depth);
552 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
553 ok( hr == S_OK, "got %08x\n", hr );
554 ok( max_depth == 16, "got %u\n", max_depth );
555 WsFreeReader( reader );
558 static void test_WsSetInputToBuffer(void)
560 HRESULT hr;
561 WS_HEAP *heap;
562 WS_XML_BUFFER *buffer;
563 WS_XML_READER *reader;
564 WS_XML_READER_PROPERTY prop;
565 const WS_XML_NODE *node;
566 ULONG size, max_depth;
568 hr = WsCreateReader( NULL, 0, &reader, NULL );
569 ok( hr == S_OK, "got %08x\n", hr );
571 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
572 ok( hr == S_OK, "got %08x\n", hr );
574 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
575 ok( hr == S_OK, "got %08x\n", hr );
577 hr = WsSetInputToBuffer( NULL, NULL, NULL, 0, NULL );
578 ok( hr == E_INVALIDARG, "got %08x\n", hr );
580 hr = WsSetInputToBuffer( reader, NULL, NULL, 0, NULL );
581 ok( hr == E_INVALIDARG, "got %08x\n", hr );
583 node = NULL;
584 hr = WsGetReaderNode( reader, &node, NULL );
585 ok( hr == S_OK, "got %08x\n", hr );
586 ok( node != NULL, "node not set\n" );
587 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
589 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
590 ok( hr == S_OK, "got %08x\n", hr );
592 node = NULL;
593 hr = WsGetReaderNode( reader, &node, NULL );
594 ok( hr == S_OK, "got %08x\n", hr );
595 ok( node != NULL, "node not set\n" );
596 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
598 /* multiple calls are allowed */
599 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
600 ok( hr == S_OK, "got %08x\n", hr );
602 /* reader properties can be set with WsSetInputToBuffer */
603 max_depth = 16;
604 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
605 prop.value = &max_depth;
606 prop.valueSize = sizeof(max_depth);
607 hr = WsSetInputToBuffer( reader, buffer, &prop, 1, NULL );
608 ok( hr == S_OK, "got %08x\n", hr );
610 max_depth = 0xdeadbeef;
611 size = sizeof(max_depth);
612 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
613 ok( hr == S_OK, "got %08x\n", hr );
614 ok( max_depth == 16, "got %u\n", max_depth );
616 WsFreeReader( reader );
617 WsFreeHeap( heap );
620 static void test_WsFillReader(void)
622 HRESULT hr;
623 WS_XML_READER *reader;
624 const WS_XML_NODE *node;
626 /* what happens of we don't call WsFillReader? */
627 hr = WsCreateReader( NULL, 0, &reader, NULL );
628 ok( hr == S_OK, "got %08x\n", hr );
630 node = NULL;
631 hr = WsGetReaderNode( reader, &node, NULL );
632 ok( hr == S_OK, "got %08x\n", hr );
633 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
635 hr = set_input( reader, data1, sizeof(data1) - 1 );
636 ok( hr == S_OK, "got %08x\n", hr );
638 node = NULL;
639 hr = WsGetReaderNode( reader, &node, NULL );
640 ok( hr == S_OK, "got %08x\n", hr );
641 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
643 hr = WsReadNode( reader, NULL );
644 ok( hr == S_OK, "got %08x\n", hr );
646 node = NULL;
647 hr = WsGetReaderNode( reader, &node, NULL );
648 ok( hr == S_OK, "got %08x\n", hr );
649 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
650 WsFreeReader( reader );
652 hr = WsCreateReader( NULL, 0, &reader, NULL );
653 ok( hr == S_OK, "got %08x\n", hr );
655 hr = set_input( reader, data1, sizeof(data1) - 1 );
656 ok( hr == S_OK, "got %08x\n", hr );
658 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
659 ok( hr == S_OK, "got %08x\n", hr );
661 hr = set_input( reader, data1, sizeof(data1) - 1 );
662 ok( hr == S_OK, "got %08x\n", hr );
664 node = NULL;
665 hr = WsGetReaderNode( reader, &node, NULL );
666 ok( hr == S_OK, "got %08x\n", hr );
667 ok( node != NULL, "node not set\n" );
668 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
670 hr = WsFillReader( NULL, sizeof(data1) - 1, NULL, NULL );
671 ok( hr == E_INVALIDARG, "got %08x\n", hr );
673 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
674 ok( hr == S_OK, "got %08x\n", hr );
676 node = NULL;
677 hr = WsGetReaderNode( reader, &node, NULL );
678 ok( hr == S_OK, "got %08x\n", hr );
679 ok( node != NULL, "node not set\n" );
680 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
682 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
683 ok( hr == S_OK, "got %08x\n", hr );
685 /* min_size larger than input size */
686 hr = WsFillReader( reader, sizeof(data1), NULL, NULL );
687 ok( hr == S_OK, "got %08x\n", hr );
688 WsFreeReader( reader );
691 static void test_WsReadToStartElement(void)
693 HRESULT hr;
694 WS_XML_READER *reader;
695 const WS_XML_NODE *node, *node2;
696 int found;
698 hr = WsCreateReader( NULL, 0, &reader, NULL );
699 ok( hr == S_OK, "got %08x\n", hr );
701 hr = set_input( reader, data1, sizeof(data1) - 1 );
702 ok( hr == S_OK, "got %08x\n", hr );
704 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
705 ok( hr == S_OK, "got %08x\n", hr );
707 hr = WsGetReaderNode( reader, &node, NULL );
708 ok( hr == S_OK, "got %08x\n", hr );
709 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
711 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
712 ok( hr == S_OK, "got %08x\n", hr );
714 hr = WsReadToStartElement( NULL, NULL, NULL, NULL, NULL );
715 ok( hr == E_INVALIDARG, "got %08x\n", hr );
717 found = -1;
718 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
719 ok( hr == S_OK, "got %08x\n", hr );
720 ok( found == FALSE, "got %d\n", found );
722 hr = WsGetReaderNode( reader, &node, NULL );
723 ok( hr == S_OK, "got %08x\n", hr );
724 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
726 hr = set_input( reader, data2, sizeof(data2) - 1 );
727 ok( hr == S_OK, "got %08x\n", hr );
729 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
730 ok( hr == S_OK, "got %08x\n", hr );
732 hr = WsGetReaderNode( reader, &node, NULL );
733 ok( hr == S_OK, "got %08x\n", hr );
734 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
736 found = -1;
737 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
738 ok( hr == S_OK, "got %08x\n", hr );
739 ok( found == TRUE, "got %d\n", found );
741 hr = WsGetReaderNode( reader, &node, NULL );
742 ok( hr == S_OK, "got %08x\n", hr );
743 if (node)
745 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
747 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
748 ok( elem->prefix != NULL, "prefix not set\n" );
749 if (elem->prefix)
751 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
753 ok( elem->localName != NULL, "localName not set\n" );
754 if (elem->localName)
756 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
757 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
759 ok( elem->ns != NULL, "ns not set\n" );
760 if (elem->ns)
762 ok( !elem->ns->length, "got %u\n", elem->ns->length );
764 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
765 ok( elem->attributes == NULL, "attributes set\n" );
766 ok( !elem->isEmpty, "isEmpty not zero\n" );
769 found = -1;
770 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
771 ok( hr == S_OK, "got %08x\n", hr );
772 ok( found == TRUE, "got %d\n", found );
774 node2 = NULL;
775 hr = WsGetReaderNode( reader, &node2, NULL );
776 ok( hr == S_OK, "got %08x\n", hr );
777 ok( node2 == node, "different node\n" );
779 hr = set_input( reader, data3, sizeof(data3) - 1 );
780 ok( hr == S_OK, "got %08x\n", hr );
782 hr = WsFillReader( reader, sizeof(data3) - 1, NULL, NULL );
783 ok( hr == S_OK, "got %08x\n", hr );
785 found = -1;
786 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
787 ok( hr == S_OK, "got %08x\n", hr );
788 ok( found == TRUE, "got %d\n", found );
790 hr = WsGetReaderNode( reader, &node, NULL );
791 ok( hr == S_OK, "got %08x\n", hr );
792 if (node)
794 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
796 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
797 ok( elem->localName != NULL, "localName not set\n" );
798 if (elem->localName)
800 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
801 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
805 hr = set_input( reader, data4, sizeof(data4) - 1 );
806 ok( hr == S_OK, "got %08x\n", hr );
808 hr = WsFillReader( reader, sizeof(data4) - 1, NULL, NULL );
809 ok( hr == S_OK, "got %08x\n", hr );
811 found = -1;
812 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
813 ok( hr == S_OK, "got %08x\n", hr );
814 ok( found == TRUE, "got %d\n", found );
815 WsFreeReader( reader );
818 static void test_WsReadStartElement(void)
820 HRESULT hr;
821 WS_XML_READER *reader;
822 const WS_XML_NODE *node, *node2;
823 int found;
825 hr = WsCreateReader( NULL, 0, &reader, NULL );
826 ok( hr == S_OK, "got %08x\n", hr );
828 hr = set_input( reader, data2, sizeof(data2) - 1 );
829 ok( hr == S_OK, "got %08x\n", hr );
831 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
832 ok( hr == S_OK, "got %08x\n", hr );
834 found = -1;
835 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
836 ok( hr == S_OK, "got %08x\n", hr );
837 ok( found == TRUE, "got %d\n", found );
839 hr = WsReadStartElement( NULL, NULL );
840 ok( hr == E_INVALIDARG, "got %08x\n", hr );
842 hr = WsGetReaderNode( reader, &node, NULL );
843 ok( hr == S_OK, "got %08x\n", hr );
844 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
846 hr = WsReadStartElement( reader, NULL );
847 ok( hr == S_OK, "got %08x\n", hr );
849 hr = WsGetReaderNode( reader, &node, NULL );
850 ok( hr == S_OK, "got %08x\n", hr );
851 if (node)
853 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
854 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
855 ok( text->text != NULL, "text not set\n" );
856 if (text->text)
858 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
859 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
860 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
861 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong data\n" );
865 hr = WsReadStartElement( reader, NULL );
866 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
868 node2 = NULL;
869 hr = WsGetReaderNode( reader, &node2, NULL );
870 ok( hr == S_OK, "got %08x\n", hr );
871 ok( node2 == node, "different node\n" );
873 hr = set_input( reader, data8, sizeof(data8) - 1 );
874 ok( hr == S_OK, "got %08x\n", hr );
876 hr = WsFillReader( reader, sizeof(data8) - 1, NULL, NULL );
877 ok( hr == S_OK, "got %08x\n", hr );
879 found = -1;
880 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
881 ok( hr == S_OK, "got %08x\n", hr );
882 ok( found == TRUE, "got %d\n", found );
884 hr = WsGetReaderNode( reader, &node, NULL );
885 ok( hr == S_OK, "got %08x\n", hr );
886 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
888 hr = WsGetReaderNode( reader, &node, NULL );
889 ok( hr == S_OK, "got %08x\n", hr );
890 if (node)
892 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
893 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
894 ok( !memcmp( elem->localName->bytes, "node1", 5), "wrong name\n" );
897 hr = WsReadStartElement( reader, NULL );
898 ok( hr == S_OK, "got %08x\n", hr );
900 hr = WsGetReaderNode( reader, &node, NULL );
901 ok( hr == S_OK, "got %08x\n", hr );
902 if (node)
904 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
905 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
906 ok( !memcmp( elem->localName->bytes, "node2", 5), "wrong name\n" );
909 hr = WsReadNode( reader, NULL );
910 ok( hr == S_OK, "got %08x\n", hr );
912 hr = WsGetReaderNode( reader, &node, NULL );
913 ok( hr == S_OK, "got %08x\n", hr );
914 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
916 hr = WsReadNode( reader, NULL );
917 ok( hr == S_OK, "got %08x\n", hr );
919 hr = WsGetReaderNode( reader, &node, NULL );
920 ok( hr == S_OK, "got %08x\n", hr );
921 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
923 hr = WsReadEndElement( reader, NULL );
924 ok( hr == S_OK, "got %08x\n", hr );
926 hr = WsGetReaderNode( reader, &node, NULL );
927 ok( hr == S_OK, "got %08x\n", hr );
928 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
930 /* WsReadEndElement advances reader to EOF */
931 hr = WsReadEndElement( reader, NULL );
932 ok( hr == S_OK, "got %08x\n", hr );
934 hr = WsGetReaderNode( reader, &node, NULL );
935 ok( hr == S_OK, "got %08x\n", hr );
936 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
938 hr = WsReadEndElement( reader, NULL );
939 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
941 WsFreeReader( reader );
944 static void test_WsReadEndElement(void)
946 HRESULT hr;
947 WS_XML_READER *reader;
948 const WS_XML_NODE *node;
949 int found;
951 hr = WsCreateReader( NULL, 0, &reader, NULL );
952 ok( hr == S_OK, "got %08x\n", hr );
954 hr = set_input( reader, data2, sizeof(data2) - 1 );
955 ok( hr == S_OK, "got %08x\n", hr );
957 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
958 ok( hr == S_OK, "got %08x\n", hr );
960 hr = WsReadEndElement( reader, NULL );
961 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
963 hr = set_input( reader, data2, sizeof(data2) - 1 );
964 ok( hr == S_OK, "got %08x\n", hr );
966 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
967 ok( hr == S_OK, "got %08x\n", hr );
969 hr = WsReadNode( reader, NULL );
970 ok( hr == S_OK, "got %08x\n", hr );
972 hr = WsGetReaderNode( reader, &node, NULL );
973 ok( hr == S_OK, "got %08x\n", hr );
974 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
976 hr = WsReadNode( reader, NULL );
977 ok( hr == S_OK, "got %08x\n", hr );
979 hr = WsGetReaderNode( reader, &node, NULL );
980 ok( hr == S_OK, "got %08x\n", hr );
981 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
983 hr = WsReadNode( reader, NULL );
984 ok( hr == S_OK, "got %08x\n", hr );
986 hr = WsGetReaderNode( reader, &node, NULL );
987 ok( hr == S_OK, "got %08x\n", hr );
988 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
990 hr = WsReadNode( reader, NULL );
991 ok( hr == S_OK, "got %08x\n", hr );
993 hr = WsGetReaderNode( reader, &node, NULL );
994 ok( hr == S_OK, "got %08x\n", hr );
995 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
997 hr = set_input( reader, data2, sizeof(data2) - 1 );
998 ok( hr == S_OK, "got %08x\n", hr );
1000 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
1001 ok( hr == S_OK, "got %08x\n", hr );
1003 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1004 ok( hr == S_OK, "got %08x\n", hr );
1006 hr = WsReadStartElement( reader, NULL );
1007 ok( hr == S_OK, "got %08x\n", hr );
1009 hr = WsGetReaderNode( reader, &node, NULL );
1010 ok( hr == S_OK, "got %08x\n", hr );
1011 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
1013 hr = WsReadNode( reader, NULL );
1014 ok( hr == S_OK, "got %08x\n", hr );
1016 hr = WsGetReaderNode( reader, &node, NULL );
1017 ok( hr == S_OK, "got %08x\n", hr );
1018 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1020 /* WsReadEndElement advances reader to EOF */
1021 hr = WsReadEndElement( reader, NULL );
1022 ok( hr == S_OK, "got %08x\n", hr );
1024 hr = WsGetReaderNode( reader, &node, NULL );
1025 ok( hr == S_OK, "got %08x\n", hr );
1026 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1028 hr = WsReadEndElement( reader, NULL );
1029 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1031 hr = set_input( reader, data5, sizeof(data5) - 1 );
1032 ok( hr == S_OK, "got %08x\n", hr );
1034 hr = WsFillReader( reader, sizeof(data5) - 1, NULL, NULL );
1035 ok( hr == S_OK, "got %08x\n", hr );
1037 hr = WsReadEndElement( reader, NULL );
1038 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1040 hr = set_input( reader, data10, sizeof(data10) - 1 );
1041 ok( hr == S_OK, "got %08x\n", hr );
1043 hr = WsFillReader( reader, sizeof(data10) - 1, NULL, NULL );
1044 ok( hr == S_OK, "got %08x\n", hr );
1046 hr = WsReadNode( reader, NULL );
1047 ok( hr == S_OK, "got %08x\n", hr );
1049 hr = WsGetReaderNode( reader, &node, NULL );
1050 ok( hr == S_OK, "got %08x\n", hr );
1051 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1053 hr = WsReadEndElement( reader, NULL );
1054 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1056 hr = set_input( reader, "<a></A>", sizeof("<a></A>") - 1 );
1057 ok( hr == S_OK, "got %08x\n", hr );
1059 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1060 ok( hr == S_OK, "got %08x\n", hr );
1062 found = -1;
1063 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1064 ok( hr == S_OK, "got %08x\n", hr );
1065 ok( found == TRUE, "got %d\n", found );
1067 hr = WsGetReaderNode( reader, &node, NULL );
1068 ok( hr == S_OK, "got %08x\n", hr );
1069 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1071 hr = WsReadEndElement( reader, NULL );
1072 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1074 hr = set_input( reader, "<a></a>", sizeof("<a></a>") - 1 );
1075 ok( hr == S_OK, "got %08x\n", hr );
1077 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1078 ok( hr == S_OK, "got %08x\n", hr );
1080 found = -1;
1081 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1082 ok( hr == S_OK, "got %08x\n", hr );
1083 ok( found == TRUE, "got %d\n", found );
1085 hr = WsGetReaderNode( reader, &node, NULL );
1086 ok( hr == S_OK, "got %08x\n", hr );
1087 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1089 hr = WsReadStartElement( reader, NULL );
1090 ok( hr == S_OK, "got %08x\n", hr );
1092 hr = WsGetReaderNode( reader, &node, NULL );
1093 ok( hr == S_OK, "got %08x\n", hr );
1094 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1096 hr = WsReadEndElement( reader, NULL );
1097 ok( hr == S_OK, "got %08x\n", hr );
1099 hr = WsGetReaderNode( reader, &node, NULL );
1100 ok( hr == S_OK, "got %08x\n", hr );
1101 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1103 hr = set_input( reader, "<a/>", sizeof("<a/>") - 1 );
1104 ok( hr == S_OK, "got %08x\n", hr );
1106 hr = WsFillReader( reader, sizeof("<a/>") - 1, NULL, NULL );
1107 ok( hr == S_OK, "got %08x\n", hr );
1109 found = -1;
1110 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1111 ok( hr == S_OK, "got %08x\n", hr );
1112 ok( found == TRUE, "got %d\n", found );
1114 hr = WsGetReaderNode( reader, &node, NULL );
1115 ok( hr == S_OK, "got %08x\n", hr );
1116 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1118 hr = WsReadStartElement( reader, NULL );
1119 ok( hr == S_OK, "got %08x\n", hr );
1121 hr = WsGetReaderNode( reader, &node, NULL );
1122 ok( hr == S_OK, "got %08x\n", hr );
1123 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1125 hr = WsReadEndElement( reader, NULL );
1126 ok( hr == S_OK, "got %08x\n", hr );
1128 WsFreeReader( reader );
1131 static void test_WsReadNode(void)
1133 static const char str1[] = "<a>";
1134 static const char str2[] = "< a>";
1135 static const char str3[] = "<a >";
1136 static const char str4[] = "<<a>>";
1137 static const char str5[] = "<>";
1138 static const char str6[] = "</a>";
1139 static const char str7[] = " <a>";
1140 static const char str8[] = "<?xml>";
1141 static const char str9[] = "<?xml?>";
1142 static const char str10[] = "<?xml ?>";
1143 static const char str11[] = "<?xml version=\"1.0\"?>";
1144 static const char str12[] = "<text>test</text>";
1145 static const char str13[] = "<?xml version=\"1.0\"?><text>test</text>";
1146 static const char str14[] = "";
1147 static const char str15[] = "<!--";
1148 static const char str16[] = "<!---->";
1149 static const char str17[] = "<!--comment-->";
1150 HRESULT hr;
1151 WS_XML_READER *reader;
1152 const WS_XML_NODE *node;
1153 unsigned int i;
1154 int found;
1155 static const struct
1157 const char *text;
1158 HRESULT hr;
1159 WS_XML_NODE_TYPE type;
1160 int todo;
1162 tests[] =
1164 { str1, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1165 { str2, WS_E_INVALID_FORMAT, 0 },
1166 { str3, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1167 { str4, WS_E_INVALID_FORMAT, 0 },
1168 { str5, WS_E_INVALID_FORMAT, 0 },
1169 { str6, WS_E_INVALID_FORMAT, 0 },
1170 { str7, S_OK, WS_XML_NODE_TYPE_TEXT },
1171 { str8, WS_E_INVALID_FORMAT, 0 },
1172 { str9, WS_E_INVALID_FORMAT, 0 },
1173 { str10, WS_E_INVALID_FORMAT, 0, 1 },
1174 { str11, S_OK, WS_XML_NODE_TYPE_EOF },
1175 { str12, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1176 { str13, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1177 { str14, WS_E_INVALID_FORMAT, 0, 1 },
1178 { str15, WS_E_INVALID_FORMAT, 0 },
1179 { str16, S_OK, WS_XML_NODE_TYPE_COMMENT },
1180 { str17, S_OK, WS_XML_NODE_TYPE_COMMENT },
1183 hr = WsCreateReader( NULL, 0, &reader, NULL );
1184 ok( hr == S_OK, "got %08x\n", hr );
1186 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
1188 hr = set_input( reader, tests[i].text, strlen(tests[i].text) );
1189 ok( hr == S_OK, "got %08x\n", hr );
1191 hr = WsFillReader( reader, strlen(tests[i].text), NULL, NULL );
1192 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1194 hr = WsReadNode( reader, NULL );
1195 todo_wine_if (tests[i].todo)
1196 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
1197 if (hr == S_OK)
1199 node = NULL;
1200 hr = WsGetReaderNode( reader, &node, NULL );
1201 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1202 ok( node != NULL, "%u: node not set\n", i );
1203 if (node)
1205 todo_wine_if (tests[i].todo)
1206 ok( node->nodeType == tests[i].type, "%u: got %u\n", i, node->nodeType );
1211 hr = set_input( reader, data6, sizeof(data6) - 1 );
1212 ok( hr == S_OK, "got %08x\n", hr );
1214 hr = WsFillReader( reader, sizeof(data6) - 1, NULL, NULL );
1215 ok( hr == S_OK, "got %08x\n", hr );
1217 found = -1;
1218 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1219 ok( hr == S_OK, "got %08x\n", hr );
1220 ok( found == TRUE, "got %d\n", found );
1222 hr = WsGetReaderNode( reader, &node, NULL );
1223 ok( hr == S_OK, "got %08x\n", hr );
1224 if (node)
1226 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
1227 WS_XML_ATTRIBUTE *attr;
1228 WS_XML_UTF8_TEXT *text;
1230 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1231 ok( elem->prefix != NULL, "prefix not set\n" );
1232 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
1233 ok( elem->prefix->bytes == NULL, "bytes set\n" );
1234 ok( elem->localName != NULL, "localName not set\n" );
1235 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
1236 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
1237 ok( elem->ns != NULL, "ns not set\n" );
1238 ok( !elem->ns->length, "got %u\n", elem->ns->length );
1239 ok( elem->ns->bytes != NULL, "bytes not set\n" );
1240 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
1241 ok( elem->attributes != NULL, "attributes not set\n" );
1242 ok( !elem->isEmpty, "isEmpty not zero\n" );
1244 attr = elem->attributes[0];
1245 ok( !attr->singleQuote, "got %u\n", attr->singleQuote );
1246 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1247 ok( attr->prefix != NULL, "prefix not set\n" );
1248 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1249 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1250 ok( attr->localName != NULL, "localName not set\n" );
1251 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
1252 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
1253 ok( attr->ns != NULL, "ns not set\n" );
1254 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1255 ok( attr->ns->bytes == NULL, "bytes set\n" );
1256 ok( attr->value != NULL, "value not set\n" );
1258 text = (WS_XML_UTF8_TEXT *)attr->value;
1259 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1260 ok( text->value.length == 5, "got %u\n", text->value.length );
1261 ok( !memcmp( text->value.bytes, "value", 5 ), "wrong data\n" );
1263 attr = elem->attributes[1];
1264 ok( attr->singleQuote == 1, "got %u\n", attr->singleQuote );
1265 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1266 ok( attr->prefix != NULL, "prefix not set\n" );
1267 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1268 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1269 ok( attr->localName != NULL, "localName not set\n" );
1270 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
1271 ok( !memcmp( attr->localName->bytes, "attr2", 5 ), "wrong data\n" );
1272 ok( attr->ns != NULL, "ns not set\n" );
1273 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1274 ok( attr->ns->bytes == NULL, "bytes set\n" );
1275 ok( attr->value != NULL, "value not set\n" );
1277 text = (WS_XML_UTF8_TEXT *)attr->value;
1278 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1279 ok( text->value.length == 6, "got %u\n", text->value.length );
1280 ok( !memcmp( text->value.bytes, "value2", 6 ), "wrong data\n" );
1283 hr = set_input( reader, data7, sizeof(data7) - 1 );
1284 ok( hr == S_OK, "got %08x\n", hr );
1286 hr = WsFillReader( reader, sizeof(data7) - 1, NULL, NULL );
1287 ok( hr == S_OK, "got %08x\n", hr );
1289 hr = WsReadNode( reader, NULL );
1290 ok( hr == S_OK, "got %08x\n", hr );
1292 hr = WsGetReaderNode( reader, &node, NULL );
1293 ok( hr == S_OK, "got %08x\n", hr );
1294 if (node)
1296 WS_XML_COMMENT_NODE *comment = (WS_XML_COMMENT_NODE *)node;
1298 ok( comment->node.nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", comment->node.nodeType );
1299 ok( comment->value.length == 9, "got %u\n", comment->value.length );
1300 ok( !memcmp( comment->value.bytes, " comment ", 9 ), "wrong data\n" );
1303 WsFreeReader( reader );
1306 static void prepare_type_test( WS_XML_READER *reader, const char *data, ULONG size )
1308 HRESULT hr;
1310 hr = set_input( reader, data, size );
1311 ok( hr == S_OK, "got %08x\n", hr );
1313 hr = WsFillReader( reader, size, NULL, NULL );
1314 ok( hr == S_OK, "got %08x\n", hr );
1316 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1317 ok( hr == S_OK, "got %08x\n", hr );
1319 hr = WsReadStartElement( reader, NULL );
1320 ok( hr == S_OK, "got %08x\n", hr );
1323 static void test_WsReadType(void)
1325 static const WCHAR testW[] = {'t','e','s','t',0};
1326 static const GUID guid1 = {0,0,0,{0,0,0,0,0,0,0,0}};
1327 static const GUID guid2 = {0,0,0,{0,0,0,0,0,0,0,0xa1}};
1328 static const char utf8[] = {'<','t','>',0xe2,0x80,0x99,'<','/','t','>'};
1329 static const WCHAR utf8W[] = {0x2019,0};
1330 HRESULT hr;
1331 WS_XML_READER *reader;
1332 WS_HEAP *heap;
1333 enum { ONE = 1, TWO = 2 };
1334 WS_XML_STRING one = { 3, (BYTE *)"ONE" };
1335 WS_XML_STRING two = { 3, (BYTE *)"TWO" };
1336 WS_ENUM_VALUE enum_values[] = { { ONE, &one }, { TWO, &two } };
1337 WS_ENUM_DESCRIPTION enum_desc;
1338 int val_enum;
1339 WCHAR *val_str;
1340 BOOL val_bool;
1341 INT8 val_int8;
1342 INT16 val_int16;
1343 INT32 val_int32;
1344 INT64 val_int64;
1345 UINT8 val_uint8;
1346 UINT16 val_uint16;
1347 UINT32 val_uint32;
1348 UINT64 val_uint64;
1349 GUID val_guid;
1350 WS_BYTES val_bytes;
1352 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1353 ok( hr == S_OK, "got %08x\n", hr );
1355 hr = WsCreateReader( NULL, 0, &reader, NULL );
1356 ok( hr == S_OK, "got %08x\n", hr );
1358 prepare_type_test( reader, data2, sizeof(data2) - 1 );
1359 hr = WsReadType( NULL, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1360 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1361 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1363 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1364 WS_READ_REQUIRED_POINTER, heap, &val_str, 0, NULL );
1365 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1367 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1368 WS_READ_REQUIRED_POINTER, heap, NULL, sizeof(val_str), NULL );
1369 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1371 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1372 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str) + 1, NULL );
1373 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1375 val_str = NULL;
1376 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1377 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1378 ok( hr == S_OK, "got %08x\n", hr );
1379 ok( val_str != NULL, "pointer not set\n" );
1380 if (val_str) ok( !lstrcmpW( val_str, testW ), "wrong data\n" );
1382 val_bool = -1;
1383 prepare_type_test( reader, "<t>true</t>", sizeof("<t>true</t>") - 1 );
1384 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1385 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1386 ok( hr == S_OK, "got %08x\n", hr );
1387 ok( val_bool == TRUE, "got %d\n", val_bool );
1389 val_bool = -1;
1390 prepare_type_test( reader, "<t>false</t>", sizeof("<t>false</t>") - 1 );
1391 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1392 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1393 ok( hr == S_OK, "got %08x\n", hr );
1394 ok( val_bool == FALSE, "got %d\n", val_bool );
1396 val_bool = -1;
1397 prepare_type_test( reader, "<t>FALSE</t>", sizeof("<t>FALSE</t>") - 1 );
1398 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1399 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1400 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1401 ok( val_bool == -1, "got %d\n", val_bool );
1403 val_bool = -1;
1404 prepare_type_test( reader, "<t>1</t>", sizeof("<t>1</t>") - 1 );
1405 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1406 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1407 ok( hr == S_OK, "got %08x\n", hr );
1408 ok( val_bool == TRUE, "got %d\n", val_bool );
1410 val_bool = -1;
1411 prepare_type_test( reader, "<t>2</t>", sizeof("<t>2</t>") - 1 );
1412 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1413 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1414 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1415 ok( val_bool == -1, "got %d\n", val_bool );
1417 val_bool = -1;
1418 prepare_type_test( reader, "<t>0</t>", sizeof("<t>0</t>") - 1 );
1419 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1420 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1421 ok( hr == S_OK, "got %08x\n", hr );
1422 ok( val_bool == FALSE, "got %d\n", val_bool );
1424 val_int8 = 0;
1425 prepare_type_test( reader, "<t>-128</t>", sizeof("<t>-128</t>") - 1 );
1426 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1427 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1428 ok( hr == S_OK, "got %08x\n", hr );
1429 ok( val_int8 == -128, "got %d\n", val_int8 );
1431 val_int8 = 0;
1432 prepare_type_test( reader, "<t> </t>", sizeof("<t> </t>") - 1 );
1433 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1434 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1435 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1436 ok( !val_int8, "got %d\n", val_int8 );
1438 val_int8 = 0;
1439 prepare_type_test( reader, "<t>-</t>", sizeof("<t>-</t>") - 1 );
1440 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1441 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1442 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1443 ok( !val_int8, "got %d\n", val_int8 );
1445 val_int8 = -1;
1446 prepare_type_test( reader, "<t>-0</t>", sizeof("<t>-0</t>") - 1 );
1447 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1448 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1449 ok( hr == S_OK, "got %08x\n", hr );
1450 ok( !val_int8, "got %d\n", val_int8 );
1452 val_int8 = 0;
1453 prepare_type_test( reader, "<t>-129</t>", sizeof("<t>-129</t>") - 1 );
1454 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1455 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1456 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1457 ok( !val_int8, "got %d\n", val_int8 );
1459 val_int16 = 0;
1460 prepare_type_test( reader, "<t>-32768</t>", sizeof("<t>-32768</t>") - 1 );
1461 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1462 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1463 ok( hr == S_OK, "got %08x\n", hr );
1464 ok( val_int16 == -32768, "got %d\n", val_int16 );
1466 val_int16 = 0;
1467 prepare_type_test( reader, "<t>-32769</t>", sizeof("<t>-32769</t>") - 1 );
1468 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1469 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1470 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1471 ok( !val_int16, "got %d\n", val_int16 );
1473 val_int32 = 0;
1474 prepare_type_test( reader, "<t>-2147483648</t>", sizeof("<t>-2147483648</t>") - 1 );
1475 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1476 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1477 ok( hr == S_OK, "got %08x\n", hr );
1478 ok( val_int32 == -2147483647 - 1, "got %d\n", val_int32 );
1480 val_int32 = 0;
1481 prepare_type_test( reader, "<t>-2147483649</t>", sizeof("<t>-2147483649</t>") - 1 );
1482 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1483 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1484 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1485 ok( !val_int32, "got %d\n", val_int32 );
1487 val_int64 = 0;
1488 prepare_type_test( reader, "<t>-9223372036854775808</t>", sizeof("<t>-9223372036854775808</t>") - 1 );
1489 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1490 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1491 ok( hr == S_OK, "got %08x\n", hr );
1492 ok( val_int64 == -9223372036854775807 - 1, "wrong value\n" );
1494 val_int64 = 0;
1495 prepare_type_test( reader, "<t>-9223372036854775809</t>", sizeof("<t>-9223372036854775809</t>") - 1 );
1496 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1497 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1498 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1499 ok( !val_int64, "wrong value\n" );
1501 val_uint8 = 0;
1502 prepare_type_test( reader, "<t> 255 </t>", sizeof("<t> 255 </t>") - 1 );
1503 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1504 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1505 ok( hr == S_OK, "got %08x\n", hr );
1506 ok( val_uint8 == 255, "got %u\n", val_uint8 );
1508 val_uint8 = 0;
1509 prepare_type_test( reader, "<t>+255</t>", sizeof("<t>+255</t>") - 1 );
1510 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1511 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1512 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1513 ok( !val_uint8, "got %u\n", val_uint8 );
1515 val_uint8 = 0;
1516 prepare_type_test( reader, "<t>-255</t>", sizeof("<t>-255</t>") - 1 );
1517 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1518 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1519 todo_wine ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1520 ok( !val_uint8, "got %u\n", val_uint8 );
1522 val_uint8 = 0;
1523 prepare_type_test( reader, "<t>0xff</t>", sizeof("<t>0xff</t>") - 1 );
1524 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1525 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1526 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1527 ok( !val_uint8, "got %u\n", val_uint8 );
1529 val_uint8 = 0;
1530 prepare_type_test( reader, "<t>256</t>", sizeof("<t>256</t>") - 1 );
1531 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1532 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1533 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1534 ok( !val_uint8, "got %u\n", val_uint8 );
1536 val_uint16 = 0;
1537 prepare_type_test( reader, "<t>65535</t>", sizeof("<t>65535</t>") - 1 );
1538 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1539 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1540 ok( hr == S_OK, "got %08x\n", hr );
1541 ok( val_uint16 == 65535, "got %u\n", val_uint16 );
1543 val_uint16 = 0;
1544 prepare_type_test( reader, "<t>65536</t>", sizeof("<t>65536</t>") - 1 );
1545 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1546 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1547 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1548 ok( !val_uint16, "got %u\n", val_uint16 );
1550 val_uint32 = 0;
1551 prepare_type_test( reader, "<t>4294967295</t>", sizeof("<t>4294967295</t>") - 1 );
1552 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1553 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1554 ok( hr == S_OK, "got %08x\n", hr );
1555 ok( val_uint32 == ~0, "got %u\n", val_uint32 );
1557 val_uint32 = 0;
1558 prepare_type_test( reader, "<t>4294967296</t>", sizeof("<t>4294967296</t>") - 1 );
1559 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1560 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1561 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1562 ok( !val_uint32, "got %u\n", val_uint32 );
1564 val_uint64 = 0;
1565 prepare_type_test( reader, "<t>18446744073709551615</t>", sizeof("<t>18446744073709551615</t>") - 1 );
1566 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1567 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1568 ok( hr == S_OK, "got %08x\n", hr );
1569 ok( val_uint64 == ~0, "wrong value\n" );
1571 val_uint64 = 0;
1572 prepare_type_test( reader, "<t>18446744073709551616</t>", sizeof("<t>18446744073709551616</t>") - 1 );
1573 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1574 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1575 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1576 ok( !val_uint64, "wrong value\n" );
1578 enum_desc.values = enum_values;
1579 enum_desc.valueCount = sizeof(enum_values)/sizeof(enum_values[0]);
1580 enum_desc.maxByteCount = 3;
1581 enum_desc.nameIndices = NULL;
1583 val_enum = 0;
1584 prepare_type_test( reader, "<t>ONE</t>", sizeof("<t>ONE</t>") - 1 );
1585 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1586 WS_READ_REQUIRED_VALUE, heap, &val_enum, sizeof(val_enum), NULL );
1587 ok( hr == S_OK, "got %08x\n", hr );
1588 ok( val_enum == 1, "got %d\n", val_enum );
1590 prepare_type_test( reader, "<t>{00000000-0000-0000-0000-000000000000}</t>",
1591 sizeof("<t>{00000000-0000-0000-0000-000000000000}</t>") - 1 );
1592 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1593 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1594 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1596 memset( &val_guid, 0xff, sizeof(val_guid) );
1597 prepare_type_test( reader, "<t> 00000000-0000-0000-0000-000000000000 </t>",
1598 sizeof("<t> 00000000-0000-0000-0000-000000000000 </t>") - 1 );
1599 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1600 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1601 ok( hr == S_OK, "got %08x\n", hr );
1602 ok( IsEqualGUID( &val_guid, &guid1 ), "wrong guid\n" );
1604 memset( &val_guid, 0, sizeof(val_guid) );
1605 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000a1</t>",
1606 sizeof("<t>00000000-0000-0000-0000-0000000000a1</t>") - 1 );
1607 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1608 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1609 ok( hr == S_OK, "got %08x\n", hr );
1610 ok( IsEqualGUID( &val_guid, &guid2 ), "wrong guid\n" );
1612 memset( &val_guid, 0, sizeof(val_guid) );
1613 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000A1</t>",
1614 sizeof("<t>00000000-0000-0000-0000-0000000000A1</t>") - 1 );
1615 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1616 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1617 ok( hr == S_OK, "got %08x\n", hr );
1618 ok( IsEqualGUID( &val_guid, &guid2 ), "wrong guid\n" );
1620 memset( &val_bytes, 0, sizeof(val_bytes) );
1621 prepare_type_test( reader, "<t>dGVzdA==</t>", sizeof("<t>dGVzdA==</t>") - 1 );
1622 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1623 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1624 ok( hr == S_OK, "got %08x\n", hr );
1625 ok( val_bytes.length == 4, "got %u\n", val_bytes.length );
1626 ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" );
1628 memset( &val_bytes, 0, sizeof(val_bytes) );
1629 prepare_type_test( reader, "<t> dGVzdA== </t>", sizeof("<t> dGVzdA== </t>") - 1 );
1630 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1631 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1632 ok( hr == S_OK, "got %08x\n", hr );
1633 ok( val_bytes.length == 4, "got %u\n", val_bytes.length );
1634 ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" );
1636 prepare_type_test( reader, "<t>dGVzdA===</t>", sizeof("<t>dGVzdA===</t>") - 1 );
1637 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1638 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1639 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1641 val_str = NULL;
1642 prepare_type_test( reader, utf8, sizeof(utf8) );
1643 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1644 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1645 ok( hr == S_OK, "got %08x\n", hr );
1646 ok( val_str != NULL, "pointer not set\n" );
1647 if (val_str) ok( !lstrcmpW( val_str, utf8W ), "wrong data %s\n", wine_dbgstr_w(val_str) );
1649 WsFreeReader( reader );
1650 WsFreeHeap( heap );
1653 static void test_WsGetXmlAttribute(void)
1655 static const WCHAR valueW[] = {'v','a','l','u','e',0};
1656 HRESULT hr;
1657 WS_XML_READER *reader;
1658 WS_XML_STRING xmlstr;
1659 WS_HEAP *heap;
1660 WCHAR *str;
1661 ULONG count;
1662 int found;
1664 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1665 ok( hr == S_OK, "got %08x\n", hr );
1667 hr = WsCreateReader( NULL, 0, &reader, NULL );
1668 ok( hr == S_OK, "got %08x\n", hr );
1670 hr = set_input( reader, data9, sizeof(data9) - 1 );
1671 ok( hr == S_OK, "got %08x\n", hr );
1673 hr = WsFillReader( reader, sizeof(data9) - 1, NULL, NULL );
1674 ok( hr == S_OK, "got %08x\n", hr );
1676 found = -1;
1677 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1678 ok( hr == S_OK, "got %08x\n", hr );
1679 ok( found == TRUE, "got %d\n", found );
1681 xmlstr.bytes = (BYTE *)"attr";
1682 xmlstr.length = sizeof("attr") - 1;
1683 xmlstr.dictionary = NULL;
1684 xmlstr.id = 0;
1685 str = NULL;
1686 count = 0;
1687 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1688 todo_wine ok( hr == S_OK, "got %08x\n", hr );
1689 todo_wine ok( str != NULL, "str not set\n" );
1690 todo_wine ok( count == 5, "got %u\n", count );
1691 /* string is not null-terminated */
1692 if (str) ok( !memcmp( str, valueW, count * sizeof(WCHAR) ), "wrong data\n" );
1694 xmlstr.bytes = (BYTE *)"none";
1695 xmlstr.length = sizeof("none") - 1;
1696 xmlstr.dictionary = NULL;
1697 xmlstr.id = 0;
1698 str = (WCHAR *)0xdeadbeef;
1699 count = 0xdeadbeef;
1700 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1701 todo_wine ok( hr == S_FALSE, "got %08x\n", hr );
1702 todo_wine ok( str == NULL, "str not set\n" );
1703 todo_wine ok( !count, "got %u\n", count );
1705 WsFreeReader( reader );
1706 WsFreeHeap( heap );
1709 static void test_WsXmlStringEquals(void)
1711 BYTE bom[] = {0xef,0xbb,0xbf};
1712 WS_XML_STRING str1 = {0, NULL}, str2 = {0, NULL};
1713 HRESULT hr;
1715 hr = WsXmlStringEquals( NULL, NULL, NULL );
1716 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1718 hr = WsXmlStringEquals( &str1, NULL, NULL );
1719 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1721 hr = WsXmlStringEquals( NULL, &str2, NULL );
1722 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1724 hr = WsXmlStringEquals( &str1, &str2, NULL );
1725 ok( hr == S_OK, "got %08x\n", hr );
1727 str1.length = 1;
1728 str1.bytes = (BYTE *)"a";
1729 hr = WsXmlStringEquals( &str1, &str1, NULL );
1730 ok( hr == S_OK, "got %08x\n", hr );
1732 str2.length = 1;
1733 str2.bytes = (BYTE *)"b";
1734 hr = WsXmlStringEquals( &str1, &str2, NULL );
1735 ok( hr == S_FALSE, "got %08x\n", hr );
1737 str2.length = 1;
1738 str2.bytes = bom;
1739 hr = WsXmlStringEquals( &str1, &str2, NULL );
1740 ok( hr == S_FALSE, "got %08x\n", hr );
1742 str1.length = 3;
1743 hr = WsXmlStringEquals( &str1, &str2, NULL );
1744 ok( hr == S_FALSE, "got %08x\n", hr );
1746 str2.length = 3;
1747 hr = WsXmlStringEquals( &str1, &str2, NULL );
1748 ok( hr == S_FALSE, "got %08x\n", hr );
1750 str1.length = 3;
1751 str1.bytes = bom;
1752 hr = WsXmlStringEquals( &str1, &str2, NULL );
1753 ok( hr == S_OK, "got %08x\n", hr );
1756 static void test_WsAlloc(void)
1758 HRESULT hr;
1759 WS_HEAP *heap;
1760 void *ptr;
1761 SIZE_T requested, actual;
1762 ULONG size;
1764 hr = WsCreateHeap( 256, 0, NULL, 0, &heap, NULL );
1765 ok( hr == S_OK, "got %08x\n", hr );
1767 ptr = (void *)0xdeadbeef;
1768 hr = WsAlloc( NULL, 16, &ptr, NULL );
1769 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1770 ok( ptr == (void *)0xdeadbeef, "ptr set\n" );
1772 ptr = (void *)0xdeadbeef;
1773 hr = WsAlloc( heap, 512, &ptr, NULL );
1774 ok( hr == WS_E_QUOTA_EXCEEDED, "got %08x\n", hr );
1775 ok( ptr == (void *)0xdeadbeef, "ptr set\n" );
1777 ptr = NULL;
1778 hr = WsAlloc( heap, 16, &ptr, NULL );
1779 ok( hr == S_OK, "got %08x\n", hr );
1780 ok( ptr != NULL, "ptr not set\n" );
1782 requested = 0xdeadbeef;
1783 size = sizeof(requested);
1784 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
1785 ok( hr == S_OK, "got %08x\n", hr );
1786 ok( requested == 16, "got %u\n", (ULONG)requested );
1788 actual = 0xdeadbeef;
1789 size = sizeof(actual);
1790 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
1791 ok( hr == S_OK, "got %08x\n", hr );
1792 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
1794 WsFreeHeap( heap );
1797 static void test_WsMoveReader(void)
1799 HRESULT hr;
1800 WS_HEAP *heap;
1801 WS_XML_READER *reader;
1802 WS_XML_WRITER *writer;
1803 WS_XML_BUFFER *buffer;
1804 WS_XML_STRING localname = {1, (BYTE *)"a"}, localname2 = {1, (BYTE *)"b"}, ns = {0, NULL};
1805 const WS_XML_NODE *node;
1806 WS_XML_ELEMENT_NODE *elem;
1807 WS_XML_UTF8_TEXT utf8;
1809 hr = WsCreateReader( NULL, 0, &reader, NULL );
1810 ok( hr == S_OK, "got %08x\n", hr );
1812 hr = WsMoveReader( NULL, WS_MOVE_TO_EOF, NULL, NULL );
1813 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1815 /* reader must be set to an XML buffer */
1816 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1817 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1819 hr = set_input( reader, data8, sizeof(data8) - 1 );
1820 ok( hr == S_OK, "got %08x\n", hr );
1822 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1823 todo_wine ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1824 WsFreeReader( reader );
1826 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1827 ok( hr == S_OK, "got %08x\n", hr );
1829 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
1830 ok( hr == S_OK, "got %08x\n", hr );
1832 hr = WsCreateWriter( NULL, 0, &writer, NULL );
1833 ok( hr == S_OK, "got %08x\n", hr );
1835 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
1836 ok( hr == S_OK, "got %08x\n", hr );
1838 /* <a><b/></a> */
1839 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
1840 ok( hr == S_OK, "got %08x\n", hr );
1842 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
1843 ok( hr == S_OK, "got %08x\n", hr );
1845 hr = WsWriteEndElement( writer, NULL );
1846 ok( hr == S_OK, "got %08x\n", hr );
1848 hr = WsWriteEndElement( writer, NULL );
1849 ok( hr == S_OK, "got %08x\n", hr );
1851 hr = WsCreateReader( NULL, 0, &reader, NULL );
1852 ok( hr == S_OK, "got %08x\n", hr );
1854 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1855 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1857 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
1858 ok( hr == S_OK, "got %08x\n", hr );
1860 /* first element is child node of BOF node */
1861 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
1862 ok( hr == S_OK, "got %08x\n", hr );
1864 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1865 ok( hr == S_OK, "got %08x\n", hr );
1867 hr = WsGetReaderNode( reader, &node, NULL );
1868 ok( hr == S_OK, "got %08x\n", hr );
1869 elem = (WS_XML_ELEMENT_NODE *)node;
1870 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1871 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1872 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1874 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1875 ok( hr == S_OK, "got %08x\n", hr );
1877 hr = WsGetReaderNode( reader, &node, NULL );
1878 ok( hr == S_OK, "got %08x\n", hr );
1879 elem = (WS_XML_ELEMENT_NODE *)node;
1880 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1881 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1882 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1884 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1885 ok( hr == S_OK, "got %08x\n", hr );
1887 hr = WsGetReaderNode( reader, &node, NULL );
1888 ok( hr == S_OK, "got %08x\n", hr );
1889 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1891 /* EOF node is last child of BOF node */
1892 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
1893 ok( hr == S_OK, "got %08x\n", hr );
1895 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1896 ok( hr == S_OK, "got %08x\n", hr );
1898 hr = WsGetReaderNode( reader, &node, NULL );
1899 ok( hr == S_OK, "got %08x\n", hr );
1900 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1902 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1903 ok( hr == S_OK, "got %08x\n", hr );
1905 hr = WsGetReaderNode( reader, &node, NULL );
1906 ok( hr == S_OK, "got %08x\n", hr );
1907 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1909 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
1910 ok( hr == S_OK, "got %08x\n", hr );
1912 hr = WsGetReaderNode( reader, &node, NULL );
1913 ok( hr == S_OK, "got %08x\n", hr );
1914 elem = (WS_XML_ELEMENT_NODE *)node;
1915 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1916 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1917 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1919 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_ELEMENT, NULL, NULL );
1920 ok( hr == S_OK, "got %08x\n", hr );
1922 hr = WsGetReaderNode( reader, &node, NULL );
1923 ok( hr == S_OK, "got %08x\n", hr );
1924 elem = (WS_XML_ELEMENT_NODE *)node;
1925 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1926 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1927 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1929 hr = WsMoveReader( reader, WS_MOVE_TO_END_ELEMENT, NULL, NULL );
1930 ok( hr == S_OK, "got %08x\n", hr );
1932 hr = WsGetReaderNode( reader, &node, NULL );
1933 ok( hr == S_OK, "got %08x\n", hr );
1934 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1936 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1937 ok( hr == S_OK, "got %08x\n", hr );
1939 hr = WsGetReaderNode( reader, &node, NULL );
1940 ok( hr == S_OK, "got %08x\n", hr );
1941 elem = (WS_XML_ELEMENT_NODE *)node;
1942 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1943 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1944 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1946 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1947 ok( hr == S_OK, "got %08x\n", hr );
1949 hr = WsGetReaderNode( reader, &node, NULL );
1950 ok( hr == S_OK, "got %08x\n", hr );
1951 elem = (WS_XML_ELEMENT_NODE *)node;
1952 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1953 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1954 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1956 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1957 ok( hr == S_OK, "got %08x\n", hr );
1959 hr = WsGetReaderNode( reader, &node, NULL );
1960 ok( hr == S_OK, "got %08x\n", hr );
1961 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
1963 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1964 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1966 WsFreeWriter( writer );
1967 WsFreeHeap( heap );
1969 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1970 ok( hr == S_OK, "got %08x\n", hr );
1972 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
1973 ok( hr == S_OK, "got %08x\n", hr );
1975 hr = WsCreateWriter( NULL, 0, &writer, NULL );
1976 ok( hr == S_OK, "got %08x\n", hr );
1978 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
1979 ok( hr == S_OK, "got %08x\n", hr );
1981 /* <a><b>test</b></a> */
1982 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
1983 ok( hr == S_OK, "got %08x\n", hr );
1985 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
1986 ok( hr == S_OK, "got %08x\n", hr );
1988 utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
1989 utf8.value.bytes = (BYTE *)"test";
1990 utf8.value.length = sizeof("test") - 1;
1991 hr = WsWriteText( writer, &utf8.text, NULL );
1992 ok( hr == S_OK, "got %08x\n", hr );
1994 hr = WsWriteEndElement( writer, NULL );
1995 ok( hr == S_OK, "got %08x\n", hr );
1997 hr = WsWriteEndElement( writer, NULL );
1998 ok( hr == S_OK, "got %08x\n", hr );
2000 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
2001 ok( hr == S_OK, "got %08x\n", hr );
2003 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2004 ok( hr == S_OK, "got %08x\n", hr );
2006 hr = WsGetReaderNode( reader, &node, NULL );
2007 ok( hr == S_OK, "got %08x\n", hr );
2008 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2010 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2011 ok( hr == S_OK, "got %08x\n", hr );
2013 hr = WsGetReaderNode( reader, &node, NULL );
2014 ok( hr == S_OK, "got %08x\n", hr );
2015 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2017 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2018 ok( hr == S_OK, "got %08x\n", hr );
2020 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2021 ok( hr == S_OK, "got %08x\n", hr );
2023 hr = WsGetReaderNode( reader, &node, NULL );
2024 ok( hr == S_OK, "got %08x\n", hr );
2025 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2027 hr = WsGetReaderNode( reader, &node, NULL );
2028 ok( hr == S_OK, "got %08x\n", hr );
2029 elem = (WS_XML_ELEMENT_NODE *)node;
2030 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2031 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2032 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2034 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2035 ok( hr == S_OK, "got %08x\n", hr );
2037 hr = WsGetReaderNode( reader, &node, NULL );
2038 ok( hr == S_OK, "got %08x\n", hr );
2039 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2041 WsFreeReader( reader );
2042 WsFreeWriter( writer );
2043 WsFreeHeap( heap );
2046 static void prepare_struct_type_test( WS_XML_READER *reader, const char *data )
2048 HRESULT hr;
2049 ULONG size = strlen( data );
2051 hr = set_input( reader, data, size );
2052 ok( hr == S_OK, "got %08x\n", hr );
2054 hr = WsFillReader( reader, size, NULL, NULL );
2055 ok( hr == S_OK, "got %08x\n", hr );
2058 static void test_simple_struct_type(void)
2060 static const WCHAR testW[] = {'t','e','s','t',0};
2061 HRESULT hr;
2062 WS_XML_READER *reader;
2063 WS_HEAP *heap;
2064 WS_STRUCT_DESCRIPTION s;
2065 WS_FIELD_DESCRIPTION f, *fields[1];
2066 WS_XML_STRING ns = {0, NULL}, localname = {3, (BYTE *)"str"};
2067 WS_XML_STRING localname2 = {4, (BYTE *)"test"};
2068 const WS_XML_NODE *node;
2069 const WS_XML_ELEMENT_NODE *elem;
2070 struct test { WCHAR *str; } *test;
2072 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2073 ok( hr == S_OK, "got %08x\n", hr );
2075 hr = WsCreateReader( NULL, 0, &reader, NULL );
2076 ok( hr == S_OK, "got %08x\n", hr );
2078 prepare_struct_type_test( reader, "<str>test</str>" );
2079 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL,
2080 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2081 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2083 hr = WsGetReaderNode( reader, &node, NULL );
2084 ok( hr == S_OK, "got %08x\n", hr );
2085 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
2087 /* element field mapping */
2088 memset( &f, 0, sizeof(f) );
2089 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2090 f.localName = &localname;
2091 f.ns = &ns;
2092 f.type = WS_WSZ_TYPE;
2093 fields[0] = &f;
2095 memset( &s, 0, sizeof(s) );
2096 s.size = sizeof(struct test);
2097 s.alignment = TYPE_ALIGNMENT(struct test);
2098 s.fields = fields;
2099 s.fieldCount = 1;
2100 s.typeLocalName = &localname2;
2101 s.typeNs = &ns;
2103 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2104 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2105 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2106 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2108 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2109 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2110 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2111 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2113 s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
2114 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2115 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2116 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2117 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2118 s.structOptions = 0;
2120 test = NULL;
2121 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str>" );
2122 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2123 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2124 ok( hr == S_OK, "got %08x\n", hr );
2125 ok( test != NULL, "test not set\n" );
2126 if (test)
2128 ok( test->str != NULL, "str not set\n" );
2129 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2132 hr = WsGetReaderNode( reader, &node, NULL );
2133 ok( hr == S_OK, "got %08x\n", hr );
2134 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2136 test = NULL;
2137 prepare_struct_type_test( reader, "<str>test</str>" );
2138 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2139 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2140 ok( hr == S_OK, "got %08x\n", hr );
2141 ok( test != NULL, "test not set\n" );
2142 if (test)
2144 ok( test->str != NULL, "str not set\n" );
2145 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2148 hr = WsGetReaderNode( reader, &node, NULL );
2149 ok( hr == S_OK, "got %08x\n", hr );
2150 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2152 test = NULL;
2153 prepare_struct_type_test( reader, "<str>test</str>" );
2154 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2155 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2156 ok( hr == S_OK, "got %08x\n", hr );
2157 ok( test != NULL, "test not set\n" );
2158 if (test)
2160 ok( test->str != NULL, "str not set\n" );
2161 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2164 hr = WsGetReaderNode( reader, &node, NULL );
2165 ok( hr == S_OK, "got %08x\n", hr );
2166 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2168 prepare_struct_type_test( reader, "<str>test</str>" );
2169 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2170 ok( hr == S_OK, "got %08x\n", hr );
2172 hr = WsGetReaderNode( reader, &node, NULL );
2173 ok( hr == S_OK, "got %08x\n", hr );
2174 elem = (const WS_XML_ELEMENT_NODE *)node;
2175 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2176 ok( elem->localName->length == 3, "got %u\n", elem->localName->length );
2177 ok( !memcmp( elem->localName->bytes, "str", 3 ), "wrong data\n" );
2179 test = NULL;
2180 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2181 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2182 ok( hr == S_OK, "got %08x\n", hr );
2183 ok( test != NULL, "test not set\n" );
2184 if (test)
2186 ok( test->str != NULL, "str not set\n" );
2187 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2190 hr = WsGetReaderNode( reader, &node, NULL );
2191 ok( hr == S_OK, "got %08x\n", hr );
2192 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2194 /* attribute field mapping */
2195 f.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2197 test = NULL;
2198 prepare_struct_type_test( reader, "<test str=\"test\"/>" );
2199 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2200 ok( hr == S_OK, "got %08x\n", hr );
2202 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2203 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2204 ok( hr == S_OK, "got %08x\n", hr );
2205 ok( test != NULL, "test not set\n" );
2206 if (test)
2208 ok( test->str != NULL, "str not set\n" );
2209 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data test %p test->str %p\n", test, test->str );
2212 hr = WsGetReaderNode( reader, &node, NULL );
2213 ok( hr == S_OK, "got %08x\n", hr );
2214 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2216 WsFreeReader( reader );
2217 WsFreeHeap( heap );
2220 static void test_cdata(void)
2222 static const char test[] = "<t><![CDATA[<data>]]></t>";
2223 HRESULT hr;
2224 WS_XML_READER *reader;
2225 const WS_XML_NODE *node;
2227 hr = WsCreateReader( NULL, 0, &reader, NULL );
2228 ok( hr == S_OK, "got %08x\n", hr );
2230 hr = set_input( reader, test, sizeof(test) - 1 );
2231 ok( hr == S_OK, "got %08x\n", hr );
2233 hr = WsFillReader( reader, sizeof(test) - 1, NULL, NULL );
2234 ok( hr == S_OK, "got %08x\n", hr );
2236 hr = WsReadNode( reader, NULL );
2237 ok( hr == S_OK, "got %08x\n", hr );
2239 hr = WsGetReaderNode( reader, &node, NULL );
2240 ok( hr == S_OK, "got %08x\n", hr );
2241 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2243 hr = WsReadNode( reader, NULL );
2244 ok( hr == S_OK, "got %08x\n", hr );
2246 hr = WsGetReaderNode( reader, &node, NULL );
2247 ok( hr == S_OK, "got %08x\n", hr );
2248 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_CDATA, "got %u\n", node->nodeType );
2250 hr = WsReadNode( reader, NULL );
2251 ok( hr == S_OK, "got %08x\n", hr );
2253 hr = WsGetReaderNode( reader, &node, NULL );
2254 ok( hr == S_OK, "got %08x\n", hr );
2255 if (node)
2257 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
2258 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
2259 ok( text->text != NULL, "text not set\n" );
2260 if (text->text)
2262 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
2263 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
2264 ok( utf8->value.length == 6, "got %u\n", utf8->value.length );
2265 ok( !memcmp( utf8->value.bytes, "<data>", 6 ), "wrong data\n" );
2269 hr = WsReadNode( reader, NULL );
2270 ok( hr == S_OK, "got %08x\n", hr );
2272 hr = WsGetReaderNode( reader, &node, NULL );
2273 ok( hr == S_OK, "got %08x\n", hr );
2274 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_CDATA, "got %u\n", node->nodeType );
2276 hr = WsReadNode( reader, NULL );
2277 ok( hr == S_OK, "got %08x\n", hr );
2279 hr = WsGetReaderNode( reader, &node, NULL );
2280 ok( hr == S_OK, "got %08x\n", hr );
2281 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2283 WsFreeReader( reader );
2286 static void test_WsFindAttribute(void)
2288 static const char test[] = "<t attr='value' attr2='value2'></t>";
2289 WS_XML_STRING ns = {0, NULL}, localname = {4, (BYTE *)"attr"};
2290 WS_XML_STRING localname2 = {5, (BYTE *)"attr2"}, localname3 = {5, (BYTE *)"attr3"};
2291 WS_XML_READER *reader;
2292 ULONG index;
2293 HRESULT hr;
2295 hr = WsCreateReader( NULL, 0, &reader, NULL );
2296 ok( hr == S_OK, "got %08x\n", hr );
2298 hr = set_input( reader, test, sizeof(test) - 1 );
2299 ok( hr == S_OK, "got %08x\n", hr );
2301 hr = WsReadNode( reader, NULL );
2302 ok( hr == S_OK, "got %08x\n", hr );
2304 hr = WsFindAttribute( reader, &localname, &ns, TRUE, NULL, NULL );
2305 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2307 hr = set_input( reader, test, sizeof(test) - 1 );
2308 ok( hr == S_OK, "got %08x\n", hr );
2310 hr = WsReadNode( reader, NULL );
2311 ok( hr == S_OK, "got %08x\n", hr );
2313 hr = WsFindAttribute( reader, &localname, NULL, TRUE, &index, NULL );
2314 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2316 hr = set_input( reader, test, sizeof(test) - 1 );
2317 ok( hr == S_OK, "got %08x\n", hr );
2319 hr = WsReadNode( reader, NULL );
2320 ok( hr == S_OK, "got %08x\n", hr );
2322 hr = WsFindAttribute( reader, NULL, &ns, TRUE, &index, NULL );
2323 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2325 hr = set_input( reader, test, sizeof(test) - 1 );
2326 ok( hr == S_OK, "got %08x\n", hr );
2328 hr = WsReadNode( reader, NULL );
2329 ok( hr == S_OK, "got %08x\n", hr );
2331 index = 0xdeadbeef;
2332 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2333 ok( hr == S_OK, "got %08x\n", hr );
2334 ok( !index, "got %u\n", index );
2336 index = 0xdeadbeef;
2337 hr = WsFindAttribute( reader, &localname2, &ns, TRUE, &index, NULL );
2338 ok( hr == S_OK, "got %08x\n", hr );
2339 ok( index == 1, "got %u\n", index );
2341 hr = WsReadNode( reader, NULL );
2342 ok( hr == S_OK, "got %08x\n", hr );
2344 index = 0xdeadbeef;
2345 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2346 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2347 ok( index == 0xdeadbeef, "got %u\n", index );
2349 hr = set_input( reader, test, sizeof(test) - 1 );
2350 ok( hr == S_OK, "got %08x\n", hr );
2352 hr = WsReadNode( reader, NULL );
2353 ok( hr == S_OK, "got %08x\n", hr );
2355 index = 0xdeadbeef;
2356 hr = WsFindAttribute( reader, &localname3, &ns, TRUE, &index, NULL );
2357 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2358 ok( index == 0xdeadbeef, "got %u\n", index );
2360 hr = set_input( reader, test, sizeof(test) - 1 );
2361 ok( hr == S_OK, "got %08x\n", hr );
2363 hr = WsReadNode( reader, NULL );
2364 ok( hr == S_OK, "got %08x\n", hr );
2366 index = 0xdeadbeef;
2367 hr = WsFindAttribute( reader, &localname3, &ns, FALSE, &index, NULL );
2368 ok( hr == S_FALSE, "got %08x\n", hr );
2369 ok( index == ~0u, "got %u\n", index );
2371 WsFreeReader( reader );
2374 static void prepare_namespace_test( WS_XML_READER *reader, const char *data )
2376 HRESULT hr;
2377 ULONG size = strlen( data );
2379 hr = set_input( reader, data, size );
2380 ok( hr == S_OK, "got %08x\n", hr );
2382 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2383 ok( hr == S_OK, "got %08x\n", hr );
2386 static void test_WsGetNamespaceFromPrefix(void)
2388 WS_XML_STRING prefix = {0, NULL};
2389 const WS_XML_STRING *ns;
2390 const WS_XML_NODE *node;
2391 WS_XML_READER *reader;
2392 HRESULT hr;
2394 hr = WsCreateReader( NULL, 0, &reader, NULL );
2395 ok( hr == S_OK, "got %08x\n", hr );
2397 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, NULL, NULL );
2398 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2400 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, &ns, NULL );
2401 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2403 hr = WsGetNamespaceFromPrefix( NULL, &prefix, FALSE, &ns, NULL );
2404 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2406 ns = (const WS_XML_STRING *)0xdeadbeef;
2407 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2408 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2409 ok( ns == (const WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2411 hr = set_input( reader, "<prefix:t xmlns:prefix2='ns'/>", sizeof("<prefix:t xmlns:prefix2='ns'/>") - 1 );
2412 ok( hr == S_OK, "got %08x\n", hr );
2413 hr = WsReadStartElement( reader, NULL );
2414 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2416 prepare_namespace_test( reader, "<t></t>" );
2417 ns = NULL;
2418 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2419 ok( hr == S_OK, "got %08x\n", hr );
2420 ok( ns != NULL, "ns not set\n" );
2421 if (ns) ok( !ns->length, "got %u\n", ns->length );
2423 prepare_namespace_test( reader, "<t xmls='ns'></t>" );
2424 ns = NULL;
2425 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2426 ok( hr == S_OK, "got %08x\n", hr );
2427 ok( ns != NULL, "ns not set\n" );
2428 if (ns) ok( !ns->length, "got %u\n", ns->length );
2430 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2431 ns = NULL;
2432 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2433 ok( hr == S_OK, "got %08x\n", hr );
2434 ok( ns != NULL, "ns not set\n" );
2435 if (ns) ok( !ns->length, "got %u\n", ns->length );
2437 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2438 prefix.bytes = (BYTE *)"prefix";
2439 prefix.length = 6;
2440 ns = NULL;
2441 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2442 ok( hr == S_OK, "got %08x\n", hr );
2443 ok( ns != NULL, "ns not set\n" );
2444 if (ns)
2446 ok( ns->length == 2, "got %u\n", ns->length );
2447 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2450 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2451 ns = NULL;
2452 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2453 ok( hr == S_OK, "got %08x\n", hr );
2454 ok( ns != NULL, "ns not set\n" );
2455 if (ns)
2457 ok( ns->length == 2, "got %u\n", ns->length );
2458 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2461 hr = set_input( reader, "<t xmlns:prefix='ns'></t>", sizeof("<t xmlns:prefix='ns'></t>") - 1 );
2462 ok( hr == S_OK, "got %08x\n", hr );
2463 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2464 ok( hr == S_OK, "got %08x\n", hr );
2465 hr = WsGetReaderNode( reader, &node, NULL );
2466 ok( hr == S_OK, "got %08x\n", hr );
2467 if (node)
2469 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2470 WS_XML_ATTRIBUTE *attr;
2471 WS_XML_UTF8_TEXT *text;
2473 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2474 ok( elem->prefix != NULL, "prefix not set\n" );
2475 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2476 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2477 ok( elem->ns != NULL, "ns not set\n" );
2478 ok( !elem->ns->length, "got %u\n", elem->ns->length );
2479 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2480 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2481 ok( elem->attributes != NULL, "attributes not set\n" );
2483 attr = elem->attributes[0];
2484 ok( attr->singleQuote, "singleQuote not set\n" );
2485 ok( attr->isXmlNs, "isXmlNs not set\n" );
2486 ok( attr->prefix != NULL, "prefix not set\n" );
2487 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2488 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2489 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2490 ok( attr->localName != NULL, "localName not set\n" );
2491 ok( attr->localName->length == 6, "got %u\n", attr->localName->length );
2492 ok( !memcmp( attr->localName->bytes, "prefix", 6 ), "wrong data\n" );
2493 ok( attr->ns != NULL, "ns not set\n" );
2494 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2495 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2496 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2497 ok( attr->value != NULL, "value not set\n" );
2499 text = (WS_XML_UTF8_TEXT *)attr->value;
2500 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
2501 ok( !text->value.length, "got %u\n", text->value.length );
2502 ok( text->value.bytes == NULL, "bytes set\n" );
2505 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2506 hr = WsReadStartElement( reader, NULL );
2507 ok( hr == S_OK, "got %08x\n", hr );
2508 hr = WsReadEndElement( reader, NULL );
2509 ok( hr == S_OK, "got %08x\n", hr );
2510 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2511 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2513 prepare_namespace_test( reader, "<t></t>" );
2514 ns = NULL;
2515 prefix.bytes = (BYTE *)"xml";
2516 prefix.length = 3;
2517 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2518 ok( hr == S_OK, "got %08x\n", hr );
2519 ok( ns != NULL, "ns not set\n" );
2520 if (ns)
2522 ok( ns->length == 36, "got %u\n", ns->length );
2523 ok( !memcmp( ns->bytes, "http://www.w3.org/XML/1998/namespace", 36 ), "wrong data\n" );
2526 prepare_namespace_test( reader, "<t></t>" );
2527 ns = NULL;
2528 prefix.bytes = (BYTE *)"xmlns";
2529 prefix.length = 5;
2530 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2531 ok( hr == S_OK, "got %08x\n", hr );
2532 ok( ns != NULL, "ns not set\n" );
2533 if (ns)
2535 ok( ns->length == 29, "got %u\n", ns->length );
2536 ok( !memcmp( ns->bytes, "http://www.w3.org/2000/xmlns/", 29 ), "wrong data\n" );
2539 prepare_namespace_test( reader, "<t></t>" );
2540 ns = (WS_XML_STRING *)0xdeadbeef;
2541 prefix.bytes = (BYTE *)"prefix2";
2542 prefix.length = 7;
2543 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2544 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2545 ok( ns == (WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2547 prepare_namespace_test( reader, "<t></t>" );
2548 ns = (WS_XML_STRING *)0xdeadbeef;
2549 prefix.bytes = (BYTE *)"prefix2";
2550 prefix.length = 7;
2551 hr = WsGetNamespaceFromPrefix( reader, &prefix, FALSE, &ns, NULL );
2552 ok( hr == S_FALSE, "got %08x\n", hr );
2553 ok( ns == NULL, "ns not set\n" );
2555 hr = set_input( reader, "<t prefix:attr='' xmlns:prefix='ns'></t>", sizeof("<t prefix:attr='' xmlns:prefix='ns'></t>") - 1 );
2556 ok( hr == S_OK, "got %08x\n", hr );
2557 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2558 ok( hr == S_OK, "got %08x\n", hr );
2559 hr = WsGetReaderNode( reader, &node, NULL );
2560 ok( hr == S_OK, "got %08x\n", hr );
2561 if (node)
2563 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2564 WS_XML_ATTRIBUTE *attr;
2566 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2567 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
2568 ok( elem->attributes != NULL, "attributes not set\n" );
2570 attr = elem->attributes[0];
2571 ok( attr->singleQuote, "singleQuote not set\n" );
2572 ok( !attr->isXmlNs, "isXmlNs is set\n" );
2573 ok( attr->prefix != NULL, "prefix not set\n" );
2574 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2575 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2576 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2577 ok( attr->localName != NULL, "localName not set\n" );
2578 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
2579 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
2580 ok( attr->ns != NULL, "ns not set\n" );
2581 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2582 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2583 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2586 hr = set_input( reader, "<t xmlns:p='ns'><u xmlns:p='ns2'/></t>", sizeof("<t xmlns:p='ns'><u xmlns:p='ns2'/></t>") - 1 );
2587 ok( hr == S_OK, "got %08x\n", hr );
2588 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2589 ok( hr == S_OK, "got %08x\n", hr );
2590 hr = WsReadStartElement( reader, NULL );
2591 ok( hr == S_OK, "got %08x\n", hr );
2593 hr = set_input( reader, "<t xmlns:p='ns'><p:u p:a=''/></t>", sizeof("<t xmlns:p='ns'><p:u p:a=''/></t>") - 1 );
2594 ok( hr == S_OK, "got %08x\n", hr );
2595 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2596 ok( hr == S_OK, "got %08x\n", hr );
2597 hr = WsReadStartElement( reader, NULL );
2598 ok( hr == S_OK, "got %08x\n", hr );
2599 hr = WsGetReaderNode( reader, &node, NULL );
2600 ok( hr == S_OK, "got %08x\n", hr );
2601 if (node)
2603 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2604 WS_XML_ATTRIBUTE *attr;
2606 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2607 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2608 ok( elem->attributes != NULL, "attributes not set\n" );
2610 attr = elem->attributes[0];
2611 ok( attr->prefix != NULL, "prefix not set\n" );
2612 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
2613 ok( attr->prefix->bytes != NULL, "bytes set\n" );
2614 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong data\n" );
2615 ok( attr->localName != NULL, "localName not set\n" );
2616 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
2617 ok( !memcmp( attr->localName->bytes, "a", 1 ), "wrong data\n" );
2618 ok( attr->ns != NULL, "ns not set\n" );
2619 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2620 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2621 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2624 hr = set_input( reader, "<t xmlns='ns'></t>", sizeof("<t xmlns='ns'></t>") - 1 );
2625 ok( hr == S_OK, "got %08x\n", hr );
2626 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2627 ok( hr == S_OK, "got %08x\n", hr );
2628 hr = WsGetReaderNode( reader, &node, NULL );
2629 ok( hr == S_OK, "got %08x\n", hr );
2630 if (node)
2632 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2633 WS_XML_ATTRIBUTE *attr;
2635 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2636 ok( elem->prefix != NULL, "prefix not set\n" );
2637 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2638 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2639 ok( elem->ns != NULL, "ns not set\n" );
2640 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
2641 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2642 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong data\n" );
2644 attr = elem->attributes[0];
2645 ok( attr->isXmlNs, "isXmlNs is not set\n" );
2646 ok( attr->prefix != NULL, "prefix not set\n" );
2647 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
2648 ok( attr->prefix->bytes == NULL, "bytes set\n" );
2649 ok( attr->localName != NULL, "localName not set\n" );
2650 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
2651 ok( !memcmp( attr->localName->bytes, "xmlns", 5 ), "wrong data\n" );
2652 ok( attr->ns != NULL, "ns not set\n" );
2653 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2654 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2655 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2658 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns2'></t>") - 1 );
2659 ok( hr == S_OK, "got %08x\n", hr );
2660 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2661 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2663 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns'></t>") - 1 );
2664 ok( hr == S_OK, "got %08x\n", hr );
2665 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2666 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2668 hr = set_input( reader, "<t xmlns:p='ns' xmlns:P='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:P='ns2'></t>") - 1 );
2669 ok( hr == S_OK, "got %08x\n", hr );
2670 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2671 ok( hr == S_OK, "got %08x\n", hr );
2673 WsFreeReader( reader );
2676 static void test_text_field_mapping(void)
2678 static const WCHAR testW[] = {'t','e','s','t',0};
2679 HRESULT hr;
2680 WS_XML_READER *reader;
2681 WS_HEAP *heap;
2682 WS_STRUCT_DESCRIPTION s;
2683 WS_FIELD_DESCRIPTION f, *fields[1];
2684 struct test
2686 WCHAR *str;
2687 } *test;
2689 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2690 ok( hr == S_OK, "got %08x\n", hr );
2692 hr = WsCreateReader( NULL, 0, &reader, NULL );
2693 ok( hr == S_OK, "got %08x\n", hr );
2695 prepare_struct_type_test( reader, "<a>test</a>" );
2697 memset( &f, 0, sizeof(f) );
2698 f.mapping = WS_TEXT_FIELD_MAPPING;
2699 f.type = WS_WSZ_TYPE;
2700 fields[0] = &f;
2702 memset( &s, 0, sizeof(s) );
2703 s.size = sizeof(struct test);
2704 s.alignment = TYPE_ALIGNMENT(struct test);
2705 s.fields = fields;
2706 s.fieldCount = 1;
2708 test = NULL;
2709 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2710 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2711 ok( hr == S_OK, "got %08x\n", hr );
2712 ok( test != NULL, "test not set\n" );
2713 ok( test->str != NULL, "str not set\n" );
2714 ok( !lstrcmpW( test->str, testW ), "got %s\n", wine_dbgstr_w(test->str) );
2716 WsFreeReader( reader );
2717 WsFreeHeap( heap );
2720 static void test_complex_struct_type(void)
2722 static const WCHAR timestampW[] =
2723 {'2','0','1','5','-','0','9','-','0','3','T','1','8',':','4','7',':','5','4',0};
2724 HRESULT hr;
2725 WS_ERROR *error;
2726 WS_ERROR_PROPERTY prop;
2727 WS_XML_READER *reader;
2728 WS_HEAP *heap;
2729 WS_STRUCT_DESCRIPTION s, s2;
2730 WS_FIELD_DESCRIPTION f, f2, *fields[1], *fields2[1];
2731 WS_XML_STRING str_officeconfig = {12, (BYTE *)"OfficeConfig"};
2732 WS_XML_STRING str_services = {8, (BYTE *)"services"};
2733 WS_XML_STRING str_generationtime = {14, (BYTE *)"GenerationTime"};
2734 WS_XML_STRING ns = {39, (BYTE *)"urn:schemas-microsoft-com:office:office"};
2735 LANGID langid = MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT );
2736 const WS_XML_NODE *node;
2737 const WS_XML_ELEMENT_NODE *elem;
2738 struct services
2740 WCHAR *generationtime;
2742 struct officeconfig
2744 struct services *services;
2745 } *test;
2747 prop.id = WS_ERROR_PROPERTY_LANGID;
2748 prop.value = &langid;
2749 prop.valueSize = sizeof(langid);
2750 hr = WsCreateError( &prop, 1, &error );
2751 ok( hr == S_OK, "got %08x\n", hr );
2753 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2754 ok( hr == S_OK, "got %08x\n", hr );
2756 hr = WsCreateReader( NULL, 0, &reader, NULL );
2757 ok( hr == S_OK, "got %08x\n", hr );
2759 /* element content type mapping */
2760 prepare_struct_type_test( reader, data11 );
2762 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2763 ok( hr == S_OK, "got %08x\n", hr );
2765 hr = WsGetReaderNode( reader, &node, NULL );
2766 ok( hr == S_OK, "got %08x\n", hr );
2767 elem = (const WS_XML_ELEMENT_NODE *)node;
2768 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2769 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
2770 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
2772 hr = WsReadStartElement( reader, NULL );
2773 ok( hr == S_OK, "got %08x\n", hr );
2775 hr = WsGetReaderNode( reader, &node, NULL );
2776 ok( hr == S_OK, "got %08x\n", hr );
2777 elem = (const WS_XML_ELEMENT_NODE *)node;
2778 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2779 ok( elem->localName->length == 8, "got %u\n", elem->localName->length );
2780 ok( !memcmp( elem->localName->bytes, "services", 8 ), "wrong data\n" );
2782 memset( &f2, 0, sizeof(f2) );
2783 f2.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2784 f2.localName = &str_generationtime;
2785 f2.ns = &ns;
2786 f2.type = WS_WSZ_TYPE;
2787 f2.options = WS_FIELD_OPTIONAL;
2788 fields2[0] = &f2;
2790 memset( &s2, 0, sizeof(s2) );
2791 s2.size = sizeof(*test->services);
2792 s2.alignment = TYPE_ALIGNMENT(struct services);
2793 s2.fields = fields2;
2794 s2.fieldCount = 1;
2795 s2.typeLocalName = &str_services;
2796 s2.typeNs = &ns;
2798 memset( &f, 0, sizeof(f) );
2799 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2800 f.localName = &str_services;
2801 f.ns = &ns;
2802 f.type = WS_STRUCT_TYPE;
2803 f.typeDescription = &s2;
2804 f.options = WS_FIELD_POINTER;
2805 fields[0] = &f;
2807 memset( &s, 0, sizeof(s) );
2808 s.size = sizeof(*test);
2809 s.alignment = TYPE_ALIGNMENT(struct officeconfig);
2810 s.fields = fields;
2811 s.fieldCount = 1;
2812 s.typeLocalName = &str_officeconfig;
2813 s.typeNs = &ns;
2815 test = NULL;
2816 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2817 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2818 ok( hr == S_OK, "got %08x\n", hr );
2819 ok( test != NULL, "test not set\n" );
2820 ok( !lstrcmpW( test->services->generationtime, timestampW ), "wrong data\n" );
2822 hr = WsGetReaderNode( reader, &node, NULL );
2823 ok( hr == S_OK, "got %08x\n", hr );
2824 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2826 hr = WsReadEndElement( reader, NULL );
2827 ok( hr == S_OK, "got %08x\n", hr );
2829 hr = WsGetReaderNode( reader, &node, NULL );
2830 ok( hr == S_OK, "got %08x\n", hr );
2831 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2833 hr = WsReadEndElement( reader, NULL );
2834 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2836 /* element type mapping */
2837 prepare_struct_type_test( reader, data11 );
2839 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2840 ok( hr == S_OK, "got %08x\n", hr );
2842 hr = WsGetReaderNode( reader, &node, NULL );
2843 ok( hr == S_OK, "got %08x\n", hr );
2844 elem = (const WS_XML_ELEMENT_NODE *)node;
2845 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2846 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
2847 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
2849 test = NULL;
2850 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2851 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2852 ok( hr == S_OK, "got %08x\n", hr );
2853 ok( test != NULL, "test not set\n" );
2854 if (test) ok( !lstrcmpW( test->services->generationtime, timestampW ), "wrong data\n" );
2856 hr = WsGetReaderNode( reader, &node, NULL );
2857 ok( hr == S_OK, "got %08x\n", hr );
2858 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2860 /* trailing content */
2861 prepare_struct_type_test( reader, data11b );
2862 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2863 ok( hr == S_OK, "got %08x\n", hr );
2865 s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
2866 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2867 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2868 ok( hr == S_OK, "got %08x\n", hr );
2870 hr = WsGetReaderNode( reader, &node, NULL );
2871 ok( hr == S_OK, "got %08x\n", hr );
2872 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2874 prepare_struct_type_test( reader, data11b );
2875 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2876 ok( hr == S_OK, "got %08x\n", hr );
2878 s.structOptions = 0;
2879 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2880 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2881 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2883 WsFreeReader( reader );
2884 WsFreeHeap( heap );
2885 WsFreeError( error );
2888 static void test_repeating_element(void)
2890 static const WCHAR oneW[] = {'1',0}, twoW[] = {'2',0};
2891 WS_XML_STRING str_name = {4, (BYTE *)"name"};
2892 WS_XML_STRING str_services = {8, (BYTE *)"services"};
2893 WS_XML_STRING str_service = {7, (BYTE *)"service"};
2894 WS_XML_STRING str_wrapper = {7, (BYTE *)"wrapper"};
2895 WS_XML_STRING str_id = {2, (BYTE *)"id"};
2896 WS_XML_STRING str_ns = {0, NULL};
2897 HRESULT hr;
2898 WS_XML_READER *reader;
2899 WS_HEAP *heap;
2900 WS_STRUCT_DESCRIPTION s, s2;
2901 WS_FIELD_DESCRIPTION f, f2, f3, *fields[1], *fields2[2];
2902 WS_ITEM_RANGE range;
2903 struct service { UINT32 id; };
2904 struct service2 { WCHAR *id; };
2905 struct service3 { WCHAR *name; WCHAR *id; };
2906 struct services
2908 struct service *service;
2909 ULONG service_count;
2910 } *test;
2911 struct services2
2913 struct service2 *service;
2914 ULONG service_count;
2915 } *test2;
2916 struct services3
2918 struct service3 *service;
2919 ULONG service_count;
2920 } *test3;
2921 struct services4
2923 struct service **service;
2924 ULONG service_count;
2925 } *test4;
2927 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2928 ok( hr == S_OK, "got %08x\n", hr );
2930 hr = WsCreateReader( NULL, 0, &reader, NULL );
2931 ok( hr == S_OK, "got %08x\n", hr );
2933 prepare_struct_type_test( reader, data12 );
2935 memset( &f2, 0, sizeof(f2) );
2936 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
2937 f2.localName = &str_id;
2938 f2.ns = &str_ns;
2939 f2.type = WS_UINT32_TYPE;
2940 fields2[0] = &f2;
2942 memset( &s2, 0, sizeof(s2) );
2943 s2.size = sizeof(struct service);
2944 s2.alignment = TYPE_ALIGNMENT(struct service);
2945 s2.fields = fields2;
2946 s2.fieldCount = 1;
2947 s2.typeLocalName = &str_service;
2949 memset( &f, 0, sizeof(f) );
2950 f.mapping = WS_REPEATING_ELEMENT_FIELD_MAPPING;
2951 f.countOffset = FIELD_OFFSET(struct services, service_count);
2952 f.type = WS_STRUCT_TYPE;
2953 f.typeDescription = &s2;
2954 f.itemLocalName = &str_service;
2955 f.itemNs = &str_ns;
2956 fields[0] = &f;
2958 memset( &s, 0, sizeof(s) );
2959 s.size = sizeof(struct services);
2960 s.alignment = TYPE_ALIGNMENT(struct services);
2961 s.fields = fields;
2962 s.fieldCount = 1;
2963 s.typeLocalName = &str_services;
2965 test = NULL;
2966 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2967 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2968 ok( hr == S_OK, "got %08x\n", hr );
2969 ok( test != NULL, "test not set\n" );
2970 ok( test->service != NULL, "service not set\n" );
2971 ok( test->service_count == 2, "got %u\n", test->service_count );
2972 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
2973 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
2975 /* array of pointers */
2976 prepare_struct_type_test( reader, data12 );
2977 f.options = WS_FIELD_POINTER;
2978 test4 = NULL;
2979 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2980 WS_READ_REQUIRED_POINTER, heap, &test4, sizeof(test4), NULL );
2981 ok( hr == S_OK || broken(hr == E_INVALIDARG) /* win7 */, "got %08x\n", hr );
2982 if (test4)
2984 ok( test4->service != NULL, "service not set\n" );
2985 ok( test4->service_count == 2, "got %u\n", test4->service_count );
2986 ok( test4->service[0]->id == 1, "got %u\n", test4->service[0]->id );
2987 ok( test4->service[1]->id == 2, "got %u\n", test4->service[1]->id );
2990 /* item range */
2991 prepare_struct_type_test( reader, data13 );
2992 f.options = 0;
2993 range.minItemCount = 0;
2994 range.maxItemCount = 1;
2995 f.itemRange = &range;
2996 test = NULL;
2997 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2998 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2999 ok( hr == S_OK, "got %08x\n", hr );
3000 ok( test != NULL, "test not set\n" );
3001 ok( test->service != NULL, "service not set\n" );
3002 ok( !test->service_count, "got %u\n", test->service_count );
3004 /* wrapper element */
3005 prepare_struct_type_test( reader, data14 );
3006 f.itemRange = NULL;
3007 f.localName = &str_wrapper;
3008 f.ns = &str_ns;
3009 test = NULL;
3010 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3011 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3012 ok( hr == S_OK, "got %08x\n", hr );
3013 ok( test != NULL, "test not set\n" );
3014 ok( test->service != NULL, "service not set\n" );
3015 ok( test->service_count == 2, "got %u\n", test->service_count );
3016 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
3017 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
3019 /* repeating text field mapping */
3020 prepare_struct_type_test( reader, data15 );
3021 f2.mapping = WS_TEXT_FIELD_MAPPING;
3022 f2.localName = NULL;
3023 f2.ns = NULL;
3024 f2.type = WS_WSZ_TYPE;
3025 s2.size = sizeof(struct service2);
3026 s2.alignment = TYPE_ALIGNMENT(struct service2);
3027 test2 = NULL;
3028 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3029 WS_READ_REQUIRED_POINTER, heap, &test2, sizeof(test2), NULL );
3030 ok( hr == S_OK, "got %08x\n", hr );
3031 ok( test2 != NULL, "test2 not set\n" );
3032 ok( test2->service != NULL, "service not set\n" );
3033 ok( test2->service_count == 2, "got %u\n", test2->service_count );
3034 ok( !lstrcmpW( test2->service[0].id, oneW ), "wrong data\n" );
3035 ok( !lstrcmpW( test2->service[1].id, twoW ), "wrong data\n" );
3037 /* repeating attribute field + text field mapping */
3038 prepare_struct_type_test( reader, data16 );
3039 f2.offset = FIELD_OFFSET(struct service3, id);
3040 memset( &f3, 0, sizeof(f3) );
3041 f3.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
3042 f3.localName = &str_name;
3043 f3.ns = &str_ns;
3044 f3.type = WS_WSZ_TYPE;
3045 fields2[0] = &f3;
3046 fields2[1] = &f2;
3047 s2.size = sizeof(struct service3);
3048 s2.alignment = TYPE_ALIGNMENT(struct service3);
3049 s2.fieldCount = 2;
3050 test3 = NULL;
3051 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3052 WS_READ_REQUIRED_POINTER, heap, &test3, sizeof(test3), NULL );
3053 ok( hr == S_OK, "got %08x\n", hr );
3054 ok( test3 != NULL, "test3 not set\n" );
3055 ok( test3->service != NULL, "service not set\n" );
3056 ok( test3->service_count == 2, "got %u\n", test3->service_count );
3057 ok( !lstrcmpW( test3->service[0].name, oneW ), "wrong data\n" );
3058 ok( !lstrcmpW( test3->service[0].id, oneW ), "wrong data\n" );
3059 ok( !lstrcmpW( test3->service[1].name, twoW ), "wrong data\n" );
3060 ok( !lstrcmpW( test3->service[1].id, twoW ), "wrong data\n" );
3062 WsFreeReader( reader );
3063 WsFreeHeap( heap );
3066 static void test_WsResetHeap(void)
3068 HRESULT hr;
3069 WS_HEAP *heap;
3070 SIZE_T requested, actual;
3071 ULONG size;
3072 void *ptr;
3074 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3075 ok( hr == S_OK, "got %08x\n", hr );
3077 requested = 0xdeadbeef;
3078 size = sizeof(requested);
3079 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3080 ok( hr == S_OK, "got %08x\n", hr );
3081 ok( !requested, "got %u\n", (ULONG)requested );
3083 actual = 0xdeadbeef;
3084 size = sizeof(actual);
3085 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3086 ok( hr == S_OK, "got %08x\n", hr );
3087 ok( !actual, "got %u\n", (ULONG)actual );
3089 hr = WsAlloc( heap, 128, &ptr, NULL );
3090 ok( hr == S_OK, "got %08x\n", hr );
3092 requested = 0xdeadbeef;
3093 size = sizeof(requested);
3094 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3095 ok( hr == S_OK, "got %08x\n", hr );
3096 ok( requested == 128, "got %u\n", (ULONG)requested );
3098 actual = 0xdeadbeef;
3099 size = sizeof(actual);
3100 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3101 ok( hr == S_OK, "got %08x\n", hr );
3102 ok( actual == 128, "got %u\n", (ULONG)actual );
3104 hr = WsAlloc( heap, 1, &ptr, NULL );
3105 ok( hr == S_OK, "got %08x\n", hr );
3107 requested = 0xdeadbeef;
3108 size = sizeof(requested);
3109 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3110 ok( hr == S_OK, "got %08x\n", hr );
3111 ok( requested == 129, "got %u\n", (ULONG)requested );
3113 actual = 0xdeadbeef;
3114 size = sizeof(actual);
3115 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3116 ok( hr == S_OK, "got %08x\n", hr );
3117 todo_wine ok( actual == 384, "got %u\n", (ULONG)actual );
3119 hr = WsResetHeap( NULL, NULL );
3120 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3122 hr = WsResetHeap( heap, NULL );
3123 ok( hr == S_OK, "got %08x\n", hr );
3125 requested = 0xdeadbeef;
3126 size = sizeof(requested);
3127 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3128 ok( hr == S_OK, "got %08x\n", hr );
3129 ok( !requested, "got %u\n", (ULONG)requested );
3131 actual = 0xdeadbeef;
3132 size = sizeof(actual);
3133 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3134 ok( hr == S_OK, "got %08x\n", hr );
3135 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
3137 WsFreeHeap( heap );
3140 static void test_datetime(void)
3142 static const struct
3144 const char *str;
3145 HRESULT hr;
3146 __int64 ticks;
3147 WS_DATETIME_FORMAT format;
3149 tests[] =
3151 {"<t>0000-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3152 {"<t>0001-01-01T00:00:00Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3153 {"<t>0001-01-01T00:00:00.Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3154 {"<t>0001-01-01T00:00:00.0Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3155 {"<t>0001-01-01T00:00:00.1Z</t>", S_OK, 0x0000f4240, WS_DATETIME_FORMAT_UTC},
3156 {"<t>0001-01-01T00:00:00.01Z</t>", S_OK, 0x0000186a0, WS_DATETIME_FORMAT_UTC},
3157 {"<t>0001-01-01T00:00:00.0000001Z</t>", S_OK, 1, WS_DATETIME_FORMAT_UTC},
3158 {"<t>0001-01-01T00:00:00.9999999Z</t>", S_OK, 0x00098967f, WS_DATETIME_FORMAT_UTC},
3159 {"<t>0001-01-01T00:00:00.0000000Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3160 {"<t>0001-01-01T00:00:00.00000001Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3161 {"<t>0001-01-01T00:00:00Z-</t>", WS_E_INVALID_FORMAT, 0},
3162 {"<t>-0001-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3163 {"<t>0001-00-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3164 {"<t>0001-13-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3165 {"<t>0001-12-01T00:00:00Z</t>", S_OK, 0x1067555f88000, WS_DATETIME_FORMAT_UTC},
3166 {"<t>0001-01-00T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3167 {"<t>2001-01-32T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3168 {"<t>2001-01-31T00:00:00Z</t>", S_OK, 0x8c2592fe3794000, WS_DATETIME_FORMAT_UTC},
3169 {"<t>1900-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3170 {"<t>2000-02-29T00:00:00Z</t>", S_OK, 0x8c1505f0e438000, 0},
3171 {"<t>2001-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3172 {"<t>2001-02-28T00:00:00Z</t>", S_OK, 0x8c26f30870a4000, WS_DATETIME_FORMAT_UTC},
3173 {"<t>0001-00-01U00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3174 {"<t>0001-01-01T24:00:00Z</t>", S_OK, 0xc92a69c000, WS_DATETIME_FORMAT_UTC},
3175 {"<t>0001-01-01T24:00:01Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3176 {"<t>0001-01-01T00:60:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3177 {"<t>0001-01-01T00:00:60Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3178 {"<t>0001-01-01T00:00:00Y</t>", WS_E_INVALID_FORMAT, 0, 0},
3179 {"<t>0001-01-01T00:00:00+00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3180 {"<t>0001-01-01T00:00:00-00:01</t>", S_OK, 0x023c34600, WS_DATETIME_FORMAT_LOCAL},
3181 {"<t>9999-12-31T24:00:00+00:01</t>", S_OK, 0x2bca2875d073fa00, WS_DATETIME_FORMAT_LOCAL},
3182 {"<t>9999-12-31T24:00:00-00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3183 {"<t>0002-01-01T00:00:00+14:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3184 {"<t>0002-01-01T00:00:00+15:00</t>", WS_E_INVALID_FORMAT, 0, 0},
3185 {"<t>0002-01-01T00:00:00+13:60</t>", WS_E_INVALID_FORMAT, 0, 0},
3186 {"<t>0002-01-01T00:00:00+13:59</t>", S_OK, 0x11e5c43cc5600, WS_DATETIME_FORMAT_LOCAL},
3187 {"<t>0002-01-01T00:00:00+01:00</t>", S_OK, 0x11ec917025800, WS_DATETIME_FORMAT_LOCAL},
3188 {"<t>2016-01-01T00:00:00-01:00</t>", S_OK, 0x8d31246dfbba800, WS_DATETIME_FORMAT_LOCAL},
3189 {"<t>2016-01-01T00:00:00Z</t>", S_OK, 0x8d3123e7df74000, WS_DATETIME_FORMAT_UTC},
3190 {"<t> 2016-01-02T03:04:05Z </t>", S_OK, 0x8d313215fb64080, WS_DATETIME_FORMAT_UTC},
3191 {"<t>+2016-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3192 {"<t></t>", WS_E_INVALID_FORMAT, 0, 0},
3193 {"<t>01-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3194 {"<t>1601-01-01T00:00:00Z</t>", S_OK, 0x701ce1722770000, WS_DATETIME_FORMAT_UTC},
3196 HRESULT hr;
3197 WS_XML_READER *reader;
3198 WS_HEAP *heap;
3199 WS_DATETIME date;
3200 ULONG i;
3202 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3203 ok( hr == S_OK, "got %08x\n", hr );
3205 hr = WsCreateReader( NULL, 0, &reader, NULL );
3206 ok( hr == S_OK, "got %08x\n", hr );
3207 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3209 memset( &date, 0, sizeof(date) );
3210 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3211 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DATETIME_TYPE, NULL,
3212 WS_READ_REQUIRED_VALUE, heap, &date, sizeof(date), NULL );
3213 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3214 if (hr == S_OK)
3216 ok( date.ticks == tests[i].ticks, "%u: got %x%08x\n", i, (ULONG)(date.ticks >> 32), (ULONG)date.ticks );
3217 ok( date.format == tests[i].format, "%u: got %u\n", i, date.format );
3221 WsFreeReader( reader );
3222 WsFreeHeap( heap );
3225 static void test_WsDateTimeToFileTime(void)
3227 static const struct
3229 WS_DATETIME dt;
3230 HRESULT hr;
3231 FILETIME ft;
3233 tests[] =
3235 { {0, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3236 { {0x701ce172276ffff, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3237 { {0x701ce1722770000, WS_DATETIME_FORMAT_UTC}, S_OK, {0, 0} },
3238 { {0x2bca2875f4373fff, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c03fff, 0x24c85a5e} },
3239 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c04000, 0x24c85a5e} },
3240 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_LOCAL}, S_OK, {0xd1c04000, 0x24c85a5e} },
3241 { {~0, WS_DATETIME_FORMAT_UTC}, S_OK, {0xdd88ffff, 0xf8fe31e8} },
3243 WS_DATETIME dt;
3244 FILETIME ft;
3245 HRESULT hr;
3246 ULONG i;
3248 hr = WsDateTimeToFileTime( NULL, NULL, NULL );
3249 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3251 dt.ticks = 0x701ce172277000;
3252 dt.format = WS_DATETIME_FORMAT_UTC;
3253 hr = WsDateTimeToFileTime( &dt, NULL, NULL );
3254 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3256 hr = WsDateTimeToFileTime( NULL, &ft, NULL );
3257 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3259 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3261 memset( &ft, 0, sizeof(ft) );
3262 hr = WsDateTimeToFileTime( &tests[i].dt, &ft, NULL );
3263 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3264 if (hr == S_OK)
3266 ok( ft.dwLowDateTime == tests[i].ft.dwLowDateTime, "%u: got %08x\n", i, ft.dwLowDateTime );
3267 ok( ft.dwHighDateTime == tests[i].ft.dwHighDateTime, "%u: got %08x\n", i, ft.dwHighDateTime );
3272 static void test_WsFileTimeToDateTime(void)
3274 WS_DATETIME dt;
3275 FILETIME ft;
3276 HRESULT hr;
3278 hr = WsFileTimeToDateTime( NULL, NULL, NULL );
3279 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3281 ft.dwLowDateTime = ft.dwHighDateTime = 0;
3282 hr = WsFileTimeToDateTime( &ft, NULL, NULL );
3283 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3285 hr = WsFileTimeToDateTime( NULL, &dt, NULL );
3286 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3288 dt.ticks = 0xdeadbeef;
3289 dt.format = 0xdeadbeef;
3290 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3291 ok( hr == S_OK, "got %08x\n", hr );
3292 ok( dt.ticks == 0x701ce1722770000, "got %x%08x\n", (ULONG)(dt.ticks >> 32), (ULONG)dt.ticks );
3293 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3295 ft.dwLowDateTime = 0xd1c03fff;
3296 ft.dwHighDateTime = 0x24c85a5e;
3297 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3298 ok( hr == S_OK, "got %08x\n", hr );
3299 ok( dt.ticks == 0x2bca2875f4373fff, "got %x%08x\n", (ULONG)(dt.ticks >> 32), (ULONG)dt.ticks );
3300 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3302 ft.dwLowDateTime++;
3303 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3304 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3306 ft.dwLowDateTime = 0xdd88ffff;
3307 ft.dwHighDateTime = 0xf8fe31e8;
3308 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3309 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3311 ft.dwLowDateTime++;
3312 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3313 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
3316 static void test_double(void)
3318 static const struct
3320 const char *str;
3321 HRESULT hr;
3322 ULONGLONG val;
3324 tests[] =
3326 {"<t>0.0</t>", S_OK, 0},
3327 {"<t>-0.0</t>", S_OK, 0x8000000000000000},
3328 {"<t>+0.0</t>", S_OK, 0},
3329 {"<t>-</t>", S_OK, 0},
3330 {"<t>+</t>", S_OK, 0},
3331 {"<t>.0</t>", S_OK, 0},
3332 {"<t>0.</t>", S_OK, 0},
3333 {"<t>0</t>", S_OK, 0},
3334 {"<t> 0 </t>", S_OK, 0},
3335 {"<t></t>", WS_E_INVALID_FORMAT, 0},
3336 {"<t>0,1</t>", WS_E_INVALID_FORMAT, 0},
3337 {"<t>1.1.</t>", WS_E_INVALID_FORMAT, 0},
3338 {"<t>1</t>", S_OK, 0x3ff0000000000000},
3339 {"<t>1.0000000000000002</t>", S_OK, 0x3ff0000000000001},
3340 {"<t>1.0000000000000004</t>", S_OK, 0x3ff0000000000002},
3341 {"<t>10000000000000000000</t>", S_OK, 0x43e158e460913d00},
3342 {"<t>100000000000000000000</t>", S_OK, 0x4415af1d78b58c40},
3343 {"<t>2</t>", S_OK, 0x4000000000000000},
3344 {"<t>-2</t>", S_OK, 0xc000000000000000},
3345 {"<t>nodouble</t>", WS_E_INVALID_FORMAT, 0},
3346 {"<t>INF</t>", S_OK, 0x7ff0000000000000},
3347 {"<t>-INF</t>", S_OK, 0xfff0000000000000},
3348 {"<t>+INF</t>", WS_E_INVALID_FORMAT, 0},
3349 {"<t>Infinity</t>", WS_E_INVALID_FORMAT, 0},
3350 {"<t>-Infinity</t>", WS_E_INVALID_FORMAT, 0},
3351 {"<t>inf</t>", WS_E_INVALID_FORMAT, 0},
3352 {"<t>NaN</t>", S_OK, 0xfff8000000000000},
3353 {"<t>-NaN</t>", WS_E_INVALID_FORMAT, 0},
3354 {"<t>NAN</t>", WS_E_INVALID_FORMAT, 0},
3355 {"<t>0.3</t>", S_OK, 0x3fd3333333333333},
3356 {"<t>0.33</t>", S_OK, 0x3fd51eb851eb851f},
3357 {"<t>0.333</t>", S_OK, 0x3fd54fdf3b645a1d},
3358 {"<t>0.3333</t>", S_OK, 0x3fd554c985f06f69},
3359 {"<t>0.33333</t>", S_OK, 0x3fd555475a31a4be},
3360 {"<t>0.333333</t>", S_OK, 0x3fd55553ef6b5d46},
3361 {"<t>0.3333333</t>", S_OK, 0x3fd55555318abc87},
3362 {"<t>0.33333333</t>", S_OK, 0x3fd5555551c112da},
3363 {"<t>0.333333333</t>", S_OK, 0x3fd5555554f9b516},
3364 {"<t>0.3333333333</t>", S_OK, 0x3fd55555554c2bb5},
3365 {"<t>0.33333333333</t>", S_OK, 0x3fd5555555546ac5},
3366 {"<t>0.3333333333333</t>", S_OK, 0x3fd55555555552fd},
3367 {"<t>0.33333333333333</t>", S_OK, 0x3fd5555555555519},
3368 {"<t>0.333333333333333</t>", S_OK, 0x3fd555555555554f},
3369 {"<t>0.3333333333333333</t>", S_OK, 0x3fd5555555555555},
3370 {"<t>0.33333333333333333</t>", S_OK, 0x3fd5555555555555},
3371 {"<t>0.1e10</t>", S_OK, 0x41cdcd6500000000},
3372 {"<t>1e</t>", WS_E_INVALID_FORMAT, 0},
3373 {"<t>1e0</t>", S_OK, 0x3ff0000000000000},
3374 {"<t>1e+1</t>", S_OK, 0x4024000000000000},
3375 {"<t>1e-1</t>", S_OK, 0x3fb999999999999a},
3376 {"<t>e10</t>", WS_E_INVALID_FORMAT, 0},
3377 {"<t>1e10.</t>", WS_E_INVALID_FORMAT, 0},
3378 {"<t>1E10</t>", S_OK, 0x4202a05f20000000},
3379 {"<t>1e10</t>", S_OK, 0x4202a05f20000000},
3380 {"<t>1e-10</t>", S_OK, 0x3ddb7cdfd9d7bdbb},
3381 {"<t>1.7976931348623158e308</t>", S_OK, 0x7fefffffffffffff},
3382 {"<t>1.7976931348623159e308</t>", S_OK, 0x7ff0000000000000},
3383 {"<t>4.94065645841247e-324</t>", S_OK, 0x1},
3385 HRESULT hr;
3386 WS_XML_READER *reader;
3387 WS_HEAP *heap;
3388 ULONGLONG val;
3389 ULONG i;
3391 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3392 ok( hr == S_OK, "got %08x\n", hr );
3394 hr = WsCreateReader( NULL, 0, &reader, NULL );
3395 ok( hr == S_OK, "got %08x\n", hr );
3397 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3399 val = 0;
3400 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3401 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DOUBLE_TYPE, NULL,
3402 WS_READ_REQUIRED_VALUE, heap, &val, sizeof(val), NULL );
3403 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3404 if (hr == tests[i].hr) ok( val == tests[i].val, "%u: got %x%08x\n", i, (ULONG)(val >> 32), (ULONG)val );
3407 WsFreeReader( reader );
3408 WsFreeHeap( heap );
3411 static void test_WsReadElement(void)
3413 WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
3414 HRESULT hr;
3415 WS_XML_READER *reader;
3416 WS_ELEMENT_DESCRIPTION desc;
3417 UINT32 val;
3419 hr = WsCreateReader( NULL, 0, &reader, NULL );
3420 ok( hr == S_OK, "got %08x\n", hr );
3422 desc.elementLocalName = &localname;
3423 desc.elementNs = &ns;
3424 desc.type = WS_UINT32_TYPE;
3425 desc.typeDescription = NULL;
3427 prepare_struct_type_test( reader, "<t>1</t>" );
3428 hr = WsReadElement( NULL, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3429 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3431 prepare_struct_type_test( reader, "<t>1</t>" );
3432 hr = WsReadElement( reader, NULL, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3433 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3435 prepare_struct_type_test( reader, "<t>1</t>" );
3436 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, NULL, sizeof(val), NULL );
3437 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3439 prepare_struct_type_test( reader, "<t>1</t>" );
3440 val = 0xdeadbeef;
3441 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3442 ok( hr == S_OK, "got %08x\n", hr );
3443 ok( val == 1, "got %u\n", val );
3445 WsFreeReader( reader );
3448 static void test_WsReadValue(void)
3450 HRESULT hr;
3451 WS_XML_READER *reader;
3452 UINT32 val;
3454 hr = WsCreateReader( NULL, 0, &reader, NULL );
3455 ok( hr == S_OK, "got %08x\n", hr );
3457 prepare_struct_type_test( reader, "<t>1</t>" );
3458 hr = WsReadValue( NULL, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3459 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3461 prepare_struct_type_test( reader, "<t>1</t>" );
3462 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, NULL, sizeof(val), NULL );
3463 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3465 /* reader must be positioned correctly */
3466 prepare_struct_type_test( reader, "<t>1</t>" );
3467 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3468 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3470 prepare_struct_type_test( reader, "<t>1</t>" );
3471 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3472 ok( hr == S_OK, "got %08x\n", hr );
3474 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3475 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3477 prepare_struct_type_test( reader, "<t>1</t>" );
3478 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3479 ok( hr == S_OK, "got %08x\n", hr );
3481 hr = WsReadStartElement( reader, NULL );
3482 ok( hr == S_OK, "got %08x\n", hr );
3484 val = 0xdeadbeef;
3485 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3486 ok( hr == S_OK, "got %08x\n", hr );
3487 ok( val == 1, "got %u\n", val );
3489 prepare_struct_type_test( reader, "<u t='1'></u>" );
3490 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3491 ok( hr == S_OK, "got %08x\n", hr );
3493 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3494 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3496 WsFreeReader( reader );
3499 static void test_WsResetError(void)
3501 WS_ERROR_PROPERTY prop;
3502 ULONG size, code;
3503 WS_ERROR *error;
3504 LANGID langid;
3505 HRESULT hr;
3507 hr = WsResetError( NULL );
3508 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3510 error = NULL;
3511 hr = WsCreateError( NULL, 0, &error );
3512 ok( hr == S_OK, "got %08x\n", hr );
3513 ok( error != NULL, "error not set\n" );
3515 code = 0xdeadbeef;
3516 size = sizeof(code);
3517 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3518 ok( hr == S_OK, "got %08x\n", hr );
3520 hr = WsResetError( error );
3521 ok( hr == S_OK, "got %08x\n", hr );
3523 code = 0xdeadbeef;
3524 size = sizeof(code);
3525 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3526 ok( hr == S_OK, "got %08x\n", hr );
3527 ok( !code, "got %u\n", code );
3529 WsFreeError( error );
3531 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
3532 prop.id = WS_ERROR_PROPERTY_LANGID;
3533 prop.value = &langid;
3534 prop.valueSize = sizeof(langid);
3535 hr = WsCreateError( &prop, 1, &error );
3536 ok( hr == S_OK, "got %08x\n", hr );
3538 langid = 0xdead;
3539 size = sizeof(langid);
3540 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3541 ok( hr == S_OK, "got %08x\n", hr );
3542 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3544 hr = WsResetError( error );
3545 ok( hr == S_OK, "got %08x\n", hr );
3547 langid = 0xdead;
3548 size = sizeof(langid);
3549 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3550 ok( hr == S_OK, "got %08x\n", hr );
3551 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3553 WsFreeError( error );
3556 static void test_WsGetReaderPosition(void)
3558 WS_HEAP *heap;
3559 WS_XML_READER *reader;
3560 WS_XML_BUFFER *buffer;
3561 WS_XML_NODE_POSITION pos;
3562 HRESULT hr;
3564 hr = WsGetReaderPosition( NULL, NULL, NULL );
3565 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3567 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3568 ok( hr == S_OK, "got %08x\n", hr );
3570 hr = WsCreateReader( NULL, 0, &reader, NULL );
3571 ok( hr == S_OK, "got %08x\n", hr );
3573 /* reader must be set to an XML buffer */
3574 hr = WsGetReaderPosition( reader, &pos, NULL );
3575 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3577 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
3578 ok( hr == S_OK, "got %08x\n", hr );
3580 hr = WsGetReaderPosition( reader, &pos, NULL );
3581 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3583 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
3584 ok( hr == S_OK, "got %08x\n", hr );
3586 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
3587 ok( hr == S_OK, "got %08x\n", hr );
3589 hr = WsGetReaderPosition( reader, NULL, NULL );
3590 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3592 pos.buffer = pos.node = NULL;
3593 hr = WsGetReaderPosition( reader, &pos, NULL );
3594 ok( hr == S_OK, "got %08x\n", hr );
3595 ok( pos.buffer != NULL, "buffer not set\n" );
3596 ok( pos.node != NULL, "node not set\n" );
3598 WsFreeReader( reader );
3599 WsFreeHeap( heap );
3602 static void test_WsSetReaderPosition(void)
3604 WS_HEAP *heap;
3605 WS_XML_READER *reader;
3606 WS_XML_BUFFER *buf1, *buf2;
3607 WS_XML_NODE_POSITION pos;
3608 HRESULT hr;
3610 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3611 ok( hr == S_OK, "got %08x\n", hr );
3613 hr = WsSetReaderPosition( NULL, NULL, NULL );
3614 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3616 hr = WsCreateReader( NULL, 0, &reader, NULL );
3617 ok( hr == S_OK, "got %08x\n", hr );
3619 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf1, NULL );
3620 ok( hr == S_OK, "got %08x\n", hr );
3622 hr = WsSetInputToBuffer( reader, buf1, NULL, 0, NULL );
3623 ok( hr == S_OK, "got %08x\n", hr );
3625 hr = WsSetReaderPosition( reader, NULL, NULL );
3626 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3628 pos.buffer = pos.node = NULL;
3629 hr = WsGetReaderPosition( reader, &pos, NULL );
3630 ok( hr == S_OK, "got %08x\n", hr );
3631 ok( pos.buffer == buf1, "wrong buffer\n" );
3632 ok( pos.node != NULL, "node not set\n" );
3634 hr = WsSetReaderPosition( reader, &pos, NULL );
3635 ok( hr == S_OK, "got %08x\n", hr );
3637 /* different buffer */
3638 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf2, NULL );
3639 ok( hr == S_OK, "got %08x\n", hr );
3641 pos.buffer = buf2;
3642 hr = WsSetReaderPosition( reader, &pos, NULL );
3643 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3645 WsFreeReader( reader );
3646 WsFreeHeap( heap );
3649 static void test_entities(void)
3651 static const char str1[] = "<t>&#xA</t>";
3652 static const char str2[] = "<t>&#xA;</t>";
3653 static const char str3[] = "<t>&#xa;</t>";
3654 static const char str4[] = "<t>&#xaaaa;</t>";
3655 static const char str5[] = "<t>&#xaaaaa;</t>";
3656 static const char str6[] = "<t>&1</t>";
3657 static const char str7[] = "<t>&1;</t>";
3658 static const char str8[] = "<t>&1111;</t>";
3659 static const char str9[] = "<t>&11111;</t>";
3660 static const char str10[] = "<t>&lt;</t>";
3661 static const char str11[] = "<t>&gt;</t>";
3662 static const char str12[] = "<t>&quot;</t>";
3663 static const char str13[] = "<t>&amp;</t>";
3664 static const char str14[] = "<t>&apos;</t>";
3665 static const char str15[] = "<t>&sopa;</t>";
3666 static const char str16[] = "<t>&#;</t>";
3667 static const char str17[] = "<t>&;</t>";
3668 static const char str18[] = "<t>&&</t>";
3669 static const char str19[] = "<t>&</t>";
3670 static const char str20[] = "<t>&#xaaaaaa;</t>";
3671 static const char str21[] = "<t>&#xd7ff;</t>";
3672 static const char str22[] = "<t>&#xd800;</t>";
3673 static const char str23[] = "<t>&#xdfff;</t>";
3674 static const char str24[] = "<t>&#xe000;</t>";
3675 static const char str25[] = "<t>&#xfffe;</t>";
3676 static const char str26[] = "<t>&#xffff;</t>";
3677 static const char str27[] = "<t>&LT;</t>";
3678 static const char str28[] = "<t>&#x0;</t>";
3679 static const char str29[] = "<t>&#0;</t>";
3680 static const char str30[] = "<t>&#65;</t>";
3681 static const char str31[] = "<t>&#65393;</t>";
3682 static const char str32[] = "<t>&#x10ffff;</t>";
3683 static const char str33[] = "<t>&#x110000;</t>";
3684 static const char str34[] = "<t>&#1114111;</t>";
3685 static const char str35[] = "<t>&#1114112;</t>";
3686 static const char res4[] = {0xea, 0xaa, 0xaa, 0x00};
3687 static const char res5[] = {0xf2, 0xaa, 0xaa, 0xaa, 0x00};
3688 static const char res21[] = {0xed, 0x9f, 0xbf, 0x00};
3689 static const char res24[] = {0xee, 0x80, 0x80, 0x00};
3690 static const char res31[] = {0xef, 0xbd, 0xb1, 0x00};
3691 static const char res32[] = {0xf4, 0x8f, 0xbf, 0xbf, 0x00};
3692 static const struct
3694 const char *str;
3695 HRESULT hr;
3696 const char *res;
3698 tests[] =
3700 { str1, WS_E_INVALID_FORMAT },
3701 { str2, S_OK, "\n" },
3702 { str3, S_OK, "\n" },
3703 { str4, S_OK, res4 },
3704 { str5, S_OK, res5 },
3705 { str6, WS_E_INVALID_FORMAT },
3706 { str7, WS_E_INVALID_FORMAT },
3707 { str8, WS_E_INVALID_FORMAT },
3708 { str9, WS_E_INVALID_FORMAT },
3709 { str10, S_OK, "<" },
3710 { str11, S_OK, ">" },
3711 { str12, S_OK, "\"" },
3712 { str13, S_OK, "&" },
3713 { str14, S_OK, "'" },
3714 { str15, WS_E_INVALID_FORMAT },
3715 { str16, WS_E_INVALID_FORMAT },
3716 { str17, WS_E_INVALID_FORMAT },
3717 { str18, WS_E_INVALID_FORMAT },
3718 { str19, WS_E_INVALID_FORMAT },
3719 { str20, WS_E_INVALID_FORMAT },
3720 { str21, S_OK, res21 },
3721 { str22, WS_E_INVALID_FORMAT },
3722 { str23, WS_E_INVALID_FORMAT },
3723 { str24, S_OK, res24 },
3724 { str25, WS_E_INVALID_FORMAT },
3725 { str26, WS_E_INVALID_FORMAT },
3726 { str27, WS_E_INVALID_FORMAT },
3727 { str28, WS_E_INVALID_FORMAT },
3728 { str29, WS_E_INVALID_FORMAT },
3729 { str30, S_OK, "A" },
3730 { str31, S_OK, res31 },
3731 { str32, S_OK, res32 },
3732 { str33, WS_E_INVALID_FORMAT },
3733 { str34, S_OK, res32 },
3734 { str35, WS_E_INVALID_FORMAT },
3736 HRESULT hr;
3737 WS_XML_READER *reader;
3738 const WS_XML_NODE *node;
3739 const WS_XML_UTF8_TEXT *utf8;
3740 ULONG i;
3742 hr = WsCreateReader( NULL, 0, &reader, NULL );
3743 ok( hr == S_OK, "got %08x\n", hr );
3745 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3747 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
3748 ok( hr == S_OK, "%u: got %08x\n", i, hr );
3750 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3751 ok( hr == S_OK, "%u: got %08x\n", i, hr );
3753 hr = WsReadNode( reader, NULL );
3754 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3755 if (hr != S_OK) continue;
3757 hr = WsGetReaderNode( reader, &node, NULL );
3758 ok( hr == S_OK, "%u: got %08x\n", i, hr );
3760 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_TEXT_NODE *)node)->text;
3761 ok( utf8->value.length == strlen(tests[i].res), "%u: got %u\n", i, utf8->value.length );
3762 ok( !memcmp( utf8->value.bytes, tests[i].res, strlen(tests[i].res) ), "%u: wrong data\n", i );
3765 hr = set_input( reader, "<t a='&#xA;&#xA;'/>", sizeof("<t a='&#xA;&#xA;'/>") - 1 );
3766 ok( hr == S_OK, "got %08x\n", hr );
3768 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3769 ok( hr == S_OK, "got %08x\n", hr );
3771 hr = WsGetReaderNode( reader, &node, NULL );
3772 ok( hr == S_OK, "got %08x\n", hr );
3774 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_ELEMENT_NODE *)node)->attributes[0]->value;
3775 ok( utf8->value.length == 2, "got %u\n", utf8->value.length );
3776 ok( !memcmp( utf8->value.bytes, "\n\n", 2 ), "wrong data\n" );
3778 WsFreeReader( reader );
3781 static void test_field_options(void)
3783 static const char xml[] =
3784 "<t xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><wsz i:nil=\"true\"/>"
3785 "<s i:nil=\"true\"/></t>";
3786 static const GUID guid_null = {0};
3787 HRESULT hr;
3788 WS_HEAP *heap;
3789 WS_XML_READER *reader;
3790 WS_STRUCT_DESCRIPTION s, s2;
3791 WS_FIELD_DESCRIPTION f, f2, f3, f4, f5, *fields[4], *fields2[1];
3792 WS_XML_STRING ns = {0, NULL}, str_wsz = {3, (BYTE *)"wsz"}, str_s = {1, (BYTE *)"s"};
3793 WS_XML_STRING str_int32 = {5, (BYTE *)"int32"}, str_guid = {4, (BYTE *)"guid"};
3794 WS_DEFAULT_VALUE def_val;
3795 INT32 val_int32;
3796 struct s
3798 INT32 int32;
3800 struct test
3802 WCHAR *wsz;
3803 struct s *s;
3804 INT32 int32;
3805 GUID guid;
3806 } *test;
3808 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3809 ok( hr == S_OK, "got %08x\n", hr );
3811 hr = WsCreateReader( NULL, 0, &reader, NULL );
3812 ok( hr == S_OK, "got %08x\n", hr );
3814 hr = set_input( reader, xml, sizeof(xml) - 1 );
3815 ok( hr == S_OK, "got %08x\n", hr );
3817 memset( &f, 0, sizeof(f) );
3818 f.mapping = WS_ELEMENT_FIELD_MAPPING;
3819 f.localName = &str_wsz;
3820 f.ns = &ns;
3821 f.type = WS_WSZ_TYPE;
3822 f.options = WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
3823 fields[0] = &f;
3825 memset( &f3, 0, sizeof(f3) );
3826 f3.mapping = WS_ELEMENT_FIELD_MAPPING;
3827 f3.localName = &str_int32;
3828 f3.ns = &ns;
3829 f3.type = WS_INT32_TYPE;
3830 fields2[0] = &f3;
3832 memset( &s2, 0, sizeof(s2) );
3833 s2.size = sizeof(struct s);
3834 s2.alignment = TYPE_ALIGNMENT(struct s);
3835 s2.fields = fields2;
3836 s2.fieldCount = 1;
3838 memset( &f2, 0, sizeof(f2) );
3839 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
3840 f2.localName = &str_s;
3841 f2.ns = &ns;
3842 f2.type = WS_STRUCT_TYPE;
3843 f2.typeDescription = &s2;
3844 f2.offset = FIELD_OFFSET(struct test, s);
3845 f2.options = WS_FIELD_POINTER|WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
3846 fields[1] = &f2;
3848 val_int32 = -1;
3849 def_val.value = &val_int32;
3850 def_val.valueSize = sizeof(val_int32);
3852 memset( &f4, 0, sizeof(f4) );
3853 f4.mapping = WS_ELEMENT_FIELD_MAPPING;
3854 f4.localName = &str_int32;
3855 f4.ns = &ns;
3856 f4.type = WS_INT32_TYPE;
3857 f4.offset = FIELD_OFFSET(struct test, int32);
3858 f4.options = WS_FIELD_OPTIONAL;
3859 f4.defaultValue = &def_val;
3860 fields[2] = &f4;
3862 memset( &f5, 0, sizeof(f5) );
3863 f5.mapping = WS_ELEMENT_FIELD_MAPPING;
3864 f5.localName = &str_guid;
3865 f5.ns = &ns;
3866 f5.type = WS_GUID_TYPE;
3867 f5.offset = FIELD_OFFSET(struct test, guid);
3868 f5.options = WS_FIELD_OPTIONAL;
3869 fields[3] = &f5;
3871 memset( &s, 0, sizeof(s) );
3872 s.size = sizeof(struct test);
3873 s.alignment = TYPE_ALIGNMENT(struct test);
3874 s.fields = fields;
3875 s.fieldCount = 4;
3877 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3878 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3879 ok( hr == S_OK, "got %08x\n", hr );
3880 ok( !test->wsz, "wsz is set\n" );
3881 ok( !test->s, "s is set\n" );
3882 ok( test->int32 == -1, "got %d\n", test->int32 );
3883 ok( IsEqualGUID( &test->guid, &guid_null ), "wrong guid\n" );
3885 WsFreeReader( reader );
3886 WsFreeHeap( heap );
3889 static void test_WsReadBytes(void)
3891 HRESULT hr;
3892 WS_XML_READER *reader;
3893 const WS_XML_NODE *node;
3894 const WS_XML_TEXT_NODE *text;
3895 const WS_XML_UTF8_TEXT *utf8;
3896 BYTE buf[4];
3897 ULONG count;
3899 hr = WsCreateReader( NULL, 0, &reader, NULL );
3900 ok( hr == S_OK, "got %08x\n", hr );
3902 hr = WsReadBytes( NULL, NULL, 0, NULL, NULL );
3903 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3905 hr = WsReadBytes( reader, NULL, 0, NULL, NULL );
3906 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3908 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
3909 ok( hr == S_OK, "got %08x\n", hr );
3911 hr = WsReadBytes( reader, NULL, 0, NULL, NULL );
3912 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3914 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
3915 ok( hr == S_OK, "got %08x\n", hr );
3917 hr = WsReadBytes( reader, buf, 0, NULL, NULL );
3918 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3920 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
3921 ok( hr == S_OK, "got %08x\n", hr );
3923 count = 0xdeadbeef;
3924 hr = WsReadBytes( reader, NULL, 0, &count, NULL );
3925 ok( hr == S_OK, "got %08x\n", hr );
3926 ok( !count, "got %u\n", count );
3928 count = 0xdeadbeef;
3929 hr = WsReadBytes( reader, NULL, 1, &count, NULL );
3930 ok( hr == S_OK, "got %08x\n", hr );
3931 ok( !count, "got %u\n", count );
3933 buf[0] = 0;
3934 count = 0xdeadbeef;
3935 hr = WsReadBytes( reader, buf, 0, &count, NULL );
3936 ok( hr == S_OK, "got %08x\n", hr );
3937 ok( !count, "got %u\n", count );
3938 ok( !buf[0], "wrong data\n" );
3940 buf[0] = 0;
3941 count = 0xdeadbeef;
3942 hr = WsReadBytes( reader, buf, 2, &count, NULL );
3943 ok( hr == S_OK, "got %08x\n", hr );
3944 ok( !count, "got %u\n", count );
3945 ok( !buf[0], "wrong data\n" );
3947 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3948 ok( hr == S_OK, "got %08x\n", hr );
3950 buf[0] = 0;
3951 count = 0xdeadbeef;
3952 hr = WsReadBytes( reader, buf, 2, &count, NULL );
3953 ok( hr == S_OK, "got %08x\n", hr );
3954 ok( !count, "got %u\n", count );
3955 ok( !buf[0], "wrong data\n" );
3957 hr = WsReadStartElement( reader, NULL );
3958 ok( hr == S_OK, "got %08x\n", hr );
3960 count = 0xdeadbeef;
3961 hr = WsReadBytes( reader, NULL, 0, &count, NULL );
3962 ok( hr == S_OK, "got %08x\n", hr );
3963 ok( !count, "got %u\n", count );
3965 buf[0] = 0;
3966 count = 0xdeadbeef;
3967 hr = WsReadBytes( reader, buf, 2, &count, NULL );
3968 ok( hr == S_OK, "got %08x\n", hr );
3969 ok( count == 2, "got %u\n", count );
3970 ok( !memcmp( buf, "te", 2 ), "wrong data\n" );
3972 hr = WsGetReaderNode( reader, &node, NULL );
3973 ok( hr == S_OK, "got %08x\n", hr );
3974 text = (const WS_XML_TEXT_NODE *)node;
3975 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
3976 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
3977 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
3978 ok( utf8->value.length == 8, "got %u\n", utf8->value.length );
3979 ok( !memcmp( utf8->value.bytes, "dGV4dA==", 8 ), "wrong data\n" );
3981 buf[0] = 0;
3982 count = 0xdeadbeef;
3983 hr = WsReadBytes( reader, buf, 2, &count, NULL );
3984 ok( hr == S_OK, "got %08x\n", hr );
3985 ok( count == 2, "got %u\n", count );
3986 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
3988 hr = WsGetReaderNode( reader, &node, NULL );
3989 ok( hr == S_OK, "got %08x\n", hr );
3990 text = (const WS_XML_TEXT_NODE *)node;
3991 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
3993 count = 0xdeadbeef;
3994 hr = WsReadBytes( reader, buf, 1, &count, NULL );
3995 ok( hr == S_OK, "got %08x\n", hr );
3996 ok( !count, "got %u\n", count );
3998 hr = WsGetReaderNode( reader, &node, NULL );
3999 ok( hr == S_OK, "got %08x\n", hr );
4000 text = (const WS_XML_TEXT_NODE *)node;
4001 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4003 WsFreeReader( reader );
4006 static void test_WsReadChars(void)
4008 static const WCHAR textW[] = {'t','e','x','t'};
4009 HRESULT hr;
4010 WS_XML_READER *reader;
4011 const WS_XML_NODE *node;
4012 const WS_XML_TEXT_NODE *text;
4013 const WS_XML_UTF8_TEXT *utf8;
4014 unsigned char buf[4];
4015 WCHAR bufW[4];
4016 ULONG count;
4018 hr = WsCreateReader( NULL, 0, &reader, NULL );
4019 ok( hr == S_OK, "got %08x\n", hr );
4021 hr = WsReadChars( NULL, NULL, 0, NULL, NULL );
4022 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4024 hr = WsReadChars( reader, NULL, 0, NULL, NULL );
4025 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4027 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4028 ok( hr == S_OK, "got %08x\n", hr );
4030 hr = WsReadChars( reader, NULL, 0, NULL, NULL );
4031 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4033 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4034 ok( hr == S_OK, "got %08x\n", hr );
4036 hr = WsReadChars( reader, bufW, 0, NULL, NULL );
4037 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4039 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4040 ok( hr == S_OK, "got %08x\n", hr );
4042 count = 0xdeadbeef;
4043 hr = WsReadChars( reader, NULL, 0, &count, NULL );
4044 ok( hr == S_OK, "got %08x\n", hr );
4045 ok( !count, "got %u\n", count );
4047 count = 0xdeadbeef;
4048 hr = WsReadChars( reader, NULL, 1, &count, NULL );
4049 ok( hr == S_OK, "got %08x\n", hr );
4050 ok( !count, "got %u\n", count );
4052 buf[0] = 0;
4053 count = 0xdeadbeef;
4054 hr = WsReadChars( reader, bufW, 0, &count, NULL );
4055 ok( hr == S_OK, "got %08x\n", hr );
4056 ok( !count, "got %u\n", count );
4057 ok( !buf[0], "wrong data\n" );
4059 buf[0] = 0;
4060 count = 0xdeadbeef;
4061 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4062 ok( hr == S_OK, "got %08x\n", hr );
4063 ok( !count, "got %u\n", count );
4064 ok( !buf[0], "wrong data\n" );
4066 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4067 ok( hr == S_OK, "got %08x\n", hr );
4069 buf[0] = 0;
4070 count = 0xdeadbeef;
4071 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4072 ok( hr == S_OK, "got %08x\n", hr );
4073 ok( !count, "got %u\n", count );
4074 ok( !buf[0], "wrong data\n" );
4076 hr = WsReadStartElement( reader, NULL );
4077 ok( hr == S_OK, "got %08x\n", hr );
4079 count = 0xdeadbeef;
4080 hr = WsReadChars( reader, NULL, 0, &count, NULL );
4081 ok( hr == S_OK, "got %08x\n", hr );
4082 ok( !count, "got %u\n", count );
4084 buf[0] = 0;
4085 count = 0xdeadbeef;
4086 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4087 ok( hr == S_OK, "got %08x\n", hr );
4088 ok( count == 2, "got %u\n", count );
4089 ok( !memcmp( bufW, textW, 2 * sizeof(WCHAR) ), "wrong data\n" );
4091 hr = WsGetReaderNode( reader, &node, NULL );
4092 ok( hr == S_OK, "got %08x\n", hr );
4093 text = (const WS_XML_TEXT_NODE *)node;
4094 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4095 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4096 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4097 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4098 ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" );
4100 /* continue reading in a different encoding */
4101 buf[0] = 0;
4102 count = 0xdeadbeef;
4103 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4104 ok( hr == S_OK, "got %08x\n", hr );
4105 ok( count == 2, "got %u\n", count );
4106 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4108 hr = WsGetReaderNode( reader, &node, NULL );
4109 ok( hr == S_OK, "got %08x\n", hr );
4110 text = (const WS_XML_TEXT_NODE *)node;
4111 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4113 count = 0xdeadbeef;
4114 hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL );
4115 ok( hr == S_OK, "got %08x\n", hr );
4116 ok( !count, "got %u\n", count );
4118 hr = WsGetReaderNode( reader, &node, NULL );
4119 ok( hr == S_OK, "got %08x\n", hr );
4120 text = (const WS_XML_TEXT_NODE *)node;
4121 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4123 WsFreeReader( reader );
4126 static void test_WsReadCharsUtf8(void)
4128 HRESULT hr;
4129 WS_XML_READER *reader;
4130 const WS_XML_NODE *node;
4131 const WS_XML_TEXT_NODE *text;
4132 const WS_XML_UTF8_TEXT *utf8;
4133 BYTE buf[4];
4134 ULONG count;
4136 hr = WsCreateReader( NULL, 0, &reader, NULL );
4137 ok( hr == S_OK, "got %08x\n", hr );
4139 hr = WsReadCharsUtf8( NULL, NULL, 0, NULL, NULL );
4140 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4142 hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL );
4143 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4145 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4146 ok( hr == S_OK, "got %08x\n", hr );
4148 hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL );
4149 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4151 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4152 ok( hr == S_OK, "got %08x\n", hr );
4154 hr = WsReadCharsUtf8( reader, buf, 0, NULL, NULL );
4155 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4157 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4158 ok( hr == S_OK, "got %08x\n", hr );
4160 count = 0xdeadbeef;
4161 hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL );
4162 ok( hr == S_OK, "got %08x\n", hr );
4163 ok( !count, "got %u\n", count );
4165 count = 0xdeadbeef;
4166 hr = WsReadCharsUtf8( reader, NULL, 1, &count, NULL );
4167 ok( hr == S_OK, "got %08x\n", hr );
4168 ok( !count, "got %u\n", count );
4170 buf[0] = 0;
4171 count = 0xdeadbeef;
4172 hr = WsReadCharsUtf8( reader, buf, 0, &count, NULL );
4173 ok( hr == S_OK, "got %08x\n", hr );
4174 ok( !count, "got %u\n", count );
4175 ok( !buf[0], "wrong data\n" );
4177 buf[0] = 0;
4178 count = 0xdeadbeef;
4179 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4180 ok( hr == S_OK, "got %08x\n", hr );
4181 ok( !count, "got %u\n", count );
4182 ok( !buf[0], "wrong data\n" );
4184 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4185 ok( hr == S_OK, "got %08x\n", hr );
4187 buf[0] = 0;
4188 count = 0xdeadbeef;
4189 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4190 ok( hr == S_OK, "got %08x\n", hr );
4191 ok( !count, "got %u\n", count );
4192 ok( !buf[0], "wrong data\n" );
4194 hr = WsReadStartElement( reader, NULL );
4195 ok( hr == S_OK, "got %08x\n", hr );
4197 count = 0xdeadbeef;
4198 hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL );
4199 ok( hr == S_OK, "got %08x\n", hr );
4200 ok( !count, "got %u\n", count );
4202 buf[0] = 0;
4203 count = 0xdeadbeef;
4204 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4205 ok( hr == S_OK, "got %08x\n", hr );
4206 ok( count == 2, "got %u\n", count );
4207 ok( !memcmp( buf, "te", 2 ), "wrong data\n" );
4209 hr = WsGetReaderNode( reader, &node, NULL );
4210 ok( hr == S_OK, "got %08x\n", hr );
4211 text = (const WS_XML_TEXT_NODE *)node;
4212 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4213 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4214 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4215 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4216 ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" );
4218 buf[0] = 0;
4219 count = 0xdeadbeef;
4220 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4221 ok( hr == S_OK, "got %08x\n", hr );
4222 ok( count == 2, "got %u\n", count );
4223 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4225 hr = WsGetReaderNode( reader, &node, NULL );
4226 ok( hr == S_OK, "got %08x\n", hr );
4227 text = (const WS_XML_TEXT_NODE *)node;
4228 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4230 count = 0xdeadbeef;
4231 hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL );
4232 ok( hr == S_OK, "got %08x\n", hr );
4233 ok( !count, "got %u\n", count );
4235 hr = WsGetReaderNode( reader, &node, NULL );
4236 ok( hr == S_OK, "got %08x\n", hr );
4237 text = (const WS_XML_TEXT_NODE *)node;
4238 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4240 WsFreeReader( reader );
4243 static void test_WsReadQualifiedName(void)
4245 static const char utf8[] = {'<','a','>',0xc3,0xab,'<','/','a','>',0};
4246 static const char localname_utf8[] = {0xc3,0xab,0};
4247 WS_XML_STRING prefix, localname, ns;
4248 WS_XML_READER *reader;
4249 WS_HEAP *heap;
4250 HRESULT hr;
4251 BOOL found;
4252 ULONG i;
4253 static const struct
4255 const char *str;
4256 HRESULT hr;
4257 const char *prefix;
4258 const char *localname;
4259 const char *ns;
4260 } tests[] =
4262 { "<a></a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4263 { "<a> </a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4264 { "<a>:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4265 { "<a>t</a>", S_OK, "", "t", "" },
4266 { "<a>p:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4267 { "<a>p:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4268 { "<a>:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4269 { "<a xmlns:p=\"ns\">p:t</a>", S_OK, "p", "t", "ns" },
4270 { "<a xmlns:p=\"ns\">p:t:</a>", S_OK, "p", "t:", "ns" },
4271 { "<a xmlns:p=\"ns\">p:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4272 { "<a xmlns:p=\"ns\">:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4273 { "<a xmlns:p=\"ns\">:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4274 { "<a xmlns:p=\"ns\">t</a>", S_OK, "", "t", "" },
4275 { "<a xmlns:p=\"ns\"> </a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4276 { "<a xmlns:p=\"ns\"></a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4277 { "<a xmlns:p=\"ns\">p:t u</a>", S_OK, "p", "t u", "ns" },
4278 { utf8, S_OK, "", localname_utf8, "" },
4279 { "<a> t </a>", S_OK, "", "t", "" },
4280 { "<a xmlns:p=\"ns\"> p:t</a>", S_OK, "p", "t", "ns" },
4281 { "<a xmlns:p=\"ns\">p :t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4282 { "<a xmlns:p=\"ns\">p: t</a>", S_OK, "p", " t", "ns" },
4285 hr = WsReadQualifiedName( NULL, NULL, NULL, NULL, NULL, NULL );
4286 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4288 hr = WsCreateReader( NULL, 0, &reader, NULL );
4289 ok( hr == S_OK, "got %08x\n", hr );
4291 hr = WsReadQualifiedName( reader, NULL, NULL, NULL, NULL, NULL );
4292 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4294 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
4295 ok( hr == S_OK, "got %08x\n", hr );
4297 hr = WsReadQualifiedName( reader, heap, NULL, NULL, NULL, NULL );
4298 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4300 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4301 ok( hr == S_OK, "got %08x\n", hr );
4302 hr = WsReadQualifiedName( reader, heap, NULL, NULL, NULL, NULL );
4303 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4305 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4306 ok( hr == S_OK, "got %08x\n", hr );
4307 hr = WsReadQualifiedName( reader, heap, NULL, &localname, NULL, NULL );
4308 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
4310 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
4312 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
4313 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4315 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4316 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4318 hr = WsReadStartElement( reader, NULL );
4319 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4321 prefix.length = localname.length = ns.length = 0xdeadbeef;
4322 prefix.bytes = localname.bytes = ns.bytes = (BYTE *)0xdeadbeef;
4324 hr = WsReadQualifiedName( reader, heap, &prefix, &localname, &ns, NULL );
4325 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
4326 if (tests[i].hr == S_OK && hr == S_OK)
4328 ok( prefix.length == strlen( tests[i].prefix ), "%u: got %u\n", i, prefix.length );
4329 ok( !memcmp( prefix.bytes, tests[i].prefix, prefix.length ), "%u: wrong data\n", i );
4331 ok( localname.length == strlen( tests[i].localname ), "%u: got %u\n", i, localname.length );
4332 ok( !memcmp( localname.bytes, tests[i].localname, localname.length ), "%u: wrong data\n", i );
4334 ok( ns.length == strlen( tests[i].ns ), "%u: got %u\n", i, ns.length );
4335 ok( !memcmp( ns.bytes, tests[i].ns, ns.length ), "%u: wrong data\n", i );
4337 else if (tests[i].hr != S_OK)
4339 ok( prefix.length == 0xdeadbeef, "got %u\n", prefix.length );
4340 ok( prefix.bytes == (BYTE *)0xdeadbeef, "got %p\n", prefix.bytes );
4342 ok( localname.length == 0xdeadbeef, "got %u\n", localname.length );
4343 ok( localname.bytes == (BYTE *)0xdeadbeef, "got %p\n", localname.bytes );
4345 ok( ns.length == 0xdeadbeef, "got %u\n", ns.length );
4346 ok( ns.bytes == (BYTE *)0xdeadbeef, "got %p\n", ns.bytes );
4350 WsFreeHeap( heap );
4351 WsFreeReader( reader );
4354 static void test_WsReadAttribute(void)
4356 WS_XML_STRING localname = {1, (BYTE *)"a"}, ns = {0, NULL};
4357 WS_XML_READER *reader;
4358 WS_ATTRIBUTE_DESCRIPTION desc;
4359 WS_HEAP *heap;
4360 UINT32 *val;
4361 BOOL found;
4362 HRESULT hr;
4364 hr = WsReadAttribute( NULL, NULL, 0, NULL, NULL, 0, NULL );
4365 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4367 hr = WsCreateReader( NULL, 0, &reader, NULL );
4368 ok( hr == S_OK, "got %08x\n", hr );
4370 hr = WsReadAttribute( reader, NULL, 0, NULL, NULL, 0, NULL );
4371 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4373 desc.attributeLocalName = &localname;
4374 desc.attributeNs = &ns;
4375 desc.type = WS_UINT32_TYPE;
4376 desc.typeDescription = NULL;
4377 hr = WsReadAttribute( reader, &desc, 0, NULL, NULL, 0, NULL );
4378 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4380 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, NULL, NULL, 0, NULL );
4381 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4383 hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL );
4384 ok( hr == S_OK, "got %08x\n", hr );
4386 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, NULL, 0, NULL );
4387 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4389 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, &val, sizeof(val), NULL );
4390 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4392 prepare_struct_type_test( reader, "<t a='1'>" );
4393 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4394 ok( hr == S_OK, "got %08x\n", hr );
4396 val = NULL;
4397 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, &val, sizeof(val), NULL );
4398 ok( hr == S_OK, "got %08x\n", hr );
4399 ok( val != NULL, "val not set\n" );
4400 ok( *val == 1, "got %u\n", *val );
4402 WsFreeHeap( heap );
4403 WsFreeReader( reader );
4406 START_TEST(reader)
4408 test_WsCreateError();
4409 test_WsCreateHeap();
4410 test_WsCreateReader();
4411 test_WsSetInput();
4412 test_WsSetInputToBuffer();
4413 test_WsFillReader();
4414 test_WsReadToStartElement();
4415 test_WsReadStartElement();
4416 test_WsReadEndElement();
4417 test_WsReadNode();
4418 test_WsReadType();
4419 test_WsGetXmlAttribute();
4420 test_WsXmlStringEquals();
4421 test_WsAlloc();
4422 test_WsMoveReader();
4423 test_simple_struct_type();
4424 test_cdata();
4425 test_WsFindAttribute();
4426 test_WsGetNamespaceFromPrefix();
4427 test_text_field_mapping();
4428 test_complex_struct_type();
4429 test_repeating_element();
4430 test_WsResetHeap();
4431 test_datetime();
4432 test_WsDateTimeToFileTime();
4433 test_WsFileTimeToDateTime();
4434 test_double();
4435 test_WsReadElement();
4436 test_WsReadValue();
4437 test_WsResetError();
4438 test_WsGetReaderPosition();
4439 test_WsSetReaderPosition();
4440 test_entities();
4441 test_field_options();
4442 test_WsReadBytes();
4443 test_WsReadChars();
4444 test_WsReadCharsUtf8();
4445 test_WsReadQualifiedName();
4446 test_WsReadAttribute();