webservices/tests: Use IsEqualGUID() to compare GUIDs.
[wine.git] / dlls / webservices / tests / reader.c
blob9d3cd753c5e07b23932e1bf6c93744260bb4dbd2
1 /*
2 * Copyright 2015 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdio.h>
20 #include "windows.h"
21 #include "webservices.h"
22 #include "wine/test.h"
24 static const char data1[] =
25 "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
27 static const char data2[] =
28 {0xef,0xbb,0xbf,'<','t','e','x','t','>','t','e','s','t','<','/','t','e','x','t','>',0};
30 static const char data3[] =
31 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
32 "<text>test</TEXT>";
34 static const char data4[] =
35 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
36 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">\r\n"
37 " <o:services o:GenerationTime=\"2015-09-03T18:47:54\">\r\n"
38 " <!--Build: 16.0.6202.6852-->\r\n"
39 " <o:default>\r\n"
40 " <o:ticket o:headerName=\"Authorization\" o:headerValue=\"{}\" />\r\n"
41 " </o:default>\r\n"
42 " <o:service o:name=\"LiveOAuthLoginStart\">\r\n"
43 " <o:url>https://login.[Live.WebHost]/oauth20_authorize.srf</o:url>\r\n"
44 " </o:service>\r\n"
45 "</o:services>\r\n"
46 "</o:OfficeConfig>\r\n";
48 static const char data5[] =
49 "</text>";
51 static const char data6[] =
52 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
53 "<text attr= \"value\" attr2='value2'>test</text>";
55 static const char data7[] =
56 "<!-- comment -->";
58 static const char data8[] =
59 "<node1><node2>test</node2></node1>";
61 static const char data9[] =
62 "<text xml:attr=\"value\">test</text>";
64 static const char data10[] =
65 "<a></b>";
67 static const char data11[] =
68 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
69 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\">"
70 "<!--Build: 16.0.6202.6852-->"
71 "</o:services>"
72 "</o:OfficeConfig>";
74 static const char data12[] =
75 "<services>"
76 "<service><id>1</id></service>"
77 "<service><id>2</id></service>"
78 "</services>";
80 static const char data13[] =
81 "<services></services>";
83 static const char data14[] =
84 "<services>"
85 "<wrapper>"
86 "<service><id>1</id></service>"
87 "<service><id>2</id></service>"
88 "</wrapper>"
89 "</services>";
91 static const char data15[] =
92 "<services>"
93 "<wrapper>"
94 "<service>1</service>"
95 "<service>2</service>"
96 "</wrapper>"
97 "</services>";
99 static const char data16[] =
100 "<services>"
101 "<wrapper>"
102 "<service name='1'>1</service>"
103 "<service name='2'>2</service>"
104 "</wrapper>"
105 "</services>";
107 static void test_WsCreateError(void)
109 HRESULT hr;
110 WS_ERROR *error;
111 WS_ERROR_PROPERTY prop;
112 ULONG size, code, count;
113 LANGID langid;
115 hr = WsCreateError( NULL, 0, NULL );
116 ok( hr == E_INVALIDARG, "got %08x\n", hr );
118 error = NULL;
119 hr = WsCreateError( NULL, 0, &error );
120 ok( hr == S_OK, "got %08x\n", hr );
121 ok( error != NULL, "error not set\n" );
123 count = 0xdeadbeef;
124 size = sizeof(count);
125 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
126 ok( hr == S_OK, "got %08x\n", hr );
127 ok( !count, "got %u\n", count );
129 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
130 ok( hr == E_INVALIDARG, "got %08x\n", hr );
132 code = 0xdeadbeef;
133 size = sizeof(code);
134 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
135 ok( hr == S_OK, "got %08x\n", hr );
136 ok( !code, "got %u\n", code );
138 code = 0xdeadbeef;
139 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
140 ok( hr == S_OK, "got %08x\n", hr );
141 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
142 ok( hr == S_OK, "got %08x\n", hr );
143 ok( code == 0xdeadbeef, "got %u\n", code );
145 langid = 0xdead;
146 size = sizeof(langid);
147 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
148 ok( hr == S_OK, "got %08x\n", hr );
149 ok( langid == GetUserDefaultUILanguage(), "got %u\n", langid );
151 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
152 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
153 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
155 count = 0xdeadbeef;
156 size = sizeof(count);
157 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID + 1, &count, size );
158 ok( hr == E_INVALIDARG, "got %08x\n", hr );
159 ok( count == 0xdeadbeef, "got %u\n", count );
160 WsFreeError( error );
162 count = 1;
163 prop.id = WS_ERROR_PROPERTY_STRING_COUNT;
164 prop.value = &count;
165 prop.valueSize = sizeof(count);
166 hr = WsCreateError( &prop, 1, &error );
167 ok( hr == E_INVALIDARG, "got %08x\n", hr );
169 code = 0xdeadbeef;
170 prop.id = WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE;
171 prop.value = &code;
172 prop.valueSize = sizeof(code);
173 hr = WsCreateError( &prop, 1, &error );
174 ok( hr == E_INVALIDARG, "got %08x\n", hr );
176 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
177 prop.id = WS_ERROR_PROPERTY_LANGID;
178 prop.value = &langid;
179 prop.valueSize = sizeof(langid);
180 hr = WsCreateError( &prop, 1, &error );
181 ok( hr == S_OK, "got %08x\n", hr );
183 langid = 0xdead;
184 size = sizeof(langid);
185 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
186 ok( hr == S_OK, "got %08x\n", hr );
187 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
188 WsFreeError( error );
190 count = 0xdeadbeef;
191 prop.id = WS_ERROR_PROPERTY_LANGID + 1;
192 prop.value = &count;
193 prop.valueSize = sizeof(count);
194 hr = WsCreateError( &prop, 1, &error );
195 ok( hr == E_INVALIDARG, "got %08x\n", hr );
198 static void test_WsCreateHeap(void)
200 HRESULT hr;
201 WS_HEAP *heap;
202 WS_HEAP_PROPERTY prop;
203 SIZE_T max, trim, requested, actual;
204 ULONG size;
206 hr = WsCreateHeap( 0, 0, NULL, 0, NULL, NULL );
207 ok( hr == E_INVALIDARG, "got %08x\n", hr );
209 heap = NULL;
210 hr = WsCreateHeap( 0, 0, NULL, 0, &heap, NULL );
211 ok( hr == S_OK, "got %08x\n", hr );
212 ok( heap != NULL, "heap not set\n" );
213 WsFreeHeap( heap );
215 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, NULL, NULL );
216 ok( hr == E_INVALIDARG, "got %08x\n", hr );
218 heap = NULL;
219 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
220 ok( hr == S_OK, "got %08x\n", hr );
221 ok( heap != NULL, "heap not set\n" );
222 WsFreeHeap( heap );
224 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, &heap, NULL );
225 ok( hr == S_OK, "got %08x\n", hr );
227 max = 0xdeadbeef;
228 size = sizeof(max);
229 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_MAX_SIZE, &max, size, NULL );
230 ok( hr == S_OK, "got %08x\n", hr );
231 ok( max == 1 << 16, "got %u\n", (ULONG)max );
233 trim = 0xdeadbeef;
234 size = sizeof(trim);
235 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_TRIM_SIZE, &trim, size, NULL );
236 ok( hr == S_OK, "got %08x\n", hr );
237 ok( trim == 1 << 6, "got %u\n", (ULONG)trim );
239 requested = 0xdeadbeef;
240 size = sizeof(requested);
241 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
242 ok( hr == S_OK, "got %08x\n", hr );
243 ok( !requested, "got %u\n", (ULONG)requested );
245 actual = 0xdeadbeef;
246 size = sizeof(actual);
247 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
248 ok( hr == S_OK, "got %08x\n", hr );
249 ok( !actual, "got %u\n", (ULONG)actual );
251 actual = 0xdeadbeef;
252 size = sizeof(actual);
253 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE + 1, &actual, size, NULL );
254 ok( hr == E_INVALIDARG, "got %08x\n", hr );
255 ok( actual == 0xdeadbeef, "got %u\n", (ULONG)actual );
256 WsFreeHeap( heap );
258 max = 1 << 16;
259 prop.id = WS_HEAP_PROPERTY_MAX_SIZE;
260 prop.value = &max;
261 prop.valueSize = sizeof(max);
262 hr = WsCreateHeap( 1 << 16, 1 << 6, &prop, 1, &heap, NULL );
263 ok( hr == E_INVALIDARG, "got %08x\n", hr );
265 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 1, &heap, NULL );
266 ok( hr == E_INVALIDARG, "got %08x\n", hr );
269 static HRESULT set_input( WS_XML_READER *reader, const char *data, ULONG size )
271 WS_XML_READER_TEXT_ENCODING text = {{WS_XML_READER_ENCODING_TYPE_TEXT}, WS_CHARSET_AUTO};
272 WS_XML_READER_BUFFER_INPUT buf;
274 buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
275 buf.encodedData = (void *)data;
276 buf.encodedDataSize = size;
277 return WsSetInput( reader, &text.encoding, &buf.input, NULL, 0, NULL );
280 static void test_WsCreateReader(void)
282 HRESULT hr;
283 WS_XML_READER *reader;
284 WS_XML_READER_PROPERTY prop;
285 ULONG size, max_depth, max_attrs, trim_size, buffer_size, max_ns;
286 BOOL allow_fragment, read_decl, in_attr;
287 ULONGLONG row, column;
288 WS_CHARSET charset;
290 hr = WsCreateReader( NULL, 0, NULL, NULL );
291 ok( hr == E_INVALIDARG, "got %08x\n", hr );
293 reader = NULL;
294 hr = WsCreateReader( NULL, 0, &reader, NULL );
295 ok( hr == S_OK, "got %08x\n", hr );
296 ok( reader != NULL, "reader not set\n" );
298 /* can't retrieve properties before input is set */
299 max_depth = 0xdeadbeef;
300 size = sizeof(max_depth);
301 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
302 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
303 ok( max_depth == 0xdeadbeef, "max_depth set\n" );
305 hr = set_input( reader, data1, sizeof(data1) - 1 );
306 ok( hr == S_OK, "got %08x\n", hr );
308 /* check some defaults */
309 max_depth = 0xdeadbeef;
310 size = sizeof(max_depth);
311 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
312 ok( hr == S_OK, "got %08x\n", hr );
313 ok( max_depth == 32, "got %u\n", max_depth );
315 allow_fragment = TRUE;
316 size = sizeof(allow_fragment);
317 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_ALLOW_FRAGMENT, &allow_fragment, size, NULL );
318 ok( hr == S_OK, "got %08x\n", hr );
319 ok( !allow_fragment, "got %d\n", allow_fragment );
321 max_attrs = 0xdeadbeef;
322 size = sizeof(max_attrs);
323 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES, &max_attrs, size, NULL );
324 ok( hr == S_OK, "got %08x\n", hr );
325 ok( max_attrs == 128, "got %u\n", max_attrs );
327 read_decl = FALSE;
328 size = sizeof(read_decl);
329 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_READ_DECLARATION, &read_decl, size, NULL );
330 ok( hr == S_OK, "got %08x\n", hr );
331 ok( read_decl, "got %u\n", read_decl );
333 charset = 0xdeadbeef;
334 size = sizeof(charset);
335 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
336 ok( hr == S_OK, "got %08x\n", hr );
337 ok( charset == WS_CHARSET_UTF8, "got %u\n", charset );
339 size = sizeof(trim_size);
340 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_UTF8_TRIM_SIZE, &trim_size, size, NULL );
341 todo_wine ok( hr == E_INVALIDARG, "got %08x\n", hr );
342 WsFreeReader( reader );
344 hr = WsCreateReader( NULL, 0, &reader, NULL );
345 ok( hr == S_OK, "got %08x\n", hr );
347 hr = set_input( reader, data1, sizeof(data1) - 1 );
348 ok( hr == S_OK, "got %08x\n", hr );
350 size = sizeof(buffer_size);
351 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_STREAM_BUFFER_SIZE, &buffer_size, size, NULL );
352 todo_wine ok( hr == E_INVALIDARG, "got %08x\n", hr );
353 WsFreeReader( reader );
355 hr = WsCreateReader( NULL, 0, &reader, NULL );
356 ok( hr == S_OK, "got %08x\n", hr );
358 hr = set_input( reader, data1, sizeof(data1) - 1 );
359 ok( hr == S_OK, "got %08x\n", hr );
361 max_ns = 0xdeadbeef;
362 size = sizeof(max_ns);
363 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_NAMESPACES, &max_ns, size, NULL );
364 ok( hr == S_OK, "got %08x\n", hr );
365 ok( max_ns == 32, "got %u\n", max_ns );
366 WsFreeReader( reader );
368 /* change a property */
369 max_depth = 16;
370 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
371 prop.value = &max_depth;
372 prop.valueSize = sizeof(max_depth);
373 hr = WsCreateReader( &prop, 1, &reader, NULL );
374 ok( hr == S_OK, "got %08x\n", hr );
376 hr = set_input( reader, data1, sizeof(data1) - 1 );
377 ok( hr == S_OK, "got %08x\n", hr );
379 max_depth = 0xdeadbeef;
380 size = sizeof(max_depth);
381 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
382 ok( hr == S_OK, "got %08x\n", hr );
383 ok( max_depth == 16, "got %u\n", max_depth );
384 WsFreeReader( reader );
386 /* show that some properties are read-only */
387 row = 1;
388 prop.id = WS_XML_READER_PROPERTY_ROW;
389 prop.value = &row;
390 prop.valueSize = sizeof(row);
391 hr = WsCreateReader( &prop, 1, &reader, NULL );
392 ok( hr == E_INVALIDARG, "got %08x\n", hr );
394 column = 1;
395 prop.id = WS_XML_READER_PROPERTY_COLUMN;
396 prop.value = &column;
397 prop.valueSize = sizeof(column);
398 hr = WsCreateReader( &prop, 1, &reader, NULL );
399 ok( hr == E_INVALIDARG, "got %08x\n", hr );
401 in_attr = TRUE;
402 prop.id = WS_XML_READER_PROPERTY_IN_ATTRIBUTE;
403 prop.value = &in_attr;
404 prop.valueSize = sizeof(in_attr);
405 hr = WsCreateReader( &prop, 1, &reader, NULL );
406 ok( hr == E_INVALIDARG, "got %08x\n", hr );
409 static void test_WsSetInput(void)
411 static char test1[] = {0xef,0xbb,0xbf,'<','a','/','>'};
412 static char test2[] = {'<','a','/','>'};
413 static char test3[] = {'<','!','-','-'};
414 static char test4[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"',
415 ' ','e','n','c','o','d','i','n','g','=','"','u','t','f','-','8','"','?','>'};
416 static char test5[] = {'<','?','x','m','l',' ','e','n','c','o','d','i','n','g','=',
417 '"','u','t','f','-','8','"','?','>'};
418 static char test6[] = {'<','?','x','m','l'};
419 static char test7[] = {'<','?','y','m','l'};
420 static char test8[] = {'<','?'};
421 static char test9[] = {'<','!'};
422 static char test10[] = {0xff,0xfe,'<',0,'a',0,'/',0,'>',0};
423 static char test11[] = {'<',0,'a',0,'/',0,'>',0};
424 static char test12[] = {'<',0,'!',0,'-',0,'-',0};
425 static char test13[] = {'<',0,'?',0};
426 static char test14[] = {'a','b'};
427 static char test15[] = {'a','b','c'};
428 static char test16[] = {'a',0};
429 static char test17[] = {'a',0,'b',0};
430 static char test18[] = {'<',0,'a',0,'b',0};
431 static char test19[] = {'<',0,'a',0};
432 static char test20[] = {0,'a','b'};
433 static char test21[] = {0,0};
434 static char test22[] = {0,0,0};
435 static char test23[] = {'<',0,'?',0,'x',0,'m',0,'l',0};
436 HRESULT hr;
437 WS_XML_READER *reader;
438 WS_XML_READER_PROPERTY prop;
439 WS_XML_READER_TEXT_ENCODING enc;
440 WS_XML_READER_BUFFER_INPUT input;
441 WS_CHARSET charset;
442 const WS_XML_NODE *node;
443 ULONG i, size, max_depth;
444 static const struct
446 void *data;
447 ULONG size;
448 HRESULT hr;
449 WS_CHARSET charset;
450 int todo;
452 tests[] =
454 { test1, sizeof(test1), S_OK, WS_CHARSET_UTF8 },
455 { test2, sizeof(test2), S_OK, WS_CHARSET_UTF8 },
456 { test3, sizeof(test3), S_OK, WS_CHARSET_UTF8 },
457 { test4, sizeof(test4), S_OK, WS_CHARSET_UTF8 },
458 { test5, sizeof(test5), WS_E_INVALID_FORMAT, 0, 1 },
459 { test6, sizeof(test6), WS_E_INVALID_FORMAT, 0, 1 },
460 { test7, sizeof(test7), WS_E_INVALID_FORMAT, 0, 1 },
461 { test8, sizeof(test8), WS_E_INVALID_FORMAT, 0 },
462 { test9, sizeof(test9), WS_E_INVALID_FORMAT, 0 },
463 { test10, sizeof(test10), S_OK, WS_CHARSET_UTF16LE },
464 { test11, sizeof(test11), S_OK, WS_CHARSET_UTF16LE },
465 { test12, sizeof(test12), S_OK, WS_CHARSET_UTF16LE },
466 { test13, sizeof(test13), WS_E_INVALID_FORMAT, 0, 1 },
467 { test14, sizeof(test14), WS_E_INVALID_FORMAT, 0 },
468 { test15, sizeof(test15), S_OK, WS_CHARSET_UTF8 },
469 { test16, sizeof(test16), WS_E_INVALID_FORMAT, 0 },
470 { test17, sizeof(test17), S_OK, WS_CHARSET_UTF8 },
471 { test18, sizeof(test18), S_OK, WS_CHARSET_UTF16LE },
472 { test19, sizeof(test19), S_OK, WS_CHARSET_UTF16LE },
473 { test20, sizeof(test20), S_OK, WS_CHARSET_UTF8 },
474 { test21, sizeof(test21), WS_E_INVALID_FORMAT, 0 },
475 { test22, sizeof(test22), S_OK, WS_CHARSET_UTF8 },
476 { test23, sizeof(test23), WS_E_INVALID_FORMAT, 0, 1 },
479 hr = WsCreateReader( NULL, 0, &reader, NULL );
480 ok( hr == S_OK, "got %08x\n", hr );
482 hr = WsSetInput( NULL, NULL, NULL, NULL, 0, NULL );
483 ok( hr == E_INVALIDARG, "got %08x\n", hr );
485 node = NULL;
486 hr = WsGetReaderNode( reader, &node, NULL );
487 ok( hr == S_OK, "got %08x\n", hr );
488 ok( node != NULL, "node not set\n" );
489 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
491 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
492 enc.charSet = WS_CHARSET_UTF8;
494 input.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
495 input.encodedData = (void *)data1;
496 input.encodedDataSize = sizeof(data1) - 1;
498 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
499 ok( hr == S_OK, "got %08x\n", hr );
501 node = NULL;
502 hr = WsGetReaderNode( reader, &node, NULL );
503 ok( hr == S_OK, "got %08x\n", hr );
504 ok( node != NULL, "node not set\n" );
505 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
507 /* multiple calls are allowed */
508 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
509 ok( hr == S_OK, "got %08x\n", hr );
511 /* charset is detected by WsSetInput */
512 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
513 enc.charSet = WS_CHARSET_AUTO;
515 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
517 input.encodedData = tests[i].data;
518 input.encodedDataSize = tests[i].size;
519 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
520 ok( hr == S_OK, "%u: got %08x\n", i, hr );
522 charset = 0xdeadbeef;
523 size = sizeof(charset);
524 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
525 todo_wine_if (tests[i].todo)
527 ok( hr == tests[i].hr, "%u: got %08x expected %08x\n", i, hr, tests[i].hr );
528 if (hr == S_OK)
529 ok( charset == tests[i].charset, "%u: got %u expected %u\n", i, charset, tests[i].charset );
533 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
534 enc.charSet = WS_CHARSET_UTF8;
536 /* reader properties can be set with WsSetInput */
537 max_depth = 16;
538 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
539 prop.value = &max_depth;
540 prop.valueSize = sizeof(max_depth);
541 hr = WsSetInput( reader, &enc.encoding, &input.input, &prop, 1, NULL );
542 ok( hr == S_OK, "got %08x\n", hr );
544 max_depth = 0xdeadbeef;
545 size = sizeof(max_depth);
546 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
547 ok( hr == S_OK, "got %08x\n", hr );
548 ok( max_depth == 16, "got %u\n", max_depth );
549 WsFreeReader( reader );
552 static void test_WsSetInputToBuffer(void)
554 HRESULT hr;
555 WS_HEAP *heap;
556 WS_XML_BUFFER *buffer;
557 WS_XML_READER *reader;
558 WS_XML_READER_PROPERTY prop;
559 const WS_XML_NODE *node;
560 ULONG size, max_depth;
562 hr = WsCreateReader( NULL, 0, &reader, NULL );
563 ok( hr == S_OK, "got %08x\n", hr );
565 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
566 ok( hr == S_OK, "got %08x\n", hr );
568 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
569 ok( hr == S_OK, "got %08x\n", hr );
571 hr = WsSetInputToBuffer( NULL, NULL, NULL, 0, NULL );
572 ok( hr == E_INVALIDARG, "got %08x\n", hr );
574 hr = WsSetInputToBuffer( reader, NULL, NULL, 0, NULL );
575 ok( hr == E_INVALIDARG, "got %08x\n", hr );
577 node = NULL;
578 hr = WsGetReaderNode( reader, &node, NULL );
579 ok( hr == S_OK, "got %08x\n", hr );
580 ok( node != NULL, "node not set\n" );
581 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
583 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
584 ok( hr == S_OK, "got %08x\n", hr );
586 node = NULL;
587 hr = WsGetReaderNode( reader, &node, NULL );
588 ok( hr == S_OK, "got %08x\n", hr );
589 ok( node != NULL, "node not set\n" );
590 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
592 /* multiple calls are allowed */
593 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
594 ok( hr == S_OK, "got %08x\n", hr );
596 /* reader properties can be set with WsSetInputToBuffer */
597 max_depth = 16;
598 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
599 prop.value = &max_depth;
600 prop.valueSize = sizeof(max_depth);
601 hr = WsSetInputToBuffer( reader, buffer, &prop, 1, NULL );
602 ok( hr == S_OK, "got %08x\n", hr );
604 max_depth = 0xdeadbeef;
605 size = sizeof(max_depth);
606 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
607 ok( hr == S_OK, "got %08x\n", hr );
608 ok( max_depth == 16, "got %u\n", max_depth );
610 WsFreeReader( reader );
611 WsFreeHeap( heap );
614 static void test_WsFillReader(void)
616 HRESULT hr;
617 WS_XML_READER *reader;
618 const WS_XML_NODE *node;
620 /* what happens of we don't call WsFillReader? */
621 hr = WsCreateReader( NULL, 0, &reader, NULL );
622 ok( hr == S_OK, "got %08x\n", hr );
624 node = NULL;
625 hr = WsGetReaderNode( reader, &node, NULL );
626 ok( hr == S_OK, "got %08x\n", hr );
627 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
629 hr = set_input( reader, data1, sizeof(data1) - 1 );
630 ok( hr == S_OK, "got %08x\n", hr );
632 node = NULL;
633 hr = WsGetReaderNode( reader, &node, NULL );
634 ok( hr == S_OK, "got %08x\n", hr );
635 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
637 hr = WsReadNode( reader, NULL );
638 ok( hr == S_OK, "got %08x\n", hr );
640 node = NULL;
641 hr = WsGetReaderNode( reader, &node, NULL );
642 ok( hr == S_OK, "got %08x\n", hr );
643 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
644 WsFreeReader( reader );
646 hr = WsCreateReader( NULL, 0, &reader, NULL );
647 ok( hr == S_OK, "got %08x\n", hr );
649 hr = set_input( reader, data1, sizeof(data1) - 1 );
650 ok( hr == S_OK, "got %08x\n", hr );
652 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
653 ok( hr == S_OK, "got %08x\n", hr );
655 hr = set_input( reader, data1, sizeof(data1) - 1 );
656 ok( hr == S_OK, "got %08x\n", hr );
658 node = NULL;
659 hr = WsGetReaderNode( reader, &node, NULL );
660 ok( hr == S_OK, "got %08x\n", hr );
661 ok( node != NULL, "node not set\n" );
662 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
664 hr = WsFillReader( NULL, sizeof(data1) - 1, NULL, NULL );
665 ok( hr == E_INVALIDARG, "got %08x\n", hr );
667 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
668 ok( hr == S_OK, "got %08x\n", hr );
670 node = NULL;
671 hr = WsGetReaderNode( reader, &node, NULL );
672 ok( hr == S_OK, "got %08x\n", hr );
673 ok( node != NULL, "node not set\n" );
674 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
676 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
677 ok( hr == S_OK, "got %08x\n", hr );
679 /* min_size larger than input size */
680 hr = WsFillReader( reader, sizeof(data1), NULL, NULL );
681 ok( hr == S_OK, "got %08x\n", hr );
682 WsFreeReader( reader );
685 static void test_WsReadToStartElement(void)
687 HRESULT hr;
688 WS_XML_READER *reader;
689 const WS_XML_NODE *node, *node2;
690 int found;
692 hr = WsCreateReader( NULL, 0, &reader, NULL );
693 ok( hr == S_OK, "got %08x\n", hr );
695 hr = set_input( reader, data1, sizeof(data1) - 1 );
696 ok( hr == S_OK, "got %08x\n", hr );
698 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
699 ok( hr == S_OK, "got %08x\n", hr );
701 hr = WsGetReaderNode( reader, &node, NULL );
702 ok( hr == S_OK, "got %08x\n", hr );
703 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
705 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
706 ok( hr == S_OK, "got %08x\n", hr );
708 hr = WsReadToStartElement( NULL, NULL, NULL, NULL, NULL );
709 ok( hr == E_INVALIDARG, "got %08x\n", hr );
711 found = -1;
712 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
713 ok( hr == S_OK, "got %08x\n", hr );
714 ok( found == FALSE, "got %d\n", found );
716 hr = WsGetReaderNode( reader, &node, NULL );
717 ok( hr == S_OK, "got %08x\n", hr );
718 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
720 hr = set_input( reader, data2, sizeof(data2) - 1 );
721 ok( hr == S_OK, "got %08x\n", hr );
723 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
724 ok( hr == S_OK, "got %08x\n", hr );
726 hr = WsGetReaderNode( reader, &node, NULL );
727 ok( hr == S_OK, "got %08x\n", hr );
728 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
730 found = -1;
731 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
732 ok( hr == S_OK, "got %08x\n", hr );
733 ok( found == TRUE, "got %d\n", found );
735 hr = WsGetReaderNode( reader, &node, NULL );
736 ok( hr == S_OK, "got %08x\n", hr );
737 if (node)
739 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
741 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
742 ok( elem->prefix != NULL, "prefix not set\n" );
743 if (elem->prefix)
745 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
747 ok( elem->localName != NULL, "localName not set\n" );
748 if (elem->localName)
750 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
751 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
753 ok( elem->ns != NULL, "ns not set\n" );
754 if (elem->ns)
756 ok( !elem->ns->length, "got %u\n", elem->ns->length );
758 ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
759 ok( elem->attributes == NULL, "attributes set\n" );
760 ok( !elem->isEmpty, "isEmpty not zero\n" );
763 found = -1;
764 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
765 ok( hr == S_OK, "got %08x\n", hr );
766 ok( found == TRUE, "got %d\n", found );
768 node2 = NULL;
769 hr = WsGetReaderNode( reader, &node2, NULL );
770 ok( hr == S_OK, "got %08x\n", hr );
771 ok( node2 == node, "different node\n" );
773 hr = set_input( reader, data3, sizeof(data3) - 1 );
774 ok( hr == S_OK, "got %08x\n", hr );
776 hr = WsFillReader( reader, sizeof(data3) - 1, NULL, NULL );
777 ok( hr == S_OK, "got %08x\n", hr );
779 found = -1;
780 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
781 ok( hr == S_OK, "got %08x\n", hr );
782 ok( found == TRUE, "got %d\n", found );
784 hr = WsGetReaderNode( reader, &node, NULL );
785 ok( hr == S_OK, "got %08x\n", hr );
786 if (node)
788 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
790 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
791 ok( elem->localName != NULL, "localName not set\n" );
792 if (elem->localName)
794 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
795 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
799 hr = set_input( reader, data4, sizeof(data4) - 1 );
800 ok( hr == S_OK, "got %08x\n", hr );
802 hr = WsFillReader( reader, sizeof(data4) - 1, NULL, NULL );
803 ok( hr == S_OK, "got %08x\n", hr );
805 found = -1;
806 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
807 ok( hr == S_OK, "got %08x\n", hr );
808 ok( found == TRUE, "got %d\n", found );
809 WsFreeReader( reader );
812 static void test_WsReadStartElement(void)
814 HRESULT hr;
815 WS_XML_READER *reader;
816 const WS_XML_NODE *node, *node2;
817 int found;
819 hr = WsCreateReader( NULL, 0, &reader, NULL );
820 ok( hr == S_OK, "got %08x\n", hr );
822 hr = set_input( reader, data2, sizeof(data2) - 1 );
823 ok( hr == S_OK, "got %08x\n", hr );
825 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
826 ok( hr == S_OK, "got %08x\n", hr );
828 found = -1;
829 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
830 ok( hr == S_OK, "got %08x\n", hr );
831 ok( found == TRUE, "got %d\n", found );
833 hr = WsReadStartElement( NULL, NULL );
834 ok( hr == E_INVALIDARG, "got %08x\n", hr );
836 hr = WsGetReaderNode( reader, &node, NULL );
837 ok( hr == S_OK, "got %08x\n", hr );
838 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
840 hr = WsReadStartElement( reader, NULL );
841 ok( hr == S_OK, "got %08x\n", hr );
843 hr = WsGetReaderNode( reader, &node, NULL );
844 ok( hr == S_OK, "got %08x\n", hr );
845 if (node)
847 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
848 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
849 ok( text->text != NULL, "text not set\n" );
850 if (text->text)
852 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
853 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
854 ok( utf8->value.length == 4, "got %u\n", utf8->value.length );
855 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong data\n" );
859 hr = WsReadStartElement( reader, NULL );
860 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
862 node2 = NULL;
863 hr = WsGetReaderNode( reader, &node2, NULL );
864 ok( hr == S_OK, "got %08x\n", hr );
865 ok( node2 == node, "different node\n" );
867 hr = set_input( reader, data8, sizeof(data8) - 1 );
868 ok( hr == S_OK, "got %08x\n", hr );
870 hr = WsFillReader( reader, sizeof(data8) - 1, NULL, NULL );
871 ok( hr == S_OK, "got %08x\n", hr );
873 found = -1;
874 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
875 ok( hr == S_OK, "got %08x\n", hr );
876 ok( found == TRUE, "got %d\n", found );
878 hr = WsGetReaderNode( reader, &node, NULL );
879 ok( hr == S_OK, "got %08x\n", hr );
880 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
882 hr = WsGetReaderNode( reader, &node, NULL );
883 ok( hr == S_OK, "got %08x\n", hr );
884 if (node)
886 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
887 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
888 ok( !memcmp( elem->localName->bytes, "node1", 5), "wrong name\n" );
891 hr = WsReadStartElement( reader, NULL );
892 ok( hr == S_OK, "got %08x\n", hr );
894 hr = WsGetReaderNode( reader, &node, NULL );
895 ok( hr == S_OK, "got %08x\n", hr );
896 if (node)
898 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
899 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
900 ok( !memcmp( elem->localName->bytes, "node2", 5), "wrong name\n" );
903 hr = WsReadNode( reader, NULL );
904 ok( hr == S_OK, "got %08x\n", hr );
906 hr = WsGetReaderNode( reader, &node, NULL );
907 ok( hr == S_OK, "got %08x\n", hr );
908 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
910 hr = WsReadNode( reader, NULL );
911 ok( hr == S_OK, "got %08x\n", hr );
913 hr = WsGetReaderNode( reader, &node, NULL );
914 ok( hr == S_OK, "got %08x\n", hr );
915 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
917 hr = WsReadEndElement( reader, NULL );
918 ok( hr == S_OK, "got %08x\n", hr );
920 hr = WsGetReaderNode( reader, &node, NULL );
921 ok( hr == S_OK, "got %08x\n", hr );
922 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
924 /* WsReadEndElement advances reader to EOF */
925 hr = WsReadEndElement( reader, NULL );
926 ok( hr == S_OK, "got %08x\n", hr );
928 hr = WsGetReaderNode( reader, &node, NULL );
929 ok( hr == S_OK, "got %08x\n", hr );
930 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
932 hr = WsReadEndElement( reader, NULL );
933 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
935 WsFreeReader( reader );
938 static void test_WsReadEndElement(void)
940 HRESULT hr;
941 WS_XML_READER *reader;
942 const WS_XML_NODE *node;
943 int found;
945 hr = WsCreateReader( NULL, 0, &reader, NULL );
946 ok( hr == S_OK, "got %08x\n", hr );
948 hr = set_input( reader, data2, sizeof(data2) - 1 );
949 ok( hr == S_OK, "got %08x\n", hr );
951 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
952 ok( hr == S_OK, "got %08x\n", hr );
954 hr = WsReadEndElement( reader, NULL );
955 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
957 hr = set_input( reader, data2, sizeof(data2) - 1 );
958 ok( hr == S_OK, "got %08x\n", hr );
960 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
961 ok( hr == S_OK, "got %08x\n", hr );
963 hr = WsReadNode( reader, NULL );
964 ok( hr == S_OK, "got %08x\n", hr );
966 hr = WsGetReaderNode( reader, &node, NULL );
967 ok( hr == S_OK, "got %08x\n", hr );
968 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
970 hr = WsReadNode( reader, NULL );
971 ok( hr == S_OK, "got %08x\n", hr );
973 hr = WsGetReaderNode( reader, &node, NULL );
974 ok( hr == S_OK, "got %08x\n", hr );
975 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
977 hr = WsReadNode( reader, NULL );
978 ok( hr == S_OK, "got %08x\n", hr );
980 hr = WsGetReaderNode( reader, &node, NULL );
981 ok( hr == S_OK, "got %08x\n", hr );
982 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
984 hr = WsReadNode( reader, NULL );
985 ok( hr == S_OK, "got %08x\n", hr );
987 hr = WsGetReaderNode( reader, &node, NULL );
988 ok( hr == S_OK, "got %08x\n", hr );
989 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
991 hr = set_input( reader, data2, sizeof(data2) - 1 );
992 ok( hr == S_OK, "got %08x\n", hr );
994 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
995 ok( hr == S_OK, "got %08x\n", hr );
997 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
998 ok( hr == S_OK, "got %08x\n", hr );
1000 hr = WsReadStartElement( reader, NULL );
1001 ok( hr == S_OK, "got %08x\n", hr );
1003 hr = WsGetReaderNode( reader, &node, NULL );
1004 ok( hr == S_OK, "got %08x\n", hr );
1005 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
1007 hr = WsReadNode( reader, NULL );
1008 ok( hr == S_OK, "got %08x\n", hr );
1010 hr = WsGetReaderNode( reader, &node, NULL );
1011 ok( hr == S_OK, "got %08x\n", hr );
1012 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1014 /* WsReadEndElement advances reader to EOF */
1015 hr = WsReadEndElement( reader, NULL );
1016 ok( hr == S_OK, "got %08x\n", hr );
1018 hr = WsGetReaderNode( reader, &node, NULL );
1019 ok( hr == S_OK, "got %08x\n", hr );
1020 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1022 hr = WsReadEndElement( reader, NULL );
1023 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1025 hr = set_input( reader, data5, sizeof(data5) - 1 );
1026 ok( hr == S_OK, "got %08x\n", hr );
1028 hr = WsFillReader( reader, sizeof(data5) - 1, NULL, NULL );
1029 ok( hr == S_OK, "got %08x\n", hr );
1031 hr = WsReadEndElement( reader, NULL );
1032 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1034 hr = set_input( reader, data10, sizeof(data10) - 1 );
1035 ok( hr == S_OK, "got %08x\n", hr );
1037 hr = WsFillReader( reader, sizeof(data10) - 1, NULL, NULL );
1038 ok( hr == S_OK, "got %08x\n", hr );
1040 hr = WsReadNode( reader, NULL );
1041 ok( hr == S_OK, "got %08x\n", hr );
1043 hr = WsGetReaderNode( reader, &node, NULL );
1044 ok( hr == S_OK, "got %08x\n", hr );
1045 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1047 hr = WsReadEndElement( reader, NULL );
1048 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1050 hr = set_input( reader, "<a></A>", sizeof("<a></A>") - 1 );
1051 ok( hr == S_OK, "got %08x\n", hr );
1053 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1054 ok( hr == S_OK, "got %08x\n", hr );
1056 found = -1;
1057 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1058 ok( hr == S_OK, "got %08x\n", hr );
1059 ok( found == TRUE, "got %d\n", found );
1061 hr = WsGetReaderNode( reader, &node, NULL );
1062 ok( hr == S_OK, "got %08x\n", hr );
1063 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1065 hr = WsReadEndElement( reader, NULL );
1066 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1068 hr = set_input( reader, "<a></a>", sizeof("<a></a>") - 1 );
1069 ok( hr == S_OK, "got %08x\n", hr );
1071 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1072 ok( hr == S_OK, "got %08x\n", hr );
1074 found = -1;
1075 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1076 ok( hr == S_OK, "got %08x\n", hr );
1077 ok( found == TRUE, "got %d\n", found );
1079 hr = WsGetReaderNode( reader, &node, NULL );
1080 ok( hr == S_OK, "got %08x\n", hr );
1081 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1083 hr = WsReadStartElement( reader, NULL );
1084 ok( hr == S_OK, "got %08x\n", hr );
1086 hr = WsGetReaderNode( reader, &node, NULL );
1087 ok( hr == S_OK, "got %08x\n", hr );
1088 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1090 hr = WsReadEndElement( reader, NULL );
1091 ok( hr == S_OK, "got %08x\n", hr );
1093 hr = WsGetReaderNode( reader, &node, NULL );
1094 ok( hr == S_OK, "got %08x\n", hr );
1095 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1097 hr = set_input( reader, "<a/>", sizeof("<a/>") - 1 );
1098 ok( hr == S_OK, "got %08x\n", hr );
1100 hr = WsFillReader( reader, sizeof("<a/>") - 1, NULL, NULL );
1101 ok( hr == S_OK, "got %08x\n", hr );
1103 found = -1;
1104 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1105 ok( hr == S_OK, "got %08x\n", hr );
1106 ok( found == TRUE, "got %d\n", found );
1108 hr = WsGetReaderNode( reader, &node, NULL );
1109 ok( hr == S_OK, "got %08x\n", hr );
1110 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1112 hr = WsReadStartElement( reader, NULL );
1113 ok( hr == S_OK, "got %08x\n", hr );
1115 hr = WsGetReaderNode( reader, &node, NULL );
1116 ok( hr == S_OK, "got %08x\n", hr );
1117 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1119 hr = WsReadEndElement( reader, NULL );
1120 ok( hr == S_OK, "got %08x\n", hr );
1122 WsFreeReader( reader );
1125 static void test_WsReadNode(void)
1127 static const char str1[] = "<a>";
1128 static const char str2[] = "< a>";
1129 static const char str3[] = "<a >";
1130 static const char str4[] = "<<a>>";
1131 static const char str5[] = "<>";
1132 static const char str6[] = "</a>";
1133 static const char str7[] = " <a>";
1134 static const char str8[] = "<?xml>";
1135 static const char str9[] = "<?xml?>";
1136 static const char str10[] = "<?xml ?>";
1137 static const char str11[] = "<?xml version=\"1.0\"?>";
1138 static const char str12[] = "<text>test</text>";
1139 static const char str13[] = "<?xml version=\"1.0\"?><text>test</text>";
1140 static const char str14[] = "";
1141 static const char str15[] = "<!--";
1142 static const char str16[] = "<!---->";
1143 static const char str17[] = "<!--comment-->";
1144 HRESULT hr;
1145 WS_XML_READER *reader;
1146 const WS_XML_NODE *node;
1147 unsigned int i;
1148 int found;
1149 static const struct
1151 const char *text;
1152 HRESULT hr;
1153 WS_XML_NODE_TYPE type;
1154 int todo;
1156 tests[] =
1158 { str1, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1159 { str2, WS_E_INVALID_FORMAT, 0 },
1160 { str3, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1161 { str4, WS_E_INVALID_FORMAT, 0 },
1162 { str5, WS_E_INVALID_FORMAT, 0 },
1163 { str6, WS_E_INVALID_FORMAT, 0 },
1164 { str7, S_OK, WS_XML_NODE_TYPE_TEXT },
1165 { str8, WS_E_INVALID_FORMAT, 0 },
1166 { str9, WS_E_INVALID_FORMAT, 0 },
1167 { str10, WS_E_INVALID_FORMAT, 0, 1 },
1168 { str11, S_OK, WS_XML_NODE_TYPE_EOF },
1169 { str12, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1170 { str13, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1171 { str14, WS_E_INVALID_FORMAT, 0, 1 },
1172 { str15, WS_E_INVALID_FORMAT, 0 },
1173 { str16, S_OK, WS_XML_NODE_TYPE_COMMENT },
1174 { str17, S_OK, WS_XML_NODE_TYPE_COMMENT },
1177 hr = WsCreateReader( NULL, 0, &reader, NULL );
1178 ok( hr == S_OK, "got %08x\n", hr );
1180 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
1182 hr = set_input( reader, tests[i].text, strlen(tests[i].text) );
1183 ok( hr == S_OK, "got %08x\n", hr );
1185 hr = WsFillReader( reader, strlen(tests[i].text), NULL, NULL );
1186 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1188 hr = WsReadNode( reader, NULL );
1189 todo_wine_if (tests[i].todo)
1190 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
1191 if (hr == S_OK)
1193 node = NULL;
1194 hr = WsGetReaderNode( reader, &node, NULL );
1195 ok( hr == S_OK, "%u: got %08x\n", i, hr );
1196 ok( node != NULL, "%u: node not set\n", i );
1197 if (node)
1199 todo_wine_if (tests[i].todo)
1200 ok( node->nodeType == tests[i].type, "%u: got %u\n", i, node->nodeType );
1205 hr = set_input( reader, data6, sizeof(data6) - 1 );
1206 ok( hr == S_OK, "got %08x\n", hr );
1208 hr = WsFillReader( reader, sizeof(data6) - 1, NULL, NULL );
1209 ok( hr == S_OK, "got %08x\n", hr );
1211 found = -1;
1212 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1213 ok( hr == S_OK, "got %08x\n", hr );
1214 ok( found == TRUE, "got %d\n", found );
1216 hr = WsGetReaderNode( reader, &node, NULL );
1217 ok( hr == S_OK, "got %08x\n", hr );
1218 if (node)
1220 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
1221 WS_XML_ATTRIBUTE *attr;
1222 WS_XML_UTF8_TEXT *text;
1224 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1225 ok( elem->prefix != NULL, "prefix not set\n" );
1226 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
1227 ok( elem->prefix->bytes == NULL, "bytes set\n" );
1228 ok( elem->localName != NULL, "localName not set\n" );
1229 ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
1230 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
1231 ok( elem->ns != NULL, "ns not set\n" );
1232 ok( !elem->ns->length, "got %u\n", elem->ns->length );
1233 ok( elem->ns->bytes != NULL, "bytes not set\n" );
1234 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
1235 ok( elem->attributes != NULL, "attributes not set\n" );
1236 ok( !elem->isEmpty, "isEmpty not zero\n" );
1238 attr = elem->attributes[0];
1239 ok( !attr->singleQuote, "got %u\n", attr->singleQuote );
1240 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1241 ok( attr->prefix != NULL, "prefix not set\n" );
1242 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1243 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1244 ok( attr->localName != NULL, "localName not set\n" );
1245 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
1246 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
1247 ok( attr->ns != NULL, "ns not set\n" );
1248 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1249 ok( attr->ns->bytes == NULL, "bytes set\n" );
1250 ok( attr->value != NULL, "value not set\n" );
1252 text = (WS_XML_UTF8_TEXT *)attr->value;
1253 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1254 ok( text->value.length == 5, "got %u\n", text->value.length );
1255 ok( !memcmp( text->value.bytes, "value", 5 ), "wrong data\n" );
1257 attr = elem->attributes[1];
1258 ok( attr->singleQuote == 1, "got %u\n", attr->singleQuote );
1259 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1260 ok( attr->prefix != NULL, "prefix not set\n" );
1261 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
1262 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1263 ok( attr->localName != NULL, "localName not set\n" );
1264 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
1265 ok( !memcmp( attr->localName->bytes, "attr2", 5 ), "wrong data\n" );
1266 ok( attr->ns != NULL, "ns not set\n" );
1267 ok( !attr->ns->length, "got %u\n", attr->ns->length );
1268 ok( attr->ns->bytes == NULL, "bytes set\n" );
1269 ok( attr->value != NULL, "value not set\n" );
1271 text = (WS_XML_UTF8_TEXT *)attr->value;
1272 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1273 ok( text->value.length == 6, "got %u\n", text->value.length );
1274 ok( !memcmp( text->value.bytes, "value2", 6 ), "wrong data\n" );
1277 hr = set_input( reader, data7, sizeof(data7) - 1 );
1278 ok( hr == S_OK, "got %08x\n", hr );
1280 hr = WsFillReader( reader, sizeof(data7) - 1, NULL, NULL );
1281 ok( hr == S_OK, "got %08x\n", hr );
1283 hr = WsReadNode( reader, NULL );
1284 ok( hr == S_OK, "got %08x\n", hr );
1286 hr = WsGetReaderNode( reader, &node, NULL );
1287 ok( hr == S_OK, "got %08x\n", hr );
1288 if (node)
1290 WS_XML_COMMENT_NODE *comment = (WS_XML_COMMENT_NODE *)node;
1292 ok( comment->node.nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", comment->node.nodeType );
1293 ok( comment->value.length == 9, "got %u\n", comment->value.length );
1294 ok( !memcmp( comment->value.bytes, " comment ", 9 ), "wrong data\n" );
1297 WsFreeReader( reader );
1300 static void prepare_type_test( WS_XML_READER *reader, const char *data, ULONG size )
1302 HRESULT hr;
1304 hr = set_input( reader, data, size );
1305 ok( hr == S_OK, "got %08x\n", hr );
1307 hr = WsFillReader( reader, size, NULL, NULL );
1308 ok( hr == S_OK, "got %08x\n", hr );
1310 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1311 ok( hr == S_OK, "got %08x\n", hr );
1313 hr = WsReadStartElement( reader, NULL );
1314 ok( hr == S_OK, "got %08x\n", hr );
1317 static void test_WsReadType(void)
1319 static const WCHAR testW[] = {'t','e','s','t',0};
1320 static const GUID guid1 = {0,0,0,{0,0,0,0,0,0,0,0}};
1321 static const GUID guid2 = {0,0,0,{0,0,0,0,0,0,0,0xa1}};
1322 HRESULT hr;
1323 WS_XML_READER *reader;
1324 WS_HEAP *heap;
1325 enum { ONE = 1, TWO = 2 };
1326 WS_XML_STRING one = { 3, (BYTE *)"ONE" };
1327 WS_XML_STRING two = { 3, (BYTE *)"TWO" };
1328 WS_ENUM_VALUE enum_values[] = { { ONE, &one }, { TWO, &two } };
1329 WS_ENUM_DESCRIPTION enum_desc;
1330 int val_enum;
1331 WCHAR *val_str;
1332 BOOL val_bool;
1333 INT8 val_int8;
1334 INT16 val_int16;
1335 INT32 val_int32;
1336 INT64 val_int64;
1337 UINT8 val_uint8;
1338 UINT16 val_uint16;
1339 UINT32 val_uint32;
1340 UINT64 val_uint64;
1341 GUID val_guid;
1343 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1344 ok( hr == S_OK, "got %08x\n", hr );
1346 hr = WsCreateReader( NULL, 0, &reader, NULL );
1347 ok( hr == S_OK, "got %08x\n", hr );
1349 prepare_type_test( reader, data2, sizeof(data2) - 1 );
1350 hr = WsReadType( NULL, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1351 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1352 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1354 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1355 WS_READ_REQUIRED_POINTER, heap, &val_str, 0, NULL );
1356 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1358 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1359 WS_READ_REQUIRED_POINTER, heap, NULL, sizeof(val_str), NULL );
1360 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1362 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1363 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str) + 1, NULL );
1364 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1366 val_str = NULL;
1367 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1368 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1369 ok( hr == S_OK, "got %08x\n", hr );
1370 ok( val_str != NULL, "pointer not set\n" );
1371 if (val_str) ok( !lstrcmpW( val_str, testW ), "wrong data\n" );
1373 val_bool = -1;
1374 prepare_type_test( reader, "<t>true</t>", sizeof("<t>true</t>") - 1 );
1375 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1376 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1377 ok( hr == S_OK, "got %08x\n", hr );
1378 ok( val_bool == TRUE, "got %d\n", val_bool );
1380 val_bool = -1;
1381 prepare_type_test( reader, "<t>false</t>", sizeof("<t>false</t>") - 1 );
1382 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1383 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1384 ok( hr == S_OK, "got %08x\n", hr );
1385 ok( val_bool == FALSE, "got %d\n", val_bool );
1387 val_bool = -1;
1388 prepare_type_test( reader, "<t>FALSE</t>", sizeof("<t>FALSE</t>") - 1 );
1389 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1390 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1391 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1392 ok( val_bool == -1, "got %d\n", val_bool );
1394 val_bool = -1;
1395 prepare_type_test( reader, "<t>1</t>", sizeof("<t>1</t>") - 1 );
1396 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1397 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1398 ok( hr == S_OK, "got %08x\n", hr );
1399 ok( val_bool == TRUE, "got %d\n", val_bool );
1401 val_bool = -1;
1402 prepare_type_test( reader, "<t>2</t>", sizeof("<t>2</t>") - 1 );
1403 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1404 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1405 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1406 ok( val_bool == -1, "got %d\n", val_bool );
1408 val_bool = -1;
1409 prepare_type_test( reader, "<t>0</t>", sizeof("<t>0</t>") - 1 );
1410 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1411 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1412 ok( hr == S_OK, "got %08x\n", hr );
1413 ok( val_bool == FALSE, "got %d\n", val_bool );
1415 val_int8 = 0;
1416 prepare_type_test( reader, "<t>-128</t>", sizeof("<t>-128</t>") - 1 );
1417 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1418 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1419 ok( hr == S_OK, "got %08x\n", hr );
1420 ok( val_int8 == -128, "got %d\n", val_int8 );
1422 val_int8 = 0;
1423 prepare_type_test( reader, "<t> </t>", sizeof("<t> </t>") - 1 );
1424 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1425 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1426 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1427 ok( !val_int8, "got %d\n", val_int8 );
1429 val_int8 = 0;
1430 prepare_type_test( reader, "<t>-</t>", sizeof("<t>-</t>") - 1 );
1431 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1432 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1433 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1434 ok( !val_int8, "got %d\n", val_int8 );
1436 val_int8 = -1;
1437 prepare_type_test( reader, "<t>-0</t>", sizeof("<t>-0</t>") - 1 );
1438 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1439 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1440 ok( hr == S_OK, "got %08x\n", hr );
1441 ok( !val_int8, "got %d\n", val_int8 );
1443 val_int8 = 0;
1444 prepare_type_test( reader, "<t>-129</t>", sizeof("<t>-129</t>") - 1 );
1445 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1446 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1447 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1448 ok( !val_int8, "got %d\n", val_int8 );
1450 val_int16 = 0;
1451 prepare_type_test( reader, "<t>-32768</t>", sizeof("<t>-32768</t>") - 1 );
1452 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1453 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1454 ok( hr == S_OK, "got %08x\n", hr );
1455 ok( val_int16 == -32768, "got %d\n", val_int16 );
1457 val_int16 = 0;
1458 prepare_type_test( reader, "<t>-32769</t>", sizeof("<t>-32769</t>") - 1 );
1459 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1460 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1461 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1462 ok( !val_int16, "got %d\n", val_int16 );
1464 val_int32 = 0;
1465 prepare_type_test( reader, "<t>-2147483648</t>", sizeof("<t>-2147483648</t>") - 1 );
1466 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1467 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1468 ok( hr == S_OK, "got %08x\n", hr );
1469 ok( val_int32 == -2147483647 - 1, "got %d\n", val_int32 );
1471 val_int32 = 0;
1472 prepare_type_test( reader, "<t>-2147483649</t>", sizeof("<t>-2147483649</t>") - 1 );
1473 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1474 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1475 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1476 ok( !val_int32, "got %d\n", val_int32 );
1478 val_int64 = 0;
1479 prepare_type_test( reader, "<t>-9223372036854775808</t>", sizeof("<t>-9223372036854775808</t>") - 1 );
1480 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1481 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1482 ok( hr == S_OK, "got %08x\n", hr );
1483 ok( val_int64 == -9223372036854775807 - 1, "wrong value\n" );
1485 val_int64 = 0;
1486 prepare_type_test( reader, "<t>-9223372036854775809</t>", sizeof("<t>-9223372036854775809</t>") - 1 );
1487 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1488 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1489 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1490 ok( !val_int64, "wrong value\n" );
1492 val_uint8 = 0;
1493 prepare_type_test( reader, "<t> 255 </t>", sizeof("<t> 255 </t>") - 1 );
1494 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1495 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1496 ok( hr == S_OK, "got %08x\n", hr );
1497 ok( val_uint8 == 255, "got %u\n", val_uint8 );
1499 val_uint8 = 0;
1500 prepare_type_test( reader, "<t>+255</t>", sizeof("<t>+255</t>") - 1 );
1501 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1502 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1503 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1504 ok( !val_uint8, "got %u\n", val_uint8 );
1506 val_uint8 = 0;
1507 prepare_type_test( reader, "<t>-255</t>", sizeof("<t>-255</t>") - 1 );
1508 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1509 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1510 todo_wine ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1511 ok( !val_uint8, "got %u\n", val_uint8 );
1513 val_uint8 = 0;
1514 prepare_type_test( reader, "<t>0xff</t>", sizeof("<t>0xff</t>") - 1 );
1515 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1516 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1517 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1518 ok( !val_uint8, "got %u\n", val_uint8 );
1520 val_uint8 = 0;
1521 prepare_type_test( reader, "<t>256</t>", sizeof("<t>256</t>") - 1 );
1522 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1523 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1524 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1525 ok( !val_uint8, "got %u\n", val_uint8 );
1527 val_uint16 = 0;
1528 prepare_type_test( reader, "<t>65535</t>", sizeof("<t>65535</t>") - 1 );
1529 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1530 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1531 ok( hr == S_OK, "got %08x\n", hr );
1532 ok( val_uint16 == 65535, "got %u\n", val_uint16 );
1534 val_uint16 = 0;
1535 prepare_type_test( reader, "<t>65536</t>", sizeof("<t>65536</t>") - 1 );
1536 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1537 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1538 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1539 ok( !val_uint16, "got %u\n", val_uint16 );
1541 val_uint32 = 0;
1542 prepare_type_test( reader, "<t>4294967295</t>", sizeof("<t>4294967295</t>") - 1 );
1543 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1544 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1545 ok( hr == S_OK, "got %08x\n", hr );
1546 ok( val_uint32 == ~0, "got %u\n", val_uint32 );
1548 val_uint32 = 0;
1549 prepare_type_test( reader, "<t>4294967296</t>", sizeof("<t>4294967296</t>") - 1 );
1550 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1551 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1552 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
1553 ok( !val_uint32, "got %u\n", val_uint32 );
1555 val_uint64 = 0;
1556 prepare_type_test( reader, "<t>18446744073709551615</t>", sizeof("<t>18446744073709551615</t>") - 1 );
1557 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1558 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1559 ok( hr == S_OK, "got %08x\n", hr );
1560 ok( val_uint64 == ~0, "wrong value\n" );
1562 val_uint64 = 0;
1563 prepare_type_test( reader, "<t>18446744073709551616</t>", sizeof("<t>18446744073709551616</t>") - 1 );
1564 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1565 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1566 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1567 ok( !val_uint64, "wrong value\n" );
1569 enum_desc.values = enum_values;
1570 enum_desc.valueCount = sizeof(enum_values)/sizeof(enum_values[0]);
1571 enum_desc.maxByteCount = 3;
1572 enum_desc.nameIndices = NULL;
1574 val_enum = 0;
1575 prepare_type_test( reader, "<t>ONE</t>", sizeof("<t>ONE</t>") - 1 );
1576 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1577 WS_READ_REQUIRED_VALUE, heap, &val_enum, sizeof(val_enum), NULL );
1578 ok( hr == S_OK, "got %08x\n", hr );
1579 ok( val_enum == 1, "got %d\n", val_enum );
1581 prepare_type_test( reader, "<t>{00000000-0000-0000-0000-000000000000}</t>",
1582 sizeof("<t>{00000000-0000-0000-0000-000000000000}</t>") - 1 );
1583 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1584 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1585 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1587 memset( &val_guid, 0xff, sizeof(val_guid) );
1588 prepare_type_test( reader, "<t> 00000000-0000-0000-0000-000000000000 </t>",
1589 sizeof("<t> 00000000-0000-0000-0000-000000000000 </t>") - 1 );
1590 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1591 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1592 ok( hr == S_OK, "got %08x\n", hr );
1593 ok( IsEqualGUID( &val_guid, &guid1 ), "wrong guid\n" );
1595 memset( &val_guid, 0, sizeof(val_guid) );
1596 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000a1</t>",
1597 sizeof("<t>00000000-0000-0000-0000-0000000000a1</t>") - 1 );
1598 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1599 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1600 ok( hr == S_OK, "got %08x\n", hr );
1601 ok( IsEqualGUID( &val_guid, &guid2 ), "wrong guid\n" );
1603 memset( &val_guid, 0, sizeof(val_guid) );
1604 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000A1</t>",
1605 sizeof("<t>00000000-0000-0000-0000-0000000000A1</t>") - 1 );
1606 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1607 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1608 ok( hr == S_OK, "got %08x\n", hr );
1609 ok( IsEqualGUID( &val_guid, &guid2 ), "wrong guid\n" );
1611 WsFreeReader( reader );
1612 WsFreeHeap( heap );
1615 static void test_WsGetXmlAttribute(void)
1617 static const WCHAR valueW[] = {'v','a','l','u','e',0};
1618 HRESULT hr;
1619 WS_XML_READER *reader;
1620 WS_XML_STRING xmlstr;
1621 WS_HEAP *heap;
1622 WCHAR *str;
1623 ULONG count;
1624 int found;
1626 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1627 ok( hr == S_OK, "got %08x\n", hr );
1629 hr = WsCreateReader( NULL, 0, &reader, NULL );
1630 ok( hr == S_OK, "got %08x\n", hr );
1632 hr = set_input( reader, data9, sizeof(data9) - 1 );
1633 ok( hr == S_OK, "got %08x\n", hr );
1635 hr = WsFillReader( reader, sizeof(data9) - 1, NULL, NULL );
1636 ok( hr == S_OK, "got %08x\n", hr );
1638 found = -1;
1639 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1640 ok( hr == S_OK, "got %08x\n", hr );
1641 ok( found == TRUE, "got %d\n", found );
1643 xmlstr.bytes = (BYTE *)"attr";
1644 xmlstr.length = sizeof("attr") - 1;
1645 xmlstr.dictionary = NULL;
1646 xmlstr.id = 0;
1647 str = NULL;
1648 count = 0;
1649 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1650 todo_wine ok( hr == S_OK, "got %08x\n", hr );
1651 todo_wine ok( str != NULL, "str not set\n" );
1652 todo_wine ok( count == 5, "got %u\n", count );
1653 /* string is not null-terminated */
1654 if (str) ok( !memcmp( str, valueW, count * sizeof(WCHAR) ), "wrong data\n" );
1656 xmlstr.bytes = (BYTE *)"none";
1657 xmlstr.length = sizeof("none") - 1;
1658 xmlstr.dictionary = NULL;
1659 xmlstr.id = 0;
1660 str = (WCHAR *)0xdeadbeef;
1661 count = 0xdeadbeef;
1662 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
1663 todo_wine ok( hr == S_FALSE, "got %08x\n", hr );
1664 todo_wine ok( str == NULL, "str not set\n" );
1665 todo_wine ok( !count, "got %u\n", count );
1667 WsFreeReader( reader );
1668 WsFreeHeap( heap );
1671 static void test_WsXmlStringEquals(void)
1673 BYTE bom[] = {0xef,0xbb,0xbf};
1674 WS_XML_STRING str1 = {0, NULL}, str2 = {0, NULL};
1675 HRESULT hr;
1677 hr = WsXmlStringEquals( NULL, NULL, NULL );
1678 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1680 hr = WsXmlStringEquals( &str1, NULL, NULL );
1681 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1683 hr = WsXmlStringEquals( NULL, &str2, NULL );
1684 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1686 hr = WsXmlStringEquals( &str1, &str2, NULL );
1687 ok( hr == S_OK, "got %08x\n", hr );
1689 str1.length = 1;
1690 str1.bytes = (BYTE *)"a";
1691 hr = WsXmlStringEquals( &str1, &str1, NULL );
1692 ok( hr == S_OK, "got %08x\n", hr );
1694 str2.length = 1;
1695 str2.bytes = (BYTE *)"b";
1696 hr = WsXmlStringEquals( &str1, &str2, NULL );
1697 ok( hr == S_FALSE, "got %08x\n", hr );
1699 str2.length = 1;
1700 str2.bytes = bom;
1701 hr = WsXmlStringEquals( &str1, &str2, NULL );
1702 ok( hr == S_FALSE, "got %08x\n", hr );
1704 str1.length = 3;
1705 hr = WsXmlStringEquals( &str1, &str2, NULL );
1706 ok( hr == S_FALSE, "got %08x\n", hr );
1708 str2.length = 3;
1709 hr = WsXmlStringEquals( &str1, &str2, NULL );
1710 ok( hr == S_FALSE, "got %08x\n", hr );
1712 str1.length = 3;
1713 str1.bytes = bom;
1714 hr = WsXmlStringEquals( &str1, &str2, NULL );
1715 ok( hr == S_OK, "got %08x\n", hr );
1718 static void test_WsAlloc(void)
1720 HRESULT hr;
1721 WS_HEAP *heap;
1722 void *ptr;
1724 hr = WsCreateHeap( 256, 0, NULL, 0, &heap, NULL );
1725 ok( hr == S_OK, "got %08x\n", hr );
1727 ptr = NULL;
1728 hr = WsAlloc( NULL, 16, &ptr, NULL );
1729 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1730 ok( ptr == NULL, "ptr set\n" );
1732 ptr = NULL;
1733 hr = WsAlloc( heap, 512, &ptr, NULL );
1734 todo_wine ok( hr == WS_E_QUOTA_EXCEEDED, "got %08x\n", hr );
1735 todo_wine ok( ptr == NULL, "ptr not set\n" );
1737 ptr = NULL;
1738 hr = WsAlloc( heap, 16, &ptr, NULL );
1739 ok( hr == S_OK, "got %08x\n", hr );
1740 ok( ptr != NULL, "ptr not set\n" );
1741 WsFreeHeap( heap );
1744 static void test_WsMoveReader(void)
1746 HRESULT hr;
1747 WS_HEAP *heap;
1748 WS_XML_READER *reader;
1749 WS_XML_WRITER *writer;
1750 WS_XML_BUFFER *buffer;
1751 WS_XML_STRING localname = {1, (BYTE *)"a"}, localname2 = {1, (BYTE *)"b"}, ns = {0, NULL};
1752 const WS_XML_NODE *node;
1753 WS_XML_ELEMENT_NODE *elem;
1754 WS_XML_UTF8_TEXT utf8;
1756 hr = WsCreateReader( NULL, 0, &reader, NULL );
1757 ok( hr == S_OK, "got %08x\n", hr );
1759 hr = WsMoveReader( NULL, WS_MOVE_TO_EOF, NULL, NULL );
1760 ok( hr == E_INVALIDARG, "got %08x\n", hr );
1762 /* reader must be set to an XML buffer */
1763 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1764 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1766 hr = set_input( reader, data8, sizeof(data8) - 1 );
1767 ok( hr == S_OK, "got %08x\n", hr );
1769 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1770 todo_wine ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1771 WsFreeReader( reader );
1773 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1774 ok( hr == S_OK, "got %08x\n", hr );
1776 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
1777 ok( hr == S_OK, "got %08x\n", hr );
1779 hr = WsCreateWriter( NULL, 0, &writer, NULL );
1780 ok( hr == S_OK, "got %08x\n", hr );
1782 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
1783 ok( hr == S_OK, "got %08x\n", hr );
1785 /* <a><b/></a> */
1786 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
1787 ok( hr == S_OK, "got %08x\n", hr );
1789 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
1790 ok( hr == S_OK, "got %08x\n", hr );
1792 hr = WsWriteEndElement( writer, NULL );
1793 ok( hr == S_OK, "got %08x\n", hr );
1795 hr = WsWriteEndElement( writer, NULL );
1796 ok( hr == S_OK, "got %08x\n", hr );
1798 hr = WsCreateReader( NULL, 0, &reader, NULL );
1799 ok( hr == S_OK, "got %08x\n", hr );
1801 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
1802 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
1804 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
1805 ok( hr == S_OK, "got %08x\n", hr );
1807 /* first element is child node of BOF node */
1808 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
1809 ok( hr == S_OK, "got %08x\n", hr );
1811 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1812 ok( hr == S_OK, "got %08x\n", hr );
1814 hr = WsGetReaderNode( reader, &node, NULL );
1815 ok( hr == S_OK, "got %08x\n", hr );
1816 elem = (WS_XML_ELEMENT_NODE *)node;
1817 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1818 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1819 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1821 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1822 ok( hr == S_OK, "got %08x\n", hr );
1824 hr = WsGetReaderNode( reader, &node, NULL );
1825 ok( hr == S_OK, "got %08x\n", hr );
1826 elem = (WS_XML_ELEMENT_NODE *)node;
1827 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1828 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1829 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1831 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1832 ok( hr == S_OK, "got %08x\n", hr );
1834 hr = WsGetReaderNode( reader, &node, NULL );
1835 ok( hr == S_OK, "got %08x\n", hr );
1836 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1838 /* EOF node is last child of BOF node */
1839 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
1840 ok( hr == S_OK, "got %08x\n", hr );
1842 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1843 ok( hr == S_OK, "got %08x\n", hr );
1845 hr = WsGetReaderNode( reader, &node, NULL );
1846 ok( hr == S_OK, "got %08x\n", hr );
1847 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1849 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1850 ok( hr == S_OK, "got %08x\n", hr );
1852 hr = WsGetReaderNode( reader, &node, NULL );
1853 ok( hr == S_OK, "got %08x\n", hr );
1854 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1856 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
1857 ok( hr == S_OK, "got %08x\n", hr );
1859 hr = WsGetReaderNode( reader, &node, NULL );
1860 ok( hr == S_OK, "got %08x\n", hr );
1861 elem = (WS_XML_ELEMENT_NODE *)node;
1862 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1863 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1864 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1866 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_ELEMENT, NULL, NULL );
1867 ok( hr == S_OK, "got %08x\n", hr );
1869 hr = WsGetReaderNode( reader, &node, NULL );
1870 ok( hr == S_OK, "got %08x\n", hr );
1871 elem = (WS_XML_ELEMENT_NODE *)node;
1872 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1873 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1874 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1876 hr = WsMoveReader( reader, WS_MOVE_TO_END_ELEMENT, NULL, NULL );
1877 ok( hr == S_OK, "got %08x\n", hr );
1879 hr = WsGetReaderNode( reader, &node, NULL );
1880 ok( hr == S_OK, "got %08x\n", hr );
1881 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1883 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1884 ok( hr == S_OK, "got %08x\n", hr );
1886 hr = WsGetReaderNode( reader, &node, NULL );
1887 ok( hr == S_OK, "got %08x\n", hr );
1888 elem = (WS_XML_ELEMENT_NODE *)node;
1889 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1890 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1891 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1893 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1894 ok( hr == S_OK, "got %08x\n", hr );
1896 hr = WsGetReaderNode( reader, &node, NULL );
1897 ok( hr == S_OK, "got %08x\n", hr );
1898 elem = (WS_XML_ELEMENT_NODE *)node;
1899 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1900 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1901 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
1903 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1904 ok( hr == S_OK, "got %08x\n", hr );
1906 hr = WsGetReaderNode( reader, &node, NULL );
1907 ok( hr == S_OK, "got %08x\n", hr );
1908 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
1910 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
1911 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
1913 WsFreeWriter( writer );
1914 WsFreeHeap( heap );
1916 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1917 ok( hr == S_OK, "got %08x\n", hr );
1919 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
1920 ok( hr == S_OK, "got %08x\n", hr );
1922 hr = WsCreateWriter( NULL, 0, &writer, NULL );
1923 ok( hr == S_OK, "got %08x\n", hr );
1925 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
1926 ok( hr == S_OK, "got %08x\n", hr );
1928 /* <a><b>test</b></a> */
1929 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
1930 ok( hr == S_OK, "got %08x\n", hr );
1932 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
1933 ok( hr == S_OK, "got %08x\n", hr );
1935 utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
1936 utf8.value.bytes = (BYTE *)"test";
1937 utf8.value.length = sizeof("test") - 1;
1938 hr = WsWriteText( writer, &utf8.text, NULL );
1939 ok( hr == S_OK, "got %08x\n", hr );
1941 hr = WsWriteEndElement( writer, NULL );
1942 ok( hr == S_OK, "got %08x\n", hr );
1944 hr = WsWriteEndElement( writer, NULL );
1945 ok( hr == S_OK, "got %08x\n", hr );
1947 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
1948 ok( hr == S_OK, "got %08x\n", hr );
1950 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
1951 ok( hr == S_OK, "got %08x\n", hr );
1953 hr = WsGetReaderNode( reader, &node, NULL );
1954 ok( hr == S_OK, "got %08x\n", hr );
1955 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1957 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1958 ok( hr == S_OK, "got %08x\n", hr );
1960 hr = WsGetReaderNode( reader, &node, NULL );
1961 ok( hr == S_OK, "got %08x\n", hr );
1962 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1964 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
1965 ok( hr == S_OK, "got %08x\n", hr );
1967 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
1968 ok( hr == S_OK, "got %08x\n", hr );
1970 hr = WsGetReaderNode( reader, &node, NULL );
1971 ok( hr == S_OK, "got %08x\n", hr );
1972 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1974 hr = WsGetReaderNode( reader, &node, NULL );
1975 ok( hr == S_OK, "got %08x\n", hr );
1976 elem = (WS_XML_ELEMENT_NODE *)node;
1977 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1978 ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
1979 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
1981 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
1982 ok( hr == S_OK, "got %08x\n", hr );
1984 hr = WsGetReaderNode( reader, &node, NULL );
1985 ok( hr == S_OK, "got %08x\n", hr );
1986 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1988 WsFreeReader( reader );
1989 WsFreeWriter( writer );
1990 WsFreeHeap( heap );
1993 static void prepare_struct_type_test( WS_XML_READER *reader, const char *data )
1995 HRESULT hr;
1996 ULONG size = strlen( data );
1998 hr = set_input( reader, data, size );
1999 ok( hr == S_OK, "got %08x\n", hr );
2001 hr = WsFillReader( reader, size, NULL, NULL );
2002 ok( hr == S_OK, "got %08x\n", hr );
2005 static void test_simple_struct_type(void)
2007 static const WCHAR testW[] = {'t','e','s','t',0};
2008 HRESULT hr;
2009 WS_XML_READER *reader;
2010 WS_HEAP *heap;
2011 WS_STRUCT_DESCRIPTION s;
2012 WS_FIELD_DESCRIPTION f, *fields[1];
2013 WS_XML_STRING ns = {0, NULL}, localname = {3, (BYTE *)"str"};
2014 WS_XML_STRING localname2 = {4, (BYTE *)"test"};
2015 const WS_XML_NODE *node;
2016 const WS_XML_ELEMENT_NODE *elem;
2017 struct test { WCHAR *str; } *test;
2019 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2020 ok( hr == S_OK, "got %08x\n", hr );
2022 hr = WsCreateReader( NULL, 0, &reader, NULL );
2023 ok( hr == S_OK, "got %08x\n", hr );
2025 prepare_struct_type_test( reader, "<str>test</str>" );
2026 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL,
2027 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2028 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2030 hr = WsGetReaderNode( reader, &node, NULL );
2031 ok( hr == S_OK, "got %08x\n", hr );
2032 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
2034 /* element field mapping */
2035 memset( &f, 0, sizeof(f) );
2036 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2037 f.localName = &localname;
2038 f.ns = &ns;
2039 f.type = WS_WSZ_TYPE;
2040 fields[0] = &f;
2042 memset( &s, 0, sizeof(s) );
2043 s.size = sizeof(struct test);
2044 s.alignment = TYPE_ALIGNMENT(struct test);
2045 s.fields = fields;
2046 s.fieldCount = 1;
2047 s.typeLocalName = &localname2;
2048 s.typeNs = &ns;
2050 test = NULL;
2051 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2052 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2053 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2054 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2056 test = NULL;
2057 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str>" );
2058 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2059 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2060 ok( hr == S_OK, "got %08x\n", hr );
2061 ok( test != NULL, "test not set\n" );
2062 if (test)
2064 ok( test->str != NULL, "str not set\n" );
2065 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2068 hr = WsGetReaderNode( reader, &node, NULL );
2069 ok( hr == S_OK, "got %08x\n", hr );
2070 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2072 test = NULL;
2073 prepare_struct_type_test( reader, "<str>test</str>" );
2074 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2075 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2076 ok( hr == S_OK, "got %08x\n", hr );
2077 ok( test != NULL, "test not set\n" );
2078 if (test)
2080 ok( test->str != NULL, "str not set\n" );
2081 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2084 hr = WsGetReaderNode( reader, &node, NULL );
2085 ok( hr == S_OK, "got %08x\n", hr );
2086 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2088 test = NULL;
2089 prepare_struct_type_test( reader, "<str>test</str>" );
2090 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2091 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2092 ok( hr == S_OK, "got %08x\n", hr );
2093 ok( test != NULL, "test not set\n" );
2094 if (test)
2096 ok( test->str != NULL, "str not set\n" );
2097 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2100 hr = WsGetReaderNode( reader, &node, NULL );
2101 ok( hr == S_OK, "got %08x\n", hr );
2102 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2104 prepare_struct_type_test( reader, "<str>test</str>" );
2105 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2106 ok( hr == S_OK, "got %08x\n", hr );
2108 hr = WsGetReaderNode( reader, &node, NULL );
2109 ok( hr == S_OK, "got %08x\n", hr );
2110 elem = (const WS_XML_ELEMENT_NODE *)node;
2111 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2112 ok( elem->localName->length == 3, "got %u\n", elem->localName->length );
2113 ok( !memcmp( elem->localName->bytes, "str", 3 ), "wrong data\n" );
2115 test = NULL;
2116 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2117 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2118 ok( hr == S_OK, "got %08x\n", hr );
2119 ok( test != NULL, "test not set\n" );
2120 if (test)
2122 ok( test->str != NULL, "str not set\n" );
2123 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
2126 hr = WsGetReaderNode( reader, &node, NULL );
2127 ok( hr == S_OK, "got %08x\n", hr );
2128 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2130 /* attribute field mapping */
2131 f.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2133 test = NULL;
2134 prepare_struct_type_test( reader, "<test str=\"test\"/>" );
2135 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2136 ok( hr == S_OK, "got %08x\n", hr );
2138 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2139 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2140 ok( hr == S_OK, "got %08x\n", hr );
2141 ok( test != NULL, "test not set\n" );
2142 if (test)
2144 ok( test->str != NULL, "str not set\n" );
2145 if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data test %p test->str %p\n", test, test->str );
2148 hr = WsGetReaderNode( reader, &node, NULL );
2149 ok( hr == S_OK, "got %08x\n", hr );
2150 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2152 WsFreeReader( reader );
2153 WsFreeHeap( heap );
2156 static void test_cdata(void)
2158 static const char test[] = "<t><![CDATA[<data>]]></t>";
2159 HRESULT hr;
2160 WS_XML_READER *reader;
2161 const WS_XML_NODE *node;
2163 hr = WsCreateReader( NULL, 0, &reader, NULL );
2164 ok( hr == S_OK, "got %08x\n", hr );
2166 hr = set_input( reader, test, sizeof(test) - 1 );
2167 ok( hr == S_OK, "got %08x\n", hr );
2169 hr = WsFillReader( reader, sizeof(test) - 1, NULL, NULL );
2170 ok( hr == S_OK, "got %08x\n", hr );
2172 hr = WsReadNode( reader, NULL );
2173 ok( hr == S_OK, "got %08x\n", hr );
2175 hr = WsGetReaderNode( reader, &node, NULL );
2176 ok( hr == S_OK, "got %08x\n", hr );
2177 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2179 hr = WsReadNode( reader, NULL );
2180 ok( hr == S_OK, "got %08x\n", hr );
2182 hr = WsGetReaderNode( reader, &node, NULL );
2183 ok( hr == S_OK, "got %08x\n", hr );
2184 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_CDATA, "got %u\n", node->nodeType );
2186 hr = WsReadNode( reader, NULL );
2187 ok( hr == S_OK, "got %08x\n", hr );
2189 hr = WsGetReaderNode( reader, &node, NULL );
2190 ok( hr == S_OK, "got %08x\n", hr );
2191 if (node)
2193 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
2194 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
2195 ok( text->text != NULL, "text not set\n" );
2196 if (text->text)
2198 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
2199 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
2200 ok( utf8->value.length == 6, "got %u\n", utf8->value.length );
2201 ok( !memcmp( utf8->value.bytes, "<data>", 6 ), "wrong data\n" );
2205 hr = WsReadNode( reader, NULL );
2206 ok( hr == S_OK, "got %08x\n", hr );
2208 hr = WsGetReaderNode( reader, &node, NULL );
2209 ok( hr == S_OK, "got %08x\n", hr );
2210 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_CDATA, "got %u\n", node->nodeType );
2212 hr = WsReadNode( reader, NULL );
2213 ok( hr == S_OK, "got %08x\n", hr );
2215 hr = WsGetReaderNode( reader, &node, NULL );
2216 ok( hr == S_OK, "got %08x\n", hr );
2217 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2219 WsFreeReader( reader );
2222 static void test_WsFindAttribute(void)
2224 static const char test[] = "<t attr='value' attr2='value2'></t>";
2225 WS_XML_STRING ns = {0, NULL}, localname = {4, (BYTE *)"attr"};
2226 WS_XML_STRING localname2 = {5, (BYTE *)"attr2"}, localname3 = {5, (BYTE *)"attr3"};
2227 WS_XML_READER *reader;
2228 ULONG index;
2229 HRESULT hr;
2231 hr = WsCreateReader( NULL, 0, &reader, NULL );
2232 ok( hr == S_OK, "got %08x\n", hr );
2234 hr = set_input( reader, test, sizeof(test) - 1 );
2235 ok( hr == S_OK, "got %08x\n", hr );
2237 hr = WsReadNode( reader, NULL );
2238 ok( hr == S_OK, "got %08x\n", hr );
2240 hr = WsFindAttribute( reader, &localname, &ns, TRUE, NULL, NULL );
2241 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2243 hr = set_input( reader, test, sizeof(test) - 1 );
2244 ok( hr == S_OK, "got %08x\n", hr );
2246 hr = WsReadNode( reader, NULL );
2247 ok( hr == S_OK, "got %08x\n", hr );
2249 hr = WsFindAttribute( reader, &localname, NULL, TRUE, &index, NULL );
2250 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2252 hr = set_input( reader, test, sizeof(test) - 1 );
2253 ok( hr == S_OK, "got %08x\n", hr );
2255 hr = WsReadNode( reader, NULL );
2256 ok( hr == S_OK, "got %08x\n", hr );
2258 hr = WsFindAttribute( reader, NULL, &ns, TRUE, &index, NULL );
2259 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2261 hr = set_input( reader, test, sizeof(test) - 1 );
2262 ok( hr == S_OK, "got %08x\n", hr );
2264 hr = WsReadNode( reader, NULL );
2265 ok( hr == S_OK, "got %08x\n", hr );
2267 index = 0xdeadbeef;
2268 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2269 ok( hr == S_OK, "got %08x\n", hr );
2270 ok( !index, "got %u\n", index );
2272 index = 0xdeadbeef;
2273 hr = WsFindAttribute( reader, &localname2, &ns, TRUE, &index, NULL );
2274 ok( hr == S_OK, "got %08x\n", hr );
2275 ok( index == 1, "got %u\n", index );
2277 hr = WsReadNode( reader, NULL );
2278 ok( hr == S_OK, "got %08x\n", hr );
2280 index = 0xdeadbeef;
2281 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2282 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2283 ok( index == 0xdeadbeef, "got %u\n", index );
2285 hr = set_input( reader, test, sizeof(test) - 1 );
2286 ok( hr == S_OK, "got %08x\n", hr );
2288 hr = WsReadNode( reader, NULL );
2289 ok( hr == S_OK, "got %08x\n", hr );
2291 index = 0xdeadbeef;
2292 hr = WsFindAttribute( reader, &localname3, &ns, TRUE, &index, NULL );
2293 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2294 ok( index == 0xdeadbeef, "got %u\n", index );
2296 hr = set_input( reader, test, sizeof(test) - 1 );
2297 ok( hr == S_OK, "got %08x\n", hr );
2299 hr = WsReadNode( reader, NULL );
2300 ok( hr == S_OK, "got %08x\n", hr );
2302 index = 0xdeadbeef;
2303 hr = WsFindAttribute( reader, &localname3, &ns, FALSE, &index, NULL );
2304 ok( hr == S_FALSE, "got %08x\n", hr );
2305 ok( index == ~0u, "got %u\n", index );
2307 WsFreeReader( reader );
2310 static void prepare_namespace_test( WS_XML_READER *reader, const char *data )
2312 HRESULT hr;
2313 ULONG size = strlen( data );
2315 hr = set_input( reader, data, size );
2316 ok( hr == S_OK, "got %08x\n", hr );
2318 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2319 ok( hr == S_OK, "got %08x\n", hr );
2322 static void test_WsGetNamespaceFromPrefix(void)
2324 WS_XML_STRING prefix = {0, NULL};
2325 const WS_XML_STRING *ns;
2326 const WS_XML_NODE *node;
2327 WS_XML_READER *reader;
2328 HRESULT hr;
2330 hr = WsCreateReader( NULL, 0, &reader, NULL );
2331 ok( hr == S_OK, "got %08x\n", hr );
2333 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, NULL, NULL );
2334 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2336 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, &ns, NULL );
2337 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2339 hr = WsGetNamespaceFromPrefix( NULL, &prefix, FALSE, &ns, NULL );
2340 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2342 ns = (const WS_XML_STRING *)0xdeadbeef;
2343 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2344 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
2345 ok( ns == (const WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2347 hr = set_input( reader, "<prefix:t xmlns:prefix2='ns'/>", sizeof("<prefix:t xmlns:prefix2='ns'/>") - 1 );
2348 ok( hr == S_OK, "got %08x\n", hr );
2349 hr = WsReadStartElement( reader, NULL );
2350 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2352 prepare_namespace_test( reader, "<t></t>" );
2353 ns = NULL;
2354 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2355 ok( hr == S_OK, "got %08x\n", hr );
2356 ok( ns != NULL, "ns not set\n" );
2357 if (ns) ok( !ns->length, "got %u\n", ns->length );
2359 prepare_namespace_test( reader, "<t xmls='ns'></t>" );
2360 ns = NULL;
2361 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2362 ok( hr == S_OK, "got %08x\n", hr );
2363 ok( ns != NULL, "ns not set\n" );
2364 if (ns) ok( !ns->length, "got %u\n", ns->length );
2366 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2367 ns = NULL;
2368 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2369 ok( hr == S_OK, "got %08x\n", hr );
2370 ok( ns != NULL, "ns not set\n" );
2371 if (ns) ok( !ns->length, "got %u\n", ns->length );
2373 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2374 prefix.bytes = (BYTE *)"prefix";
2375 prefix.length = 6;
2376 ns = NULL;
2377 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2378 ok( hr == S_OK, "got %08x\n", hr );
2379 ok( ns != NULL, "ns not set\n" );
2380 if (ns)
2382 ok( ns->length == 2, "got %u\n", ns->length );
2383 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2386 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2387 ns = NULL;
2388 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2389 ok( hr == S_OK, "got %08x\n", hr );
2390 ok( ns != NULL, "ns not set\n" );
2391 if (ns)
2393 ok( ns->length == 2, "got %u\n", ns->length );
2394 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2397 hr = set_input( reader, "<t xmlns:prefix='ns'></t>", sizeof("<t xmlns:prefix='ns'></t>") - 1 );
2398 ok( hr == S_OK, "got %08x\n", hr );
2399 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2400 ok( hr == S_OK, "got %08x\n", hr );
2401 hr = WsGetReaderNode( reader, &node, NULL );
2402 ok( hr == S_OK, "got %08x\n", hr );
2403 if (node)
2405 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2406 WS_XML_ATTRIBUTE *attr;
2407 WS_XML_UTF8_TEXT *text;
2409 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2410 ok( elem->prefix != NULL, "prefix not set\n" );
2411 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2412 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2413 ok( elem->ns != NULL, "ns not set\n" );
2414 ok( !elem->ns->length, "got %u\n", elem->ns->length );
2415 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2416 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2417 ok( elem->attributes != NULL, "attributes not set\n" );
2419 attr = elem->attributes[0];
2420 ok( attr->singleQuote, "singleQuote not set\n" );
2421 ok( attr->isXmlNs, "isXmlNs not set\n" );
2422 ok( attr->prefix != NULL, "prefix not set\n" );
2423 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2424 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2425 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2426 ok( attr->localName != NULL, "localName not set\n" );
2427 ok( attr->localName->length == 6, "got %u\n", attr->localName->length );
2428 ok( !memcmp( attr->localName->bytes, "prefix", 6 ), "wrong data\n" );
2429 ok( attr->ns != NULL, "ns not set\n" );
2430 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2431 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2432 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2433 ok( attr->value != NULL, "value not set\n" );
2435 text = (WS_XML_UTF8_TEXT *)attr->value;
2436 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
2437 ok( !text->value.length, "got %u\n", text->value.length );
2438 ok( text->value.bytes == NULL, "bytes set\n" );
2441 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2442 hr = WsReadStartElement( reader, NULL );
2443 ok( hr == S_OK, "got %08x\n", hr );
2444 hr = WsReadEndElement( reader, NULL );
2445 ok( hr == S_OK, "got %08x\n", hr );
2446 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2447 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2449 prepare_namespace_test( reader, "<t></t>" );
2450 ns = NULL;
2451 prefix.bytes = (BYTE *)"xml";
2452 prefix.length = 3;
2453 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2454 ok( hr == S_OK, "got %08x\n", hr );
2455 ok( ns != NULL, "ns not set\n" );
2456 if (ns)
2458 ok( ns->length == 36, "got %u\n", ns->length );
2459 ok( !memcmp( ns->bytes, "http://www.w3.org/XML/1998/namespace", 36 ), "wrong data\n" );
2462 prepare_namespace_test( reader, "<t></t>" );
2463 ns = NULL;
2464 prefix.bytes = (BYTE *)"xmlns";
2465 prefix.length = 5;
2466 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2467 ok( hr == S_OK, "got %08x\n", hr );
2468 ok( ns != NULL, "ns not set\n" );
2469 if (ns)
2471 ok( ns->length == 29, "got %u\n", ns->length );
2472 ok( !memcmp( ns->bytes, "http://www.w3.org/2000/xmlns/", 29 ), "wrong data\n" );
2475 prepare_namespace_test( reader, "<t></t>" );
2476 ns = (WS_XML_STRING *)0xdeadbeef;
2477 prefix.bytes = (BYTE *)"prefix2";
2478 prefix.length = 7;
2479 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2480 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2481 ok( ns == (WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2483 prepare_namespace_test( reader, "<t></t>" );
2484 ns = (WS_XML_STRING *)0xdeadbeef;
2485 prefix.bytes = (BYTE *)"prefix2";
2486 prefix.length = 7;
2487 hr = WsGetNamespaceFromPrefix( reader, &prefix, FALSE, &ns, NULL );
2488 ok( hr == S_FALSE, "got %08x\n", hr );
2489 ok( ns == NULL, "ns not set\n" );
2491 hr = set_input( reader, "<t prefix:attr='' xmlns:prefix='ns'></t>", sizeof("<t prefix:attr='' xmlns:prefix='ns'></t>") - 1 );
2492 ok( hr == S_OK, "got %08x\n", hr );
2493 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2494 ok( hr == S_OK, "got %08x\n", hr );
2495 hr = WsGetReaderNode( reader, &node, NULL );
2496 ok( hr == S_OK, "got %08x\n", hr );
2497 if (node)
2499 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2500 WS_XML_ATTRIBUTE *attr;
2502 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2503 ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
2504 ok( elem->attributes != NULL, "attributes not set\n" );
2506 attr = elem->attributes[0];
2507 ok( attr->singleQuote, "singleQuote not set\n" );
2508 ok( !attr->isXmlNs, "isXmlNs is set\n" );
2509 ok( attr->prefix != NULL, "prefix not set\n" );
2510 ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
2511 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2512 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2513 ok( attr->localName != NULL, "localName not set\n" );
2514 ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
2515 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
2516 ok( attr->ns != NULL, "ns not set\n" );
2517 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2518 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2519 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2522 hr = set_input( reader, "<t xmlns:p='ns'><u xmlns:p='ns2'/></t>", sizeof("<t xmlns:p='ns'><u xmlns:p='ns2'/></t>") - 1 );
2523 ok( hr == S_OK, "got %08x\n", hr );
2524 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2525 ok( hr == S_OK, "got %08x\n", hr );
2526 hr = WsReadStartElement( reader, NULL );
2527 ok( hr == S_OK, "got %08x\n", hr );
2529 hr = set_input( reader, "<t xmlns:p='ns'><p:u p:a=''/></t>", sizeof("<t xmlns:p='ns'><p:u p:a=''/></t>") - 1 );
2530 ok( hr == S_OK, "got %08x\n", hr );
2531 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2532 ok( hr == S_OK, "got %08x\n", hr );
2533 hr = WsReadStartElement( reader, NULL );
2534 ok( hr == S_OK, "got %08x\n", hr );
2535 hr = WsGetReaderNode( reader, &node, NULL );
2536 ok( hr == S_OK, "got %08x\n", hr );
2537 if (node)
2539 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2540 WS_XML_ATTRIBUTE *attr;
2542 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2543 ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
2544 ok( elem->attributes != NULL, "attributes not set\n" );
2546 attr = elem->attributes[0];
2547 ok( attr->prefix != NULL, "prefix not set\n" );
2548 ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
2549 ok( attr->prefix->bytes != NULL, "bytes set\n" );
2550 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong data\n" );
2551 ok( attr->localName != NULL, "localName not set\n" );
2552 ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
2553 ok( !memcmp( attr->localName->bytes, "a", 1 ), "wrong data\n" );
2554 ok( attr->ns != NULL, "ns not set\n" );
2555 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2556 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2557 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2560 hr = set_input( reader, "<t xmlns='ns'></t>", sizeof("<t xmlns='ns'></t>") - 1 );
2561 ok( hr == S_OK, "got %08x\n", hr );
2562 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2563 ok( hr == S_OK, "got %08x\n", hr );
2564 hr = WsGetReaderNode( reader, &node, NULL );
2565 ok( hr == S_OK, "got %08x\n", hr );
2566 if (node)
2568 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2569 WS_XML_ATTRIBUTE *attr;
2571 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2572 ok( elem->prefix != NULL, "prefix not set\n" );
2573 ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
2574 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2575 ok( elem->ns != NULL, "ns not set\n" );
2576 ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
2577 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2578 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong data\n" );
2580 attr = elem->attributes[0];
2581 ok( attr->isXmlNs, "isXmlNs is not set\n" );
2582 ok( attr->prefix != NULL, "prefix not set\n" );
2583 ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
2584 ok( attr->prefix->bytes == NULL, "bytes set\n" );
2585 ok( attr->localName != NULL, "localName not set\n" );
2586 ok( attr->localName->length == 5, "got %u\n", attr->localName->length );
2587 ok( !memcmp( attr->localName->bytes, "xmlns", 5 ), "wrong data\n" );
2588 ok( attr->ns != NULL, "ns not set\n" );
2589 ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
2590 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2591 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2594 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns2'></t>") - 1 );
2595 ok( hr == S_OK, "got %08x\n", hr );
2596 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2597 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2599 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns'></t>") - 1 );
2600 ok( hr == S_OK, "got %08x\n", hr );
2601 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2602 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2604 hr = set_input( reader, "<t xmlns:p='ns' xmlns:P='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:P='ns2'></t>") - 1 );
2605 ok( hr == S_OK, "got %08x\n", hr );
2606 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2607 ok( hr == S_OK, "got %08x\n", hr );
2609 WsFreeReader( reader );
2612 static void test_text_field_mapping(void)
2614 static const WCHAR testW[] = {'t','e','s','t',0};
2615 HRESULT hr;
2616 WS_XML_READER *reader;
2617 WS_HEAP *heap;
2618 WS_STRUCT_DESCRIPTION s;
2619 WS_FIELD_DESCRIPTION f, *fields[1];
2620 struct test
2622 WCHAR *str;
2623 } *test;
2625 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2626 ok( hr == S_OK, "got %08x\n", hr );
2628 hr = WsCreateReader( NULL, 0, &reader, NULL );
2629 ok( hr == S_OK, "got %08x\n", hr );
2631 prepare_struct_type_test( reader, "<a>test</a>" );
2633 memset( &f, 0, sizeof(f) );
2634 f.mapping = WS_TEXT_FIELD_MAPPING;
2635 f.type = WS_WSZ_TYPE;
2636 fields[0] = &f;
2638 memset( &s, 0, sizeof(s) );
2639 s.size = sizeof(struct test);
2640 s.alignment = TYPE_ALIGNMENT(struct test);
2641 s.fields = fields;
2642 s.fieldCount = 1;
2644 test = NULL;
2645 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2646 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2647 ok( hr == S_OK, "got %08x\n", hr );
2648 ok( test != NULL, "test not set\n" );
2649 ok( test->str != NULL, "str not set\n" );
2650 ok( !lstrcmpW( test->str, testW ), "got %s\n", wine_dbgstr_w(test->str) );
2652 WsFreeReader( reader );
2653 WsFreeHeap( heap );
2656 static void test_complex_struct_type(void)
2658 static const WCHAR timestampW[] =
2659 {'2','0','1','5','-','0','9','-','0','3','T','1','8',':','4','7',':','5','4',0};
2660 HRESULT hr;
2661 WS_ERROR *error;
2662 WS_ERROR_PROPERTY prop;
2663 WS_XML_READER *reader;
2664 WS_HEAP *heap;
2665 WS_STRUCT_DESCRIPTION s, s2;
2666 WS_FIELD_DESCRIPTION f, f2, *fields[1], *fields2[1];
2667 WS_XML_STRING str_officeconfig = {12, (BYTE *)"OfficeConfig"};
2668 WS_XML_STRING str_services = {8, (BYTE *)"services"};
2669 WS_XML_STRING str_generationtime = {14, (BYTE *)"GenerationTime"};
2670 WS_XML_STRING ns = {39, (BYTE *)"urn:schemas-microsoft-com:office:office"};
2671 LANGID langid = MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT );
2672 const WS_XML_NODE *node;
2673 const WS_XML_ELEMENT_NODE *elem;
2674 struct services
2676 WCHAR *generationtime;
2678 struct officeconfig
2680 struct services *services;
2681 } *test;
2683 prop.id = WS_ERROR_PROPERTY_LANGID;
2684 prop.value = &langid;
2685 prop.valueSize = sizeof(langid);
2686 hr = WsCreateError( &prop, 1, &error );
2687 ok( hr == S_OK, "got %08x\n", hr );
2689 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2690 ok( hr == S_OK, "got %08x\n", hr );
2692 hr = WsCreateReader( NULL, 0, &reader, NULL );
2693 ok( hr == S_OK, "got %08x\n", hr );
2695 /* element content type mapping */
2696 prepare_struct_type_test( reader, data11 );
2698 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2699 ok( hr == S_OK, "got %08x\n", hr );
2701 hr = WsGetReaderNode( reader, &node, NULL );
2702 ok( hr == S_OK, "got %08x\n", hr );
2703 elem = (const WS_XML_ELEMENT_NODE *)node;
2704 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2705 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
2706 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
2708 hr = WsReadStartElement( reader, NULL );
2709 ok( hr == S_OK, "got %08x\n", hr );
2711 hr = WsGetReaderNode( reader, &node, NULL );
2712 ok( hr == S_OK, "got %08x\n", hr );
2713 elem = (const WS_XML_ELEMENT_NODE *)node;
2714 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2715 ok( elem->localName->length == 8, "got %u\n", elem->localName->length );
2716 ok( !memcmp( elem->localName->bytes, "services", 8 ), "wrong data\n" );
2718 memset( &f2, 0, sizeof(f2) );
2719 f2.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2720 f2.localName = &str_generationtime;
2721 f2.ns = &ns;
2722 f2.type = WS_WSZ_TYPE;
2723 f2.options = WS_FIELD_OPTIONAL;
2724 fields2[0] = &f2;
2726 memset( &s2, 0, sizeof(s2) );
2727 s2.size = sizeof(*test->services);
2728 s2.alignment = TYPE_ALIGNMENT(struct services);
2729 s2.fields = fields2;
2730 s2.fieldCount = 1;
2731 s2.typeLocalName = &str_services;
2732 s2.typeNs = &ns;
2734 memset( &f, 0, sizeof(f) );
2735 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2736 f.localName = &str_services;
2737 f.ns = &ns;
2738 f.type = WS_STRUCT_TYPE;
2739 f.typeDescription = &s2;
2740 f.options = WS_FIELD_POINTER;
2741 fields[0] = &f;
2743 memset( &s, 0, sizeof(s) );
2744 s.size = sizeof(*test);
2745 s.alignment = TYPE_ALIGNMENT(struct officeconfig);
2746 s.fields = fields;
2747 s.fieldCount = 1;
2748 s.typeLocalName = &str_officeconfig;
2749 s.typeNs = &ns;
2751 test = NULL;
2752 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2753 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2754 ok( hr == S_OK, "got %08x\n", hr );
2755 ok( test != NULL, "test not set\n" );
2756 ok( !lstrcmpW( test->services->generationtime, timestampW ), "wrong data\n" );
2758 hr = WsGetReaderNode( reader, &node, NULL );
2759 ok( hr == S_OK, "got %08x\n", hr );
2760 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2762 hr = WsReadEndElement( reader, NULL );
2763 ok( hr == S_OK, "got %08x\n", hr );
2765 hr = WsGetReaderNode( reader, &node, NULL );
2766 ok( hr == S_OK, "got %08x\n", hr );
2767 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2769 hr = WsReadEndElement( reader, NULL );
2770 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
2772 /* element type mapping */
2773 prepare_struct_type_test( reader, data11 );
2775 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2776 ok( hr == S_OK, "got %08x\n", hr );
2778 hr = WsGetReaderNode( reader, &node, NULL );
2779 ok( hr == S_OK, "got %08x\n", hr );
2780 elem = (const WS_XML_ELEMENT_NODE *)node;
2781 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2782 ok( elem->localName->length == 12, "got %u\n", elem->localName->length );
2783 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
2785 test = NULL;
2786 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2787 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
2788 ok( hr == S_OK, "got %08x\n", hr );
2789 ok( test != NULL, "test not set\n" );
2790 if (test) ok( !lstrcmpW( test->services->generationtime, timestampW ), "wrong data\n" );
2792 hr = WsGetReaderNode( reader, &node, NULL );
2793 ok( hr == S_OK, "got %08x\n", hr );
2794 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2796 WsFreeReader( reader );
2797 WsFreeHeap( heap );
2798 WsFreeError( error );
2801 static void test_repeating_element(void)
2803 static const WCHAR oneW[] = {'1',0}, twoW[] = {'2',0};
2804 WS_XML_STRING str_name = {4, (BYTE *)"name"};
2805 WS_XML_STRING str_services = {8, (BYTE *)"services"};
2806 WS_XML_STRING str_service = {7, (BYTE *)"service"};
2807 WS_XML_STRING str_wrapper = {7, (BYTE *)"wrapper"};
2808 WS_XML_STRING str_id = {2, (BYTE *)"id"};
2809 WS_XML_STRING str_ns = {0, NULL};
2810 HRESULT hr;
2811 WS_XML_READER *reader;
2812 WS_HEAP *heap;
2813 WS_STRUCT_DESCRIPTION s, s2;
2814 WS_FIELD_DESCRIPTION f, f2, f3, *fields[1], *fields2[2];
2815 WS_ITEM_RANGE range;
2816 struct service { UINT32 id; };
2817 struct service2 { WCHAR *id; };
2818 struct service3 { WCHAR *name; WCHAR *id; };
2819 struct services
2821 struct service *service;
2822 ULONG service_count;
2823 } *test;
2824 struct services2
2826 struct service2 *service;
2827 ULONG service_count;
2828 } *test2;
2829 struct services3
2831 struct service3 *service;
2832 ULONG service_count;
2833 } *test3;
2834 struct services4
2836 struct service **service;
2837 ULONG service_count;
2838 } *test4;
2840 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2841 ok( hr == S_OK, "got %08x\n", hr );
2843 hr = WsCreateReader( NULL, 0, &reader, NULL );
2844 ok( hr == S_OK, "got %08x\n", hr );
2846 prepare_struct_type_test( reader, data12 );
2848 memset( &f2, 0, sizeof(f2) );
2849 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
2850 f2.localName = &str_id;
2851 f2.ns = &str_ns;
2852 f2.type = WS_UINT32_TYPE;
2853 fields2[0] = &f2;
2855 memset( &s2, 0, sizeof(s2) );
2856 s2.size = sizeof(struct service);
2857 s2.alignment = TYPE_ALIGNMENT(struct service);
2858 s2.fields = fields2;
2859 s2.fieldCount = 1;
2860 s2.typeLocalName = &str_service;
2862 memset( &f, 0, sizeof(f) );
2863 f.mapping = WS_REPEATING_ELEMENT_FIELD_MAPPING;
2864 f.countOffset = FIELD_OFFSET(struct services, service_count);
2865 f.type = WS_STRUCT_TYPE;
2866 f.typeDescription = &s2;
2867 f.itemLocalName = &str_service;
2868 f.itemNs = &str_ns;
2869 fields[0] = &f;
2871 memset( &s, 0, sizeof(s) );
2872 s.size = sizeof(struct services);
2873 s.alignment = TYPE_ALIGNMENT(struct services);
2874 s.fields = fields;
2875 s.fieldCount = 1;
2876 s.typeLocalName = &str_services;
2878 test = NULL;
2879 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2880 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2881 ok( hr == S_OK, "got %08x\n", hr );
2882 ok( test != NULL, "test not set\n" );
2883 ok( test->service != NULL, "service not set\n" );
2884 ok( test->service_count == 2, "got %u\n", test->service_count );
2885 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
2886 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
2888 /* array of pointers */
2889 prepare_struct_type_test( reader, data12 );
2890 f.options = WS_FIELD_POINTER;
2891 test4 = NULL;
2892 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2893 WS_READ_REQUIRED_POINTER, heap, &test4, sizeof(test4), NULL );
2894 ok( hr == S_OK || broken(hr == E_INVALIDARG) /* win7 */, "got %08x\n", hr );
2895 if (test4)
2897 ok( test4->service != NULL, "service not set\n" );
2898 ok( test4->service_count == 2, "got %u\n", test4->service_count );
2899 ok( test4->service[0]->id == 1, "got %u\n", test4->service[0]->id );
2900 ok( test4->service[1]->id == 2, "got %u\n", test4->service[1]->id );
2903 /* item range */
2904 prepare_struct_type_test( reader, data13 );
2905 f.options = 0;
2906 range.minItemCount = 0;
2907 range.maxItemCount = 1;
2908 f.itemRange = &range;
2909 test = NULL;
2910 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2911 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2912 ok( hr == S_OK, "got %08x\n", hr );
2913 ok( test != NULL, "test not set\n" );
2914 ok( test->service != NULL, "service not set\n" );
2915 ok( !test->service_count, "got %u\n", test->service_count );
2917 /* wrapper element */
2918 prepare_struct_type_test( reader, data14 );
2919 f.itemRange = NULL;
2920 f.localName = &str_wrapper;
2921 f.ns = &str_ns;
2922 test = NULL;
2923 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2924 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2925 ok( hr == S_OK, "got %08x\n", hr );
2926 ok( test != NULL, "test not set\n" );
2927 ok( test->service != NULL, "service not set\n" );
2928 ok( test->service_count == 2, "got %u\n", test->service_count );
2929 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
2930 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
2932 /* repeating text field mapping */
2933 prepare_struct_type_test( reader, data15 );
2934 f2.mapping = WS_TEXT_FIELD_MAPPING;
2935 f2.localName = NULL;
2936 f2.ns = NULL;
2937 f2.type = WS_WSZ_TYPE;
2938 s2.size = sizeof(struct service2);
2939 s2.alignment = TYPE_ALIGNMENT(struct service2);
2940 test2 = NULL;
2941 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2942 WS_READ_REQUIRED_POINTER, heap, &test2, sizeof(test2), NULL );
2943 ok( hr == S_OK, "got %08x\n", hr );
2944 ok( test2 != NULL, "test2 not set\n" );
2945 ok( test2->service != NULL, "service not set\n" );
2946 ok( test2->service_count == 2, "got %u\n", test2->service_count );
2947 ok( !lstrcmpW( test2->service[0].id, oneW ), "wrong data\n" );
2948 ok( !lstrcmpW( test2->service[1].id, twoW ), "wrong data\n" );
2950 /* repeating attribute field + text field mapping */
2951 prepare_struct_type_test( reader, data16 );
2952 f2.offset = FIELD_OFFSET(struct service3, id);
2953 memset( &f3, 0, sizeof(f3) );
2954 f3.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2955 f3.localName = &str_name;
2956 f3.ns = &str_ns;
2957 f3.type = WS_WSZ_TYPE;
2958 fields2[0] = &f3;
2959 fields2[1] = &f2;
2960 s2.size = sizeof(struct service3);
2961 s2.alignment = TYPE_ALIGNMENT(struct service3);
2962 s2.fieldCount = 2;
2963 test3 = NULL;
2964 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2965 WS_READ_REQUIRED_POINTER, heap, &test3, sizeof(test3), NULL );
2966 ok( hr == S_OK, "got %08x\n", hr );
2967 ok( test3 != NULL, "test3 not set\n" );
2968 ok( test3->service != NULL, "service not set\n" );
2969 ok( test3->service_count == 2, "got %u\n", test3->service_count );
2970 ok( !lstrcmpW( test3->service[0].name, oneW ), "wrong data\n" );
2971 ok( !lstrcmpW( test3->service[0].id, oneW ), "wrong data\n" );
2972 ok( !lstrcmpW( test3->service[1].name, twoW ), "wrong data\n" );
2973 ok( !lstrcmpW( test3->service[1].id, twoW ), "wrong data\n" );
2975 WsFreeReader( reader );
2976 WsFreeHeap( heap );
2979 static void test_WsResetHeap(void)
2981 HRESULT hr;
2982 WS_HEAP *heap;
2983 SIZE_T requested, actual;
2984 ULONG size;
2985 void *ptr;
2987 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2988 ok( hr == S_OK, "got %08x\n", hr );
2990 requested = 0xdeadbeef;
2991 size = sizeof(requested);
2992 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
2993 ok( hr == S_OK, "got %08x\n", hr );
2994 ok( !requested, "got %u\n", (ULONG)requested );
2996 actual = 0xdeadbeef;
2997 size = sizeof(actual);
2998 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
2999 ok( hr == S_OK, "got %08x\n", hr );
3000 ok( !actual, "got %u\n", (ULONG)actual );
3002 hr = WsAlloc( heap, 128, &ptr, NULL );
3003 ok( hr == S_OK, "got %08x\n", hr );
3005 requested = 0xdeadbeef;
3006 size = sizeof(requested);
3007 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3008 ok( hr == S_OK, "got %08x\n", hr );
3009 todo_wine ok( requested == 128, "got %u\n", (ULONG)requested );
3011 actual = 0xdeadbeef;
3012 size = sizeof(actual);
3013 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3014 ok( hr == S_OK, "got %08x\n", hr );
3015 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
3017 hr = WsAlloc( heap, 1, &ptr, NULL );
3018 ok( hr == S_OK, "got %08x\n", hr );
3020 requested = 0xdeadbeef;
3021 size = sizeof(requested);
3022 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3023 ok( hr == S_OK, "got %08x\n", hr );
3024 todo_wine ok( requested == 129, "got %u\n", (ULONG)requested );
3026 actual = 0xdeadbeef;
3027 size = sizeof(actual);
3028 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3029 ok( hr == S_OK, "got %08x\n", hr );
3030 todo_wine ok( actual == 384, "got %u\n", (ULONG)actual );
3032 hr = WsResetHeap( NULL, NULL );
3033 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3035 hr = WsResetHeap( heap, NULL );
3036 ok( hr == S_OK, "got %08x\n", hr );
3038 requested = 0xdeadbeef;
3039 size = sizeof(requested);
3040 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3041 ok( hr == S_OK, "got %08x\n", hr );
3042 ok( !requested, "got %u\n", (ULONG)requested );
3044 actual = 0xdeadbeef;
3045 size = sizeof(actual);
3046 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3047 ok( hr == S_OK, "got %08x\n", hr );
3048 todo_wine ok( actual == 128, "got %u\n", (ULONG)actual );
3050 WsFreeHeap( heap );
3053 static void test_datetime(void)
3055 static const struct
3057 const char *str;
3058 HRESULT hr;
3059 __int64 ticks;
3060 WS_DATETIME_FORMAT format;
3062 tests[] =
3064 {"<t>0000-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3065 {"<t>0001-01-01T00:00:00Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3066 {"<t>0001-01-01T00:00:00.Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3067 {"<t>0001-01-01T00:00:00.0Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3068 {"<t>0001-01-01T00:00:00.1Z</t>", S_OK, 0x0000f4240, WS_DATETIME_FORMAT_UTC},
3069 {"<t>0001-01-01T00:00:00.01Z</t>", S_OK, 0x0000186a0, WS_DATETIME_FORMAT_UTC},
3070 {"<t>0001-01-01T00:00:00.0000001Z</t>", S_OK, 1, WS_DATETIME_FORMAT_UTC},
3071 {"<t>0001-01-01T00:00:00.9999999Z</t>", S_OK, 0x00098967f, WS_DATETIME_FORMAT_UTC},
3072 {"<t>0001-01-01T00:00:00.0000000Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3073 {"<t>0001-01-01T00:00:00.00000001Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3074 {"<t>0001-01-01T00:00:00Z-</t>", WS_E_INVALID_FORMAT, 0},
3075 {"<t>-0001-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3076 {"<t>0001-00-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3077 {"<t>0001-13-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3078 {"<t>0001-12-01T00:00:00Z</t>", S_OK, 0x1067555f88000, WS_DATETIME_FORMAT_UTC},
3079 {"<t>0001-01-00T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3080 {"<t>2001-01-32T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3081 {"<t>2001-01-31T00:00:00Z</t>", S_OK, 0x8c2592fe3794000, WS_DATETIME_FORMAT_UTC},
3082 {"<t>1900-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3083 {"<t>2000-02-29T00:00:00Z</t>", S_OK, 0x8c1505f0e438000, 0},
3084 {"<t>2001-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3085 {"<t>2001-02-28T00:00:00Z</t>", S_OK, 0x8c26f30870a4000, WS_DATETIME_FORMAT_UTC},
3086 {"<t>0001-00-01U00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3087 {"<t>0001-01-01T24:00:00Z</t>", S_OK, 0xc92a69c000, WS_DATETIME_FORMAT_UTC},
3088 {"<t>0001-01-01T24:00:01Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3089 {"<t>0001-01-01T00:60:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3090 {"<t>0001-01-01T00:00:60Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3091 {"<t>0001-01-01T00:00:00Y</t>", WS_E_INVALID_FORMAT, 0, 0},
3092 {"<t>0001-01-01T00:00:00+00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3093 {"<t>0001-01-01T00:00:00-00:01</t>", S_OK, 0x023c34600, WS_DATETIME_FORMAT_LOCAL},
3094 {"<t>9999-12-31T24:00:00+00:01</t>", S_OK, 0x2bca2875d073fa00, WS_DATETIME_FORMAT_LOCAL},
3095 {"<t>9999-12-31T24:00:00-00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3096 {"<t>0002-01-01T00:00:00+14:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3097 {"<t>0002-01-01T00:00:00+15:00</t>", WS_E_INVALID_FORMAT, 0, 0},
3098 {"<t>0002-01-01T00:00:00+13:60</t>", WS_E_INVALID_FORMAT, 0, 0},
3099 {"<t>0002-01-01T00:00:00+13:59</t>", S_OK, 0x11e5c43cc5600, WS_DATETIME_FORMAT_LOCAL},
3100 {"<t>0002-01-01T00:00:00+01:00</t>", S_OK, 0x11ec917025800, WS_DATETIME_FORMAT_LOCAL},
3101 {"<t>2016-01-01T00:00:00-01:00</t>", S_OK, 0x8d31246dfbba800, WS_DATETIME_FORMAT_LOCAL},
3102 {"<t>2016-01-01T00:00:00Z</t>", S_OK, 0x8d3123e7df74000, WS_DATETIME_FORMAT_UTC},
3103 {"<t> 2016-01-02T03:04:05Z </t>", S_OK, 0x8d313215fb64080, WS_DATETIME_FORMAT_UTC},
3104 {"<t>+2016-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3105 {"<t></t>", WS_E_INVALID_FORMAT, 0, 0},
3106 {"<t>01-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3107 {"<t>1601-01-01T00:00:00Z</t>", S_OK, 0x701ce1722770000, WS_DATETIME_FORMAT_UTC},
3109 HRESULT hr;
3110 WS_XML_READER *reader;
3111 WS_HEAP *heap;
3112 WS_DATETIME date;
3113 ULONG i;
3115 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3116 ok( hr == S_OK, "got %08x\n", hr );
3118 hr = WsCreateReader( NULL, 0, &reader, NULL );
3119 ok( hr == S_OK, "got %08x\n", hr );
3120 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3122 memset( &date, 0, sizeof(date) );
3123 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3124 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DATETIME_TYPE, NULL,
3125 WS_READ_REQUIRED_VALUE, heap, &date, sizeof(date), NULL );
3126 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3127 if (hr == S_OK)
3129 ok( date.ticks == tests[i].ticks, "%u: got %x%08x\n", i, (ULONG)(date.ticks >> 32), (ULONG)date.ticks );
3130 ok( date.format == tests[i].format, "%u: got %u\n", i, date.format );
3134 WsFreeReader( reader );
3135 WsFreeHeap( heap );
3138 static void test_WsDateTimeToFileTime(void)
3140 static const struct
3142 WS_DATETIME dt;
3143 HRESULT hr;
3144 FILETIME ft;
3146 tests[] =
3148 { {0, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3149 { {0x701ce172276ffff, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3150 { {0x701ce1722770000, WS_DATETIME_FORMAT_UTC}, S_OK, {0, 0} },
3151 { {0x2bca2875f4373fff, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c03fff, 0x24c85a5e} },
3152 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c04000, 0x24c85a5e} },
3153 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_LOCAL}, S_OK, {0xd1c04000, 0x24c85a5e} },
3154 { {~0, WS_DATETIME_FORMAT_UTC}, S_OK, {0xdd88ffff, 0xf8fe31e8} },
3156 WS_DATETIME dt;
3157 FILETIME ft;
3158 HRESULT hr;
3159 ULONG i;
3161 hr = WsDateTimeToFileTime( NULL, NULL, NULL );
3162 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3164 dt.ticks = 0x701ce172277000;
3165 dt.format = WS_DATETIME_FORMAT_UTC;
3166 hr = WsDateTimeToFileTime( &dt, NULL, NULL );
3167 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3169 hr = WsDateTimeToFileTime( NULL, &ft, NULL );
3170 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3172 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3174 memset( &ft, 0, sizeof(ft) );
3175 hr = WsDateTimeToFileTime( &tests[i].dt, &ft, NULL );
3176 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3177 if (hr == S_OK)
3179 ok( ft.dwLowDateTime == tests[i].ft.dwLowDateTime, "%u: got %08x\n", i, ft.dwLowDateTime );
3180 ok( ft.dwHighDateTime == tests[i].ft.dwHighDateTime, "%u: got %08x\n", i, ft.dwHighDateTime );
3185 static void test_WsFileTimeToDateTime(void)
3187 WS_DATETIME dt;
3188 FILETIME ft;
3189 HRESULT hr;
3191 hr = WsFileTimeToDateTime( NULL, NULL, NULL );
3192 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3194 ft.dwLowDateTime = ft.dwHighDateTime = 0;
3195 hr = WsFileTimeToDateTime( &ft, NULL, NULL );
3196 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3198 hr = WsFileTimeToDateTime( NULL, &dt, NULL );
3199 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3201 dt.ticks = 0xdeadbeef;
3202 dt.format = 0xdeadbeef;
3203 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3204 ok( hr == S_OK, "got %08x\n", hr );
3205 ok( dt.ticks == 0x701ce1722770000, "got %x%08x\n", (ULONG)(dt.ticks >> 32), (ULONG)dt.ticks );
3206 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3208 ft.dwLowDateTime = 0xd1c03fff;
3209 ft.dwHighDateTime = 0x24c85a5e;
3210 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3211 ok( hr == S_OK, "got %08x\n", hr );
3212 ok( dt.ticks == 0x2bca2875f4373fff, "got %x%08x\n", (ULONG)(dt.ticks >> 32), (ULONG)dt.ticks );
3213 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3215 ft.dwLowDateTime++;
3216 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3217 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3219 ft.dwLowDateTime = 0xdd88ffff;
3220 ft.dwHighDateTime = 0xf8fe31e8;
3221 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3222 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3224 ft.dwLowDateTime++;
3225 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3226 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
3229 static void test_double(void)
3231 static const struct
3233 const char *str;
3234 HRESULT hr;
3235 ULONGLONG val;
3237 tests[] =
3239 {"<t>0.0</t>", S_OK, 0},
3240 {"<t>-0.0</t>", S_OK, 0x8000000000000000},
3241 {"<t>+0.0</t>", S_OK, 0},
3242 {"<t>-</t>", S_OK, 0},
3243 {"<t>+</t>", S_OK, 0},
3244 {"<t>.0</t>", S_OK, 0},
3245 {"<t>0.</t>", S_OK, 0},
3246 {"<t>0</t>", S_OK, 0},
3247 {"<t> 0 </t>", S_OK, 0},
3248 {"<t></t>", WS_E_INVALID_FORMAT, 0},
3249 {"<t>0,1</t>", WS_E_INVALID_FORMAT, 0},
3250 {"<t>1.1.</t>", WS_E_INVALID_FORMAT, 0},
3251 {"<t>1</t>", S_OK, 0x3ff0000000000000},
3252 {"<t>1.0000000000000002</t>", S_OK, 0x3ff0000000000001},
3253 {"<t>1.0000000000000004</t>", S_OK, 0x3ff0000000000002},
3254 {"<t>10000000000000000000</t>", S_OK, 0x43e158e460913d00},
3255 {"<t>100000000000000000000</t>", S_OK, 0x4415af1d78b58c40},
3256 {"<t>2</t>", S_OK, 0x4000000000000000},
3257 {"<t>-2</t>", S_OK, 0xc000000000000000},
3258 {"<t>nodouble</t>", WS_E_INVALID_FORMAT, 0},
3259 {"<t>INF</t>", S_OK, 0x7ff0000000000000},
3260 {"<t>-INF</t>", S_OK, 0xfff0000000000000},
3261 {"<t>+INF</t>", WS_E_INVALID_FORMAT, 0},
3262 {"<t>Infinity</t>", WS_E_INVALID_FORMAT, 0},
3263 {"<t>-Infinity</t>", WS_E_INVALID_FORMAT, 0},
3264 {"<t>inf</t>", WS_E_INVALID_FORMAT, 0},
3265 {"<t>NaN</t>", S_OK, 0xfff8000000000000},
3266 {"<t>-NaN</t>", WS_E_INVALID_FORMAT, 0},
3267 {"<t>NAN</t>", WS_E_INVALID_FORMAT, 0},
3268 {"<t>0.3</t>", S_OK, 0x3fd3333333333333},
3269 {"<t>0.33</t>", S_OK, 0x3fd51eb851eb851f},
3270 {"<t>0.333</t>", S_OK, 0x3fd54fdf3b645a1d},
3271 {"<t>0.3333</t>", S_OK, 0x3fd554c985f06f69},
3272 {"<t>0.33333</t>", S_OK, 0x3fd555475a31a4be},
3273 {"<t>0.333333</t>", S_OK, 0x3fd55553ef6b5d46},
3274 {"<t>0.3333333</t>", S_OK, 0x3fd55555318abc87},
3275 {"<t>0.33333333</t>", S_OK, 0x3fd5555551c112da},
3276 {"<t>0.333333333</t>", S_OK, 0x3fd5555554f9b516},
3277 {"<t>0.3333333333</t>", S_OK, 0x3fd55555554c2bb5},
3278 {"<t>0.33333333333</t>", S_OK, 0x3fd5555555546ac5},
3279 {"<t>0.3333333333333</t>", S_OK, 0x3fd55555555552fd},
3280 {"<t>0.33333333333333</t>", S_OK, 0x3fd5555555555519},
3281 {"<t>0.333333333333333</t>", S_OK, 0x3fd555555555554f},
3282 {"<t>0.3333333333333333</t>", S_OK, 0x3fd5555555555555},
3283 {"<t>0.33333333333333333</t>", S_OK, 0x3fd5555555555555},
3284 {"<t>0.1e10</t>", S_OK, 0x41cdcd6500000000},
3285 {"<t>1e</t>", WS_E_INVALID_FORMAT, 0},
3286 {"<t>1e0</t>", S_OK, 0x3ff0000000000000},
3287 {"<t>1e+1</t>", S_OK, 0x4024000000000000},
3288 {"<t>1e-1</t>", S_OK, 0x3fb999999999999a},
3289 {"<t>e10</t>", WS_E_INVALID_FORMAT, 0},
3290 {"<t>1e10.</t>", WS_E_INVALID_FORMAT, 0},
3291 {"<t>1E10</t>", S_OK, 0x4202a05f20000000},
3292 {"<t>1e10</t>", S_OK, 0x4202a05f20000000},
3293 {"<t>1e-10</t>", S_OK, 0x3ddb7cdfd9d7bdbb},
3294 {"<t>1.7976931348623158e308</t>", S_OK, 0x7fefffffffffffff},
3295 {"<t>1.7976931348623159e308</t>", S_OK, 0x7ff0000000000000},
3296 {"<t>4.94065645841247e-324</t>", S_OK, 0x1},
3298 HRESULT hr;
3299 WS_XML_READER *reader;
3300 WS_HEAP *heap;
3301 ULONGLONG val;
3302 ULONG i;
3304 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3305 ok( hr == S_OK, "got %08x\n", hr );
3307 hr = WsCreateReader( NULL, 0, &reader, NULL );
3308 ok( hr == S_OK, "got %08x\n", hr );
3310 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3312 val = 0;
3313 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3314 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DOUBLE_TYPE, NULL,
3315 WS_READ_REQUIRED_VALUE, heap, &val, sizeof(val), NULL );
3316 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3317 if (hr == tests[i].hr) ok( val == tests[i].val, "%u: got %x%08x\n", i, (ULONG)(val >> 32), (ULONG)val );
3320 WsFreeReader( reader );
3321 WsFreeHeap( heap );
3324 static void test_WsReadElement(void)
3326 WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
3327 HRESULT hr;
3328 WS_XML_READER *reader;
3329 WS_ELEMENT_DESCRIPTION desc;
3330 UINT32 val;
3332 hr = WsCreateReader( NULL, 0, &reader, NULL );
3333 ok( hr == S_OK, "got %08x\n", hr );
3335 desc.elementLocalName = &localname;
3336 desc.elementNs = &ns;
3337 desc.type = WS_UINT32_TYPE;
3338 desc.typeDescription = NULL;
3340 prepare_struct_type_test( reader, "<t>1</t>" );
3341 hr = WsReadElement( NULL, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3342 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3344 prepare_struct_type_test( reader, "<t>1</t>" );
3345 hr = WsReadElement( reader, NULL, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3346 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3348 prepare_struct_type_test( reader, "<t>1</t>" );
3349 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, NULL, sizeof(val), NULL );
3350 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3352 prepare_struct_type_test( reader, "<t>1</t>" );
3353 val = 0xdeadbeef;
3354 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3355 ok( hr == S_OK, "got %08x\n", hr );
3356 ok( val == 1, "got %u\n", val );
3358 WsFreeReader( reader );
3361 static void test_WsReadValue(void)
3363 HRESULT hr;
3364 WS_XML_READER *reader;
3365 UINT32 val;
3367 hr = WsCreateReader( NULL, 0, &reader, NULL );
3368 ok( hr == S_OK, "got %08x\n", hr );
3370 prepare_struct_type_test( reader, "<t>1</t>" );
3371 hr = WsReadValue( NULL, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3372 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3374 prepare_struct_type_test( reader, "<t>1</t>" );
3375 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, NULL, sizeof(val), NULL );
3376 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3378 /* reader must be positioned correctly */
3379 prepare_struct_type_test( reader, "<t>1</t>" );
3380 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3381 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3383 prepare_struct_type_test( reader, "<t>1</t>" );
3384 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3385 ok( hr == S_OK, "got %08x\n", hr );
3387 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3388 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3390 prepare_struct_type_test( reader, "<t>1</t>" );
3391 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3392 ok( hr == S_OK, "got %08x\n", hr );
3394 hr = WsReadStartElement( reader, NULL );
3395 ok( hr == S_OK, "got %08x\n", hr );
3397 val = 0xdeadbeef;
3398 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3399 ok( hr == S_OK, "got %08x\n", hr );
3400 ok( val == 1, "got %u\n", val );
3402 prepare_struct_type_test( reader, "<u t='1'></u>" );
3403 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3404 ok( hr == S_OK, "got %08x\n", hr );
3406 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3407 ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
3409 WsFreeReader( reader );
3412 static void test_WsResetError(void)
3414 WS_ERROR_PROPERTY prop;
3415 ULONG size, code;
3416 WS_ERROR *error;
3417 LANGID langid;
3418 HRESULT hr;
3420 hr = WsResetError( NULL );
3421 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3423 error = NULL;
3424 hr = WsCreateError( NULL, 0, &error );
3425 ok( hr == S_OK, "got %08x\n", hr );
3426 ok( error != NULL, "error not set\n" );
3428 code = 0xdeadbeef;
3429 size = sizeof(code);
3430 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3431 ok( hr == S_OK, "got %08x\n", hr );
3433 hr = WsResetError( error );
3434 ok( hr == S_OK, "got %08x\n", hr );
3436 code = 0xdeadbeef;
3437 size = sizeof(code);
3438 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3439 ok( hr == S_OK, "got %08x\n", hr );
3440 ok( !code, "got %u\n", code );
3442 WsFreeError( error );
3444 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
3445 prop.id = WS_ERROR_PROPERTY_LANGID;
3446 prop.value = &langid;
3447 prop.valueSize = sizeof(langid);
3448 hr = WsCreateError( &prop, 1, &error );
3449 ok( hr == S_OK, "got %08x\n", hr );
3451 langid = 0xdead;
3452 size = sizeof(langid);
3453 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3454 ok( hr == S_OK, "got %08x\n", hr );
3455 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3457 hr = WsResetError( error );
3458 ok( hr == S_OK, "got %08x\n", hr );
3460 langid = 0xdead;
3461 size = sizeof(langid);
3462 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
3463 ok( hr == S_OK, "got %08x\n", hr );
3464 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
3466 WsFreeError( error );
3469 static void test_WsGetReaderPosition(void)
3471 WS_HEAP *heap;
3472 WS_XML_READER *reader;
3473 WS_XML_BUFFER *buffer;
3474 WS_XML_NODE_POSITION pos;
3475 HRESULT hr;
3477 hr = WsGetReaderPosition( NULL, NULL, NULL );
3478 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3480 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3481 ok( hr == S_OK, "got %08x\n", hr );
3483 hr = WsCreateReader( NULL, 0, &reader, NULL );
3484 ok( hr == S_OK, "got %08x\n", hr );
3486 /* reader must be set to an XML buffer */
3487 hr = WsGetReaderPosition( reader, &pos, NULL );
3488 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3490 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
3491 ok( hr == S_OK, "got %08x\n", hr );
3493 hr = WsGetReaderPosition( reader, &pos, NULL );
3494 ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
3496 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
3497 ok( hr == S_OK, "got %08x\n", hr );
3499 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
3500 ok( hr == S_OK, "got %08x\n", hr );
3502 hr = WsGetReaderPosition( reader, NULL, NULL );
3503 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3505 pos.buffer = pos.node = NULL;
3506 hr = WsGetReaderPosition( reader, &pos, NULL );
3507 ok( hr == S_OK, "got %08x\n", hr );
3508 ok( pos.buffer != NULL, "buffer not set\n" );
3509 ok( pos.node != NULL, "node not set\n" );
3511 WsFreeReader( reader );
3512 WsFreeHeap( heap );
3515 static void test_WsSetReaderPosition(void)
3517 WS_HEAP *heap;
3518 WS_XML_READER *reader;
3519 WS_XML_BUFFER *buf1, *buf2;
3520 WS_XML_NODE_POSITION pos;
3521 HRESULT hr;
3523 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3524 ok( hr == S_OK, "got %08x\n", hr );
3526 hr = WsSetReaderPosition( NULL, NULL, NULL );
3527 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3529 hr = WsCreateReader( NULL, 0, &reader, NULL );
3530 ok( hr == S_OK, "got %08x\n", hr );
3532 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf1, NULL );
3533 ok( hr == S_OK, "got %08x\n", hr );
3535 hr = WsSetInputToBuffer( reader, buf1, NULL, 0, NULL );
3536 ok( hr == S_OK, "got %08x\n", hr );
3538 hr = WsSetReaderPosition( reader, NULL, NULL );
3539 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3541 pos.buffer = pos.node = NULL;
3542 hr = WsGetReaderPosition( reader, &pos, NULL );
3543 ok( hr == S_OK, "got %08x\n", hr );
3544 ok( pos.buffer == buf1, "wrong buffer\n" );
3545 ok( pos.node != NULL, "node not set\n" );
3547 hr = WsSetReaderPosition( reader, &pos, NULL );
3548 ok( hr == S_OK, "got %08x\n", hr );
3550 /* different buffer */
3551 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf2, NULL );
3552 ok( hr == S_OK, "got %08x\n", hr );
3554 pos.buffer = buf2;
3555 hr = WsSetReaderPosition( reader, &pos, NULL );
3556 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3558 WsFreeReader( reader );
3559 WsFreeHeap( heap );
3562 static void test_entities(void)
3564 static const char str1[] = "<t>&#xA</t>";
3565 static const char str2[] = "<t>&#xA;</t>";
3566 static const char str3[] = "<t>&#xa;</t>";
3567 static const char str4[] = "<t>&#xaaaa;</t>";
3568 static const char str5[] = "<t>&#xaaaaa;</t>";
3569 static const char str6[] = "<t>&1</t>";
3570 static const char str7[] = "<t>&1;</t>";
3571 static const char str8[] = "<t>&1111;</t>";
3572 static const char str9[] = "<t>&11111;</t>";
3573 static const char str10[] = "<t>&lt;</t>";
3574 static const char str11[] = "<t>&gt;</t>";
3575 static const char str12[] = "<t>&quot;</t>";
3576 static const char str13[] = "<t>&amp;</t>";
3577 static const char str14[] = "<t>&apos;</t>";
3578 static const char str15[] = "<t>&sopa;</t>";
3579 static const char str16[] = "<t>&#;</t>";
3580 static const char str17[] = "<t>&;</t>";
3581 static const char str18[] = "<t>&&</t>";
3582 static const char str19[] = "<t>&</t>";
3583 static const char str20[] = "<t>&#xaaaaaa;</t>";
3584 static const char str21[] = "<t>&#xd7ff;</t>";
3585 static const char str22[] = "<t>&#xd800;</t>";
3586 static const char str23[] = "<t>&#xdfff;</t>";
3587 static const char str24[] = "<t>&#xe000;</t>";
3588 static const char str25[] = "<t>&#xfffe;</t>";
3589 static const char str26[] = "<t>&#xffff;</t>";
3590 static const char str27[] = "<t>&LT;</t>";
3591 static const char res4[] = {0xea, 0xaa, 0xaa, 0x00};
3592 static const char res5[] = {0xf2, 0xaa, 0xaa, 0xaa, 0x00};
3593 static const char res21[] = {0xed, 0x9f, 0xbf, 0x00};
3594 static const char res24[] = {0xee, 0x80, 0x80, 0x00};
3595 static const struct
3597 const char *str;
3598 HRESULT hr;
3599 const char *res;
3601 tests[] =
3603 { str1, WS_E_INVALID_FORMAT },
3604 { str2, S_OK, "\n" },
3605 { str3, S_OK, "\n" },
3606 { str4, S_OK, res4 },
3607 { str5, S_OK, res5 },
3608 { str6, WS_E_INVALID_FORMAT },
3609 { str7, WS_E_INVALID_FORMAT },
3610 { str8, WS_E_INVALID_FORMAT },
3611 { str9, WS_E_INVALID_FORMAT },
3612 { str10, S_OK, "<" },
3613 { str11, S_OK, ">" },
3614 { str12, S_OK, "\"" },
3615 { str13, S_OK, "&" },
3616 { str14, S_OK, "'" },
3617 { str15, WS_E_INVALID_FORMAT },
3618 { str16, WS_E_INVALID_FORMAT },
3619 { str17, WS_E_INVALID_FORMAT },
3620 { str18, WS_E_INVALID_FORMAT },
3621 { str19, WS_E_INVALID_FORMAT },
3622 { str20, WS_E_INVALID_FORMAT },
3623 { str21, S_OK, res21 },
3624 { str22, WS_E_INVALID_FORMAT },
3625 { str23, WS_E_INVALID_FORMAT },
3626 { str24, S_OK, res24 },
3627 { str25, WS_E_INVALID_FORMAT },
3628 { str26, WS_E_INVALID_FORMAT },
3629 { str27, WS_E_INVALID_FORMAT },
3631 HRESULT hr;
3632 WS_XML_READER *reader;
3633 const WS_XML_NODE *node;
3634 const WS_XML_UTF8_TEXT *utf8;
3635 ULONG i;
3637 hr = WsCreateReader( NULL, 0, &reader, NULL );
3638 ok( hr == S_OK, "got %08x\n", hr );
3640 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
3642 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
3643 ok( hr == S_OK, "%u: got %08x\n", i, hr );
3645 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3646 ok( hr == S_OK, "%u: got %08x\n", i, hr );
3648 hr = WsReadNode( reader, NULL );
3649 ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
3650 if (hr != S_OK) continue;
3652 hr = WsGetReaderNode( reader, &node, NULL );
3653 ok( hr == S_OK, "%u: got %08x\n", i, hr );
3655 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_TEXT_NODE *)node)->text;
3656 ok( utf8->value.length == strlen(tests[i].res), "%u: got %u\n", i, utf8->value.length );
3657 ok( !memcmp( utf8->value.bytes, tests[i].res, strlen(tests[i].res) ), "%u: wrong data\n", i );
3660 hr = set_input( reader, "<t a='&#xA;&#xA;'/>", sizeof("<t a='&#xA;&#xA;'/>") - 1 );
3661 ok( hr == S_OK, "got %08x\n", hr );
3663 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3664 ok( hr == S_OK, "got %08x\n", hr );
3666 hr = WsGetReaderNode( reader, &node, NULL );
3667 ok( hr == S_OK, "got %08x\n", hr );
3669 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_ELEMENT_NODE *)node)->attributes[0]->value;
3670 ok( utf8->value.length == 2, "got %u\n", utf8->value.length );
3671 ok( !memcmp( utf8->value.bytes, "\n\n", 2 ), "wrong data\n" );
3673 WsFreeReader( reader );
3676 static void test_field_options(void)
3678 static const char xml[] =
3679 "<t xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><wsz i:nil=\"true\"/>"
3680 "<s i:nil=\"true\"/></t>";
3681 static const GUID guid_null = {0};
3682 HRESULT hr;
3683 WS_HEAP *heap;
3684 WS_XML_READER *reader;
3685 WS_STRUCT_DESCRIPTION s, s2;
3686 WS_FIELD_DESCRIPTION f, f2, f3, f4, f5, *fields[4], *fields2[1];
3687 WS_XML_STRING ns = {0, NULL}, str_wsz = {3, (BYTE *)"wsz"}, str_s = {1, (BYTE *)"s"};
3688 WS_XML_STRING str_int32 = {5, (BYTE *)"int32"}, str_guid = {4, (BYTE *)"guid"};
3689 WS_DEFAULT_VALUE def_val;
3690 INT32 val_int32;
3691 struct s
3693 INT32 int32;
3695 struct test
3697 WCHAR *wsz;
3698 struct s *s;
3699 INT32 int32;
3700 GUID guid;
3701 } *test;
3703 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3704 ok( hr == S_OK, "got %08x\n", hr );
3706 hr = WsCreateReader( NULL, 0, &reader, NULL );
3707 ok( hr == S_OK, "got %08x\n", hr );
3709 hr = set_input( reader, xml, sizeof(xml) - 1 );
3710 ok( hr == S_OK, "got %08x\n", hr );
3712 memset( &f, 0, sizeof(f) );
3713 f.mapping = WS_ELEMENT_FIELD_MAPPING;
3714 f.localName = &str_wsz;
3715 f.ns = &ns;
3716 f.type = WS_WSZ_TYPE;
3717 f.options = WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
3718 fields[0] = &f;
3720 memset( &f3, 0, sizeof(f3) );
3721 f3.mapping = WS_ELEMENT_FIELD_MAPPING;
3722 f3.localName = &str_int32;
3723 f3.ns = &ns;
3724 f3.type = WS_INT32_TYPE;
3725 fields2[0] = &f3;
3727 memset( &s2, 0, sizeof(s2) );
3728 s2.size = sizeof(struct s);
3729 s2.alignment = TYPE_ALIGNMENT(struct s);
3730 s2.fields = fields2;
3731 s2.fieldCount = 1;
3733 memset( &f2, 0, sizeof(f2) );
3734 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
3735 f2.localName = &str_s;
3736 f2.ns = &ns;
3737 f2.type = WS_STRUCT_TYPE;
3738 f2.typeDescription = &s2;
3739 f2.offset = FIELD_OFFSET(struct test, s);
3740 f2.options = WS_FIELD_POINTER|WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
3741 fields[1] = &f2;
3743 val_int32 = -1;
3744 def_val.value = &val_int32;
3745 def_val.valueSize = sizeof(val_int32);
3747 memset( &f4, 0, sizeof(f4) );
3748 f4.mapping = WS_ELEMENT_FIELD_MAPPING;
3749 f4.localName = &str_int32;
3750 f4.ns = &ns;
3751 f4.type = WS_INT32_TYPE;
3752 f4.offset = FIELD_OFFSET(struct test, int32);
3753 f4.options = WS_FIELD_OPTIONAL;
3754 f4.defaultValue = &def_val;
3755 fields[2] = &f4;
3757 memset( &f5, 0, sizeof(f5) );
3758 f5.mapping = WS_ELEMENT_FIELD_MAPPING;
3759 f5.localName = &str_guid;
3760 f5.ns = &ns;
3761 f5.type = WS_GUID_TYPE;
3762 f5.offset = FIELD_OFFSET(struct test, guid);
3763 f5.options = WS_FIELD_OPTIONAL;
3764 fields[3] = &f5;
3766 memset( &s, 0, sizeof(s) );
3767 s.size = sizeof(struct test);
3768 s.alignment = TYPE_ALIGNMENT(struct test);
3769 s.fields = fields;
3770 s.fieldCount = 4;
3772 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3773 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3774 ok( hr == S_OK, "got %08x\n", hr );
3775 ok( !test->wsz, "wsz is set\n" );
3776 ok( !test->s, "s is set\n" );
3777 ok( test->int32 == -1, "got %d\n", test->int32 );
3778 ok( IsEqualGUID( &test->guid, &guid_null ), "wrong guid\n" );
3780 WsFreeReader( reader );
3781 WsFreeHeap( heap );
3784 START_TEST(reader)
3786 test_WsCreateError();
3787 test_WsCreateHeap();
3788 test_WsCreateReader();
3789 test_WsSetInput();
3790 test_WsSetInputToBuffer();
3791 test_WsFillReader();
3792 test_WsReadToStartElement();
3793 test_WsReadStartElement();
3794 test_WsReadEndElement();
3795 test_WsReadNode();
3796 test_WsReadType();
3797 test_WsGetXmlAttribute();
3798 test_WsXmlStringEquals();
3799 test_WsAlloc();
3800 test_WsMoveReader();
3801 test_simple_struct_type();
3802 test_cdata();
3803 test_WsFindAttribute();
3804 test_WsGetNamespaceFromPrefix();
3805 test_text_field_mapping();
3806 test_complex_struct_type();
3807 test_repeating_element();
3808 test_WsResetHeap();
3809 test_datetime();
3810 test_WsDateTimeToFileTime();
3811 test_WsFileTimeToDateTime();
3812 test_double();
3813 test_WsReadElement();
3814 test_WsReadValue();
3815 test_WsResetError();
3816 test_WsGetReaderPosition();
3817 test_WsSetReaderPosition();
3818 test_entities();
3819 test_field_options();