webservices: Add support for reading text in binary mode.
[wine.git] / dlls / webservices / tests / reader.c
blob4af941b0b1a4fce4db0664e73d5dbc289464ca59
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 static char test24[] = {'<',0,'a',0,'>',0,'b',0,'<',0,'/',0,'>',0};
443 HRESULT hr;
444 WS_XML_READER *reader;
445 WS_XML_READER_PROPERTY prop;
446 WS_XML_READER_TEXT_ENCODING enc;
447 WS_XML_READER_BUFFER_INPUT input;
448 WS_XML_TEXT_NODE *text;
449 WS_XML_UTF8_TEXT *utf8;
450 WS_CHARSET charset;
451 const WS_XML_NODE *node;
452 ULONG i, size, max_depth;
453 BOOL found;
454 static const struct
456 void *data;
457 ULONG size;
458 HRESULT hr;
459 WS_CHARSET charset;
460 int todo;
462 tests[] =
464 { test1, sizeof(test1), S_OK, WS_CHARSET_UTF8 },
465 { test2, sizeof(test2), S_OK, WS_CHARSET_UTF8 },
466 { test3, sizeof(test3), S_OK, WS_CHARSET_UTF8 },
467 { test4, sizeof(test4), S_OK, WS_CHARSET_UTF8 },
468 { test5, sizeof(test5), WS_E_INVALID_FORMAT, 0, 1 },
469 { test6, sizeof(test6), WS_E_INVALID_FORMAT, 0, 1 },
470 { test7, sizeof(test7), WS_E_INVALID_FORMAT, 0, 1 },
471 { test8, sizeof(test8), WS_E_INVALID_FORMAT, 0 },
472 { test9, sizeof(test9), WS_E_INVALID_FORMAT, 0 },
473 { test10, sizeof(test10), S_OK, WS_CHARSET_UTF16LE },
474 { test11, sizeof(test11), S_OK, WS_CHARSET_UTF16LE },
475 { test12, sizeof(test12), S_OK, WS_CHARSET_UTF16LE },
476 { test13, sizeof(test13), WS_E_INVALID_FORMAT, 0, 1 },
477 { test14, sizeof(test14), WS_E_INVALID_FORMAT, 0 },
478 { test15, sizeof(test15), S_OK, WS_CHARSET_UTF8 },
479 { test16, sizeof(test16), WS_E_INVALID_FORMAT, 0 },
480 { test17, sizeof(test17), S_OK, WS_CHARSET_UTF8 },
481 { test18, sizeof(test18), S_OK, WS_CHARSET_UTF16LE },
482 { test19, sizeof(test19), S_OK, WS_CHARSET_UTF16LE },
483 { test20, sizeof(test20), S_OK, WS_CHARSET_UTF8 },
484 { test21, sizeof(test21), WS_E_INVALID_FORMAT, 0 },
485 { test22, sizeof(test22), S_OK, WS_CHARSET_UTF8 },
486 { test23, sizeof(test23), WS_E_INVALID_FORMAT, 0, 1 },
489 hr = WsCreateReader( NULL, 0, &reader, NULL );
490 ok( hr == S_OK, "got %08x\n", hr );
492 hr = WsSetInput( NULL, NULL, NULL, NULL, 0, NULL );
493 ok( hr == E_INVALIDARG, "got %08x\n", hr );
495 node = NULL;
496 hr = WsGetReaderNode( reader, &node, NULL );
497 ok( hr == S_OK, "got %08x\n", hr );
498 ok( node != NULL, "node not set\n" );
499 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
501 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
502 enc.charSet = WS_CHARSET_UTF8;
504 input.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
505 input.encodedData = (void *)data1;
506 input.encodedDataSize = sizeof(data1) - 1;
508 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
509 ok( hr == S_OK, "got %08x\n", hr );
511 node = NULL;
512 hr = WsGetReaderNode( reader, &node, NULL );
513 ok( hr == S_OK, "got %08x\n", hr );
514 ok( node != NULL, "node not set\n" );
515 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
517 /* multiple calls are allowed */
518 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
519 ok( hr == S_OK, "got %08x\n", hr );
521 /* charset is detected by WsSetInput */
522 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
523 enc.charSet = WS_CHARSET_AUTO;
525 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
527 input.encodedData = tests[i].data;
528 input.encodedDataSize = tests[i].size;
529 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
530 ok( hr == S_OK, "%u: got %08x\n", i, hr );
532 charset = 0xdeadbeef;
533 size = sizeof(charset);
534 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
535 todo_wine_if (tests[i].todo)
537 ok( hr == tests[i].hr, "%u: got %08x expected %08x\n", i, hr, tests[i].hr );
538 if (hr == S_OK)
539 ok( charset == tests[i].charset, "%u: got %u expected %u\n", i, charset, tests[i].charset );
543 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
544 enc.charSet = WS_CHARSET_UTF8;
546 /* reader properties can be set with WsSetInput */
547 max_depth = 16;
548 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
549 prop.value = &max_depth;
550 prop.valueSize = sizeof(max_depth);
551 hr = WsSetInput( reader, &enc.encoding, &input.input, &prop, 1, NULL );
552 ok( hr == S_OK, "got %08x\n", hr );
554 max_depth = 0xdeadbeef;
555 size = sizeof(max_depth);
556 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
557 ok( hr == S_OK, "got %08x\n", hr );
558 ok( max_depth == 16, "got %u\n", max_depth );
560 /* show that the reader converts text to UTF-8 */
561 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
562 enc.charSet = WS_CHARSET_UTF16LE;
563 input.encodedData = (void *)test24;
564 input.encodedDataSize = sizeof(test24);
565 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
566 ok( hr == S_OK, "got %08x\n", hr );
568 found = -1;
569 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
570 todo_wine ok( hr == S_OK, "got %08x\n", hr );
571 if (hr == S_OK)
573 ok( found == TRUE, "got %d\n", found );
575 hr = WsReadStartElement( reader, NULL );
576 ok( hr == S_OK, "got %08x\n", hr );
578 hr = WsGetReaderNode( reader, &node, NULL );
579 ok( hr == S_OK, "got %08x\n", hr );
580 text = (WS_XML_TEXT_NODE *)node;
581 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
582 ok( text->text != NULL, "text not set\n" );
583 utf8 = (WS_XML_UTF8_TEXT *)text->text;
584 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
585 ok( utf8->value.length == 1, "got %u\n", utf8->value.length );
586 ok( utf8->value.bytes[0] == 'b', "wrong data\n" );
588 WsFreeReader( reader );
591 static void test_WsSetInputToBuffer(void)
593 HRESULT hr;
594 WS_HEAP *heap;
595 WS_XML_BUFFER *buffer;
596 WS_XML_READER *reader;
597 WS_XML_READER_PROPERTY prop;
598 const WS_XML_NODE *node;
599 ULONG size, max_depth;
601 hr = WsCreateReader( NULL, 0, &reader, NULL );
602 ok( hr == S_OK, "got %08x\n", hr );
604 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
605 ok( hr == S_OK, "got %08x\n", hr );
607 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
608 ok( hr == S_OK, "got %08x\n", hr );
610 hr = WsSetInputToBuffer( NULL, NULL, NULL, 0, NULL );
611 ok( hr == E_INVALIDARG, "got %08x\n", hr );
613 hr = WsSetInputToBuffer( reader, NULL, NULL, 0, NULL );
614 ok( hr == E_INVALIDARG, "got %08x\n", hr );
616 node = NULL;
617 hr = WsGetReaderNode( reader, &node, NULL );
618 ok( hr == S_OK, "got %08x\n", hr );
619 ok( node != NULL, "node not set\n" );
620 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
622 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
623 ok( hr == S_OK, "got %08x\n", hr );
625 node = NULL;
626 hr = WsGetReaderNode( reader, &node, NULL );
627 ok( hr == S_OK, "got %08x\n", hr );
628 ok( node != NULL, "node not set\n" );
629 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
631 /* multiple calls are allowed */
632 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
633 ok( hr == S_OK, "got %08x\n", hr );
635 /* reader properties can be set with WsSetInputToBuffer */
636 max_depth = 16;
637 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
638 prop.value = &max_depth;
639 prop.valueSize = sizeof(max_depth);
640 hr = WsSetInputToBuffer( reader, buffer, &prop, 1, NULL );
641 ok( hr == S_OK, "got %08x\n", hr );
643 max_depth = 0xdeadbeef;
644 size = sizeof(max_depth);
645 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
646 ok( hr == S_OK, "got %08x\n", hr );
647 ok( max_depth == 16, "got %u\n", max_depth );
649 WsFreeReader( reader );
650 WsFreeHeap( heap );
653 static void test_WsFillReader(void)
655 HRESULT hr;
656 WS_XML_READER *reader;
657 const WS_XML_NODE *node;
659 /* what happens of we don't call WsFillReader? */
660 hr = WsCreateReader( NULL, 0, &reader, NULL );
661 ok( hr == S_OK, "got %08x\n", hr );
663 node = NULL;
664 hr = WsGetReaderNode( reader, &node, NULL );
665 ok( hr == S_OK, "got %08x\n", hr );
666 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
668 hr = set_input( reader, data1, sizeof(data1) - 1 );
669 ok( hr == S_OK, "got %08x\n", hr );
671 node = NULL;
672 hr = WsGetReaderNode( reader, &node, NULL );
673 ok( hr == S_OK, "got %08x\n", hr );
674 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
676 hr = WsReadNode( reader, NULL );
677 ok( hr == S_OK, "got %08x\n", hr );
679 node = NULL;
680 hr = WsGetReaderNode( reader, &node, NULL );
681 ok( hr == S_OK, "got %08x\n", hr );
682 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
683 WsFreeReader( reader );
685 hr = WsCreateReader( NULL, 0, &reader, NULL );
686 ok( hr == S_OK, "got %08x\n", hr );
688 hr = set_input( reader, data1, sizeof(data1) - 1 );
689 ok( hr == S_OK, "got %08x\n", hr );
691 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
692 ok( hr == S_OK, "got %08x\n", hr );
694 hr = set_input( reader, data1, sizeof(data1) - 1 );
695 ok( hr == S_OK, "got %08x\n", hr );
697 node = NULL;
698 hr = WsGetReaderNode( reader, &node, NULL );
699 ok( hr == S_OK, "got %08x\n", hr );
700 ok( node != NULL, "node not set\n" );
701 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
703 hr = WsFillReader( NULL, sizeof(data1) - 1, NULL, NULL );
704 ok( hr == E_INVALIDARG, "got %08x\n", hr );
706 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
707 ok( hr == S_OK, "got %08x\n", hr );
709 node = NULL;
710 hr = WsGetReaderNode( reader, &node, NULL );
711 ok( hr == S_OK, "got %08x\n", hr );
712 ok( node != NULL, "node not set\n" );
713 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
715 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
716 ok( hr == S_OK, "got %08x\n", hr );
718 /* min_size larger than input size */
719 hr = WsFillReader( reader, sizeof(data1), NULL, NULL );
720 ok( hr == S_OK, "got %08x\n", hr );
721 WsFreeReader( reader );
724 static void test_WsReadToStartElement(void)
726 HRESULT hr;
727 WS_XML_READER *reader;
728 const WS_XML_NODE *node, *node2;
729 int found;
731 hr = WsCreateReader( NULL, 0, &reader, NULL );
732 ok( hr == S_OK, "got %08x\n", hr );
734 hr = set_input( reader, data1, sizeof(data1) - 1 );
735 ok( hr == S_OK, "got %08x\n", hr );
737 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
738 ok( hr == S_OK, "got %08x\n", hr );
740 hr = WsGetReaderNode( reader, &node, NULL );
741 ok( hr == S_OK, "got %08x\n", hr );
742 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
744 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
745 ok( hr == S_OK, "got %08x\n", hr );
747 hr = WsReadToStartElement( NULL, NULL, NULL, NULL, NULL );
748 ok( hr == E_INVALIDARG, "got %08x\n", hr );
750 found = -1;
751 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
752 ok( hr == S_OK, "got %08x\n", hr );
753 ok( found == FALSE, "got %d\n", found );
755 hr = WsGetReaderNode( reader, &node, NULL );
756 ok( hr == S_OK, "got %08x\n", hr );
757 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
759 hr = set_input( reader, data2, sizeof(data2) - 1 );
760 ok( hr == S_OK, "got %08x\n", hr );
762 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
763 ok( hr == S_OK, "got %08x\n", hr );
765 hr = WsGetReaderNode( reader, &node, NULL );
766 ok( hr == S_OK, "got %08x\n", hr );
767 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
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 hr = WsGetReaderNode( reader, &node, NULL );
775 ok( hr == S_OK, "got %08x\n", hr );
776 if (node)
778 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
780 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
781 ok( elem->prefix != NULL, "prefix not set\n" );
782 if (elem->prefix)
784 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
786 ok( elem->localName != NULL, "localName not set\n" );
787 if (elem->localName)
789 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
790 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
792 ok( elem->ns != NULL, "ns not set\n" );
793 if (elem->ns)
795 ok( !elem->ns->length, "got %u\n", elem->ns->length );
797 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
798 ok( elem->attributes == NULL, "attributes set\n" );
799 ok( !elem->isEmpty, "isEmpty not zero\n" );
802 found = -1;
803 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
804 ok( hr == S_OK, "got %08x\n", hr );
805 ok( found == TRUE, "got %d\n", found );
807 node2 = NULL;
808 hr = WsGetReaderNode( reader, &node2, NULL );
809 ok( hr == S_OK, "got %08x\n", hr );
810 ok( node2 == node, "different node\n" );
812 hr = set_input( reader, data3, sizeof(data3) - 1 );
813 ok( hr == S_OK, "got %08x\n", hr );
815 hr = WsFillReader( reader, sizeof(data3) - 1, NULL, NULL );
816 ok( hr == S_OK, "got %08x\n", hr );
818 found = -1;
819 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
820 ok( hr == S_OK, "got %08x\n", hr );
821 ok( found == TRUE, "got %d\n", found );
823 hr = WsGetReaderNode( reader, &node, NULL );
824 ok( hr == S_OK, "got %08x\n", hr );
825 if (node)
827 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
829 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
830 ok( elem->localName != NULL, "localName not set\n" );
831 if (elem->localName)
833 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
834 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
838 hr = set_input( reader, data4, sizeof(data4) - 1 );
839 ok( hr == S_OK, "got %08x\n", hr );
841 hr = WsFillReader( reader, sizeof(data4) - 1, NULL, NULL );
842 ok( hr == S_OK, "got %08x\n", hr );
844 found = -1;
845 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
846 ok( hr == S_OK, "got %08x\n", hr );
847 ok( found == TRUE, "got %d\n", found );
848 WsFreeReader( reader );
851 static void test_WsReadStartElement(void)
853 HRESULT hr;
854 WS_XML_READER *reader;
855 const WS_XML_NODE *node, *node2;
856 int found;
858 hr = WsCreateReader( NULL, 0, &reader, NULL );
859 ok( hr == S_OK, "got %08x\n", hr );
861 hr = set_input( reader, data2, sizeof(data2) - 1 );
862 ok( hr == S_OK, "got %08x\n", hr );
864 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
865 ok( hr == S_OK, "got %08x\n", hr );
867 found = -1;
868 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
869 ok( hr == S_OK, "got %08x\n", hr );
870 ok( found == TRUE, "got %d\n", found );
872 hr = WsReadStartElement( NULL, NULL );
873 ok( hr == E_INVALIDARG, "got %08x\n", hr );
875 hr = WsGetReaderNode( reader, &node, NULL );
876 ok( hr == S_OK, "got %08x\n", hr );
877 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
879 hr = WsReadStartElement( reader, NULL );
880 ok( hr == S_OK, "got %08x\n", hr );
882 hr = WsGetReaderNode( reader, &node, NULL );
883 ok( hr == S_OK, "got %08x\n", hr );
884 if (node)
886 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
887 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
888 ok( text->text != NULL, "text not set\n" );
889 if (text->text)
891 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
892 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
893 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
894 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong data\n" );
898 hr = WsReadStartElement( reader, NULL );
899 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
901 node2 = NULL;
902 hr = WsGetReaderNode( reader, &node2, NULL );
903 ok( hr == S_OK, "got %08x\n", hr );
904 ok( node2 == node, "different node\n" );
906 hr = set_input( reader, data8, sizeof(data8) - 1 );
907 ok( hr == S_OK, "got %08x\n", hr );
909 hr = WsFillReader( reader, sizeof(data8) - 1, NULL, NULL );
910 ok( hr == S_OK, "got %08x\n", hr );
912 found = -1;
913 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
914 ok( hr == S_OK, "got %08x\n", hr );
915 ok( found == TRUE, "got %d\n", found );
917 hr = WsGetReaderNode( reader, &node, NULL );
918 ok( hr == S_OK, "got %08x\n", hr );
919 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
921 hr = WsGetReaderNode( reader, &node, NULL );
922 ok( hr == S_OK, "got %08x\n", hr );
923 if (node)
925 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
926 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
927 ok( !memcmp( elem->localName->bytes, "node1", 5), "wrong name\n" );
930 hr = WsReadStartElement( reader, NULL );
931 ok( hr == S_OK, "got %08x\n", hr );
933 hr = WsGetReaderNode( reader, &node, NULL );
934 ok( hr == S_OK, "got %08x\n", hr );
935 if (node)
937 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
938 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
939 ok( !memcmp( elem->localName->bytes, "node2", 5), "wrong name\n" );
942 hr = WsReadNode( reader, NULL );
943 ok( hr == S_OK, "got %08x\n", hr );
945 hr = WsGetReaderNode( reader, &node, NULL );
946 ok( hr == S_OK, "got %08x\n", hr );
947 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
949 hr = WsReadNode( reader, NULL );
950 ok( hr == S_OK, "got %08x\n", hr );
952 hr = WsGetReaderNode( reader, &node, NULL );
953 ok( hr == S_OK, "got %08x\n", hr );
954 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
956 hr = WsReadEndElement( reader, NULL );
957 ok( hr == S_OK, "got %08x\n", hr );
959 hr = WsGetReaderNode( reader, &node, NULL );
960 ok( hr == S_OK, "got %08x\n", hr );
961 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
963 /* WsReadEndElement advances reader to EOF */
964 hr = WsReadEndElement( reader, NULL );
965 ok( hr == S_OK, "got %08x\n", hr );
967 hr = WsGetReaderNode( reader, &node, NULL );
968 ok( hr == S_OK, "got %08x\n", hr );
969 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
971 hr = WsReadEndElement( reader, NULL );
972 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
974 WsFreeReader( reader );
977 static void test_WsReadEndElement(void)
979 HRESULT hr;
980 WS_XML_READER *reader;
981 const WS_XML_NODE *node;
982 int found;
984 hr = WsCreateReader( NULL, 0, &reader, NULL );
985 ok( hr == S_OK, "got %08x\n", hr );
987 hr = set_input( reader, data2, sizeof(data2) - 1 );
988 ok( hr == S_OK, "got %08x\n", hr );
990 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
991 ok( hr == S_OK, "got %08x\n", hr );
993 hr = WsReadEndElement( reader, NULL );
994 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
996 hr = set_input( reader, data2, sizeof(data2) - 1 );
997 ok( hr == S_OK, "got %08x\n", hr );
999 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
1000 ok( hr == S_OK, "got %08x\n", hr );
1002 hr = WsReadNode( reader, NULL );
1003 ok( hr == S_OK, "got %08x\n", hr );
1005 hr = WsGetReaderNode( reader, &node, NULL );
1006 ok( hr == S_OK, "got %08x\n", hr );
1007 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1009 hr = WsReadNode( reader, NULL );
1010 ok( hr == S_OK, "got %08x\n", hr );
1012 hr = WsGetReaderNode( reader, &node, NULL );
1013 ok( hr == S_OK, "got %08x\n", hr );
1014 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
1016 hr = WsReadNode( reader, NULL );
1017 ok( hr == S_OK, "got %08x\n", hr );
1019 hr = WsGetReaderNode( reader, &node, NULL );
1020 ok( hr == S_OK, "got %08x\n", hr );
1021 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1023 hr = WsReadNode( reader, NULL );
1024 ok( hr == S_OK, "got %08x\n", hr );
1026 hr = WsGetReaderNode( reader, &node, NULL );
1027 ok( hr == S_OK, "got %08x\n", hr );
1028 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1030 hr = set_input( reader, data2, sizeof(data2) - 1 );
1031 ok( hr == S_OK, "got %08x\n", hr );
1033 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
1034 ok( hr == S_OK, "got %08x\n", hr );
1036 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1037 ok( hr == S_OK, "got %08x\n", hr );
1039 hr = WsReadStartElement( reader, NULL );
1040 ok( hr == S_OK, "got %08x\n", hr );
1042 hr = WsGetReaderNode( reader, &node, NULL );
1043 ok( hr == S_OK, "got %08x\n", hr );
1044 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
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_END_ELEMENT, "got %u\n", node->nodeType );
1053 /* WsReadEndElement advances reader to EOF */
1054 hr = WsReadEndElement( reader, NULL );
1055 ok( hr == S_OK, "got %08x\n", hr );
1057 hr = WsGetReaderNode( reader, &node, NULL );
1058 ok( hr == S_OK, "got %08x\n", hr );
1059 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1061 hr = WsReadEndElement( reader, NULL );
1062 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1064 hr = set_input( reader, data5, sizeof(data5) - 1 );
1065 ok( hr == S_OK, "got %08x\n", hr );
1067 hr = WsFillReader( reader, sizeof(data5) - 1, NULL, NULL );
1068 ok( hr == S_OK, "got %08x\n", hr );
1070 hr = WsReadEndElement( reader, NULL );
1071 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1073 hr = set_input( reader, data10, sizeof(data10) - 1 );
1074 ok( hr == S_OK, "got %08x\n", hr );
1076 hr = WsFillReader( reader, sizeof(data10) - 1, NULL, NULL );
1077 ok( hr == S_OK, "got %08x\n", hr );
1079 hr = WsReadNode( reader, NULL );
1080 ok( hr == S_OK, "got %08x\n", hr );
1082 hr = WsGetReaderNode( reader, &node, NULL );
1083 ok( hr == S_OK, "got %08x\n", hr );
1084 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1086 hr = WsReadEndElement( reader, NULL );
1087 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1089 hr = set_input( reader, "<a></A>", sizeof("<a></A>") - 1 );
1090 ok( hr == S_OK, "got %08x\n", hr );
1092 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1093 ok( hr == S_OK, "got %08x\n", hr );
1095 found = -1;
1096 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1097 ok( hr == S_OK, "got %08x\n", hr );
1098 ok( found == TRUE, "got %d\n", found );
1100 hr = WsGetReaderNode( reader, &node, NULL );
1101 ok( hr == S_OK, "got %08x\n", hr );
1102 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1104 hr = WsReadEndElement( reader, NULL );
1105 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1107 hr = set_input( reader, "<a></a>", sizeof("<a></a>") - 1 );
1108 ok( hr == S_OK, "got %08x\n", hr );
1110 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1111 ok( hr == S_OK, "got %08x\n", hr );
1113 found = -1;
1114 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1115 ok( hr == S_OK, "got %08x\n", hr );
1116 ok( found == TRUE, "got %d\n", found );
1118 hr = WsGetReaderNode( reader, &node, NULL );
1119 ok( hr == S_OK, "got %08x\n", hr );
1120 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1122 hr = WsReadStartElement( reader, NULL );
1123 ok( hr == S_OK, "got %08x\n", hr );
1125 hr = WsGetReaderNode( reader, &node, NULL );
1126 ok( hr == S_OK, "got %08x\n", hr );
1127 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1129 hr = WsReadEndElement( reader, NULL );
1130 ok( hr == S_OK, "got %08x\n", hr );
1132 hr = WsGetReaderNode( reader, &node, NULL );
1133 ok( hr == S_OK, "got %08x\n", hr );
1134 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1136 hr = set_input( reader, "<a/>", sizeof("<a/>") - 1 );
1137 ok( hr == S_OK, "got %08x\n", hr );
1139 hr = WsFillReader( reader, sizeof("<a/>") - 1, NULL, NULL );
1140 ok( hr == S_OK, "got %08x\n", hr );
1142 found = -1;
1143 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1144 ok( hr == S_OK, "got %08x\n", hr );
1145 ok( found == TRUE, "got %d\n", found );
1147 hr = WsGetReaderNode( reader, &node, NULL );
1148 ok( hr == S_OK, "got %08x\n", hr );
1149 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1151 hr = WsReadStartElement( reader, NULL );
1152 ok( hr == S_OK, "got %08x\n", hr );
1154 hr = WsGetReaderNode( reader, &node, NULL );
1155 ok( hr == S_OK, "got %08x\n", hr );
1156 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1158 hr = WsReadEndElement( reader, NULL );
1159 ok( hr == S_OK, "got %08x\n", hr );
1161 WsFreeReader( reader );
1164 static void test_WsReadNode(void)
1166 static const char str1[] = "<a>";
1167 static const char str2[] = "< a>";
1168 static const char str3[] = "<a >";
1169 static const char str4[] = "<<a>>";
1170 static const char str5[] = "<>";
1171 static const char str6[] = "</a>";
1172 static const char str7[] = " <a>";
1173 static const char str8[] = "<?xml>";
1174 static const char str9[] = "<?xml?>";
1175 static const char str10[] = "<?xml ?>";
1176 static const char str11[] = "<?xml version=\"1.0\"?>";
1177 static const char str12[] = "<text>test</text>";
1178 static const char str13[] = "<?xml version=\"1.0\"?><text>test</text>";
1179 static const char str14[] = "";
1180 static const char str15[] = "<!--";
1181 static const char str16[] = "<!---->";
1182 static const char str17[] = "<!--comment-->";
1183 HRESULT hr;
1184 WS_XML_READER *reader;
1185 const WS_XML_NODE *node;
1186 unsigned int i;
1187 int found;
1188 static const struct
1190 const char *text;
1191 HRESULT hr;
1192 WS_XML_NODE_TYPE type;
1193 int todo;
1195 tests[] =
1197 { str1, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1198 { str2, WS_E_INVALID_FORMAT, 0 },
1199 { str3, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1200 { str4, WS_E_INVALID_FORMAT, 0 },
1201 { str5, WS_E_INVALID_FORMAT, 0 },
1202 { str6, WS_E_INVALID_FORMAT, 0 },
1203 { str7, S_OK, WS_XML_NODE_TYPE_TEXT },
1204 { str8, WS_E_INVALID_FORMAT, 0 },
1205 { str9, WS_E_INVALID_FORMAT, 0 },
1206 { str10, WS_E_INVALID_FORMAT, 0, 1 },
1207 { str11, S_OK, WS_XML_NODE_TYPE_EOF },
1208 { str12, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1209 { str13, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1210 { str14, WS_E_INVALID_FORMAT, 0, 1 },
1211 { str15, WS_E_INVALID_FORMAT, 0 },
1212 { str16, S_OK, WS_XML_NODE_TYPE_COMMENT },
1213 { str17, S_OK, WS_XML_NODE_TYPE_COMMENT },
1216 hr = WsCreateReader( NULL, 0, &reader, NULL );
1217 ok( hr == S_OK, "got %08x\n", hr );
1219 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
1221 hr = set_input( reader, tests[i].text, strlen(tests[i].text) );
1222 ok( hr == S_OK, "got %08x\n", hr );
1224 hr = WsFillReader( reader, strlen(tests[i].text), NULL, NULL );
1225 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1227 hr = WsReadNode( reader, NULL );
1228 todo_wine_if (tests[i].todo)
1229 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
1230 if (hr == S_OK)
1232 node = NULL;
1233 hr = WsGetReaderNode( reader, &node, NULL );
1234 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1235 ok( node != NULL, "%u: node not set\n", i );
1236 if (node)
1238 todo_wine_if (tests[i].todo)
1239 ok( node->nodeType == tests[i].type, "%u: got %u\n", i, node->nodeType );
1244 hr = set_input( reader, data6, sizeof(data6) - 1 );
1245 ok( hr == S_OK, "got %08x\n", hr );
1247 hr = WsFillReader( reader, sizeof(data6) - 1, NULL, NULL );
1248 ok( hr == S_OK, "got %08x\n", hr );
1250 found = -1;
1251 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1252 ok( hr == S_OK, "got %08x\n", hr );
1253 ok( found == TRUE, "got %d\n", found );
1255 hr = WsGetReaderNode( reader, &node, NULL );
1256 ok( hr == S_OK, "got %08x\n", hr );
1257 if (node)
1259 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
1260 WS_XML_ATTRIBUTE *attr;
1261 WS_XML_UTF8_TEXT *text;
1263 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1264 ok( elem->prefix != NULL, "prefix not set\n" );
1265 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
1266 ok( elem->prefix->bytes == NULL, "bytes set\n" );
1267 ok( elem->localName != NULL, "localName not set\n" );
1268 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
1269 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
1270 ok( elem->ns != NULL, "ns not set\n" );
1271 ok( !elem->ns->length, "got %u\n", elem->ns->length );
1272 ok( elem->ns->bytes != NULL, "bytes not set\n" );
1273 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
1274 ok( elem->attributes != NULL, "attributes not set\n" );
1275 ok( !elem->isEmpty, "isEmpty not zero\n" );
1277 attr = elem->attributes[0];
1278 ok( !attr->singleQuote, "got %u\n", attr->singleQuote );
1279 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1280 ok( attr->prefix != NULL, "prefix not set\n" );
1281 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1282 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1283 ok( attr->localName != NULL, "localName not set\n" );
1284 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
1285 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
1286 ok( attr->ns != NULL, "ns not set\n" );
1287 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1288 ok( attr->ns->bytes == NULL, "bytes set\n" );
1289 ok( attr->value != NULL, "value not set\n" );
1291 text = (WS_XML_UTF8_TEXT *)attr->value;
1292 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1293 ok( text->value.length == 5, "got %u\n", text->value.length );
1294 ok( !memcmp( text->value.bytes, "value", 5 ), "wrong data\n" );
1296 attr = elem->attributes[1];
1297 ok( attr->singleQuote == 1, "got %u\n", attr->singleQuote );
1298 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1299 ok( attr->prefix != NULL, "prefix not set\n" );
1300 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1301 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1302 ok( attr->localName != NULL, "localName not set\n" );
1303 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
1304 ok( !memcmp( attr->localName->bytes, "attr2", 5 ), "wrong data\n" );
1305 ok( attr->ns != NULL, "ns not set\n" );
1306 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1307 ok( attr->ns->bytes == NULL, "bytes set\n" );
1308 ok( attr->value != NULL, "value not set\n" );
1310 text = (WS_XML_UTF8_TEXT *)attr->value;
1311 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1312 ok( text->value.length == 6, "got %u\n", text->value.length );
1313 ok( !memcmp( text->value.bytes, "value2", 6 ), "wrong data\n" );
1316 hr = set_input( reader, data7, sizeof(data7) - 1 );
1317 ok( hr == S_OK, "got %08x\n", hr );
1319 hr = WsFillReader( reader, sizeof(data7) - 1, NULL, NULL );
1320 ok( hr == S_OK, "got %08x\n", hr );
1322 hr = WsReadNode( reader, NULL );
1323 ok( hr == S_OK, "got %08x\n", hr );
1325 hr = WsGetReaderNode( reader, &node, NULL );
1326 ok( hr == S_OK, "got %08x\n", hr );
1327 if (node)
1329 WS_XML_COMMENT_NODE *comment = (WS_XML_COMMENT_NODE *)node;
1331 ok( comment->node.nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", comment->node.nodeType );
1332 ok( comment->value.length == 9, "got %u\n", comment->value.length );
1333 ok( !memcmp( comment->value.bytes, " comment ", 9 ), "wrong data\n" );
1336 WsFreeReader( reader );
1339 static void prepare_type_test( WS_XML_READER *reader, const char *data, ULONG size )
1341 HRESULT hr;
1343 hr = set_input( reader, data, size );
1344 ok( hr == S_OK, "got %08x\n", hr );
1346 hr = WsFillReader( reader, size, NULL, NULL );
1347 ok( hr == S_OK, "got %08x\n", hr );
1349 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1350 ok( hr == S_OK, "got %08x\n", hr );
1352 hr = WsReadStartElement( reader, NULL );
1353 ok( hr == S_OK, "got %08x\n", hr );
1356 static void test_WsReadType(void)
1358 static const WCHAR testW[] = {'t','e','s','t',0};
1359 static const GUID guid1 = {0,0,0,{0,0,0,0,0,0,0,0}};
1360 static const GUID guid2 = {0,0,0,{0,0,0,0,0,0,0,0xa1}};
1361 static const char utf8[] = {'<','t','>',0xe2,0x80,0x99,'<','/','t','>'};
1362 static const WCHAR utf8W[] = {0x2019,0};
1363 HRESULT hr;
1364 WS_XML_READER *reader;
1365 WS_HEAP *heap;
1366 enum { ONE = 1, TWO = 2 };
1367 WS_XML_STRING one = { 3, (BYTE *)"ONE" };
1368 WS_XML_STRING two = { 3, (BYTE *)"TWO" };
1369 WS_ENUM_VALUE enum_values[] = { { ONE, &one }, { TWO, &two } };
1370 WS_ENUM_DESCRIPTION enum_desc;
1371 int val_enum;
1372 WCHAR *val_str;
1373 BOOL val_bool;
1374 INT8 val_int8;
1375 INT16 val_int16;
1376 INT32 val_int32;
1377 INT64 val_int64;
1378 UINT8 val_uint8;
1379 UINT16 val_uint16;
1380 UINT32 val_uint32;
1381 UINT64 val_uint64;
1382 GUID val_guid;
1383 WS_BYTES val_bytes;
1385 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1386 ok( hr == S_OK, "got %08x\n", hr );
1388 hr = WsCreateReader( NULL, 0, &reader, NULL );
1389 ok( hr == S_OK, "got %08x\n", hr );
1391 prepare_type_test( reader, data2, sizeof(data2) - 1 );
1392 hr = WsReadType( NULL, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1393 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1394 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1396 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1397 WS_READ_REQUIRED_POINTER, heap, &val_str, 0, NULL );
1398 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1400 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1401 WS_READ_REQUIRED_POINTER, heap, NULL, sizeof(val_str), NULL );
1402 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1404 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1405 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str) + 1, NULL );
1406 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1408 val_str = NULL;
1409 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1410 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1411 ok( hr == S_OK, "got %08x\n", hr );
1412 ok( val_str != NULL, "pointer not set\n" );
1413 if (val_str) ok( !lstrcmpW( val_str, testW ), "wrong data\n" );
1415 val_bool = -1;
1416 prepare_type_test( reader, "<t>true</t>", sizeof("<t>true</t>") - 1 );
1417 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1418 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1419 ok( hr == S_OK, "got %08x\n", hr );
1420 ok( val_bool == TRUE, "got %d\n", val_bool );
1422 val_bool = -1;
1423 prepare_type_test( reader, "<t>false</t>", sizeof("<t>false</t>") - 1 );
1424 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1425 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1426 ok( hr == S_OK, "got %08x\n", hr );
1427 ok( val_bool == FALSE, "got %d\n", val_bool );
1429 val_bool = -1;
1430 prepare_type_test( reader, "<t>FALSE</t>", sizeof("<t>FALSE</t>") - 1 );
1431 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1432 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1433 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1434 ok( val_bool == -1, "got %d\n", val_bool );
1436 val_bool = -1;
1437 prepare_type_test( reader, "<t>1</t>", sizeof("<t>1</t>") - 1 );
1438 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1439 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1440 ok( hr == S_OK, "got %08x\n", hr );
1441 ok( val_bool == TRUE, "got %d\n", val_bool );
1443 val_bool = -1;
1444 prepare_type_test( reader, "<t>2</t>", sizeof("<t>2</t>") - 1 );
1445 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1446 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1447 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1448 ok( val_bool == -1, "got %d\n", val_bool );
1450 val_bool = -1;
1451 prepare_type_test( reader, "<t>0</t>", sizeof("<t>0</t>") - 1 );
1452 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1453 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1454 ok( hr == S_OK, "got %08x\n", hr );
1455 ok( val_bool == FALSE, "got %d\n", val_bool );
1457 val_int8 = 0;
1458 prepare_type_test( reader, "<t>-128</t>", sizeof("<t>-128</t>") - 1 );
1459 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1460 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1461 ok( hr == S_OK, "got %08x\n", hr );
1462 ok( val_int8 == -128, "got %d\n", val_int8 );
1464 val_int8 = 0;
1465 prepare_type_test( reader, "<t> </t>", sizeof("<t> </t>") - 1 );
1466 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1467 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1468 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1469 ok( !val_int8, "got %d\n", val_int8 );
1471 val_int8 = 0;
1472 prepare_type_test( reader, "<t>-</t>", sizeof("<t>-</t>") - 1 );
1473 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1474 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1475 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1476 ok( !val_int8, "got %d\n", val_int8 );
1478 val_int8 = -1;
1479 prepare_type_test( reader, "<t>-0</t>", sizeof("<t>-0</t>") - 1 );
1480 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1481 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1482 ok( hr == S_OK, "got %08x\n", hr );
1483 ok( !val_int8, "got %d\n", val_int8 );
1485 val_int8 = 0;
1486 prepare_type_test( reader, "<t>-129</t>", sizeof("<t>-129</t>") - 1 );
1487 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1488 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1489 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1490 ok( !val_int8, "got %d\n", val_int8 );
1492 val_int16 = 0;
1493 prepare_type_test( reader, "<t>-32768</t>", sizeof("<t>-32768</t>") - 1 );
1494 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1495 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1496 ok( hr == S_OK, "got %08x\n", hr );
1497 ok( val_int16 == -32768, "got %d\n", val_int16 );
1499 val_int16 = 0;
1500 prepare_type_test( reader, "<t>-32769</t>", sizeof("<t>-32769</t>") - 1 );
1501 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1502 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1503 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1504 ok( !val_int16, "got %d\n", val_int16 );
1506 val_int32 = 0;
1507 prepare_type_test( reader, "<t>-2147483648</t>", sizeof("<t>-2147483648</t>") - 1 );
1508 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1509 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1510 ok( hr == S_OK, "got %08x\n", hr );
1511 ok( val_int32 == -2147483647 - 1, "got %d\n", val_int32 );
1513 val_int32 = 0;
1514 prepare_type_test( reader, "<t>-2147483649</t>", sizeof("<t>-2147483649</t>") - 1 );
1515 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1516 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1517 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1518 ok( !val_int32, "got %d\n", val_int32 );
1520 val_int64 = 0;
1521 prepare_type_test( reader, "<t>-9223372036854775808</t>", sizeof("<t>-9223372036854775808</t>") - 1 );
1522 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1523 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1524 ok( hr == S_OK, "got %08x\n", hr );
1525 ok( val_int64 == -9223372036854775807 - 1, "wrong value\n" );
1527 val_int64 = 0;
1528 prepare_type_test( reader, "<t>-9223372036854775809</t>", sizeof("<t>-9223372036854775809</t>") - 1 );
1529 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1530 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1531 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1532 ok( !val_int64, "wrong value\n" );
1534 val_uint8 = 0;
1535 prepare_type_test( reader, "<t> 255 </t>", sizeof("<t> 255 </t>") - 1 );
1536 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1537 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1538 ok( hr == S_OK, "got %08x\n", hr );
1539 ok( val_uint8 == 255, "got %u\n", val_uint8 );
1541 val_uint8 = 0;
1542 prepare_type_test( reader, "<t>+255</t>", sizeof("<t>+255</t>") - 1 );
1543 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1544 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1545 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1546 ok( !val_uint8, "got %u\n", val_uint8 );
1548 val_uint8 = 0;
1549 prepare_type_test( reader, "<t>-255</t>", sizeof("<t>-255</t>") - 1 );
1550 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1551 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1552 todo_wine ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1553 ok( !val_uint8, "got %u\n", val_uint8 );
1555 val_uint8 = 0;
1556 prepare_type_test( reader, "<t>0xff</t>", sizeof("<t>0xff</t>") - 1 );
1557 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1558 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1559 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1560 ok( !val_uint8, "got %u\n", val_uint8 );
1562 val_uint8 = 0;
1563 prepare_type_test( reader, "<t>256</t>", sizeof("<t>256</t>") - 1 );
1564 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1565 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1566 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1567 ok( !val_uint8, "got %u\n", val_uint8 );
1569 val_uint16 = 0;
1570 prepare_type_test( reader, "<t>65535</t>", sizeof("<t>65535</t>") - 1 );
1571 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1572 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1573 ok( hr == S_OK, "got %08x\n", hr );
1574 ok( val_uint16 == 65535, "got %u\n", val_uint16 );
1576 val_uint16 = 0;
1577 prepare_type_test( reader, "<t>65536</t>", sizeof("<t>65536</t>") - 1 );
1578 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1579 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1580 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1581 ok( !val_uint16, "got %u\n", val_uint16 );
1583 val_uint32 = 0;
1584 prepare_type_test( reader, "<t>4294967295</t>", sizeof("<t>4294967295</t>") - 1 );
1585 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1586 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1587 ok( hr == S_OK, "got %08x\n", hr );
1588 ok( val_uint32 == ~0, "got %u\n", val_uint32 );
1590 val_uint32 = 0;
1591 prepare_type_test( reader, "<t>4294967296</t>", sizeof("<t>4294967296</t>") - 1 );
1592 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1593 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1594 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1595 ok( !val_uint32, "got %u\n", val_uint32 );
1597 val_uint64 = 0;
1598 prepare_type_test( reader, "<t>18446744073709551615</t>", sizeof("<t>18446744073709551615</t>") - 1 );
1599 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1600 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1601 ok( hr == S_OK, "got %08x\n", hr );
1602 ok( val_uint64 == ~0, "wrong value\n" );
1604 val_uint64 = 0;
1605 prepare_type_test( reader, "<t>18446744073709551616</t>", sizeof("<t>18446744073709551616</t>") - 1 );
1606 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1607 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1608 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1609 ok( !val_uint64, "wrong value\n" );
1611 enum_desc.values = enum_values;
1612 enum_desc.valueCount = sizeof(enum_values)/sizeof(enum_values[0]);
1613 enum_desc.maxByteCount = 3;
1614 enum_desc.nameIndices = NULL;
1616 val_enum = 0;
1617 prepare_type_test( reader, "<t>ONE</t>", sizeof("<t>ONE</t>") - 1 );
1618 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1619 WS_READ_REQUIRED_VALUE, heap, &val_enum, sizeof(val_enum), NULL );
1620 ok( hr == S_OK, "got %08x\n", hr );
1621 ok( val_enum == 1, "got %d\n", val_enum );
1623 prepare_type_test( reader, "<t>{00000000-0000-0000-0000-000000000000}</t>",
1624 sizeof("<t>{00000000-0000-0000-0000-000000000000}</t>") - 1 );
1625 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1626 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1627 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1629 memset( &val_guid, 0xff, sizeof(val_guid) );
1630 prepare_type_test( reader, "<t> 00000000-0000-0000-0000-000000000000 </t>",
1631 sizeof("<t> 00000000-0000-0000-0000-000000000000 </t>") - 1 );
1632 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1633 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1634 ok( hr == S_OK, "got %08x\n", hr );
1635 ok( IsEqualGUID( &val_guid, &guid1 ), "wrong guid\n" );
1637 memset( &val_guid, 0, sizeof(val_guid) );
1638 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000a1</t>",
1639 sizeof("<t>00000000-0000-0000-0000-0000000000a1</t>") - 1 );
1640 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1641 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1642 ok( hr == S_OK, "got %08x\n", hr );
1643 ok( IsEqualGUID( &val_guid, &guid2 ), "wrong guid\n" );
1645 memset( &val_guid, 0, sizeof(val_guid) );
1646 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000A1</t>",
1647 sizeof("<t>00000000-0000-0000-0000-0000000000A1</t>") - 1 );
1648 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1649 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1650 ok( hr == S_OK, "got %08x\n", hr );
1651 ok( IsEqualGUID( &val_guid, &guid2 ), "wrong guid\n" );
1653 memset( &val_bytes, 0, sizeof(val_bytes) );
1654 prepare_type_test( reader, "<t>dGVzdA==</t>", sizeof("<t>dGVzdA==</t>") - 1 );
1655 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1656 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1657 ok( hr == S_OK, "got %08x\n", hr );
1658 ok( val_bytes.length == 4, "got %u\n", val_bytes.length );
1659 ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" );
1661 memset( &val_bytes, 0, sizeof(val_bytes) );
1662 prepare_type_test( reader, "<t> dGVzdA== </t>", sizeof("<t> dGVzdA== </t>") - 1 );
1663 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1664 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1665 ok( hr == S_OK, "got %08x\n", hr );
1666 ok( val_bytes.length == 4, "got %u\n", val_bytes.length );
1667 ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" );
1669 prepare_type_test( reader, "<t>dGVzdA===</t>", sizeof("<t>dGVzdA===</t>") - 1 );
1670 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1671 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1672 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1674 val_str = NULL;
1675 prepare_type_test( reader, utf8, sizeof(utf8) );
1676 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1677 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1678 ok( hr == S_OK, "got %08x\n", hr );
1679 ok( val_str != NULL, "pointer not set\n" );
1680 if (val_str) ok( !lstrcmpW( val_str, utf8W ), "wrong data %s\n", wine_dbgstr_w(val_str) );
1682 WsFreeReader( reader );
1683 WsFreeHeap( heap );
1686 static void test_WsGetXmlAttribute(void)
1688 static const WCHAR valueW[] = {'v','a','l','u','e',0};
1689 HRESULT hr;
1690 WS_XML_READER *reader;
1691 WS_XML_STRING xmlstr;
1692 WS_HEAP *heap;
1693 WCHAR *str;
1694 ULONG count;
1695 int found;
1697 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1698 ok( hr == S_OK, "got %08x\n", hr );
1700 hr = WsCreateReader( NULL, 0, &reader, NULL );
1701 ok( hr == S_OK, "got %08x\n", hr );
1703 hr = set_input( reader, data9, sizeof(data9) - 1 );
1704 ok( hr == S_OK, "got %08x\n", hr );
1706 hr = WsFillReader( reader, sizeof(data9) - 1, NULL, NULL );
1707 ok( hr == S_OK, "got %08x\n", hr );
1709 found = -1;
1710 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1711 ok( hr == S_OK, "got %08x\n", hr );
1712 ok( found == TRUE, "got %d\n", found );
1714 xmlstr.bytes = (BYTE *)"attr";
1715 xmlstr.length = sizeof("attr") - 1;
1716 xmlstr.dictionary = NULL;
1717 xmlstr.id = 0;
1718 str = NULL;
1719 count = 0;
1720 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1721 todo_wine ok( hr == S_OK, "got %08x\n", hr );
1722 todo_wine ok( str != NULL, "str not set\n" );
1723 todo_wine ok( count == 5, "got %u\n", count );
1724 /* string is not null-terminated */
1725 if (str) ok( !memcmp( str, valueW, count * sizeof(WCHAR) ), "wrong data\n" );
1727 xmlstr.bytes = (BYTE *)"none";
1728 xmlstr.length = sizeof("none") - 1;
1729 xmlstr.dictionary = NULL;
1730 xmlstr.id = 0;
1731 str = (WCHAR *)0xdeadbeef;
1732 count = 0xdeadbeef;
1733 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1734 todo_wine ok( hr == S_FALSE, "got %08x\n", hr );
1735 todo_wine ok( str == NULL, "str not set\n" );
1736 todo_wine ok( !count, "got %u\n", count );
1738 WsFreeReader( reader );
1739 WsFreeHeap( heap );
1742 static void test_WsXmlStringEquals(void)
1744 BYTE bom[] = {0xef,0xbb,0xbf};
1745 WS_XML_STRING str1 = {0, NULL}, str2 = {0, NULL};
1746 HRESULT hr;
1748 hr = WsXmlStringEquals( NULL, NULL, NULL );
1749 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1751 hr = WsXmlStringEquals( &str1, NULL, NULL );
1752 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1754 hr = WsXmlStringEquals( NULL, &str2, NULL );
1755 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1757 hr = WsXmlStringEquals( &str1, &str2, NULL );
1758 ok( hr == S_OK, "got %08x\n", hr );
1760 str1.length = 1;
1761 str1.bytes = (BYTE *)"a";
1762 hr = WsXmlStringEquals( &str1, &str1, NULL );
1763 ok( hr == S_OK, "got %08x\n", hr );
1765 str2.length = 1;
1766 str2.bytes = (BYTE *)"b";
1767 hr = WsXmlStringEquals( &str1, &str2, NULL );
1768 ok( hr == S_FALSE, "got %08x\n", hr );
1770 str2.length = 1;
1771 str2.bytes = bom;
1772 hr = WsXmlStringEquals( &str1, &str2, NULL );
1773 ok( hr == S_FALSE, "got %08x\n", hr );
1775 str1.length = 3;
1776 hr = WsXmlStringEquals( &str1, &str2, NULL );
1777 ok( hr == S_FALSE, "got %08x\n", hr );
1779 str2.length = 3;
1780 hr = WsXmlStringEquals( &str1, &str2, NULL );
1781 ok( hr == S_FALSE, "got %08x\n", hr );
1783 str1.length = 3;
1784 str1.bytes = bom;
1785 hr = WsXmlStringEquals( &str1, &str2, NULL );
1786 ok( hr == S_OK, "got %08x\n", hr );
1789 static void test_WsAlloc(void)
1791 HRESULT hr;
1792 WS_HEAP *heap;
1793 void *ptr;
1794 SIZE_T requested, actual;
1795 ULONG size;
1797 hr = WsCreateHeap( 256, 0, NULL, 0, &heap, NULL );
1798 ok( hr == S_OK, "got %08x\n", hr );
1800 ptr = (void *)0xdeadbeef;
1801 hr = WsAlloc( NULL, 16, &ptr, NULL );
1802 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1803 ok( ptr == (void *)0xdeadbeef, "ptr set\n" );
1805 ptr = (void *)0xdeadbeef;
1806 hr = WsAlloc( heap, 512, &ptr, NULL );
1807 ok( hr == WS_E_QUOTA_EXCEEDED, "got %08x\n", hr );
1808 ok( ptr == (void *)0xdeadbeef, "ptr set\n" );
1810 ptr = NULL;
1811 hr = WsAlloc( heap, 16, &ptr, NULL );
1812 ok( hr == S_OK, "got %08x\n", hr );
1813 ok( ptr != NULL, "ptr not set\n" );
1815 requested = 0xdeadbeef;
1816 size = sizeof(requested);
1817 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
1818 ok( hr == S_OK, "got %08x\n", hr );
1819 ok( requested == 16, "got %u\n", (ULONG)requested );
1821 actual = 0xdeadbeef;
1822 size = sizeof(actual);
1823 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
1824 ok( hr == S_OK, "got %08x\n", hr );
1825 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
1827 WsFreeHeap( heap );
1830 static void test_WsMoveReader(void)
1832 HRESULT hr;
1833 WS_HEAP *heap;
1834 WS_XML_READER *reader;
1835 WS_XML_WRITER *writer;
1836 WS_XML_BUFFER *buffer;
1837 WS_XML_STRING localname = {1, (BYTE *)"a"}, localname2 = {1, (BYTE *)"b"}, ns = {0, NULL};
1838 const WS_XML_NODE *node;
1839 WS_XML_ELEMENT_NODE *elem;
1840 WS_XML_UTF8_TEXT utf8;
1842 hr = WsCreateReader( NULL, 0, &reader, NULL );
1843 ok( hr == S_OK, "got %08x\n", hr );
1845 hr = WsMoveReader( NULL, WS_MOVE_TO_EOF, NULL, NULL );
1846 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1848 /* reader must be set to an XML buffer */
1849 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1850 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1852 hr = set_input( reader, data8, sizeof(data8) - 1 );
1853 ok( hr == S_OK, "got %08x\n", hr );
1855 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1856 todo_wine ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1857 WsFreeReader( reader );
1859 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1860 ok( hr == S_OK, "got %08x\n", hr );
1862 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
1863 ok( hr == S_OK, "got %08x\n", hr );
1865 hr = WsCreateWriter( NULL, 0, &writer, NULL );
1866 ok( hr == S_OK, "got %08x\n", hr );
1868 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
1869 ok( hr == S_OK, "got %08x\n", hr );
1871 /* <a><b/></a> */
1872 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
1873 ok( hr == S_OK, "got %08x\n", hr );
1875 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
1876 ok( hr == S_OK, "got %08x\n", hr );
1878 hr = WsWriteEndElement( writer, NULL );
1879 ok( hr == S_OK, "got %08x\n", hr );
1881 hr = WsWriteEndElement( writer, NULL );
1882 ok( hr == S_OK, "got %08x\n", hr );
1884 hr = WsCreateReader( NULL, 0, &reader, NULL );
1885 ok( hr == S_OK, "got %08x\n", hr );
1887 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1888 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1890 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
1891 ok( hr == S_OK, "got %08x\n", hr );
1893 /* first element is child node of BOF node */
1894 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
1895 ok( hr == S_OK, "got %08x\n", hr );
1897 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1898 ok( hr == S_OK, "got %08x\n", hr );
1900 hr = WsGetReaderNode( reader, &node, NULL );
1901 ok( hr == S_OK, "got %08x\n", hr );
1902 elem = (WS_XML_ELEMENT_NODE *)node;
1903 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1904 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1905 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1907 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1908 ok( hr == S_OK, "got %08x\n", hr );
1910 hr = WsGetReaderNode( reader, &node, NULL );
1911 ok( hr == S_OK, "got %08x\n", hr );
1912 elem = (WS_XML_ELEMENT_NODE *)node;
1913 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1914 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1915 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1917 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1918 ok( hr == S_OK, "got %08x\n", hr );
1920 hr = WsGetReaderNode( reader, &node, NULL );
1921 ok( hr == S_OK, "got %08x\n", hr );
1922 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1924 /* EOF node is last child of BOF node */
1925 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
1926 ok( hr == S_OK, "got %08x\n", hr );
1928 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1929 ok( hr == S_OK, "got %08x\n", hr );
1931 hr = WsGetReaderNode( reader, &node, NULL );
1932 ok( hr == S_OK, "got %08x\n", hr );
1933 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1935 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1936 ok( hr == S_OK, "got %08x\n", hr );
1938 hr = WsGetReaderNode( reader, &node, NULL );
1939 ok( hr == S_OK, "got %08x\n", hr );
1940 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1942 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
1943 ok( hr == S_OK, "got %08x\n", hr );
1945 hr = WsGetReaderNode( reader, &node, NULL );
1946 ok( hr == S_OK, "got %08x\n", hr );
1947 elem = (WS_XML_ELEMENT_NODE *)node;
1948 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1949 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1950 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1952 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_ELEMENT, NULL, NULL );
1953 ok( hr == S_OK, "got %08x\n", hr );
1955 hr = WsGetReaderNode( reader, &node, NULL );
1956 ok( hr == S_OK, "got %08x\n", hr );
1957 elem = (WS_XML_ELEMENT_NODE *)node;
1958 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1959 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1960 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1962 hr = WsMoveReader( reader, WS_MOVE_TO_END_ELEMENT, NULL, NULL );
1963 ok( hr == S_OK, "got %08x\n", hr );
1965 hr = WsGetReaderNode( reader, &node, NULL );
1966 ok( hr == S_OK, "got %08x\n", hr );
1967 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1969 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1970 ok( hr == S_OK, "got %08x\n", hr );
1972 hr = WsGetReaderNode( reader, &node, NULL );
1973 ok( hr == S_OK, "got %08x\n", hr );
1974 elem = (WS_XML_ELEMENT_NODE *)node;
1975 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1976 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1977 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1979 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1980 ok( hr == S_OK, "got %08x\n", hr );
1982 hr = WsGetReaderNode( reader, &node, NULL );
1983 ok( hr == S_OK, "got %08x\n", hr );
1984 elem = (WS_XML_ELEMENT_NODE *)node;
1985 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1986 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1987 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1989 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1990 ok( hr == S_OK, "got %08x\n", hr );
1992 hr = WsGetReaderNode( reader, &node, NULL );
1993 ok( hr == S_OK, "got %08x\n", hr );
1994 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
1996 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1997 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1999 WsFreeWriter( writer );
2000 WsFreeHeap( heap );
2002 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2003 ok( hr == S_OK, "got %08x\n", hr );
2005 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
2006 ok( hr == S_OK, "got %08x\n", hr );
2008 hr = WsCreateWriter( NULL, 0, &writer, NULL );
2009 ok( hr == S_OK, "got %08x\n", hr );
2011 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
2012 ok( hr == S_OK, "got %08x\n", hr );
2014 /* <a><b>test</b></a> */
2015 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
2016 ok( hr == S_OK, "got %08x\n", hr );
2018 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
2019 ok( hr == S_OK, "got %08x\n", hr );
2021 utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
2022 utf8.value.bytes = (BYTE *)"test";
2023 utf8.value.length = sizeof("test") - 1;
2024 hr = WsWriteText( writer, &utf8.text, NULL );
2025 ok( hr == S_OK, "got %08x\n", hr );
2027 hr = WsWriteEndElement( writer, NULL );
2028 ok( hr == S_OK, "got %08x\n", hr );
2030 hr = WsWriteEndElement( writer, NULL );
2031 ok( hr == S_OK, "got %08x\n", hr );
2033 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
2034 ok( hr == S_OK, "got %08x\n", hr );
2036 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2037 ok( hr == S_OK, "got %08x\n", hr );
2039 hr = WsGetReaderNode( reader, &node, NULL );
2040 ok( hr == S_OK, "got %08x\n", hr );
2041 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2043 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2044 ok( hr == S_OK, "got %08x\n", hr );
2046 hr = WsGetReaderNode( reader, &node, NULL );
2047 ok( hr == S_OK, "got %08x\n", hr );
2048 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2050 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2051 ok( hr == S_OK, "got %08x\n", hr );
2053 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2054 ok( hr == S_OK, "got %08x\n", hr );
2056 hr = WsGetReaderNode( reader, &node, NULL );
2057 ok( hr == S_OK, "got %08x\n", hr );
2058 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2060 hr = WsGetReaderNode( reader, &node, NULL );
2061 ok( hr == S_OK, "got %08x\n", hr );
2062 elem = (WS_XML_ELEMENT_NODE *)node;
2063 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2064 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
2065 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2067 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2068 ok( hr == S_OK, "got %08x\n", hr );
2070 hr = WsGetReaderNode( reader, &node, NULL );
2071 ok( hr == S_OK, "got %08x\n", hr );
2072 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2074 WsFreeReader( reader );
2075 WsFreeWriter( writer );
2076 WsFreeHeap( heap );
2079 static void prepare_struct_type_test( WS_XML_READER *reader, const char *data )
2081 HRESULT hr;
2082 ULONG size = strlen( data );
2084 hr = set_input( reader, data, size );
2085 ok( hr == S_OK, "got %08x\n", hr );
2087 hr = WsFillReader( reader, size, NULL, NULL );
2088 ok( hr == S_OK, "got %08x\n", hr );
2091 static void test_simple_struct_type(void)
2093 static const WCHAR testW[] = {'t','e','s','t',0};
2094 HRESULT hr;
2095 WS_XML_READER *reader;
2096 WS_HEAP *heap;
2097 WS_STRUCT_DESCRIPTION s;
2098 WS_FIELD_DESCRIPTION f, *fields[1];
2099 WS_XML_STRING ns = {0, NULL}, localname = {3, (BYTE *)"str"};
2100 WS_XML_STRING localname2 = {4, (BYTE *)"test"};
2101 const WS_XML_NODE *node;
2102 const WS_XML_ELEMENT_NODE *elem;
2103 struct test { WCHAR *str; } *test;
2105 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2106 ok( hr == S_OK, "got %08x\n", hr );
2108 hr = WsCreateReader( NULL, 0, &reader, NULL );
2109 ok( hr == S_OK, "got %08x\n", hr );
2111 prepare_struct_type_test( reader, "<str>test</str>" );
2112 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL,
2113 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2114 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2116 hr = WsGetReaderNode( reader, &node, NULL );
2117 ok( hr == S_OK, "got %08x\n", hr );
2118 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
2120 /* element field mapping */
2121 memset( &f, 0, sizeof(f) );
2122 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2123 f.localName = &localname;
2124 f.ns = &ns;
2125 f.type = WS_WSZ_TYPE;
2126 fields[0] = &f;
2128 memset( &s, 0, sizeof(s) );
2129 s.size = sizeof(struct test);
2130 s.alignment = TYPE_ALIGNMENT(struct test);
2131 s.fields = fields;
2132 s.fieldCount = 1;
2133 s.typeLocalName = &localname2;
2134 s.typeNs = &ns;
2136 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2137 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2138 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2139 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2141 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2142 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2143 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2144 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2146 s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
2147 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2148 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2149 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2150 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2151 s.structOptions = 0;
2153 test = NULL;
2154 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str>" );
2155 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2156 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2157 ok( hr == S_OK, "got %08x\n", hr );
2158 ok( test != NULL, "test not set\n" );
2159 if (test)
2161 ok( test->str != NULL, "str not set\n" );
2162 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2165 hr = WsGetReaderNode( reader, &node, NULL );
2166 ok( hr == S_OK, "got %08x\n", hr );
2167 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2169 test = NULL;
2170 prepare_struct_type_test( reader, "<str>test</str>" );
2171 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2172 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2173 ok( hr == S_OK, "got %08x\n", hr );
2174 ok( test != NULL, "test not set\n" );
2175 if (test)
2177 ok( test->str != NULL, "str not set\n" );
2178 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2181 hr = WsGetReaderNode( reader, &node, NULL );
2182 ok( hr == S_OK, "got %08x\n", hr );
2183 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2185 test = NULL;
2186 prepare_struct_type_test( reader, "<str>test</str>" );
2187 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2188 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2189 ok( hr == S_OK, "got %08x\n", hr );
2190 ok( test != NULL, "test not set\n" );
2191 if (test)
2193 ok( test->str != NULL, "str not set\n" );
2194 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2197 hr = WsGetReaderNode( reader, &node, NULL );
2198 ok( hr == S_OK, "got %08x\n", hr );
2199 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2201 prepare_struct_type_test( reader, "<str>test</str>" );
2202 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2203 ok( hr == S_OK, "got %08x\n", hr );
2205 hr = WsGetReaderNode( reader, &node, NULL );
2206 ok( hr == S_OK, "got %08x\n", hr );
2207 elem = (const WS_XML_ELEMENT_NODE *)node;
2208 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2209 ok( elem->localName->length == 3, "got %u\n", elem->localName->length );
2210 ok( !memcmp( elem->localName->bytes, "str", 3 ), "wrong data\n" );
2212 test = NULL;
2213 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2214 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2215 ok( hr == S_OK, "got %08x\n", hr );
2216 ok( test != NULL, "test not set\n" );
2217 if (test)
2219 ok( test->str != NULL, "str not set\n" );
2220 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2223 hr = WsGetReaderNode( reader, &node, NULL );
2224 ok( hr == S_OK, "got %08x\n", hr );
2225 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2227 /* attribute field mapping */
2228 f.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2230 test = NULL;
2231 prepare_struct_type_test( reader, "<test str=\"test\"/>" );
2232 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2233 ok( hr == S_OK, "got %08x\n", hr );
2235 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2236 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2237 ok( hr == S_OK, "got %08x\n", hr );
2238 ok( test != NULL, "test not set\n" );
2239 if (test)
2241 ok( test->str != NULL, "str not set\n" );
2242 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data test %p test->str %p\n", test, test->str );
2245 hr = WsGetReaderNode( reader, &node, NULL );
2246 ok( hr == S_OK, "got %08x\n", hr );
2247 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2249 WsFreeReader( reader );
2250 WsFreeHeap( heap );
2253 static void test_cdata(void)
2255 static const char test[] = "<t><![CDATA[<data>]]></t>";
2256 HRESULT hr;
2257 WS_XML_READER *reader;
2258 const WS_XML_NODE *node;
2260 hr = WsCreateReader( NULL, 0, &reader, NULL );
2261 ok( hr == S_OK, "got %08x\n", hr );
2263 hr = set_input( reader, test, sizeof(test) - 1 );
2264 ok( hr == S_OK, "got %08x\n", hr );
2266 hr = WsFillReader( reader, sizeof(test) - 1, NULL, NULL );
2267 ok( hr == S_OK, "got %08x\n", hr );
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_ELEMENT, "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_CDATA, "got %u\n", node->nodeType );
2283 hr = WsReadNode( reader, NULL );
2284 ok( hr == S_OK, "got %08x\n", hr );
2286 hr = WsGetReaderNode( reader, &node, NULL );
2287 ok( hr == S_OK, "got %08x\n", hr );
2288 if (node)
2290 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
2291 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
2292 ok( text->text != NULL, "text not set\n" );
2293 if (text->text)
2295 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
2296 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
2297 ok( utf8->value.length == 6, "got %u\n", utf8->value.length );
2298 ok( !memcmp( utf8->value.bytes, "<data>", 6 ), "wrong data\n" );
2302 hr = WsReadNode( reader, NULL );
2303 ok( hr == S_OK, "got %08x\n", hr );
2305 hr = WsGetReaderNode( reader, &node, NULL );
2306 ok( hr == S_OK, "got %08x\n", hr );
2307 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_CDATA, "got %u\n", node->nodeType );
2309 hr = WsReadNode( reader, NULL );
2310 ok( hr == S_OK, "got %08x\n", hr );
2312 hr = WsGetReaderNode( reader, &node, NULL );
2313 ok( hr == S_OK, "got %08x\n", hr );
2314 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2316 WsFreeReader( reader );
2319 static void test_WsFindAttribute(void)
2321 static const char test[] = "<t attr='value' attr2='value2'></t>";
2322 WS_XML_STRING ns = {0, NULL}, localname = {4, (BYTE *)"attr"};
2323 WS_XML_STRING localname2 = {5, (BYTE *)"attr2"}, localname3 = {5, (BYTE *)"attr3"};
2324 WS_XML_READER *reader;
2325 ULONG index;
2326 HRESULT hr;
2328 hr = WsCreateReader( NULL, 0, &reader, NULL );
2329 ok( hr == S_OK, "got %08x\n", hr );
2331 hr = set_input( reader, test, sizeof(test) - 1 );
2332 ok( hr == S_OK, "got %08x\n", hr );
2334 hr = WsReadNode( reader, NULL );
2335 ok( hr == S_OK, "got %08x\n", hr );
2337 hr = WsFindAttribute( reader, &localname, &ns, TRUE, NULL, NULL );
2338 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2340 hr = set_input( reader, test, sizeof(test) - 1 );
2341 ok( hr == S_OK, "got %08x\n", hr );
2343 hr = WsReadNode( reader, NULL );
2344 ok( hr == S_OK, "got %08x\n", hr );
2346 hr = WsFindAttribute( reader, &localname, NULL, TRUE, &index, NULL );
2347 ok( hr == E_INVALIDARG, "got %08x\n", hr );
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 hr = WsFindAttribute( reader, NULL, &ns, TRUE, &index, NULL );
2356 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2358 hr = set_input( reader, test, sizeof(test) - 1 );
2359 ok( hr == S_OK, "got %08x\n", hr );
2361 hr = WsReadNode( reader, NULL );
2362 ok( hr == S_OK, "got %08x\n", hr );
2364 index = 0xdeadbeef;
2365 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2366 ok( hr == S_OK, "got %08x\n", hr );
2367 ok( !index, "got %u\n", index );
2369 index = 0xdeadbeef;
2370 hr = WsFindAttribute( reader, &localname2, &ns, TRUE, &index, NULL );
2371 ok( hr == S_OK, "got %08x\n", hr );
2372 ok( index == 1, "got %u\n", index );
2374 hr = WsReadNode( reader, NULL );
2375 ok( hr == S_OK, "got %08x\n", hr );
2377 index = 0xdeadbeef;
2378 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2379 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2380 ok( index == 0xdeadbeef, "got %u\n", index );
2382 hr = set_input( reader, test, sizeof(test) - 1 );
2383 ok( hr == S_OK, "got %08x\n", hr );
2385 hr = WsReadNode( reader, NULL );
2386 ok( hr == S_OK, "got %08x\n", hr );
2388 index = 0xdeadbeef;
2389 hr = WsFindAttribute( reader, &localname3, &ns, TRUE, &index, NULL );
2390 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2391 ok( index == 0xdeadbeef, "got %u\n", index );
2393 hr = set_input( reader, test, sizeof(test) - 1 );
2394 ok( hr == S_OK, "got %08x\n", hr );
2396 hr = WsReadNode( reader, NULL );
2397 ok( hr == S_OK, "got %08x\n", hr );
2399 index = 0xdeadbeef;
2400 hr = WsFindAttribute( reader, &localname3, &ns, FALSE, &index, NULL );
2401 ok( hr == S_FALSE, "got %08x\n", hr );
2402 ok( index == ~0u, "got %u\n", index );
2404 WsFreeReader( reader );
2407 static void prepare_namespace_test( WS_XML_READER *reader, const char *data )
2409 HRESULT hr;
2410 ULONG size = strlen( data );
2412 hr = set_input( reader, data, size );
2413 ok( hr == S_OK, "got %08x\n", hr );
2415 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2416 ok( hr == S_OK, "got %08x\n", hr );
2419 static void test_WsGetNamespaceFromPrefix(void)
2421 WS_XML_STRING prefix = {0, NULL};
2422 const WS_XML_STRING *ns;
2423 const WS_XML_NODE *node;
2424 WS_XML_READER *reader;
2425 HRESULT hr;
2427 hr = WsCreateReader( NULL, 0, &reader, NULL );
2428 ok( hr == S_OK, "got %08x\n", hr );
2430 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, NULL, NULL );
2431 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2433 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, &ns, NULL );
2434 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2436 hr = WsGetNamespaceFromPrefix( NULL, &prefix, FALSE, &ns, NULL );
2437 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2439 ns = (const WS_XML_STRING *)0xdeadbeef;
2440 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2441 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2442 ok( ns == (const WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2444 hr = set_input( reader, "<prefix:t xmlns:prefix2='ns'/>", sizeof("<prefix:t xmlns:prefix2='ns'/>") - 1 );
2445 ok( hr == S_OK, "got %08x\n", hr );
2446 hr = WsReadStartElement( reader, NULL );
2447 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2449 prepare_namespace_test( reader, "<t></t>" );
2450 ns = NULL;
2451 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2452 ok( hr == S_OK, "got %08x\n", hr );
2453 ok( ns != NULL, "ns not set\n" );
2454 if (ns) ok( !ns->length, "got %u\n", ns->length );
2456 prepare_namespace_test( reader, "<t xmls='ns'></t>" );
2457 ns = NULL;
2458 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2459 ok( hr == S_OK, "got %08x\n", hr );
2460 ok( ns != NULL, "ns not set\n" );
2461 if (ns) ok( !ns->length, "got %u\n", ns->length );
2463 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2464 ns = NULL;
2465 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2466 ok( hr == S_OK, "got %08x\n", hr );
2467 ok( ns != NULL, "ns not set\n" );
2468 if (ns) ok( !ns->length, "got %u\n", ns->length );
2470 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2471 prefix.bytes = (BYTE *)"prefix";
2472 prefix.length = 6;
2473 ns = NULL;
2474 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2475 ok( hr == S_OK, "got %08x\n", hr );
2476 ok( ns != NULL, "ns not set\n" );
2477 if (ns)
2479 ok( ns->length == 2, "got %u\n", ns->length );
2480 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2483 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2484 ns = NULL;
2485 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2486 ok( hr == S_OK, "got %08x\n", hr );
2487 ok( ns != NULL, "ns not set\n" );
2488 if (ns)
2490 ok( ns->length == 2, "got %u\n", ns->length );
2491 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2494 hr = set_input( reader, "<t xmlns:prefix='ns'></t>", sizeof("<t xmlns:prefix='ns'></t>") - 1 );
2495 ok( hr == S_OK, "got %08x\n", hr );
2496 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2497 ok( hr == S_OK, "got %08x\n", hr );
2498 hr = WsGetReaderNode( reader, &node, NULL );
2499 ok( hr == S_OK, "got %08x\n", hr );
2500 if (node)
2502 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2503 WS_XML_ATTRIBUTE *attr;
2504 WS_XML_UTF8_TEXT *text;
2506 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2507 ok( elem->prefix != NULL, "prefix not set\n" );
2508 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2509 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2510 ok( elem->ns != NULL, "ns not set\n" );
2511 ok( !elem->ns->length, "got %u\n", elem->ns->length );
2512 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2513 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2514 ok( elem->attributes != NULL, "attributes not set\n" );
2516 attr = elem->attributes[0];
2517 ok( attr->singleQuote, "singleQuote not set\n" );
2518 ok( attr->isXmlNs, "isXmlNs not set\n" );
2519 ok( attr->prefix != NULL, "prefix not set\n" );
2520 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2521 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2522 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2523 ok( attr->localName != NULL, "localName not set\n" );
2524 ok( attr->localName->length == 6, "got %u\n", attr->localName->length );
2525 ok( !memcmp( attr->localName->bytes, "prefix", 6 ), "wrong data\n" );
2526 ok( attr->ns != NULL, "ns not set\n" );
2527 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2528 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2529 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2530 ok( attr->value != NULL, "value not set\n" );
2532 text = (WS_XML_UTF8_TEXT *)attr->value;
2533 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
2534 ok( !text->value.length, "got %u\n", text->value.length );
2535 ok( text->value.bytes == NULL, "bytes set\n" );
2538 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2539 hr = WsReadStartElement( reader, NULL );
2540 ok( hr == S_OK, "got %08x\n", hr );
2541 hr = WsReadEndElement( reader, NULL );
2542 ok( hr == S_OK, "got %08x\n", hr );
2543 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2544 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2546 prepare_namespace_test( reader, "<t></t>" );
2547 ns = NULL;
2548 prefix.bytes = (BYTE *)"xml";
2549 prefix.length = 3;
2550 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2551 ok( hr == S_OK, "got %08x\n", hr );
2552 ok( ns != NULL, "ns not set\n" );
2553 if (ns)
2555 ok( ns->length == 36, "got %u\n", ns->length );
2556 ok( !memcmp( ns->bytes, "http://www.w3.org/XML/1998/namespace", 36 ), "wrong data\n" );
2559 prepare_namespace_test( reader, "<t></t>" );
2560 ns = NULL;
2561 prefix.bytes = (BYTE *)"xmlns";
2562 prefix.length = 5;
2563 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2564 ok( hr == S_OK, "got %08x\n", hr );
2565 ok( ns != NULL, "ns not set\n" );
2566 if (ns)
2568 ok( ns->length == 29, "got %u\n", ns->length );
2569 ok( !memcmp( ns->bytes, "http://www.w3.org/2000/xmlns/", 29 ), "wrong data\n" );
2572 prepare_namespace_test( reader, "<t></t>" );
2573 ns = (WS_XML_STRING *)0xdeadbeef;
2574 prefix.bytes = (BYTE *)"prefix2";
2575 prefix.length = 7;
2576 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2577 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2578 ok( ns == (WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2580 prepare_namespace_test( reader, "<t></t>" );
2581 ns = (WS_XML_STRING *)0xdeadbeef;
2582 prefix.bytes = (BYTE *)"prefix2";
2583 prefix.length = 7;
2584 hr = WsGetNamespaceFromPrefix( reader, &prefix, FALSE, &ns, NULL );
2585 ok( hr == S_FALSE, "got %08x\n", hr );
2586 ok( ns == NULL, "ns not set\n" );
2588 hr = set_input( reader, "<t prefix:attr='' xmlns:prefix='ns'></t>", sizeof("<t prefix:attr='' xmlns:prefix='ns'></t>") - 1 );
2589 ok( hr == S_OK, "got %08x\n", hr );
2590 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2591 ok( hr == S_OK, "got %08x\n", hr );
2592 hr = WsGetReaderNode( reader, &node, NULL );
2593 ok( hr == S_OK, "got %08x\n", hr );
2594 if (node)
2596 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2597 WS_XML_ATTRIBUTE *attr;
2599 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2600 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
2601 ok( elem->attributes != NULL, "attributes not set\n" );
2603 attr = elem->attributes[0];
2604 ok( attr->singleQuote, "singleQuote not set\n" );
2605 ok( !attr->isXmlNs, "isXmlNs is set\n" );
2606 ok( attr->prefix != NULL, "prefix not set\n" );
2607 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2608 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2609 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2610 ok( attr->localName != NULL, "localName not set\n" );
2611 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
2612 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
2613 ok( attr->ns != NULL, "ns not set\n" );
2614 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2615 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2616 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2619 hr = set_input( reader, "<t xmlns:p='ns'><u xmlns:p='ns2'/></t>", sizeof("<t xmlns:p='ns'><u xmlns:p='ns2'/></t>") - 1 );
2620 ok( hr == S_OK, "got %08x\n", hr );
2621 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2622 ok( hr == S_OK, "got %08x\n", hr );
2623 hr = WsReadStartElement( reader, NULL );
2624 ok( hr == S_OK, "got %08x\n", hr );
2626 hr = set_input( reader, "<t xmlns:p='ns'><p:u p:a=''/></t>", sizeof("<t xmlns:p='ns'><p:u p:a=''/></t>") - 1 );
2627 ok( hr == S_OK, "got %08x\n", hr );
2628 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2629 ok( hr == S_OK, "got %08x\n", hr );
2630 hr = WsReadStartElement( reader, NULL );
2631 ok( hr == S_OK, "got %08x\n", hr );
2632 hr = WsGetReaderNode( reader, &node, NULL );
2633 ok( hr == S_OK, "got %08x\n", hr );
2634 if (node)
2636 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2637 WS_XML_ATTRIBUTE *attr;
2639 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2640 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2641 ok( elem->attributes != NULL, "attributes not set\n" );
2643 attr = elem->attributes[0];
2644 ok( attr->prefix != NULL, "prefix not set\n" );
2645 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
2646 ok( attr->prefix->bytes != NULL, "bytes set\n" );
2647 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong data\n" );
2648 ok( attr->localName != NULL, "localName not set\n" );
2649 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
2650 ok( !memcmp( attr->localName->bytes, "a", 1 ), "wrong data\n" );
2651 ok( attr->ns != NULL, "ns not set\n" );
2652 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2653 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2654 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2657 hr = set_input( reader, "<t xmlns='ns'></t>", sizeof("<t xmlns='ns'></t>") - 1 );
2658 ok( hr == S_OK, "got %08x\n", hr );
2659 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2660 ok( hr == S_OK, "got %08x\n", hr );
2661 hr = WsGetReaderNode( reader, &node, NULL );
2662 ok( hr == S_OK, "got %08x\n", hr );
2663 if (node)
2665 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2666 WS_XML_ATTRIBUTE *attr;
2668 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2669 ok( elem->prefix != NULL, "prefix not set\n" );
2670 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2671 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2672 ok( elem->ns != NULL, "ns not set\n" );
2673 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
2674 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2675 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong data\n" );
2677 attr = elem->attributes[0];
2678 ok( attr->isXmlNs, "isXmlNs is not set\n" );
2679 ok( attr->prefix != NULL, "prefix not set\n" );
2680 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
2681 ok( attr->prefix->bytes == NULL, "bytes set\n" );
2682 ok( attr->localName != NULL, "localName not set\n" );
2683 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
2684 ok( !memcmp( attr->localName->bytes, "xmlns", 5 ), "wrong data\n" );
2685 ok( attr->ns != NULL, "ns not set\n" );
2686 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2687 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2688 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2691 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns2'></t>") - 1 );
2692 ok( hr == S_OK, "got %08x\n", hr );
2693 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2694 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2696 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns'></t>") - 1 );
2697 ok( hr == S_OK, "got %08x\n", hr );
2698 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2699 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2701 hr = set_input( reader, "<t xmlns:p='ns' xmlns:P='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:P='ns2'></t>") - 1 );
2702 ok( hr == S_OK, "got %08x\n", hr );
2703 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2704 ok( hr == S_OK, "got %08x\n", hr );
2706 WsFreeReader( reader );
2709 static void test_text_field_mapping(void)
2711 static const WCHAR testW[] = {'t','e','s','t',0};
2712 HRESULT hr;
2713 WS_XML_READER *reader;
2714 WS_HEAP *heap;
2715 WS_STRUCT_DESCRIPTION s;
2716 WS_FIELD_DESCRIPTION f, *fields[1];
2717 struct test
2719 WCHAR *str;
2720 } *test;
2722 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2723 ok( hr == S_OK, "got %08x\n", hr );
2725 hr = WsCreateReader( NULL, 0, &reader, NULL );
2726 ok( hr == S_OK, "got %08x\n", hr );
2728 prepare_struct_type_test( reader, "<a>test</a>" );
2730 memset( &f, 0, sizeof(f) );
2731 f.mapping = WS_TEXT_FIELD_MAPPING;
2732 f.type = WS_WSZ_TYPE;
2733 fields[0] = &f;
2735 memset( &s, 0, sizeof(s) );
2736 s.size = sizeof(struct test);
2737 s.alignment = TYPE_ALIGNMENT(struct test);
2738 s.fields = fields;
2739 s.fieldCount = 1;
2741 test = NULL;
2742 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2743 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2744 ok( hr == S_OK, "got %08x\n", hr );
2745 ok( test != NULL, "test not set\n" );
2746 ok( test->str != NULL, "str not set\n" );
2747 ok( !lstrcmpW( test->str, testW ), "got %s\n", wine_dbgstr_w(test->str) );
2749 WsFreeReader( reader );
2750 WsFreeHeap( heap );
2753 static void test_complex_struct_type(void)
2755 static const WCHAR timestampW[] =
2756 {'2','0','1','5','-','0','9','-','0','3','T','1','8',':','4','7',':','5','4',0};
2757 HRESULT hr;
2758 WS_ERROR *error;
2759 WS_ERROR_PROPERTY prop;
2760 WS_XML_READER *reader;
2761 WS_HEAP *heap;
2762 WS_STRUCT_DESCRIPTION s, s2;
2763 WS_FIELD_DESCRIPTION f, f2, *fields[1], *fields2[1];
2764 WS_XML_STRING str_officeconfig = {12, (BYTE *)"OfficeConfig"};
2765 WS_XML_STRING str_services = {8, (BYTE *)"services"};
2766 WS_XML_STRING str_generationtime = {14, (BYTE *)"GenerationTime"};
2767 WS_XML_STRING ns = {39, (BYTE *)"urn:schemas-microsoft-com:office:office"};
2768 LANGID langid = MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT );
2769 const WS_XML_NODE *node;
2770 const WS_XML_ELEMENT_NODE *elem;
2771 struct services
2773 WCHAR *generationtime;
2775 struct officeconfig
2777 struct services *services;
2778 } *test;
2780 prop.id = WS_ERROR_PROPERTY_LANGID;
2781 prop.value = &langid;
2782 prop.valueSize = sizeof(langid);
2783 hr = WsCreateError( &prop, 1, &error );
2784 ok( hr == S_OK, "got %08x\n", hr );
2786 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2787 ok( hr == S_OK, "got %08x\n", hr );
2789 hr = WsCreateReader( NULL, 0, &reader, NULL );
2790 ok( hr == S_OK, "got %08x\n", hr );
2792 /* element content type mapping */
2793 prepare_struct_type_test( reader, data11 );
2795 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2796 ok( hr == S_OK, "got %08x\n", hr );
2798 hr = WsGetReaderNode( reader, &node, NULL );
2799 ok( hr == S_OK, "got %08x\n", hr );
2800 elem = (const WS_XML_ELEMENT_NODE *)node;
2801 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2802 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
2803 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
2805 hr = WsReadStartElement( reader, NULL );
2806 ok( hr == S_OK, "got %08x\n", hr );
2808 hr = WsGetReaderNode( reader, &node, NULL );
2809 ok( hr == S_OK, "got %08x\n", hr );
2810 elem = (const WS_XML_ELEMENT_NODE *)node;
2811 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2812 ok( elem->localName->length == 8, "got %u\n", elem->localName->length );
2813 ok( !memcmp( elem->localName->bytes, "services", 8 ), "wrong data\n" );
2815 memset( &f2, 0, sizeof(f2) );
2816 f2.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2817 f2.localName = &str_generationtime;
2818 f2.ns = &ns;
2819 f2.type = WS_WSZ_TYPE;
2820 f2.options = WS_FIELD_OPTIONAL;
2821 fields2[0] = &f2;
2823 memset( &s2, 0, sizeof(s2) );
2824 s2.size = sizeof(*test->services);
2825 s2.alignment = TYPE_ALIGNMENT(struct services);
2826 s2.fields = fields2;
2827 s2.fieldCount = 1;
2828 s2.typeLocalName = &str_services;
2829 s2.typeNs = &ns;
2831 memset( &f, 0, sizeof(f) );
2832 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2833 f.localName = &str_services;
2834 f.ns = &ns;
2835 f.type = WS_STRUCT_TYPE;
2836 f.typeDescription = &s2;
2837 f.options = WS_FIELD_POINTER;
2838 fields[0] = &f;
2840 memset( &s, 0, sizeof(s) );
2841 s.size = sizeof(*test);
2842 s.alignment = TYPE_ALIGNMENT(struct officeconfig);
2843 s.fields = fields;
2844 s.fieldCount = 1;
2845 s.typeLocalName = &str_officeconfig;
2846 s.typeNs = &ns;
2848 test = NULL;
2849 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2850 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2851 ok( hr == S_OK, "got %08x\n", hr );
2852 ok( test != NULL, "test not set\n" );
2853 ok( !lstrcmpW( test->services->generationtime, timestampW ), "wrong data\n" );
2855 hr = WsGetReaderNode( reader, &node, NULL );
2856 ok( hr == S_OK, "got %08x\n", hr );
2857 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2859 hr = WsReadEndElement( reader, NULL );
2860 ok( hr == S_OK, "got %08x\n", hr );
2862 hr = WsGetReaderNode( reader, &node, NULL );
2863 ok( hr == S_OK, "got %08x\n", hr );
2864 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2866 hr = WsReadEndElement( reader, NULL );
2867 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2869 /* element type mapping */
2870 prepare_struct_type_test( reader, data11 );
2872 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2873 ok( hr == S_OK, "got %08x\n", hr );
2875 hr = WsGetReaderNode( reader, &node, NULL );
2876 ok( hr == S_OK, "got %08x\n", hr );
2877 elem = (const WS_XML_ELEMENT_NODE *)node;
2878 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2879 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
2880 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
2882 test = NULL;
2883 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2884 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2885 ok( hr == S_OK, "got %08x\n", hr );
2886 ok( test != NULL, "test not set\n" );
2887 if (test) ok( !lstrcmpW( test->services->generationtime, timestampW ), "wrong data\n" );
2889 hr = WsGetReaderNode( reader, &node, NULL );
2890 ok( hr == S_OK, "got %08x\n", hr );
2891 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2893 /* trailing content */
2894 prepare_struct_type_test( reader, data11b );
2895 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2896 ok( hr == S_OK, "got %08x\n", hr );
2898 s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
2899 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2900 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2901 ok( hr == S_OK, "got %08x\n", hr );
2903 hr = WsGetReaderNode( reader, &node, NULL );
2904 ok( hr == S_OK, "got %08x\n", hr );
2905 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2907 prepare_struct_type_test( reader, data11b );
2908 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2909 ok( hr == S_OK, "got %08x\n", hr );
2911 s.structOptions = 0;
2912 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2913 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2914 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2916 WsFreeReader( reader );
2917 WsFreeHeap( heap );
2918 WsFreeError( error );
2921 static void test_repeating_element(void)
2923 static const WCHAR oneW[] = {'1',0}, twoW[] = {'2',0};
2924 WS_XML_STRING str_name = {4, (BYTE *)"name"};
2925 WS_XML_STRING str_services = {8, (BYTE *)"services"};
2926 WS_XML_STRING str_service = {7, (BYTE *)"service"};
2927 WS_XML_STRING str_wrapper = {7, (BYTE *)"wrapper"};
2928 WS_XML_STRING str_id = {2, (BYTE *)"id"};
2929 WS_XML_STRING str_ns = {0, NULL};
2930 HRESULT hr;
2931 WS_XML_READER *reader;
2932 WS_HEAP *heap;
2933 WS_STRUCT_DESCRIPTION s, s2;
2934 WS_FIELD_DESCRIPTION f, f2, f3, *fields[1], *fields2[2];
2935 WS_ITEM_RANGE range;
2936 struct service { UINT32 id; };
2937 struct service2 { WCHAR *id; };
2938 struct service3 { WCHAR *name; WCHAR *id; };
2939 struct services
2941 struct service *service;
2942 ULONG service_count;
2943 } *test;
2944 struct services2
2946 struct service2 *service;
2947 ULONG service_count;
2948 } *test2;
2949 struct services3
2951 struct service3 *service;
2952 ULONG service_count;
2953 } *test3;
2954 struct services4
2956 struct service **service;
2957 ULONG service_count;
2958 } *test4;
2960 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2961 ok( hr == S_OK, "got %08x\n", hr );
2963 hr = WsCreateReader( NULL, 0, &reader, NULL );
2964 ok( hr == S_OK, "got %08x\n", hr );
2966 prepare_struct_type_test( reader, data12 );
2968 memset( &f2, 0, sizeof(f2) );
2969 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
2970 f2.localName = &str_id;
2971 f2.ns = &str_ns;
2972 f2.type = WS_UINT32_TYPE;
2973 fields2[0] = &f2;
2975 memset( &s2, 0, sizeof(s2) );
2976 s2.size = sizeof(struct service);
2977 s2.alignment = TYPE_ALIGNMENT(struct service);
2978 s2.fields = fields2;
2979 s2.fieldCount = 1;
2980 s2.typeLocalName = &str_service;
2982 memset( &f, 0, sizeof(f) );
2983 f.mapping = WS_REPEATING_ELEMENT_FIELD_MAPPING;
2984 f.countOffset = FIELD_OFFSET(struct services, service_count);
2985 f.type = WS_STRUCT_TYPE;
2986 f.typeDescription = &s2;
2987 f.itemLocalName = &str_service;
2988 f.itemNs = &str_ns;
2989 fields[0] = &f;
2991 memset( &s, 0, sizeof(s) );
2992 s.size = sizeof(struct services);
2993 s.alignment = TYPE_ALIGNMENT(struct services);
2994 s.fields = fields;
2995 s.fieldCount = 1;
2996 s.typeLocalName = &str_services;
2998 test = NULL;
2999 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3000 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3001 ok( hr == S_OK, "got %08x\n", hr );
3002 ok( test != NULL, "test not set\n" );
3003 ok( test->service != NULL, "service not set\n" );
3004 ok( test->service_count == 2, "got %u\n", test->service_count );
3005 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
3006 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
3008 /* array of pointers */
3009 prepare_struct_type_test( reader, data12 );
3010 f.options = WS_FIELD_POINTER;
3011 test4 = NULL;
3012 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3013 WS_READ_REQUIRED_POINTER, heap, &test4, sizeof(test4), NULL );
3014 ok( hr == S_OK || broken(hr == E_INVALIDARG) /* win7 */, "got %08x\n", hr );
3015 if (test4)
3017 ok( test4->service != NULL, "service not set\n" );
3018 ok( test4->service_count == 2, "got %u\n", test4->service_count );
3019 ok( test4->service[0]->id == 1, "got %u\n", test4->service[0]->id );
3020 ok( test4->service[1]->id == 2, "got %u\n", test4->service[1]->id );
3023 /* item range */
3024 prepare_struct_type_test( reader, data13 );
3025 f.options = 0;
3026 range.minItemCount = 0;
3027 range.maxItemCount = 1;
3028 f.itemRange = &range;
3029 test = NULL;
3030 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3031 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3032 ok( hr == S_OK, "got %08x\n", hr );
3033 ok( test != NULL, "test not set\n" );
3034 ok( test->service != NULL, "service not set\n" );
3035 ok( !test->service_count, "got %u\n", test->service_count );
3037 /* wrapper element */
3038 prepare_struct_type_test( reader, data14 );
3039 f.itemRange = NULL;
3040 f.localName = &str_wrapper;
3041 f.ns = &str_ns;
3042 test = NULL;
3043 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3044 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3045 ok( hr == S_OK, "got %08x\n", hr );
3046 ok( test != NULL, "test not set\n" );
3047 ok( test->service != NULL, "service not set\n" );
3048 ok( test->service_count == 2, "got %u\n", test->service_count );
3049 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
3050 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
3052 /* repeating text field mapping */
3053 prepare_struct_type_test( reader, data15 );
3054 f2.mapping = WS_TEXT_FIELD_MAPPING;
3055 f2.localName = NULL;
3056 f2.ns = NULL;
3057 f2.type = WS_WSZ_TYPE;
3058 s2.size = sizeof(struct service2);
3059 s2.alignment = TYPE_ALIGNMENT(struct service2);
3060 test2 = NULL;
3061 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3062 WS_READ_REQUIRED_POINTER, heap, &test2, sizeof(test2), NULL );
3063 ok( hr == S_OK, "got %08x\n", hr );
3064 ok( test2 != NULL, "test2 not set\n" );
3065 ok( test2->service != NULL, "service not set\n" );
3066 ok( test2->service_count == 2, "got %u\n", test2->service_count );
3067 ok( !lstrcmpW( test2->service[0].id, oneW ), "wrong data\n" );
3068 ok( !lstrcmpW( test2->service[1].id, twoW ), "wrong data\n" );
3070 /* repeating attribute field + text field mapping */
3071 prepare_struct_type_test( reader, data16 );
3072 f2.offset = FIELD_OFFSET(struct service3, id);
3073 memset( &f3, 0, sizeof(f3) );
3074 f3.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
3075 f3.localName = &str_name;
3076 f3.ns = &str_ns;
3077 f3.type = WS_WSZ_TYPE;
3078 fields2[0] = &f3;
3079 fields2[1] = &f2;
3080 s2.size = sizeof(struct service3);
3081 s2.alignment = TYPE_ALIGNMENT(struct service3);
3082 s2.fieldCount = 2;
3083 test3 = NULL;
3084 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3085 WS_READ_REQUIRED_POINTER, heap, &test3, sizeof(test3), NULL );
3086 ok( hr == S_OK, "got %08x\n", hr );
3087 ok( test3 != NULL, "test3 not set\n" );
3088 ok( test3->service != NULL, "service not set\n" );
3089 ok( test3->service_count == 2, "got %u\n", test3->service_count );
3090 ok( !lstrcmpW( test3->service[0].name, oneW ), "wrong data\n" );
3091 ok( !lstrcmpW( test3->service[0].id, oneW ), "wrong data\n" );
3092 ok( !lstrcmpW( test3->service[1].name, twoW ), "wrong data\n" );
3093 ok( !lstrcmpW( test3->service[1].id, twoW ), "wrong data\n" );
3095 WsFreeReader( reader );
3096 WsFreeHeap( heap );
3099 static void test_WsResetHeap(void)
3101 HRESULT hr;
3102 WS_HEAP *heap;
3103 SIZE_T requested, actual;
3104 ULONG size;
3105 void *ptr;
3107 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3108 ok( hr == S_OK, "got %08x\n", hr );
3110 requested = 0xdeadbeef;
3111 size = sizeof(requested);
3112 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3113 ok( hr == S_OK, "got %08x\n", hr );
3114 ok( !requested, "got %u\n", (ULONG)requested );
3116 actual = 0xdeadbeef;
3117 size = sizeof(actual);
3118 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3119 ok( hr == S_OK, "got %08x\n", hr );
3120 ok( !actual, "got %u\n", (ULONG)actual );
3122 hr = WsAlloc( heap, 128, &ptr, 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 == 128, "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 ok( actual == 128, "got %u\n", (ULONG)actual );
3137 hr = WsAlloc( heap, 1, &ptr, NULL );
3138 ok( hr == S_OK, "got %08x\n", hr );
3140 requested = 0xdeadbeef;
3141 size = sizeof(requested);
3142 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3143 ok( hr == S_OK, "got %08x\n", hr );
3144 ok( requested == 129, "got %u\n", (ULONG)requested );
3146 actual = 0xdeadbeef;
3147 size = sizeof(actual);
3148 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3149 ok( hr == S_OK, "got %08x\n", hr );
3150 todo_wine ok( actual == 384, "got %u\n", (ULONG)actual );
3152 hr = WsResetHeap( NULL, NULL );
3153 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3155 hr = WsResetHeap( heap, NULL );
3156 ok( hr == S_OK, "got %08x\n", hr );
3158 requested = 0xdeadbeef;
3159 size = sizeof(requested);
3160 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3161 ok( hr == S_OK, "got %08x\n", hr );
3162 ok( !requested, "got %u\n", (ULONG)requested );
3164 actual = 0xdeadbeef;
3165 size = sizeof(actual);
3166 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3167 ok( hr == S_OK, "got %08x\n", hr );
3168 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
3170 WsFreeHeap( heap );
3173 static void test_datetime(void)
3175 static const struct
3177 const char *str;
3178 HRESULT hr;
3179 __int64 ticks;
3180 WS_DATETIME_FORMAT format;
3182 tests[] =
3184 {"<t>0000-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3185 {"<t>0001-01-01T00:00:00Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3186 {"<t>0001-01-01T00:00:00.Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3187 {"<t>0001-01-01T00:00:00.0Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3188 {"<t>0001-01-01T00:00:00.1Z</t>", S_OK, 0x0000f4240, WS_DATETIME_FORMAT_UTC},
3189 {"<t>0001-01-01T00:00:00.01Z</t>", S_OK, 0x0000186a0, WS_DATETIME_FORMAT_UTC},
3190 {"<t>0001-01-01T00:00:00.0000001Z</t>", S_OK, 1, WS_DATETIME_FORMAT_UTC},
3191 {"<t>0001-01-01T00:00:00.9999999Z</t>", S_OK, 0x00098967f, WS_DATETIME_FORMAT_UTC},
3192 {"<t>0001-01-01T00:00:00.0000000Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3193 {"<t>0001-01-01T00:00:00.00000001Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3194 {"<t>0001-01-01T00:00:00Z-</t>", WS_E_INVALID_FORMAT, 0},
3195 {"<t>-0001-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3196 {"<t>0001-00-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3197 {"<t>0001-13-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3198 {"<t>0001-12-01T00:00:00Z</t>", S_OK, 0x1067555f88000, WS_DATETIME_FORMAT_UTC},
3199 {"<t>0001-01-00T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3200 {"<t>2001-01-32T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3201 {"<t>2001-01-31T00:00:00Z</t>", S_OK, 0x8c2592fe3794000, WS_DATETIME_FORMAT_UTC},
3202 {"<t>1900-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3203 {"<t>2000-02-29T00:00:00Z</t>", S_OK, 0x8c1505f0e438000, 0},
3204 {"<t>2001-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3205 {"<t>2001-02-28T00:00:00Z</t>", S_OK, 0x8c26f30870a4000, WS_DATETIME_FORMAT_UTC},
3206 {"<t>0001-00-01U00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3207 {"<t>0001-01-01T24:00:00Z</t>", S_OK, 0xc92a69c000, WS_DATETIME_FORMAT_UTC},
3208 {"<t>0001-01-01T24:00:01Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3209 {"<t>0001-01-01T00:60:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3210 {"<t>0001-01-01T00:00:60Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3211 {"<t>0001-01-01T00:00:00Y</t>", WS_E_INVALID_FORMAT, 0, 0},
3212 {"<t>0001-01-01T00:00:00+00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3213 {"<t>0001-01-01T00:00:00-00:01</t>", S_OK, 0x023c34600, WS_DATETIME_FORMAT_LOCAL},
3214 {"<t>9999-12-31T24:00:00+00:01</t>", S_OK, 0x2bca2875d073fa00, WS_DATETIME_FORMAT_LOCAL},
3215 {"<t>9999-12-31T24:00:00-00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3216 {"<t>0002-01-01T00:00:00+14:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3217 {"<t>0002-01-01T00:00:00+15:00</t>", WS_E_INVALID_FORMAT, 0, 0},
3218 {"<t>0002-01-01T00:00:00+13:60</t>", WS_E_INVALID_FORMAT, 0, 0},
3219 {"<t>0002-01-01T00:00:00+13:59</t>", S_OK, 0x11e5c43cc5600, WS_DATETIME_FORMAT_LOCAL},
3220 {"<t>0002-01-01T00:00:00+01:00</t>", S_OK, 0x11ec917025800, WS_DATETIME_FORMAT_LOCAL},
3221 {"<t>2016-01-01T00:00:00-01:00</t>", S_OK, 0x8d31246dfbba800, WS_DATETIME_FORMAT_LOCAL},
3222 {"<t>2016-01-01T00:00:00Z</t>", S_OK, 0x8d3123e7df74000, WS_DATETIME_FORMAT_UTC},
3223 {"<t> 2016-01-02T03:04:05Z </t>", S_OK, 0x8d313215fb64080, WS_DATETIME_FORMAT_UTC},
3224 {"<t>+2016-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3225 {"<t></t>", WS_E_INVALID_FORMAT, 0, 0},
3226 {"<t>01-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3227 {"<t>1601-01-01T00:00:00Z</t>", S_OK, 0x701ce1722770000, WS_DATETIME_FORMAT_UTC},
3229 HRESULT hr;
3230 WS_XML_READER *reader;
3231 WS_HEAP *heap;
3232 WS_DATETIME date;
3233 ULONG i;
3235 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3236 ok( hr == S_OK, "got %08x\n", hr );
3238 hr = WsCreateReader( NULL, 0, &reader, NULL );
3239 ok( hr == S_OK, "got %08x\n", hr );
3240 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3242 memset( &date, 0, sizeof(date) );
3243 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3244 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DATETIME_TYPE, NULL,
3245 WS_READ_REQUIRED_VALUE, heap, &date, sizeof(date), NULL );
3246 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3247 if (hr == S_OK)
3249 ok( date.ticks == tests[i].ticks, "%u: got %x%08x\n", i, (ULONG)(date.ticks >> 32), (ULONG)date.ticks );
3250 ok( date.format == tests[i].format, "%u: got %u\n", i, date.format );
3254 WsFreeReader( reader );
3255 WsFreeHeap( heap );
3258 static void test_WsDateTimeToFileTime(void)
3260 static const struct
3262 WS_DATETIME dt;
3263 HRESULT hr;
3264 FILETIME ft;
3266 tests[] =
3268 { {0, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3269 { {0x701ce172276ffff, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3270 { {0x701ce1722770000, WS_DATETIME_FORMAT_UTC}, S_OK, {0, 0} },
3271 { {0x2bca2875f4373fff, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c03fff, 0x24c85a5e} },
3272 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c04000, 0x24c85a5e} },
3273 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_LOCAL}, S_OK, {0xd1c04000, 0x24c85a5e} },
3274 { {~0, WS_DATETIME_FORMAT_UTC}, S_OK, {0xdd88ffff, 0xf8fe31e8} },
3276 WS_DATETIME dt;
3277 FILETIME ft;
3278 HRESULT hr;
3279 ULONG i;
3281 hr = WsDateTimeToFileTime( NULL, NULL, NULL );
3282 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3284 dt.ticks = 0x701ce172277000;
3285 dt.format = WS_DATETIME_FORMAT_UTC;
3286 hr = WsDateTimeToFileTime( &dt, NULL, NULL );
3287 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3289 hr = WsDateTimeToFileTime( NULL, &ft, NULL );
3290 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3292 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3294 memset( &ft, 0, sizeof(ft) );
3295 hr = WsDateTimeToFileTime( &tests[i].dt, &ft, NULL );
3296 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3297 if (hr == S_OK)
3299 ok( ft.dwLowDateTime == tests[i].ft.dwLowDateTime, "%u: got %08x\n", i, ft.dwLowDateTime );
3300 ok( ft.dwHighDateTime == tests[i].ft.dwHighDateTime, "%u: got %08x\n", i, ft.dwHighDateTime );
3305 static void test_WsFileTimeToDateTime(void)
3307 WS_DATETIME dt;
3308 FILETIME ft;
3309 HRESULT hr;
3311 hr = WsFileTimeToDateTime( NULL, NULL, NULL );
3312 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3314 ft.dwLowDateTime = ft.dwHighDateTime = 0;
3315 hr = WsFileTimeToDateTime( &ft, NULL, NULL );
3316 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3318 hr = WsFileTimeToDateTime( NULL, &dt, NULL );
3319 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3321 dt.ticks = 0xdeadbeef;
3322 dt.format = 0xdeadbeef;
3323 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3324 ok( hr == S_OK, "got %08x\n", hr );
3325 ok( dt.ticks == 0x701ce1722770000, "got %x%08x\n", (ULONG)(dt.ticks >> 32), (ULONG)dt.ticks );
3326 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3328 ft.dwLowDateTime = 0xd1c03fff;
3329 ft.dwHighDateTime = 0x24c85a5e;
3330 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3331 ok( hr == S_OK, "got %08x\n", hr );
3332 ok( dt.ticks == 0x2bca2875f4373fff, "got %x%08x\n", (ULONG)(dt.ticks >> 32), (ULONG)dt.ticks );
3333 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3335 ft.dwLowDateTime++;
3336 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3337 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3339 ft.dwLowDateTime = 0xdd88ffff;
3340 ft.dwHighDateTime = 0xf8fe31e8;
3341 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3342 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3344 ft.dwLowDateTime++;
3345 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3346 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
3349 static void test_double(void)
3351 static const struct
3353 const char *str;
3354 HRESULT hr;
3355 ULONGLONG val;
3357 tests[] =
3359 {"<t>0.0</t>", S_OK, 0},
3360 {"<t>-0.0</t>", S_OK, 0x8000000000000000},
3361 {"<t>+0.0</t>", S_OK, 0},
3362 {"<t>-</t>", S_OK, 0},
3363 {"<t>+</t>", S_OK, 0},
3364 {"<t>.0</t>", S_OK, 0},
3365 {"<t>0.</t>", S_OK, 0},
3366 {"<t>0</t>", S_OK, 0},
3367 {"<t> 0 </t>", S_OK, 0},
3368 {"<t></t>", WS_E_INVALID_FORMAT, 0},
3369 {"<t>0,1</t>", WS_E_INVALID_FORMAT, 0},
3370 {"<t>1.1.</t>", WS_E_INVALID_FORMAT, 0},
3371 {"<t>1</t>", S_OK, 0x3ff0000000000000},
3372 {"<t>1.0000000000000002</t>", S_OK, 0x3ff0000000000001},
3373 {"<t>1.0000000000000004</t>", S_OK, 0x3ff0000000000002},
3374 {"<t>10000000000000000000</t>", S_OK, 0x43e158e460913d00},
3375 {"<t>100000000000000000000</t>", S_OK, 0x4415af1d78b58c40},
3376 {"<t>2</t>", S_OK, 0x4000000000000000},
3377 {"<t>-2</t>", S_OK, 0xc000000000000000},
3378 {"<t>nodouble</t>", WS_E_INVALID_FORMAT, 0},
3379 {"<t>INF</t>", S_OK, 0x7ff0000000000000},
3380 {"<t>-INF</t>", S_OK, 0xfff0000000000000},
3381 {"<t>+INF</t>", WS_E_INVALID_FORMAT, 0},
3382 {"<t>Infinity</t>", WS_E_INVALID_FORMAT, 0},
3383 {"<t>-Infinity</t>", WS_E_INVALID_FORMAT, 0},
3384 {"<t>inf</t>", WS_E_INVALID_FORMAT, 0},
3385 {"<t>NaN</t>", S_OK, 0xfff8000000000000},
3386 {"<t>-NaN</t>", WS_E_INVALID_FORMAT, 0},
3387 {"<t>NAN</t>", WS_E_INVALID_FORMAT, 0},
3388 {"<t>0.3</t>", S_OK, 0x3fd3333333333333},
3389 {"<t>0.33</t>", S_OK, 0x3fd51eb851eb851f},
3390 {"<t>0.333</t>", S_OK, 0x3fd54fdf3b645a1d},
3391 {"<t>0.3333</t>", S_OK, 0x3fd554c985f06f69},
3392 {"<t>0.33333</t>", S_OK, 0x3fd555475a31a4be},
3393 {"<t>0.333333</t>", S_OK, 0x3fd55553ef6b5d46},
3394 {"<t>0.3333333</t>", S_OK, 0x3fd55555318abc87},
3395 {"<t>0.33333333</t>", S_OK, 0x3fd5555551c112da},
3396 {"<t>0.333333333</t>", S_OK, 0x3fd5555554f9b516},
3397 {"<t>0.3333333333</t>", S_OK, 0x3fd55555554c2bb5},
3398 {"<t>0.33333333333</t>", S_OK, 0x3fd5555555546ac5},
3399 {"<t>0.3333333333333</t>", S_OK, 0x3fd55555555552fd},
3400 {"<t>0.33333333333333</t>", S_OK, 0x3fd5555555555519},
3401 {"<t>0.333333333333333</t>", S_OK, 0x3fd555555555554f},
3402 {"<t>0.3333333333333333</t>", S_OK, 0x3fd5555555555555},
3403 {"<t>0.33333333333333333</t>", S_OK, 0x3fd5555555555555},
3404 {"<t>0.1e10</t>", S_OK, 0x41cdcd6500000000},
3405 {"<t>1e</t>", WS_E_INVALID_FORMAT, 0},
3406 {"<t>1e0</t>", S_OK, 0x3ff0000000000000},
3407 {"<t>1e+1</t>", S_OK, 0x4024000000000000},
3408 {"<t>1e-1</t>", S_OK, 0x3fb999999999999a},
3409 {"<t>e10</t>", WS_E_INVALID_FORMAT, 0},
3410 {"<t>1e10.</t>", WS_E_INVALID_FORMAT, 0},
3411 {"<t>1E10</t>", S_OK, 0x4202a05f20000000},
3412 {"<t>1e10</t>", S_OK, 0x4202a05f20000000},
3413 {"<t>1e-10</t>", S_OK, 0x3ddb7cdfd9d7bdbb},
3414 {"<t>1.7976931348623158e308</t>", S_OK, 0x7fefffffffffffff},
3415 {"<t>1.7976931348623159e308</t>", S_OK, 0x7ff0000000000000},
3416 {"<t>4.94065645841247e-324</t>", S_OK, 0x1},
3418 HRESULT hr;
3419 WS_XML_READER *reader;
3420 WS_HEAP *heap;
3421 ULONGLONG val;
3422 ULONG i;
3424 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3425 ok( hr == S_OK, "got %08x\n", hr );
3427 hr = WsCreateReader( NULL, 0, &reader, NULL );
3428 ok( hr == S_OK, "got %08x\n", hr );
3430 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3432 val = 0;
3433 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3434 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DOUBLE_TYPE, NULL,
3435 WS_READ_REQUIRED_VALUE, heap, &val, sizeof(val), NULL );
3436 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3437 if (hr == tests[i].hr) ok( val == tests[i].val, "%u: got %x%08x\n", i, (ULONG)(val >> 32), (ULONG)val );
3440 WsFreeReader( reader );
3441 WsFreeHeap( heap );
3444 static void test_WsReadElement(void)
3446 WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
3447 HRESULT hr;
3448 WS_XML_READER *reader;
3449 WS_ELEMENT_DESCRIPTION desc;
3450 UINT32 val;
3452 hr = WsCreateReader( NULL, 0, &reader, NULL );
3453 ok( hr == S_OK, "got %08x\n", hr );
3455 desc.elementLocalName = &localname;
3456 desc.elementNs = &ns;
3457 desc.type = WS_UINT32_TYPE;
3458 desc.typeDescription = NULL;
3460 prepare_struct_type_test( reader, "<t>1</t>" );
3461 hr = WsReadElement( NULL, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3462 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3464 prepare_struct_type_test( reader, "<t>1</t>" );
3465 hr = WsReadElement( reader, NULL, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3466 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3468 prepare_struct_type_test( reader, "<t>1</t>" );
3469 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, NULL, sizeof(val), NULL );
3470 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3472 prepare_struct_type_test( reader, "<t>1</t>" );
3473 val = 0xdeadbeef;
3474 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3475 ok( hr == S_OK, "got %08x\n", hr );
3476 ok( val == 1, "got %u\n", val );
3478 WsFreeReader( reader );
3481 static void test_WsReadValue(void)
3483 HRESULT hr;
3484 WS_XML_READER *reader;
3485 UINT32 val;
3487 hr = WsCreateReader( NULL, 0, &reader, NULL );
3488 ok( hr == S_OK, "got %08x\n", hr );
3490 prepare_struct_type_test( reader, "<t>1</t>" );
3491 hr = WsReadValue( NULL, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3492 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3494 prepare_struct_type_test( reader, "<t>1</t>" );
3495 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, NULL, sizeof(val), NULL );
3496 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3498 /* reader must be positioned correctly */
3499 prepare_struct_type_test( reader, "<t>1</t>" );
3500 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3501 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3503 prepare_struct_type_test( reader, "<t>1</t>" );
3504 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3505 ok( hr == S_OK, "got %08x\n", hr );
3507 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3508 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3510 prepare_struct_type_test( reader, "<t>1</t>" );
3511 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3512 ok( hr == S_OK, "got %08x\n", hr );
3514 hr = WsReadStartElement( reader, NULL );
3515 ok( hr == S_OK, "got %08x\n", hr );
3517 val = 0xdeadbeef;
3518 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3519 ok( hr == S_OK, "got %08x\n", hr );
3520 ok( val == 1, "got %u\n", val );
3522 prepare_struct_type_test( reader, "<u t='1'></u>" );
3523 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3524 ok( hr == S_OK, "got %08x\n", hr );
3526 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3527 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3529 WsFreeReader( reader );
3532 static void test_WsResetError(void)
3534 WS_ERROR_PROPERTY prop;
3535 ULONG size, code;
3536 WS_ERROR *error;
3537 LANGID langid;
3538 HRESULT hr;
3540 hr = WsResetError( NULL );
3541 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3543 error = NULL;
3544 hr = WsCreateError( NULL, 0, &error );
3545 ok( hr == S_OK, "got %08x\n", hr );
3546 ok( error != NULL, "error not set\n" );
3548 code = 0xdeadbeef;
3549 size = sizeof(code);
3550 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3551 ok( hr == S_OK, "got %08x\n", hr );
3553 hr = WsResetError( error );
3554 ok( hr == S_OK, "got %08x\n", hr );
3556 code = 0xdeadbeef;
3557 size = sizeof(code);
3558 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3559 ok( hr == S_OK, "got %08x\n", hr );
3560 ok( !code, "got %u\n", code );
3562 WsFreeError( error );
3564 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
3565 prop.id = WS_ERROR_PROPERTY_LANGID;
3566 prop.value = &langid;
3567 prop.valueSize = sizeof(langid);
3568 hr = WsCreateError( &prop, 1, &error );
3569 ok( hr == S_OK, "got %08x\n", hr );
3571 langid = 0xdead;
3572 size = sizeof(langid);
3573 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3574 ok( hr == S_OK, "got %08x\n", hr );
3575 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3577 hr = WsResetError( error );
3578 ok( hr == S_OK, "got %08x\n", hr );
3580 langid = 0xdead;
3581 size = sizeof(langid);
3582 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3583 ok( hr == S_OK, "got %08x\n", hr );
3584 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3586 WsFreeError( error );
3589 static void test_WsGetReaderPosition(void)
3591 WS_HEAP *heap;
3592 WS_XML_READER *reader;
3593 WS_XML_BUFFER *buffer;
3594 WS_XML_NODE_POSITION pos;
3595 HRESULT hr;
3597 hr = WsGetReaderPosition( NULL, NULL, NULL );
3598 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3600 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3601 ok( hr == S_OK, "got %08x\n", hr );
3603 hr = WsCreateReader( NULL, 0, &reader, NULL );
3604 ok( hr == S_OK, "got %08x\n", hr );
3606 /* reader must be set to an XML buffer */
3607 hr = WsGetReaderPosition( reader, &pos, NULL );
3608 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3610 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
3611 ok( hr == S_OK, "got %08x\n", hr );
3613 hr = WsGetReaderPosition( reader, &pos, NULL );
3614 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3616 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
3617 ok( hr == S_OK, "got %08x\n", hr );
3619 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
3620 ok( hr == S_OK, "got %08x\n", hr );
3622 hr = WsGetReaderPosition( reader, NULL, NULL );
3623 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3625 pos.buffer = pos.node = NULL;
3626 hr = WsGetReaderPosition( reader, &pos, NULL );
3627 ok( hr == S_OK, "got %08x\n", hr );
3628 ok( pos.buffer != NULL, "buffer not set\n" );
3629 ok( pos.node != NULL, "node not set\n" );
3631 WsFreeReader( reader );
3632 WsFreeHeap( heap );
3635 static void test_WsSetReaderPosition(void)
3637 WS_HEAP *heap;
3638 WS_XML_READER *reader;
3639 WS_XML_BUFFER *buf1, *buf2;
3640 WS_XML_NODE_POSITION pos;
3641 HRESULT hr;
3643 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3644 ok( hr == S_OK, "got %08x\n", hr );
3646 hr = WsSetReaderPosition( NULL, NULL, NULL );
3647 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3649 hr = WsCreateReader( NULL, 0, &reader, NULL );
3650 ok( hr == S_OK, "got %08x\n", hr );
3652 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf1, NULL );
3653 ok( hr == S_OK, "got %08x\n", hr );
3655 hr = WsSetInputToBuffer( reader, buf1, NULL, 0, NULL );
3656 ok( hr == S_OK, "got %08x\n", hr );
3658 hr = WsSetReaderPosition( reader, NULL, NULL );
3659 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3661 pos.buffer = pos.node = NULL;
3662 hr = WsGetReaderPosition( reader, &pos, NULL );
3663 ok( hr == S_OK, "got %08x\n", hr );
3664 ok( pos.buffer == buf1, "wrong buffer\n" );
3665 ok( pos.node != NULL, "node not set\n" );
3667 hr = WsSetReaderPosition( reader, &pos, NULL );
3668 ok( hr == S_OK, "got %08x\n", hr );
3670 /* different buffer */
3671 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf2, NULL );
3672 ok( hr == S_OK, "got %08x\n", hr );
3674 pos.buffer = buf2;
3675 hr = WsSetReaderPosition( reader, &pos, NULL );
3676 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3678 WsFreeReader( reader );
3679 WsFreeHeap( heap );
3682 static void test_entities(void)
3684 static const char str1[] = "<t>&#xA</t>";
3685 static const char str2[] = "<t>&#xA;</t>";
3686 static const char str3[] = "<t>&#xa;</t>";
3687 static const char str4[] = "<t>&#xaaaa;</t>";
3688 static const char str5[] = "<t>&#xaaaaa;</t>";
3689 static const char str6[] = "<t>&1</t>";
3690 static const char str7[] = "<t>&1;</t>";
3691 static const char str8[] = "<t>&1111;</t>";
3692 static const char str9[] = "<t>&11111;</t>";
3693 static const char str10[] = "<t>&lt;</t>";
3694 static const char str11[] = "<t>&gt;</t>";
3695 static const char str12[] = "<t>&quot;</t>";
3696 static const char str13[] = "<t>&amp;</t>";
3697 static const char str14[] = "<t>&apos;</t>";
3698 static const char str15[] = "<t>&sopa;</t>";
3699 static const char str16[] = "<t>&#;</t>";
3700 static const char str17[] = "<t>&;</t>";
3701 static const char str18[] = "<t>&&</t>";
3702 static const char str19[] = "<t>&</t>";
3703 static const char str20[] = "<t>&#xaaaaaa;</t>";
3704 static const char str21[] = "<t>&#xd7ff;</t>";
3705 static const char str22[] = "<t>&#xd800;</t>";
3706 static const char str23[] = "<t>&#xdfff;</t>";
3707 static const char str24[] = "<t>&#xe000;</t>";
3708 static const char str25[] = "<t>&#xfffe;</t>";
3709 static const char str26[] = "<t>&#xffff;</t>";
3710 static const char str27[] = "<t>&LT;</t>";
3711 static const char str28[] = "<t>&#x0;</t>";
3712 static const char str29[] = "<t>&#0;</t>";
3713 static const char str30[] = "<t>&#65;</t>";
3714 static const char str31[] = "<t>&#65393;</t>";
3715 static const char str32[] = "<t>&#x10ffff;</t>";
3716 static const char str33[] = "<t>&#x110000;</t>";
3717 static const char str34[] = "<t>&#1114111;</t>";
3718 static const char str35[] = "<t>&#1114112;</t>";
3719 static const char res4[] = {0xea, 0xaa, 0xaa, 0x00};
3720 static const char res5[] = {0xf2, 0xaa, 0xaa, 0xaa, 0x00};
3721 static const char res21[] = {0xed, 0x9f, 0xbf, 0x00};
3722 static const char res24[] = {0xee, 0x80, 0x80, 0x00};
3723 static const char res31[] = {0xef, 0xbd, 0xb1, 0x00};
3724 static const char res32[] = {0xf4, 0x8f, 0xbf, 0xbf, 0x00};
3725 static const struct
3727 const char *str;
3728 HRESULT hr;
3729 const char *res;
3731 tests[] =
3733 { str1, WS_E_INVALID_FORMAT },
3734 { str2, S_OK, "\n" },
3735 { str3, S_OK, "\n" },
3736 { str4, S_OK, res4 },
3737 { str5, S_OK, res5 },
3738 { str6, WS_E_INVALID_FORMAT },
3739 { str7, WS_E_INVALID_FORMAT },
3740 { str8, WS_E_INVALID_FORMAT },
3741 { str9, WS_E_INVALID_FORMAT },
3742 { str10, S_OK, "<" },
3743 { str11, S_OK, ">" },
3744 { str12, S_OK, "\"" },
3745 { str13, S_OK, "&" },
3746 { str14, S_OK, "'" },
3747 { str15, WS_E_INVALID_FORMAT },
3748 { str16, WS_E_INVALID_FORMAT },
3749 { str17, WS_E_INVALID_FORMAT },
3750 { str18, WS_E_INVALID_FORMAT },
3751 { str19, WS_E_INVALID_FORMAT },
3752 { str20, WS_E_INVALID_FORMAT },
3753 { str21, S_OK, res21 },
3754 { str22, WS_E_INVALID_FORMAT },
3755 { str23, WS_E_INVALID_FORMAT },
3756 { str24, S_OK, res24 },
3757 { str25, WS_E_INVALID_FORMAT },
3758 { str26, WS_E_INVALID_FORMAT },
3759 { str27, WS_E_INVALID_FORMAT },
3760 { str28, WS_E_INVALID_FORMAT },
3761 { str29, WS_E_INVALID_FORMAT },
3762 { str30, S_OK, "A" },
3763 { str31, S_OK, res31 },
3764 { str32, S_OK, res32 },
3765 { str33, WS_E_INVALID_FORMAT },
3766 { str34, S_OK, res32 },
3767 { str35, WS_E_INVALID_FORMAT },
3769 HRESULT hr;
3770 WS_XML_READER *reader;
3771 const WS_XML_NODE *node;
3772 const WS_XML_UTF8_TEXT *utf8;
3773 ULONG i;
3775 hr = WsCreateReader( NULL, 0, &reader, NULL );
3776 ok( hr == S_OK, "got %08x\n", hr );
3778 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3780 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
3781 ok( hr == S_OK, "%u: got %08x\n", i, hr );
3783 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3784 ok( hr == S_OK, "%u: got %08x\n", i, hr );
3786 hr = WsReadNode( reader, NULL );
3787 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3788 if (hr != S_OK) continue;
3790 hr = WsGetReaderNode( reader, &node, NULL );
3791 ok( hr == S_OK, "%u: got %08x\n", i, hr );
3793 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_TEXT_NODE *)node)->text;
3794 ok( utf8->value.length == strlen(tests[i].res), "%u: got %u\n", i, utf8->value.length );
3795 ok( !memcmp( utf8->value.bytes, tests[i].res, strlen(tests[i].res) ), "%u: wrong data\n", i );
3798 hr = set_input( reader, "<t a='&#xA;&#xA;'/>", sizeof("<t a='&#xA;&#xA;'/>") - 1 );
3799 ok( hr == S_OK, "got %08x\n", hr );
3801 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3802 ok( hr == S_OK, "got %08x\n", hr );
3804 hr = WsGetReaderNode( reader, &node, NULL );
3805 ok( hr == S_OK, "got %08x\n", hr );
3807 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_ELEMENT_NODE *)node)->attributes[0]->value;
3808 ok( utf8->value.length == 2, "got %u\n", utf8->value.length );
3809 ok( !memcmp( utf8->value.bytes, "\n\n", 2 ), "wrong data\n" );
3811 WsFreeReader( reader );
3814 static void test_field_options(void)
3816 static const char xml[] =
3817 "<t xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><wsz i:nil=\"true\"/>"
3818 "<s i:nil=\"true\"/></t>";
3819 static const GUID guid_null = {0};
3820 HRESULT hr;
3821 WS_HEAP *heap;
3822 WS_XML_READER *reader;
3823 WS_STRUCT_DESCRIPTION s, s2;
3824 WS_FIELD_DESCRIPTION f, f2, f3, f4, f5, *fields[4], *fields2[1];
3825 WS_XML_STRING ns = {0, NULL}, str_wsz = {3, (BYTE *)"wsz"}, str_s = {1, (BYTE *)"s"};
3826 WS_XML_STRING str_int32 = {5, (BYTE *)"int32"}, str_guid = {4, (BYTE *)"guid"};
3827 WS_DEFAULT_VALUE def_val;
3828 INT32 val_int32;
3829 struct s
3831 INT32 int32;
3833 struct test
3835 WCHAR *wsz;
3836 struct s *s;
3837 INT32 int32;
3838 GUID guid;
3839 } *test;
3841 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3842 ok( hr == S_OK, "got %08x\n", hr );
3844 hr = WsCreateReader( NULL, 0, &reader, NULL );
3845 ok( hr == S_OK, "got %08x\n", hr );
3847 hr = set_input( reader, xml, sizeof(xml) - 1 );
3848 ok( hr == S_OK, "got %08x\n", hr );
3850 memset( &f, 0, sizeof(f) );
3851 f.mapping = WS_ELEMENT_FIELD_MAPPING;
3852 f.localName = &str_wsz;
3853 f.ns = &ns;
3854 f.type = WS_WSZ_TYPE;
3855 f.options = WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
3856 fields[0] = &f;
3858 memset( &f3, 0, sizeof(f3) );
3859 f3.mapping = WS_ELEMENT_FIELD_MAPPING;
3860 f3.localName = &str_int32;
3861 f3.ns = &ns;
3862 f3.type = WS_INT32_TYPE;
3863 fields2[0] = &f3;
3865 memset( &s2, 0, sizeof(s2) );
3866 s2.size = sizeof(struct s);
3867 s2.alignment = TYPE_ALIGNMENT(struct s);
3868 s2.fields = fields2;
3869 s2.fieldCount = 1;
3871 memset( &f2, 0, sizeof(f2) );
3872 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
3873 f2.localName = &str_s;
3874 f2.ns = &ns;
3875 f2.type = WS_STRUCT_TYPE;
3876 f2.typeDescription = &s2;
3877 f2.offset = FIELD_OFFSET(struct test, s);
3878 f2.options = WS_FIELD_POINTER|WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
3879 fields[1] = &f2;
3881 val_int32 = -1;
3882 def_val.value = &val_int32;
3883 def_val.valueSize = sizeof(val_int32);
3885 memset( &f4, 0, sizeof(f4) );
3886 f4.mapping = WS_ELEMENT_FIELD_MAPPING;
3887 f4.localName = &str_int32;
3888 f4.ns = &ns;
3889 f4.type = WS_INT32_TYPE;
3890 f4.offset = FIELD_OFFSET(struct test, int32);
3891 f4.options = WS_FIELD_OPTIONAL;
3892 f4.defaultValue = &def_val;
3893 fields[2] = &f4;
3895 memset( &f5, 0, sizeof(f5) );
3896 f5.mapping = WS_ELEMENT_FIELD_MAPPING;
3897 f5.localName = &str_guid;
3898 f5.ns = &ns;
3899 f5.type = WS_GUID_TYPE;
3900 f5.offset = FIELD_OFFSET(struct test, guid);
3901 f5.options = WS_FIELD_OPTIONAL;
3902 fields[3] = &f5;
3904 memset( &s, 0, sizeof(s) );
3905 s.size = sizeof(struct test);
3906 s.alignment = TYPE_ALIGNMENT(struct test);
3907 s.fields = fields;
3908 s.fieldCount = 4;
3910 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3911 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3912 ok( hr == S_OK, "got %08x\n", hr );
3913 ok( !test->wsz, "wsz is set\n" );
3914 ok( !test->s, "s is set\n" );
3915 ok( test->int32 == -1, "got %d\n", test->int32 );
3916 ok( IsEqualGUID( &test->guid, &guid_null ), "wrong guid\n" );
3918 WsFreeReader( reader );
3919 WsFreeHeap( heap );
3922 static void test_WsReadBytes(void)
3924 HRESULT hr;
3925 WS_XML_READER *reader;
3926 const WS_XML_NODE *node;
3927 const WS_XML_TEXT_NODE *text;
3928 const WS_XML_UTF8_TEXT *utf8;
3929 BYTE buf[4];
3930 ULONG count;
3932 hr = WsCreateReader( NULL, 0, &reader, NULL );
3933 ok( hr == S_OK, "got %08x\n", hr );
3935 hr = WsReadBytes( NULL, NULL, 0, NULL, NULL );
3936 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3938 hr = WsReadBytes( reader, NULL, 0, NULL, NULL );
3939 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3941 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
3942 ok( hr == S_OK, "got %08x\n", hr );
3944 hr = WsReadBytes( reader, NULL, 0, NULL, NULL );
3945 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3947 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
3948 ok( hr == S_OK, "got %08x\n", hr );
3950 hr = WsReadBytes( reader, buf, 0, NULL, NULL );
3951 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3953 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
3954 ok( hr == S_OK, "got %08x\n", hr );
3956 count = 0xdeadbeef;
3957 hr = WsReadBytes( reader, NULL, 0, &count, NULL );
3958 ok( hr == S_OK, "got %08x\n", hr );
3959 ok( !count, "got %u\n", count );
3961 count = 0xdeadbeef;
3962 hr = WsReadBytes( reader, NULL, 1, &count, NULL );
3963 ok( hr == S_OK, "got %08x\n", hr );
3964 ok( !count, "got %u\n", count );
3966 buf[0] = 0;
3967 count = 0xdeadbeef;
3968 hr = WsReadBytes( reader, buf, 0, &count, NULL );
3969 ok( hr == S_OK, "got %08x\n", hr );
3970 ok( !count, "got %u\n", count );
3971 ok( !buf[0], "wrong data\n" );
3973 buf[0] = 0;
3974 count = 0xdeadbeef;
3975 hr = WsReadBytes( reader, buf, 2, &count, NULL );
3976 ok( hr == S_OK, "got %08x\n", hr );
3977 ok( !count, "got %u\n", count );
3978 ok( !buf[0], "wrong data\n" );
3980 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3981 ok( hr == S_OK, "got %08x\n", hr );
3983 buf[0] = 0;
3984 count = 0xdeadbeef;
3985 hr = WsReadBytes( reader, buf, 2, &count, NULL );
3986 ok( hr == S_OK, "got %08x\n", hr );
3987 ok( !count, "got %u\n", count );
3988 ok( !buf[0], "wrong data\n" );
3990 hr = WsReadStartElement( reader, NULL );
3991 ok( hr == S_OK, "got %08x\n", hr );
3993 count = 0xdeadbeef;
3994 hr = WsReadBytes( reader, NULL, 0, &count, NULL );
3995 ok( hr == S_OK, "got %08x\n", hr );
3996 ok( !count, "got %u\n", count );
3998 buf[0] = 0;
3999 count = 0xdeadbeef;
4000 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4001 ok( hr == S_OK, "got %08x\n", hr );
4002 ok( count == 2, "got %u\n", count );
4003 ok( !memcmp( buf, "te", 2 ), "wrong data\n" );
4005 hr = WsGetReaderNode( reader, &node, NULL );
4006 ok( hr == S_OK, "got %08x\n", hr );
4007 text = (const WS_XML_TEXT_NODE *)node;
4008 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4009 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4010 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4011 ok( utf8->value.length == 8, "got %u\n", utf8->value.length );
4012 ok( !memcmp( utf8->value.bytes, "dGV4dA==", 8 ), "wrong data\n" );
4014 buf[0] = 0;
4015 count = 0xdeadbeef;
4016 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4017 ok( hr == S_OK, "got %08x\n", hr );
4018 ok( count == 2, "got %u\n", count );
4019 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4021 hr = WsGetReaderNode( reader, &node, NULL );
4022 ok( hr == S_OK, "got %08x\n", hr );
4023 text = (const WS_XML_TEXT_NODE *)node;
4024 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4026 count = 0xdeadbeef;
4027 hr = WsReadBytes( reader, buf, 1, &count, NULL );
4028 ok( hr == S_OK, "got %08x\n", hr );
4029 ok( !count, "got %u\n", count );
4031 hr = WsGetReaderNode( reader, &node, NULL );
4032 ok( hr == S_OK, "got %08x\n", hr );
4033 text = (const WS_XML_TEXT_NODE *)node;
4034 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4036 WsFreeReader( reader );
4039 static void test_WsReadChars(void)
4041 static const WCHAR textW[] = {'t','e','x','t'};
4042 HRESULT hr;
4043 WS_XML_READER *reader;
4044 const WS_XML_NODE *node;
4045 const WS_XML_TEXT_NODE *text;
4046 const WS_XML_UTF8_TEXT *utf8;
4047 unsigned char buf[4];
4048 WCHAR bufW[4];
4049 ULONG count;
4051 hr = WsCreateReader( NULL, 0, &reader, NULL );
4052 ok( hr == S_OK, "got %08x\n", hr );
4054 hr = WsReadChars( NULL, NULL, 0, NULL, NULL );
4055 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4057 hr = WsReadChars( reader, NULL, 0, NULL, NULL );
4058 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4060 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4061 ok( hr == S_OK, "got %08x\n", hr );
4063 hr = WsReadChars( reader, NULL, 0, NULL, NULL );
4064 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4066 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4067 ok( hr == S_OK, "got %08x\n", hr );
4069 hr = WsReadChars( reader, bufW, 0, NULL, NULL );
4070 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4072 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4073 ok( hr == S_OK, "got %08x\n", hr );
4075 count = 0xdeadbeef;
4076 hr = WsReadChars( reader, NULL, 0, &count, NULL );
4077 ok( hr == S_OK, "got %08x\n", hr );
4078 ok( !count, "got %u\n", count );
4080 count = 0xdeadbeef;
4081 hr = WsReadChars( reader, NULL, 1, &count, NULL );
4082 ok( hr == S_OK, "got %08x\n", hr );
4083 ok( !count, "got %u\n", count );
4085 buf[0] = 0;
4086 count = 0xdeadbeef;
4087 hr = WsReadChars( reader, bufW, 0, &count, NULL );
4088 ok( hr == S_OK, "got %08x\n", hr );
4089 ok( !count, "got %u\n", count );
4090 ok( !buf[0], "wrong data\n" );
4092 buf[0] = 0;
4093 count = 0xdeadbeef;
4094 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4095 ok( hr == S_OK, "got %08x\n", hr );
4096 ok( !count, "got %u\n", count );
4097 ok( !buf[0], "wrong data\n" );
4099 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4100 ok( hr == S_OK, "got %08x\n", hr );
4102 buf[0] = 0;
4103 count = 0xdeadbeef;
4104 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4105 ok( hr == S_OK, "got %08x\n", hr );
4106 ok( !count, "got %u\n", count );
4107 ok( !buf[0], "wrong data\n" );
4109 hr = WsReadStartElement( reader, NULL );
4110 ok( hr == S_OK, "got %08x\n", hr );
4112 count = 0xdeadbeef;
4113 hr = WsReadChars( reader, NULL, 0, &count, NULL );
4114 ok( hr == S_OK, "got %08x\n", hr );
4115 ok( !count, "got %u\n", count );
4117 buf[0] = 0;
4118 count = 0xdeadbeef;
4119 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4120 ok( hr == S_OK, "got %08x\n", hr );
4121 ok( count == 2, "got %u\n", count );
4122 ok( !memcmp( bufW, textW, 2 * sizeof(WCHAR) ), "wrong data\n" );
4124 hr = WsGetReaderNode( reader, &node, NULL );
4125 ok( hr == S_OK, "got %08x\n", hr );
4126 text = (const WS_XML_TEXT_NODE *)node;
4127 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4128 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4129 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4130 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4131 ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" );
4133 /* continue reading in a different encoding */
4134 buf[0] = 0;
4135 count = 0xdeadbeef;
4136 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4137 ok( hr == S_OK, "got %08x\n", hr );
4138 ok( count == 2, "got %u\n", count );
4139 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4141 hr = WsGetReaderNode( reader, &node, NULL );
4142 ok( hr == S_OK, "got %08x\n", hr );
4143 text = (const WS_XML_TEXT_NODE *)node;
4144 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4146 count = 0xdeadbeef;
4147 hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL );
4148 ok( hr == S_OK, "got %08x\n", hr );
4149 ok( !count, "got %u\n", count );
4151 hr = WsGetReaderNode( reader, &node, NULL );
4152 ok( hr == S_OK, "got %08x\n", hr );
4153 text = (const WS_XML_TEXT_NODE *)node;
4154 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4156 WsFreeReader( reader );
4159 static void test_WsReadCharsUtf8(void)
4161 HRESULT hr;
4162 WS_XML_READER *reader;
4163 const WS_XML_NODE *node;
4164 const WS_XML_TEXT_NODE *text;
4165 const WS_XML_UTF8_TEXT *utf8;
4166 BYTE buf[4];
4167 ULONG count;
4169 hr = WsCreateReader( NULL, 0, &reader, NULL );
4170 ok( hr == S_OK, "got %08x\n", hr );
4172 hr = WsReadCharsUtf8( NULL, NULL, 0, NULL, NULL );
4173 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4175 hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL );
4176 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4178 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4179 ok( hr == S_OK, "got %08x\n", hr );
4181 hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL );
4182 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4184 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4185 ok( hr == S_OK, "got %08x\n", hr );
4187 hr = WsReadCharsUtf8( reader, buf, 0, NULL, NULL );
4188 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4190 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4191 ok( hr == S_OK, "got %08x\n", hr );
4193 count = 0xdeadbeef;
4194 hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL );
4195 ok( hr == S_OK, "got %08x\n", hr );
4196 ok( !count, "got %u\n", count );
4198 count = 0xdeadbeef;
4199 hr = WsReadCharsUtf8( reader, NULL, 1, &count, NULL );
4200 ok( hr == S_OK, "got %08x\n", hr );
4201 ok( !count, "got %u\n", count );
4203 buf[0] = 0;
4204 count = 0xdeadbeef;
4205 hr = WsReadCharsUtf8( reader, buf, 0, &count, NULL );
4206 ok( hr == S_OK, "got %08x\n", hr );
4207 ok( !count, "got %u\n", count );
4208 ok( !buf[0], "wrong data\n" );
4210 buf[0] = 0;
4211 count = 0xdeadbeef;
4212 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4213 ok( hr == S_OK, "got %08x\n", hr );
4214 ok( !count, "got %u\n", count );
4215 ok( !buf[0], "wrong data\n" );
4217 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4218 ok( hr == S_OK, "got %08x\n", hr );
4220 buf[0] = 0;
4221 count = 0xdeadbeef;
4222 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4223 ok( hr == S_OK, "got %08x\n", hr );
4224 ok( !count, "got %u\n", count );
4225 ok( !buf[0], "wrong data\n" );
4227 hr = WsReadStartElement( reader, NULL );
4228 ok( hr == S_OK, "got %08x\n", hr );
4230 count = 0xdeadbeef;
4231 hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL );
4232 ok( hr == S_OK, "got %08x\n", hr );
4233 ok( !count, "got %u\n", count );
4235 buf[0] = 0;
4236 count = 0xdeadbeef;
4237 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4238 ok( hr == S_OK, "got %08x\n", hr );
4239 ok( count == 2, "got %u\n", count );
4240 ok( !memcmp( buf, "te", 2 ), "wrong data\n" );
4242 hr = WsGetReaderNode( reader, &node, NULL );
4243 ok( hr == S_OK, "got %08x\n", hr );
4244 text = (const WS_XML_TEXT_NODE *)node;
4245 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4246 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4247 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4248 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4249 ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" );
4251 buf[0] = 0;
4252 count = 0xdeadbeef;
4253 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4254 ok( hr == S_OK, "got %08x\n", hr );
4255 ok( count == 2, "got %u\n", count );
4256 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4258 hr = WsGetReaderNode( reader, &node, NULL );
4259 ok( hr == S_OK, "got %08x\n", hr );
4260 text = (const WS_XML_TEXT_NODE *)node;
4261 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4263 count = 0xdeadbeef;
4264 hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL );
4265 ok( hr == S_OK, "got %08x\n", hr );
4266 ok( !count, "got %u\n", count );
4268 hr = WsGetReaderNode( reader, &node, NULL );
4269 ok( hr == S_OK, "got %08x\n", hr );
4270 text = (const WS_XML_TEXT_NODE *)node;
4271 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4273 WsFreeReader( reader );
4276 static void test_WsReadQualifiedName(void)
4278 static const char utf8[] = {'<','a','>',0xc3,0xab,'<','/','a','>',0};
4279 static const char localname_utf8[] = {0xc3,0xab,0};
4280 WS_XML_STRING prefix, localname, ns;
4281 WS_XML_READER *reader;
4282 WS_HEAP *heap;
4283 HRESULT hr;
4284 BOOL found;
4285 ULONG i;
4286 static const struct
4288 const char *str;
4289 HRESULT hr;
4290 const char *prefix;
4291 const char *localname;
4292 const char *ns;
4293 } tests[] =
4295 { "<a></a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4296 { "<a> </a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4297 { "<a>:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4298 { "<a>t</a>", S_OK, "", "t", "" },
4299 { "<a>p:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4300 { "<a>p:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4301 { "<a>:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4302 { "<a xmlns:p=\"ns\">p:t</a>", S_OK, "p", "t", "ns" },
4303 { "<a xmlns:p=\"ns\">p:t:</a>", S_OK, "p", "t:", "ns" },
4304 { "<a xmlns:p=\"ns\">p:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4305 { "<a xmlns:p=\"ns\">:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4306 { "<a xmlns:p=\"ns\">:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4307 { "<a xmlns:p=\"ns\">t</a>", S_OK, "", "t", "" },
4308 { "<a xmlns:p=\"ns\"> </a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4309 { "<a xmlns:p=\"ns\"></a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4310 { "<a xmlns:p=\"ns\">p:t u</a>", S_OK, "p", "t u", "ns" },
4311 { utf8, S_OK, "", localname_utf8, "" },
4312 { "<a> t </a>", S_OK, "", "t", "" },
4313 { "<a xmlns:p=\"ns\"> p:t</a>", S_OK, "p", "t", "ns" },
4314 { "<a xmlns:p=\"ns\">p :t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4315 { "<a xmlns:p=\"ns\">p: t</a>", S_OK, "p", " t", "ns" },
4318 hr = WsReadQualifiedName( NULL, NULL, NULL, NULL, NULL, NULL );
4319 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4321 hr = WsCreateReader( NULL, 0, &reader, NULL );
4322 ok( hr == S_OK, "got %08x\n", hr );
4324 hr = WsReadQualifiedName( reader, NULL, NULL, NULL, NULL, NULL );
4325 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4327 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
4328 ok( hr == S_OK, "got %08x\n", hr );
4330 hr = WsReadQualifiedName( reader, heap, NULL, NULL, NULL, NULL );
4331 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4333 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4334 ok( hr == S_OK, "got %08x\n", hr );
4335 hr = WsReadQualifiedName( reader, heap, NULL, NULL, NULL, NULL );
4336 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4338 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4339 ok( hr == S_OK, "got %08x\n", hr );
4340 hr = WsReadQualifiedName( reader, heap, NULL, &localname, NULL, NULL );
4341 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
4343 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
4345 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
4346 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4348 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4349 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4351 hr = WsReadStartElement( reader, NULL );
4352 ok( hr == S_OK, "%u: got %08x\n", i, hr );
4354 prefix.length = localname.length = ns.length = 0xdeadbeef;
4355 prefix.bytes = localname.bytes = ns.bytes = (BYTE *)0xdeadbeef;
4357 hr = WsReadQualifiedName( reader, heap, &prefix, &localname, &ns, NULL );
4358 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
4359 if (tests[i].hr == S_OK && hr == S_OK)
4361 ok( prefix.length == strlen( tests[i].prefix ), "%u: got %u\n", i, prefix.length );
4362 ok( !memcmp( prefix.bytes, tests[i].prefix, prefix.length ), "%u: wrong data\n", i );
4364 ok( localname.length == strlen( tests[i].localname ), "%u: got %u\n", i, localname.length );
4365 ok( !memcmp( localname.bytes, tests[i].localname, localname.length ), "%u: wrong data\n", i );
4367 ok( ns.length == strlen( tests[i].ns ), "%u: got %u\n", i, ns.length );
4368 ok( !memcmp( ns.bytes, tests[i].ns, ns.length ), "%u: wrong data\n", i );
4370 else if (tests[i].hr != S_OK)
4372 ok( prefix.length == 0xdeadbeef, "got %u\n", prefix.length );
4373 ok( prefix.bytes == (BYTE *)0xdeadbeef, "got %p\n", prefix.bytes );
4375 ok( localname.length == 0xdeadbeef, "got %u\n", localname.length );
4376 ok( localname.bytes == (BYTE *)0xdeadbeef, "got %p\n", localname.bytes );
4378 ok( ns.length == 0xdeadbeef, "got %u\n", ns.length );
4379 ok( ns.bytes == (BYTE *)0xdeadbeef, "got %p\n", ns.bytes );
4383 WsFreeHeap( heap );
4384 WsFreeReader( reader );
4387 static void test_WsReadAttribute(void)
4389 WS_XML_STRING localname = {1, (BYTE *)"a"}, ns = {0, NULL};
4390 WS_XML_READER *reader;
4391 WS_ATTRIBUTE_DESCRIPTION desc;
4392 WS_HEAP *heap;
4393 UINT32 *val;
4394 BOOL found;
4395 HRESULT hr;
4397 hr = WsReadAttribute( NULL, NULL, 0, NULL, NULL, 0, NULL );
4398 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4400 hr = WsCreateReader( NULL, 0, &reader, NULL );
4401 ok( hr == S_OK, "got %08x\n", hr );
4403 hr = WsReadAttribute( reader, NULL, 0, NULL, NULL, 0, NULL );
4404 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4406 desc.attributeLocalName = &localname;
4407 desc.attributeNs = &ns;
4408 desc.type = WS_UINT32_TYPE;
4409 desc.typeDescription = NULL;
4410 hr = WsReadAttribute( reader, &desc, 0, NULL, NULL, 0, NULL );
4411 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4413 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, NULL, NULL, 0, NULL );
4414 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4416 hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL );
4417 ok( hr == S_OK, "got %08x\n", hr );
4419 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, NULL, 0, NULL );
4420 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4422 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, &val, sizeof(val), NULL );
4423 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4425 prepare_struct_type_test( reader, "<t a='1'>" );
4426 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4427 ok( hr == S_OK, "got %08x\n", hr );
4429 val = NULL;
4430 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, &val, sizeof(val), NULL );
4431 ok( hr == S_OK, "got %08x\n", hr );
4432 ok( val != NULL, "val not set\n" );
4433 ok( *val == 1, "got %u\n", *val );
4435 WsFreeHeap( heap );
4436 WsFreeReader( reader );
4439 static void test_WsSkipNode(void)
4441 const WS_XML_NODE *node;
4442 WS_XML_READER *reader;
4443 HRESULT hr;
4445 hr = WsSkipNode( NULL, NULL );
4446 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4448 hr = WsCreateReader( NULL, 0, &reader, NULL );
4449 ok( hr == S_OK, "got %08x\n", hr );
4451 hr = WsSkipNode( reader, NULL );
4452 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4454 hr = set_input( reader, "<t><u></u></t>", sizeof("<t><u></u></t>") - 1 );
4455 ok( hr == S_OK, "got %08x\n", hr );
4457 hr = WsGetReaderNode( reader, &node, NULL );
4458 ok( hr == S_OK, "got %08x\n", hr );
4459 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
4461 /* BOF */
4462 hr = WsSkipNode( reader, NULL );
4463 ok( hr == S_OK, "got %08x\n", hr );
4464 hr = WsGetReaderNode( reader, &node, NULL );
4465 ok( hr == S_OK, "got %08x\n", hr );
4466 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4468 /* element */
4469 hr = WsSkipNode( reader, NULL );
4470 ok( hr == S_OK, "got %08x\n", hr );
4471 hr = WsGetReaderNode( reader, &node, NULL );
4472 ok( hr == S_OK, "got %08x\n", hr );
4473 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
4475 /* EOF */
4476 hr = WsSkipNode( reader, NULL );
4477 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
4479 hr = set_input( reader, "<!--comment--><t></t>", sizeof("<!--comment--><t></t>") - 1 );
4480 ok( hr == S_OK, "got %08x\n", hr );
4482 /* non-element */
4483 hr = WsSkipNode( reader, NULL );
4484 ok( hr == S_OK, "got %08x\n", hr );
4485 hr = WsGetReaderNode( reader, &node, NULL );
4486 ok( hr == S_OK, "got %08x\n", hr );
4487 ok( node->nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", node->nodeType );
4489 hr = WsSkipNode( reader, NULL );
4490 ok( hr == S_OK, "got %08x\n", hr );
4491 hr = WsGetReaderNode( reader, &node, NULL );
4492 ok( hr == S_OK, "got %08x\n", hr );
4493 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4495 WsFreeReader( reader );
4498 static HRESULT set_input_bin( WS_XML_READER *reader, const char *data, ULONG size )
4500 WS_XML_READER_BINARY_ENCODING bin = {{WS_XML_READER_ENCODING_TYPE_BINARY}};
4501 WS_XML_READER_BUFFER_INPUT buf;
4503 buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
4504 buf.encodedData = (void *)data;
4505 buf.encodedDataSize = size;
4506 return WsSetInput( reader, &bin.encoding, &buf.input, NULL, 0, NULL );
4509 static void test_binary_encoding(void)
4511 static const char res[] =
4512 {0x40,0x01,'t',0x01};
4513 static const char res2[] =
4514 {0x6d,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01};
4515 static const char res3[] =
4516 {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x01};
4517 static const char res4[] =
4518 {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x99,0x04,'t','e','s','t'};
4519 const WS_XML_NODE *node;
4520 const WS_XML_ELEMENT_NODE *elem;
4521 const WS_XML_ATTRIBUTE *attr;
4522 const WS_XML_TEXT_NODE *text;
4523 const WS_XML_UTF8_TEXT *utf8;
4524 WS_XML_READER *reader;
4525 HRESULT hr;
4527 hr = WsCreateReader( NULL, 0, &reader, NULL );
4528 ok( hr == S_OK, "got %08x\n", hr );
4530 /* short element */
4531 hr = set_input_bin( reader, res, sizeof(res) );
4532 ok( hr == S_OK, "got %08x\n", hr );
4534 hr = WsReadNode( reader, NULL );
4535 ok( hr == S_OK, "got %08x\n", hr );
4536 hr = WsGetReaderNode( reader, &node, NULL );
4537 ok( hr == S_OK, "got %08x\n", hr );
4538 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4539 elem = (const WS_XML_ELEMENT_NODE *)node;
4540 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
4541 ok( elem->prefix->bytes == NULL, "bytes set\n" );
4542 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4543 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4544 ok( !elem->ns->length, "got %u\n", elem->ns->length );
4545 ok( elem->ns->bytes != NULL, "bytes not set\n" );
4546 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
4547 ok( !elem->isEmpty, "empty\n" );
4549 hr = WsReadNode( reader, NULL );
4550 ok( hr == S_OK, "got %08x\n", hr );
4551 hr = WsGetReaderNode( reader, &node, NULL );
4552 ok( hr == S_OK, "got %08x\n", hr );
4553 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4555 /* single character prefix element */
4556 hr = set_input_bin( reader, res2, sizeof(res2) );
4557 ok( hr == S_OK, "got %08x\n", hr );
4559 hr = WsReadNode( reader, NULL );
4560 ok( hr == S_OK, "got %08x\n", hr );
4561 hr = WsGetReaderNode( reader, &node, NULL );
4562 ok( hr == S_OK, "got %08x\n", hr );
4563 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4564 elem = (const WS_XML_ELEMENT_NODE *)node;
4565 ok( elem->prefix->length == 1, "got %u\n", elem->prefix->length );
4566 ok( !memcmp( elem->prefix->bytes, "p", 1 ), "wrong prefix\n" );
4567 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4568 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4569 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
4570 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4571 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
4572 ok( !elem->isEmpty, "empty\n" );
4573 attr = elem->attributes[0];
4574 ok( !attr->singleQuote, "single quote\n" );
4575 ok( attr->isXmlNs, "not xmlns\n" );
4576 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
4577 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
4578 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4579 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4581 hr = WsReadNode( reader, NULL );
4582 ok( hr == S_OK, "got %08x\n", hr );
4583 hr = WsGetReaderNode( reader, &node, NULL );
4584 ok( hr == S_OK, "got %08x\n", hr );
4585 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4587 /* element */
4588 hr = set_input_bin( reader, res3, sizeof(res3) );
4589 ok( hr == S_OK, "got %08x\n", hr );
4591 hr = WsReadNode( reader, NULL );
4592 ok( hr == S_OK, "got %08x\n", hr );
4593 hr = WsGetReaderNode( reader, &node, NULL );
4594 ok( hr == S_OK, "got %08x\n", hr );
4595 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4596 elem = (const WS_XML_ELEMENT_NODE *)node;
4597 ok( elem->prefix->length == 2, "got %u\n", elem->prefix->length );
4598 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4599 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4600 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4601 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
4602 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4603 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
4604 ok( !elem->isEmpty, "empty\n" );
4605 attr = elem->attributes[0];
4606 ok( !attr->singleQuote, "single quote\n" );
4607 ok( attr->isXmlNs, "not xmlns\n" );
4608 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
4609 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4610 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4611 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4613 hr = WsReadNode( reader, NULL );
4614 ok( hr == S_OK, "got %08x\n", hr );
4615 hr = WsGetReaderNode( reader, &node, NULL );
4616 ok( hr == S_OK, "got %08x\n", hr );
4617 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4619 /* element with text */
4620 hr = set_input_bin( reader, res4, sizeof(res4) );
4621 ok( hr == S_OK, "got %08x\n", hr );
4623 hr = WsReadNode( reader, NULL );
4624 ok( hr == S_OK, "got %08x\n", hr );
4625 hr = WsGetReaderNode( reader, &node, NULL );
4626 ok( hr == S_OK, "got %08x\n", hr );
4627 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4628 elem = (const WS_XML_ELEMENT_NODE *)node;
4629 ok( elem->prefix->length == 2, "got %u\n", elem->prefix->length );
4630 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4631 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
4632 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
4633 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
4634 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4635 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
4636 ok( !elem->isEmpty, "empty\n" );
4637 attr = elem->attributes[0];
4638 ok( !attr->singleQuote, "single quote\n" );
4639 ok( attr->isXmlNs, "not xmlns\n" );
4640 ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
4641 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
4642 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
4643 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
4645 hr = WsReadNode( reader, NULL );
4646 ok( hr == S_OK, "got %08x\n", hr );
4647 hr = WsGetReaderNode( reader, &node, NULL );
4648 ok( hr == S_OK, "got %08x\n", hr );
4649 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
4650 text = (const WS_XML_TEXT_NODE *)node;
4651 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4652 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4653 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
4654 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong text\n" );
4656 hr = WsReadNode( reader, NULL );
4657 ok( hr == S_OK, "got %08x\n", hr );
4658 hr = WsGetReaderNode( reader, &node, NULL );
4659 ok( hr == S_OK, "got %08x\n", hr );
4660 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
4662 WsFreeReader( reader );
4665 START_TEST(reader)
4667 test_WsCreateError();
4668 test_WsCreateHeap();
4669 test_WsCreateReader();
4670 test_WsSetInput();
4671 test_WsSetInputToBuffer();
4672 test_WsFillReader();
4673 test_WsReadToStartElement();
4674 test_WsReadStartElement();
4675 test_WsReadEndElement();
4676 test_WsReadNode();
4677 test_WsReadType();
4678 test_WsGetXmlAttribute();
4679 test_WsXmlStringEquals();
4680 test_WsAlloc();
4681 test_WsMoveReader();
4682 test_simple_struct_type();
4683 test_cdata();
4684 test_WsFindAttribute();
4685 test_WsGetNamespaceFromPrefix();
4686 test_text_field_mapping();
4687 test_complex_struct_type();
4688 test_repeating_element();
4689 test_WsResetHeap();
4690 test_datetime();
4691 test_WsDateTimeToFileTime();
4692 test_WsFileTimeToDateTime();
4693 test_double();
4694 test_WsReadElement();
4695 test_WsReadValue();
4696 test_WsResetError();
4697 test_WsGetReaderPosition();
4698 test_WsSetReaderPosition();
4699 test_entities();
4700 test_field_options();
4701 test_WsReadBytes();
4702 test_WsReadChars();
4703 test_WsReadCharsUtf8();
4704 test_WsReadQualifiedName();
4705 test_WsReadAttribute();
4706 test_WsSkipNode();
4707 test_binary_encoding();