windowscodecs: Silence fixme for IID_CMetaBitmapRenderTarget.
[wine.git] / dlls / webservices / tests / reader.c
blob7f42d0488e3bb671d214e465c6e4eef8cddf738f
1 /*
2 * Copyright 2015 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdio.h>
20 #include "windows.h"
21 #include "rpc.h"
22 #include "webservices.h"
23 #include "wine/test.h"
25 static const GUID guid_null;
27 static const char data1[] =
28 "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
30 static const char data2[] =
31 {0xef,0xbb,0xbf,'<','t','e','x','t','>','t','e','s','t','<','/','t','e','x','t','>',0};
33 static const char data3[] =
34 "<?xml version=\"1.0\" encoding=\"utf-8\"?> "
35 "<text>test</TEXT>";
37 static const char data4[] =
38 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
39 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">\r\n"
40 " <o:services o:GenerationTime=\"2015-09-03T18:47:54\">\r\n"
41 " <!--Build: 16.0.6202.6852-->\r\n"
42 " <o:default>\r\n"
43 " <o:ticket o:headerName=\"Authorization\" o:headerValue=\"{}\" />\r\n"
44 " </o:default>\r\n"
45 " <o:service o:name=\"LiveOAuthLoginStart\">\r\n"
46 " <o:url>https://login.[Live.WebHost]/oauth20_authorize.srf</o:url>\r\n"
47 " </o:service>\r\n"
48 "</o:services>\r\n"
49 "</o:OfficeConfig>\r\n";
51 static const char data5[] =
52 "</text>";
54 static const char data6[] =
55 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
56 "<text attr= \"value\" attr2='value2'>test</text>";
58 static const char data7[] =
59 "<!-- comment -->";
61 static const char data8[] =
62 "<node1><node2>test</node2></node1>";
64 static const char data9[] =
65 "<text xml:attr=\"value\">test</text>";
67 static const char data10[] =
68 "<a></b>";
70 static void test_WsCreateError(void)
72 HRESULT hr;
73 WS_ERROR *error;
74 WS_ERROR_PROPERTY prop;
75 ULONG size, code, count;
76 LANGID langid;
78 hr = WsCreateError( NULL, 0, NULL );
79 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
81 error = NULL;
82 hr = WsCreateError( NULL, 0, &error );
83 ok( hr == S_OK, "got %#lx\n", hr );
84 ok( error != NULL, "error not set\n" );
86 count = 0xdeadbeef;
87 size = sizeof(count);
88 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
89 ok( hr == S_OK, "got %#lx\n", hr );
90 ok( !count, "got %lu\n", count );
92 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
93 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
95 code = 0xdeadbeef;
96 size = sizeof(code);
97 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
98 ok( hr == S_OK, "got %#lx\n", hr );
99 ok( !code, "got %lu\n", code );
101 code = 0xdeadbeef;
102 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
103 ok( hr == S_OK, "got %#lx\n", hr );
104 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
105 ok( hr == S_OK, "got %#lx\n", hr );
106 ok( code == 0xdeadbeef, "got %lu\n", code );
108 langid = 0xdead;
109 size = sizeof(langid);
110 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
111 ok( hr == S_OK, "got %#lx\n", hr );
112 ok( langid == GetUserDefaultUILanguage(), "got %u\n", langid );
114 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
115 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
116 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
118 count = 0xdeadbeef;
119 size = sizeof(count);
120 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID + 1, &count, size );
121 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
122 ok( count == 0xdeadbeef, "got %lu\n", count );
123 WsFreeError( error );
125 count = 1;
126 prop.id = WS_ERROR_PROPERTY_STRING_COUNT;
127 prop.value = &count;
128 prop.valueSize = sizeof(count);
129 hr = WsCreateError( &prop, 1, &error );
130 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
132 code = 0xdeadbeef;
133 prop.id = WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE;
134 prop.value = &code;
135 prop.valueSize = sizeof(code);
136 hr = WsCreateError( &prop, 1, &error );
137 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
139 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
140 prop.id = WS_ERROR_PROPERTY_LANGID;
141 prop.value = &langid;
142 prop.valueSize = sizeof(langid);
143 hr = WsCreateError( &prop, 1, &error );
144 ok( hr == S_OK, "got %#lx\n", hr );
146 langid = 0xdead;
147 size = sizeof(langid);
148 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
149 ok( hr == S_OK, "got %#lx\n", hr );
150 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
151 WsFreeError( error );
153 count = 0xdeadbeef;
154 prop.id = WS_ERROR_PROPERTY_LANGID + 1;
155 prop.value = &count;
156 prop.valueSize = sizeof(count);
157 hr = WsCreateError( &prop, 1, &error );
158 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
161 static void test_WsCreateHeap(void)
163 HRESULT hr;
164 WS_HEAP *heap;
165 WS_HEAP_PROPERTY prop;
166 SIZE_T max, trim, requested, actual;
167 ULONG size;
169 hr = WsCreateHeap( 0, 0, NULL, 0, NULL, NULL );
170 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
172 heap = NULL;
173 hr = WsCreateHeap( 0, 0, NULL, 0, &heap, NULL );
174 ok( hr == S_OK, "got %#lx\n", hr );
175 ok( heap != NULL, "heap not set\n" );
176 WsFreeHeap( heap );
178 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, NULL, NULL );
179 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
181 heap = NULL;
182 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
183 ok( hr == S_OK, "got %#lx\n", hr );
184 ok( heap != NULL, "heap not set\n" );
185 WsFreeHeap( heap );
187 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 0, &heap, NULL );
188 ok( hr == S_OK, "got %#lx\n", hr );
190 max = 0xdeadbeef;
191 size = sizeof(max);
192 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_MAX_SIZE, &max, size, NULL );
193 ok( hr == S_OK, "got %#lx\n", hr );
194 ok( max == 1 << 16, "got %Iu\n", max );
196 trim = 0xdeadbeef;
197 size = sizeof(trim);
198 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_TRIM_SIZE, &trim, size, NULL );
199 ok( hr == S_OK, "got %#lx\n", hr );
200 ok( trim == 1 << 6, "got %Iu\n", trim );
202 requested = 0xdeadbeef;
203 size = sizeof(requested);
204 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
205 ok( hr == S_OK, "got %#lx\n", hr );
206 ok( !requested, "got %Iu\n", requested );
208 actual = 0xdeadbeef;
209 size = sizeof(actual);
210 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
211 ok( hr == S_OK, "got %#lx\n", hr );
212 ok( !actual, "got %Iu\n", actual );
214 actual = 0xdeadbeef;
215 size = sizeof(actual);
216 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE + 1, &actual, size, NULL );
217 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
218 ok( actual == 0xdeadbeef, "got %Iu\n", actual );
219 WsFreeHeap( heap );
221 max = 1 << 16;
222 prop.id = WS_HEAP_PROPERTY_MAX_SIZE;
223 prop.value = &max;
224 prop.valueSize = sizeof(max);
225 hr = WsCreateHeap( 1 << 16, 1 << 6, &prop, 1, &heap, NULL );
226 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
228 hr = WsCreateHeap( 1 << 16, 1 << 6, NULL, 1, &heap, NULL );
229 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
232 static HRESULT set_input( WS_XML_READER *reader, const char *data, ULONG size )
234 WS_XML_READER_TEXT_ENCODING text = {{WS_XML_READER_ENCODING_TYPE_TEXT}, WS_CHARSET_AUTO};
235 WS_XML_READER_BUFFER_INPUT buf;
237 buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
238 buf.encodedData = (void *)data;
239 buf.encodedDataSize = size;
240 return WsSetInput( reader, &text.encoding, &buf.input, NULL, 0, NULL );
243 static void test_WsCreateReader(void)
245 HRESULT hr;
246 WS_XML_READER *reader;
247 WS_XML_READER_PROPERTY prop;
248 ULONG size, max_depth, max_attrs, trim_size, buffer_size, max_ns;
249 BOOL allow_fragment, read_decl, in_attr;
250 ULONGLONG row, column;
251 WS_CHARSET charset;
253 hr = WsCreateReader( NULL, 0, NULL, NULL );
254 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
256 reader = NULL;
257 hr = WsCreateReader( NULL, 0, &reader, NULL );
258 ok( hr == S_OK, "got %#lx\n", hr );
259 ok( reader != NULL, "reader not set\n" );
261 /* can't retrieve properties before input is set */
262 max_depth = 0xdeadbeef;
263 size = sizeof(max_depth);
264 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
265 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
266 ok( max_depth == 0xdeadbeef, "max_depth set\n" );
268 hr = set_input( reader, data1, sizeof(data1) - 1 );
269 ok( hr == S_OK, "got %#lx\n", hr );
271 /* check some defaults */
272 max_depth = 0xdeadbeef;
273 size = sizeof(max_depth);
274 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
275 ok( hr == S_OK, "got %#lx\n", hr );
276 ok( max_depth == 32, "got %lu\n", max_depth );
278 allow_fragment = TRUE;
279 size = sizeof(allow_fragment);
280 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_ALLOW_FRAGMENT, &allow_fragment, size, NULL );
281 ok( hr == S_OK, "got %#lx\n", hr );
282 ok( !allow_fragment, "got %d\n", allow_fragment );
284 max_attrs = 0xdeadbeef;
285 size = sizeof(max_attrs);
286 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES, &max_attrs, size, NULL );
287 ok( hr == S_OK, "got %#lx\n", hr );
288 ok( max_attrs == 128, "got %lu\n", max_attrs );
290 read_decl = FALSE;
291 size = sizeof(read_decl);
292 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_READ_DECLARATION, &read_decl, size, NULL );
293 ok( hr == S_OK, "got %#lx\n", hr );
294 ok( read_decl, "got %u\n", read_decl );
296 charset = 0xdeadbeef;
297 size = sizeof(charset);
298 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
299 ok( hr == S_OK, "got %#lx\n", hr );
300 ok( charset == WS_CHARSET_UTF8, "got %u\n", charset );
302 size = sizeof(trim_size);
303 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_UTF8_TRIM_SIZE, &trim_size, size, NULL );
304 todo_wine ok( hr == E_INVALIDARG, "got %#lx\n", hr );
305 WsFreeReader( reader );
307 hr = WsCreateReader( NULL, 0, &reader, NULL );
308 ok( hr == S_OK, "got %#lx\n", hr );
310 hr = set_input( reader, data1, sizeof(data1) - 1 );
311 ok( hr == S_OK, "got %#lx\n", hr );
313 size = sizeof(buffer_size);
314 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_STREAM_BUFFER_SIZE, &buffer_size, size, NULL );
315 todo_wine ok( hr == E_INVALIDARG, "got %#lx\n", hr );
316 WsFreeReader( reader );
318 hr = WsCreateReader( NULL, 0, &reader, NULL );
319 ok( hr == S_OK, "got %#lx\n", hr );
321 hr = set_input( reader, data1, sizeof(data1) - 1 );
322 ok( hr == S_OK, "got %#lx\n", hr );
324 max_ns = 0xdeadbeef;
325 size = sizeof(max_ns);
326 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_NAMESPACES, &max_ns, size, NULL );
327 ok( hr == S_OK, "got %#lx\n", hr );
328 ok( max_ns == 32, "got %lu\n", max_ns );
329 WsFreeReader( reader );
331 /* change a property */
332 max_depth = 16;
333 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
334 prop.value = &max_depth;
335 prop.valueSize = sizeof(max_depth);
336 hr = WsCreateReader( &prop, 1, &reader, NULL );
337 ok( hr == S_OK, "got %#lx\n", hr );
339 hr = set_input( reader, data1, sizeof(data1) - 1 );
340 ok( hr == S_OK, "got %#lx\n", hr );
342 max_depth = 0xdeadbeef;
343 size = sizeof(max_depth);
344 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
345 ok( hr == S_OK, "got %#lx\n", hr );
346 ok( max_depth == 16, "got %lu\n", max_depth );
347 WsFreeReader( reader );
349 /* show that some properties are read-only */
350 row = 1;
351 prop.id = WS_XML_READER_PROPERTY_ROW;
352 prop.value = &row;
353 prop.valueSize = sizeof(row);
354 hr = WsCreateReader( &prop, 1, &reader, NULL );
355 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
357 column = 1;
358 prop.id = WS_XML_READER_PROPERTY_COLUMN;
359 prop.value = &column;
360 prop.valueSize = sizeof(column);
361 hr = WsCreateReader( &prop, 1, &reader, NULL );
362 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
364 in_attr = TRUE;
365 prop.id = WS_XML_READER_PROPERTY_IN_ATTRIBUTE;
366 prop.value = &in_attr;
367 prop.valueSize = sizeof(in_attr);
368 hr = WsCreateReader( &prop, 1, &reader, NULL );
369 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
372 static void test_WsSetInput(void)
374 static char test1[] = {0xef,0xbb,0xbf,'<','a','/','>'};
375 static char test2[] = {'<','a','/','>'};
376 static char test3[] = {'<','!','-','-'};
377 static char test4[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"',
378 ' ','e','n','c','o','d','i','n','g','=','"','u','t','f','-','8','"','?','>'};
379 static char test5[] = {'<','?','x','m','l',' ','e','n','c','o','d','i','n','g','=',
380 '"','u','t','f','-','8','"','?','>'};
381 static char test6[] = {'<','?','x','m','l'};
382 static char test7[] = {'<','?','y','m','l'};
383 static char test8[] = {'<','?'};
384 static char test9[] = {'<','!'};
385 static char test10[] = {0xff,0xfe,'<',0,'a',0,'/',0,'>',0};
386 static char test11[] = {'<',0,'a',0,'/',0,'>',0};
387 static char test12[] = {'<',0,'!',0,'-',0,'-',0};
388 static char test13[] = {'<',0,'?',0};
389 static char test14[] = {'a','b'};
390 static char test15[] = {'a','b','c'};
391 static char test16[] = {'a',0};
392 static char test17[] = {'a',0,'b',0};
393 static char test18[] = {'<',0,'a',0,'b',0};
394 static char test19[] = {'<',0,'a',0};
395 static char test20[] = {0,'a','b'};
396 static char test21[] = {0,0};
397 static char test22[] = {0,0,0};
398 static char test23[] = {'<',0,'?',0,'x',0,'m',0,'l',0};
399 static char test24[] = {'<',0,'a',0,'>',0,'b',0,'<',0,'/',0,'>',0};
400 HRESULT hr;
401 WS_XML_READER *reader;
402 WS_XML_READER_PROPERTY prop;
403 WS_XML_READER_TEXT_ENCODING enc;
404 WS_XML_READER_BUFFER_INPUT input;
405 WS_XML_TEXT_NODE *text;
406 WS_XML_UTF8_TEXT *utf8;
407 WS_CHARSET charset;
408 const WS_XML_NODE *node;
409 ULONG i, size, max_depth;
410 BOOL found;
411 static const struct
413 void *data;
414 ULONG size;
415 HRESULT hr;
416 WS_CHARSET charset;
417 int todo;
419 tests[] =
421 { test1, sizeof(test1), S_OK, WS_CHARSET_UTF8 },
422 { test2, sizeof(test2), S_OK, WS_CHARSET_UTF8 },
423 { test3, sizeof(test3), S_OK, WS_CHARSET_UTF8 },
424 { test4, sizeof(test4), S_OK, WS_CHARSET_UTF8 },
425 { test5, sizeof(test5), WS_E_INVALID_FORMAT, 0, 1 },
426 { test6, sizeof(test6), WS_E_INVALID_FORMAT, 0, 1 },
427 { test7, sizeof(test7), WS_E_INVALID_FORMAT, 0, 1 },
428 { test8, sizeof(test8), WS_E_INVALID_FORMAT, 0 },
429 { test9, sizeof(test9), WS_E_INVALID_FORMAT, 0 },
430 { test10, sizeof(test10), S_OK, WS_CHARSET_UTF16LE },
431 { test11, sizeof(test11), S_OK, WS_CHARSET_UTF16LE },
432 { test12, sizeof(test12), S_OK, WS_CHARSET_UTF16LE },
433 { test13, sizeof(test13), WS_E_INVALID_FORMAT, 0, 1 },
434 { test14, sizeof(test14), WS_E_INVALID_FORMAT, 0 },
435 { test15, sizeof(test15), S_OK, WS_CHARSET_UTF8 },
436 { test16, sizeof(test16), WS_E_INVALID_FORMAT, 0 },
437 { test17, sizeof(test17), S_OK, WS_CHARSET_UTF8 },
438 { test18, sizeof(test18), S_OK, WS_CHARSET_UTF16LE },
439 { test19, sizeof(test19), S_OK, WS_CHARSET_UTF16LE },
440 { test20, sizeof(test20), S_OK, WS_CHARSET_UTF8 },
441 { test21, sizeof(test21), WS_E_INVALID_FORMAT, 0 },
442 { test22, sizeof(test22), S_OK, WS_CHARSET_UTF8 },
443 { test23, sizeof(test23), WS_E_INVALID_FORMAT, 0, 1 },
446 hr = WsCreateReader( NULL, 0, &reader, NULL );
447 ok( hr == S_OK, "got %#lx\n", hr );
449 hr = WsSetInput( NULL, NULL, NULL, NULL, 0, NULL );
450 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
452 node = NULL;
453 hr = WsGetReaderNode( reader, &node, NULL );
454 ok( hr == S_OK, "got %#lx\n", hr );
455 ok( node != NULL, "node not set\n" );
456 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
458 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
459 enc.charSet = WS_CHARSET_UTF8;
461 input.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
462 input.encodedData = (void *)data1;
463 input.encodedDataSize = sizeof(data1) - 1;
465 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
466 ok( hr == S_OK, "got %#lx\n", hr );
468 node = NULL;
469 hr = WsGetReaderNode( reader, &node, NULL );
470 ok( hr == S_OK, "got %#lx\n", hr );
471 ok( node != NULL, "node not set\n" );
472 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
474 /* multiple calls are allowed */
475 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
476 ok( hr == S_OK, "got %#lx\n", hr );
478 /* charset is detected by WsSetInput */
479 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
480 enc.charSet = WS_CHARSET_AUTO;
482 for (i = 0; i < ARRAY_SIZE( tests ); i++)
484 input.encodedData = tests[i].data;
485 input.encodedDataSize = tests[i].size;
486 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
487 ok( hr == S_OK, "%lu: got %#lx\n", i, hr );
489 charset = 0xdeadbeef;
490 size = sizeof(charset);
491 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
492 todo_wine_if (tests[i].todo)
494 ok( hr == tests[i].hr, "%lu: got %#lx expected %#lx\n", i, hr, tests[i].hr );
495 if (hr == S_OK)
496 ok( charset == tests[i].charset, "%lu: got %u expected %u\n", i, charset, tests[i].charset );
500 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
501 enc.charSet = WS_CHARSET_UTF8;
503 /* reader properties can be set with WsSetInput */
504 max_depth = 16;
505 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
506 prop.value = &max_depth;
507 prop.valueSize = sizeof(max_depth);
508 hr = WsSetInput( reader, &enc.encoding, &input.input, &prop, 1, NULL );
509 ok( hr == S_OK, "got %#lx\n", hr );
511 max_depth = 0xdeadbeef;
512 size = sizeof(max_depth);
513 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
514 ok( hr == S_OK, "got %#lx\n", hr );
515 ok( max_depth == 16, "got %lu\n", max_depth );
517 /* show that the reader converts text to UTF-8 */
518 enc.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT;
519 enc.charSet = WS_CHARSET_UTF16LE;
520 input.encodedData = (void *)test24;
521 input.encodedDataSize = sizeof(test24);
522 hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
523 ok( hr == S_OK, "got %#lx\n", hr );
525 found = -1;
526 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
527 ok( hr == S_OK, "got %#lx\n", hr );
528 if (hr == S_OK)
530 ok( found == TRUE, "got %d\n", found );
532 hr = WsReadStartElement( reader, NULL );
533 ok( hr == S_OK, "got %#lx\n", hr );
535 hr = WsGetReaderNode( reader, &node, NULL );
536 ok( hr == S_OK, "got %#lx\n", hr );
537 text = (WS_XML_TEXT_NODE *)node;
538 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
539 ok( text->text != NULL, "text not set\n" );
540 utf8 = (WS_XML_UTF8_TEXT *)text->text;
541 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
542 ok( utf8->value.length == 1, "got %lu\n", utf8->value.length );
543 ok( utf8->value.bytes[0] == 'b', "wrong data\n" );
545 WsFreeReader( reader );
548 static void test_WsSetInputToBuffer(void)
550 HRESULT hr;
551 WS_HEAP *heap;
552 WS_XML_BUFFER *buffer;
553 WS_XML_READER *reader;
554 WS_XML_READER_PROPERTY prop;
555 const WS_XML_NODE *node;
556 ULONG size, max_depth;
558 hr = WsCreateReader( NULL, 0, &reader, NULL );
559 ok( hr == S_OK, "got %#lx\n", hr );
561 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
562 ok( hr == S_OK, "got %#lx\n", hr );
564 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
565 ok( hr == S_OK, "got %#lx\n", hr );
567 hr = WsSetInputToBuffer( NULL, NULL, NULL, 0, NULL );
568 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
570 hr = WsSetInputToBuffer( reader, NULL, NULL, 0, NULL );
571 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
573 node = NULL;
574 hr = WsGetReaderNode( reader, &node, NULL );
575 ok( hr == S_OK, "got %#lx\n", hr );
576 ok( node != NULL, "node not set\n" );
577 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
579 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
580 ok( hr == S_OK, "got %#lx\n", hr );
582 node = NULL;
583 hr = WsGetReaderNode( reader, &node, NULL );
584 ok( hr == S_OK, "got %#lx\n", hr );
585 ok( node != NULL, "node not set\n" );
586 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
588 /* multiple calls are allowed */
589 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
590 ok( hr == S_OK, "got %#lx\n", hr );
592 /* reader properties can be set with WsSetInputToBuffer */
593 max_depth = 16;
594 prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
595 prop.value = &max_depth;
596 prop.valueSize = sizeof(max_depth);
597 hr = WsSetInputToBuffer( reader, buffer, &prop, 1, NULL );
598 ok( hr == S_OK, "got %#lx\n", hr );
600 max_depth = 0xdeadbeef;
601 size = sizeof(max_depth);
602 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
603 ok( hr == S_OK, "got %#lx\n", hr );
604 ok( max_depth == 16, "got %lu\n", max_depth );
606 WsFreeReader( reader );
607 WsFreeHeap( heap );
610 static void test_WsFillReader(void)
612 HRESULT hr;
613 WS_XML_READER *reader;
614 const WS_XML_NODE *node;
616 /* what happens of we don't call WsFillReader? */
617 hr = WsCreateReader( NULL, 0, &reader, NULL );
618 ok( hr == S_OK, "got %#lx\n", hr );
620 node = NULL;
621 hr = WsGetReaderNode( reader, &node, NULL );
622 ok( hr == S_OK, "got %#lx\n", hr );
623 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
625 hr = set_input( reader, data1, sizeof(data1) - 1 );
626 ok( hr == S_OK, "got %#lx\n", hr );
628 node = NULL;
629 hr = WsGetReaderNode( reader, &node, NULL );
630 ok( hr == S_OK, "got %#lx\n", hr );
631 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
633 hr = WsReadNode( reader, NULL );
634 ok( hr == S_OK, "got %#lx\n", hr );
636 node = NULL;
637 hr = WsGetReaderNode( reader, &node, NULL );
638 ok( hr == S_OK, "got %#lx\n", hr );
639 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
640 WsFreeReader( reader );
642 hr = WsCreateReader( NULL, 0, &reader, NULL );
643 ok( hr == S_OK, "got %#lx\n", hr );
645 hr = set_input( reader, data1, sizeof(data1) - 1 );
646 ok( hr == S_OK, "got %#lx\n", hr );
648 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
649 ok( hr == S_OK, "got %#lx\n", hr );
651 hr = set_input( reader, data1, sizeof(data1) - 1 );
652 ok( hr == S_OK, "got %#lx\n", hr );
654 node = NULL;
655 hr = WsGetReaderNode( reader, &node, NULL );
656 ok( hr == S_OK, "got %#lx\n", hr );
657 ok( node != NULL, "node not set\n" );
658 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
660 hr = WsFillReader( NULL, sizeof(data1) - 1, NULL, NULL );
661 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
663 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
664 ok( hr == S_OK, "got %#lx\n", hr );
666 node = NULL;
667 hr = WsGetReaderNode( reader, &node, NULL );
668 ok( hr == S_OK, "got %#lx\n", hr );
669 ok( node != NULL, "node not set\n" );
670 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
672 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
673 ok( hr == S_OK, "got %#lx\n", hr );
675 /* min_size larger than input size */
676 hr = WsFillReader( reader, sizeof(data1), NULL, NULL );
677 ok( hr == S_OK, "got %#lx\n", hr );
678 WsFreeReader( reader );
681 static void test_WsReadToStartElement(void)
683 HRESULT hr;
684 WS_XML_READER *reader;
685 const WS_XML_NODE *node, *node2;
686 int found;
688 hr = WsCreateReader( NULL, 0, &reader, NULL );
689 ok( hr == S_OK, "got %#lx\n", hr );
691 hr = set_input( reader, data1, sizeof(data1) - 1 );
692 ok( hr == S_OK, "got %#lx\n", hr );
694 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
695 ok( hr == S_OK, "got %#lx\n", hr );
697 hr = WsGetReaderNode( reader, &node, NULL );
698 ok( hr == S_OK, "got %#lx\n", hr );
699 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
701 hr = WsFillReader( reader, sizeof(data1) - 1, NULL, NULL );
702 ok( hr == S_OK, "got %#lx\n", hr );
704 hr = WsReadToStartElement( NULL, NULL, NULL, NULL, NULL );
705 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
707 found = -1;
708 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
709 ok( hr == S_OK, "got %#lx\n", hr );
710 ok( found == FALSE, "got %d\n", found );
712 hr = WsGetReaderNode( reader, &node, NULL );
713 ok( hr == S_OK, "got %#lx\n", hr );
714 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
716 hr = set_input( reader, data2, sizeof(data2) - 1 );
717 ok( hr == S_OK, "got %#lx\n", hr );
719 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
720 ok( hr == S_OK, "got %#lx\n", hr );
722 hr = WsGetReaderNode( reader, &node, NULL );
723 ok( hr == S_OK, "got %#lx\n", hr );
724 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
726 found = -1;
727 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
728 ok( hr == S_OK, "got %#lx\n", hr );
729 ok( found == TRUE, "got %d\n", found );
731 hr = WsGetReaderNode( reader, &node, NULL );
732 ok( hr == S_OK, "got %#lx\n", hr );
733 if (node)
735 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
737 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
738 ok( elem->prefix != NULL, "prefix not set\n" );
739 if (elem->prefix)
741 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
743 ok( elem->localName != NULL, "localName not set\n" );
744 if (elem->localName)
746 ok( elem->localName->length == 4, "got %lu\n", elem->localName->length );
747 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
749 ok( elem->ns != NULL, "ns not set\n" );
750 if (elem->ns)
752 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
754 ok( !elem->attributeCount, "got %lu\n", elem->attributeCount );
755 ok( elem->attributes == NULL, "attributes set\n" );
756 ok( !elem->isEmpty, "isEmpty not zero\n" );
759 found = -1;
760 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
761 ok( hr == S_OK, "got %#lx\n", hr );
762 ok( found == TRUE, "got %d\n", found );
764 node2 = NULL;
765 hr = WsGetReaderNode( reader, &node2, NULL );
766 ok( hr == S_OK, "got %#lx\n", hr );
767 ok( node2 == node, "different node\n" );
769 hr = set_input( reader, data3, sizeof(data3) - 1 );
770 ok( hr == S_OK, "got %#lx\n", hr );
772 hr = WsFillReader( reader, sizeof(data3) - 1, NULL, NULL );
773 ok( hr == S_OK, "got %#lx\n", hr );
775 found = -1;
776 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
777 ok( hr == S_OK, "got %#lx\n", hr );
778 ok( found == TRUE, "got %d\n", found );
780 hr = WsGetReaderNode( reader, &node, NULL );
781 ok( hr == S_OK, "got %#lx\n", hr );
782 if (node)
784 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
786 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
787 ok( elem->localName != NULL, "localName not set\n" );
788 if (elem->localName)
790 ok( elem->localName->length == 4, "got %lu\n", elem->localName->length );
791 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
795 hr = set_input( reader, data4, sizeof(data4) - 1 );
796 ok( hr == S_OK, "got %#lx\n", hr );
798 hr = WsFillReader( reader, sizeof(data4) - 1, NULL, NULL );
799 ok( hr == S_OK, "got %#lx\n", hr );
801 found = -1;
802 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
803 ok( hr == S_OK, "got %#lx\n", hr );
804 ok( found == TRUE, "got %d\n", found );
805 WsFreeReader( reader );
808 static void test_WsReadStartElement(void)
810 HRESULT hr;
811 WS_XML_READER *reader;
812 const WS_XML_NODE *node, *node2;
813 int found;
815 hr = WsCreateReader( NULL, 0, &reader, NULL );
816 ok( hr == S_OK, "got %#lx\n", hr );
818 hr = set_input( reader, data2, sizeof(data2) - 1 );
819 ok( hr == S_OK, "got %#lx\n", hr );
821 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
822 ok( hr == S_OK, "got %#lx\n", hr );
824 found = -1;
825 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
826 ok( hr == S_OK, "got %#lx\n", hr );
827 ok( found == TRUE, "got %d\n", found );
829 hr = WsReadStartElement( NULL, NULL );
830 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
832 hr = WsGetReaderNode( reader, &node, NULL );
833 ok( hr == S_OK, "got %#lx\n", hr );
834 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
836 hr = WsReadStartElement( reader, NULL );
837 ok( hr == S_OK, "got %#lx\n", hr );
839 hr = WsGetReaderNode( reader, &node, NULL );
840 ok( hr == S_OK, "got %#lx\n", hr );
841 if (node)
843 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
844 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
845 ok( text->text != NULL, "text not set\n" );
846 if (text->text)
848 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
849 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
850 ok( utf8->value.length == 4, "got %lu\n", utf8->value.length );
851 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong data\n" );
855 hr = WsReadStartElement( reader, NULL );
856 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
858 node2 = NULL;
859 hr = WsGetReaderNode( reader, &node2, NULL );
860 ok( hr == S_OK, "got %#lx\n", hr );
861 ok( node2 == node, "different node\n" );
863 hr = set_input( reader, data8, sizeof(data8) - 1 );
864 ok( hr == S_OK, "got %#lx\n", hr );
866 hr = WsFillReader( reader, sizeof(data8) - 1, NULL, NULL );
867 ok( hr == S_OK, "got %#lx\n", hr );
869 found = -1;
870 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
871 ok( hr == S_OK, "got %#lx\n", hr );
872 ok( found == TRUE, "got %d\n", found );
874 hr = WsGetReaderNode( reader, &node, NULL );
875 ok( hr == S_OK, "got %#lx\n", hr );
876 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
878 hr = WsGetReaderNode( reader, &node, NULL );
879 ok( hr == S_OK, "got %#lx\n", hr );
880 if (node)
882 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
883 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
884 ok( !memcmp( elem->localName->bytes, "node1", 5), "wrong name\n" );
887 hr = WsReadStartElement( reader, NULL );
888 ok( hr == S_OK, "got %#lx\n", hr );
890 hr = WsGetReaderNode( reader, &node, NULL );
891 ok( hr == S_OK, "got %#lx\n", hr );
892 if (node)
894 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
895 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
896 ok( !memcmp( elem->localName->bytes, "node2", 5), "wrong name\n" );
899 hr = WsReadNode( reader, NULL );
900 ok( hr == S_OK, "got %#lx\n", hr );
902 hr = WsGetReaderNode( reader, &node, NULL );
903 ok( hr == S_OK, "got %#lx\n", hr );
904 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
906 hr = WsReadNode( reader, NULL );
907 ok( hr == S_OK, "got %#lx\n", hr );
909 hr = WsGetReaderNode( reader, &node, NULL );
910 ok( hr == S_OK, "got %#lx\n", hr );
911 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
913 hr = WsReadEndElement( reader, NULL );
914 ok( hr == S_OK, "got %#lx\n", hr );
916 hr = WsGetReaderNode( reader, &node, NULL );
917 ok( hr == S_OK, "got %#lx\n", hr );
918 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
920 /* WsReadEndElement advances reader to EOF */
921 hr = WsReadEndElement( reader, NULL );
922 ok( hr == S_OK, "got %#lx\n", hr );
924 hr = WsGetReaderNode( reader, &node, NULL );
925 ok( hr == S_OK, "got %#lx\n", hr );
926 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
928 hr = WsReadEndElement( reader, NULL );
929 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
931 hr = set_input( reader, data3, sizeof(data3) - 1 );
932 ok( hr == S_OK, "got %#lx\n", hr );
934 hr = WsReadStartElement( reader, NULL );
935 ok( hr == S_OK, "got %#lx\n", hr );
937 node = NULL;
938 hr = WsGetReaderNode( reader, &node, NULL );
939 ok( hr == S_OK, "got %#lx\n", hr );
940 if (node)
942 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
943 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
944 ok( text->text != NULL, "text not set\n" );
945 if (text->text)
947 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
948 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
949 ok( utf8->value.length == 4, "got %lu\n", utf8->value.length );
950 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong data\n" );
954 hr = set_input( reader, " <text>test</text>", sizeof(" <text>test</text>") - 1 );
955 ok( hr == S_OK, "got %#lx\n", hr );
957 hr = WsReadStartElement( reader, NULL );
958 ok( hr == S_OK, "got %#lx\n", hr );
960 node = NULL;
961 hr = WsGetReaderNode( reader, &node, NULL );
962 ok( hr == S_OK, "got %#lx\n", hr );
963 if (node)
965 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
966 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
967 ok( text->text != NULL, "text not set\n" );
968 if (text->text)
970 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
971 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
972 ok( utf8->value.length == 4, "got %lu\n", utf8->value.length );
973 ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong data\n" );
977 WsFreeReader( reader );
980 static void test_WsReadEndElement(void)
982 HRESULT hr;
983 WS_XML_READER *reader;
984 const WS_XML_NODE *node;
985 int found;
987 hr = WsCreateReader( NULL, 0, &reader, NULL );
988 ok( hr == S_OK, "got %#lx\n", hr );
990 hr = set_input( reader, data2, sizeof(data2) - 1 );
991 ok( hr == S_OK, "got %#lx\n", hr );
993 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
994 ok( hr == S_OK, "got %#lx\n", hr );
996 hr = WsReadEndElement( reader, NULL );
997 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
999 hr = set_input( reader, data2, sizeof(data2) - 1 );
1000 ok( hr == S_OK, "got %#lx\n", hr );
1002 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
1003 ok( hr == S_OK, "got %#lx\n", hr );
1005 hr = WsReadNode( reader, NULL );
1006 ok( hr == S_OK, "got %#lx\n", hr );
1008 hr = WsGetReaderNode( reader, &node, NULL );
1009 ok( hr == S_OK, "got %#lx\n", hr );
1010 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1012 hr = WsReadNode( reader, NULL );
1013 ok( hr == S_OK, "got %#lx\n", hr );
1015 hr = WsGetReaderNode( reader, &node, NULL );
1016 ok( hr == S_OK, "got %#lx\n", hr );
1017 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
1019 hr = WsReadNode( reader, NULL );
1020 ok( hr == S_OK, "got %#lx\n", hr );
1022 hr = WsGetReaderNode( reader, &node, NULL );
1023 ok( hr == S_OK, "got %#lx\n", hr );
1024 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1026 hr = WsReadNode( reader, NULL );
1027 ok( hr == S_OK, "got %#lx\n", hr );
1029 hr = WsGetReaderNode( reader, &node, NULL );
1030 ok( hr == S_OK, "got %#lx\n", hr );
1031 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1033 hr = set_input( reader, data2, sizeof(data2) - 1 );
1034 ok( hr == S_OK, "got %#lx\n", hr );
1036 hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
1037 ok( hr == S_OK, "got %#lx\n", hr );
1039 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1040 ok( hr == S_OK, "got %#lx\n", hr );
1042 hr = WsReadStartElement( reader, NULL );
1043 ok( hr == S_OK, "got %#lx\n", hr );
1045 hr = WsGetReaderNode( reader, &node, NULL );
1046 ok( hr == S_OK, "got %#lx\n", hr );
1047 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
1049 hr = WsReadNode( reader, NULL );
1050 ok( hr == S_OK, "got %#lx\n", hr );
1052 hr = WsGetReaderNode( reader, &node, NULL );
1053 ok( hr == S_OK, "got %#lx\n", hr );
1054 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1056 /* WsReadEndElement advances reader to EOF */
1057 hr = WsReadEndElement( reader, NULL );
1058 ok( hr == S_OK, "got %#lx\n", hr );
1060 hr = WsGetReaderNode( reader, &node, NULL );
1061 ok( hr == S_OK, "got %#lx\n", hr );
1062 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1064 hr = WsReadEndElement( reader, NULL );
1065 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1067 hr = set_input( reader, data5, sizeof(data5) - 1 );
1068 ok( hr == S_OK, "got %#lx\n", hr );
1070 hr = WsFillReader( reader, sizeof(data5) - 1, NULL, NULL );
1071 ok( hr == S_OK, "got %#lx\n", hr );
1073 hr = WsReadEndElement( reader, NULL );
1074 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1076 hr = set_input( reader, data10, sizeof(data10) - 1 );
1077 ok( hr == S_OK, "got %#lx\n", hr );
1079 hr = WsFillReader( reader, sizeof(data10) - 1, NULL, NULL );
1080 ok( hr == S_OK, "got %#lx\n", hr );
1082 hr = WsReadNode( reader, NULL );
1083 ok( hr == S_OK, "got %#lx\n", hr );
1085 hr = WsGetReaderNode( reader, &node, NULL );
1086 ok( hr == S_OK, "got %#lx\n", hr );
1087 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1089 hr = WsReadEndElement( reader, NULL );
1090 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1092 hr = set_input( reader, "<a></A>", sizeof("<a></A>") - 1 );
1093 ok( hr == S_OK, "got %#lx\n", hr );
1095 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1096 ok( hr == S_OK, "got %#lx\n", hr );
1098 found = -1;
1099 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1100 ok( hr == S_OK, "got %#lx\n", hr );
1101 ok( found == TRUE, "got %d\n", found );
1103 hr = WsGetReaderNode( reader, &node, NULL );
1104 ok( hr == S_OK, "got %#lx\n", hr );
1105 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1107 hr = WsReadEndElement( reader, NULL );
1108 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1110 hr = set_input( reader, "<a></a>", sizeof("<a></a>") - 1 );
1111 ok( hr == S_OK, "got %#lx\n", hr );
1113 hr = WsFillReader( reader, sizeof("<a></a>") - 1, NULL, NULL );
1114 ok( hr == S_OK, "got %#lx\n", hr );
1116 found = -1;
1117 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1118 ok( hr == S_OK, "got %#lx\n", hr );
1119 ok( found == TRUE, "got %d\n", found );
1121 hr = WsGetReaderNode( reader, &node, NULL );
1122 ok( hr == S_OK, "got %#lx\n", hr );
1123 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1125 hr = WsReadStartElement( reader, NULL );
1126 ok( hr == S_OK, "got %#lx\n", hr );
1128 hr = WsGetReaderNode( reader, &node, NULL );
1129 ok( hr == S_OK, "got %#lx\n", hr );
1130 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1132 hr = WsReadEndElement( reader, NULL );
1133 ok( hr == S_OK, "got %#lx\n", hr );
1135 hr = WsGetReaderNode( reader, &node, NULL );
1136 ok( hr == S_OK, "got %#lx\n", hr );
1137 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
1139 hr = set_input( reader, "<a/>", sizeof("<a/>") - 1 );
1140 ok( hr == S_OK, "got %#lx\n", hr );
1142 hr = WsFillReader( reader, sizeof("<a/>") - 1, NULL, NULL );
1143 ok( hr == S_OK, "got %#lx\n", hr );
1145 found = -1;
1146 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1147 ok( hr == S_OK, "got %#lx\n", hr );
1148 ok( found == TRUE, "got %d\n", found );
1150 hr = WsGetReaderNode( reader, &node, NULL );
1151 ok( hr == S_OK, "got %#lx\n", hr );
1152 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
1154 hr = WsReadStartElement( reader, NULL );
1155 ok( hr == S_OK, "got %#lx\n", hr );
1157 hr = WsGetReaderNode( reader, &node, NULL );
1158 ok( hr == S_OK, "got %#lx\n", hr );
1159 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
1161 hr = WsReadEndElement( reader, NULL );
1162 ok( hr == S_OK, "got %#lx\n", hr );
1164 WsFreeReader( reader );
1167 static void test_WsReadNode(void)
1169 static const char str1[] = "<a>";
1170 static const char str2[] = "< a>";
1171 static const char str3[] = "<a >";
1172 static const char str4[] = "<<a>>";
1173 static const char str5[] = "<>";
1174 static const char str6[] = "</a>";
1175 static const char str7[] = " <a>";
1176 static const char str8[] = "<?xml>";
1177 static const char str9[] = "<?xml?>";
1178 static const char str10[] = "<?xml ?>";
1179 static const char str11[] = "<?xml version=\"1.0\"?>";
1180 static const char str12[] = "<text>test</text>";
1181 static const char str13[] = "<?xml version=\"1.0\"?><text>test</text>";
1182 static const char str14[] = "";
1183 static const char str15[] = "<!--";
1184 static const char str16[] = "<!---->";
1185 static const char str17[] = "<!--comment-->";
1186 HRESULT hr;
1187 WS_XML_READER *reader;
1188 WS_XML_DICTIONARY *dict;
1189 const WS_XML_NODE *node;
1190 unsigned int i;
1191 int found;
1192 static const struct
1194 const char *text;
1195 HRESULT hr;
1196 WS_XML_NODE_TYPE type;
1197 int todo;
1199 tests[] =
1201 { str1, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1202 { str2, WS_E_INVALID_FORMAT, 0 },
1203 { str3, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1204 { str4, WS_E_INVALID_FORMAT, 0 },
1205 { str5, WS_E_INVALID_FORMAT, 0 },
1206 { str6, WS_E_INVALID_FORMAT, 0 },
1207 { str7, S_OK, WS_XML_NODE_TYPE_TEXT },
1208 { str8, WS_E_INVALID_FORMAT, 0 },
1209 { str9, WS_E_INVALID_FORMAT, 0 },
1210 { str10, WS_E_INVALID_FORMAT, 0, 1 },
1211 { str11, S_OK, WS_XML_NODE_TYPE_EOF },
1212 { str12, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1213 { str13, S_OK, WS_XML_NODE_TYPE_ELEMENT },
1214 { str14, WS_E_INVALID_FORMAT, 0, 1 },
1215 { str15, WS_E_INVALID_FORMAT, 0 },
1216 { str16, S_OK, WS_XML_NODE_TYPE_COMMENT },
1217 { str17, S_OK, WS_XML_NODE_TYPE_COMMENT },
1220 hr = WsCreateReader( NULL, 0, &reader, NULL );
1221 ok( hr == S_OK, "got %#lx\n", hr );
1223 for (i = 0; i < ARRAY_SIZE( tests ); i++)
1225 hr = set_input( reader, tests[i].text, strlen(tests[i].text) );
1226 ok( hr == S_OK, "got %#lx\n", hr );
1228 hr = WsFillReader( reader, strlen(tests[i].text), NULL, NULL );
1229 ok( hr == S_OK, "%u: got %#lx\n", i, hr );
1231 hr = WsReadNode( reader, NULL );
1232 todo_wine_if (tests[i].todo)
1233 ok( hr == tests[i].hr, "%u: got %#lx\n", i, hr );
1234 if (hr == S_OK)
1236 node = NULL;
1237 hr = WsGetReaderNode( reader, &node, NULL );
1238 ok( hr == S_OK, "%u: got %#lx\n", i, hr );
1239 ok( node != NULL, "%u: node not set\n", i );
1240 if (node)
1242 todo_wine_if (tests[i].todo)
1243 ok( node->nodeType == tests[i].type, "%u: got %u\n", i, node->nodeType );
1248 hr = set_input( reader, data6, sizeof(data6) - 1 );
1249 ok( hr == S_OK, "got %#lx\n", hr );
1251 hr = WsFillReader( reader, sizeof(data6) - 1, NULL, NULL );
1252 ok( hr == S_OK, "got %#lx\n", hr );
1254 found = -1;
1255 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
1256 ok( hr == S_OK, "got %#lx\n", hr );
1257 ok( found == TRUE, "got %d\n", found );
1259 hr = WsGetReaderNode( reader, &node, NULL );
1260 ok( hr == S_OK, "got %#lx\n", hr );
1261 if (node)
1263 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
1264 WS_XML_ATTRIBUTE *attr;
1265 WS_XML_UTF8_TEXT *text;
1267 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
1268 ok( elem->prefix != NULL, "prefix not set\n" );
1269 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
1270 ok( elem->prefix->bytes == NULL, "bytes set\n" );
1271 ok( elem->localName != NULL, "localName not set\n" );
1272 ok( elem->localName->length == 4, "got %lu\n", elem->localName->length );
1273 ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
1274 ok( elem->ns != NULL, "ns not set\n" );
1275 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
1276 ok( elem->ns->bytes != NULL, "bytes not set\n" );
1277 ok( elem->attributeCount == 2, "got %lu\n", elem->attributeCount );
1278 ok( elem->attributes != NULL, "attributes not set\n" );
1279 ok( !elem->isEmpty, "isEmpty not zero\n" );
1281 attr = elem->attributes[0];
1282 ok( !attr->singleQuote, "got %u\n", attr->singleQuote );
1283 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1284 ok( attr->prefix != NULL, "prefix not set\n" );
1285 ok( !attr->prefix->length, "got %lu\n", attr->prefix->length );
1286 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1287 ok( attr->localName != NULL, "localName not set\n" );
1288 ok( attr->localName->length == 4, "got %lu\n", attr->localName->length );
1289 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
1290 ok( attr->ns != NULL, "ns not set\n" );
1291 ok( !attr->ns->length, "got %lu\n", attr->ns->length );
1292 ok( attr->ns->bytes == NULL, "bytes set\n" );
1293 ok( attr->value != NULL, "value not set\n" );
1295 text = (WS_XML_UTF8_TEXT *)attr->value;
1296 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1297 ok( text->value.length == 5, "got %lu\n", text->value.length );
1298 ok( !memcmp( text->value.bytes, "value", 5 ), "wrong data\n" );
1300 attr = elem->attributes[1];
1301 ok( attr->singleQuote == 1, "got %u\n", attr->singleQuote );
1302 ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
1303 ok( attr->prefix != NULL, "prefix not set\n" );
1304 ok( !attr->prefix->length, "got %lu\n", attr->prefix->length );
1305 ok( attr->prefix->bytes == NULL, "bytes set\n" );
1306 ok( attr->localName != NULL, "localName not set\n" );
1307 ok( attr->localName->length == 5, "got %lu\n", attr->localName->length );
1308 ok( !memcmp( attr->localName->bytes, "attr2", 5 ), "wrong data\n" );
1309 ok( attr->ns != NULL, "ns not set\n" );
1310 ok( !attr->ns->length, "got %lu\n", attr->ns->length );
1311 ok( attr->ns->bytes == NULL, "bytes set\n" );
1312 ok( attr->value != NULL, "value not set\n" );
1314 text = (WS_XML_UTF8_TEXT *)attr->value;
1315 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
1316 ok( text->value.length == 6, "got %lu\n", text->value.length );
1317 ok( !memcmp( text->value.bytes, "value2", 6 ), "wrong data\n" );
1320 hr = set_input( reader, data7, sizeof(data7) - 1 );
1321 ok( hr == S_OK, "got %#lx\n", hr );
1323 hr = WsFillReader( reader, sizeof(data7) - 1, NULL, NULL );
1324 ok( hr == S_OK, "got %#lx\n", hr );
1326 hr = WsReadNode( reader, NULL );
1327 ok( hr == S_OK, "got %#lx\n", hr );
1329 hr = WsGetReaderNode( reader, &node, NULL );
1330 ok( hr == S_OK, "got %#lx\n", hr );
1331 if (node)
1333 WS_XML_COMMENT_NODE *comment = (WS_XML_COMMENT_NODE *)node;
1335 ok( comment->node.nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", comment->node.nodeType );
1336 ok( comment->value.length == 9, "got %lu\n", comment->value.length );
1337 ok( !memcmp( comment->value.bytes, " comment ", 9 ), "wrong data\n" );
1340 dict = (WS_XML_DICTIONARY *)0xdeadbeef;
1341 hr = WsGetDictionary( WS_ENCODING_XML_UTF8, &dict, NULL );
1342 ok( hr == S_OK, "got %#lx\n", hr );
1343 ok( dict == NULL, "got %p\n", dict );
1345 dict = NULL;
1346 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_1, &dict, NULL );
1347 ok( hr == S_OK, "got %#lx\n", hr );
1348 ok( dict != NULL, "dict not set\n" );
1350 dict = NULL;
1351 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_SESSION_1, &dict, NULL );
1352 ok( hr == S_OK, "got %#lx\n", hr );
1353 ok( dict != NULL, "dict not set\n" );
1355 WsFreeReader( reader );
1358 static HRESULT set_output( WS_XML_WRITER *writer )
1360 WS_XML_WRITER_TEXT_ENCODING text = {{WS_XML_WRITER_ENCODING_TYPE_TEXT}, WS_CHARSET_UTF8};
1361 WS_XML_WRITER_BUFFER_OUTPUT buf = {{WS_XML_WRITER_OUTPUT_TYPE_BUFFER}};
1362 return WsSetOutput( writer, &text.encoding, &buf.output, NULL, 0, NULL );
1365 static void check_output_buffer( WS_XML_BUFFER *buffer, const char *expected, unsigned int line )
1367 WS_XML_WRITER *writer;
1368 WS_BYTES bytes;
1369 ULONG size = sizeof(bytes);
1370 int len = strlen(expected);
1371 HRESULT hr;
1373 hr = WsCreateWriter( NULL, 0, &writer, NULL );
1374 ok( hr == S_OK, "got %#lx\n", hr );
1376 hr = set_output( writer );
1377 ok( hr == S_OK, "got %#lx\n", hr );
1379 hr = WsWriteXmlBuffer( writer, buffer, NULL );
1380 ok( hr == S_OK, "got %#lx\n", hr );
1382 memset( &bytes, 0, sizeof(bytes) );
1383 hr = WsGetWriterProperty( writer, WS_XML_WRITER_PROPERTY_BYTES, &bytes, size, NULL );
1384 ok( hr == S_OK, "%u: got %#lx\n", line, hr );
1385 ok( bytes.length == len, "%u: got %lu expected %d\n", line, bytes.length, len );
1386 if (bytes.length != len) return;
1387 ok( !memcmp( bytes.bytes, expected, len ), "%u: got %s expected %s\n", line, bytes.bytes, expected );
1389 WsFreeWriter( writer );
1392 static void prepare_type_test( WS_XML_READER *reader, const char *data, ULONG size )
1394 HRESULT hr;
1396 hr = set_input( reader, data, size );
1397 ok( hr == S_OK, "got %#lx\n", hr );
1399 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1400 ok( hr == S_OK, "got %#lx\n", hr );
1402 hr = WsReadStartElement( reader, NULL );
1403 ok( hr == S_OK, "got %#lx\n", hr );
1406 static void test_WsReadType(void)
1408 static const GUID guid = {0,0,0,{0,0,0,0,0,0,0,0xa1}};
1409 static const char utf8[] = {'<','t','>',0xe2,0x80,0x99,'<','/','t','>'};
1410 static const char faultxml[] =
1411 "<s:Body xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Fault>"
1412 "<faultcode>s:Client</faultcode><faultstring>Example Fault</faultstring>"
1413 "<faultactor>http://example.com/fault</faultactor>"
1414 "<detail><ErrorCode>1030</ErrorCode></detail></s:Fault></s:Body>";
1415 static const char faultcode[] = "Client";
1416 static const WCHAR faultstring[] = L"Example Fault";
1417 static const WCHAR faultactor[] = L"http://example.com/fault";
1418 static const char faultdetail[] = "<detail><ErrorCode>1030</ErrorCode></detail>";
1419 HRESULT hr;
1420 WS_XML_READER *reader;
1421 WS_HEAP *heap;
1422 enum { ONE = 1, TWO = 2 };
1423 WS_XML_STRING one = { 3, (BYTE *)"ONE" }, two = { 3, (BYTE *)"TWO" }, val_xmlstr, *ptr_xmlstr;
1424 WS_ENUM_VALUE enum_values[] = { { ONE, &one }, { TWO, &two } };
1425 WS_ENUM_DESCRIPTION enum_desc;
1426 int val_enum, *ptr_enum;
1427 WCHAR *val_str;
1428 BOOL val_bool, *ptr_bool;
1429 INT8 val_int8, *ptr_int8;
1430 INT16 val_int16, *ptr_int16;
1431 INT32 val_int32, *ptr_int32;
1432 INT64 val_int64, *ptr_int64;
1433 UINT8 val_uint8, *ptr_uint8;
1434 UINT16 val_uint16, *ptr_uint16;
1435 UINT32 val_uint32, *ptr_uint32;
1436 UINT64 val_uint64, *ptr_uint64;
1437 GUID val_guid, *ptr_guid;
1438 WS_BYTES val_bytes, *ptr_bytes;
1439 WS_STRING val_string, *ptr_string;
1440 WS_UNIQUE_ID val_id, *ptr_id;
1441 WS_XML_QNAME val_qname, *ptr_qname;
1442 WS_FAULT_DESCRIPTION fault_desc;
1443 WS_FAULT fault;
1445 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
1446 ok( hr == S_OK, "got %#lx\n", hr );
1448 hr = WsCreateReader( NULL, 0, &reader, NULL );
1449 ok( hr == S_OK, "got %#lx\n", hr );
1451 prepare_type_test( reader, data2, sizeof(data2) - 1 );
1452 hr = WsReadType( NULL, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1453 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1454 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
1456 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1457 WS_READ_REQUIRED_POINTER, heap, &val_str, 0, NULL );
1458 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
1460 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1461 WS_READ_REQUIRED_POINTER, heap, NULL, sizeof(val_str), NULL );
1462 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
1464 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1465 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str) + 1, NULL );
1466 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
1468 val_str = NULL;
1469 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1470 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1471 ok( hr == S_OK, "got %#lx\n", hr );
1472 ok( val_str != NULL, "pointer not set\n" );
1473 if (val_str) ok( !wcscmp( val_str, L"test" ), "wrong data\n" );
1475 val_bool = -1;
1476 prepare_type_test( reader, "<t>true</t>", sizeof("<t>true</t>") - 1 );
1477 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1478 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1479 ok( hr == S_OK, "got %#lx\n", hr );
1480 ok( val_bool == TRUE, "got %d\n", val_bool );
1482 val_bool = -1;
1483 prepare_type_test( reader, "<t>false</t>", sizeof("<t>false</t>") - 1 );
1484 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1485 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL );
1486 ok( hr == S_OK, "got %#lx\n", hr );
1487 ok( val_bool == FALSE, "got %d\n", val_bool );
1489 val_bool = -1;
1490 prepare_type_test( reader, "<t>FALSE</t>", sizeof("<t>FALSE</t>") - 1 );
1491 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1492 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1493 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1494 ok( val_bool == -1, "got %d\n", val_bool );
1496 val_bool = -1;
1497 prepare_type_test( reader, "<t>1</t>", sizeof("<t>1</t>") - 1 );
1498 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1499 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1500 ok( hr == S_OK, "got %#lx\n", hr );
1501 ok( val_bool == TRUE, "got %d\n", val_bool );
1503 val_bool = -1;
1504 prepare_type_test( reader, "<t>2</t>", sizeof("<t>2</t>") - 1 );
1505 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1506 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1507 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1508 ok( val_bool == -1, "got %d\n", val_bool );
1510 val_bool = -1;
1511 prepare_type_test( reader, "<t>0</t>", sizeof("<t>0</t>") - 1 );
1512 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1513 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1514 ok( hr == S_OK, "got %#lx\n", hr );
1515 ok( val_bool == FALSE, "got %d\n", val_bool );
1517 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1518 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1519 WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL );
1520 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1522 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1523 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL,
1524 WS_READ_REQUIRED_POINTER, heap, &ptr_bool, sizeof(ptr_bool), NULL );
1525 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1527 val_int8 = 0;
1528 prepare_type_test( reader, "<t>-128</t>", sizeof("<t>-128</t>") - 1 );
1529 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1530 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1531 ok( hr == S_OK, "got %#lx\n", hr );
1532 ok( val_int8 == -128, "got %d\n", val_int8 );
1534 prepare_type_test( reader, "<t> </t>", sizeof("<t> </t>") - 1 );
1535 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1536 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1537 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1539 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1540 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1541 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1542 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1544 prepare_type_test( reader, "<t>-</t>", sizeof("<t>-</t>") - 1 );
1545 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1546 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1547 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1549 val_int8 = -1;
1550 prepare_type_test( reader, "<t>-0</t>", sizeof("<t>-0</t>") - 1 );
1551 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1552 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1553 ok( hr == S_OK, "got %#lx\n", hr );
1554 ok( !val_int8, "got %d\n", val_int8 );
1556 prepare_type_test( reader, "<t>-129</t>", sizeof("<t>-129</t>") - 1 );
1557 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1558 WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL );
1559 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %#lx\n", hr );
1561 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1562 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL,
1563 WS_READ_REQUIRED_POINTER, heap, &ptr_int8, sizeof(ptr_int8), NULL );
1564 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1566 val_int16 = 0;
1567 prepare_type_test( reader, "<t>-32768</t>", sizeof("<t>-32768</t>") - 1 );
1568 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1569 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1570 ok( hr == S_OK, "got %#lx\n", hr );
1571 ok( val_int16 == -32768, "got %d\n", val_int16 );
1573 prepare_type_test( reader, "<t>-32769</t>", sizeof("<t>-32769</t>") - 1 );
1574 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1575 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1576 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %#lx\n", hr );
1578 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1579 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1580 WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL );
1581 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1583 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1584 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL,
1585 WS_READ_REQUIRED_POINTER, heap, &ptr_int16, sizeof(ptr_int16), NULL );
1586 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1588 val_int32 = 0;
1589 prepare_type_test( reader, "<t>-2147483648</t>", sizeof("<t>-2147483648</t>") - 1 );
1590 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1591 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1592 ok( hr == S_OK, "got %#lx\n", hr );
1593 ok( val_int32 == -2147483647 - 1, "got %d\n", val_int32 );
1595 prepare_type_test( reader, "<t>-2147483649</t>", sizeof("<t>-2147483649</t>") - 1 );
1596 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1597 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1598 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1600 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1601 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1602 WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL );
1603 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1605 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1606 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL,
1607 WS_READ_REQUIRED_POINTER, heap, &ptr_int32, sizeof(ptr_int32), NULL );
1608 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1610 val_int64 = 0;
1611 prepare_type_test( reader, "<t>-9223372036854775808</t>", sizeof("<t>-9223372036854775808</t>") - 1 );
1612 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1613 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1614 ok( hr == S_OK, "got %#lx\n", hr );
1615 ok( val_int64 == -9223372036854775807 - 1, "wrong value\n" );
1617 prepare_type_test( reader, "<t>-9223372036854775809</t>", sizeof("<t>-9223372036854775809</t>") - 1 );
1618 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1619 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1620 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1622 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1623 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1624 WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL );
1625 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1627 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1628 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL,
1629 WS_READ_REQUIRED_POINTER, heap, &ptr_int64, sizeof(ptr_int64), NULL );
1630 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1632 val_uint8 = 0;
1633 prepare_type_test( reader, "<t> 255 </t>", sizeof("<t> 255 </t>") - 1 );
1634 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1635 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1636 ok( hr == S_OK, "got %#lx\n", hr );
1637 ok( val_uint8 == 255, "got %u\n", val_uint8 );
1639 prepare_type_test( reader, "<t>+255</t>", sizeof("<t>+255</t>") - 1 );
1640 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1641 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1642 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1644 prepare_type_test( reader, "<t>-255</t>", sizeof("<t>-255</t>") - 1 );
1645 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1646 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1647 todo_wine ok( hr == WS_E_NUMERIC_OVERFLOW, "got %#lx\n", hr );
1649 prepare_type_test( reader, "<t>0xff</t>", sizeof("<t>0xff</t>") - 1 );
1650 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1651 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1652 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1654 prepare_type_test( reader, "<t>256</t>", sizeof("<t>256</t>") - 1 );
1655 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1656 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1657 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %#lx\n", hr );
1659 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1660 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1661 WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL );
1662 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1664 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1665 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL,
1666 WS_READ_REQUIRED_POINTER, heap, &ptr_uint8, sizeof(ptr_uint8), NULL );
1667 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1669 val_uint16 = 0;
1670 prepare_type_test( reader, "<t>65535</t>", sizeof("<t>65535</t>") - 1 );
1671 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1672 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1673 ok( hr == S_OK, "got %#lx\n", hr );
1674 ok( val_uint16 == 65535, "got %u\n", val_uint16 );
1676 prepare_type_test( reader, "<t>65536</t>", sizeof("<t>65536</t>") - 1 );
1677 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1678 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1679 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %#lx\n", hr );
1681 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1682 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1683 WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL );
1684 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1686 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1687 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL,
1688 WS_READ_REQUIRED_POINTER, heap, &ptr_uint16, sizeof(ptr_uint16), NULL );
1689 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1691 val_uint32 = 0;
1692 prepare_type_test( reader, "<t>4294967295</t>", sizeof("<t>4294967295</t>") - 1 );
1693 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1694 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1695 ok( hr == S_OK, "got %#lx\n", hr );
1696 ok( val_uint32 == ~0, "got %u\n", val_uint32 );
1698 prepare_type_test( reader, "<t>4294967296</t>", sizeof("<t>4294967296</t>") - 1 );
1699 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1700 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1701 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %#lx\n", hr );
1703 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1704 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1705 WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL );
1706 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1708 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1709 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL,
1710 WS_READ_REQUIRED_POINTER, heap, &ptr_uint32, sizeof(ptr_uint32), NULL );
1711 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1713 val_uint64 = 0;
1714 prepare_type_test( reader, "<t>18446744073709551615</t>", sizeof("<t>18446744073709551615</t>") - 1 );
1715 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1716 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1717 ok( hr == S_OK, "got %#lx\n", hr );
1718 ok( val_uint64 == ~0, "wrong value\n" );
1720 prepare_type_test( reader, "<t>18446744073709551616</t>", sizeof("<t>18446744073709551616</t>") - 1 );
1721 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1722 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1723 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1725 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1726 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1727 WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL );
1728 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1730 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1731 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL,
1732 WS_READ_REQUIRED_POINTER, heap, &ptr_uint64, sizeof(ptr_uint64), NULL );
1733 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1735 enum_desc.values = enum_values;
1736 enum_desc.valueCount = ARRAY_SIZE( enum_values );
1737 enum_desc.maxByteCount = 3;
1738 enum_desc.nameIndices = NULL;
1740 val_enum = 0;
1741 prepare_type_test( reader, "<t>ONE</t>", sizeof("<t>ONE</t>") - 1 );
1742 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1743 WS_READ_REQUIRED_VALUE, heap, &val_enum, sizeof(val_enum), NULL );
1744 ok( hr == S_OK, "got %#lx\n", hr );
1745 ok( val_enum == 1, "got %d\n", val_enum );
1747 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1748 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1749 WS_READ_REQUIRED_VALUE, heap, &val_enum, sizeof(val_enum), NULL );
1750 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1752 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1753 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_ENUM_TYPE, &enum_desc,
1754 WS_READ_REQUIRED_POINTER, heap, &ptr_enum, sizeof(ptr_enum), NULL );
1755 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1757 prepare_type_test( reader, "<t>{00000000-0000-0000-0000-000000000000}</t>",
1758 sizeof("<t>{00000000-0000-0000-0000-000000000000}</t>") - 1 );
1759 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1760 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1761 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1763 memset( &val_guid, 0xff, sizeof(val_guid) );
1764 prepare_type_test( reader, "<t> 00000000-0000-0000-0000-000000000000 </t>",
1765 sizeof("<t> 00000000-0000-0000-0000-000000000000 </t>") - 1 );
1766 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1767 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1768 ok( hr == S_OK, "got %#lx\n", hr );
1769 ok( IsEqualGUID( &val_guid, &guid_null ), "wrong guid\n" );
1771 memset( &val_guid, 0, sizeof(val_guid) );
1772 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000a1</t>",
1773 sizeof("<t>00000000-0000-0000-0000-0000000000a1</t>") - 1 );
1774 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1775 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1776 ok( hr == S_OK, "got %#lx\n", hr );
1777 ok( IsEqualGUID( &val_guid, &guid ), "wrong guid\n" );
1779 memset( &val_guid, 0, sizeof(val_guid) );
1780 prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000A1</t>",
1781 sizeof("<t>00000000-0000-0000-0000-0000000000A1</t>") - 1 );
1782 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1783 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1784 ok( hr == S_OK, "got %#lx\n", hr );
1785 ok( IsEqualGUID( &val_guid, &guid ), "wrong guid\n" );
1787 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1788 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1789 WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
1790 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1792 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1793 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
1794 WS_READ_REQUIRED_POINTER, heap, &ptr_guid, sizeof(ptr_guid), NULL );
1795 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1797 memset( &val_bytes, 0, sizeof(val_bytes) );
1798 prepare_type_test( reader, "<t>dGVzdA==</t>", sizeof("<t>dGVzdA==</t>") - 1 );
1799 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1800 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1801 ok( hr == S_OK, "got %#lx\n", hr );
1802 ok( val_bytes.length == 4, "got %lu\n", val_bytes.length );
1803 ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" );
1805 memset( &val_bytes, 0, sizeof(val_bytes) );
1806 prepare_type_test( reader, "<t> dGVzdA== </t>", sizeof("<t> dGVzdA== </t>") - 1 );
1807 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1808 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1809 ok( hr == S_OK, "got %#lx\n", hr );
1810 ok( val_bytes.length == 4, "got %lu\n", val_bytes.length );
1811 ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" );
1813 prepare_type_test( reader, "<t>dGVzdA===</t>", sizeof("<t>dGVzdA===</t>") - 1 );
1814 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1815 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1816 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1818 val_bytes.length = 0xdeadbeef;
1819 val_bytes.bytes = (BYTE *)0xdeadbeef;
1820 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1821 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1822 WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL );
1823 ok( hr == S_OK, "got %#lx\n", hr );
1824 ok( !val_bytes.length, "got %lu\n", val_bytes.length );
1825 todo_wine ok( val_bytes.bytes != NULL, "got %p\n", val_bytes.bytes );
1827 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1828 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL,
1829 WS_READ_REQUIRED_POINTER, heap, &ptr_bytes, sizeof(ptr_bytes), NULL );
1830 ok( hr == S_OK, "got %#lx\n", hr );
1831 ok( !ptr_bytes->length, "got %lu\n", ptr_bytes->length );
1832 todo_wine ok( ptr_bytes->bytes != NULL, "got %p\n", ptr_bytes->bytes );
1834 val_str = NULL;
1835 prepare_type_test( reader, utf8, sizeof(utf8) );
1836 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1837 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1838 ok( hr == S_OK, "got %#lx\n", hr );
1839 ok( val_str != NULL, "pointer not set\n" );
1840 ok( !lstrcmpW( val_str, L"\x2019" ), "got %s\n", wine_dbgstr_w(val_str) );
1842 val_str = NULL;
1843 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1844 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL,
1845 WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL );
1846 ok( hr == S_OK, "got %#lx\n", hr );
1847 ok( val_str != NULL, "got %p\n", val_str );
1848 ok( !val_str[0], "got %s\n", wine_dbgstr_w(val_str) );
1850 memset( &val_xmlstr, 0, sizeof(val_xmlstr) );
1851 prepare_type_test( reader, "<t> test </t>", sizeof("<t> test </t>") - 1 );
1852 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_XML_STRING_TYPE, NULL,
1853 WS_READ_REQUIRED_VALUE, heap, &val_xmlstr, sizeof(val_xmlstr), NULL );
1854 ok( hr == S_OK, "got %#lx\n", hr );
1855 ok( val_xmlstr.length == 6, "got %lu\n", val_xmlstr.length );
1856 ok( !memcmp( val_xmlstr.bytes, " test ", 6 ), "wrong data\n" );
1858 val_xmlstr.length = 0xdeadbeef;
1859 val_xmlstr.bytes = (BYTE *)0xdeadbeef;
1860 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1861 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_XML_STRING_TYPE, NULL,
1862 WS_READ_REQUIRED_VALUE, heap, &val_xmlstr, sizeof(val_xmlstr), NULL );
1863 ok( hr == S_OK, "got %#lx\n", hr );
1864 ok( !val_xmlstr.length, "got %lu\n", val_bytes.length );
1865 todo_wine ok( val_xmlstr.bytes != NULL, "got %p\n", val_bytes.bytes );
1867 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_XML_STRING_TYPE, NULL,
1868 WS_READ_REQUIRED_POINTER, heap, &ptr_xmlstr, sizeof(ptr_xmlstr), NULL );
1869 ok( hr == S_OK, "got %#lx\n", hr );
1870 ok( !ptr_xmlstr->length, "got %lu\n", ptr_bytes->length );
1871 todo_wine ok( ptr_xmlstr->bytes != NULL, "got %p\n", ptr_bytes->bytes );
1873 memset( &val_string, 0, sizeof(val_string) );
1874 prepare_type_test( reader, "<t> test </t>", sizeof("<t> test </t>") - 1 );
1875 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRING_TYPE, NULL,
1876 WS_READ_REQUIRED_VALUE, heap, &val_string, sizeof(val_string), NULL );
1877 ok( hr == S_OK, "got %#lx\n", hr );
1878 ok( val_string.length == 6, "got %lu\n", val_string.length );
1879 ok( !memcmp( val_string.chars, L" test ", 12 ), "wrong data\n" );
1881 val_string.length = 0xdeadbeef;
1882 val_string.chars = (WCHAR *)0xdeadbeef;
1883 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1884 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRING_TYPE, NULL,
1885 WS_READ_REQUIRED_VALUE, heap, &val_string, sizeof(val_string), NULL );
1886 ok( hr == S_OK, "got %#lx\n", hr );
1887 ok( !val_string.length, "got %lu\n", val_string.length );
1888 todo_wine ok( val_string.chars != NULL, "got %p\n", val_string.chars );
1890 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRING_TYPE, NULL,
1891 WS_READ_REQUIRED_POINTER, heap, &ptr_string, sizeof(ptr_string), NULL );
1892 ok( hr == S_OK, "got %#lx\n", hr );
1893 ok( !ptr_string->length, "got %lu\n", ptr_string->length );
1894 todo_wine ok( ptr_string->chars != NULL, "got %p\n", ptr_string->chars );
1896 memset( &val_id, 0, sizeof(val_id) );
1897 val_id.guid.Data1 = 0xdeadbeef;
1898 prepare_type_test( reader, "<t> test </t>", sizeof("<t> test </t>") - 1 );
1899 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL,
1900 WS_READ_REQUIRED_VALUE, heap, &val_id, sizeof(val_id), NULL );
1901 ok( hr == S_OK, "got %#lx\n", hr );
1902 ok( val_id.uri.length == 6, "got %lu\n", val_string.length );
1903 ok( !memcmp( val_id.uri.chars, L" test ", 12 ), "wrong data\n" );
1904 ok( IsEqualGUID( &val_id.guid, &guid_null ), "wrong guid\n" );
1906 memset( &val_id, 0, sizeof(val_id) );
1907 prepare_type_test( reader, "<t>urn:uuid:00000000-0000-0000-0000-0000000000a1</t>",
1908 sizeof("<t>urn:uuid:00000000-0000-0000-0000-0000000000a1</t>") - 1 );
1909 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL,
1910 WS_READ_REQUIRED_VALUE, heap, &val_id, sizeof(val_id), NULL );
1911 ok( hr == S_OK, "got %#lx\n", hr );
1912 ok( !val_id.uri.length, "got %lu\n", val_string.length );
1913 ok( val_id.uri.chars == NULL, "chars set %s\n", wine_dbgstr_wn(val_id.uri.chars, val_id.uri.length) );
1914 ok( IsEqualGUID( &val_id.guid, &guid ), "wrong guid\n" );
1916 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1917 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL,
1918 WS_READ_REQUIRED_VALUE, heap, &val_id, sizeof(val_id), NULL );
1919 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1921 prepare_type_test( reader, "<t></t>", sizeof("<t></t>") - 1 );
1922 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL,
1923 WS_READ_REQUIRED_POINTER, heap, &ptr_id, sizeof(ptr_id), NULL );
1924 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1926 memset( &val_qname, 0, sizeof(val_qname) );
1927 hr = set_input( reader, "<t>u</t>", sizeof("<t>u</t>") - 1 );
1928 ok( hr == S_OK, "got %#lx\n", hr );
1929 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1930 ok( hr == S_OK, "got %#lx\n", hr );
1931 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_XML_QNAME_TYPE, NULL,
1932 WS_READ_REQUIRED_VALUE, heap, &val_qname, sizeof(val_qname), NULL );
1933 ok( hr == S_OK, "got %#lx\n", hr );
1934 ok( val_qname.localName.length == 1, "got %lu\n", val_qname.localName.length );
1935 ok( val_qname.localName.bytes[0] == 'u', "wrong data\n" );
1936 ok( !val_qname.ns.length, "got %lu\n", val_qname.ns.length );
1937 ok( val_qname.ns.bytes != NULL, "bytes not set\n" );
1939 memset( &val_qname, 0, sizeof(val_qname) );
1940 hr = set_input( reader, "<p:t xmlns:p=\"ns\"> p:u </p:t>", sizeof("<p:t xmlns:p=\"ns\"> p:u </p:t>") - 1 );
1941 ok( hr == S_OK, "got %#lx\n", hr );
1942 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1943 ok( hr == S_OK, "got %#lx\n", hr );
1944 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_XML_QNAME_TYPE, NULL,
1945 WS_READ_REQUIRED_VALUE, heap, &val_qname, sizeof(val_qname), NULL );
1946 ok( hr == S_OK, "got %#lx\n", hr );
1947 ok( val_qname.localName.length == 1, "got %lu\n", val_qname.localName.length );
1948 ok( val_qname.localName.bytes[0] == 'u', "wrong data\n" );
1949 ok( val_qname.ns.length == 2, "got %lu\n", val_qname.ns.length );
1950 ok( !memcmp( val_qname.ns.bytes, "ns", 2 ), "wrong data\n" );
1952 hr = set_input( reader, "<t></t>", sizeof("<t></t>") - 1 );
1953 ok( hr == S_OK, "got %#lx\n", hr );
1954 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1955 ok( hr == S_OK, "got %#lx\n", hr );
1956 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_XML_QNAME_TYPE, NULL,
1957 WS_READ_REQUIRED_VALUE, heap, &val_qname, sizeof(val_qname), NULL );
1958 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1960 hr = set_input( reader, "<t></t>", sizeof("<t></t>") - 1 );
1961 ok( hr == S_OK, "got %#lx\n", hr );
1962 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1963 ok( hr == S_OK, "got %#lx\n", hr );
1964 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_XML_QNAME_TYPE, NULL,
1965 WS_READ_REQUIRED_POINTER, heap, &ptr_qname, sizeof(ptr_qname), NULL );
1966 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
1968 prepare_type_test( reader, faultxml, sizeof(faultxml) - 1 );
1969 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
1970 ok( hr == S_OK, "got %#lx\n", hr );
1971 memset( &fault, 0, sizeof(fault) );
1973 fault_desc.envelopeVersion = WS_ENVELOPE_VERSION_SOAP_1_1;
1974 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_FAULT_TYPE, &fault_desc,
1975 WS_READ_REQUIRED_VALUE, heap, &fault, sizeof(fault), NULL );
1976 ok( hr == S_OK, "got %#lx\n", hr );
1977 ok( fault.code->value.localName.length == sizeof(faultcode) - 1, "got %lu\n", fault.code->value.localName.length );
1978 ok( !memcmp( fault.code->value.localName.bytes, faultcode, sizeof(faultcode) - 1 ), "wrong fault code\n" );
1979 ok( !fault.code->subCode, "subcode is not NULL\n" );
1980 ok( fault.reasonCount == 1, "got %lu\n", fault.reasonCount );
1981 ok( fault.reasons[0].text.length == ARRAY_SIZE(faultstring) - 1, "got %lu\n", fault.reasons[0].text.length );
1982 ok( !memcmp( fault.reasons[0].text.chars, faultstring, (ARRAY_SIZE(faultstring) - 1) * sizeof(WCHAR) ),
1983 "wrong fault string\n" );
1984 ok( fault.actor.length == ARRAY_SIZE(faultactor) - 1, "got %lu\n", fault.actor.length );
1985 ok( !memcmp( fault.actor.chars, faultactor, ARRAY_SIZE(faultactor) - 1 ), "wrong fault actor\n" );
1986 ok( !fault.node.length, "fault node not empty\n" );
1987 ok( fault.detail != NULL, "fault detail not set\n" );
1988 check_output_buffer( fault.detail, faultdetail, __LINE__ );
1990 fault_desc.envelopeVersion = WS_ENVELOPE_VERSION_NONE;
1991 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_FAULT_TYPE, &fault_desc,
1992 WS_READ_REQUIRED_VALUE, heap, &fault, sizeof(fault), NULL );
1993 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
1995 WsFreeReader( reader );
1996 WsFreeHeap( heap );
1999 static void test_WsGetXmlAttribute(void)
2001 HRESULT hr;
2002 WS_XML_READER *reader;
2003 WS_XML_STRING xmlstr;
2004 WS_HEAP *heap;
2005 WCHAR *str;
2006 ULONG count;
2007 int found;
2009 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2010 ok( hr == S_OK, "got %#lx\n", hr );
2012 hr = WsCreateReader( NULL, 0, &reader, NULL );
2013 ok( hr == S_OK, "got %#lx\n", hr );
2015 hr = set_input( reader, data9, sizeof(data9) - 1 );
2016 ok( hr == S_OK, "got %#lx\n", hr );
2018 hr = WsFillReader( reader, sizeof(data9) - 1, NULL, NULL );
2019 ok( hr == S_OK, "got %#lx\n", hr );
2021 found = -1;
2022 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
2023 ok( hr == S_OK, "got %#lx\n", hr );
2024 ok( found == TRUE, "got %d\n", found );
2026 xmlstr.bytes = (BYTE *)"attr";
2027 xmlstr.length = sizeof("attr") - 1;
2028 xmlstr.dictionary = NULL;
2029 xmlstr.id = 0;
2030 str = NULL;
2031 count = 0;
2032 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
2033 todo_wine ok( hr == S_OK, "got %#lx\n", hr );
2034 todo_wine ok( str != NULL, "str not set\n" );
2035 todo_wine ok( count == 5, "got %lu\n", count );
2036 /* string is not null-terminated */
2037 if (str) ok( !memcmp( str, L"value", count * sizeof(WCHAR) ), "wrong data\n" );
2039 xmlstr.bytes = (BYTE *)"none";
2040 xmlstr.length = sizeof("none") - 1;
2041 xmlstr.dictionary = NULL;
2042 xmlstr.id = 0;
2043 str = (WCHAR *)0xdeadbeef;
2044 count = 0xdeadbeef;
2045 hr = WsGetXmlAttribute( reader, &xmlstr, heap, &str, &count, NULL );
2046 todo_wine ok( hr == S_FALSE, "got %#lx\n", hr );
2047 todo_wine ok( str == NULL, "str not set\n" );
2048 todo_wine ok( !count, "got %lu\n", count );
2050 WsFreeReader( reader );
2051 WsFreeHeap( heap );
2054 static void test_WsXmlStringEquals(void)
2056 BYTE bom[] = {0xef,0xbb,0xbf};
2057 WS_XML_STRING str1 = {0, NULL}, str2 = {0, NULL};
2058 HRESULT hr;
2060 hr = WsXmlStringEquals( NULL, NULL, NULL );
2061 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
2063 hr = WsXmlStringEquals( &str1, NULL, NULL );
2064 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
2066 hr = WsXmlStringEquals( NULL, &str2, NULL );
2067 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
2069 hr = WsXmlStringEquals( &str1, &str2, NULL );
2070 ok( hr == S_OK, "got %#lx\n", hr );
2072 str1.length = 1;
2073 str1.bytes = (BYTE *)"a";
2074 hr = WsXmlStringEquals( &str1, &str1, NULL );
2075 ok( hr == S_OK, "got %#lx\n", hr );
2077 str2.length = 1;
2078 str2.bytes = (BYTE *)"b";
2079 hr = WsXmlStringEquals( &str1, &str2, NULL );
2080 ok( hr == S_FALSE, "got %#lx\n", hr );
2082 str2.length = 1;
2083 str2.bytes = bom;
2084 hr = WsXmlStringEquals( &str1, &str2, NULL );
2085 ok( hr == S_FALSE, "got %#lx\n", hr );
2087 str1.length = 3;
2088 hr = WsXmlStringEquals( &str1, &str2, NULL );
2089 ok( hr == S_FALSE, "got %#lx\n", hr );
2091 str2.length = 3;
2092 hr = WsXmlStringEquals( &str1, &str2, NULL );
2093 ok( hr == S_FALSE, "got %#lx\n", hr );
2095 str1.length = 3;
2096 str1.bytes = bom;
2097 hr = WsXmlStringEquals( &str1, &str2, NULL );
2098 ok( hr == S_OK, "got %#lx\n", hr );
2101 static void test_WsAlloc(void)
2103 HRESULT hr;
2104 WS_HEAP *heap;
2105 void *ptr;
2106 SIZE_T requested, actual;
2107 ULONG size;
2109 hr = WsCreateHeap( 256, 0, NULL, 0, &heap, NULL );
2110 ok( hr == S_OK, "got %#lx\n", hr );
2112 ptr = (void *)0xdeadbeef;
2113 hr = WsAlloc( NULL, 16, &ptr, NULL );
2114 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
2115 ok( ptr == (void *)0xdeadbeef, "ptr set\n" );
2117 ptr = (void *)0xdeadbeef;
2118 hr = WsAlloc( heap, 512, &ptr, NULL );
2119 ok( hr == WS_E_QUOTA_EXCEEDED, "got %#lx\n", hr );
2120 ok( ptr == (void *)0xdeadbeef, "ptr set\n" );
2122 ptr = NULL;
2123 hr = WsAlloc( heap, 16, &ptr, NULL );
2124 ok( hr == S_OK, "got %#lx\n", hr );
2125 ok( ptr != NULL, "ptr not set\n" );
2127 requested = 0xdeadbeef;
2128 size = sizeof(requested);
2129 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
2130 ok( hr == S_OK, "got %#lx\n", hr );
2131 ok( requested == 16, "got %Iu\n", requested );
2133 actual = 0xdeadbeef;
2134 size = sizeof(actual);
2135 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
2136 ok( hr == S_OK, "got %#lx\n", hr );
2137 todo_wine ok( actual == 128, "got %Iu\n", actual );
2139 WsFreeHeap( heap );
2142 static void test_WsMoveReader(void)
2144 HRESULT hr;
2145 WS_HEAP *heap;
2146 WS_XML_READER *reader;
2147 WS_XML_WRITER *writer;
2148 WS_XML_BUFFER *buffer;
2149 WS_XML_STRING localname = {1, (BYTE *)"a"}, localname2 = {1, (BYTE *)"b"}, ns = {0, NULL};
2150 const WS_XML_NODE *node;
2151 WS_XML_ELEMENT_NODE *elem;
2152 WS_XML_UTF8_TEXT utf8;
2154 hr = WsCreateReader( NULL, 0, &reader, NULL );
2155 ok( hr == S_OK, "got %#lx\n", hr );
2157 hr = WsMoveReader( NULL, WS_MOVE_TO_EOF, NULL, NULL );
2158 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
2160 /* reader must be set to an XML buffer */
2161 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
2162 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
2164 hr = set_input( reader, data8, sizeof(data8) - 1 );
2165 ok( hr == S_OK, "got %#lx\n", hr );
2167 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
2168 todo_wine ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
2169 WsFreeReader( reader );
2171 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2172 ok( hr == S_OK, "got %#lx\n", hr );
2174 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
2175 ok( hr == S_OK, "got %#lx\n", hr );
2177 hr = WsCreateWriter( NULL, 0, &writer, NULL );
2178 ok( hr == S_OK, "got %#lx\n", hr );
2180 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
2181 ok( hr == S_OK, "got %#lx\n", hr );
2183 /* <a><b/></a> */
2184 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
2185 ok( hr == S_OK, "got %#lx\n", hr );
2187 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
2188 ok( hr == S_OK, "got %#lx\n", hr );
2190 hr = WsWriteEndElement( writer, NULL );
2191 ok( hr == S_OK, "got %#lx\n", hr );
2193 hr = WsWriteEndElement( writer, NULL );
2194 ok( hr == S_OK, "got %#lx\n", hr );
2196 hr = WsCreateReader( NULL, 0, &reader, NULL );
2197 ok( hr == S_OK, "got %#lx\n", hr );
2199 hr = WsMoveReader( reader, WS_MOVE_TO_EOF, NULL, NULL );
2200 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
2202 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
2203 ok( hr == S_OK, "got %#lx\n", hr );
2205 /* first element is child node of BOF node */
2206 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
2207 ok( hr == S_OK, "got %#lx\n", hr );
2209 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2210 ok( hr == S_OK, "got %#lx\n", hr );
2212 hr = WsGetReaderNode( reader, &node, NULL );
2213 ok( hr == S_OK, "got %#lx\n", hr );
2214 elem = (WS_XML_ELEMENT_NODE *)node;
2215 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2216 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
2217 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
2219 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2220 ok( hr == S_OK, "got %#lx\n", hr );
2222 hr = WsGetReaderNode( reader, &node, NULL );
2223 ok( hr == S_OK, "got %#lx\n", hr );
2224 elem = (WS_XML_ELEMENT_NODE *)node;
2225 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2226 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
2227 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2229 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2230 ok( hr == S_OK, "got %#lx\n", hr );
2232 hr = WsGetReaderNode( reader, &node, NULL );
2233 ok( hr == S_OK, "got %#lx\n", hr );
2234 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2236 /* EOF node is last child of BOF node */
2237 hr = WsMoveReader( reader, WS_MOVE_TO_BOF, NULL, NULL );
2238 ok( hr == S_OK, "got %#lx\n", hr );
2240 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2241 ok( hr == S_OK, "got %#lx\n", hr );
2243 hr = WsGetReaderNode( reader, &node, NULL );
2244 ok( hr == S_OK, "got %#lx\n", hr );
2245 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2247 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2248 ok( hr == S_OK, "got %#lx\n", hr );
2250 hr = WsGetReaderNode( reader, &node, NULL );
2251 ok( hr == S_OK, "got %#lx\n", hr );
2252 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2254 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2255 ok( hr == S_OK, "got %#lx\n", hr );
2257 hr = WsGetReaderNode( reader, &node, NULL );
2258 ok( hr == S_OK, "got %#lx\n", hr );
2259 elem = (WS_XML_ELEMENT_NODE *)node;
2260 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2261 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
2262 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
2264 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_ELEMENT, NULL, NULL );
2265 ok( hr == S_OK, "got %#lx\n", hr );
2267 hr = WsGetReaderNode( reader, &node, NULL );
2268 ok( hr == S_OK, "got %#lx\n", hr );
2269 elem = (WS_XML_ELEMENT_NODE *)node;
2270 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2271 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
2272 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2274 hr = WsMoveReader( reader, WS_MOVE_TO_END_ELEMENT, NULL, NULL );
2275 ok( hr == S_OK, "got %#lx\n", hr );
2277 hr = WsGetReaderNode( reader, &node, NULL );
2278 ok( hr == S_OK, "got %#lx\n", hr );
2279 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2281 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2282 ok( hr == S_OK, "got %#lx\n", hr );
2284 hr = WsGetReaderNode( reader, &node, NULL );
2285 ok( hr == S_OK, "got %#lx\n", hr );
2286 elem = (WS_XML_ELEMENT_NODE *)node;
2287 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2288 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
2289 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2291 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2292 ok( hr == S_OK, "got %#lx\n", hr );
2294 hr = WsGetReaderNode( reader, &node, NULL );
2295 ok( hr == S_OK, "got %#lx\n", hr );
2296 elem = (WS_XML_ELEMENT_NODE *)node;
2297 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2298 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
2299 ok( !memcmp( elem->localName->bytes, "a", 1 ), "wrong data\n" );
2301 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2302 ok( hr == S_OK, "got %#lx\n", hr );
2304 hr = WsGetReaderNode( reader, &node, NULL );
2305 ok( hr == S_OK, "got %#lx\n", hr );
2306 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
2308 hr = WsMoveReader( reader, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
2309 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
2311 WsFreeWriter( writer );
2312 WsFreeHeap( heap );
2314 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2315 ok( hr == S_OK, "got %#lx\n", hr );
2317 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
2318 ok( hr == S_OK, "got %#lx\n", hr );
2320 hr = WsCreateWriter( NULL, 0, &writer, NULL );
2321 ok( hr == S_OK, "got %#lx\n", hr );
2323 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
2324 ok( hr == S_OK, "got %#lx\n", hr );
2326 /* <a><b>test</b></a> */
2327 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
2328 ok( hr == S_OK, "got %#lx\n", hr );
2330 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
2331 ok( hr == S_OK, "got %#lx\n", hr );
2333 memset(&utf8, 0, sizeof(utf8));
2334 utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
2335 utf8.value.bytes = (BYTE *)"test";
2336 utf8.value.length = sizeof("test") - 1;
2337 hr = WsWriteText( writer, &utf8.text, NULL );
2338 ok( hr == S_OK, "got %#lx\n", hr );
2340 hr = WsWriteEndElement( writer, NULL );
2341 ok( hr == S_OK, "got %#lx\n", hr );
2343 hr = WsWriteEndElement( writer, NULL );
2344 ok( hr == S_OK, "got %#lx\n", hr );
2346 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
2347 ok( hr == S_OK, "got %#lx\n", hr );
2349 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2350 ok( hr == S_OK, "got %#lx\n", hr );
2352 hr = WsGetReaderNode( reader, &node, NULL );
2353 ok( hr == S_OK, "got %#lx\n", hr );
2354 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2356 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2357 ok( hr == S_OK, "got %#lx\n", hr );
2359 hr = WsGetReaderNode( reader, &node, NULL );
2360 ok( hr == S_OK, "got %#lx\n", hr );
2361 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2363 hr = WsMoveReader( reader, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
2364 ok( hr == S_OK, "got %#lx\n", hr );
2366 hr = WsMoveReader( reader, WS_MOVE_TO_CHILD_NODE, NULL, NULL );
2367 ok( hr == S_OK, "got %#lx\n", hr );
2369 hr = WsGetReaderNode( reader, &node, NULL );
2370 ok( hr == S_OK, "got %#lx\n", hr );
2371 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2373 hr = WsGetReaderNode( reader, &node, NULL );
2374 ok( hr == S_OK, "got %#lx\n", hr );
2375 elem = (WS_XML_ELEMENT_NODE *)node;
2376 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2377 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
2378 ok( !memcmp( elem->localName->bytes, "b", 1 ), "wrong data\n" );
2380 hr = WsMoveReader( reader, WS_MOVE_TO_NEXT_NODE, NULL, NULL );
2381 ok( hr == S_OK, "got %#lx\n", hr );
2383 hr = WsGetReaderNode( reader, &node, NULL );
2384 ok( hr == S_OK, "got %#lx\n", hr );
2385 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2387 WsFreeReader( reader );
2388 WsFreeWriter( writer );
2389 WsFreeHeap( heap );
2392 static void prepare_struct_type_test( WS_XML_READER *reader, const char *data )
2394 HRESULT hr;
2395 ULONG size = strlen( data );
2397 hr = set_input( reader, data, size );
2398 ok( hr == S_OK, "got %#lx\n", hr );
2401 static void test_simple_struct_type(void)
2403 HRESULT hr;
2404 WS_XML_READER *reader;
2405 WS_HEAP *heap;
2406 WS_STRUCT_DESCRIPTION s;
2407 WS_FIELD_DESCRIPTION f, *fields[1];
2408 WS_XML_STRING ns = {0, NULL}, localname = {3, (BYTE *)"str"};
2409 WS_XML_STRING localname2 = {4, (BYTE *)"test"};
2410 const WS_XML_NODE *node;
2411 const WS_XML_ELEMENT_NODE *elem;
2412 struct test { WCHAR *str; } *test;
2414 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
2415 ok( hr == S_OK, "got %#lx\n", hr );
2417 hr = WsCreateReader( NULL, 0, &reader, NULL );
2418 ok( hr == S_OK, "got %#lx\n", hr );
2420 prepare_struct_type_test( reader, "<str>test</str>" );
2421 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL,
2422 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2423 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
2425 hr = WsGetReaderNode( reader, &node, NULL );
2426 ok( hr == S_OK, "got %#lx\n", hr );
2427 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
2429 /* element field mapping */
2430 memset( &f, 0, sizeof(f) );
2431 f.mapping = WS_ELEMENT_FIELD_MAPPING;
2432 f.localName = &localname;
2433 f.ns = &ns;
2434 f.type = WS_WSZ_TYPE;
2435 fields[0] = &f;
2437 memset( &s, 0, sizeof(s) );
2438 s.size = sizeof(struct test);
2439 s.alignment = TYPE_ALIGNMENT(struct test);
2440 s.fields = fields;
2441 s.fieldCount = 1;
2442 s.typeLocalName = &localname2;
2443 s.typeNs = &ns;
2445 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2446 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2447 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2448 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
2450 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2451 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2452 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2453 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
2455 s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
2456 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
2457 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2458 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2459 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
2460 s.structOptions = 0;
2462 test = NULL;
2463 prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str>" );
2464 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2465 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2466 ok( hr == S_OK, "got %#lx\n", hr );
2467 ok( test != NULL, "test not set\n" );
2468 if (test)
2470 ok( test->str != NULL, "str not set\n" );
2471 if (test->str) ok( !wcscmp( test->str, L"test" ), "wrong data\n" );
2474 hr = WsGetReaderNode( reader, &node, NULL );
2475 ok( hr == S_OK, "got %#lx\n", hr );
2476 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2478 test = NULL;
2479 prepare_struct_type_test( reader, "<str>test</str>" );
2480 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2481 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2482 ok( hr == S_OK, "got %#lx\n", hr );
2483 ok( test != NULL, "test not set\n" );
2484 if (test)
2486 ok( test->str != NULL, "str not set\n" );
2487 if (test->str) ok( !wcscmp( test->str, L"test" ), "wrong data\n" );
2490 hr = WsGetReaderNode( reader, &node, NULL );
2491 ok( hr == S_OK, "got %#lx\n", hr );
2492 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2494 test = NULL;
2495 prepare_struct_type_test( reader, "<str>test</str>" );
2496 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2497 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2498 ok( hr == S_OK, "got %#lx\n", hr );
2499 ok( test != NULL, "test not set\n" );
2500 if (test)
2502 ok( test->str != NULL, "str not set\n" );
2503 if (test->str) ok( !wcscmp( test->str, L"test" ), "wrong data\n" );
2506 hr = WsGetReaderNode( reader, &node, NULL );
2507 ok( hr == S_OK, "got %#lx\n", hr );
2508 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2510 prepare_struct_type_test( reader, "<str>test</str>" );
2511 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2512 ok( hr == S_OK, "got %#lx\n", hr );
2514 hr = WsGetReaderNode( reader, &node, NULL );
2515 ok( hr == S_OK, "got %#lx\n", hr );
2516 elem = (const WS_XML_ELEMENT_NODE *)node;
2517 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2518 ok( elem->localName->length == 3, "got %lu\n", elem->localName->length );
2519 ok( !memcmp( elem->localName->bytes, "str", 3 ), "wrong data\n" );
2521 test = NULL;
2522 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2523 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2524 ok( hr == S_OK, "got %#lx\n", hr );
2525 ok( test != NULL, "test not set\n" );
2526 if (test)
2528 ok( test->str != NULL, "str not set\n" );
2529 if (test->str) ok( !wcscmp( test->str, L"test" ), "wrong data\n" );
2532 hr = WsGetReaderNode( reader, &node, NULL );
2533 ok( hr == S_OK, "got %#lx\n", hr );
2534 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2536 /* attribute field mapping */
2537 f.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
2539 test = NULL;
2540 prepare_struct_type_test( reader, "<test str=\"test\"/>" );
2541 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2542 ok( hr == S_OK, "got %#lx\n", hr );
2544 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
2545 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
2546 ok( hr == S_OK, "got %#lx\n", hr );
2547 ok( test != NULL, "test not set\n" );
2548 if (test)
2550 ok( test->str != NULL, "str not set\n" );
2551 if (test->str) ok( !wcscmp( test->str, L"test" ), "wrong data test %p test->str %p\n", test, test->str );
2554 hr = WsGetReaderNode( reader, &node, NULL );
2555 ok( hr == S_OK, "got %#lx\n", hr );
2556 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
2558 WsFreeReader( reader );
2559 WsFreeHeap( heap );
2562 static void test_cdata(void)
2564 static const char test[] = "<t><![CDATA[<data>]]></t>";
2565 HRESULT hr;
2566 WS_XML_READER *reader;
2567 const WS_XML_NODE *node;
2569 hr = WsCreateReader( NULL, 0, &reader, NULL );
2570 ok( hr == S_OK, "got %#lx\n", hr );
2572 hr = set_input( reader, test, sizeof(test) - 1 );
2573 ok( hr == S_OK, "got %#lx\n", hr );
2575 hr = WsFillReader( reader, sizeof(test) - 1, NULL, NULL );
2576 ok( hr == S_OK, "got %#lx\n", hr );
2578 hr = WsReadNode( reader, NULL );
2579 ok( hr == S_OK, "got %#lx\n", hr );
2581 hr = WsGetReaderNode( reader, &node, NULL );
2582 ok( hr == S_OK, "got %#lx\n", hr );
2583 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
2585 hr = WsReadNode( reader, NULL );
2586 ok( hr == S_OK, "got %#lx\n", hr );
2588 hr = WsGetReaderNode( reader, &node, NULL );
2589 ok( hr == S_OK, "got %#lx\n", hr );
2590 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_CDATA, "got %u\n", node->nodeType );
2592 hr = WsReadNode( reader, NULL );
2593 ok( hr == S_OK, "got %#lx\n", hr );
2595 hr = WsGetReaderNode( reader, &node, NULL );
2596 ok( hr == S_OK, "got %#lx\n", hr );
2597 if (node)
2599 WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
2600 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
2601 ok( text->text != NULL, "text not set\n" );
2602 if (text->text)
2604 WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
2605 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
2606 ok( utf8->value.length == 6, "got %lu\n", utf8->value.length );
2607 ok( !memcmp( utf8->value.bytes, "<data>", 6 ), "wrong data\n" );
2611 hr = WsReadNode( reader, NULL );
2612 ok( hr == S_OK, "got %#lx\n", hr );
2614 hr = WsGetReaderNode( reader, &node, NULL );
2615 ok( hr == S_OK, "got %#lx\n", hr );
2616 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_CDATA, "got %u\n", node->nodeType );
2618 hr = WsReadNode( reader, NULL );
2619 ok( hr == S_OK, "got %#lx\n", hr );
2621 hr = WsGetReaderNode( reader, &node, NULL );
2622 ok( hr == S_OK, "got %#lx\n", hr );
2623 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
2625 WsFreeReader( reader );
2628 static void test_WsFindAttribute(void)
2630 static const char test[] = "<t attr='value' attr2='value2'></t>";
2631 static const char test2[] = "<p:t attr='value' p:attr2='value2' xmlns:p=\"ns\"></t>";
2632 WS_XML_STRING ns = {0, NULL}, ns2 = {2, (BYTE *)"ns"}, localname = {4, (BYTE *)"attr"};
2633 WS_XML_STRING localname2 = {5, (BYTE *)"attr2"}, localname3 = {5, (BYTE *)"attr3"};
2634 WS_XML_READER *reader;
2635 ULONG index;
2636 HRESULT hr;
2638 hr = WsCreateReader( NULL, 0, &reader, NULL );
2639 ok( hr == S_OK, "got %#lx\n", hr );
2641 hr = set_input( reader, test, sizeof(test) - 1 );
2642 ok( hr == S_OK, "got %#lx\n", hr );
2644 hr = WsReadNode( reader, NULL );
2645 ok( hr == S_OK, "got %#lx\n", hr );
2647 hr = WsFindAttribute( reader, &localname, &ns, TRUE, NULL, NULL );
2648 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
2650 hr = set_input( reader, test, sizeof(test) - 1 );
2651 ok( hr == S_OK, "got %#lx\n", hr );
2653 hr = WsReadNode( reader, NULL );
2654 ok( hr == S_OK, "got %#lx\n", hr );
2656 hr = WsFindAttribute( reader, &localname, NULL, TRUE, &index, NULL );
2657 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
2659 hr = set_input( reader, test, sizeof(test) - 1 );
2660 ok( hr == S_OK, "got %#lx\n", hr );
2662 hr = WsReadNode( reader, NULL );
2663 ok( hr == S_OK, "got %#lx\n", hr );
2665 hr = WsFindAttribute( reader, NULL, &ns, TRUE, &index, NULL );
2666 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
2668 hr = set_input( reader, test, sizeof(test) - 1 );
2669 ok( hr == S_OK, "got %#lx\n", hr );
2671 hr = WsReadNode( reader, NULL );
2672 ok( hr == S_OK, "got %#lx\n", hr );
2674 index = 0xdeadbeef;
2675 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2676 ok( hr == S_OK, "got %#lx\n", hr );
2677 ok( !index, "got %lu\n", index );
2679 index = 0xdeadbeef;
2680 hr = WsFindAttribute( reader, &localname2, &ns, TRUE, &index, NULL );
2681 ok( hr == S_OK, "got %#lx\n", hr );
2682 ok( index == 1, "got %lu\n", index );
2684 hr = WsReadNode( reader, NULL );
2685 ok( hr == S_OK, "got %#lx\n", hr );
2687 index = 0xdeadbeef;
2688 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2689 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
2690 ok( index == 0xdeadbeef, "got %lu\n", index );
2692 hr = set_input( reader, test, sizeof(test) - 1 );
2693 ok( hr == S_OK, "got %#lx\n", hr );
2695 hr = WsReadNode( reader, NULL );
2696 ok( hr == S_OK, "got %#lx\n", hr );
2698 index = 0xdeadbeef;
2699 hr = WsFindAttribute( reader, &localname3, &ns, TRUE, &index, NULL );
2700 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
2701 ok( index == 0xdeadbeef, "got %lu\n", index );
2703 hr = set_input( reader, test, sizeof(test) - 1 );
2704 ok( hr == S_OK, "got %#lx\n", hr );
2706 hr = WsReadNode( reader, NULL );
2707 ok( hr == S_OK, "got %#lx\n", hr );
2709 index = 0xdeadbeef;
2710 hr = WsFindAttribute( reader, &localname3, &ns, FALSE, &index, NULL );
2711 ok( hr == S_FALSE, "got %#lx\n", hr );
2712 ok( index == ~0u, "got %lu\n", index );
2714 hr = set_input( reader, test2, sizeof(test2) - 1 );
2715 ok( hr == S_OK, "got %#lx\n", hr );
2717 hr = WsReadNode( reader, NULL );
2718 ok( hr == S_OK, "got %#lx\n", hr );
2720 index = 0xdeadbeef;
2721 hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
2722 ok( hr == S_OK, "got %#lx\n", hr );
2723 ok( !index, "got %lu\n", index );
2725 hr = WsFindAttribute( reader, &localname2, &ns2, TRUE, &index, NULL );
2726 ok( hr == S_OK, "got %#lx\n", hr );
2728 hr = WsFindAttribute( reader, &localname2, &ns, TRUE, &index, NULL );
2729 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
2731 hr = set_input( reader, test2, sizeof(test2) - 1 );
2732 ok( hr == S_OK, "got %#lx\n", hr );
2734 hr = WsReadNode( reader, NULL );
2735 ok( hr == S_OK, "got %#lx\n", hr );
2737 hr = WsFindAttribute( reader, &localname, &ns2, TRUE, &index, NULL );
2738 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
2740 WsFreeReader( reader );
2743 static void prepare_namespace_test( WS_XML_READER *reader, const char *data )
2745 HRESULT hr;
2746 ULONG size = strlen( data );
2748 hr = set_input( reader, data, size );
2749 ok( hr == S_OK, "got %#lx\n", hr );
2751 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2752 ok( hr == S_OK, "got %#lx\n", hr );
2755 static void test_WsGetNamespaceFromPrefix(void)
2757 WS_XML_STRING prefix = {0, NULL};
2758 const WS_XML_STRING *ns;
2759 const WS_XML_NODE *node;
2760 WS_XML_READER *reader;
2761 HRESULT hr;
2763 hr = WsCreateReader( NULL, 0, &reader, NULL );
2764 ok( hr == S_OK, "got %#lx\n", hr );
2766 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, NULL, NULL );
2767 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
2769 hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, &ns, NULL );
2770 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
2772 hr = WsGetNamespaceFromPrefix( NULL, &prefix, FALSE, &ns, NULL );
2773 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
2775 ns = (const WS_XML_STRING *)0xdeadbeef;
2776 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2777 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
2778 ok( ns == (const WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2780 hr = set_input( reader, "<prefix:t xmlns:prefix2='ns'/>", sizeof("<prefix:t xmlns:prefix2='ns'/>") - 1 );
2781 ok( hr == S_OK, "got %#lx\n", hr );
2782 hr = WsReadStartElement( reader, NULL );
2783 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
2785 prepare_namespace_test( reader, "<t></t>" );
2786 ns = NULL;
2787 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2788 ok( hr == S_OK, "got %#lx\n", hr );
2789 ok( ns != NULL, "ns not set\n" );
2790 if (ns) ok( !ns->length, "got %lu\n", ns->length );
2792 prepare_namespace_test( reader, "<t xmls='ns'></t>" );
2793 ns = NULL;
2794 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2795 ok( hr == S_OK, "got %#lx\n", hr );
2796 ok( ns != NULL, "ns not set\n" );
2797 if (ns) ok( !ns->length, "got %lu\n", ns->length );
2799 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2800 ns = NULL;
2801 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2802 ok( hr == S_OK, "got %#lx\n", hr );
2803 ok( ns != NULL, "ns not set\n" );
2804 if (ns) ok( !ns->length, "got %lu\n", ns->length );
2806 prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
2807 prefix.bytes = (BYTE *)"prefix";
2808 prefix.length = 6;
2809 ns = NULL;
2810 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2811 ok( hr == S_OK, "got %#lx\n", hr );
2812 ok( ns != NULL, "ns not set\n" );
2813 if (ns)
2815 ok( ns->length == 2, "got %lu\n", ns->length );
2816 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2819 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2820 ns = NULL;
2821 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2822 ok( hr == S_OK, "got %#lx\n", hr );
2823 ok( ns != NULL, "ns not set\n" );
2824 if (ns)
2826 ok( ns->length == 2, "got %lu\n", ns->length );
2827 ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
2830 hr = set_input( reader, "<t xmlns:prefix='ns'></t>", sizeof("<t xmlns:prefix='ns'></t>") - 1 );
2831 ok( hr == S_OK, "got %#lx\n", hr );
2832 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2833 ok( hr == S_OK, "got %#lx\n", hr );
2834 hr = WsGetReaderNode( reader, &node, NULL );
2835 ok( hr == S_OK, "got %#lx\n", hr );
2836 if (node)
2838 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2839 WS_XML_ATTRIBUTE *attr;
2840 WS_XML_UTF8_TEXT *text;
2842 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2843 ok( elem->prefix != NULL, "prefix not set\n" );
2844 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
2845 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
2846 ok( elem->ns != NULL, "ns not set\n" );
2847 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
2848 ok( elem->ns->bytes != NULL, "bytes not set\n" );
2849 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
2850 ok( elem->attributes != NULL, "attributes not set\n" );
2852 attr = elem->attributes[0];
2853 ok( attr->singleQuote, "singleQuote not set\n" );
2854 ok( attr->isXmlNs, "isXmlNs not set\n" );
2855 ok( attr->prefix != NULL, "prefix not set\n" );
2856 ok( attr->prefix->length == 6, "got %lu\n", attr->prefix->length );
2857 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2858 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2859 ok( attr->localName != NULL, "localName not set\n" );
2860 ok( attr->localName->length == 6, "got %lu\n", attr->localName->length );
2861 ok( !memcmp( attr->localName->bytes, "prefix", 6 ), "wrong data\n" );
2862 ok( attr->ns != NULL, "ns not set\n" );
2863 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
2864 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2865 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2866 ok( attr->value != NULL, "value not set\n" );
2868 text = (WS_XML_UTF8_TEXT *)attr->value;
2869 ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
2870 ok( !text->value.length, "got %lu\n", text->value.length );
2871 ok( text->value.bytes == NULL, "bytes set\n" );
2874 prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
2875 hr = WsReadStartElement( reader, NULL );
2876 ok( hr == S_OK, "got %#lx\n", hr );
2877 hr = WsReadEndElement( reader, NULL );
2878 ok( hr == S_OK, "got %#lx\n", hr );
2879 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2880 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
2882 prepare_namespace_test( reader, "<t></t>" );
2883 ns = NULL;
2884 prefix.bytes = (BYTE *)"xml";
2885 prefix.length = 3;
2886 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2887 ok( hr == S_OK, "got %#lx\n", hr );
2888 ok( ns != NULL, "ns not set\n" );
2889 if (ns)
2891 ok( ns->length == 36, "got %lu\n", ns->length );
2892 ok( !memcmp( ns->bytes, "http://www.w3.org/XML/1998/namespace", 36 ), "wrong data\n" );
2895 prepare_namespace_test( reader, "<t></t>" );
2896 ns = NULL;
2897 prefix.bytes = (BYTE *)"xmlns";
2898 prefix.length = 5;
2899 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2900 ok( hr == S_OK, "got %#lx\n", hr );
2901 ok( ns != NULL, "ns not set\n" );
2902 if (ns)
2904 ok( ns->length == 29, "got %lu\n", ns->length );
2905 ok( !memcmp( ns->bytes, "http://www.w3.org/2000/xmlns/", 29 ), "wrong data\n" );
2908 prepare_namespace_test( reader, "<t></t>" );
2909 ns = (WS_XML_STRING *)0xdeadbeef;
2910 prefix.bytes = (BYTE *)"prefix2";
2911 prefix.length = 7;
2912 hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
2913 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
2914 ok( ns == (WS_XML_STRING *)0xdeadbeef, "ns set\n" );
2916 prepare_namespace_test( reader, "<t></t>" );
2917 ns = (WS_XML_STRING *)0xdeadbeef;
2918 prefix.bytes = (BYTE *)"prefix2";
2919 prefix.length = 7;
2920 hr = WsGetNamespaceFromPrefix( reader, &prefix, FALSE, &ns, NULL );
2921 ok( hr == S_FALSE, "got %#lx\n", hr );
2922 ok( ns == NULL, "ns not set\n" );
2924 hr = set_input( reader, "<t prefix:attr='' xmlns:prefix='ns'></t>", sizeof("<t prefix:attr='' xmlns:prefix='ns'></t>") - 1 );
2925 ok( hr == S_OK, "got %#lx\n", hr );
2926 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2927 ok( hr == S_OK, "got %#lx\n", hr );
2928 hr = WsGetReaderNode( reader, &node, NULL );
2929 ok( hr == S_OK, "got %#lx\n", hr );
2930 if (node)
2932 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2933 WS_XML_ATTRIBUTE *attr;
2935 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2936 ok( elem->attributeCount == 2, "got %lu\n", elem->attributeCount );
2937 ok( elem->attributes != NULL, "attributes not set\n" );
2939 attr = elem->attributes[0];
2940 ok( attr->singleQuote, "singleQuote not set\n" );
2941 ok( !attr->isXmlNs, "isXmlNs is set\n" );
2942 ok( attr->prefix != NULL, "prefix not set\n" );
2943 ok( attr->prefix->length == 6, "got %lu\n", attr->prefix->length );
2944 ok( attr->prefix->bytes != NULL, "bytes not set\n" );
2945 ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
2946 ok( attr->localName != NULL, "localName not set\n" );
2947 ok( attr->localName->length == 4, "got %lu\n", attr->localName->length );
2948 ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
2949 ok( attr->ns != NULL, "ns not set\n" );
2950 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
2951 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2952 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2955 hr = set_input( reader, "<t xmlns:p='ns'><u xmlns:p='ns2'/></t>", sizeof("<t xmlns:p='ns'><u xmlns:p='ns2'/></t>") - 1 );
2956 ok( hr == S_OK, "got %#lx\n", hr );
2957 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2958 ok( hr == S_OK, "got %#lx\n", hr );
2959 hr = WsReadStartElement( reader, NULL );
2960 ok( hr == S_OK, "got %#lx\n", hr );
2962 hr = set_input( reader, "<t xmlns:p='ns'><p:u p:a=''/></t>", sizeof("<t xmlns:p='ns'><p:u p:a=''/></t>") - 1 );
2963 ok( hr == S_OK, "got %#lx\n", hr );
2964 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2965 ok( hr == S_OK, "got %#lx\n", hr );
2966 hr = WsReadStartElement( reader, NULL );
2967 ok( hr == S_OK, "got %#lx\n", hr );
2968 hr = WsGetReaderNode( reader, &node, NULL );
2969 ok( hr == S_OK, "got %#lx\n", hr );
2970 if (node)
2972 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
2973 WS_XML_ATTRIBUTE *attr;
2975 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
2976 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
2977 ok( elem->attributes != NULL, "attributes not set\n" );
2979 attr = elem->attributes[0];
2980 ok( attr->prefix != NULL, "prefix not set\n" );
2981 ok( attr->prefix->length == 1, "got %lu\n", attr->prefix->length );
2982 ok( attr->prefix->bytes != NULL, "bytes set\n" );
2983 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong data\n" );
2984 ok( attr->localName != NULL, "localName not set\n" );
2985 ok( attr->localName->length == 1, "got %lu\n", attr->localName->length );
2986 ok( !memcmp( attr->localName->bytes, "a", 1 ), "wrong data\n" );
2987 ok( attr->ns != NULL, "ns not set\n" );
2988 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
2989 ok( attr->ns->bytes != NULL, "bytes not set\n" );
2990 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
2993 hr = set_input( reader, "<t xmlns='ns'></t>", sizeof("<t xmlns='ns'></t>") - 1 );
2994 ok( hr == S_OK, "got %#lx\n", hr );
2995 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
2996 ok( hr == S_OK, "got %#lx\n", hr );
2997 hr = WsGetReaderNode( reader, &node, NULL );
2998 ok( hr == S_OK, "got %#lx\n", hr );
2999 if (node)
3001 WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
3002 WS_XML_ATTRIBUTE *attr;
3004 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
3005 ok( elem->prefix != NULL, "prefix not set\n" );
3006 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
3007 ok( elem->prefix->bytes == NULL, "bytes not set\n" );
3008 ok( elem->ns != NULL, "ns not set\n" );
3009 ok( elem->ns->length == 2, "got %lu\n", elem->ns->length );
3010 ok( elem->ns->bytes != NULL, "bytes not set\n" );
3011 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong data\n" );
3013 attr = elem->attributes[0];
3014 ok( attr->isXmlNs, "isXmlNs is not set\n" );
3015 ok( attr->prefix != NULL, "prefix not set\n" );
3016 ok( !attr->prefix->length, "got %lu\n", attr->prefix->length );
3017 ok( attr->prefix->bytes == NULL, "bytes set\n" );
3018 ok( attr->localName != NULL, "localName not set\n" );
3019 ok( attr->localName->length == 5, "got %lu\n", attr->localName->length );
3020 ok( !memcmp( attr->localName->bytes, "xmlns", 5 ), "wrong data\n" );
3021 ok( attr->ns != NULL, "ns not set\n" );
3022 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
3023 ok( attr->ns->bytes != NULL, "bytes not set\n" );
3024 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
3027 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns2'></t>") - 1 );
3028 ok( hr == S_OK, "got %#lx\n", hr );
3029 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3030 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
3032 hr = set_input( reader, "<t xmlns:p='ns' xmlns:p='ns'></t>", sizeof("<t xmlns:p='ns' xmlns:p='ns'></t>") - 1 );
3033 ok( hr == S_OK, "got %#lx\n", hr );
3034 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3035 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
3037 hr = set_input( reader, "<t xmlns:p='ns' xmlns:P='ns2'></t>", sizeof("<t xmlns:p='ns' xmlns:P='ns2'></t>") - 1 );
3038 ok( hr == S_OK, "got %#lx\n", hr );
3039 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3040 ok( hr == S_OK, "got %#lx\n", hr );
3042 WsFreeReader( reader );
3045 static void test_text_field_mapping(void)
3047 HRESULT hr;
3048 WS_XML_READER *reader;
3049 WS_HEAP *heap;
3050 WS_STRUCT_DESCRIPTION s;
3051 WS_FIELD_DESCRIPTION f, *fields[1];
3052 struct test
3054 WCHAR *str;
3055 } *test;
3057 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3058 ok( hr == S_OK, "got %#lx\n", hr );
3060 hr = WsCreateReader( NULL, 0, &reader, NULL );
3061 ok( hr == S_OK, "got %#lx\n", hr );
3063 prepare_struct_type_test( reader, "<a>test</a>" );
3065 memset( &f, 0, sizeof(f) );
3066 f.mapping = WS_TEXT_FIELD_MAPPING;
3067 f.type = WS_WSZ_TYPE;
3068 fields[0] = &f;
3070 memset( &s, 0, sizeof(s) );
3071 s.size = sizeof(struct test);
3072 s.alignment = TYPE_ALIGNMENT(struct test);
3073 s.fields = fields;
3074 s.fieldCount = 1;
3076 test = NULL;
3077 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3078 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3079 ok( hr == S_OK, "got %#lx\n", hr );
3080 ok( test != NULL, "test not set\n" );
3081 ok( test->str != NULL, "str not set\n" );
3082 ok( !wcscmp( test->str, L"test" ), "got %s\n", wine_dbgstr_w(test->str) );
3084 WsFreeReader( reader );
3085 WsFreeHeap( heap );
3088 static void test_complex_struct_type(void)
3090 static const char data[] =
3091 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
3092 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\">"
3093 "<!--Build: 16.0.6202.6852-->"
3094 "</o:services>"
3095 "</o:OfficeConfig>";
3096 static const char data2[] =
3097 "<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
3098 "<o:services o:GenerationTime=\"2015-09-03T18:47:54\"></o:services>"
3099 "<trailing>content</trailing>"
3100 "</o:OfficeConfig>";
3101 HRESULT hr;
3102 WS_ERROR *error;
3103 WS_ERROR_PROPERTY prop;
3104 WS_XML_READER *reader;
3105 WS_HEAP *heap;
3106 WS_STRUCT_DESCRIPTION s, s2;
3107 WS_FIELD_DESCRIPTION f, f2, *fields[1], *fields2[1];
3108 WS_XML_STRING str_officeconfig = {12, (BYTE *)"OfficeConfig"};
3109 WS_XML_STRING str_services = {8, (BYTE *)"services"};
3110 WS_XML_STRING str_generationtime = {14, (BYTE *)"GenerationTime"};
3111 WS_XML_STRING ns = {39, (BYTE *)"urn:schemas-microsoft-com:office:office"};
3112 LANGID langid = MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT );
3113 const WS_XML_NODE *node;
3114 const WS_XML_ELEMENT_NODE *elem;
3115 struct services
3117 WCHAR *generationtime;
3119 struct officeconfig
3121 struct services *services;
3122 } *test;
3124 prop.id = WS_ERROR_PROPERTY_LANGID;
3125 prop.value = &langid;
3126 prop.valueSize = sizeof(langid);
3127 hr = WsCreateError( &prop, 1, &error );
3128 ok( hr == S_OK, "got %#lx\n", hr );
3130 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3131 ok( hr == S_OK, "got %#lx\n", hr );
3133 hr = WsCreateReader( NULL, 0, &reader, NULL );
3134 ok( hr == S_OK, "got %#lx\n", hr );
3136 /* element content type mapping */
3137 prepare_struct_type_test( reader, data );
3139 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3140 ok( hr == S_OK, "got %#lx\n", hr );
3142 hr = WsGetReaderNode( reader, &node, NULL );
3143 ok( hr == S_OK, "got %#lx\n", hr );
3144 elem = (const WS_XML_ELEMENT_NODE *)node;
3145 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
3146 ok( elem->localName->length == 12, "got %lu\n", elem->localName->length );
3147 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
3149 hr = WsReadStartElement( reader, NULL );
3150 ok( hr == S_OK, "got %#lx\n", hr );
3152 hr = WsGetReaderNode( reader, &node, NULL );
3153 ok( hr == S_OK, "got %#lx\n", hr );
3154 elem = (const WS_XML_ELEMENT_NODE *)node;
3155 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
3156 ok( elem->localName->length == 8, "got %lu\n", elem->localName->length );
3157 ok( !memcmp( elem->localName->bytes, "services", 8 ), "wrong data\n" );
3159 memset( &f2, 0, sizeof(f2) );
3160 f2.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
3161 f2.localName = &str_generationtime;
3162 f2.ns = &ns;
3163 f2.type = WS_WSZ_TYPE;
3164 f2.options = WS_FIELD_OPTIONAL;
3165 fields2[0] = &f2;
3167 memset( &s2, 0, sizeof(s2) );
3168 s2.size = sizeof(*test->services);
3169 s2.alignment = TYPE_ALIGNMENT(struct services);
3170 s2.fields = fields2;
3171 s2.fieldCount = 1;
3172 s2.typeLocalName = &str_services;
3173 s2.typeNs = &ns;
3175 memset( &f, 0, sizeof(f) );
3176 f.mapping = WS_ELEMENT_FIELD_MAPPING;
3177 f.localName = &str_services;
3178 f.ns = &ns;
3179 f.type = WS_STRUCT_TYPE;
3180 f.typeDescription = &s2;
3181 f.options = WS_FIELD_POINTER;
3182 fields[0] = &f;
3184 memset( &s, 0, sizeof(s) );
3185 s.size = sizeof(*test);
3186 s.alignment = TYPE_ALIGNMENT(struct officeconfig);
3187 s.fields = fields;
3188 s.fieldCount = 1;
3189 s.typeLocalName = &str_officeconfig;
3190 s.typeNs = &ns;
3192 test = NULL;
3193 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3194 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
3195 ok( hr == S_OK, "got %#lx\n", hr );
3196 ok( test != NULL, "test not set\n" );
3197 ok( !wcscmp( test->services->generationtime, L"2015-09-03T18:47:54" ), "wrong data\n" );
3199 hr = WsGetReaderNode( reader, &node, NULL );
3200 ok( hr == S_OK, "got %#lx\n", hr );
3201 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
3203 hr = WsReadEndElement( reader, NULL );
3204 ok( hr == S_OK, "got %#lx\n", hr );
3206 hr = WsGetReaderNode( reader, &node, NULL );
3207 ok( hr == S_OK, "got %#lx\n", hr );
3208 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
3210 hr = WsReadEndElement( reader, NULL );
3211 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
3213 /* element type mapping */
3214 prepare_struct_type_test( reader, data );
3216 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3217 ok( hr == S_OK, "got %#lx\n", hr );
3219 hr = WsGetReaderNode( reader, &node, NULL );
3220 ok( hr == S_OK, "got %#lx\n", hr );
3221 elem = (const WS_XML_ELEMENT_NODE *)node;
3222 ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
3223 ok( elem->localName->length == 12, "got %lu\n", elem->localName->length );
3224 ok( !memcmp( elem->localName->bytes, "OfficeConfig", 12 ), "wrong data\n" );
3226 test = NULL;
3227 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3228 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
3229 ok( hr == S_OK, "got %#lx\n", hr );
3230 ok( test != NULL, "test not set\n" );
3231 if (test) ok( !wcscmp( test->services->generationtime, L"2015-09-03T18:47:54" ), "wrong data\n" );
3233 hr = WsGetReaderNode( reader, &node, NULL );
3234 ok( hr == S_OK, "got %#lx\n", hr );
3235 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
3237 /* trailing content */
3238 prepare_struct_type_test( reader, data2 );
3239 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3240 ok( hr == S_OK, "got %#lx\n", hr );
3242 s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
3243 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3244 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
3245 ok( hr == S_OK, "got %#lx\n", hr );
3247 hr = WsGetReaderNode( reader, &node, NULL );
3248 ok( hr == S_OK, "got %#lx\n", hr );
3249 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
3251 prepare_struct_type_test( reader, data2 );
3252 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3253 ok( hr == S_OK, "got %#lx\n", hr );
3255 s.structOptions = 0;
3256 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3257 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
3258 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
3260 WsFreeReader( reader );
3261 WsFreeHeap( heap );
3262 WsFreeError( error );
3265 static void test_repeating_element(void)
3267 static const char data[] =
3268 "<services>"
3269 "<service><id>1</id></service>"
3270 "<service><id>2</id></service>"
3271 "</services>";
3272 static const char data2[] =
3273 "<services></services>";
3274 static const char data3[] =
3275 "<services>"
3276 "<wrapper>"
3277 "<service><id>1</id></service>"
3278 "<service><id>2</id></service>"
3279 "</wrapper>"
3280 "</services>";
3281 static const char data4[] =
3282 "<services>"
3283 "<wrapper>"
3284 "<service>1</service>"
3285 "<service>2</service>"
3286 "</wrapper>"
3287 "</services>";
3288 static const char data5[] =
3289 "<services>"
3290 "<wrapper>"
3291 "<service name='1'>1</service>"
3292 "<service name='2'>2</service>"
3293 "</wrapper>"
3294 "</services>";
3295 static const char data6[] =
3296 "<services>"
3297 "<service><name></name></service>"
3298 "</services>";
3299 WS_XML_STRING str_name = {4, (BYTE *)"name"};
3300 WS_XML_STRING str_services = {8, (BYTE *)"services"};
3301 WS_XML_STRING str_service = {7, (BYTE *)"service"};
3302 WS_XML_STRING str_wrapper = {7, (BYTE *)"wrapper"};
3303 WS_XML_STRING str_id = {2, (BYTE *)"id"};
3304 WS_XML_STRING str_ns = {0, NULL};
3305 HRESULT hr;
3306 WS_XML_READER *reader;
3307 WS_HEAP *heap;
3308 WS_STRUCT_DESCRIPTION s, s2;
3309 WS_FIELD_DESCRIPTION f, f2, f3, *fields[1], *fields2[2];
3310 WS_ITEM_RANGE range;
3311 struct service { UINT32 id; };
3312 struct service2 { WCHAR *id; };
3313 struct service3 { WCHAR *name; WCHAR *id; };
3314 struct service4 { WS_STRING name; };
3315 struct services
3317 struct service *service;
3318 ULONG service_count;
3319 } *test;
3320 struct services2
3322 struct service2 *service;
3323 ULONG service_count;
3324 } *test2;
3325 struct services3
3327 struct service3 *service;
3328 ULONG service_count;
3329 } *test3;
3330 struct services4
3332 struct service **service;
3333 ULONG service_count;
3334 } *test4;
3335 struct services5
3337 struct service4 *service;
3338 ULONG service_count;
3339 } *test5;
3341 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3342 ok( hr == S_OK, "got %#lx\n", hr );
3344 hr = WsCreateReader( NULL, 0, &reader, NULL );
3345 ok( hr == S_OK, "got %#lx\n", hr );
3347 prepare_struct_type_test( reader, data );
3349 memset( &f2, 0, sizeof(f2) );
3350 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
3351 f2.localName = &str_id;
3352 f2.ns = &str_ns;
3353 f2.type = WS_UINT32_TYPE;
3354 fields2[0] = &f2;
3356 memset( &s2, 0, sizeof(s2) );
3357 s2.size = sizeof(struct service);
3358 s2.alignment = TYPE_ALIGNMENT(struct service);
3359 s2.fields = fields2;
3360 s2.fieldCount = 1;
3361 s2.typeLocalName = &str_service;
3363 memset( &f, 0, sizeof(f) );
3364 f.mapping = WS_REPEATING_ELEMENT_FIELD_MAPPING;
3365 f.countOffset = FIELD_OFFSET(struct services, service_count);
3366 f.type = WS_STRUCT_TYPE;
3367 f.typeDescription = &s2;
3368 f.itemLocalName = &str_service;
3369 f.itemNs = &str_ns;
3370 fields[0] = &f;
3372 memset( &s, 0, sizeof(s) );
3373 s.size = sizeof(struct services);
3374 s.alignment = TYPE_ALIGNMENT(struct services);
3375 s.fields = fields;
3376 s.fieldCount = 1;
3377 s.typeLocalName = &str_services;
3379 test = NULL;
3380 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3381 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3382 ok( hr == S_OK, "got %#lx\n", hr );
3383 ok( test != NULL, "test not set\n" );
3384 ok( test->service != NULL, "service not set\n" );
3385 ok( test->service_count == 2, "got %lu\n", test->service_count );
3386 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
3387 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
3389 /* array of pointers */
3390 prepare_struct_type_test( reader, data );
3391 f.options = WS_FIELD_POINTER;
3392 test4 = NULL;
3393 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3394 WS_READ_REQUIRED_POINTER, heap, &test4, sizeof(test4), NULL );
3395 ok( hr == S_OK || broken(hr == E_INVALIDARG) /* win7 */, "got %#lx\n", hr );
3396 if (test4)
3398 ok( test4->service != NULL, "service not set\n" );
3399 ok( test4->service_count == 2, "got %lu\n", test4->service_count );
3400 ok( test4->service[0]->id == 1, "got %u\n", test4->service[0]->id );
3401 ok( test4->service[1]->id == 2, "got %u\n", test4->service[1]->id );
3404 /* item range */
3405 prepare_struct_type_test( reader, data2 );
3406 f.options = 0;
3407 range.minItemCount = 0;
3408 range.maxItemCount = 1;
3409 f.itemRange = &range;
3410 test = NULL;
3411 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3412 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3413 ok( hr == S_OK, "got %#lx\n", hr );
3414 ok( test != NULL, "test not set\n" );
3415 ok( test->service != NULL, "service not set\n" );
3416 ok( !test->service_count, "got %lu\n", test->service_count );
3418 /* wrapper element */
3419 prepare_struct_type_test( reader, data3 );
3420 f.itemRange = NULL;
3421 f.localName = &str_wrapper;
3422 f.ns = &str_ns;
3423 test = NULL;
3424 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3425 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
3426 ok( hr == S_OK, "got %#lx\n", hr );
3427 ok( test != NULL, "test not set\n" );
3428 ok( test->service != NULL, "service not set\n" );
3429 ok( test->service_count == 2, "got %lu\n", test->service_count );
3430 ok( test->service[0].id == 1, "got %u\n", test->service[0].id );
3431 ok( test->service[1].id == 2, "got %u\n", test->service[1].id );
3433 /* repeating text field mapping */
3434 prepare_struct_type_test( reader, data4 );
3435 f2.mapping = WS_TEXT_FIELD_MAPPING;
3436 f2.localName = NULL;
3437 f2.ns = NULL;
3438 f2.type = WS_WSZ_TYPE;
3439 s2.size = sizeof(struct service2);
3440 s2.alignment = TYPE_ALIGNMENT(struct service2);
3441 test2 = NULL;
3442 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3443 WS_READ_REQUIRED_POINTER, heap, &test2, sizeof(test2), NULL );
3444 ok( hr == S_OK, "got %#lx\n", hr );
3445 ok( test2 != NULL, "test2 not set\n" );
3446 ok( test2->service != NULL, "service not set\n" );
3447 ok( test2->service_count == 2, "got %lu\n", test2->service_count );
3448 ok( !wcscmp( test2->service[0].id, L"1" ), "wrong data\n" );
3449 ok( !wcscmp( test2->service[1].id, L"2" ), "wrong data\n" );
3451 /* repeating attribute field + text field mapping */
3452 prepare_struct_type_test( reader, data5 );
3453 f2.offset = FIELD_OFFSET(struct service3, id);
3454 memset( &f3, 0, sizeof(f3) );
3455 f3.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
3456 f3.localName = &str_name;
3457 f3.ns = &str_ns;
3458 f3.type = WS_WSZ_TYPE;
3459 fields2[0] = &f3;
3460 fields2[1] = &f2;
3461 s2.size = sizeof(struct service3);
3462 s2.alignment = TYPE_ALIGNMENT(struct service3);
3463 s2.fieldCount = 2;
3464 test3 = NULL;
3465 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3466 WS_READ_REQUIRED_POINTER, heap, &test3, sizeof(test3), NULL );
3467 ok( hr == S_OK, "got %#lx\n", hr );
3468 ok( test3 != NULL, "test3 not set\n" );
3469 ok( test3->service != NULL, "service not set\n" );
3470 ok( test3->service_count == 2, "got %lu\n", test3->service_count );
3471 ok( !wcscmp( test3->service[0].name, L"1" ), "wrong data\n" );
3472 ok( !wcscmp( test3->service[0].id, L"1" ), "wrong data\n" );
3473 ok( !wcscmp( test3->service[1].name, L"2" ), "wrong data\n" );
3474 ok( !wcscmp( test3->service[1].id, L"2" ), "wrong data\n" );
3476 /* empty text, item range */
3477 prepare_struct_type_test( reader, data6 );
3479 memset( &f2, 0, sizeof(f2) );
3480 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
3481 f2.localName = &str_name;
3482 f2.ns = &str_ns;
3483 f2.type = WS_STRING_TYPE;
3484 fields2[0] = &f2;
3486 memset( &s2, 0, sizeof(s2) );
3487 s2.size = sizeof(struct service4);
3488 s2.alignment = TYPE_ALIGNMENT(struct service4);
3489 s2.fields = fields2;
3490 s2.fieldCount = 1;
3491 s2.typeLocalName = &str_service;
3493 range.minItemCount = 1;
3494 range.maxItemCount = 2;
3495 memset( &f, 0, sizeof(f) );
3496 f.mapping = WS_REPEATING_ELEMENT_FIELD_MAPPING;
3497 f.countOffset = FIELD_OFFSET(struct services5, service_count);
3498 f.type = WS_STRUCT_TYPE;
3499 f.typeDescription = &s2;
3500 f.itemLocalName = &str_service;
3501 f.itemNs = &str_ns;
3502 f.itemRange = &range;
3503 fields[0] = &f;
3505 memset( &s, 0, sizeof(s) );
3506 s.size = sizeof(struct services5);
3507 s.alignment = TYPE_ALIGNMENT(struct services5);
3508 s.fields = fields;
3509 s.fieldCount = 1;
3510 s.typeLocalName = &str_services;
3512 test5 = NULL;
3513 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
3514 WS_READ_REQUIRED_POINTER, heap, &test5, sizeof(test5), NULL );
3515 ok( hr == S_OK, "got %#lx\n", hr );
3516 ok( test5 != NULL, "test5 not set\n" );
3517 ok( test5->service != NULL, "service not set\n" );
3518 ok( test5->service_count == 1, "got %lu\n", test5->service_count );
3519 ok( !test5->service[0].name.length, "got %lu\n", test5->service[0].name.length );
3520 todo_wine ok( test5->service[0].name.chars != NULL, "chars set\n" );
3522 WsFreeReader( reader );
3523 WsFreeHeap( heap );
3526 static void test_WsResetHeap(void)
3528 HRESULT hr;
3529 WS_HEAP *heap;
3530 SIZE_T requested, actual;
3531 ULONG size;
3532 void *ptr;
3534 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3535 ok( hr == S_OK, "got %#lx\n", hr );
3537 requested = 0xdeadbeef;
3538 size = sizeof(requested);
3539 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3540 ok( hr == S_OK, "got %#lx\n", hr );
3541 ok( !requested, "got %Iu\n", requested );
3543 actual = 0xdeadbeef;
3544 size = sizeof(actual);
3545 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3546 ok( hr == S_OK, "got %#lx\n", hr );
3547 ok( !actual, "got %Iu\n", actual );
3549 hr = WsAlloc( heap, 128, &ptr, NULL );
3550 ok( hr == S_OK, "got %#lx\n", hr );
3552 requested = 0xdeadbeef;
3553 size = sizeof(requested);
3554 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3555 ok( hr == S_OK, "got %#lx\n", hr );
3556 ok( requested == 128, "got %Iu\n", requested );
3558 actual = 0xdeadbeef;
3559 size = sizeof(actual);
3560 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3561 ok( hr == S_OK, "got %#lx\n", hr );
3562 ok( actual == 128, "got %Iu\n", actual );
3564 hr = WsAlloc( heap, 1, &ptr, NULL );
3565 ok( hr == S_OK, "got %#lx\n", hr );
3567 requested = 0xdeadbeef;
3568 size = sizeof(requested);
3569 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3570 ok( hr == S_OK, "got %#lx\n", hr );
3571 ok( requested == 129, "got %Iu\n", requested );
3573 actual = 0xdeadbeef;
3574 size = sizeof(actual);
3575 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3576 ok( hr == S_OK, "got %#lx\n", hr );
3577 todo_wine ok( actual == 384, "got %Iu\n", actual );
3579 hr = WsResetHeap( NULL, NULL );
3580 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3582 hr = WsResetHeap( heap, NULL );
3583 ok( hr == S_OK, "got %#lx\n", hr );
3585 requested = 0xdeadbeef;
3586 size = sizeof(requested);
3587 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_REQUESTED_SIZE, &requested, size, NULL );
3588 ok( hr == S_OK, "got %#lx\n", hr );
3589 ok( !requested, "got %Iu\n", requested );
3591 actual = 0xdeadbeef;
3592 size = sizeof(actual);
3593 hr = WsGetHeapProperty( heap, WS_HEAP_PROPERTY_ACTUAL_SIZE, &actual, size, NULL );
3594 ok( hr == S_OK, "got %#lx\n", hr );
3595 todo_wine ok( actual == 128, "got %Iu\n", actual );
3597 WsFreeHeap( heap );
3600 static void test_datetime(void)
3602 static const struct
3604 const char *str;
3605 HRESULT hr;
3606 __int64 ticks;
3607 WS_DATETIME_FORMAT format;
3609 tests[] =
3611 {"<t>0000-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3612 {"<t>0001-01-01T00:00:00Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3613 {"<t>0001-01-01T00:00:00.Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3614 {"<t>0001-01-01T00:00:00.0Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3615 {"<t>0001-01-01T00:00:00.1Z</t>", S_OK, 0x0000f4240, WS_DATETIME_FORMAT_UTC},
3616 {"<t>0001-01-01T00:00:00.01Z</t>", S_OK, 0x0000186a0, WS_DATETIME_FORMAT_UTC},
3617 {"<t>0001-01-01T00:00:00.0000001Z</t>", S_OK, 1, WS_DATETIME_FORMAT_UTC},
3618 {"<t>0001-01-01T00:00:00.9999999Z</t>", S_OK, 0x00098967f, WS_DATETIME_FORMAT_UTC},
3619 {"<t>0001-01-01T00:00:00.0000000Z</t>", S_OK, 0, WS_DATETIME_FORMAT_UTC},
3620 {"<t>0001-01-01T00:00:00.00000001Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3621 {"<t>0001-01-01T00:00:00Z-</t>", WS_E_INVALID_FORMAT, 0},
3622 {"<t>-0001-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3623 {"<t>0001-00-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3624 {"<t>0001-13-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3625 {"<t>0001-12-01T00:00:00Z</t>", S_OK, 0x1067555f88000, WS_DATETIME_FORMAT_UTC},
3626 {"<t>0001-01-00T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3627 {"<t>2001-01-32T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3628 {"<t>2001-01-31T00:00:00Z</t>", S_OK, 0x8c2592fe3794000, WS_DATETIME_FORMAT_UTC},
3629 {"<t>1900-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3630 {"<t>2000-02-29T00:00:00Z</t>", S_OK, 0x8c1505f0e438000, 0},
3631 {"<t>2001-02-29T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3632 {"<t>2001-02-28T00:00:00Z</t>", S_OK, 0x8c26f30870a4000, WS_DATETIME_FORMAT_UTC},
3633 {"<t>0001-00-01U00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3634 {"<t>0001-01-01T24:00:00Z</t>", S_OK, 0xc92a69c000, WS_DATETIME_FORMAT_UTC},
3635 {"<t>0001-01-01T24:00:01Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3636 {"<t>0001-01-01T00:60:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3637 {"<t>0001-01-01T00:00:60Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3638 {"<t>0001-01-01T00:00:00Y</t>", WS_E_INVALID_FORMAT, 0, 0},
3639 {"<t>0001-01-01T00:00:00+00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3640 {"<t>0001-01-01T00:00:00-00:01</t>", S_OK, 0x023c34600, WS_DATETIME_FORMAT_LOCAL},
3641 {"<t>9999-12-31T24:00:00+00:01</t>", S_OK, 0x2bca2875d073fa00, WS_DATETIME_FORMAT_LOCAL},
3642 {"<t>9999-12-31T24:00:00-00:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3643 {"<t>0002-01-01T00:00:00+14:01</t>", WS_E_INVALID_FORMAT, 0, 0},
3644 {"<t>0002-01-01T00:00:00+15:00</t>", WS_E_INVALID_FORMAT, 0, 0},
3645 {"<t>0002-01-01T00:00:00+13:60</t>", WS_E_INVALID_FORMAT, 0, 0},
3646 {"<t>0002-01-01T00:00:00+13:59</t>", S_OK, 0x11e5c43cc5600, WS_DATETIME_FORMAT_LOCAL},
3647 {"<t>0002-01-01T00:00:00+01:00</t>", S_OK, 0x11ec917025800, WS_DATETIME_FORMAT_LOCAL},
3648 {"<t>2016-01-01T00:00:00-01:00</t>", S_OK, 0x8d31246dfbba800, WS_DATETIME_FORMAT_LOCAL},
3649 {"<t>2016-01-01T00:00:00Z</t>", S_OK, 0x8d3123e7df74000, WS_DATETIME_FORMAT_UTC},
3650 {"<t> 2016-01-02T03:04:05Z </t>", S_OK, 0x8d313215fb64080, WS_DATETIME_FORMAT_UTC},
3651 {"<t>+2016-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3652 {"<t></t>", WS_E_INVALID_FORMAT, 0, 0},
3653 {"<t>01-01-01T00:00:00Z</t>", WS_E_INVALID_FORMAT, 0, 0},
3654 {"<t>1601-01-01T00:00:00Z</t>", S_OK, 0x701ce1722770000, WS_DATETIME_FORMAT_UTC},
3656 HRESULT hr;
3657 WS_XML_READER *reader;
3658 WS_HEAP *heap;
3659 WS_DATETIME date;
3660 ULONG i;
3662 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3663 ok( hr == S_OK, "got %#lx\n", hr );
3665 hr = WsCreateReader( NULL, 0, &reader, NULL );
3666 ok( hr == S_OK, "got %#lx\n", hr );
3667 for (i = 0; i < ARRAY_SIZE( tests ); i++)
3669 memset( &date, 0, sizeof(date) );
3670 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3671 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DATETIME_TYPE, NULL,
3672 WS_READ_REQUIRED_VALUE, heap, &date, sizeof(date), NULL );
3673 ok( hr == tests[i].hr, "%lu: got %#lx\n", i, hr );
3674 if (hr == S_OK)
3676 ok( date.ticks == tests[i].ticks, "%lu: got %s\n", i, wine_dbgstr_longlong(date.ticks) );
3677 ok( date.format == tests[i].format, "%lu: got %u\n", i, date.format );
3681 WsFreeReader( reader );
3682 WsFreeHeap( heap );
3685 static void test_WsDateTimeToFileTime(void)
3687 static const struct
3689 WS_DATETIME dt;
3690 HRESULT hr;
3691 FILETIME ft;
3693 tests[] =
3695 { {0, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3696 { {0x701ce172276ffff, WS_DATETIME_FORMAT_UTC}, WS_E_INVALID_FORMAT, {0, 0} },
3697 { {0x701ce1722770000, WS_DATETIME_FORMAT_UTC}, S_OK, {0, 0} },
3698 { {0x2bca2875f4373fff, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c03fff, 0x24c85a5e} },
3699 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_UTC}, S_OK, {0xd1c04000, 0x24c85a5e} },
3700 { {0x2bca2875f4374000, WS_DATETIME_FORMAT_LOCAL}, S_OK, {0xd1c04000, 0x24c85a5e} },
3701 { {~0, WS_DATETIME_FORMAT_UTC}, S_OK, {0xdd88ffff, 0xf8fe31e8} },
3703 WS_DATETIME dt;
3704 FILETIME ft;
3705 HRESULT hr;
3706 ULONG i;
3708 hr = WsDateTimeToFileTime( NULL, NULL, NULL );
3709 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3711 dt.ticks = 0x701ce172277000;
3712 dt.format = WS_DATETIME_FORMAT_UTC;
3713 hr = WsDateTimeToFileTime( &dt, NULL, NULL );
3714 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3716 hr = WsDateTimeToFileTime( NULL, &ft, NULL );
3717 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3719 for (i = 0; i < ARRAY_SIZE( tests ); i++)
3721 memset( &ft, 0, sizeof(ft) );
3722 hr = WsDateTimeToFileTime( &tests[i].dt, &ft, NULL );
3723 ok( hr == tests[i].hr, "%lu: got %#lx\n", i, hr );
3724 if (hr == S_OK)
3726 ok( ft.dwLowDateTime == tests[i].ft.dwLowDateTime, "%lu: got %#lx\n", i, ft.dwLowDateTime );
3727 ok( ft.dwHighDateTime == tests[i].ft.dwHighDateTime, "%lu: got %#lx\n", i, ft.dwHighDateTime );
3732 static void test_WsFileTimeToDateTime(void)
3734 WS_DATETIME dt;
3735 FILETIME ft;
3736 HRESULT hr;
3738 hr = WsFileTimeToDateTime( NULL, NULL, NULL );
3739 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3741 ft.dwLowDateTime = ft.dwHighDateTime = 0;
3742 hr = WsFileTimeToDateTime( &ft, NULL, NULL );
3743 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3745 hr = WsFileTimeToDateTime( NULL, &dt, NULL );
3746 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3748 dt.ticks = 0xdeadbeef;
3749 dt.format = 0xdeadbeef;
3750 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3751 ok( hr == S_OK, "got %#lx\n", hr );
3752 ok( dt.ticks == 0x701ce1722770000, "got %s\n", wine_dbgstr_longlong(dt.ticks) );
3753 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3755 ft.dwLowDateTime = 0xd1c03fff;
3756 ft.dwHighDateTime = 0x24c85a5e;
3757 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3758 ok( hr == S_OK, "got %#lx\n", hr );
3759 ok( dt.ticks == 0x2bca2875f4373fff, "got %s\n", wine_dbgstr_longlong(dt.ticks) );
3760 ok( dt.format == WS_DATETIME_FORMAT_UTC, "got %u\n", dt.format );
3762 ft.dwLowDateTime++;
3763 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3764 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
3766 ft.dwLowDateTime = 0xdd88ffff;
3767 ft.dwHighDateTime = 0xf8fe31e8;
3768 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3769 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
3771 ft.dwLowDateTime++;
3772 hr = WsFileTimeToDateTime( &ft, &dt, NULL );
3773 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %#lx\n", hr );
3776 static void test_double(void)
3778 static const struct
3780 const char *str;
3781 HRESULT hr;
3782 ULONGLONG val;
3784 tests[] =
3786 {"<t>0.0</t>", S_OK, 0},
3787 {"<t>-0.0</t>", S_OK, 0x8000000000000000},
3788 {"<t>+0.0</t>", S_OK, 0},
3789 {"<t>-</t>", S_OK, 0},
3790 {"<t>-.</t>", S_OK, 0},
3791 {"<t>+</t>", S_OK, 0},
3792 {"<t>+.</t>", S_OK, 0},
3793 {"<t>.</t>", S_OK, 0},
3794 {"<t>.0</t>", S_OK, 0},
3795 {"<t>0.</t>", S_OK, 0},
3796 {"<t>0</t>", S_OK, 0},
3797 {"<t> 0 </t>", S_OK, 0},
3798 {"<t></t>", WS_E_INVALID_FORMAT, 0},
3799 {"<t>0,1</t>", WS_E_INVALID_FORMAT, 0},
3800 {"<t>1.1.</t>", WS_E_INVALID_FORMAT, 0},
3801 {"<t>1</t>", S_OK, 0x3ff0000000000000},
3802 {"<t>1.0000000000000002</t>", S_OK, 0x3ff0000000000001},
3803 {"<t>1.0000000000000004</t>", S_OK, 0x3ff0000000000002},
3804 {"<t>10000000000000000000</t>", S_OK, 0x43e158e460913d00},
3805 {"<t>100000000000000000000</t>", S_OK, 0x4415af1d78b58c40},
3806 {"<t>2</t>", S_OK, 0x4000000000000000},
3807 {"<t>-2</t>", S_OK, 0xc000000000000000},
3808 {"<t>nodouble</t>", WS_E_INVALID_FORMAT, 0},
3809 {"<t>INF</t>", S_OK, 0x7ff0000000000000},
3810 {"<t>-INF</t>", S_OK, 0xfff0000000000000},
3811 {"<t>+INF</t>", WS_E_INVALID_FORMAT, 0},
3812 {"<t>Infinity</t>", WS_E_INVALID_FORMAT, 0},
3813 {"<t>-Infinity</t>", WS_E_INVALID_FORMAT, 0},
3814 {"<t>inf</t>", WS_E_INVALID_FORMAT, 0},
3815 {"<t>NaN</t>", S_OK, 0xfff8000000000000},
3816 {"<t>-NaN</t>", WS_E_INVALID_FORMAT, 0},
3817 {"<t>NAN</t>", WS_E_INVALID_FORMAT, 0},
3818 {"<t>0.3</t>", S_OK, 0x3fd3333333333333},
3819 {"<t>0.33</t>", S_OK, 0x3fd51eb851eb851f},
3820 {"<t>0.333</t>", S_OK, 0x3fd54fdf3b645a1d},
3821 {"<t>0.3333</t>", S_OK, 0x3fd554c985f06f69},
3822 {"<t>0.33333</t>", S_OK, 0x3fd555475a31a4be},
3823 {"<t>0.333333</t>", S_OK, 0x3fd55553ef6b5d46},
3824 {"<t>0.3333333</t>", S_OK, 0x3fd55555318abc87},
3825 {"<t>0.33333333</t>", S_OK, 0x3fd5555551c112da},
3826 {"<t>0.333333333</t>", S_OK, 0x3fd5555554f9b516},
3827 {"<t>0.3333333333</t>", S_OK, 0x3fd55555554c2bb5},
3828 {"<t>0.33333333333</t>", S_OK, 0x3fd5555555546ac5},
3829 {"<t>0.3333333333333</t>", S_OK, 0x3fd55555555552fd},
3830 {"<t>0.33333333333333</t>", S_OK, 0x3fd5555555555519},
3831 {"<t>0.333333333333333</t>", S_OK, 0x3fd555555555554f},
3832 {"<t>0.3333333333333333</t>", S_OK, 0x3fd5555555555555},
3833 {"<t>0.33333333333333333</t>", S_OK, 0x3fd5555555555555},
3834 {"<t>0.1e10</t>", S_OK, 0x41cdcd6500000000},
3835 {"<t>1e</t>", WS_E_INVALID_FORMAT, 0},
3836 {"<t>1e0</t>", S_OK, 0x3ff0000000000000},
3837 {"<t>1e+1</t>", S_OK, 0x4024000000000000},
3838 {"<t>1e-1</t>", S_OK, 0x3fb999999999999a},
3839 {"<t>e10</t>", WS_E_INVALID_FORMAT, 0},
3840 {"<t>1e10.</t>", WS_E_INVALID_FORMAT, 0},
3841 {"<t>1E10</t>", S_OK, 0x4202a05f20000000},
3842 {"<t>1e10</t>", S_OK, 0x4202a05f20000000},
3843 {"<t>1e-10</t>", S_OK, 0x3ddb7cdfd9d7bdbb},
3844 {"<t>1.7976931348623158e308</t>", S_OK, 0x7fefffffffffffff},
3845 {"<t>1.7976931348623159e308</t>", S_OK, 0x7ff0000000000000},
3846 {"<t>4.94065645841247e-324</t>", S_OK, 0x1},
3848 HRESULT hr;
3849 WS_XML_READER *reader;
3850 WS_HEAP *heap;
3851 ULONGLONG val;
3852 ULONG i;
3854 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
3855 ok( hr == S_OK, "got %#lx\n", hr );
3857 hr = WsCreateReader( NULL, 0, &reader, NULL );
3858 ok( hr == S_OK, "got %#lx\n", hr );
3860 for (i = 0; i < ARRAY_SIZE( tests ); i++)
3862 val = 0;
3863 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
3864 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DOUBLE_TYPE, NULL,
3865 WS_READ_REQUIRED_VALUE, heap, &val, sizeof(val), NULL );
3866 ok( hr == tests[i].hr, "%lu: got %#lx\n", i, hr );
3867 if (hr == tests[i].hr) ok( val == tests[i].val, "%lu: got %s\n", i, wine_dbgstr_longlong(val) );
3870 WsFreeReader( reader );
3871 WsFreeHeap( heap );
3874 static void test_WsReadElement(void)
3876 WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
3877 HRESULT hr;
3878 WS_XML_READER *reader;
3879 WS_ELEMENT_DESCRIPTION desc;
3880 UINT32 val;
3882 hr = WsCreateReader( NULL, 0, &reader, NULL );
3883 ok( hr == S_OK, "got %#lx\n", hr );
3885 desc.elementLocalName = &localname;
3886 desc.elementNs = &ns;
3887 desc.type = WS_UINT32_TYPE;
3888 desc.typeDescription = NULL;
3890 prepare_struct_type_test( reader, "<t>1</t>" );
3891 hr = WsReadElement( NULL, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3892 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3894 prepare_struct_type_test( reader, "<t>1</t>" );
3895 hr = WsReadElement( reader, NULL, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3896 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3898 prepare_struct_type_test( reader, "<t>1</t>" );
3899 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, NULL, sizeof(val), NULL );
3900 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3902 prepare_struct_type_test( reader, "<t>1</t>" );
3903 val = 0xdeadbeef;
3904 hr = WsReadElement( reader, &desc, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL );
3905 ok( hr == S_OK, "got %#lx\n", hr );
3906 ok( val == 1, "got %u\n", val );
3908 WsFreeReader( reader );
3911 static void test_WsReadValue(void)
3913 HRESULT hr;
3914 WS_XML_READER *reader;
3915 UINT32 val;
3917 hr = WsCreateReader( NULL, 0, &reader, NULL );
3918 ok( hr == S_OK, "got %#lx\n", hr );
3920 prepare_struct_type_test( reader, "<t>1</t>" );
3921 hr = WsReadValue( NULL, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3922 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3924 prepare_struct_type_test( reader, "<t>1</t>" );
3925 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, NULL, sizeof(val), NULL );
3926 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3928 /* reader must be positioned correctly */
3929 prepare_struct_type_test( reader, "<t>1</t>" );
3930 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3931 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
3933 prepare_struct_type_test( reader, "<t>1</t>" );
3934 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3935 ok( hr == S_OK, "got %#lx\n", hr );
3937 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3938 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
3940 prepare_struct_type_test( reader, "<t>1</t>" );
3941 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3942 ok( hr == S_OK, "got %#lx\n", hr );
3944 hr = WsReadStartElement( reader, NULL );
3945 ok( hr == S_OK, "got %#lx\n", hr );
3947 val = 0xdeadbeef;
3948 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3949 ok( hr == S_OK, "got %#lx\n", hr );
3950 ok( val == 1, "got %u\n", val );
3952 prepare_struct_type_test( reader, "<u t='1'></u>" );
3953 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
3954 ok( hr == S_OK, "got %#lx\n", hr );
3956 hr = WsReadValue( reader, WS_UINT32_VALUE_TYPE, &val, sizeof(val), NULL );
3957 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
3959 WsFreeReader( reader );
3962 static void test_WsResetError(void)
3964 WS_ERROR_PROPERTY prop;
3965 ULONG size, code, count;
3966 WS_ERROR *error;
3967 LANGID langid;
3968 WS_STRING str;
3969 WS_FAULT fault;
3970 WS_XML_STRING xmlstr;
3971 WS_FAULT *faultp;
3972 HRESULT hr;
3974 hr = WsResetError( NULL );
3975 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
3977 error = NULL;
3978 hr = WsCreateError( NULL, 0, &error );
3979 ok( hr == S_OK, "got %#lx\n", hr );
3980 ok( error != NULL, "error not set\n" );
3982 code = 0xdeadbeef;
3983 size = sizeof(code);
3984 hr = WsSetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3985 ok( hr == S_OK, "got %#lx\n", hr );
3987 hr = WsResetError( error );
3988 ok( hr == S_OK, "got %#lx\n", hr );
3990 code = 0xdeadbeef;
3991 size = sizeof(code);
3992 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, size );
3993 ok( hr == S_OK, "got %#lx\n", hr );
3994 ok( !code, "got %lu\n", code );
3996 WsFreeError( error );
3998 langid = MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT );
3999 prop.id = WS_ERROR_PROPERTY_LANGID;
4000 prop.value = &langid;
4001 prop.valueSize = sizeof(langid);
4002 hr = WsCreateError( &prop, 1, &error );
4003 ok( hr == S_OK, "got %#lx\n", hr );
4005 langid = 0xdead;
4006 size = sizeof(langid);
4007 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
4008 ok( hr == S_OK, "got %#lx\n", hr );
4009 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
4011 hr = WsResetError( error );
4012 ok( hr == S_OK, "got %#lx\n", hr );
4014 langid = 0xdead;
4015 size = sizeof(langid);
4016 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_LANGID, &langid, size );
4017 ok( hr == S_OK, "got %#lx\n", hr );
4018 ok( langid == MAKELANGID( LANG_DUTCH, SUBLANG_DEFAULT ), "got %u\n", langid );
4020 WsFreeError( error );
4022 str.chars = (WCHAR *) L"str";
4023 str.length = 3;
4025 hr = WsCreateError( NULL, 0, &error );
4026 ok( hr == S_OK, "got %#lx\n", hr );
4028 hr = WsAddErrorString(error, &str );
4029 ok( hr == S_OK, "got %#lx\n", hr );
4030 hr = WsAddErrorString(error, &str );
4031 ok( hr == S_OK, "got %#lx\n", hr );
4033 count = 0xdeadbeef;
4034 size = sizeof(count);
4035 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
4036 ok( hr == S_OK, "got %#lx\n", hr );
4037 ok( count == 2, "got %lu\n", count );
4039 hr = WsResetError( error );
4040 ok( hr == S_OK, "got %#lx\n", hr );
4042 count = 0xdeadbeef;
4043 size = sizeof(count);
4044 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, size );
4045 ok( hr == S_OK, "got %#lx\n", hr );
4046 ok( count == 0, "got %lu\n", count );
4048 WsFreeError( error );
4050 memset( &fault, 0, sizeof(fault) );
4051 memset( &xmlstr, 0, sizeof(xmlstr) );
4052 xmlstr.bytes = (BYTE *)"str";
4053 xmlstr.length = 3;
4055 hr = WsCreateError( NULL, 0, &error );
4056 ok( hr == S_OK, "got %#lx\n", hr );
4058 hr = WsSetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_FAULT, &fault, sizeof(fault) );
4059 ok( hr == S_OK, "got %#lx\n", hr );
4060 hr = WsSetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_ACTION, &xmlstr, sizeof(xmlstr) );
4061 ok( hr == S_OK, "got %#lx\n", hr );
4063 hr = WsResetError( error );
4064 ok( hr == S_OK, "got %#lx\n", hr );
4066 faultp = (WS_FAULT *)0xdeadbeef;
4067 hr = WsGetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_FAULT, &faultp, sizeof(faultp) );
4068 ok( hr == S_OK, "got %#lx\n", hr );
4069 ok( faultp == NULL, "faultp != NULL\n" );
4071 xmlstr.length = 0xdeadbeef;
4072 xmlstr.bytes = (BYTE *)0xdeadbeef;
4073 hr = WsGetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_ACTION, &xmlstr, sizeof(xmlstr) );
4074 ok( hr == S_OK, "got %#lx\n", hr );
4075 ok( xmlstr.length == 0, "got %lu\n", xmlstr.length );
4077 WsFreeError( error );
4080 static void test_WsGetReaderPosition(void)
4082 WS_HEAP *heap;
4083 WS_XML_READER *reader;
4084 WS_XML_BUFFER *buffer;
4085 WS_XML_NODE_POSITION pos;
4086 HRESULT hr;
4088 hr = WsGetReaderPosition( NULL, NULL, NULL );
4089 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4091 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
4092 ok( hr == S_OK, "got %#lx\n", hr );
4094 hr = WsCreateReader( NULL, 0, &reader, NULL );
4095 ok( hr == S_OK, "got %#lx\n", hr );
4097 /* reader must be set to an XML buffer */
4098 hr = WsGetReaderPosition( reader, &pos, NULL );
4099 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
4101 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4102 ok( hr == S_OK, "got %#lx\n", hr );
4104 hr = WsGetReaderPosition( reader, &pos, NULL );
4105 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
4107 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
4108 ok( hr == S_OK, "got %#lx\n", hr );
4110 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
4111 ok( hr == S_OK, "got %#lx\n", hr );
4113 hr = WsGetReaderPosition( reader, NULL, NULL );
4114 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4116 pos.buffer = pos.node = NULL;
4117 hr = WsGetReaderPosition( reader, &pos, NULL );
4118 ok( hr == S_OK, "got %#lx\n", hr );
4119 ok( pos.buffer != NULL, "buffer not set\n" );
4120 ok( pos.node != NULL, "node not set\n" );
4122 WsFreeReader( reader );
4123 WsFreeHeap( heap );
4126 static void test_WsSetReaderPosition(void)
4128 WS_HEAP *heap;
4129 WS_XML_READER *reader;
4130 WS_XML_BUFFER *buf1, *buf2;
4131 WS_XML_NODE_POSITION pos;
4132 HRESULT hr;
4134 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
4135 ok( hr == S_OK, "got %#lx\n", hr );
4137 hr = WsSetReaderPosition( NULL, NULL, NULL );
4138 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4140 hr = WsCreateReader( NULL, 0, &reader, NULL );
4141 ok( hr == S_OK, "got %#lx\n", hr );
4143 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf1, NULL );
4144 ok( hr == S_OK, "got %#lx\n", hr );
4146 hr = WsSetInputToBuffer( reader, buf1, NULL, 0, NULL );
4147 ok( hr == S_OK, "got %#lx\n", hr );
4149 hr = WsSetReaderPosition( reader, NULL, NULL );
4150 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4152 pos.buffer = pos.node = NULL;
4153 hr = WsGetReaderPosition( reader, &pos, NULL );
4154 ok( hr == S_OK, "got %#lx\n", hr );
4155 ok( pos.buffer == buf1, "wrong buffer\n" );
4156 ok( pos.node != NULL, "node not set\n" );
4158 hr = WsSetReaderPosition( reader, &pos, NULL );
4159 ok( hr == S_OK, "got %#lx\n", hr );
4161 /* different buffer */
4162 hr = WsCreateXmlBuffer( heap, NULL, 0, &buf2, NULL );
4163 ok( hr == S_OK, "got %#lx\n", hr );
4165 pos.buffer = buf2;
4166 hr = WsSetReaderPosition( reader, &pos, NULL );
4167 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4169 WsFreeReader( reader );
4170 WsFreeHeap( heap );
4173 static void test_entities(void)
4175 static const char str1[] = "<t>&#xA</t>";
4176 static const char str2[] = "<t>&#xA;</t>";
4177 static const char str3[] = "<t>&#xa;</t>";
4178 static const char str4[] = "<t>&#xaaaa;</t>";
4179 static const char str5[] = "<t>&#xaaaaa;</t>";
4180 static const char str6[] = "<t>&1</t>";
4181 static const char str7[] = "<t>&1;</t>";
4182 static const char str8[] = "<t>&1111;</t>";
4183 static const char str9[] = "<t>&11111;</t>";
4184 static const char str10[] = "<t>&lt;</t>";
4185 static const char str11[] = "<t>&gt;</t>";
4186 static const char str12[] = "<t>&quot;</t>";
4187 static const char str13[] = "<t>&amp;</t>";
4188 static const char str14[] = "<t>&apos;</t>";
4189 static const char str15[] = "<t>&sopa;</t>";
4190 static const char str16[] = "<t>&#;</t>";
4191 static const char str17[] = "<t>&;</t>";
4192 static const char str18[] = "<t>&&</t>";
4193 static const char str19[] = "<t>&</t>";
4194 static const char str20[] = "<t>&#xaaaaaa;</t>";
4195 static const char str21[] = "<t>&#xd7ff;</t>";
4196 static const char str22[] = "<t>&#xd800;</t>";
4197 static const char str23[] = "<t>&#xdfff;</t>";
4198 static const char str24[] = "<t>&#xe000;</t>";
4199 static const char str25[] = "<t>&#xfffe;</t>";
4200 static const char str26[] = "<t>&#xffff;</t>";
4201 static const char str27[] = "<t>&LT;</t>";
4202 static const char str28[] = "<t>&#x0;</t>";
4203 static const char str29[] = "<t>&#0;</t>";
4204 static const char str30[] = "<t>&#65;</t>";
4205 static const char str31[] = "<t>&#65393;</t>";
4206 static const char str32[] = "<t>&#x10ffff;</t>";
4207 static const char str33[] = "<t>&#x110000;</t>";
4208 static const char str34[] = "<t>&#1114111;</t>";
4209 static const char str35[] = "<t>&#1114112;</t>";
4210 static const char res4[] = {0xea, 0xaa, 0xaa, 0x00};
4211 static const char res5[] = {0xf2, 0xaa, 0xaa, 0xaa, 0x00};
4212 static const char res21[] = {0xed, 0x9f, 0xbf, 0x00};
4213 static const char res24[] = {0xee, 0x80, 0x80, 0x00};
4214 static const char res31[] = {0xef, 0xbd, 0xb1, 0x00};
4215 static const char res32[] = {0xf4, 0x8f, 0xbf, 0xbf, 0x00};
4216 static const struct
4218 const char *str;
4219 HRESULT hr;
4220 const char *res;
4222 tests[] =
4224 { str1, WS_E_INVALID_FORMAT },
4225 { str2, S_OK, "\n" },
4226 { str3, S_OK, "\n" },
4227 { str4, S_OK, res4 },
4228 { str5, S_OK, res5 },
4229 { str6, WS_E_INVALID_FORMAT },
4230 { str7, WS_E_INVALID_FORMAT },
4231 { str8, WS_E_INVALID_FORMAT },
4232 { str9, WS_E_INVALID_FORMAT },
4233 { str10, S_OK, "<" },
4234 { str11, S_OK, ">" },
4235 { str12, S_OK, "\"" },
4236 { str13, S_OK, "&" },
4237 { str14, S_OK, "'" },
4238 { str15, WS_E_INVALID_FORMAT },
4239 { str16, WS_E_INVALID_FORMAT },
4240 { str17, WS_E_INVALID_FORMAT },
4241 { str18, WS_E_INVALID_FORMAT },
4242 { str19, WS_E_INVALID_FORMAT },
4243 { str20, WS_E_INVALID_FORMAT },
4244 { str21, S_OK, res21 },
4245 { str22, WS_E_INVALID_FORMAT },
4246 { str23, WS_E_INVALID_FORMAT },
4247 { str24, S_OK, res24 },
4248 { str25, WS_E_INVALID_FORMAT },
4249 { str26, WS_E_INVALID_FORMAT },
4250 { str27, WS_E_INVALID_FORMAT },
4251 { str28, WS_E_INVALID_FORMAT },
4252 { str29, WS_E_INVALID_FORMAT },
4253 { str30, S_OK, "A" },
4254 { str31, S_OK, res31 },
4255 { str32, S_OK, res32 },
4256 { str33, WS_E_INVALID_FORMAT },
4257 { str34, S_OK, res32 },
4258 { str35, WS_E_INVALID_FORMAT },
4260 HRESULT hr;
4261 WS_XML_READER *reader;
4262 const WS_XML_NODE *node;
4263 const WS_XML_UTF8_TEXT *utf8;
4264 ULONG i;
4266 hr = WsCreateReader( NULL, 0, &reader, NULL );
4267 ok( hr == S_OK, "got %#lx\n", hr );
4269 for (i = 0; i < ARRAY_SIZE( tests ); i++)
4271 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
4272 ok( hr == S_OK, "%lu: got %#lx\n", i, hr );
4274 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4275 ok( hr == S_OK, "%lu: got %#lx\n", i, hr );
4277 hr = WsReadNode( reader, NULL );
4278 ok( hr == tests[i].hr, "%lu: got %#lx\n", i, hr );
4279 if (hr != S_OK) continue;
4281 hr = WsGetReaderNode( reader, &node, NULL );
4282 ok( hr == S_OK, "%lu: got %#lx\n", i, hr );
4284 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_TEXT_NODE *)node)->text;
4285 ok( utf8->value.length == strlen(tests[i].res), "%lu: got %lu\n", i, utf8->value.length );
4286 ok( !memcmp( utf8->value.bytes, tests[i].res, strlen(tests[i].res) ), "%lu: wrong data\n", i );
4289 hr = set_input( reader, "<t a='&#xA;&#xA;'/>", sizeof("<t a='&#xA;&#xA;'/>") - 1 );
4290 ok( hr == S_OK, "got %#lx\n", hr );
4292 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4293 ok( hr == S_OK, "got %#lx\n", hr );
4295 hr = WsGetReaderNode( reader, &node, NULL );
4296 ok( hr == S_OK, "got %#lx\n", hr );
4298 utf8 = (const WS_XML_UTF8_TEXT *)((const WS_XML_ELEMENT_NODE *)node)->attributes[0]->value;
4299 ok( utf8->value.length == 2, "got %lu\n", utf8->value.length );
4300 ok( !memcmp( utf8->value.bytes, "\n\n", 2 ), "wrong data\n" );
4302 WsFreeReader( reader );
4305 static void test_field_options(void)
4307 static const char xml[] =
4308 "<t xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><wsz i:nil=\"true\"/>"
4309 "<s i:nil=\"true\"/></t>";
4310 HRESULT hr;
4311 WS_HEAP *heap;
4312 WS_XML_READER *reader;
4313 WS_STRUCT_DESCRIPTION s, s2;
4314 WS_FIELD_DESCRIPTION f, f2, f3, f4, f5, *fields[4], *fields2[1];
4315 WS_XML_STRING ns = {0, NULL}, str_wsz = {3, (BYTE *)"wsz"}, str_s = {1, (BYTE *)"s"};
4316 WS_XML_STRING str_int32 = {5, (BYTE *)"int32"}, str_guid = {4, (BYTE *)"guid"};
4317 WS_DEFAULT_VALUE def_val;
4318 INT32 val_int32;
4319 struct s
4321 INT32 int32;
4323 struct test
4325 WCHAR *wsz;
4326 struct s *s;
4327 INT32 int32;
4328 GUID guid;
4329 } *test;
4331 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
4332 ok( hr == S_OK, "got %#lx\n", hr );
4334 hr = WsCreateReader( NULL, 0, &reader, NULL );
4335 ok( hr == S_OK, "got %#lx\n", hr );
4337 hr = set_input( reader, xml, sizeof(xml) - 1 );
4338 ok( hr == S_OK, "got %#lx\n", hr );
4340 memset( &f, 0, sizeof(f) );
4341 f.mapping = WS_ELEMENT_FIELD_MAPPING;
4342 f.localName = &str_wsz;
4343 f.ns = &ns;
4344 f.type = WS_WSZ_TYPE;
4345 f.options = WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
4346 fields[0] = &f;
4348 memset( &f3, 0, sizeof(f3) );
4349 f3.mapping = WS_ELEMENT_FIELD_MAPPING;
4350 f3.localName = &str_int32;
4351 f3.ns = &ns;
4352 f3.type = WS_INT32_TYPE;
4353 fields2[0] = &f3;
4355 memset( &s2, 0, sizeof(s2) );
4356 s2.size = sizeof(struct s);
4357 s2.alignment = TYPE_ALIGNMENT(struct s);
4358 s2.fields = fields2;
4359 s2.fieldCount = 1;
4361 memset( &f2, 0, sizeof(f2) );
4362 f2.mapping = WS_ELEMENT_FIELD_MAPPING;
4363 f2.localName = &str_s;
4364 f2.ns = &ns;
4365 f2.type = WS_STRUCT_TYPE;
4366 f2.typeDescription = &s2;
4367 f2.offset = FIELD_OFFSET(struct test, s);
4368 f2.options = WS_FIELD_POINTER|WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE;
4369 fields[1] = &f2;
4371 val_int32 = -1;
4372 def_val.value = &val_int32;
4373 def_val.valueSize = sizeof(val_int32);
4375 memset( &f4, 0, sizeof(f4) );
4376 f4.mapping = WS_ELEMENT_FIELD_MAPPING;
4377 f4.localName = &str_int32;
4378 f4.ns = &ns;
4379 f4.type = WS_INT32_TYPE;
4380 f4.offset = FIELD_OFFSET(struct test, int32);
4381 f4.options = WS_FIELD_OPTIONAL;
4382 f4.defaultValue = &def_val;
4383 fields[2] = &f4;
4385 memset( &f5, 0, sizeof(f5) );
4386 f5.mapping = WS_ELEMENT_FIELD_MAPPING;
4387 f5.localName = &str_guid;
4388 f5.ns = &ns;
4389 f5.type = WS_GUID_TYPE;
4390 f5.offset = FIELD_OFFSET(struct test, guid);
4391 f5.options = WS_FIELD_OPTIONAL;
4392 fields[3] = &f5;
4394 memset( &s, 0, sizeof(s) );
4395 s.size = sizeof(struct test);
4396 s.alignment = TYPE_ALIGNMENT(struct test);
4397 s.fields = fields;
4398 s.fieldCount = 4;
4400 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
4401 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
4402 ok( hr == S_OK, "got %#lx\n", hr );
4403 ok( !test->wsz, "wsz is set\n" );
4404 ok( !test->s, "s is set\n" );
4405 ok( test->int32 == -1, "got %d\n", test->int32 );
4406 ok( IsEqualGUID( &test->guid, &guid_null ), "wrong guid\n" );
4408 WsFreeReader( reader );
4409 WsFreeHeap( heap );
4412 static void test_WsReadBytes(void)
4414 HRESULT hr;
4415 WS_XML_READER *reader;
4416 const WS_XML_NODE *node;
4417 const WS_XML_TEXT_NODE *text;
4418 const WS_XML_UTF8_TEXT *utf8;
4419 BYTE buf[4];
4420 ULONG count;
4422 hr = WsCreateReader( NULL, 0, &reader, NULL );
4423 ok( hr == S_OK, "got %#lx\n", hr );
4425 hr = WsReadBytes( NULL, NULL, 0, NULL, NULL );
4426 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4428 hr = WsReadBytes( reader, NULL, 0, NULL, NULL );
4429 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
4431 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
4432 ok( hr == S_OK, "got %#lx\n", hr );
4434 hr = WsReadBytes( reader, NULL, 0, NULL, NULL );
4435 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4437 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
4438 ok( hr == S_OK, "got %#lx\n", hr );
4440 hr = WsReadBytes( reader, buf, 0, NULL, NULL );
4441 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4443 hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 );
4444 ok( hr == S_OK, "got %#lx\n", hr );
4446 count = 0xdeadbeef;
4447 hr = WsReadBytes( reader, NULL, 0, &count, NULL );
4448 ok( hr == S_OK, "got %#lx\n", hr );
4449 ok( !count, "got %lu\n", count );
4451 count = 0xdeadbeef;
4452 hr = WsReadBytes( reader, NULL, 1, &count, NULL );
4453 ok( hr == S_OK, "got %#lx\n", hr );
4454 ok( !count, "got %lu\n", count );
4456 buf[0] = 0;
4457 count = 0xdeadbeef;
4458 hr = WsReadBytes( reader, buf, 0, &count, NULL );
4459 ok( hr == S_OK, "got %#lx\n", hr );
4460 ok( !count, "got %lu\n", count );
4461 ok( !buf[0], "wrong data\n" );
4463 buf[0] = 0;
4464 count = 0xdeadbeef;
4465 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4466 ok( hr == S_OK, "got %#lx\n", hr );
4467 ok( !count, "got %lu\n", count );
4468 ok( !buf[0], "wrong data\n" );
4470 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4471 ok( hr == S_OK, "got %#lx\n", hr );
4473 buf[0] = 0;
4474 count = 0xdeadbeef;
4475 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4476 ok( hr == S_OK, "got %#lx\n", hr );
4477 ok( !count, "got %lu\n", count );
4478 ok( !buf[0], "wrong data\n" );
4480 hr = WsReadStartElement( reader, NULL );
4481 ok( hr == S_OK, "got %#lx\n", hr );
4483 count = 0xdeadbeef;
4484 hr = WsReadBytes( reader, NULL, 0, &count, NULL );
4485 ok( hr == S_OK, "got %#lx\n", hr );
4486 ok( !count, "got %lu\n", count );
4488 buf[0] = 0;
4489 count = 0xdeadbeef;
4490 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4491 ok( hr == S_OK, "got %#lx\n", hr );
4492 ok( count == 2, "got %lu\n", count );
4493 ok( !memcmp( buf, "te", 2 ), "wrong data\n" );
4495 hr = WsGetReaderNode( reader, &node, NULL );
4496 ok( hr == S_OK, "got %#lx\n", hr );
4497 text = (const WS_XML_TEXT_NODE *)node;
4498 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4499 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4500 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4501 ok( utf8->value.length == 8, "got %lu\n", utf8->value.length );
4502 ok( !memcmp( utf8->value.bytes, "dGV4dA==", 8 ), "wrong data\n" );
4504 buf[0] = 0;
4505 count = 0xdeadbeef;
4506 hr = WsReadBytes( reader, buf, 2, &count, NULL );
4507 ok( hr == S_OK, "got %#lx\n", hr );
4508 ok( count == 2, "got %lu\n", count );
4509 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4511 hr = WsGetReaderNode( reader, &node, NULL );
4512 ok( hr == S_OK, "got %#lx\n", hr );
4513 text = (const WS_XML_TEXT_NODE *)node;
4514 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4516 count = 0xdeadbeef;
4517 hr = WsReadBytes( reader, buf, 1, &count, NULL );
4518 ok( hr == S_OK, "got %#lx\n", hr );
4519 ok( !count, "got %lu\n", count );
4521 hr = WsGetReaderNode( reader, &node, NULL );
4522 ok( hr == S_OK, "got %#lx\n", hr );
4523 text = (const WS_XML_TEXT_NODE *)node;
4524 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4526 WsFreeReader( reader );
4529 static void test_WsReadChars(void)
4531 HRESULT hr;
4532 WS_XML_READER *reader;
4533 const WS_XML_NODE *node;
4534 const WS_XML_TEXT_NODE *text;
4535 const WS_XML_UTF8_TEXT *utf8;
4536 unsigned char buf[4];
4537 WCHAR bufW[4];
4538 ULONG count;
4540 hr = WsCreateReader( NULL, 0, &reader, NULL );
4541 ok( hr == S_OK, "got %#lx\n", hr );
4543 hr = WsReadChars( NULL, NULL, 0, NULL, NULL );
4544 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4546 hr = WsReadChars( reader, NULL, 0, NULL, NULL );
4547 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
4549 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4550 ok( hr == S_OK, "got %#lx\n", hr );
4552 hr = WsReadChars( reader, NULL, 0, NULL, NULL );
4553 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4555 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4556 ok( hr == S_OK, "got %#lx\n", hr );
4558 hr = WsReadChars( reader, bufW, 0, NULL, NULL );
4559 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4561 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4562 ok( hr == S_OK, "got %#lx\n", hr );
4564 count = 0xdeadbeef;
4565 hr = WsReadChars( reader, NULL, 0, &count, NULL );
4566 ok( hr == S_OK, "got %#lx\n", hr );
4567 ok( !count, "got %lu\n", count );
4569 count = 0xdeadbeef;
4570 hr = WsReadChars( reader, NULL, 1, &count, NULL );
4571 ok( hr == S_OK, "got %#lx\n", hr );
4572 ok( !count, "got %lu\n", count );
4574 buf[0] = 0;
4575 count = 0xdeadbeef;
4576 hr = WsReadChars( reader, bufW, 0, &count, NULL );
4577 ok( hr == S_OK, "got %#lx\n", hr );
4578 ok( !count, "got %lu\n", count );
4579 ok( !buf[0], "wrong data\n" );
4581 buf[0] = 0;
4582 count = 0xdeadbeef;
4583 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4584 ok( hr == S_OK, "got %#lx\n", hr );
4585 ok( !count, "got %lu\n", count );
4586 ok( !buf[0], "wrong data\n" );
4588 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4589 ok( hr == S_OK, "got %#lx\n", hr );
4591 buf[0] = 0;
4592 count = 0xdeadbeef;
4593 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4594 ok( hr == S_OK, "got %#lx\n", hr );
4595 ok( !count, "got %lu\n", count );
4596 ok( !buf[0], "wrong data\n" );
4598 hr = WsReadStartElement( reader, NULL );
4599 ok( hr == S_OK, "got %#lx\n", hr );
4601 count = 0xdeadbeef;
4602 hr = WsReadChars( reader, NULL, 0, &count, NULL );
4603 ok( hr == S_OK, "got %#lx\n", hr );
4604 ok( !count, "got %lu\n", count );
4606 buf[0] = 0;
4607 count = 0xdeadbeef;
4608 hr = WsReadChars( reader, bufW, 2, &count, NULL );
4609 ok( hr == S_OK, "got %#lx\n", hr );
4610 ok( count == 2, "got %lu\n", count );
4611 ok( !memcmp( bufW, L"te", 2 * sizeof(WCHAR) ), "wrong data\n" );
4613 hr = WsGetReaderNode( reader, &node, NULL );
4614 ok( hr == S_OK, "got %#lx\n", hr );
4615 text = (const WS_XML_TEXT_NODE *)node;
4616 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4617 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4618 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4619 ok( utf8->value.length == 4, "got %lu\n", utf8->value.length );
4620 ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" );
4622 /* continue reading in a different encoding */
4623 buf[0] = 0;
4624 count = 0xdeadbeef;
4625 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4626 ok( hr == S_OK, "got %#lx\n", hr );
4627 ok( count == 2, "got %lu\n", count );
4628 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4630 hr = WsGetReaderNode( reader, &node, NULL );
4631 ok( hr == S_OK, "got %#lx\n", hr );
4632 text = (const WS_XML_TEXT_NODE *)node;
4633 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4635 count = 0xdeadbeef;
4636 hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL );
4637 ok( hr == S_OK, "got %#lx\n", hr );
4638 ok( !count, "got %lu\n", count );
4640 hr = WsGetReaderNode( reader, &node, NULL );
4641 ok( hr == S_OK, "got %#lx\n", hr );
4642 text = (const WS_XML_TEXT_NODE *)node;
4643 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4645 WsFreeReader( reader );
4648 static void test_WsReadCharsUtf8(void)
4650 HRESULT hr;
4651 WS_XML_READER *reader;
4652 const WS_XML_NODE *node;
4653 const WS_XML_TEXT_NODE *text;
4654 const WS_XML_UTF8_TEXT *utf8;
4655 BYTE buf[4];
4656 ULONG count;
4658 hr = WsCreateReader( NULL, 0, &reader, NULL );
4659 ok( hr == S_OK, "got %#lx\n", hr );
4661 hr = WsReadCharsUtf8( NULL, NULL, 0, NULL, NULL );
4662 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4664 hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL );
4665 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
4667 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4668 ok( hr == S_OK, "got %#lx\n", hr );
4670 hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL );
4671 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4673 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4674 ok( hr == S_OK, "got %#lx\n", hr );
4676 hr = WsReadCharsUtf8( reader, buf, 0, NULL, NULL );
4677 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4679 hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 );
4680 ok( hr == S_OK, "got %#lx\n", hr );
4682 count = 0xdeadbeef;
4683 hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL );
4684 ok( hr == S_OK, "got %#lx\n", hr );
4685 ok( !count, "got %lu\n", count );
4687 count = 0xdeadbeef;
4688 hr = WsReadCharsUtf8( reader, NULL, 1, &count, NULL );
4689 ok( hr == S_OK, "got %#lx\n", hr );
4690 ok( !count, "got %lu\n", count );
4692 buf[0] = 0;
4693 count = 0xdeadbeef;
4694 hr = WsReadCharsUtf8( reader, buf, 0, &count, NULL );
4695 ok( hr == S_OK, "got %#lx\n", hr );
4696 ok( !count, "got %lu\n", count );
4697 ok( !buf[0], "wrong data\n" );
4699 buf[0] = 0;
4700 count = 0xdeadbeef;
4701 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4702 ok( hr == S_OK, "got %#lx\n", hr );
4703 ok( !count, "got %lu\n", count );
4704 ok( !buf[0], "wrong data\n" );
4706 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
4707 ok( hr == S_OK, "got %#lx\n", hr );
4709 buf[0] = 0;
4710 count = 0xdeadbeef;
4711 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4712 ok( hr == S_OK, "got %#lx\n", hr );
4713 ok( !count, "got %lu\n", count );
4714 ok( !buf[0], "wrong data\n" );
4716 hr = WsReadStartElement( reader, NULL );
4717 ok( hr == S_OK, "got %#lx\n", hr );
4719 count = 0xdeadbeef;
4720 hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL );
4721 ok( hr == S_OK, "got %#lx\n", hr );
4722 ok( !count, "got %lu\n", count );
4724 buf[0] = 0;
4725 count = 0xdeadbeef;
4726 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4727 ok( hr == S_OK, "got %#lx\n", hr );
4728 ok( count == 2, "got %lu\n", count );
4729 ok( !memcmp( buf, "te", 2 ), "wrong data\n" );
4731 hr = WsGetReaderNode( reader, &node, NULL );
4732 ok( hr == S_OK, "got %#lx\n", hr );
4733 text = (const WS_XML_TEXT_NODE *)node;
4734 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4735 utf8 = (const WS_XML_UTF8_TEXT *)text->text;
4736 ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType );
4737 ok( utf8->value.length == 4, "got %lu\n", utf8->value.length );
4738 ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" );
4740 buf[0] = 0;
4741 count = 0xdeadbeef;
4742 hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL );
4743 ok( hr == S_OK, "got %#lx\n", hr );
4744 ok( count == 2, "got %lu\n", count );
4745 ok( !memcmp( buf, "xt", 2 ), "wrong data\n" );
4747 hr = WsGetReaderNode( reader, &node, NULL );
4748 ok( hr == S_OK, "got %#lx\n", hr );
4749 text = (const WS_XML_TEXT_NODE *)node;
4750 ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType );
4752 count = 0xdeadbeef;
4753 hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL );
4754 ok( hr == S_OK, "got %#lx\n", hr );
4755 ok( !count, "got %lu\n", count );
4757 hr = WsGetReaderNode( reader, &node, NULL );
4758 ok( hr == S_OK, "got %#lx\n", hr );
4759 text = (const WS_XML_TEXT_NODE *)node;
4760 ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType );
4762 WsFreeReader( reader );
4765 static void test_WsReadQualifiedName(void)
4767 static const char utf8[] = {'<','a','>',0xc3,0xab,'<','/','a','>',0};
4768 static const char localname_utf8[] = {0xc3,0xab,0};
4769 WS_XML_STRING prefix, localname, ns;
4770 WS_XML_READER *reader;
4771 WS_HEAP *heap;
4772 HRESULT hr;
4773 BOOL found;
4774 ULONG i;
4775 static const struct
4777 const char *str;
4778 HRESULT hr;
4779 const char *prefix;
4780 const char *localname;
4781 const char *ns;
4782 } tests[] =
4784 { "<a></a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4785 { "<a> </a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4786 { "<a>:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4787 { "<a>t</a>", S_OK, "", "t", "" },
4788 { "<a>p:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4789 { "<a>p:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4790 { "<a>:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4791 { "<a xmlns:p=\"ns\">p:t</a>", S_OK, "p", "t", "ns" },
4792 { "<a xmlns:p=\"ns\">p:t:</a>", S_OK, "p", "t:", "ns" },
4793 { "<a xmlns:p=\"ns\">p:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4794 { "<a xmlns:p=\"ns\">:t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4795 { "<a xmlns:p=\"ns\">:</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4796 { "<a xmlns:p=\"ns\">t</a>", S_OK, "", "t", "" },
4797 { "<a xmlns:p=\"ns\"> </a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4798 { "<a xmlns:p=\"ns\"></a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4799 { "<a xmlns:p=\"ns\">p:t u</a>", S_OK, "p", "t u", "ns" },
4800 { utf8, S_OK, "", localname_utf8, "" },
4801 { "<a> t </a>", S_OK, "", "t", "" },
4802 { "<a xmlns:p=\"ns\"> p:t</a>", S_OK, "p", "t", "ns" },
4803 { "<a xmlns:p=\"ns\">p :t</a>", WS_E_INVALID_FORMAT, NULL, NULL, NULL },
4804 { "<a xmlns:p=\"ns\">p: t</a>", S_OK, "p", " t", "ns" },
4807 hr = WsReadQualifiedName( NULL, NULL, NULL, NULL, NULL, NULL );
4808 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4810 hr = WsCreateReader( NULL, 0, &reader, NULL );
4811 ok( hr == S_OK, "got %#lx\n", hr );
4813 hr = WsReadQualifiedName( reader, NULL, NULL, NULL, NULL, NULL );
4814 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4816 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
4817 ok( hr == S_OK, "got %#lx\n", hr );
4819 hr = WsReadQualifiedName( reader, heap, NULL, NULL, NULL, NULL );
4820 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
4822 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4823 ok( hr == S_OK, "got %#lx\n", hr );
4824 hr = WsReadQualifiedName( reader, heap, NULL, NULL, NULL, NULL );
4825 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4827 hr = set_input( reader, "<t/>", sizeof("<t/>") - 1 );
4828 ok( hr == S_OK, "got %#lx\n", hr );
4829 hr = WsReadQualifiedName( reader, heap, NULL, &localname, NULL, NULL );
4830 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
4832 for (i = 0; i < ARRAY_SIZE( tests ); i++)
4834 hr = set_input( reader, tests[i].str, strlen(tests[i].str) );
4835 ok( hr == S_OK, "%lu: got %#lx\n", i, hr );
4837 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4838 ok( hr == S_OK, "%lu: got %#lx\n", i, hr );
4840 hr = WsReadStartElement( reader, NULL );
4841 ok( hr == S_OK, "%lu: got %#lx\n", i, hr );
4843 prefix.length = localname.length = ns.length = 0xdeadbeef;
4844 prefix.bytes = localname.bytes = ns.bytes = (BYTE *)0xdeadbeef;
4846 hr = WsReadQualifiedName( reader, heap, &prefix, &localname, &ns, NULL );
4847 ok( hr == tests[i].hr, "%lu: got %#lx\n", i, hr );
4848 if (tests[i].hr == S_OK && hr == S_OK)
4850 ok( prefix.length == strlen( tests[i].prefix ), "%lu: got %lu\n", i, prefix.length );
4851 ok( !memcmp( prefix.bytes, tests[i].prefix, prefix.length ), "%lu: wrong data\n", i );
4853 ok( localname.length == strlen( tests[i].localname ), "%lu: got %lu\n", i, localname.length );
4854 ok( !memcmp( localname.bytes, tests[i].localname, localname.length ), "%lu: wrong data\n", i );
4856 ok( ns.length == strlen( tests[i].ns ), "%lu: got %lu\n", i, ns.length );
4857 ok( !memcmp( ns.bytes, tests[i].ns, ns.length ), "%lu: wrong data\n", i );
4859 else if (tests[i].hr != S_OK)
4861 ok( prefix.length == 0xdeadbeef, "got %lu\n", prefix.length );
4862 ok( prefix.bytes == (BYTE *)0xdeadbeef, "got %p\n", prefix.bytes );
4864 ok( localname.length == 0xdeadbeef, "got %lu\n", localname.length );
4865 ok( localname.bytes == (BYTE *)0xdeadbeef, "got %p\n", localname.bytes );
4867 ok( ns.length == 0xdeadbeef, "got %lu\n", ns.length );
4868 ok( ns.bytes == (BYTE *)0xdeadbeef, "got %p\n", ns.bytes );
4872 WsFreeHeap( heap );
4873 WsFreeReader( reader );
4876 static void test_WsReadAttribute(void)
4878 WS_XML_STRING localname = {1, (BYTE *)"a"}, ns = {0, NULL};
4879 WS_XML_READER *reader;
4880 WS_ATTRIBUTE_DESCRIPTION desc;
4881 WS_HEAP *heap;
4882 UINT32 *val;
4883 BOOL found;
4884 HRESULT hr;
4886 hr = WsReadAttribute( NULL, NULL, 0, NULL, NULL, 0, NULL );
4887 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4889 hr = WsCreateReader( NULL, 0, &reader, NULL );
4890 ok( hr == S_OK, "got %#lx\n", hr );
4892 hr = WsReadAttribute( reader, NULL, 0, NULL, NULL, 0, NULL );
4893 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4895 desc.attributeLocalName = &localname;
4896 desc.attributeNs = &ns;
4897 desc.type = WS_UINT32_TYPE;
4898 desc.typeDescription = NULL;
4899 hr = WsReadAttribute( reader, &desc, 0, NULL, NULL, 0, NULL );
4900 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4902 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, NULL, NULL, 0, NULL );
4903 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4905 hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL );
4906 ok( hr == S_OK, "got %#lx\n", hr );
4908 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, NULL, 0, NULL );
4909 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4911 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, &val, sizeof(val), NULL );
4912 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
4914 prepare_struct_type_test( reader, "<t a='1'>" );
4915 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
4916 ok( hr == S_OK, "got %#lx\n", hr );
4918 val = NULL;
4919 hr = WsReadAttribute( reader, &desc, WS_READ_REQUIRED_POINTER, heap, &val, sizeof(val), NULL );
4920 ok( hr == S_OK, "got %#lx\n", hr );
4921 ok( val != NULL, "val not set\n" );
4922 ok( *val == 1, "got %u\n", *val );
4924 WsFreeHeap( heap );
4925 WsFreeReader( reader );
4928 static void test_WsSkipNode(void)
4930 const WS_XML_NODE *node;
4931 WS_XML_READER *reader;
4932 HRESULT hr;
4934 hr = WsSkipNode( NULL, NULL );
4935 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4937 hr = WsCreateReader( NULL, 0, &reader, NULL );
4938 ok( hr == S_OK, "got %#lx\n", hr );
4940 hr = WsSkipNode( reader, NULL );
4941 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
4943 hr = set_input( reader, "<t><u></u></t>", sizeof("<t><u></u></t>") - 1 );
4944 ok( hr == S_OK, "got %#lx\n", hr );
4946 hr = WsGetReaderNode( reader, &node, NULL );
4947 ok( hr == S_OK, "got %#lx\n", hr );
4948 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
4950 /* BOF */
4951 hr = WsSkipNode( reader, NULL );
4952 ok( hr == S_OK, "got %#lx\n", hr );
4953 hr = WsGetReaderNode( reader, &node, NULL );
4954 ok( hr == S_OK, "got %#lx\n", hr );
4955 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4957 /* element */
4958 hr = WsSkipNode( reader, NULL );
4959 ok( hr == S_OK, "got %#lx\n", hr );
4960 hr = WsGetReaderNode( reader, &node, NULL );
4961 ok( hr == S_OK, "got %#lx\n", hr );
4962 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
4964 /* EOF */
4965 hr = WsSkipNode( reader, NULL );
4966 ok( hr == WS_E_INVALID_OPERATION, "got %#lx\n", hr );
4968 hr = set_input( reader, "<!--comment--><t></t>", sizeof("<!--comment--><t></t>") - 1 );
4969 ok( hr == S_OK, "got %#lx\n", hr );
4971 /* non-element */
4972 hr = WsSkipNode( reader, NULL );
4973 ok( hr == S_OK, "got %#lx\n", hr );
4974 hr = WsGetReaderNode( reader, &node, NULL );
4975 ok( hr == S_OK, "got %#lx\n", hr );
4976 ok( node->nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", node->nodeType );
4978 hr = WsSkipNode( reader, NULL );
4979 ok( hr == S_OK, "got %#lx\n", hr );
4980 hr = WsGetReaderNode( reader, &node, NULL );
4981 ok( hr == S_OK, "got %#lx\n", hr );
4982 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
4984 WsFreeReader( reader );
4987 static HRESULT set_input_bin( WS_XML_READER *reader, const char *data, ULONG size, WS_XML_DICTIONARY *dict )
4989 WS_XML_READER_BINARY_ENCODING bin = {{WS_XML_READER_ENCODING_TYPE_BINARY}, dict};
4990 WS_XML_READER_BUFFER_INPUT buf;
4992 buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
4993 buf.encodedData = (void *)data;
4994 buf.encodedDataSize = size;
4995 return WsSetInput( reader, &bin.encoding, &buf.input, NULL, 0, NULL );
4998 static const WS_XML_TEXT_NODE *read_text_node( WS_XML_READER *reader )
5000 const WS_XML_NODE *node;
5001 if (WsReadNode( reader, NULL ) != S_OK) return NULL;
5002 if (WsReadNode( reader, NULL ) != S_OK) return NULL;
5003 if (WsGetReaderNode( reader, &node, NULL ) != S_OK) return NULL;
5004 if (node->nodeType != WS_XML_NODE_TYPE_TEXT) return NULL;
5005 return (const WS_XML_TEXT_NODE *)node;
5008 static void test_binary_encoding(void)
5010 WS_XML_STRING str_s = {1, (BYTE *)"s"}, str_s_a = {3, (BYTE *)"s_a"}, str_s_b = {3, (BYTE *)"s_b"};
5011 WS_XML_STRING str_a = {1, (BYTE *)"a"}, str_b = {1, (BYTE *)"b"};
5012 static WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
5013 static const char test[] =
5014 {0x40,0x01,'t',0x01};
5015 static const char test2[] =
5016 {0x6d,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01};
5017 static const char test3[] =
5018 {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x01};
5019 static const char test4[] =
5020 {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x99,0x04,'t','e','s','t'};
5021 static const char test5[] =
5022 {0x40,0x01,'t',0x9f,0x01,'a'};
5023 static const char test6[] =
5024 {0x40,0x01,'t',0xa0,0x01,0x00,'a',0x9f,0x01,'b'};
5025 static const char test7[] =
5026 {0x40,0x01,'t',0xb5,0xff,0xff,0xff,0xff};
5027 static const char test8[] =
5028 {0x40,0x01,'t',0xb5,0x00,0x00,0x00,0x00};
5029 static const char test9[] =
5030 {0x40,0x01,'t',0x81};
5031 static const char test10[] =
5032 {0x40,0x01,'t',0x83};
5033 static const char test11[] =
5034 {0x40,0x01,'t',0x85};
5035 static const char test12[] =
5036 {0x40,0x01,'t',0x87};
5037 static const char test13[] =
5038 {0x40,0x01,'t',0x89,0xff};
5039 static const char test14[] =
5040 {0x40,0x01,'t',0x8b,0xff,0xff};
5041 static const char test15[] =
5042 {0x40,0x01,'t',0x8d,0xff,0xff,0xff,0xff};
5043 static const char test16[] =
5044 {0x40,0x01,'t',0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
5045 static const char test17[] =
5046 {0x40,0x01,'t',0x93,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
5047 static const char test18[] =
5048 {0x40,0x01,'t',0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
5049 static const char test19[] =
5050 {0x40,0x01,'t',0x99,0x01,0x61};
5051 static const char test20[] =
5052 {0x40,0x01,'t',0x9b,0x01,0x00,0x61};
5053 static const char test21[] =
5054 {0x40,0x01,'t',0x9d,0x01,0x00,0x00,0x00,0x61};
5055 static const char test22[] =
5056 {0x40,0x01,'t',0x9f,0x01,0x61};
5057 static const char test23[] =
5058 {0x40,0x01,'t',0xa1,0x01,0x00,0x61};
5059 static const char test24[] =
5060 {0x40,0x01,'t',0xa3,0x01,0x00,0x00,0x00,0x61};
5061 static const char test25[] =
5062 {0x40,0x01,'t',0xa9};
5063 static const char test26[] =
5064 {0x40,0x01,'t',0xab,0x0c};
5065 static const char test27[] =
5066 {0x40,0x01,'t',0xad,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
5067 static const char test28[] =
5068 {0x40,0x01,'t',0xb1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
5069 static const char test29[] =
5070 {0x40,0x01,'t',0xb3,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
5071 static const char test30[] =
5072 {0x40,0x01,'t',0x08,0x02,'n','s',0x01};
5073 static const char test31[] =
5074 {0x40,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01};
5075 static const char test32[] =
5076 {0x40,0x01,'t',0xb3,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
5077 static const char test100[] =
5078 {0x40,0x01,'t',0x04,0x01,'t',0x98,0x00,0x01};
5079 static const char test101[] =
5080 {0x40,0x01,'t',0x35,0x01,'t',0x98,0x00,0x09,0x01,'p',0x02,'n','s',0x01};
5081 static const char test102[] =
5082 {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x00,0x09,0x02,'p','2',0x02,'n','s',0x01};
5083 static const char test103[] =
5084 {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x04,'t','e','s','t',0x09,0x02,'p','2',0x02,'n','s',0x01};
5085 static const char test200[] =
5086 {0x02,0x07,'c','o','m','m','e','n','t'};
5087 static const char test_endelem[] =
5088 { 0x40, 0x01, 't', 0x40, 0x01, 'a', 0x83, 0x40, 0x01, 's', 0x40, 0x03, 's', '_', 'a', 0x82, 0x01, 0x01,
5089 0x40, 0x01, 'b', 0x83, 0x01 };
5090 const WS_XML_NODE *node;
5091 const WS_XML_TEXT_NODE *text_node;
5092 const WS_XML_ELEMENT_NODE *elem;
5093 const WS_XML_ATTRIBUTE *attr;
5094 const WS_XML_UTF8_TEXT *utf8_text;
5095 const WS_XML_BASE64_TEXT *base64_text;
5096 const WS_XML_INT32_TEXT *int32_text;
5097 const WS_XML_INT64_TEXT *int64_text;
5098 const WS_XML_DOUBLE_TEXT *double_text;
5099 const WS_XML_DATETIME_TEXT *datetime_text;
5100 const WS_XML_BOOL_TEXT *bool_text;
5101 const WS_XML_UNIQUE_ID_TEXT *unique_id_text;
5102 const WS_XML_GUID_TEXT *guid_text;
5103 const WS_XML_UINT64_TEXT *uint64_text;
5104 const WS_XML_COMMENT_NODE *comment;
5105 WS_XML_DICTIONARY *dict;
5106 WS_XML_READER *reader;
5107 WS_HEAP *heap;
5108 BOOL found;
5109 HRESULT hr;
5110 WS_STRUCT_DESCRIPTION s, s2;
5111 WS_FIELD_DESCRIPTION f, f1[3], f2[2], *fields[3], *fields2[2];
5112 struct typetest
5114 WS_BYTES data;
5115 } *typetest;
5116 struct typetest2
5118 UINT32 val;
5119 } *typetest2;
5120 struct typetest3
5122 UINT64 val;
5123 } *typetest3;
5124 struct s
5126 INT32 s_a;
5127 INT32 s_b;
5129 struct test
5131 INT32 a;
5132 struct s *s;
5133 INT32 b;
5134 } *test_struct;
5136 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_1, &dict, NULL );
5137 ok( hr == S_OK, "got %#lx\n", hr );
5139 hr = WsCreateReader( NULL, 0, &reader, NULL );
5140 ok( hr == S_OK, "got %#lx\n", hr );
5142 /* short element */
5143 hr = set_input_bin( reader, test, sizeof(test), NULL );
5144 ok( hr == S_OK, "got %#lx\n", hr );
5146 hr = WsReadNode( reader, NULL );
5147 ok( hr == S_OK, "got %#lx\n", hr );
5148 hr = WsGetReaderNode( reader, &node, NULL );
5149 ok( hr == S_OK, "got %#lx\n", hr );
5150 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5151 elem = (const WS_XML_ELEMENT_NODE *)node;
5152 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
5153 ok( elem->prefix->bytes == NULL, "bytes set\n" );
5154 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
5155 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5156 ok( elem->localName->dictionary != NULL, "dictionary not set\n" );
5157 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
5158 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5159 ok( !elem->attributeCount, "got %lu\n", elem->attributeCount );
5160 ok( !elem->isEmpty, "empty\n" );
5162 hr = WsReadNode( reader, NULL );
5163 ok( hr == S_OK, "got %#lx\n", hr );
5164 hr = WsGetReaderNode( reader, &node, NULL );
5165 ok( hr == S_OK, "got %#lx\n", hr );
5166 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5168 /* single character prefix element */
5169 hr = set_input_bin( reader, test2, sizeof(test2), NULL );
5170 ok( hr == S_OK, "got %#lx\n", hr );
5172 hr = WsReadNode( reader, NULL );
5173 ok( hr == S_OK, "got %#lx\n", hr );
5174 hr = WsGetReaderNode( reader, &node, NULL );
5175 ok( hr == S_OK, "got %#lx\n", hr );
5176 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5177 elem = (const WS_XML_ELEMENT_NODE *)node;
5178 ok( elem->prefix->length == 1, "got %lu\n", elem->prefix->length );
5179 ok( !memcmp( elem->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5180 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
5181 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5182 ok( elem->ns->length == 2, "got %lu\n", elem->ns->length );
5183 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5184 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
5185 ok( !elem->isEmpty, "empty\n" );
5186 attr = elem->attributes[0];
5187 ok( !attr->singleQuote, "single quote\n" );
5188 ok( attr->isXmlNs, "not xmlns\n" );
5189 ok( attr->prefix->length == 1, "got %lu\n", attr->prefix->length );
5190 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5191 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
5192 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5194 hr = WsReadNode( reader, NULL );
5195 ok( hr == S_OK, "got %#lx\n", hr );
5196 hr = WsGetReaderNode( reader, &node, NULL );
5197 ok( hr == S_OK, "got %#lx\n", hr );
5198 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5200 /* element */
5201 hr = set_input_bin( reader, test3, sizeof(test3), NULL );
5202 ok( hr == S_OK, "got %#lx\n", hr );
5204 hr = WsReadNode( reader, NULL );
5205 ok( hr == S_OK, "got %#lx\n", hr );
5206 hr = WsGetReaderNode( reader, &node, NULL );
5207 ok( hr == S_OK, "got %#lx\n", hr );
5208 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5209 elem = (const WS_XML_ELEMENT_NODE *)node;
5210 ok( elem->prefix->length == 2, "got %lu\n", elem->prefix->length );
5211 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5212 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
5213 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5214 ok( elem->ns->length == 2, "got %lu\n", elem->ns->length );
5215 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5216 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
5217 ok( !elem->isEmpty, "empty\n" );
5218 attr = elem->attributes[0];
5219 ok( !attr->singleQuote, "single quote\n" );
5220 ok( attr->isXmlNs, "not xmlns\n" );
5221 ok( attr->prefix->length == 2, "got %lu\n", attr->prefix->length );
5222 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5223 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
5224 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5226 hr = WsReadNode( reader, NULL );
5227 ok( hr == S_OK, "got %#lx\n", hr );
5228 hr = WsGetReaderNode( reader, &node, NULL );
5229 ok( hr == S_OK, "got %#lx\n", hr );
5230 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5232 /* element with text */
5233 hr = set_input_bin( reader, test4, sizeof(test4), NULL );
5234 ok( hr == S_OK, "got %#lx\n", hr );
5236 hr = WsReadNode( reader, NULL );
5237 ok( hr == S_OK, "got %#lx\n", hr );
5238 hr = WsGetReaderNode( reader, &node, NULL );
5239 ok( hr == S_OK, "got %#lx\n", hr );
5240 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5241 elem = (const WS_XML_ELEMENT_NODE *)node;
5242 ok( elem->prefix->length == 2, "got %lu\n", elem->prefix->length );
5243 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5244 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
5245 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5246 ok( elem->ns->length == 2, "got %lu\n", elem->ns->length );
5247 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5248 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
5249 ok( !elem->isEmpty, "empty\n" );
5250 attr = elem->attributes[0];
5251 ok( !attr->singleQuote, "single quote\n" );
5252 ok( attr->isXmlNs, "not xmlns\n" );
5253 ok( attr->prefix->length == 2, "got %lu\n", attr->prefix->length );
5254 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5255 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
5256 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5258 hr = WsReadNode( reader, NULL );
5259 ok( hr == S_OK, "got %#lx\n", hr );
5260 hr = WsGetReaderNode( reader, &node, NULL );
5261 ok( hr == S_OK, "got %#lx\n", hr );
5262 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
5263 text_node = (const WS_XML_TEXT_NODE *)node;
5264 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text_node->text->textType );
5265 utf8_text = (const WS_XML_UTF8_TEXT *)text_node->text;
5266 ok( utf8_text->value.length == 4, "got %lu\n", utf8_text->value.length );
5267 ok( !memcmp( utf8_text->value.bytes, "test", 4 ), "wrong text\n" );
5269 hr = WsReadNode( reader, NULL );
5270 ok( hr == S_OK, "got %#lx\n", hr );
5271 hr = WsGetReaderNode( reader, &node, NULL );
5272 ok( hr == S_OK, "got %#lx\n", hr );
5273 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5275 /* bool text, TRUE */
5276 hr = set_input_bin( reader, test7, sizeof(test7), NULL );
5277 ok( hr == S_OK, "got %#lx\n", hr );
5278 text_node = read_text_node( reader );
5279 ok( text_node != NULL, "no text\n" );
5280 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BOOL, "got %u\n", text_node->text->textType );
5281 bool_text = (WS_XML_BOOL_TEXT *)text_node->text;
5282 ok( bool_text->value == TRUE, "got %d\n", bool_text->value );
5284 /* bool text, FALSE */
5285 hr = set_input_bin( reader, test8, sizeof(test8), NULL );
5286 ok( hr == S_OK, "got %#lx\n", hr );
5287 text_node = read_text_node( reader );
5288 ok( text_node != NULL, "no text\n" );
5289 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BOOL, "got %u\n", text_node->text->textType );
5290 bool_text = (WS_XML_BOOL_TEXT *)text_node->text;
5291 ok( !bool_text->value, "got %d\n", bool_text->value );
5293 /* zero text */
5294 hr = set_input_bin( reader, test9, sizeof(test9), NULL );
5295 ok( hr == S_OK, "got %#lx\n", hr );
5296 text_node = read_text_node( reader );
5297 ok( text_node != NULL, "no text\n" );
5298 ok( text_node->text->textType == WS_XML_TEXT_TYPE_INT32, "got %u\n", text_node->text->textType );
5299 int32_text = (WS_XML_INT32_TEXT *)text_node->text;
5300 ok( !int32_text->value, "got %d\n", int32_text->value );
5302 /* one text */
5303 hr = set_input_bin( reader, test10, sizeof(test10), NULL );
5304 ok( hr == S_OK, "got %#lx\n", hr );
5305 text_node = read_text_node( reader );
5306 ok( text_node != NULL, "no text\n" );
5307 ok( text_node->text->textType == WS_XML_TEXT_TYPE_INT32, "got %u\n", text_node->text->textType );
5308 int32_text = (WS_XML_INT32_TEXT *)text_node->text;
5309 ok( int32_text->value == 1, "got %d\n", int32_text->value );
5311 /* false text */
5312 hr = set_input_bin( reader, test11, sizeof(test11), NULL );
5313 ok( hr == S_OK, "got %#lx\n", hr );
5314 text_node = read_text_node( reader );
5315 ok( text_node != NULL, "no text\n" );
5316 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BOOL, "got %u\n", text_node->text->textType );
5317 bool_text = (WS_XML_BOOL_TEXT *)text_node->text;
5318 ok( !bool_text->value, "got %d\n", bool_text->value );
5320 /* true text */
5321 hr = set_input_bin( reader, test12, sizeof(test12), NULL );
5322 ok( hr == S_OK, "got %#lx\n", hr );
5323 text_node = read_text_node( reader );
5324 ok( text_node != NULL, "no text\n" );
5325 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BOOL, "got %u\n", text_node->text->textType );
5326 bool_text = (WS_XML_BOOL_TEXT *)text_node->text;
5327 ok( bool_text->value == TRUE, "got %d\n", bool_text->value );
5329 /* int32 text, int8 record */
5330 hr = set_input_bin( reader, test13, sizeof(test13), NULL );
5331 ok( hr == S_OK, "got %#lx\n", hr );
5332 text_node = read_text_node( reader );
5333 ok( text_node != NULL, "no text\n" );
5334 ok( text_node->text->textType == WS_XML_TEXT_TYPE_INT32, "got %u\n", text_node->text->textType );
5335 int32_text = (WS_XML_INT32_TEXT *)text_node->text;
5336 ok( int32_text->value == -1, "got %d\n", int32_text->value );
5338 /* int32 text, int16 record */
5339 hr = set_input_bin( reader, test14, sizeof(test14), NULL );
5340 ok( hr == S_OK, "got %#lx\n", hr );
5341 text_node = read_text_node( reader );
5342 ok( text_node != NULL, "no text\n" );
5343 ok( text_node->text->textType == WS_XML_TEXT_TYPE_INT32, "got %u\n", text_node->text->textType );
5344 int32_text = (WS_XML_INT32_TEXT *)text_node->text;
5345 ok( int32_text->value == -1, "got %d\n", int32_text->value );
5347 /* int32 text, int32 record */
5348 hr = set_input_bin( reader, test15, sizeof(test15), NULL );
5349 ok( hr == S_OK, "got %#lx\n", hr );
5350 text_node = read_text_node( reader );
5351 ok( text_node != NULL, "no text\n" );
5352 ok( text_node->text->textType == WS_XML_TEXT_TYPE_INT32, "got %u\n", text_node->text->textType );
5353 int32_text = (WS_XML_INT32_TEXT *)text_node->text;
5354 ok( int32_text->value == -1, "got %d\n", int32_text->value );
5356 /* int64 text, int64 record */
5357 hr = set_input_bin( reader, test16, sizeof(test16), NULL );
5358 ok( hr == S_OK, "got %#lx\n", hr );
5359 text_node = read_text_node( reader );
5360 ok( text_node != NULL, "no text\n" );
5361 ok( text_node->text->textType == WS_XML_TEXT_TYPE_INT64, "got %u\n", text_node->text->textType );
5362 int64_text = (WS_XML_INT64_TEXT *)text_node->text;
5363 ok( int64_text->value == -1, "got %s\n", wine_dbgstr_longlong(int64_text->value) );
5365 /* double text */
5366 hr = set_input_bin( reader, test17, sizeof(test17), NULL );
5367 ok( hr == S_OK, "got %#lx\n", hr );
5368 text_node = read_text_node( reader );
5369 ok( text_node != NULL, "no text\n" );
5370 ok( text_node->text->textType == WS_XML_TEXT_TYPE_DOUBLE, "got %u\n", text_node->text->textType );
5371 double_text = (WS_XML_DOUBLE_TEXT *)text_node->text;
5372 ok( !double_text->value, "got %s\n", wine_dbgstr_longlong(double_text->value) );
5374 /* datetime text */
5375 hr = set_input_bin( reader, test18, sizeof(test18), NULL );
5376 ok( hr == S_OK, "got %#lx\n", hr );
5377 text_node = read_text_node( reader );
5378 ok( text_node != NULL, "no text\n" );
5379 ok( text_node->text->textType == WS_XML_TEXT_TYPE_DATETIME, "got %u\n", text_node->text->textType );
5380 datetime_text = (WS_XML_DATETIME_TEXT *)text_node->text;
5381 ok( !datetime_text->value.ticks, "got %s\n", wine_dbgstr_longlong(datetime_text->value.ticks) );
5382 ok( datetime_text->value.format == WS_DATETIME_FORMAT_NONE, "got %u\n", datetime_text->value.format );
5384 /* utf8 text, chars8 record */
5385 hr = set_input_bin( reader, test19, sizeof(test19), NULL );
5386 ok( hr == S_OK, "got %#lx\n", hr );
5387 text_node = read_text_node( reader );
5388 ok( text_node != NULL, "no text\n" );
5389 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text_node->text->textType );
5390 utf8_text = (WS_XML_UTF8_TEXT *)text_node->text;
5391 ok( utf8_text->value.length == 1, "got %lu\n", utf8_text->value.length );
5392 ok( utf8_text->value.bytes[0] == 'a', "got %02x\n", utf8_text->value.bytes[0] );
5394 /* utf8 text, chars16 record */
5395 hr = set_input_bin( reader, test20, sizeof(test20), NULL );
5396 ok( hr == S_OK, "got %#lx\n", hr );
5397 text_node = read_text_node( reader );
5398 ok( text_node != NULL, "no text\n" );
5399 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text_node->text->textType );
5400 utf8_text = (WS_XML_UTF8_TEXT *)text_node->text;
5401 ok( utf8_text->value.length == 1, "got %lu\n", utf8_text->value.length );
5402 ok( utf8_text->value.bytes[0] == 'a', "got %02x\n", utf8_text->value.bytes[0] );
5404 /* utf8 text, chars32 record */
5405 hr = set_input_bin( reader, test21, sizeof(test21), NULL );
5406 ok( hr == S_OK, "got %#lx\n", hr );
5407 text_node = read_text_node( reader );
5408 ok( text_node != NULL, "no text\n" );
5409 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text_node->text->textType );
5410 utf8_text = (WS_XML_UTF8_TEXT *)text_node->text;
5411 ok( utf8_text->value.length == 1, "got %lu\n", utf8_text->value.length );
5412 ok( utf8_text->value.bytes[0] == 'a', "got %02x\n", utf8_text->value.bytes[0] );
5414 /* base64 text, bytes8 record */
5415 hr = set_input_bin( reader, test22, sizeof(test22), NULL );
5416 ok( hr == S_OK, "got %#lx\n", hr );
5417 text_node = read_text_node( reader );
5418 ok( text_node != NULL, "no text\n" );
5419 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text_node->text->textType );
5420 base64_text = (WS_XML_BASE64_TEXT *)text_node->text;
5421 ok( base64_text->length == 1, "got %lu\n", base64_text->length );
5422 ok( base64_text->bytes[0] == 'a', "got %02x\n", base64_text->bytes[0] );
5424 /* base64 text, bytes16 record */
5425 hr = set_input_bin( reader, test23, sizeof(test23), NULL );
5426 ok( hr == S_OK, "got %#lx\n", hr );
5427 text_node = read_text_node( reader );
5428 ok( text_node != NULL, "no text\n" );
5429 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text_node->text->textType );
5430 base64_text = (WS_XML_BASE64_TEXT *)text_node->text;
5431 ok( base64_text->length == 1, "got %lu\n", base64_text->length );
5432 ok( base64_text->bytes[0] == 'a', "got %02x\n", base64_text->bytes[0] );
5434 /* base64 text, bytes32 record */
5435 hr = set_input_bin( reader, test24, sizeof(test24), NULL );
5436 ok( hr == S_OK, "got %#lx\n", hr );
5437 text_node = read_text_node( reader );
5438 ok( text_node != NULL, "no text\n" );
5439 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text_node->text->textType );
5440 base64_text = (WS_XML_BASE64_TEXT *)text_node->text;
5441 ok( base64_text->length == 1, "got %lu\n", base64_text->length );
5442 ok( base64_text->bytes[0] == 'a', "got %02x\n", base64_text->bytes[0] );
5444 /* empty text */
5445 hr = set_input_bin( reader, test25, sizeof(test25), NULL );
5446 ok( hr == S_OK, "got %#lx\n", hr );
5447 text_node = read_text_node( reader );
5448 ok( text_node != NULL, "no text\n" );
5449 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text_node->text->textType );
5450 utf8_text = (WS_XML_UTF8_TEXT *)text_node->text;
5451 ok( !utf8_text->value.length, "got %lu\n", utf8_text->value.length );
5452 ok( utf8_text->value.bytes != NULL, "bytes not set\n" );
5454 /* dictionary text */
5455 hr = set_input_bin( reader, test26, sizeof(test26), dict );
5456 ok( hr == S_OK, "got %#lx\n", hr );
5457 text_node = read_text_node( reader );
5458 ok( text_node != NULL, "no text\n" );
5459 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text_node->text->textType );
5460 utf8_text = (WS_XML_UTF8_TEXT *)text_node->text;
5461 ok( utf8_text->value.length == 2, "got %lu\n", utf8_text->value.length );
5462 ok( utf8_text->value.bytes[0] == 'T', "got %02x\n", utf8_text->value.bytes[0] );
5463 ok( utf8_text->value.bytes[1] == 'o', "got %02x\n", utf8_text->value.bytes[0] );
5465 /* unique id text */
5466 hr = set_input_bin( reader, test27, sizeof(test27), NULL );
5467 ok( hr == S_OK, "got %#lx\n", hr );
5468 text_node = read_text_node( reader );
5469 ok( text_node != NULL, "no text\n" );
5470 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UNIQUE_ID, "got %u\n", text_node->text->textType );
5471 unique_id_text = (WS_XML_UNIQUE_ID_TEXT *)text_node->text;
5472 ok( IsEqualGUID( &unique_id_text->value, &guid_null ), "wrong data\n" );
5474 /* guid text */
5475 hr = set_input_bin( reader, test28, sizeof(test28), NULL );
5476 ok( hr == S_OK, "got %#lx\n", hr );
5477 text_node = read_text_node( reader );
5478 ok( text_node != NULL, "no text\n" );
5479 ok( text_node->text->textType == WS_XML_TEXT_TYPE_GUID, "got %u\n", text_node->text->textType );
5480 guid_text = (WS_XML_GUID_TEXT *)text_node->text;
5481 ok( IsEqualGUID( &guid_text->value, &guid_null ), "wrong data\n" );
5483 /* uint64 text */
5484 hr = set_input_bin( reader, test29, sizeof(test29), NULL );
5485 ok( hr == S_OK, "got %#lx\n", hr );
5486 text_node = read_text_node( reader );
5487 ok( text_node != NULL, "no text\n" );
5488 ok( text_node->text->textType == WS_XML_TEXT_TYPE_UINT64, "got %u\n", text_node->text->textType );
5489 uint64_text = (WS_XML_UINT64_TEXT *)text_node->text;
5490 ok( uint64_text->value == 1, "got %s\n", wine_dbgstr_longlong(uint64_text->value) );
5492 /* short xmlns attribute */
5493 hr = set_input_bin( reader, test30, sizeof(test30), NULL );
5494 ok( hr == S_OK, "got %#lx\n", hr );
5496 hr = WsReadNode( reader, NULL );
5497 ok( hr == S_OK, "got %#lx\n", hr );
5498 hr = WsGetReaderNode( reader, &node, NULL );
5499 ok( hr == S_OK, "got %#lx\n", hr );
5500 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5501 elem = (const WS_XML_ELEMENT_NODE *)node;
5502 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
5503 ok( elem->prefix->bytes == NULL, "bytes set\n" );
5504 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
5505 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5506 ok( elem->ns->length == 2, "got %lu\n", elem->ns->length );
5507 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5508 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
5509 ok( !elem->isEmpty, "empty\n" );
5510 attr = elem->attributes[0];
5511 ok( !attr->singleQuote, "single quote\n" );
5512 ok( attr->isXmlNs, "not xmlns\n" );
5513 ok( !attr->prefix->length, "got %lu\n", attr->prefix->length );
5514 ok( attr->prefix->bytes == NULL, "bytes set\n" );
5515 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
5516 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5518 /* xmlns attribute */
5519 hr = set_input_bin( reader, test31, sizeof(test31), NULL );
5520 ok( hr == S_OK, "got %#lx\n", hr );
5522 hr = WsReadNode( reader, NULL );
5523 ok( hr == S_OK, "got %#lx\n", hr );
5524 hr = WsGetReaderNode( reader, &node, NULL );
5525 ok( hr == S_OK, "got %#lx\n", hr );
5526 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5527 elem = (const WS_XML_ELEMENT_NODE *)node;
5528 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
5529 ok( elem->prefix->bytes == NULL, "bytes set\n" );
5530 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
5531 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5532 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
5533 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5534 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
5535 ok( !elem->isEmpty, "empty\n" );
5536 attr = elem->attributes[0];
5537 ok( !attr->singleQuote, "single quote\n" );
5538 ok( attr->isXmlNs, "not xmlns\n" );
5539 ok( attr->prefix->length == 1, "got %lu\n", attr->prefix->length );
5540 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5541 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
5542 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5544 /* short attribute */
5545 hr = set_input_bin( reader, test100, sizeof(test100), NULL );
5546 ok( hr == S_OK, "got %#lx\n", hr );
5548 hr = WsReadNode( reader, NULL );
5549 ok( hr == S_OK, "got %#lx\n", hr );
5550 hr = WsGetReaderNode( reader, &node, NULL );
5551 ok( hr == S_OK, "got %#lx\n", hr );
5552 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5553 elem = (const WS_XML_ELEMENT_NODE *)node;
5554 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
5555 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
5556 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5557 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
5558 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5559 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
5560 ok( !elem->isEmpty, "empty\n" );
5561 attr = elem->attributes[0];
5562 ok( !attr->singleQuote, "single quote\n" );
5563 ok( !attr->isXmlNs, "is xmlns\n" );
5564 ok( !attr->prefix->length, "got %lu\n", attr->prefix->length );
5565 ok( attr->localName->length == 1, "got %lu\n", attr->localName->length );
5566 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
5567 ok( !attr->ns->length, "got %lu\n", attr->ns->length );
5568 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5569 ok( attr->value != NULL, "value not set\n" );
5570 utf8_text = (const WS_XML_UTF8_TEXT *)attr->value;
5571 ok( utf8_text->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8_text->text.textType );
5572 ok( !utf8_text->value.length, "got %lu\n", utf8_text->value.length );
5573 ok( utf8_text->value.bytes != NULL, "bytes not set\n" );
5575 hr = WsReadNode( reader, NULL );
5576 ok( hr == S_OK, "got %#lx\n", hr );
5577 hr = WsGetReaderNode( reader, &node, NULL );
5578 ok( hr == S_OK, "got %#lx\n", hr );
5579 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5581 /* single character prefix attribute */
5582 hr = set_input_bin( reader, test101, sizeof(test101), NULL );
5583 ok( hr == S_OK, "got %#lx\n", hr );
5585 hr = WsReadNode( reader, NULL );
5586 ok( hr == S_OK, "got %#lx\n", hr );
5587 hr = WsGetReaderNode( reader, &node, NULL );
5588 ok( hr == S_OK, "got %#lx\n", hr );
5589 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5590 elem = (const WS_XML_ELEMENT_NODE *)node;
5591 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
5592 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
5593 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5594 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
5595 ok( elem->ns->bytes != NULL, "ns not set\n" );
5596 ok( elem->attributeCount == 2, "got %lu\n", elem->attributeCount );
5597 ok( !elem->isEmpty, "empty\n" );
5598 attr = elem->attributes[0];
5599 ok( !attr->singleQuote, "single quote\n" );
5600 ok( !attr->isXmlNs, "is xmlns\n" );
5601 ok( attr->prefix->length == 1, "got %lu\n", attr->prefix->length );
5602 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5603 ok( attr->localName->length == 1, "got %lu\n", attr->localName->length );
5604 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
5605 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
5606 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5607 ok( attr->value != NULL, "value not set\n" );
5608 utf8_text = (const WS_XML_UTF8_TEXT *)attr->value;
5609 ok( utf8_text->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8_text->text.textType );
5610 ok( !utf8_text->value.length, "got %lu\n", utf8_text->value.length );
5611 ok( utf8_text->value.bytes != NULL, "bytes not set\n" );
5612 attr = elem->attributes[1];
5613 ok( !attr->singleQuote, "single quote\n" );
5614 ok( attr->isXmlNs, "not xmlns\n" );
5615 ok( attr->prefix->length == 1, "got %lu\n", attr->prefix->length );
5616 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
5617 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
5618 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5620 hr = WsReadNode( reader, NULL );
5621 ok( hr == S_OK, "got %#lx\n", hr );
5622 hr = WsGetReaderNode( reader, &node, NULL );
5623 ok( hr == S_OK, "got %#lx\n", hr );
5624 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5626 /* attribute */
5627 hr = set_input_bin( reader, test102, sizeof(test102), NULL );
5628 ok( hr == S_OK, "got %#lx\n", hr );
5630 hr = WsReadNode( reader, NULL );
5631 ok( hr == S_OK, "got %#lx\n", hr );
5632 hr = WsGetReaderNode( reader, &node, NULL );
5633 ok( hr == S_OK, "got %#lx\n", hr );
5634 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5635 elem = (const WS_XML_ELEMENT_NODE *)node;
5636 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
5637 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
5638 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5639 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
5640 ok( elem->ns->bytes != NULL, "ns not set\n" );
5641 ok( elem->attributeCount == 2, "got %lu\n", elem->attributeCount );
5642 ok( !elem->isEmpty, "empty\n" );
5643 attr = elem->attributes[0];
5644 ok( !attr->singleQuote, "single quote\n" );
5645 ok( !attr->isXmlNs, "is xmlns\n" );
5646 ok( attr->prefix->length == 2, "got %lu\n", attr->prefix->length );
5647 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5648 ok( attr->localName->length == 1, "got %lu\n", attr->localName->length );
5649 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
5650 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
5651 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5652 ok( attr->value != NULL, "value not set\n" );
5653 utf8_text = (const WS_XML_UTF8_TEXT *)attr->value;
5654 ok( utf8_text->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8_text->text.textType );
5655 ok( !utf8_text->value.length, "got %lu\n", utf8_text->value.length );
5656 ok( utf8_text->value.bytes != NULL, "bytes not set\n" );
5657 attr = elem->attributes[1];
5658 ok( !attr->singleQuote, "single quote\n" );
5659 ok( attr->isXmlNs, "not xmlns\n" );
5660 ok( attr->prefix->length == 2, "got %lu\n", attr->prefix->length );
5661 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5662 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
5663 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5665 hr = WsReadNode( reader, NULL );
5666 ok( hr == S_OK, "got %#lx\n", hr );
5667 hr = WsGetReaderNode( reader, &node, NULL );
5668 ok( hr == S_OK, "got %#lx\n", hr );
5669 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5671 /* attribute with value */
5672 hr = set_input_bin( reader, test103, sizeof(test103), NULL );
5673 ok( hr == S_OK, "got %#lx\n", hr );
5675 hr = WsReadNode( reader, NULL );
5676 ok( hr == S_OK, "got %#lx\n", hr );
5677 hr = WsGetReaderNode( reader, &node, NULL );
5678 ok( hr == S_OK, "got %#lx\n", hr );
5679 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5680 elem = (const WS_XML_ELEMENT_NODE *)node;
5681 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
5682 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
5683 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5684 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
5685 ok( elem->ns->bytes != NULL, "ns not set\n" );
5686 ok( elem->attributeCount == 2, "got %lu\n", elem->attributeCount );
5687 ok( !elem->isEmpty, "empty\n" );
5688 attr = elem->attributes[0];
5689 ok( !attr->singleQuote, "single quote\n" );
5690 ok( !attr->isXmlNs, "is xmlns\n" );
5691 ok( attr->prefix->length == 2, "got %lu\n", attr->prefix->length );
5692 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5693 ok( attr->localName->length == 1, "got %lu\n", attr->localName->length );
5694 ok( !memcmp( attr->localName->bytes, "t", 1 ), "wrong name\n" );
5695 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
5696 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5697 ok( attr->value != NULL, "value not set\n" );
5698 utf8_text = (const WS_XML_UTF8_TEXT *)attr->value;
5699 ok( utf8_text->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8_text->text.textType );
5700 ok( utf8_text->value.length == 4, "got %lu\n", utf8_text->value.length );
5701 ok( !memcmp( utf8_text->value.bytes, "test", 4 ), "wrong value\n" );
5702 attr = elem->attributes[1];
5703 ok( !attr->singleQuote, "single quote\n" );
5704 ok( attr->isXmlNs, "not xmlns\n" );
5705 ok( attr->prefix->length == 2, "got %lu\n", attr->prefix->length );
5706 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
5707 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
5708 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
5710 hr = WsReadNode( reader, NULL );
5711 ok( hr == S_OK, "got %#lx\n", hr );
5712 hr = WsGetReaderNode( reader, &node, NULL );
5713 ok( hr == S_OK, "got %#lx\n", hr );
5714 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
5716 hr = WsReadNode( reader, NULL );
5717 ok( hr == S_OK, "got %#lx\n", hr );
5718 hr = WsGetReaderNode( reader, &node, NULL );
5719 ok( hr == S_OK, "got %#lx\n", hr );
5720 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
5722 /* comment */
5723 hr = set_input_bin( reader, test200, sizeof(test200), NULL );
5724 ok( hr == S_OK, "got %#lx\n", hr );
5726 hr = WsReadNode( reader, NULL );
5727 ok( hr == S_OK, "got %#lx\n", hr );
5728 hr = WsGetReaderNode( reader, &node, NULL );
5729 ok( hr == S_OK, "got %#lx\n", hr );
5730 ok( node->nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", node->nodeType );
5731 comment = (const WS_XML_COMMENT_NODE *)node;
5732 ok( comment->value.length == 7, "got %lu\n", comment->value.length );
5733 ok( !memcmp( comment->value.bytes, "comment", 7 ), "wrong data\n" );
5735 hr = set_input_bin( reader, test, sizeof(test), NULL );
5736 ok( hr == S_OK, "got %#lx\n", hr );
5738 found = -1;
5739 hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
5740 ok( hr == S_OK, "got %#lx\n", hr );
5741 ok( found == TRUE, "got %d\n", found );
5742 hr = WsReadStartElement( reader, NULL );
5743 ok( hr == S_OK, "got %#lx\n", hr );
5744 hr = WsReadEndElement( reader, NULL );
5745 ok( hr == S_OK, "got %#lx\n", hr );
5747 /* element with byte record text */
5748 hr = set_input_bin( reader, test5, sizeof(test5), NULL );
5749 ok( hr == S_OK, "got %#lx\n", hr );
5751 hr = WsReadNode( reader, NULL );
5752 ok( hr == S_OK, "got %#lx\n", hr );
5753 hr = WsReadNode( reader, NULL );
5754 ok( hr == S_OK, "got %#lx\n", hr );
5755 hr = WsGetReaderNode( reader, &node, NULL );
5756 ok( hr == S_OK, "got %#lx\n", hr );
5757 ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
5758 text_node = (const WS_XML_TEXT_NODE *)node;
5759 ok( text_node->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text_node->text->textType );
5760 base64_text = (const WS_XML_BASE64_TEXT *)text_node->text;
5761 ok( base64_text->length == 1, "got %lu\n", base64_text->length );
5762 ok( base64_text->bytes[0] == 'a', "wrong data %02x\n", base64_text->bytes[0] );
5764 /* element with mixed byte record text */
5765 hr = set_input_bin( reader, test6, sizeof(test6), NULL );
5766 ok( hr == S_OK, "got %#lx\n", hr );
5768 hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL );
5769 ok( hr == S_OK, "got %#lx\n", hr );
5771 memset( &f, 0, sizeof(f) );
5772 f.mapping = WS_ELEMENT_FIELD_MAPPING;
5773 f.localName = &localname;
5774 f.ns = &ns;
5775 f.type = WS_BYTES_TYPE;
5776 f.offset = FIELD_OFFSET(struct typetest, data);
5777 fields[0] = &f;
5779 memset( &s, 0, sizeof(s) );
5780 s.size = sizeof(struct typetest);
5781 s.alignment = TYPE_ALIGNMENT(struct typetest);
5782 s.fields = fields;
5783 s.fieldCount = 1;
5785 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
5786 WS_READ_REQUIRED_POINTER, heap, &typetest, sizeof(typetest), NULL );
5787 ok( hr == S_OK, "got %#lx\n", hr );
5788 ok( typetest->data.length == 2, "got %lu\n", typetest->data.length );
5789 ok( !memcmp( typetest->data.bytes, "ab", 2 ), "wrong data\n" );
5791 /* record value too large for description type */
5792 hr = set_input_bin( reader, test32, sizeof(test32), NULL );
5793 ok( hr == S_OK, "got %#lx\n", hr );
5795 hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL );
5796 ok( hr == S_OK, "got %#lx\n", hr );
5798 memset( &f, 0, sizeof(f) );
5799 f.mapping = WS_ELEMENT_FIELD_MAPPING;
5800 f.localName = &localname;
5801 f.ns = &ns;
5802 f.type = WS_UINT32_TYPE;
5803 f.offset = FIELD_OFFSET(struct typetest2, val);
5804 fields[0] = &f;
5806 memset( &s, 0, sizeof(s) );
5807 s.size = sizeof(struct typetest2);
5808 s.alignment = TYPE_ALIGNMENT(struct typetest2);
5809 s.fields = fields;
5810 s.fieldCount = 1;
5812 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
5813 WS_READ_REQUIRED_POINTER, heap, &typetest2, sizeof(typetest2), NULL );
5814 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %#lx\n", hr );
5816 /* record value too small for description type */
5817 hr = set_input_bin( reader, test16, sizeof(test16), NULL );
5818 ok( hr == S_OK, "got %#lx\n", hr );
5820 hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL );
5821 ok( hr == S_OK, "got %#lx\n", hr );
5823 memset( &f, 0, sizeof(f) );
5824 f.mapping = WS_ELEMENT_FIELD_MAPPING;
5825 f.localName = &localname;
5826 f.ns = &ns;
5827 f.type = WS_UINT64_TYPE;
5828 f.offset = FIELD_OFFSET(struct typetest3, val);
5829 fields[0] = &f;
5831 memset( &s, 0, sizeof(s) );
5832 s.size = sizeof(struct typetest3);
5833 s.alignment = TYPE_ALIGNMENT(struct typetest3);
5834 s.fields = fields;
5835 s.fieldCount = 1;
5837 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
5838 WS_READ_REQUIRED_POINTER, heap, &typetest3, sizeof(typetest3), NULL );
5839 ok( hr == WS_E_NUMERIC_OVERFLOW, "got %#lx\n", hr );
5841 /* Test optional ending field on a nested struct. */
5842 hr = set_input_bin( reader, test_endelem, sizeof(test_endelem), NULL );
5843 ok( hr == S_OK, "got %#lx\n", hr );
5845 memset( &f1[0], 0, sizeof(f1[0]) );
5846 f1[0].mapping = WS_ELEMENT_FIELD_MAPPING;
5847 f1[0].localName = &str_a;
5848 f1[0].ns = &ns;
5849 f1[0].type = WS_INT32_TYPE;
5850 fields[0] = &f1[0];
5852 memset( &f1[1], 0, sizeof(f1[1]) );
5853 f1[1].mapping = WS_ELEMENT_FIELD_MAPPING;
5854 f1[1].localName = &str_s;
5855 f1[1].ns = &ns;
5856 f1[1].type = WS_STRUCT_TYPE;
5857 f1[1].typeDescription = &s2;
5858 f1[1].options = WS_FIELD_POINTER;
5859 f1[1].offset = FIELD_OFFSET(struct test, s);
5860 fields[1] = &f1[1];
5862 memset( &f1[2], 0, sizeof(f1[2]) );
5863 f1[2].mapping = WS_ELEMENT_FIELD_MAPPING;
5864 f1[2].localName = &str_b;
5865 f1[2].ns = &ns;
5866 f1[2].type = WS_INT32_TYPE;
5867 f1[2].offset = FIELD_OFFSET(struct test, b);
5868 fields[2] = &f1[2];
5870 memset( &f2[0], 0, sizeof(f2[0]) );
5871 f2[0].mapping = WS_ELEMENT_FIELD_MAPPING;
5872 f2[0].localName = &str_s_a;
5873 f2[0].ns = &ns;
5874 f2[0].type = WS_INT32_TYPE;
5875 fields2[0] = &f2[0];
5877 memset( &f2[1], 0, sizeof(f2[1]) );
5878 f2[1].mapping = WS_ELEMENT_FIELD_MAPPING;
5879 f2[1].localName = &str_s_b;
5880 f2[1].ns = &ns;
5881 f2[1].type = WS_INT32_TYPE;
5882 f2[1].offset = FIELD_OFFSET(struct s, s_b);
5883 f2[1].options = WS_FIELD_OPTIONAL;
5884 fields2[1] = &f2[1];
5886 memset( &s2, 0, sizeof(s2) );
5887 s2.size = sizeof(struct s);
5888 s2.alignment = TYPE_ALIGNMENT(struct s);
5889 s2.fields = fields2;
5890 s2.fieldCount = 2;
5892 memset( &s, 0, sizeof(s) );
5893 s.size = sizeof(struct test);
5894 s.alignment = TYPE_ALIGNMENT(struct test);
5895 s.fields = fields;
5896 s.fieldCount = 3;
5898 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
5899 WS_READ_REQUIRED_POINTER, heap, &test_struct, sizeof(test_struct), NULL );
5900 ok( hr == S_OK, "got %#lx\n", hr );
5901 ok( test_struct->a == 1, "got %d\n", test_struct->a );
5902 ok( !!test_struct->s, "s is not set\n" );
5903 ok( test_struct->s->s_a == 1, "got %d\n", test_struct->s->s_a );
5904 ok( test_struct->s->s_b == 0, "got %d\n", test_struct->s->s_b );
5905 ok( test_struct->b == 1, "got %d\n", test_struct->b );
5907 WsFreeHeap( heap );
5908 WsFreeReader( reader );
5911 static void test_dictionary(void)
5913 static const GUID dict_static =
5914 {0xf93578f8,0x5852,0x4eb7,{0xa6,0xfc,0xe7,0x2b,0xb7,0x1d,0xb6,0x22}};
5915 static const char test[] =
5916 {0x42,0x04,0x01};
5917 static const char test2[] =
5918 {0x53,0x06,0x0b,0x01,'p',0x0a,0x01};
5919 static const char test3[] =
5920 {0x43,0x02,'p','2',0x06,0x0b,0x02,'p','2',0x0a,0x01};
5921 static const char test4[] =
5922 {0x42,0x06,0x06,0x06,0x98,0x00,0x01};
5923 static const char test5[] =
5924 {0x42,0x06,0x1b,0x06,0x98,0x00,0x0b,0x01,'p',0x0a,0x01};
5925 static const char test6[] =
5926 {0x42,0x06,0x07,0x02,'p','2',0x06,0x98,0x00,0x0b,0x02,'p','2',0x0a,0x01};
5927 static const char test7[] =
5928 {0x40,0x01,'t',0x0a,0x0a,0x01};
5929 static const char test8[] =
5930 {0x40,0x01,'t',0x0b,0x01,'p',0x0a,0x01};
5931 static const char test9[] =
5932 {0x42,0x0c,0x01};
5933 static const char test10[] =
5934 {0x42,0x04,0xab,0x0c,0x01};
5935 const WS_XML_NODE *node;
5936 const WS_XML_ELEMENT_NODE *elem;
5937 const WS_XML_ATTRIBUTE *attr;
5938 const WS_XML_UTF8_TEXT *utf8;
5939 WS_XML_STRING strings[6];
5940 WS_XML_DICTIONARY dict, *dict2;
5941 WS_XML_READER *reader;
5942 HRESULT hr;
5944 hr = WsCreateReader( NULL, 0, &reader, NULL );
5945 ok( hr == S_OK, "got %#lx\n", hr );
5947 strings[0].length = 0;
5948 strings[0].bytes = NULL;
5949 strings[0].dictionary = &dict;
5950 strings[0].id = 0;
5951 strings[1].length = 1;
5952 strings[1].bytes = (BYTE *)"p";
5953 strings[1].dictionary = &dict;
5954 strings[1].id = 1;
5955 strings[2].length = 1;
5956 strings[2].bytes = (BYTE *)"t";
5957 strings[2].dictionary = &dict;
5958 strings[2].id = ~0u;
5959 strings[3].length = 1;
5960 strings[3].bytes = (BYTE *)"u";
5961 strings[3].dictionary = &dict;
5962 strings[3].id = 3;
5963 strings[4].length = 2;
5964 strings[4].bytes = (BYTE *)"p2";
5965 strings[4].dictionary = &dict;
5966 strings[4].id = 4;
5967 strings[5].length = 2;
5968 strings[5].bytes = (BYTE *)"ns";
5969 strings[5].dictionary = &dict;
5970 strings[5].id = 5;
5972 UuidCreate( &dict.guid );
5973 dict.strings = strings;
5974 dict.stringCount = ARRAY_SIZE( strings );
5975 dict.isConst = TRUE;
5977 /* short dictionary element */
5978 hr = set_input_bin( reader, test, sizeof(test), &dict );
5979 ok( hr == S_OK, "got %#lx\n", hr );
5981 hr = WsReadNode( reader, NULL );
5982 ok( hr == S_OK, "got %#lx\n", hr );
5983 hr = WsGetReaderNode( reader, &node, NULL );
5984 ok( hr == S_OK, "got %#lx\n", hr );
5985 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
5986 elem = (const WS_XML_ELEMENT_NODE *)node;
5987 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
5988 ok( elem->prefix->bytes == NULL, "bytes set\n" );
5989 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
5990 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
5991 ok( elem->localName->dictionary == &dict, "unexpected dict\n" );
5992 ok( elem->localName->id == ~0u, "unexpected id %#lx\n", elem->localName->id );
5993 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
5994 ok( elem->ns->bytes != NULL, "bytes not set\n" );
5995 ok( !elem->attributeCount, "got %lu\n", elem->attributeCount );
5996 ok( !elem->isEmpty, "empty\n" );
5998 hr = WsReadNode( reader, NULL );
5999 ok( hr == S_OK, "got %#lx\n", hr );
6000 hr = WsGetReaderNode( reader, &node, NULL );
6001 ok( hr == S_OK, "got %#lx\n", hr );
6002 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
6004 /* single character prefix dictionary element */
6005 hr = set_input_bin( reader, test2, sizeof(test2), &dict );
6006 ok( hr == S_OK, "got %#lx\n", hr );
6008 hr = WsReadNode( reader, NULL );
6009 ok( hr == S_OK, "got %#lx\n", hr );
6010 hr = WsGetReaderNode( reader, &node, NULL );
6011 ok( hr == S_OK, "got %#lx\n", hr );
6012 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6013 elem = (const WS_XML_ELEMENT_NODE *)node;
6014 ok( elem->prefix->length == 1, "got %lu\n", elem->prefix->length );
6015 ok( !memcmp( elem->prefix->bytes, "p", 1 ), "wrong prefix\n" );
6016 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
6017 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
6018 ok( elem->ns->length == 2, "got %lu\n", elem->ns->length );
6019 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
6020 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
6021 ok( !elem->isEmpty, "empty\n" );
6022 attr = elem->attributes[0];
6023 ok( !attr->singleQuote, "single quote\n" );
6024 ok( attr->isXmlNs, "not xmlns\n" );
6025 ok( attr->prefix->length == 1, "got %lu\n", attr->prefix->length );
6026 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
6027 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
6028 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
6029 ok( attr->ns->dictionary == &dict, "unexpected dict\n" );
6030 ok( attr->ns->id == 5, "unexpected id %#lx\n", attr->ns->id );
6032 hr = WsReadNode( reader, NULL );
6033 ok( hr == S_OK, "got %#lx\n", hr );
6034 hr = WsGetReaderNode( reader, &node, NULL );
6035 ok( hr == S_OK, "got %#lx\n", hr );
6036 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
6038 /* dictionary element */
6039 hr = set_input_bin( reader, test3, sizeof(test3), &dict );
6040 ok( hr == S_OK, "got %#lx\n", hr );
6042 hr = WsReadNode( reader, NULL );
6043 ok( hr == S_OK, "got %#lx\n", hr );
6044 hr = WsGetReaderNode( reader, &node, NULL );
6045 ok( hr == S_OK, "got %#lx\n", hr );
6046 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6047 elem = (const WS_XML_ELEMENT_NODE *)node;
6048 ok( elem->prefix->length == 2, "got %lu\n", elem->prefix->length );
6049 ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
6050 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
6051 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
6052 ok( elem->localName->dictionary == &dict, "unexpected dict\n" );
6053 ok( elem->localName->id == 3, "unexpected id %#lx\n", elem->localName->id );
6054 ok( elem->ns->length == 2, "got %lu\n", elem->ns->length );
6055 ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
6056 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
6057 ok( !elem->isEmpty, "empty\n" );
6058 attr = elem->attributes[0];
6059 ok( !attr->singleQuote, "single quote\n" );
6060 ok( attr->isXmlNs, "not xmlns\n" );
6061 ok( attr->prefix->length == 2, "got %lu\n", attr->prefix->length );
6062 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
6063 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
6064 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
6066 hr = WsReadNode( reader, NULL );
6067 ok( hr == S_OK, "got %#lx\n", hr );
6068 hr = WsGetReaderNode( reader, &node, NULL );
6069 ok( hr == S_OK, "got %#lx\n", hr );
6070 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
6072 /* short dictionary attribute */
6073 hr = set_input_bin( reader, test4, sizeof(test4), &dict );
6074 ok( hr == S_OK, "got %#lx\n", hr );
6076 hr = WsReadNode( reader, NULL );
6077 ok( hr == S_OK, "got %#lx\n", hr );
6078 hr = WsGetReaderNode( reader, &node, NULL );
6079 ok( hr == S_OK, "got %#lx\n", hr );
6080 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6081 elem = (const WS_XML_ELEMENT_NODE *)node;
6082 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
6083 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
6084 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
6085 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
6086 ok( elem->ns->bytes != NULL, "bytes not set\n" );
6087 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
6088 ok( !elem->isEmpty, "empty\n" );
6089 attr = elem->attributes[0];
6090 ok( !attr->singleQuote, "single quote\n" );
6091 ok( !attr->isXmlNs, "is xmlns\n" );
6092 ok( !attr->prefix->length, "got %lu\n", attr->prefix->length );
6093 ok( attr->localName->length == 1, "got %lu\n", attr->localName->length );
6094 ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
6095 ok( attr->localName->id == 3, "unexpected id %#lx\n", attr->localName->id );
6096 ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
6097 ok( !attr->ns->length, "got %lu\n", attr->ns->length );
6098 ok( elem->ns->bytes != NULL, "bytes not set\n" );
6099 ok( attr->value != NULL, "value not set\n" );
6100 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
6101 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
6102 ok( !utf8->value.length, "got %lu\n", utf8->value.length );
6103 ok( utf8->value.bytes != NULL, "bytes not set\n" );
6105 hr = WsReadNode( reader, NULL );
6106 ok( hr == S_OK, "got %#lx\n", hr );
6107 hr = WsGetReaderNode( reader, &node, NULL );
6108 ok( hr == S_OK, "got %#lx\n", hr );
6109 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
6111 /* single character prefix dictionary attribute */
6112 hr = set_input_bin( reader, test5, sizeof(test5), &dict );
6113 ok( hr == S_OK, "got %#lx\n", hr );
6115 hr = WsReadNode( reader, NULL );
6116 ok( hr == S_OK, "got %#lx\n", hr );
6117 hr = WsGetReaderNode( reader, &node, NULL );
6118 ok( hr == S_OK, "got %#lx\n", hr );
6119 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6120 elem = (const WS_XML_ELEMENT_NODE *)node;
6121 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
6122 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
6123 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
6124 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
6125 ok( elem->ns->bytes != NULL, "ns not set\n" );
6126 ok( elem->attributeCount == 2, "got %lu\n", elem->attributeCount );
6127 ok( !elem->isEmpty, "empty\n" );
6128 attr = elem->attributes[0];
6129 ok( !attr->singleQuote, "single quote\n" );
6130 ok( !attr->isXmlNs, "is xmlns\n" );
6131 ok( attr->prefix->length == 1, "got %lu\n", attr->prefix->length );
6132 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
6133 ok( attr->localName->length == 1, "got %lu\n", attr->localName->length );
6134 ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
6135 ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
6136 ok( attr->localName->id == 3, "unexpected id %#lx\n", attr->localName->id );
6137 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
6138 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
6139 ok( attr->value != NULL, "value not set\n" );
6140 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
6141 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
6142 ok( !utf8->value.length, "got %lu\n", utf8->value.length );
6143 ok( utf8->value.bytes != NULL, "bytes not set\n" );
6144 attr = elem->attributes[1];
6145 ok( !attr->singleQuote, "single quote\n" );
6146 ok( attr->isXmlNs, "not xmlns\n" );
6147 ok( attr->prefix->length == 1, "got %lu\n", attr->prefix->length );
6148 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
6149 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
6150 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
6152 hr = WsReadNode( reader, NULL );
6153 ok( hr == S_OK, "got %#lx\n", hr );
6154 hr = WsGetReaderNode( reader, &node, NULL );
6155 ok( hr == S_OK, "got %#lx\n", hr );
6156 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
6158 /* dictionary attribute */
6159 hr = set_input_bin( reader, test6, sizeof(test6), &dict );
6160 ok( hr == S_OK, "got %#lx\n", hr );
6162 hr = WsReadNode( reader, NULL );
6163 ok( hr == S_OK, "got %#lx\n", hr );
6164 hr = WsGetReaderNode( reader, &node, NULL );
6165 ok( hr == S_OK, "got %#lx\n", hr );
6166 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6167 elem = (const WS_XML_ELEMENT_NODE *)node;
6168 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
6169 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
6170 ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
6171 ok( !elem->ns->length, "got %lu\n", elem->ns->length );
6172 ok( elem->ns->bytes != NULL, "ns not set\n" );
6173 ok( elem->attributeCount == 2, "got %lu\n", elem->attributeCount );
6174 ok( !elem->isEmpty, "empty\n" );
6175 attr = elem->attributes[0];
6176 ok( !attr->singleQuote, "single quote\n" );
6177 ok( !attr->isXmlNs, "is xmlns\n" );
6178 ok( attr->prefix->length == 2, "got %lu\n", attr->prefix->length );
6179 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
6180 ok( attr->localName->length == 1, "got %lu\n", attr->localName->length );
6181 ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
6182 ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
6183 ok( attr->localName->id == 3, "unexpected id %#lx\n", attr->localName->id );
6184 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
6185 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
6186 ok( attr->value != NULL, "value not set\n" );
6187 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
6188 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
6189 ok( !utf8->value.length, "got %lu\n", utf8->value.length );
6190 ok( utf8->value.bytes != NULL, "bytes not set\n" );
6191 attr = elem->attributes[1];
6192 ok( !attr->singleQuote, "single quote\n" );
6193 ok( attr->isXmlNs, "not xmlns\n" );
6194 ok( attr->prefix->length == 2, "got %lu\n", attr->prefix->length );
6195 ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
6196 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
6197 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
6199 /* short dictionary xmlns attribute */
6200 hr = set_input_bin( reader, test7, sizeof(test7), &dict );
6201 ok( hr == S_OK, "got %#lx\n", hr );
6203 hr = WsReadNode( reader, NULL );
6204 ok( hr == S_OK, "got %#lx\n", hr );
6205 hr = WsGetReaderNode( reader, &node, NULL );
6206 ok( hr == S_OK, "got %#lx\n", hr );
6207 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6208 elem = (const WS_XML_ELEMENT_NODE *)node;
6209 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
6210 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
6211 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
6212 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
6213 ok( !elem->isEmpty, "empty\n" );
6214 attr = elem->attributes[0];
6215 ok( !attr->singleQuote, "single quote\n" );
6216 ok( attr->isXmlNs, "not xmlns\n" );
6217 ok( !attr->prefix->length, "got %lu\n", attr->prefix->length );
6218 ok( attr->prefix->bytes == NULL, "bytes set\n" );
6219 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
6220 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
6221 ok( attr->ns->dictionary == &dict, "unexpected dict\n" );
6222 ok( attr->ns->id == 5, "unexpected id %#lx\n", attr->ns->id );
6223 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
6224 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
6225 ok( !utf8->value.length, "got %lu\n", utf8->value.length );
6226 todo_wine ok( utf8->value.bytes != NULL, "bytes not set\n" );
6228 /* dictionary xmlns attribute */
6229 hr = set_input_bin( reader, test8, sizeof(test8), &dict );
6230 ok( hr == S_OK, "got %#lx\n", hr );
6232 hr = WsReadNode( reader, NULL );
6233 ok( hr == S_OK, "got %#lx\n", hr );
6234 hr = WsGetReaderNode( reader, &node, NULL );
6235 ok( hr == S_OK, "got %#lx\n", hr );
6236 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6237 elem = (const WS_XML_ELEMENT_NODE *)node;
6238 ok( !elem->prefix->length, "got %lu\n", elem->prefix->length );
6239 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
6240 ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
6241 ok( elem->attributeCount == 1, "got %lu\n", elem->attributeCount );
6242 ok( !elem->isEmpty, "empty\n" );
6243 attr = elem->attributes[0];
6244 ok( !attr->singleQuote, "single quote\n" );
6245 ok( attr->isXmlNs, "not xmlns\n" );
6246 ok( attr->prefix->length == 1, "got %lu\n", attr->prefix->length );
6247 ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
6248 ok( attr->ns->length == 2, "got %lu\n", attr->ns->length );
6249 ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
6250 ok( attr->ns->dictionary == &dict, "unexpected dict\n" );
6251 ok( attr->ns->id == 5, "unexpected id %#lx\n", attr->ns->id );
6252 utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
6253 ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
6254 ok( !utf8->value.length, "got %lu\n", utf8->value.length );
6255 todo_wine ok( utf8->value.bytes != NULL, "bytes not set\n" );
6257 hr = WsReadNode( reader, NULL );
6258 ok( hr == S_OK, "got %#lx\n", hr );
6259 hr = WsGetReaderNode( reader, &node, NULL );
6260 ok( hr == S_OK, "got %#lx\n", hr );
6261 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
6263 /* element name string id out of range */
6264 hr = set_input_bin( reader, test9, sizeof(test9), &dict );
6265 ok( hr == S_OK, "got %#lx\n", hr );
6266 hr = WsReadNode( reader, NULL );
6267 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
6269 /* text string id out of range */
6270 hr = set_input_bin( reader, test10, sizeof(test10), &dict );
6271 ok( hr == S_OK, "got %#lx\n", hr );
6272 hr = WsReadNode( reader, NULL );
6273 ok( hr == S_OK, "got %#lx\n", hr );
6274 hr = WsGetReaderNode( reader, &node, NULL );
6275 ok( hr == S_OK, "got %#lx\n", hr );
6276 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6277 hr = WsReadNode( reader, NULL );
6278 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
6280 hr = WsGetDictionary( 0, NULL, NULL );
6281 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
6283 hr = WsGetDictionary( WS_ENCODING_XML_UTF8, NULL, NULL );
6284 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
6286 dict2 = (WS_XML_DICTIONARY *)0xdeadbeef;
6287 hr = WsGetDictionary( WS_ENCODING_XML_UTF8, &dict2, NULL );
6288 ok( hr == S_OK, "got %#lx\n", hr );
6289 ok( dict2 == NULL, "got %p\n", dict2 );
6291 dict2 = NULL;
6292 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_1, &dict2, NULL );
6293 ok( hr == S_OK, "got %#lx\n", hr );
6294 ok( dict2 != NULL, "dict2 not set\n" );
6295 ok( dict2 != &dict, "got %p\n", dict2 );
6297 dict2 = NULL;
6298 hr = WsGetDictionary( WS_ENCODING_XML_BINARY_SESSION_1, &dict2, NULL );
6299 ok( hr == S_OK, "got %#lx\n", hr );
6300 ok( dict2 != NULL, "dict2 not set\n" );
6301 ok( dict2 != &dict, "got %p\n", dict2 );
6302 ok( !memcmp( &dict2->guid, &dict_static, sizeof(dict_static) ),
6303 "got %s\n", wine_dbgstr_guid(&dict2->guid) );
6304 ok( dict2->stringCount == 488 || dict2->stringCount == 487 /* < win10 */, "got %lu\n", dict2->stringCount );
6305 ok( dict2->strings[0].length == 14, "got %lu\n", dict2->strings[0].length );
6306 ok( !memcmp( dict2->strings[0].bytes, "mustUnderstand", 14 ), "wrong data\n" );
6308 WsFreeReader( reader );
6311 static HRESULT prepare_xml_buffer_test( WS_XML_READER *reader, WS_HEAP *heap )
6313 WS_XML_STRING localname = {1, (BYTE *)"t"}, localname2 = {1, (BYTE *)"u"}, ns = {0, NULL};
6314 WS_XML_WRITER *writer;
6315 WS_XML_BUFFER *buffer;
6316 HRESULT hr;
6318 hr = WsCreateWriter( NULL, 0, &writer, NULL );
6319 ok( hr == S_OK, "got %#lx\n", hr );
6321 hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
6322 ok( hr == S_OK, "got %#lx\n", hr );
6324 hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
6325 ok( hr == S_OK, "got %#lx\n", hr );
6327 hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
6328 ok( hr == S_OK, "got %#lx\n", hr );
6329 hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
6330 ok( hr == S_OK, "got %#lx\n", hr );
6331 hr = WsWriteEndElement( writer, NULL );
6332 ok( hr == S_OK, "got %#lx\n", hr );
6333 hr = WsWriteEndElement( writer, NULL );
6334 ok( hr == S_OK, "got %#lx\n", hr );
6336 hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
6337 ok( hr == S_OK, "got %#lx\n", hr );
6338 WsFreeWriter( writer );
6339 return S_OK;
6342 static void test_WsReadXmlBuffer(void)
6344 const WS_XML_NODE *node;
6345 WS_XML_READER *reader;
6346 WS_XML_BUFFER *buffer;
6347 WS_HEAP *heap;
6348 HRESULT hr;
6350 hr = WsReadXmlBuffer( NULL, NULL, NULL, NULL );
6351 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
6353 hr = WsCreateReader( NULL, 0, &reader, NULL );
6354 ok( hr == S_OK, "got %#lx\n", hr );
6356 hr = WsReadXmlBuffer( reader, NULL, NULL, NULL );
6357 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
6359 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
6360 ok( hr == S_OK, "got %#lx\n", hr );
6362 hr = WsReadXmlBuffer( reader, heap, NULL, NULL );
6363 ok( hr == E_FAIL, "got %#lx\n", hr );
6365 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6366 todo_wine ok( hr == E_FAIL, "got %#lx\n", hr );
6368 hr = set_input( reader, "<t><u><v/></u></t></w>", sizeof("<t><u><v/></u></t></w>") - 1 );
6369 ok( hr == S_OK, "got %#lx\n", hr );
6371 hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
6372 ok( hr == S_OK, "got %#lx\n", hr );
6374 hr = WsReadStartElement( reader, NULL );
6375 ok( hr == S_OK, "got %#lx\n", hr );
6377 hr = WsGetReaderNode( reader, &node, NULL );
6378 ok( hr == S_OK, "got %#lx\n", hr );
6379 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6381 /* reader positioned at element */
6382 buffer = NULL;
6383 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6384 ok( hr == S_OK, "got %#lx\n", hr );
6385 ok( buffer != NULL, "buffer not set\n" );
6386 check_output_buffer( buffer, "<u><v/></u>", __LINE__ );
6388 hr = WsGetReaderNode( reader, &node, NULL );
6389 ok( hr == S_OK, "got %#lx\n", hr );
6390 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
6392 /* reader positioned at end element */
6393 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6394 ok( hr == E_FAIL, "got %#lx\n", hr );
6396 hr = set_input( reader, "<t><u/></t><v/>", sizeof("<t><u/></t><v/>") - 1 );
6397 ok( hr == S_OK, "got %#lx\n", hr );
6399 hr = WsGetReaderNode( reader, &node, NULL );
6400 ok( hr == S_OK, "got %#lx\n", hr );
6401 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
6403 /* reader positioned at BOF */
6404 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6405 todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
6407 hr = WsGetReaderNode( reader, &node, NULL );
6408 ok( hr == S_OK, "got %#lx\n", hr );
6409 todo_wine ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
6411 hr = set_input( reader, "<!--comment--><t></t>", sizeof("<!--comment--><t></t>") - 1 );
6412 ok( hr == S_OK, "got %#lx\n", hr );
6414 hr = WsReadNode( reader, NULL );
6415 ok( hr == S_OK, "got %#lx\n", hr );
6417 hr = WsGetReaderNode( reader, &node, NULL );
6418 ok( hr == S_OK, "got %#lx\n", hr );
6419 ok( node->nodeType == WS_XML_NODE_TYPE_COMMENT, "got %u\n", node->nodeType );
6421 /* reader positioned at non-element */
6422 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6423 ok( hr == E_FAIL, "got %#lx\n", hr );
6425 hr = prepare_xml_buffer_test( reader, heap );
6426 ok( hr == S_OK, "got %#lx\n", hr );
6428 hr = WsGetReaderNode( reader, &node, NULL );
6429 ok( hr == S_OK, "got %#lx\n", hr );
6430 ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
6432 /* reader positioned at BOF, input buffer */
6433 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6434 ok( hr == S_OK, "got %#lx\n", hr );
6435 check_output_buffer( buffer, "<t><u/></t>", __LINE__ );
6437 hr = WsGetReaderNode( reader, &node, NULL );
6438 ok( hr == S_OK, "got %#lx\n", hr );
6439 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
6441 /* reader positioned at EOF, input buffer */
6442 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6443 ok( hr == E_FAIL, "got %#lx\n", hr );
6445 hr = prepare_xml_buffer_test( reader, heap );
6446 ok( hr == S_OK, "got %#lx\n", hr );
6448 hr = WsReadNode( reader, NULL );
6449 ok( hr == S_OK, "got %#lx\n", hr );
6450 hr = WsReadNode( reader, NULL );
6451 ok( hr == S_OK, "got %#lx\n", hr );
6453 hr = WsGetReaderNode( reader, &node, NULL );
6454 ok( hr == S_OK, "got %#lx\n", hr );
6455 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6457 /* reader positioned at element, input buffer */
6458 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6459 ok( hr == S_OK, "got %#lx\n", hr );
6460 check_output_buffer( buffer, "<u/>", __LINE__ );
6462 hr = WsGetReaderNode( reader, &node, NULL );
6463 ok( hr == S_OK, "got %#lx\n", hr );
6464 ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
6466 /* reader positioned at end element, input buffer */
6467 hr = WsReadXmlBuffer( reader, heap, &buffer, NULL );
6468 ok( hr == E_FAIL, "got %#lx\n", hr );
6470 WsFreeReader( reader );
6471 WsFreeHeap( heap );
6474 static void test_union_type(void)
6476 static WS_XML_STRING str_ns = {0, NULL}, str_a = {1, (BYTE *)"a"}, str_b = {1, (BYTE *)"b"};
6477 static WS_XML_STRING str_s = {1, (BYTE *)"s"};
6478 HRESULT hr;
6479 WS_XML_READER *reader;
6480 WS_HEAP *heap;
6481 WS_UNION_DESCRIPTION u;
6482 WS_UNION_FIELD_DESCRIPTION f, f2, *fields[2];
6483 WS_FIELD_DESCRIPTION f_struct, *fields_struct[1];
6484 WS_STRUCT_DESCRIPTION s;
6485 const WS_XML_NODE *node;
6486 enum choice {CHOICE_A, CHOICE_B, CHOICE_NONE};
6487 struct test
6489 enum choice choice;
6490 union
6492 WCHAR *a;
6493 UINT32 b;
6494 } value;
6495 } *test;
6497 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
6498 ok( hr == S_OK, "got %#lx\n", hr );
6500 hr = WsCreateReader( NULL, 0, &reader, NULL );
6501 ok( hr == S_OK, "got %#lx\n", hr );
6503 memset( &f, 0, sizeof(f) );
6504 f.value = CHOICE_A;
6505 f.field.mapping = WS_ELEMENT_FIELD_MAPPING;
6506 f.field.localName = &str_a;
6507 f.field.ns = &str_ns;
6508 f.field.type = WS_WSZ_TYPE;
6509 f.field.offset = FIELD_OFFSET(struct test, value.a);
6510 fields[0] = &f;
6512 memset( &f2, 0, sizeof(f2) );
6513 f2.value = CHOICE_B;
6514 f2.field.mapping = WS_ELEMENT_FIELD_MAPPING;
6515 f2.field.localName = &str_b;
6516 f2.field.ns = &str_ns;
6517 f2.field.type = WS_UINT32_TYPE;
6518 f2.field.offset = FIELD_OFFSET(struct test, value.b);
6519 fields[1] = &f2;
6521 memset( &u, 0, sizeof(u) );
6522 u.size = sizeof(struct test);
6523 u.alignment = TYPE_ALIGNMENT(struct test);
6524 u.fields = fields;
6525 u.fieldCount = 2;
6526 u.enumOffset = FIELD_OFFSET(struct test, choice);
6527 u.noneEnumValue = CHOICE_NONE;
6529 memset( &f_struct, 0, sizeof(f_struct) );
6530 f_struct.mapping = WS_ELEMENT_CHOICE_FIELD_MAPPING;
6531 f_struct.type = WS_UNION_TYPE;
6532 f_struct.typeDescription = &u;
6533 fields_struct[0] = &f_struct;
6535 memset( &s, 0, sizeof(s) );
6536 s.size = sizeof(struct test);
6537 s.alignment = TYPE_ALIGNMENT(struct test);
6538 s.fields = fields_struct;
6539 s.fieldCount = 1;
6540 s.typeLocalName = &str_s;
6541 s.typeNs = &str_ns;
6543 test = NULL;
6544 prepare_struct_type_test( reader, "<a>test</a>" );
6545 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6546 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6547 ok( hr == S_OK, "got %#lx\n", hr );
6548 ok( test != NULL, "test not set\n" );
6549 ok( test->choice == CHOICE_A, "got %d\n", test->choice );
6550 ok( !wcscmp(test->value.a, L"test"), "got %s\n", wine_dbgstr_w(test->value.a) );
6551 hr = WsGetReaderNode( reader, &node, NULL );
6552 ok( hr == S_OK, "got %#lx\n", hr );
6553 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
6555 test = NULL;
6556 prepare_struct_type_test( reader, "<b>123</b>" );
6557 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6558 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6559 ok( hr == S_OK, "got %#lx\n", hr );
6560 ok( test != NULL, "test not set\n" );
6561 ok( test->choice == CHOICE_B, "got %d\n", test->choice );
6562 ok( test->value.b == 123, "got %u\n", test->value.b );
6564 prepare_struct_type_test( reader, "<c>456</c>" );
6565 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6566 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6567 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
6568 hr = WsGetReaderNode( reader, &node, NULL );
6569 ok( hr == S_OK, "got %#lx\n", hr );
6570 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6572 f_struct.options = WS_FIELD_NILLABLE;
6573 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6574 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6575 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
6577 f_struct.options = WS_FIELD_POINTER|WS_FIELD_NILLABLE;
6578 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6579 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6580 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
6582 f_struct.options = WS_FIELD_POINTER;
6583 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6584 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6585 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
6587 test = NULL;
6588 f_struct.options = WS_FIELD_OPTIONAL;
6589 prepare_struct_type_test( reader, "<c>456</c>" );
6590 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6591 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6592 todo_wine ok( hr == S_OK, "got %#lx\n", hr );
6593 ok( test != NULL, "test not set\n" );
6594 ok( test->choice == CHOICE_NONE, "got %d\n", test->choice );
6595 hr = WsGetReaderNode( reader, &node, NULL );
6596 ok( hr == S_OK, "got %#lx\n", hr );
6597 ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6599 WsFreeReader( reader );
6600 WsFreeHeap( heap );
6603 static void test_float(void)
6605 static const struct
6607 const char *str;
6608 HRESULT hr;
6609 ULONG val;
6611 tests[] =
6613 {"<t>0.0</t>", S_OK, 0},
6614 {"<t>-0.0</t>", S_OK, 0x80000000},
6615 {"<t>+0.0</t>", S_OK, 0},
6616 {"<t>-</t>", S_OK, 0},
6617 {"<t>+</t>", S_OK, 0},
6618 {"<t>.0</t>", S_OK, 0},
6619 {"<t>0.</t>", S_OK, 0},
6620 {"<t>0</t>", S_OK, 0},
6621 {"<t> 0 </t>", S_OK, 0},
6622 {"<t></t>", WS_E_INVALID_FORMAT, 0},
6623 {"<t>0,1</t>", WS_E_INVALID_FORMAT, 0},
6624 {"<t>1.1.</t>", WS_E_INVALID_FORMAT, 0},
6625 {"<t>1</t>", S_OK, 0x3f800000},
6626 {"<t>1.0000001</t>", S_OK, 0x3f800001},
6627 {"<t>1.0000002</t>", S_OK, 0x3f800002},
6628 {"<t>10000000000000000000</t>", S_OK, 0x5f0ac723},
6629 {"<t>100000000000000000000</t>", S_OK, 0x60ad78ec},
6630 {"<t>2</t>", S_OK, 0x40000000},
6631 {"<t>-2</t>", S_OK, 0xc0000000},
6632 {"<t>nofloat</t>", WS_E_INVALID_FORMAT, 0},
6633 {"<t>INF</t>", S_OK, 0x7f800000},
6634 {"<t>-INF</t>", S_OK, 0xff800000},
6635 {"<t>+INF</t>", WS_E_INVALID_FORMAT, 0},
6636 {"<t>Infinity</t>", WS_E_INVALID_FORMAT, 0},
6637 {"<t>-Infinity</t>", WS_E_INVALID_FORMAT, 0},
6638 {"<t>inf</t>", WS_E_INVALID_FORMAT, 0},
6639 {"<t>NaN</t>", S_OK, 0xffc00000},
6640 {"<t>-NaN</t>", WS_E_INVALID_FORMAT, 0},
6641 {"<t>NAN</t>", WS_E_INVALID_FORMAT, 0},
6642 {"<t>0.3</t>", S_OK, 0x3e99999a},
6643 {"<t>0.33</t>", S_OK, 0x3ea8f5c3},
6644 {"<t>0.333</t>", S_OK, 0x3eaa7efa},
6645 {"<t>0.3333</t>", S_OK, 0x3eaaa64c},
6646 {"<t>0.33333</t>", S_OK, 0x3eaaaa3b},
6647 {"<t>0.333333</t>", S_OK, 0x3eaaaa9f},
6648 {"<t>0.3333333</t>", S_OK, 0x3eaaaaaa},
6649 {"<t>0.33333333</t>", S_OK, 0x3eaaaaab},
6650 {"<t>0.333333333</t>", S_OK, 0x3eaaaaab},
6651 {"<t>0.1e10</t>", S_OK, 0x4e6e6b28},
6652 {"<t>1e</t>", WS_E_INVALID_FORMAT, 0},
6653 {"<t>1e0</t>", S_OK, 0x3f800000},
6654 {"<t>1e+1</t>", S_OK, 0x41200000},
6655 {"<t>1e-1</t>", S_OK, 0x3dcccccd},
6656 {"<t>e10</t>", WS_E_INVALID_FORMAT, 0},
6657 {"<t>1e10.</t>", WS_E_INVALID_FORMAT, 0},
6658 {"<t>1E10</t>", S_OK, 0x501502f9},
6659 {"<t>1e10</t>", S_OK, 0x501502f9},
6660 {"<t>1e-10</t>", S_OK, 0x2edbe6ff},
6661 {"<t>3.4028235e38</t>", S_OK, 0x7f7fffff},
6662 {"<t>3.4028236e38</t>", S_OK, 0x7f800000},
6663 {"<t>1.1754942e-38</t>", S_OK, 0x007fffff},
6664 {"<t>1.1754943e-38</t>", S_OK, 0x00800000},
6666 HRESULT hr;
6667 WS_XML_READER *reader;
6668 WS_HEAP *heap;
6669 ULONG val, i;
6671 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
6672 ok( hr == S_OK, "got %#lx\n", hr );
6674 hr = WsCreateReader( NULL, 0, &reader, NULL );
6675 ok( hr == S_OK, "got %#lx\n", hr );
6677 for (i = 0; i < ARRAY_SIZE( tests ); i++)
6679 val = 0;
6680 prepare_type_test( reader, tests[i].str, strlen(tests[i].str) );
6681 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_FLOAT_TYPE, NULL,
6682 WS_READ_REQUIRED_VALUE, heap, &val, sizeof(val), NULL );
6683 ok( hr == tests[i].hr, "%lu: got %#lx\n", i, hr );
6684 if (hr == tests[i].hr) ok( val == tests[i].val, "%lu: got %#lx\n", i, val );
6687 WsFreeReader( reader );
6688 WsFreeHeap( heap );
6691 static void test_repeating_element_choice(void)
6693 static WS_XML_STRING str_ns = {0, NULL}, str_a = {1, (BYTE *)"a"}, str_b = {1, (BYTE *)"b"};
6694 static WS_XML_STRING str_s = {1, (BYTE *)"s"}, str_t = {1, (BYTE *)"t"};
6695 HRESULT hr;
6696 WS_XML_READER *reader;
6697 WS_HEAP *heap;
6698 WS_UNION_DESCRIPTION u;
6699 WS_UNION_FIELD_DESCRIPTION f, f2, *fields[2];
6700 WS_FIELD_DESCRIPTION f_items, *fields_items[1];
6701 WS_STRUCT_DESCRIPTION s;
6702 const WS_XML_NODE *node;
6703 enum choice {CHOICE_A, CHOICE_B, CHOICE_NONE};
6704 struct item
6706 enum choice choice;
6707 union
6709 WCHAR *a;
6710 UINT32 b;
6711 } value;
6713 struct test
6715 struct item *items;
6716 ULONG count;
6717 } *test;
6719 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
6720 ok( hr == S_OK, "got %#lx\n", hr );
6722 hr = WsCreateReader( NULL, 0, &reader, NULL );
6723 ok( hr == S_OK, "got %#lx\n", hr );
6725 memset( &f, 0, sizeof(f) );
6726 f.value = CHOICE_A;
6727 f.field.mapping = WS_ELEMENT_FIELD_MAPPING;
6728 f.field.localName = &str_a;
6729 f.field.ns = &str_ns;
6730 f.field.type = WS_WSZ_TYPE;
6731 f.field.offset = FIELD_OFFSET(struct item, value.a);
6732 fields[0] = &f;
6734 memset( &f2, 0, sizeof(f2) );
6735 f2.value = CHOICE_B;
6736 f2.field.mapping = WS_ELEMENT_FIELD_MAPPING;
6737 f2.field.localName = &str_b;
6738 f2.field.ns = &str_ns;
6739 f2.field.type = WS_UINT32_TYPE;
6740 f2.field.offset = FIELD_OFFSET(struct item, value.b);
6741 fields[1] = &f2;
6743 memset( &u, 0, sizeof(u) );
6744 u.size = sizeof(struct item);
6745 u.alignment = TYPE_ALIGNMENT(struct item);
6746 u.fields = fields;
6747 u.fieldCount = 2;
6748 u.enumOffset = FIELD_OFFSET(struct item, choice);
6749 u.noneEnumValue = CHOICE_NONE;
6751 memset( &f_items, 0, sizeof(f_items) );
6752 f_items.mapping = WS_REPEATING_ELEMENT_CHOICE_FIELD_MAPPING;
6753 f_items.localName = &str_t;
6754 f_items.ns = &str_ns;
6755 f_items.type = WS_UNION_TYPE;
6756 f_items.typeDescription = &u;
6757 f_items.countOffset = FIELD_OFFSET(struct test, count);
6758 fields_items[0] = &f_items;
6760 memset( &s, 0, sizeof(s) );
6761 s.size = sizeof(struct test);
6762 s.alignment = TYPE_ALIGNMENT(struct test);
6763 s.fields = fields_items;
6764 s.fieldCount = 1;
6765 s.typeLocalName = &str_s;
6766 s.typeNs = &str_ns;
6768 test = NULL;
6769 prepare_struct_type_test( reader, "<t><a>test</a></t>" );
6770 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6771 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6772 ok( hr == S_OK, "got %#lx\n", hr );
6773 ok( test != NULL, "test not set\n" );
6774 ok( test->count == 1, "got %lu\n", test->count );
6775 ok( test->items[0].choice == CHOICE_A, "got %d\n", test->items[0].choice );
6776 ok( !wcscmp(test->items[0].value.a, L"test"), "got %s\n", wine_dbgstr_w(test->items[0].value.a) );
6778 test = NULL;
6779 prepare_struct_type_test( reader, "<t><b>123</b></t>" );
6780 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6781 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6782 ok( hr == S_OK, "got %#lx\n", hr );
6783 ok( test != NULL, "test not set\n" );
6784 ok( test->count == 1, "got %lu\n", test->count );
6785 ok( test->items[0].choice == CHOICE_B, "got %d\n", test->items[0].choice );
6786 ok( test->items[0].value.b == 123, "got %u\n", test->items[0].value.b );
6788 test = NULL;
6789 prepare_struct_type_test( reader, "<t><a>test</a><b>123</b></t>" );
6790 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6791 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6792 ok( hr == S_OK, "got %#lx\n", hr );
6793 ok( test != NULL, "test not set\n" );
6794 ok( test->count == 2, "got %lu\n", test->count );
6795 ok( test->items[0].choice == CHOICE_A, "got %d\n", test->items[0].choice );
6796 ok( !wcscmp(test->items[0].value.a, L"test"), "got %s\n", wine_dbgstr_w(test->items[0].value.a) );
6797 ok( test->items[1].choice == CHOICE_B, "got %d\n", test->items[1].choice );
6798 ok( test->items[1].value.b == 123, "got %u\n", test->items[1].value.b );
6800 prepare_struct_type_test( reader, "<t><c>123</c></t>" );
6801 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6802 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6803 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
6805 hr = WsGetReaderNode( reader, &node, NULL );
6806 ok( hr == S_OK, "got %#lx\n", hr );
6807 todo_wine ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
6808 if (node->nodeType == WS_XML_NODE_TYPE_ELEMENT)
6810 const WS_XML_ELEMENT_NODE *elem = (const WS_XML_ELEMENT_NODE *)node;
6811 ok( elem->localName->length == 1, "got %lu\n", elem->localName->length );
6812 ok( elem->localName->bytes[0] == 'c', "got '%c'\n", elem->localName->bytes[0] );
6815 prepare_struct_type_test( reader, "<t></t>" );
6816 hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6817 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6818 ok( hr == S_OK, "got %#lx\n", hr );
6819 ok( test != NULL, "test not set\n" );
6820 ok( !test->count, "got %lu\n", test->count );
6822 hr = WsGetReaderNode( reader, &node, NULL );
6823 ok( hr == S_OK, "got %#lx\n", hr );
6824 ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
6826 WsFreeReader( reader );
6827 WsFreeHeap( heap );
6830 static void test_empty_text_field(void)
6832 static WS_XML_STRING str_ns = {0, NULL}, str_t = {1, (BYTE *)"t"};
6833 HRESULT hr;
6834 WS_XML_READER *reader;
6835 WS_HEAP *heap;
6836 WS_FIELD_DESCRIPTION f, *fields[1];
6837 WS_STRUCT_DESCRIPTION s;
6838 struct test
6840 WS_STRING str;
6841 } *test;
6842 struct test2
6844 WCHAR *str;
6845 } *test2;
6846 struct test3
6848 BOOL bool;
6849 } *test3;
6850 struct test4
6852 WS_XML_STRING str;
6853 } *test4;
6854 struct test5
6856 WS_BYTES bytes;
6857 } *test5;
6859 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
6860 ok( hr == S_OK, "got %#lx\n", hr );
6862 hr = WsCreateReader( NULL, 0, &reader, NULL );
6863 ok( hr == S_OK, "got %#lx\n", hr );
6865 memset( &f, 0, sizeof(f) );
6866 f.mapping = WS_TEXT_FIELD_MAPPING;
6867 f.type = WS_STRING_TYPE;
6868 f.offset = FIELD_OFFSET(struct test, str);
6869 fields[0] = &f;
6871 memset( &s, 0, sizeof(s) );
6872 s.size = sizeof(struct test);
6873 s.alignment = TYPE_ALIGNMENT(struct test);
6874 s.fields = fields;
6875 s.fieldCount = 1;
6876 s.typeLocalName = &str_t;
6877 s.typeNs = &str_ns;
6879 test = NULL;
6880 prepare_struct_type_test( reader, "<t></t>" );
6881 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6882 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
6883 ok( hr == S_OK, "got %#lx\n", hr );
6884 ok( test != NULL, "test not set\n" );
6885 ok( !test->str.length, "got %lu\n", test->str.length );
6886 todo_wine ok( test->str.chars != NULL, "chars not set\n" );
6888 memset( &f, 0, sizeof(f) );
6889 f.mapping = WS_TEXT_FIELD_MAPPING;
6890 f.type = WS_WSZ_TYPE;
6891 f.offset = FIELD_OFFSET(struct test2, str);
6892 fields[0] = &f;
6894 memset( &s, 0, sizeof(s) );
6895 s.size = sizeof(struct test2);
6896 s.alignment = TYPE_ALIGNMENT(struct test2);
6897 s.fields = fields;
6898 s.fieldCount = 1;
6899 s.typeLocalName = &str_t;
6900 s.typeNs = &str_ns;
6902 test2 = NULL;
6903 prepare_struct_type_test( reader, "<t></t>" );
6904 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6905 WS_READ_REQUIRED_POINTER, heap, &test2, sizeof(test2), NULL );
6906 ok( hr == S_OK, "got %#lx\n", hr );
6907 ok( test2 != NULL, "test2 not set\n" );
6908 ok( test2->str != NULL, "str not set\n" );
6909 ok( !test2->str[0], "not empty\n" );
6911 memset( &f, 0, sizeof(f) );
6912 f.mapping = WS_TEXT_FIELD_MAPPING;
6913 f.type = WS_BOOL_TYPE;
6914 f.offset = FIELD_OFFSET(struct test3, bool);
6915 fields[0] = &f;
6917 memset( &s, 0, sizeof(s) );
6918 s.size = sizeof(struct test3);
6919 s.alignment = TYPE_ALIGNMENT(struct test3);
6920 s.fields = fields;
6921 s.fieldCount = 1;
6922 s.typeLocalName = &str_t;
6923 s.typeNs = &str_ns;
6925 prepare_struct_type_test( reader, "<t></t>" );
6926 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6927 WS_READ_REQUIRED_POINTER, heap, &test3, sizeof(test3), NULL );
6928 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
6930 memset( &f, 0, sizeof(f) );
6931 f.mapping = WS_TEXT_FIELD_MAPPING;
6932 f.type = WS_XML_STRING_TYPE;
6933 f.offset = FIELD_OFFSET(struct test4, str);
6934 fields[0] = &f;
6936 memset( &s, 0, sizeof(s) );
6937 s.size = sizeof(struct test4);
6938 s.alignment = TYPE_ALIGNMENT(struct test4);
6939 s.fields = fields;
6940 s.fieldCount = 1;
6941 s.typeLocalName = &str_t;
6942 s.typeNs = &str_ns;
6944 test4 = NULL;
6945 prepare_struct_type_test( reader, "<t></t>" );
6946 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6947 WS_READ_REQUIRED_POINTER, heap, &test4, sizeof(test4), NULL );
6948 ok( hr == S_OK, "got %#lx\n", hr );
6949 ok( test4 != NULL, "test4 not set\n" );
6950 ok( !test4->str.length, "got %lu\n", test4->str.length );
6951 todo_wine ok( test4->str.bytes != NULL, "bytes not set\n" );
6953 memset( &f, 0, sizeof(f) );
6954 f.mapping = WS_TEXT_FIELD_MAPPING;
6955 f.type = WS_BYTES_TYPE;
6956 f.offset = FIELD_OFFSET(struct test5, bytes);
6957 fields[0] = &f;
6959 memset( &s, 0, sizeof(s) );
6960 s.size = sizeof(struct test5);
6961 s.alignment = TYPE_ALIGNMENT(struct test5);
6962 s.fields = fields;
6963 s.fieldCount = 1;
6964 s.typeLocalName = &str_t;
6965 s.typeNs = &str_ns;
6967 test5 = NULL;
6968 prepare_struct_type_test( reader, "<t></t>" );
6969 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
6970 WS_READ_REQUIRED_POINTER, heap, &test5, sizeof(test5), NULL );
6971 ok( hr == S_OK, "got %#lx\n", hr );
6972 ok( test5 != NULL, "test5 not set\n" );
6973 ok( !test5->bytes.length, "got %lu\n", test5->bytes.length );
6974 todo_wine ok( test5->bytes.bytes != NULL, "bytes not set\n" );
6976 WsFreeReader( reader );
6977 WsFreeHeap( heap );
6980 static const char stream_utf8[] = {0xef,0xbb,0xbf,'<','t','/','>',0};
6981 static const struct stream_test
6983 const char *xml;
6984 HRESULT hr;
6985 int todo;
6987 stream_tests[] =
6989 { "", WS_E_QUOTA_EXCEEDED },
6990 { "<?xml version=\"1.0\" encoding=\"utf-8\"?><t/>", S_OK },
6991 { "<t/>", S_OK },
6992 { stream_utf8, S_OK, 1 },
6995 static CALLBACK HRESULT read_callback( void *state, void *buf, ULONG buflen, ULONG *retlen,
6996 const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
6998 struct stream_test *test = state;
6999 ULONG len = strlen( test->xml );
7001 ok( state != NULL, "NULL state\n" );
7002 ok( buf != NULL, "NULL buf\n" );
7003 ok( buflen > 0, "zero buflen\n" );
7004 ok( retlen != NULL, "NULL retlen\n" );
7005 if (buflen < len) return WS_E_QUOTA_EXCEEDED;
7006 memcpy( buf, test->xml, len );
7007 *retlen = len;
7008 return S_OK;
7011 static void test_stream_input(void)
7013 static WS_XML_STRING str_ns = {0, NULL}, str_t = {1, (BYTE *)"t"};
7014 WS_XML_READER_TEXT_ENCODING text = {{WS_XML_READER_ENCODING_TYPE_TEXT}};
7015 WS_XML_READER_STREAM_INPUT stream;
7016 WS_XML_READER *reader;
7017 const WS_XML_NODE *node;
7018 WS_CHARSET charset;
7019 HRESULT hr;
7020 BOOL found;
7021 ULONG i, size;
7023 hr = WsCreateReader( NULL, 0, &reader, NULL );
7024 ok( hr == S_OK, "got %#lx\n", hr );
7026 stream.input.inputType = WS_XML_READER_INPUT_TYPE_STREAM;
7027 stream.readCallback = read_callback;
7028 stream.readCallbackState = (void *)&stream_tests[2];
7029 hr = WsSetInput( reader, &text.encoding, &stream.input, NULL, 0, NULL );
7030 ok( hr == S_OK, "got %#lx\n", hr );
7032 size = sizeof(charset);
7033 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
7034 todo_wine ok( hr == WS_E_QUOTA_EXCEEDED, "got %#lx\n", hr );
7036 hr = WsSetInput( reader, &text.encoding, &stream.input, NULL, 0, NULL );
7037 ok( hr == S_OK, "got %#lx\n", hr );
7039 hr = WsFillReader( reader, strlen(stream_tests[2].xml), NULL, NULL );
7040 ok( hr == S_OK, "got %#lx\n", hr );
7042 charset = 0xdeadbeef;
7043 size = sizeof(charset);
7044 hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, size, NULL );
7045 ok( hr == S_OK, "got %#lx\n", hr );
7046 ok( charset == WS_CHARSET_UTF8, "got %u\n", charset );
7048 found = -1;
7049 hr = WsReadToStartElement( reader, &str_t, &str_ns, &found, NULL );
7050 ok( hr == S_OK, "got %#lx\n", hr );
7052 hr = WsFillReader( reader, 1, NULL, NULL );
7053 ok( hr == S_OK, "got %#lx\n", hr );
7055 hr = WsReadStartElement( reader, NULL );
7056 ok( hr == S_OK, "got %#lx\n", hr );
7058 for (i = 0; i < ARRAY_SIZE(stream_tests); i++)
7060 stream.readCallbackState = (void *)&stream_tests[i];
7061 hr = WsSetInput( reader, &text.encoding, &stream.input, NULL, 0, NULL );
7062 ok( hr == S_OK, "%lu: got %#lx\n", i, hr );
7064 hr = WsFillReader( reader, strlen( stream_tests[i].xml ), NULL, NULL );
7065 ok( hr == S_OK, "%lu: got %#lx\n", i, hr );
7067 found = -1;
7068 hr = WsReadToStartElement( reader, &str_t, &str_ns, &found, NULL );
7069 todo_wine_if(stream_tests[i].todo) ok( hr == stream_tests[i].hr, "%lu: got %#lx\n", i, hr );
7070 if (hr == S_OK)
7072 ok( found == TRUE, "%lu: got %d\n", i, found );
7073 hr = WsReadStartElement( reader, NULL );
7074 ok( hr == S_OK, "%lu: got %#lx\n", i, hr );
7076 hr = WsGetReaderNode( reader, &node, NULL );
7077 ok( hr == S_OK, "%lu: got %#lx\n", i, hr );
7078 if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "%lu: got %u\n", i, node->nodeType );
7082 WsFreeReader( reader );
7085 static void test_description_type(void)
7087 static WS_XML_STRING ns = {0, NULL}, ns2 = {2, (BYTE *)"ns"}, localname = {1, (BYTE *)"t"};
7088 static WS_XML_STRING val = {3, (BYTE *)"val"};
7089 HRESULT hr;
7090 WS_XML_READER *reader;
7091 WS_HEAP *heap;
7092 WS_FIELD_DESCRIPTION f, f2, *fields[2];
7093 WS_STRUCT_DESCRIPTION s;
7094 struct test
7096 const WS_STRUCT_DESCRIPTION *desc;
7097 INT32 val;
7098 } *test;
7100 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
7101 ok( hr == S_OK, "got %#lx\n", hr );
7103 hr = WsCreateReader( NULL, 0, &reader, NULL );
7104 ok( hr == S_OK, "got %#lx\n", hr );
7106 memset( &f, 0, sizeof(f) );
7107 f.mapping = WS_TYPE_ATTRIBUTE_FIELD_MAPPING;
7108 f.type = WS_DESCRIPTION_TYPE;
7109 fields[0] = &f;
7111 memset( &f2, 0, sizeof(f2) );
7112 f2.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
7113 f2.localName = &val;
7114 f2.ns = &ns;
7115 f2.offset = FIELD_OFFSET(struct test, val);
7116 f2.type = WS_INT32_TYPE;
7117 fields[1] = &f2;
7119 memset( &s, 0, sizeof(s) );
7120 s.size = sizeof(struct test);
7121 s.alignment = TYPE_ALIGNMENT(struct test);
7122 s.fields = fields;
7123 s.fieldCount = 2;
7124 s.typeLocalName = &localname;
7125 s.typeNs = &ns;
7127 prepare_struct_type_test( reader, "<t val=\"-1\" xmlns=\"ns\"/>" );
7128 hr = WsReadToStartElement( reader, &localname, &ns2, NULL, NULL );
7129 ok( hr == S_OK, "got %#lx\n", hr );
7131 test = NULL;
7132 hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
7133 WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
7134 ok( hr == S_OK, "got %#lx\n", hr );
7135 ok( test != NULL, "test not set\n" );
7136 if (test)
7138 ok( test->val == -1, "got %d\n", test->val );
7139 ok( test->desc == &s, "got %p\n", test->desc );
7142 WsFreeReader( reader );
7143 WsFreeHeap( heap );
7146 static void test_WsAddErrorString(void)
7148 static const WS_STRING emptystr = { 0 };
7149 static const WS_STRING str1 = WS_STRING_VALUE( L"str1" );
7150 static const WS_STRING str2 = WS_STRING_VALUE( L"str2" );
7151 ULONG count;
7152 WS_ERROR *error;
7153 WS_STRING out;
7154 HRESULT hr;
7156 hr = WsCreateError( NULL, 0, &error );
7157 ok( hr == S_OK, "got %#lx\n", hr );
7159 hr = WsAddErrorString( NULL, NULL );
7160 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
7161 hr = WsAddErrorString( NULL, &str1 );
7162 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
7163 hr = WsAddErrorString( error, NULL );
7164 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
7166 hr = WsAddErrorString( error, &emptystr );
7167 ok( hr == S_OK, "got %#lx\n", hr );
7168 hr = WsAddErrorString(error, &str2 );
7169 ok( hr == S_OK, "got %#lx\n", hr );
7170 hr = WsAddErrorString(error, &str1 );
7171 ok( hr == S_OK, "got %#lx\n", hr );
7173 count = 0xdeadbeef;
7174 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, sizeof(count) );
7175 ok( hr == S_OK, "got %#lx\n", hr );
7176 ok( count == 3, "got %lu\n", count );
7178 hr = WsGetErrorString( error, 0, &out );
7179 ok( hr == S_OK, "got %#lx\n", hr );
7180 ok( out.length == str1.length, "got %lu\n", out.length );
7181 ok( !memcmp( out.chars, str1.chars, str1.length ), "wrong error string\n" );
7183 hr = WsGetErrorString( error, 1, &out );
7184 ok( hr == S_OK, "got %#lx\n", hr );
7185 ok( out.length == str2.length, "got %lu\n", out.length );
7186 ok( !memcmp( out.chars, str2.chars, str2.length ), "wrong error string\n" );
7188 hr = WsGetErrorString( error, 2, &out );
7189 ok( hr == S_OK, "got %#lx\n", hr );
7190 ok( out.length == 0, "got %lu\n", out.length );
7191 ok( out.chars != NULL, "out.chars == NULL\n" );
7193 WsFreeError( error );
7196 static void test_WsSetFaultErrorProperty(void)
7198 static const WCHAR expected_errorstr[] = L"The fault reason was: 'Some reason'.";
7199 static const char detailxml[] = "<detail><ErrorCode>1030</ErrorCode></detail>";
7200 static const LANGID langid = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US );
7201 static const WS_XML_STRING action = { 24, (BYTE *)"http://example.com/fault" };
7202 WS_ERROR_PROPERTY prop;
7203 WS_ERROR *error;
7204 WS_FAULT fault;
7205 WS_FAULT *faultp;
7206 WS_XML_STRING outxmlstr;
7207 WS_STRING outstr;
7208 ULONG count;
7209 WS_HEAP *heap;
7210 WS_XML_READER *reader;
7211 HRESULT hr;
7213 prop.id = WS_ERROR_PROPERTY_LANGID;
7214 prop.value = (void *)&langid;
7215 prop.valueSize = sizeof(langid);
7217 hr = WsCreateError( &prop, 1, &error );
7218 ok( hr == S_OK, "got %#lx\n", hr );
7220 hr = WsSetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_FAULT, NULL, sizeof(WS_FAULT) );
7221 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
7223 hr = WsSetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_ACTION, NULL, sizeof(WS_XML_STRING) );
7224 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
7226 memset( &fault, 0, sizeof(fault) );
7228 fault.code = calloc( 1, sizeof(WS_FAULT_CODE) );
7229 fault.code->value.localName.bytes = (BYTE *)"Server";
7230 fault.code->value.localName.length = 6;
7231 fault.code->subCode = calloc( 1, sizeof(WS_FAULT_CODE) );
7232 fault.code->subCode->value.localName.bytes = (BYTE *)"SubCode";
7233 fault.code->subCode->value.localName.length = 7;
7235 fault.reasons = calloc( 1, sizeof(*fault.reasons) );
7236 fault.reasonCount = 1;
7237 fault.reasons[0].lang.chars = (WCHAR *) L"en-US";
7238 fault.reasons[0].lang.length = 5;
7239 fault.reasons[0].text.chars = (WCHAR *) L"Some reason";
7240 fault.reasons[0].text.length = 11;
7242 hr = WsSetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_FAULT, &fault, sizeof(WS_FAULT) );
7243 ok( hr == S_OK, "got %#lx\n", hr );
7245 faultp = NULL;
7246 hr = WsGetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_FAULT, &faultp, sizeof(faultp) );
7247 ok( hr == S_OK, "got %#lx\n", hr );
7248 ok( faultp != NULL, "faultp not set\n" );
7249 ok( faultp != &fault, "fault not copied\n" );
7251 ok( faultp->code && faultp->code != fault.code, "fault code not copied\n" );
7252 ok( faultp->code->value.localName.length == 6, "got %lu\n", faultp->code->value.localName.length );
7253 ok( !memcmp( faultp->code->value.localName.bytes, fault.code->value.localName.bytes, 6 ),
7254 "wrong code localName\n" );
7255 ok( faultp->code->value.localName.bytes != fault.code->value.localName.bytes,
7256 "fault code localName not copied\n" );
7257 ok( faultp->code->value.ns.length == 0, "got %lu\n", faultp->code->value.ns.length );
7258 ok( faultp->code->subCode && faultp->code->subCode != fault.code->subCode,
7259 "fault code subCode not copied\n" );
7260 ok( faultp->code->subCode->value.localName.length == 7,"got %lu\n", faultp->code->subCode->value.localName.length );
7261 ok( !memcmp( faultp->code->subCode->value.localName.bytes, fault.code->subCode->value.localName.bytes, 7 ),
7262 "wrong subCode localName\n" );
7263 ok( faultp->code->subCode->value.localName.bytes != fault.code->subCode->value.localName.bytes,
7264 "fault code subCode localName not copied\n" );
7265 ok( faultp->code->subCode->value.ns.length == 0, "got %lu\n", faultp->code->subCode->value.ns.length );
7266 ok( faultp->code->subCode->subCode == NULL, "fault->code->subCode->subCode != NULL\n");
7268 ok( faultp->reasons != fault.reasons, "fault reasons not copied\n" );
7269 ok( faultp->reasonCount == 1, "got %lu\n", faultp->reasonCount );
7270 ok( faultp->reasons[0].lang.length == 5, "got %lu\n", faultp->reasons[0].text.length );
7271 ok( !memcmp( faultp->reasons[0].lang.chars, fault.reasons[0].lang.chars, 5 * sizeof(WCHAR) ),
7272 "wrong fault reason lang\n" );
7273 ok( faultp->reasons[0].lang.chars != fault.reasons[0].lang.chars,
7274 "fault reason lang not copied\n" );
7275 ok( faultp->reasons[0].text.length == 11, "got %lu\n", faultp->reasons[0].text.length );
7276 ok( !memcmp( faultp->reasons[0].text.chars, fault.reasons[0].text.chars, 11 * sizeof(WCHAR) ),
7277 "wrong fault reason text\n" );
7278 ok( faultp->reasons[0].text.chars != fault.reasons[0].text.chars,
7279 "fault reason text not copied\n" );
7281 ok( faultp->actor.length == 0, "got %lu\n", faultp->actor.length );
7282 ok( faultp->node.length == 0, "got %lu\n", faultp->node.length );
7283 ok( faultp->detail == NULL, "faultp->detail != NULL\n" );
7285 count = 0xdeadbeef;
7286 hr = WsGetErrorProperty( error, WS_ERROR_PROPERTY_STRING_COUNT, &count, sizeof(count) );
7287 ok( hr == S_OK, "got %#lx\n", hr );
7288 ok( count == 1, "got %lu\n", count );
7290 hr = WsGetErrorString( error, 0, &outstr );
7291 ok( hr == S_OK, "got %#lx\n", hr );
7292 ok( outstr.length == ARRAY_SIZE(expected_errorstr) - 1, "got %lu\n", outstr.length );
7293 ok( !memcmp( outstr.chars, expected_errorstr, (ARRAY_SIZE(expected_errorstr) - 1) * sizeof(WCHAR) ),
7294 "wrong error string\n" );
7296 outxmlstr.bytes = (BYTE *)0xdeadbeef;
7297 outxmlstr.length = 0xdeadbeef;
7298 hr = WsGetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_ACTION, &outxmlstr, sizeof(outxmlstr) );
7299 ok( hr == S_OK, "got %#lx\n", hr );
7300 ok( outxmlstr.length == 0, "got %lu\n", outxmlstr.length );
7302 hr = WsSetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_ACTION, &action, sizeof(action) );
7303 ok( hr == S_OK, "got %#lx\n", hr );
7305 outxmlstr.bytes = (BYTE *)0xdeadbeef;
7306 outxmlstr.length = 0xdeadbeef;
7307 hr = WsGetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_ACTION, &outxmlstr, sizeof(outxmlstr) );
7308 ok( hr == S_OK, "got %#lx\n", hr );
7309 ok( outxmlstr.length == 24, "got %lu\n", outxmlstr.length );
7310 ok( !memcmp( outxmlstr.bytes, action.bytes, 24 ), "wrong fault action\n" );
7312 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
7313 ok( hr == S_OK, "got %#lx\n", hr );
7314 hr = WsCreateReader( NULL, 0, &reader, NULL );
7315 ok( hr == S_OK, "got %#lx\n", hr );
7316 hr = set_input( reader, detailxml, strlen(detailxml) );
7317 ok( hr == S_OK, "got %#lx\n", hr );
7318 hr = WsReadXmlBuffer( reader, heap, &fault.detail, NULL );
7319 ok( hr == S_OK, "got %#lx\n", hr );
7321 hr = WsSetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_FAULT, &fault, sizeof(WS_FAULT) );
7322 ok( hr == S_OK, "got %#lx\n", hr );
7324 hr = WsGetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_FAULT, &faultp, sizeof(faultp) );
7325 ok( hr == S_OK, "got %#lx\n", hr );
7326 ok( faultp != NULL, "faultp not set\n" );
7327 ok( faultp->detail != NULL, "fault detail not set\n" );
7328 ok( faultp->detail != fault.detail, "fault detail not copied\n" );
7329 check_output_buffer( faultp->detail, detailxml, __LINE__ );
7331 free( fault.code->subCode );
7332 free( fault.code );
7333 free( fault.reasons );
7334 WsFreeReader( reader );
7335 WsFreeHeap( heap );
7336 WsFreeError( error );
7339 static void test_WsGetFaultErrorDetail(void)
7341 static const char detailxml[] = "<detail><ErrorCode>1030</ErrorCode></detail>";
7342 static const char badxml[] = "<bad><ErrorCode>1030</ErrorCode></bad>";
7344 WS_ERROR *error;
7345 WS_HEAP *heap;
7346 WS_XML_READER *reader;
7347 WS_FAULT fault;
7348 WS_XML_STRING action = { 24, (BYTE *)"http://example.com/fault" };
7349 WS_XML_STRING action2 = { 25, (BYTE *)"http://example.com/fault2" };
7350 WS_XML_STRING localname = { 9, (BYTE *)"ErrorCode" }, localname2 = { 9, (BYTE *)"OtherCode" };
7351 WS_XML_STRING ns = { 0 };
7352 WS_ELEMENT_DESCRIPTION desc = { &localname, &ns, WS_UINT32_TYPE, NULL };
7353 WS_ELEMENT_DESCRIPTION desc2 = { &localname2, &ns, WS_UINT32_TYPE, NULL };
7354 WS_FAULT_DETAIL_DESCRIPTION fault_desc;
7355 UINT32 code;
7356 UINT32 *codep;
7357 HRESULT hr;
7359 hr = WsCreateError( NULL, 0, &error );
7360 ok( hr == S_OK, "got %#lx\n", hr );
7362 memset( &fault, 0, sizeof(fault) );
7364 hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
7365 ok( hr == S_OK, "got %#lx\n", hr );
7366 hr = WsCreateReader( NULL, 0, &reader, NULL );
7367 ok( hr == S_OK, "got %#lx\n", hr );
7369 hr = set_input( reader, detailxml, strlen(detailxml) );
7370 ok( hr == S_OK, "got %#lx\n", hr );
7371 hr = WsReadXmlBuffer( reader, heap, &fault.detail, NULL );
7372 ok( hr == S_OK, "got %#lx\n", hr );
7373 hr = WsSetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_FAULT, &fault, sizeof(fault) );
7374 ok( hr == S_OK, "got %#lx\n", hr );
7376 fault_desc.action = NULL;
7377 fault_desc.detailElementDescription = &desc;
7379 code = 0xdeadbeef;
7380 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_REQUIRED_VALUE, heap, &code, sizeof(code) );
7381 ok( hr == S_OK, "got %#lx\n", hr );
7382 ok( code == 1030, "got %u\n", code );
7384 codep = (UINT32 *)0xdeadbeef;
7385 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_OPTIONAL_POINTER, heap, &codep, sizeof(codep) );
7386 ok( hr == S_OK, "got %#lx\n", hr );
7387 ok( codep != NULL, "codep == NULL\n" );
7388 ok( *codep == 1030, "got %u\n", *codep );
7390 fault_desc.action = &action;
7392 code = 0xdeadbeef;
7393 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_REQUIRED_VALUE, heap, &code, sizeof(code) );
7394 ok( hr == S_OK, "got %#lx\n", hr );
7395 ok( code == 1030, "got %u\n", code );
7397 hr = WsSetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_ACTION, &action, sizeof(action) );
7398 ok( hr == S_OK, "got %#lx\n", hr );
7400 fault_desc.action = NULL;
7402 code = 0xdeadbeef;
7403 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_REQUIRED_VALUE, heap, &code, sizeof(code) );
7404 ok( hr == S_OK, "got %#lx\n", hr );
7405 ok( code == 1030, "got %u\n", code );
7407 fault_desc.action = &action2;
7409 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_REQUIRED_VALUE, heap, &code, sizeof(code) );
7410 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
7412 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_REQUIRED_POINTER, heap, &codep, sizeof(codep) );
7413 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
7415 codep = (UINT32 *)0xdeadbeef;
7416 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_OPTIONAL_POINTER, heap, &codep, sizeof(codep) );
7417 ok( hr == S_OK, "got %#lx\n", hr );
7418 ok( codep == NULL, "codep != NULL\n" );
7420 codep = (UINT32 *)0xdeadbeef;
7421 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_NILLABLE_POINTER, heap, &codep, sizeof(codep) );
7422 ok( hr == S_OK, "got %#lx\n", hr );
7423 ok( codep == NULL, "codep != NULL\n" );
7425 fault_desc.action = NULL;
7426 fault_desc.detailElementDescription = &desc2;
7428 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_REQUIRED_VALUE, heap, &code, sizeof(code) );
7429 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
7431 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_REQUIRED_POINTER, heap, &codep, sizeof(codep) );
7432 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
7434 codep = (UINT32 *)0xdeadbeef;
7435 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_OPTIONAL_POINTER, heap, &codep, sizeof(codep) );
7436 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
7437 ok( codep == NULL, "codep != NULL\n" );
7439 codep = (UINT32 *)0xdeadbeef;
7440 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_NILLABLE_POINTER, heap, &codep, sizeof(codep) );
7441 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
7442 ok( codep == NULL, "codep != NULL\n" );
7444 hr = set_input( reader, badxml, strlen(badxml) );
7445 ok( hr == S_OK, "got %#lx\n", hr );
7446 hr = WsReadXmlBuffer( reader, heap, &fault.detail, NULL );
7447 ok( hr == S_OK, "got %#lx\n", hr );
7448 hr = WsSetFaultErrorProperty( error, WS_FAULT_ERROR_PROPERTY_FAULT, &fault, sizeof(fault) );
7449 ok( hr == S_OK, "got %#lx\n", hr );
7451 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_REQUIRED_VALUE, heap, &code, sizeof(code) );
7452 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
7454 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_REQUIRED_POINTER, heap, &codep, sizeof(codep) );
7455 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
7457 codep = (UINT32 *)0xdeadbeef;
7458 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_OPTIONAL_POINTER, heap, &codep, sizeof(codep) );
7459 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
7460 ok( codep == NULL, "codep != NULL\n" );
7462 codep = (UINT32 *)0xdeadbeef;
7463 hr = WsGetFaultErrorDetail( error, &fault_desc, WS_READ_NILLABLE_POINTER, heap, &codep, sizeof(codep) );
7464 ok( hr == WS_E_INVALID_FORMAT, "got %#lx\n", hr );
7465 ok( codep == NULL, "codep != NULL\n" );
7467 WsFreeReader( reader );
7468 WsFreeHeap( heap );
7469 WsFreeError( error );
7472 START_TEST(reader)
7474 test_WsCreateError();
7475 test_WsCreateHeap();
7476 test_WsCreateReader();
7477 test_WsSetInput();
7478 test_WsSetInputToBuffer();
7479 test_WsFillReader();
7480 test_WsReadToStartElement();
7481 test_WsReadStartElement();
7482 test_WsReadEndElement();
7483 test_WsReadNode();
7484 test_WsReadType();
7485 test_WsGetXmlAttribute();
7486 test_WsXmlStringEquals();
7487 test_WsAlloc();
7488 test_WsMoveReader();
7489 test_simple_struct_type();
7490 test_cdata();
7491 test_WsFindAttribute();
7492 test_WsGetNamespaceFromPrefix();
7493 test_text_field_mapping();
7494 test_complex_struct_type();
7495 test_repeating_element();
7496 test_WsResetHeap();
7497 test_datetime();
7498 test_WsDateTimeToFileTime();
7499 test_WsFileTimeToDateTime();
7500 test_double();
7501 test_WsReadElement();
7502 test_WsReadValue();
7503 test_WsResetError();
7504 test_WsGetReaderPosition();
7505 test_WsSetReaderPosition();
7506 test_entities();
7507 test_field_options();
7508 test_WsReadBytes();
7509 test_WsReadChars();
7510 test_WsReadCharsUtf8();
7511 test_WsReadQualifiedName();
7512 test_WsReadAttribute();
7513 test_WsSkipNode();
7514 test_binary_encoding();
7515 test_dictionary();
7516 test_WsReadXmlBuffer();
7517 test_union_type();
7518 test_float();
7519 test_repeating_element_choice();
7520 test_empty_text_field();
7521 test_stream_input();
7522 test_description_type();
7523 test_WsAddErrorString();
7524 test_WsSetFaultErrorProperty();
7525 test_WsGetFaultErrorDetail();