wined3d: Pass a wined3d_device_context to wined3d_cs_emit_blt_sub_resource().
[wine/zf.git] / dlls / xmllite / tests / reader.c
blobcb3a3f4e57177e97d21ebe1c406cf865bef00c39
1 /*
2 * IXmlReader tests
4 * Copyright 2010, 2012-2013, 2016-2017 Nikolay Sivov
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #define CONST_VTABLE
24 #include <stdarg.h>
25 #include <stdio.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "initguid.h"
30 #include "ole2.h"
31 #include "xmllite.h"
32 #include "wine/test.h"
33 #include "wine/heap.h"
35 DEFINE_GUID(IID_IXmlReaderInput, 0x0b3ccc9b, 0x9214, 0x428b, 0xa2, 0xae, 0xef, 0x3a, 0xa8, 0x71, 0xaf, 0xda);
37 static const char xmldecl_full[] = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
38 static const char xmldecl_short[] = "<?xml version=\"1.0\"?><RegistrationInfo/>";
40 static IStream *create_stream_on_data(const void *data, unsigned int size)
42 IStream *stream = NULL;
43 HGLOBAL hglobal;
44 void *ptr;
45 HRESULT hr;
47 hglobal = GlobalAlloc(GHND, size);
48 ptr = GlobalLock(hglobal);
50 memcpy(ptr, data, size);
52 hr = CreateStreamOnHGlobal(hglobal, TRUE, &stream);
53 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
54 ok(stream != NULL, "Expected non-NULL stream\n");
56 GlobalUnlock(hglobal);
58 return stream;
61 static void test_reader_pos(IXmlReader *reader, UINT line, UINT pos, UINT line_broken,
62 UINT pos_broken, int _line_)
64 UINT l = ~0u, p = ~0u;
65 BOOL broken_state;
67 IXmlReader_GetLineNumber(reader, &l);
68 IXmlReader_GetLinePosition(reader, &p);
70 if (line_broken == ~0u && pos_broken == ~0u)
71 broken_state = FALSE;
72 else
73 broken_state = broken((line_broken == ~0u ? line : line_broken) == l &&
74 (pos_broken == ~0u ? pos : pos_broken) == p);
76 ok_(__FILE__, _line_)((l == line && pos == p) || broken_state,
77 "Expected (%d,%d), got (%d,%d)\n", line, pos, l, p);
79 #define TEST_READER_POSITION(reader, line, pos) \
80 test_reader_pos(reader, line, pos, ~0u, ~0u, __LINE__)
81 #define TEST_READER_POSITION2(reader, line, pos, line_broken, pos_broken) \
82 test_reader_pos(reader, line, pos, line_broken, pos_broken, __LINE__)
84 typedef struct input_iids_t {
85 IID iids[10];
86 int count;
87 } input_iids_t;
89 static const IID *setinput_full[] = {
90 &IID_IXmlReaderInput,
91 &IID_IStream,
92 &IID_ISequentialStream,
93 NULL
96 /* this applies to early xmllite versions */
97 static const IID *setinput_full_old[] = {
98 &IID_IXmlReaderInput,
99 &IID_ISequentialStream,
100 &IID_IStream,
101 NULL
104 /* after ::SetInput(IXmlReaderInput*) */
105 static const IID *setinput_readerinput[] = {
106 &IID_IStream,
107 &IID_ISequentialStream,
108 NULL
111 static const IID *empty_seq[] = {
112 NULL
115 static input_iids_t input_iids;
117 static void ok_iids_(const input_iids_t *iids, const IID **expected, const IID **exp_broken, BOOL todo, int line)
119 int i = 0, size = 0;
121 while (expected[i++]) size++;
123 todo_wine_if (todo)
124 ok_(__FILE__, line)(iids->count == size, "Sequence size mismatch (%d), got (%d)\n", size, iids->count);
126 if (iids->count != size) return;
128 for (i = 0; i < size; i++) {
129 ok_(__FILE__, line)(IsEqualGUID(&iids->iids[i], expected[i]) ||
130 (exp_broken ? broken(IsEqualGUID(&iids->iids[i], exp_broken[i])) : FALSE),
131 "Wrong IID(%d), got %s\n", i, wine_dbgstr_guid(&iids->iids[i]));
134 #define ok_iids(got, exp, brk, todo) ok_iids_(got, exp, brk, todo, __LINE__)
136 static const char *state_to_str(XmlReadState state)
138 static const char* state_names[] = {
139 "XmlReadState_Initial",
140 "XmlReadState_Interactive",
141 "XmlReadState_Error",
142 "XmlReadState_EndOfFile",
143 "XmlReadState_Closed"
146 static const char unknown[] = "unknown";
148 switch (state)
150 case XmlReadState_Initial:
151 case XmlReadState_Interactive:
152 case XmlReadState_Error:
153 case XmlReadState_EndOfFile:
154 case XmlReadState_Closed:
155 return state_names[state];
156 default:
157 return unknown;
161 static const char *type_to_str(XmlNodeType type)
163 static const char* type_names[] = {
164 "XmlNodeType_None",
165 "XmlNodeType_Element",
166 "XmlNodeType_Attribute",
167 "XmlNodeType_Text",
168 "XmlNodeType_CDATA",
169 "", "",
170 "XmlNodeType_ProcessingInstruction",
171 "XmlNodeType_Comment",
173 "XmlNodeType_DocumentType",
174 "", "",
175 "XmlNodeType_Whitespace",
177 "XmlNodeType_EndElement",
179 "XmlNodeType_XmlDeclaration"
182 static const char unknown[] = "unknown";
184 switch (type)
186 case XmlNodeType_None:
187 case XmlNodeType_Element:
188 case XmlNodeType_Attribute:
189 case XmlNodeType_Text:
190 case XmlNodeType_CDATA:
191 case XmlNodeType_ProcessingInstruction:
192 case XmlNodeType_Comment:
193 case XmlNodeType_DocumentType:
194 case XmlNodeType_Whitespace:
195 case XmlNodeType_EndElement:
196 case XmlNodeType_XmlDeclaration:
197 return type_names[type];
198 default:
199 return unknown;
203 #define set_input_string(a,b) _set_input_string(__LINE__,a,b);
204 static void _set_input_string(unsigned line, IXmlReader *reader, const char *xml)
206 IStream *stream;
207 HRESULT hr;
209 stream = create_stream_on_data(xml, strlen(xml));
211 hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
212 ok_(__FILE__,line)(hr == S_OK, "got %08x\n", hr);
214 IStream_Release(stream);
217 #define read_node(a,b) _read_node(__LINE__,a,b)
218 static void _read_node(unsigned line, IXmlReader *reader, XmlNodeType expected_type)
220 XmlNodeType type;
221 HRESULT hr;
223 hr = IXmlReader_Read(reader, &type);
224 if (expected_type == XmlNodeType_None)
225 ok_(__FILE__,line)(hr == S_FALSE, "Read returned %08x, expected S_FALSE\n", hr);
226 else
227 ok_(__FILE__,line)(hr == S_OK, "Read returned %08x\n", hr);
228 ok_(__FILE__,line)(type == expected_type, "read type %d, expected %d\n", type, expected_type);
231 #define next_attribute(a) _next_attribute(__LINE__,a)
232 static void _next_attribute(unsigned line, IXmlReader *reader)
234 HRESULT hr;
235 hr = IXmlReader_MoveToNextAttribute(reader);
236 ok_(__FILE__,line)(hr == S_OK, "MoveToNextAttribute returned %08x\n", hr);
239 #define move_to_element(a) _move_to_element(__LINE__,a)
240 static void _move_to_element(unsigned line, IXmlReader *reader)
242 HRESULT hr;
243 hr = IXmlReader_MoveToElement(reader);
244 ok_(__FILE__,line)(hr == S_OK, "MoveToElement failed: %08x\n", hr);
247 static void test_read_state(IXmlReader *reader, XmlReadState expected,
248 XmlReadState exp_broken, int line)
250 BOOL broken_state;
251 LONG_PTR state;
253 state = -1; /* invalid state value */
254 IXmlReader_GetProperty(reader, XmlReaderProperty_ReadState, &state);
256 if (exp_broken == expected)
257 broken_state = FALSE;
258 else
259 broken_state = broken(exp_broken == state);
261 ok_(__FILE__, line)(state == expected || broken_state, "Expected (%s), got (%s)\n",
262 state_to_str(expected), state_to_str(state));
265 #define TEST_READER_STATE(reader, state) test_read_state(reader, state, state, __LINE__)
266 #define TEST_READER_STATE2(reader, state, brk) test_read_state(reader, state, brk, __LINE__)
268 #define reader_value(a,b) _reader_value(__LINE__,a,b)
269 static const WCHAR *_reader_value(unsigned line, IXmlReader *reader, const WCHAR *expect)
271 const WCHAR *str = (void*)0xdeadbeef;
272 ULONG len = 0xdeadbeef;
273 HRESULT hr;
275 hr = IXmlReader_GetValue(reader, &str, &len);
276 ok_(__FILE__,line)(hr == S_OK, "GetValue returned %08x\n", hr);
277 ok_(__FILE__,line)(len == lstrlenW(str), "len = %u\n", len);
278 ok_(__FILE__,line)(!lstrcmpW(str, expect), "value = %s\n", wine_dbgstr_w(str));
279 return str;
282 #define reader_name(a,b) _reader_name(__LINE__,a,b)
283 static const WCHAR *_reader_name(unsigned line, IXmlReader *reader, const WCHAR *expect)
285 const WCHAR *str = (void*)0xdeadbeef;
286 ULONG len = 0xdeadbeef;
287 HRESULT hr;
289 hr = IXmlReader_GetLocalName(reader, &str, &len);
290 ok_(__FILE__,line)(hr == S_OK, "GetLocalName returned %08x\n", hr);
291 ok_(__FILE__,line)(len == lstrlenW(str), "len = %u\n", len);
292 ok_(__FILE__,line)(!lstrcmpW(str, expect), "name = %s\n", wine_dbgstr_w(str));
293 return str;
296 #define reader_prefix(a,b) _reader_prefix(__LINE__,a,b)
297 static const WCHAR *_reader_prefix(unsigned line, IXmlReader *reader, const WCHAR *expect)
299 const WCHAR *str = (void*)0xdeadbeef;
300 ULONG len = 0xdeadbeef;
301 HRESULT hr;
303 hr = IXmlReader_GetPrefix(reader, &str, &len);
304 ok_(__FILE__,line)(hr == S_OK, "GetPrefix returned %08x\n", hr);
305 ok_(__FILE__,line)(len == lstrlenW(str), "len = %u\n", len);
306 ok_(__FILE__,line)(!lstrcmpW(str, expect), "prefix = %s\n", wine_dbgstr_w(str));
307 return str;
310 #define reader_namespace(a,b) _reader_namespace(__LINE__,a,b)
311 static const WCHAR *_reader_namespace(unsigned line, IXmlReader *reader, const WCHAR *expect)
313 const WCHAR *str = (void*)0xdeadbeef;
314 ULONG len = 0xdeadbeef;
315 HRESULT hr;
317 hr = IXmlReader_GetNamespaceUri(reader, &str, &len);
318 ok_(__FILE__,line)(hr == S_OK, "GetNamespaceUri returned %08x\n", hr);
319 ok_(__FILE__,line)(len == lstrlenW(str), "len = %u\n", len);
320 ok_(__FILE__,line)(!lstrcmpW(str, expect), "namespace = %s\n", wine_dbgstr_w(str));
321 return str;
324 #define reader_qname(a,b) _reader_qname(a,b,__LINE__)
325 static const WCHAR *_reader_qname(IXmlReader *reader, const WCHAR *expect, unsigned line)
327 const WCHAR *str = (void*)0xdeadbeef;
328 ULONG len = 0xdeadbeef;
329 HRESULT hr;
331 hr = IXmlReader_GetQualifiedName(reader, &str, &len);
332 ok_(__FILE__,line)(hr == S_OK, "GetQualifiedName returned %08x\n", hr);
333 ok_(__FILE__,line)(len == lstrlenW(str), "len = %u\n", len);
334 ok_(__FILE__,line)(!lstrcmpW(str, expect), "name = %s\n", wine_dbgstr_w(str));
335 return str;
338 #define read_value_char(a,b) _read_value_char(a,b,__LINE__)
339 static void _read_value_char(IXmlReader *reader, WCHAR expected_char, unsigned line)
341 WCHAR c = 0xffff;
342 UINT count = 0;
343 HRESULT hr;
345 hr = IXmlReader_ReadValueChunk(reader, &c, 1, &count);
346 ok_(__FILE__,line)(hr == S_OK, "got %08x\n", hr);
347 ok_(__FILE__,line)(count == 1, "got %u\n", c);
348 ok_(__FILE__,line)(c == expected_char, "got %x\n", c);
351 typedef struct _testinput
353 IUnknown IUnknown_iface;
354 LONG ref;
355 } testinput;
357 static inline testinput *impl_from_IUnknown(IUnknown *iface)
359 return CONTAINING_RECORD(iface, testinput, IUnknown_iface);
362 static HRESULT WINAPI testinput_QueryInterface(IUnknown *iface, REFIID riid, void** ppvObj)
364 if (IsEqualGUID( riid, &IID_IUnknown ))
366 *ppvObj = iface;
367 IUnknown_AddRef(iface);
368 return S_OK;
371 input_iids.iids[input_iids.count++] = *riid;
373 *ppvObj = NULL;
375 return E_NOINTERFACE;
378 static ULONG WINAPI testinput_AddRef(IUnknown *iface)
380 testinput *This = impl_from_IUnknown(iface);
381 return InterlockedIncrement(&This->ref);
384 static ULONG WINAPI testinput_Release(IUnknown *iface)
386 testinput *This = impl_from_IUnknown(iface);
387 LONG ref;
389 ref = InterlockedDecrement(&This->ref);
390 if (ref == 0)
391 heap_free(This);
393 return ref;
396 static const struct IUnknownVtbl testinput_vtbl =
398 testinput_QueryInterface,
399 testinput_AddRef,
400 testinput_Release
403 static HRESULT testinput_createinstance(void **ppObj)
405 testinput *input;
407 input = heap_alloc(sizeof(*input));
408 if(!input) return E_OUTOFMEMORY;
410 input->IUnknown_iface.lpVtbl = &testinput_vtbl;
411 input->ref = 1;
413 *ppObj = &input->IUnknown_iface;
415 return S_OK;
418 static HRESULT WINAPI teststream_QueryInterface(ISequentialStream *iface, REFIID riid, void **obj)
420 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_ISequentialStream))
422 *obj = iface;
423 return S_OK;
426 *obj = NULL;
427 return E_NOINTERFACE;
430 static ULONG WINAPI teststream_AddRef(ISequentialStream *iface)
432 return 2;
435 static ULONG WINAPI teststream_Release(ISequentialStream *iface)
437 return 1;
440 static int stream_readcall;
442 static HRESULT WINAPI teststream_Read(ISequentialStream *iface, void *pv, ULONG cb, ULONG *pread)
444 static const char xml[] = "<!-- comment -->";
446 if (stream_readcall++)
448 *pread = 0;
449 return E_PENDING;
452 *pread = sizeof(xml) / 2;
453 memcpy(pv, xml, *pread);
454 return S_OK;
457 static HRESULT WINAPI teststream_Write(ISequentialStream *iface, const void *pv, ULONG cb, ULONG *written)
459 ok(0, "unexpected call\n");
460 return E_NOTIMPL;
463 static const ISequentialStreamVtbl teststreamvtbl =
465 teststream_QueryInterface,
466 teststream_AddRef,
467 teststream_Release,
468 teststream_Read,
469 teststream_Write
472 static HRESULT WINAPI resolver_QI(IXmlResolver *iface, REFIID riid, void **obj)
474 ok(0, "unexpected call, riid %s\n", wine_dbgstr_guid(riid));
476 if (IsEqualIID(riid, &IID_IXmlResolver) || IsEqualIID(riid, &IID_IUnknown))
478 *obj = iface;
479 IXmlResolver_AddRef(iface);
480 return S_OK;
483 *obj = NULL;
484 return E_NOINTERFACE;
487 static ULONG WINAPI resolver_AddRef(IXmlResolver *iface)
489 return 2;
492 static ULONG WINAPI resolver_Release(IXmlResolver *iface)
494 return 1;
497 static HRESULT WINAPI resolver_ResolveUri(IXmlResolver *iface, const WCHAR *base_uri,
498 const WCHAR *public_id, const WCHAR *system_id, IUnknown **input)
500 ok(0, "unexpected call\n");
501 return E_NOTIMPL;
504 static const IXmlResolverVtbl resolvervtbl =
506 resolver_QI,
507 resolver_AddRef,
508 resolver_Release,
509 resolver_ResolveUri
512 static IXmlResolver testresolver = { &resolvervtbl };
514 static void test_reader_create(void)
516 IXmlResolver *resolver;
517 IUnknown *input, *unk;
518 IXmlReader *reader;
519 DtdProcessing dtd;
520 XmlNodeType nodetype;
521 HRESULT hr;
523 /* crashes native */
524 if (0)
526 CreateXmlReader(&IID_IXmlReader, NULL, NULL);
527 CreateXmlReader(NULL, (void**)&reader, NULL);
530 hr = CreateXmlReader(&IID_IStream, (void **)&unk, NULL);
531 ok(hr == E_NOINTERFACE, "got %08x\n", hr);
533 hr = CreateXmlReader(&IID_IUnknown, (void **)&unk, NULL);
534 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
535 hr = IUnknown_QueryInterface(unk, &IID_IXmlReader, (void **)&reader);
536 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
537 ok(unk == (IUnknown *)reader, "unexpected interface\n");
538 IXmlReader_Release(reader);
539 IUnknown_Release(unk);
541 hr = CreateXmlReader(&IID_IUnknown, (void **)&reader, NULL);
542 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
543 IXmlReader_Release(reader);
545 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
546 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
548 TEST_READER_STATE(reader, XmlReadState_Closed);
550 nodetype = XmlNodeType_Element;
551 hr = IXmlReader_GetNodeType(reader, &nodetype);
552 ok(hr == S_FALSE, "got %08x\n", hr);
553 ok(nodetype == XmlNodeType_None, "got %d\n", nodetype);
555 /* crashes on XP, 2k3, works on newer versions */
556 if (0)
558 hr = IXmlReader_GetNodeType(reader, NULL);
559 ok(hr == E_INVALIDARG, "got %08x\n", hr);
562 resolver = (void*)0xdeadbeef;
563 hr = IXmlReader_GetProperty(reader, XmlReaderProperty_XmlResolver, (LONG_PTR*)&resolver);
564 ok(hr == S_OK, "got 0x%08x\n", hr);
565 ok(resolver == NULL, "got %p\n", resolver);
567 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_XmlResolver, 0);
568 ok(hr == S_OK, "got 0x%08x\n", hr);
570 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_XmlResolver, (LONG_PTR)&testresolver);
571 ok(hr == S_OK, "got 0x%08x\n", hr);
573 resolver = NULL;
574 hr = IXmlReader_GetProperty(reader, XmlReaderProperty_XmlResolver, (LONG_PTR*)&resolver);
575 ok(hr == S_OK, "got 0x%08x\n", hr);
576 ok(resolver == &testresolver, "got %p\n", resolver);
577 IXmlResolver_Release(resolver);
579 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_XmlResolver, 0);
580 ok(hr == S_OK, "got 0x%08x\n", hr);
582 dtd = 2;
583 hr = IXmlReader_GetProperty(reader, XmlReaderProperty_DtdProcessing, (LONG_PTR*)&dtd);
584 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
585 ok(dtd == DtdProcessing_Prohibit, "got %d\n", dtd);
587 dtd = 2;
588 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_DtdProcessing, dtd);
589 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
591 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_DtdProcessing, -1);
592 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
594 /* Null input pointer, releases previous input */
595 hr = IXmlReader_SetInput(reader, NULL);
596 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
598 TEST_READER_STATE2(reader, XmlReadState_Initial, XmlReadState_Closed);
600 /* test input interface selection sequence */
601 hr = testinput_createinstance((void**)&input);
602 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
604 if (hr == S_OK)
606 input_iids.count = 0;
607 hr = IXmlReader_SetInput(reader, input);
608 ok(hr == E_NOINTERFACE, "Expected E_NOINTERFACE, got %08x\n", hr);
609 ok_iids(&input_iids, setinput_full, setinput_full_old, FALSE);
610 IUnknown_Release(input);
612 IXmlReader_Release(reader);
615 static void test_readerinput(void)
617 IXmlReaderInput *reader_input;
618 IXmlReader *reader, *reader2;
619 IUnknown *obj, *input;
620 IStream *stream, *stream2;
621 XmlNodeType nodetype;
622 HRESULT hr;
623 LONG ref;
625 hr = CreateXmlReaderInputWithEncodingName(NULL, NULL, NULL, FALSE, NULL, NULL);
626 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
627 hr = CreateXmlReaderInputWithEncodingName(NULL, NULL, NULL, FALSE, NULL, &reader_input);
628 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
630 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
631 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
633 ref = IStream_AddRef(stream);
634 ok(ref == 2, "Expected 2, got %d\n", ref);
635 IStream_Release(stream);
636 hr = CreateXmlReaderInputWithEncodingName((IUnknown*)stream, NULL, NULL, FALSE, NULL, &reader_input);
637 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
639 hr = IUnknown_QueryInterface(reader_input, &IID_IStream, (void**)&stream2);
640 ok(hr == E_NOINTERFACE, "Expected S_OK, got %08x\n", hr);
642 hr = IUnknown_QueryInterface(reader_input, &IID_ISequentialStream, (void**)&stream2);
643 ok(hr == E_NOINTERFACE, "Expected S_OK, got %08x\n", hr);
645 /* IXmlReaderInput grabs a stream reference */
646 ref = IStream_AddRef(stream);
647 ok(ref == 3, "Expected 3, got %d\n", ref);
648 IStream_Release(stream);
650 /* try ::SetInput() with valid IXmlReaderInput */
651 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
652 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
654 ref = IUnknown_AddRef(reader_input);
655 ok(ref == 2, "Expected 2, got %d\n", ref);
656 IUnknown_Release(reader_input);
658 hr = IXmlReader_SetInput(reader, reader_input);
659 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
661 TEST_READER_STATE(reader, XmlReadState_Initial);
663 nodetype = XmlNodeType_Element;
664 hr = IXmlReader_GetNodeType(reader, &nodetype);
665 ok(hr == S_OK, "got %08x\n", hr);
666 ok(nodetype == XmlNodeType_None, "got %d\n", nodetype);
668 /* IXmlReader grabs a IXmlReaderInput reference */
669 ref = IUnknown_AddRef(reader_input);
670 ok(ref == 3, "Expected 3, got %d\n", ref);
671 IUnknown_Release(reader_input);
673 ref = IStream_AddRef(stream);
674 ok(ref == 4, "Expected 4, got %d\n", ref);
675 IStream_Release(stream);
677 /* reset input and check state */
678 hr = IXmlReader_SetInput(reader, NULL);
679 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
681 TEST_READER_STATE2(reader, XmlReadState_Initial, XmlReadState_Closed);
683 IXmlReader_Release(reader);
685 ref = IStream_AddRef(stream);
686 ok(ref == 3, "Expected 3, got %d\n", ref);
687 IStream_Release(stream);
689 ref = IUnknown_AddRef(reader_input);
690 ok(ref == 2, "Expected 2, got %d\n", ref);
691 IUnknown_Release(reader_input);
693 /* IID_IXmlReaderInput */
694 /* it returns a kind of private undocumented vtable incompatible with IUnknown,
695 so it's not a COM interface actually.
696 Such query will be used only to check if input is really IXmlReaderInput */
697 obj = (IUnknown*)0xdeadbeef;
698 hr = IUnknown_QueryInterface(reader_input, &IID_IXmlReaderInput, (void**)&obj);
699 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
700 ref = IUnknown_AddRef(reader_input);
701 ok(ref == 3, "Expected 3, got %d\n", ref);
702 IUnknown_Release(reader_input);
704 IUnknown_Release(reader_input);
705 IUnknown_Release(reader_input);
706 IStream_Release(stream);
708 /* test input interface selection sequence */
709 input = NULL;
710 hr = testinput_createinstance((void**)&input);
711 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
713 input_iids.count = 0;
714 ref = IUnknown_AddRef(input);
715 ok(ref == 2, "Expected 2, got %d\n", ref);
716 IUnknown_Release(input);
717 hr = CreateXmlReaderInputWithEncodingName(input, NULL, NULL, FALSE, NULL, &reader_input);
718 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
719 ok_iids(&input_iids, empty_seq, NULL, FALSE);
720 /* IXmlReaderInput stores stream interface as IUnknown */
721 ref = IUnknown_AddRef(input);
722 ok(ref == 3, "Expected 3, got %d\n", ref);
723 IUnknown_Release(input);
725 hr = CreateXmlReader(&IID_IXmlReader, (LPVOID*)&reader, NULL);
726 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
728 input_iids.count = 0;
729 ref = IUnknown_AddRef(reader_input);
730 ok(ref == 2, "Expected 2, got %d\n", ref);
731 IUnknown_Release(reader_input);
732 ref = IUnknown_AddRef(input);
733 ok(ref == 3, "Expected 3, got %d\n", ref);
734 IUnknown_Release(input);
735 hr = IXmlReader_SetInput(reader, reader_input);
736 ok(hr == E_NOINTERFACE, "Expected E_NOINTERFACE, got %08x\n", hr);
737 ok_iids(&input_iids, setinput_readerinput, NULL, FALSE);
739 TEST_READER_STATE(reader, XmlReadState_Closed);
741 ref = IUnknown_AddRef(input);
742 ok(ref == 3, "Expected 3, got %d\n", ref);
743 IUnknown_Release(input);
745 ref = IUnknown_AddRef(reader_input);
746 ok(ref == 3 || broken(ref == 2) /* versions 1.0.x and 1.1.x - XP, Vista */,
747 "Expected 3, got %d\n", ref);
748 IUnknown_Release(reader_input);
749 /* repeat another time, no check or caching here */
750 input_iids.count = 0;
751 hr = IXmlReader_SetInput(reader, reader_input);
752 ok(hr == E_NOINTERFACE, "Expected E_NOINTERFACE, got %08x\n", hr);
753 ok_iids(&input_iids, setinput_readerinput, NULL, FALSE);
755 /* another reader */
756 hr = CreateXmlReader(&IID_IXmlReader, (LPVOID*)&reader2, NULL);
757 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
759 /* resolving from IXmlReaderInput to IStream/ISequentialStream is done at
760 ::SetInput() level, each time it's called */
761 input_iids.count = 0;
762 hr = IXmlReader_SetInput(reader2, reader_input);
763 ok(hr == E_NOINTERFACE, "Expected E_NOINTERFACE, got %08x\n", hr);
764 ok_iids(&input_iids, setinput_readerinput, NULL, FALSE);
766 IXmlReader_Release(reader2);
767 IXmlReader_Release(reader);
769 IUnknown_Release(reader_input);
770 IUnknown_Release(input);
773 static void test_reader_state(void)
775 XmlNodeType nodetype;
776 IXmlReader *reader;
777 HRESULT hr;
779 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
780 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
782 /* invalid arguments */
783 hr = IXmlReader_GetProperty(reader, XmlReaderProperty_ReadState, NULL);
784 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
786 /* attempt to read on closed reader */
787 TEST_READER_STATE(reader, XmlReadState_Closed);
789 if (0)
791 /* newer versions crash here, probably because no input was set */
792 hr = IXmlReader_Read(reader, &nodetype);
793 ok(hr == S_FALSE, "got %08x\n", hr);
795 set_input_string(reader, "xml");
796 TEST_READER_STATE(reader, XmlReadState_Initial);
798 nodetype = XmlNodeType_Element;
799 hr = IXmlReader_Read(reader, &nodetype);
800 todo_wine
801 ok(FAILED(hr), "got %08x\n", hr);
802 ok(nodetype == XmlNodeType_None, "Unexpected node type %d\n", nodetype);
804 todo_wine
805 TEST_READER_STATE(reader, XmlReadState_Error);
807 nodetype = XmlNodeType_Element;
808 hr = IXmlReader_Read(reader, &nodetype);
809 todo_wine
810 ok(FAILED(hr), "got %08x\n", hr);
811 ok(nodetype == XmlNodeType_None, "Unexpected node type %d\n", nodetype);
813 IXmlReader_Release(reader);
816 static void test_reader_depth(IXmlReader *reader, UINT depth, UINT brk, int line)
818 BOOL condition;
819 UINT d = ~0u;
821 IXmlReader_GetDepth(reader, &d);
823 condition = d == depth;
824 if (brk != ~0u)
825 condition |= broken(d == brk);
826 ok_(__FILE__, line)(condition, "Unexpected nesting depth %u, expected %u\n", d, depth);
829 #define TEST_DEPTH(reader, depth) test_reader_depth(reader, depth, ~0u, __LINE__)
830 #define TEST_DEPTH2(reader, depth, brk) test_reader_depth(reader, depth, brk, __LINE__)
832 static void test_read_xmldeclaration(void)
834 static const struct
836 WCHAR name[12];
837 WCHAR val[12];
838 } name_val[] =
840 { {'v','e','r','s','i','o','n',0}, {'1','.','0',0} },
841 { {'e','n','c','o','d','i','n','g',0}, {'U','T','F','-','8',0} },
842 { {'s','t','a','n','d','a','l','o','n','e',0}, {'y','e','s',0} }
844 IXmlReader *reader;
845 IStream *stream;
846 HRESULT hr;
847 XmlNodeType type;
848 UINT count = 0, len, i;
849 BOOL ret;
850 const WCHAR *val;
852 hr = CreateXmlReader(&IID_IXmlReader, (LPVOID*)&reader, NULL);
853 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
855 stream = create_stream_on_data(xmldecl_full, sizeof(xmldecl_full));
857 hr = IXmlReader_SetInput(reader, (IUnknown*)stream);
858 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
860 hr = IXmlReader_GetAttributeCount(reader, &count);
861 ok(hr == S_OK, "got %08x\n", hr);
862 ok(count == 0, "got %d\n", count);
864 /* try to move without attributes */
865 hr = IXmlReader_MoveToElement(reader);
866 ok(hr == S_FALSE, "got %08x\n", hr);
868 hr = IXmlReader_MoveToNextAttribute(reader);
869 ok(hr == S_FALSE, "got %08x\n", hr);
871 hr = IXmlReader_MoveToFirstAttribute(reader);
872 ok(hr == S_FALSE, "got %08x\n", hr);
874 TEST_READER_POSITION(reader, 0, 0);
876 read_node(reader, XmlNodeType_XmlDeclaration);
878 /* new version 1.2.x and 1.3.x properly update position for <?xml ?> */
879 TEST_READER_POSITION2(reader, 1, 3, ~0u, 55);
881 TEST_DEPTH(reader, 0);
882 TEST_READER_STATE(reader, XmlReadState_Interactive);
884 reader_value(reader, L"");
886 /* check attributes */
887 next_attribute(reader);
889 TEST_DEPTH(reader, 1);
891 type = XmlNodeType_None;
892 hr = IXmlReader_GetNodeType(reader, &type);
893 ok(hr == S_OK, "got %08x\n", hr);
894 ok(type == XmlNodeType_Attribute, "got %d\n", type);
896 TEST_READER_POSITION2(reader, 1, 7, ~0u, 55);
898 /* try to move from last attribute */
899 next_attribute(reader);
900 next_attribute(reader);
901 hr = IXmlReader_MoveToNextAttribute(reader);
902 ok(hr == S_FALSE, "got %08x\n", hr);
904 type = XmlNodeType_None;
905 hr = IXmlReader_GetNodeType(reader, &type);
906 ok(hr == S_OK, "got %08x\n", hr);
907 ok(type == XmlNodeType_Attribute, "got %d\n", type);
909 hr = IXmlReader_MoveToFirstAttribute(reader);
910 ok(hr == S_OK, "got %08x\n", hr);
911 TEST_READER_POSITION2(reader, 1, 7, ~0u, 55);
913 hr = IXmlReader_GetAttributeCount(reader, NULL);
914 ok(hr == E_INVALIDARG, "got %08x\n", hr);
916 hr = IXmlReader_GetAttributeCount(reader, &count);
917 ok(hr == S_OK, "got %08x\n", hr);
918 ok(count == 3, "Expected 3, got %d\n", count);
920 for (i = 0; i < count; i++)
922 len = 0;
923 hr = IXmlReader_GetLocalName(reader, &val, &len);
924 ok(hr == S_OK, "got %08x\n", hr);
925 ok(len == lstrlenW(name_val[i].name), "expected %u, got %u\n", lstrlenW(name_val[i].name), len);
926 ok(!lstrcmpW(name_val[i].name, val), "expected %s, got %s\n", wine_dbgstr_w(name_val[i].name), wine_dbgstr_w(val));
928 len = 0;
929 hr = IXmlReader_GetValue(reader, &val, &len);
930 ok(hr == S_OK, "got %08x\n", hr);
931 ok(len == lstrlenW(name_val[i].val), "expected %u, got %u\n", lstrlenW(name_val[i].val), len);
932 ok(!lstrcmpW(name_val[i].val, val), "expected %s, got %s\n", wine_dbgstr_w(name_val[i].val), wine_dbgstr_w(val));
934 hr = IXmlReader_MoveToNextAttribute(reader);
935 ok(hr == ((i < count - 1) ? S_OK : S_FALSE), "got %08x\n", hr);
938 TEST_DEPTH(reader, 1);
940 move_to_element(reader);
941 TEST_READER_POSITION2(reader, 1, 3, ~0u, 55);
943 type = XmlNodeType_None;
944 hr = IXmlReader_GetNodeType(reader, &type);
945 ok(hr == S_OK, "got %08x\n", hr);
946 ok(type == XmlNodeType_XmlDeclaration, "got %d\n", type);
948 type = XmlNodeType_XmlDeclaration;
949 hr = IXmlReader_Read(reader, &type);
950 /* newer versions return syntax error here cause document is incomplete,
951 it makes more sense than invalid char error */
952 todo_wine {
953 ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "got 0x%08x\n", hr);
954 ok(type == XmlNodeType_None, "got %d\n", type);
956 IStream_Release(stream);
958 /* test short variant */
959 stream = create_stream_on_data(xmldecl_short, sizeof(xmldecl_short));
961 hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
962 ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
964 read_node(reader, XmlNodeType_XmlDeclaration);
965 TEST_READER_POSITION2(reader, 1, 3, ~0u, 21);
966 TEST_READER_STATE(reader, XmlReadState_Interactive);
968 hr = IXmlReader_GetAttributeCount(reader, &count);
969 ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
970 ok(count == 1, "expected 1, got %d\n", count);
972 ret = IXmlReader_IsEmptyElement(reader);
973 ok(!ret, "element should not be empty\n");
975 reader_value(reader, L"");
976 reader_name(reader, L"xml");
978 reader_qname(reader, L"xml");
980 /* check attributes */
981 next_attribute(reader);
983 type = -1;
984 hr = IXmlReader_GetNodeType(reader, &type);
985 ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
986 ok(type == XmlNodeType_Attribute, "got %d\n", type);
987 TEST_READER_POSITION2(reader, 1, 7, ~0u, 21);
989 /* try to move from last attribute */
990 hr = IXmlReader_MoveToNextAttribute(reader);
991 ok(hr == S_FALSE, "expected S_FALSE, got %08x\n", hr);
993 read_node(reader, XmlNodeType_Element);
994 TEST_READER_POSITION2(reader, 1, 23, ~0u, 40);
995 TEST_READER_STATE(reader, XmlReadState_Interactive);
997 hr = IXmlReader_GetAttributeCount(reader, &count);
998 ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
999 ok(count == 0, "expected 0, got %d\n", count);
1001 ret = IXmlReader_IsEmptyElement(reader);
1002 ok(ret, "element should be empty\n");
1004 reader_value(reader, L"");
1005 reader_name(reader, L"RegistrationInfo");
1007 type = -1;
1008 hr = IXmlReader_Read(reader, &type);
1009 todo_wine
1010 ok(hr == WC_E_SYNTAX || hr == WC_E_XMLCHARACTER /* XP */, "expected WC_E_SYNTAX, got %08x\n", hr);
1011 ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
1012 TEST_READER_POSITION(reader, 1, 41);
1013 todo_wine
1014 TEST_READER_STATE(reader, XmlReadState_Error);
1016 IStream_Release(stream);
1017 IXmlReader_Release(reader);
1020 struct test_entry
1022 const char *xml;
1023 const WCHAR *name;
1024 const WCHAR *value;
1025 HRESULT hr;
1026 HRESULT hr_broken; /* this is set to older version results */
1027 BOOL todo;
1030 static struct test_entry comment_tests[] =
1032 { "<!-- comment -->", L"", L" comment ", S_OK },
1033 { "<!-- - comment-->", L"", L" - comment", S_OK },
1034 { "<!-- -- comment-->", NULL, NULL, WC_E_COMMENT, WC_E_GREATERTHAN },
1035 { "<!-- -- comment--->", NULL, NULL, WC_E_COMMENT, WC_E_GREATERTHAN },
1036 { NULL }
1039 static void test_read_comment(void)
1041 static const char *teststr = "<a>text<!-- comment --></a>";
1042 struct test_entry *test = comment_tests;
1043 static const XmlNodeType types[] =
1045 XmlNodeType_Element,
1046 XmlNodeType_Text,
1047 XmlNodeType_Comment,
1048 XmlNodeType_EndElement,
1050 unsigned int i = 0;
1051 IXmlReader *reader;
1052 XmlNodeType type;
1053 HRESULT hr;
1055 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1056 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1058 set_input_string(reader, teststr);
1060 while (IXmlReader_Read(reader, &type) == S_OK)
1062 const WCHAR *value;
1064 ok(type == types[i], "%d: unexpected node type %d\n", i, type);
1066 if (type == XmlNodeType_Text || type == XmlNodeType_Comment)
1068 hr = IXmlReader_GetValue(reader, &value, NULL);
1069 ok(hr == S_OK, "got %08x\n", hr);
1070 ok(*value != 0, "Expected node value\n");
1072 i++;
1075 while (test->xml)
1077 set_input_string(reader, test->xml);
1079 type = XmlNodeType_None;
1080 hr = IXmlReader_Read(reader, &type);
1081 if (test->hr_broken)
1082 ok(hr == test->hr || broken(hr == test->hr_broken), "got %08x for %s\n", hr, test->xml);
1083 else
1084 ok(hr == test->hr, "got %08x for %s\n", hr, test->xml);
1085 if (hr == S_OK)
1087 const WCHAR *str;
1089 ok(type == XmlNodeType_Comment, "got %d for %s\n", type, test->xml);
1091 reader_name(reader, L"");
1093 str = NULL;
1094 hr = IXmlReader_GetLocalName(reader, &str, NULL);
1095 ok(hr == S_OK, "got 0x%08x\n", hr);
1096 ok(*str == 0, "got %s\n", wine_dbgstr_w(str));
1098 reader_qname(reader, L"");
1100 str = NULL;
1101 hr = IXmlReader_GetQualifiedName(reader, &str, NULL);
1102 ok(hr == S_OK, "got 0x%08x\n", hr);
1103 ok(*str == 0, "got %s\n", wine_dbgstr_w(str));
1105 /* value */
1106 reader_value(reader, test->value);
1109 test++;
1112 IXmlReader_Release(reader);
1115 static struct test_entry pi_tests[] =
1117 { "<?pi?>", L"pi", L"", S_OK },
1118 { "<?pi ?>", L"pi", L"", S_OK },
1119 { "<?pi ?>", L"pi", L"", S_OK },
1120 { "<?pi pi data?>", L"pi", L"pi data", S_OK },
1121 { "<?pi pi data ?>", L"pi", L"pi data ", S_OK },
1122 { "<?pi data ?>", L"pi", L"data ", S_OK },
1123 { "<?pi:pi?>", NULL, NULL, NC_E_NAMECOLON, WC_E_NAMECHARACTER },
1124 { "<?:pi ?>", NULL, NULL, WC_E_PI, WC_E_NAMECHARACTER },
1125 { "<?-pi ?>", NULL, NULL, WC_E_PI, WC_E_NAMECHARACTER },
1126 { "<?xml-stylesheet ?>", L"xml-stylesheet", L"", S_OK },
1127 { NULL }
1130 static void test_read_pi(void)
1132 struct test_entry *test = pi_tests;
1133 IXmlReader *reader;
1134 HRESULT hr;
1136 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1137 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1139 while (test->xml)
1141 XmlNodeType type;
1143 set_input_string(reader, test->xml);
1145 type = XmlNodeType_None;
1146 hr = IXmlReader_Read(reader, &type);
1147 if (test->hr_broken)
1148 ok(hr == test->hr || broken(hr == test->hr_broken), "got %08x for %s\n", hr, test->xml);
1149 else
1150 ok(hr == test->hr, "got %08x for %s\n", hr, test->xml);
1151 if (hr == S_OK)
1153 const WCHAR *str;
1154 UINT len;
1156 ok(type == XmlNodeType_ProcessingInstruction, "got %d for %s\n", type, test->xml);
1158 reader_name(reader, test->name);
1160 len = 0;
1161 str = NULL;
1162 hr = IXmlReader_GetQualifiedName(reader, &str, &len);
1163 ok(hr == S_OK, "got 0x%08x\n", hr);
1164 ok(len == lstrlenW(test->name), "got %u\n", len);
1165 ok(!lstrcmpW(str, test->name), "got %s\n", wine_dbgstr_w(str));
1167 /* value */
1168 reader_value(reader, test->value);
1171 test++;
1174 IXmlReader_Release(reader);
1177 struct nodes_test {
1178 const char *xml;
1179 struct {
1180 XmlNodeType type;
1181 const WCHAR *value;
1182 } nodes[20];
1185 static const char misc_test_xml[] =
1186 "<!-- comment1 -->"
1187 "<!-- comment2 -->"
1188 "<?pi1 pi1body ?>"
1189 "<!-- comment3 -->"
1190 " \t \r \n"
1191 "<!-- comment4 -->"
1192 "<a>"
1193 "\r\n\t"
1194 "<b/>"
1195 "text"
1196 "<!-- comment -->"
1197 "text2"
1198 "<?pi pibody ?>"
1199 "\r\n"
1200 "</a>"
1203 static struct nodes_test misc_test = {
1204 misc_test_xml,
1206 { XmlNodeType_Comment, L" comment1 " },
1207 { XmlNodeType_Comment, L" comment2 " },
1208 { XmlNodeType_ProcessingInstruction, L"pi1body " },
1209 { XmlNodeType_Comment, L" comment3 " },
1210 { XmlNodeType_Whitespace, L" \t \n \n" },
1211 { XmlNodeType_Comment, L" comment4 " },
1212 { XmlNodeType_Element, L"" },
1213 { XmlNodeType_Whitespace, L"\n\t" },
1214 { XmlNodeType_Element, L"" },
1215 { XmlNodeType_Text, L"text" },
1216 { XmlNodeType_Comment, L" comment " },
1217 { XmlNodeType_Text, L"text2" },
1218 { XmlNodeType_ProcessingInstruction, L"pibody " },
1219 { XmlNodeType_Whitespace, L"\n" },
1220 { XmlNodeType_EndElement, L"" },
1221 { XmlNodeType_None, L"" }
1225 static void test_read_full(void)
1227 struct nodes_test *test = &misc_test;
1228 IXmlReader *reader;
1229 HRESULT hr;
1230 int i;
1232 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1233 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1235 set_input_string(reader, test->xml);
1237 i = 0;
1240 read_node(reader, test->nodes[i].type);
1241 reader_value(reader, test->nodes[i].value);
1242 } while(test->nodes[i++].type != XmlNodeType_None);
1244 IXmlReader_Release(reader);
1247 static const char test_public_dtd[] =
1248 "<!DOCTYPE testdtd PUBLIC \"pubid\" \"externalid uri\" >";
1250 static void test_read_public_dtd(void)
1252 static const WCHAR dtdnameW[] = {'t','e','s','t','d','t','d',0};
1253 IXmlReader *reader;
1254 const WCHAR *str;
1255 XmlNodeType type;
1256 UINT len, count;
1257 HRESULT hr;
1259 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1260 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1262 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_DtdProcessing, DtdProcessing_Parse);
1263 ok(hr == S_OK, "got 0x%8x\n", hr);
1265 set_input_string(reader, test_public_dtd);
1267 read_node(reader, XmlNodeType_DocumentType);
1269 count = 0;
1270 hr = IXmlReader_GetAttributeCount(reader, &count);
1271 ok(hr == S_OK, "got %08x\n", hr);
1272 ok(count == 2, "got %d\n", count);
1274 hr = IXmlReader_MoveToFirstAttribute(reader);
1275 ok(hr == S_OK, "got %08x\n", hr);
1277 type = XmlNodeType_None;
1278 hr = IXmlReader_GetNodeType(reader, &type);
1279 ok(hr == S_OK, "got %08x\n", hr);
1280 ok(type == XmlNodeType_Attribute, "got %d\n", type);
1282 reader_name(reader, L"PUBLIC");
1283 reader_value(reader, L"pubid");
1285 next_attribute(reader);
1287 type = XmlNodeType_None;
1288 hr = IXmlReader_GetNodeType(reader, &type);
1289 ok(hr == S_OK, "got %08x\n", hr);
1290 ok(type == XmlNodeType_Attribute, "got %d\n", type);
1292 reader_name(reader, L"SYSTEM");
1293 reader_value(reader, L"externalid uri");
1295 move_to_element(reader);
1296 reader_name(reader, L"testdtd");
1298 len = 0;
1299 str = NULL;
1300 hr = IXmlReader_GetQualifiedName(reader, &str, &len);
1301 ok(hr == S_OK, "got 0x%08x\n", hr);
1302 todo_wine {
1303 ok(len == lstrlenW(dtdnameW), "got %u\n", len);
1304 ok(!lstrcmpW(str, dtdnameW), "got %s\n", wine_dbgstr_w(str));
1306 IXmlReader_Release(reader);
1309 static const char test_system_dtd[] =
1310 "<!DOCTYPE testdtd SYSTEM \"externalid uri\" >"
1311 "<!-- comment -->";
1313 static void test_read_system_dtd(void)
1315 static const WCHAR dtdnameW[] = {'t','e','s','t','d','t','d',0};
1316 IXmlReader *reader;
1317 const WCHAR *str;
1318 XmlNodeType type;
1319 UINT len, count;
1320 HRESULT hr;
1322 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1323 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1325 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_DtdProcessing, DtdProcessing_Parse);
1326 ok(hr == S_OK, "got 0x%8x\n", hr);
1328 set_input_string(reader, test_system_dtd);
1330 read_node(reader, XmlNodeType_DocumentType);
1332 count = 0;
1333 hr = IXmlReader_GetAttributeCount(reader, &count);
1334 ok(hr == S_OK, "got %08x\n", hr);
1335 ok(count == 1, "got %d\n", count);
1337 hr = IXmlReader_MoveToFirstAttribute(reader);
1338 ok(hr == S_OK, "got %08x\n", hr);
1340 type = XmlNodeType_None;
1341 hr = IXmlReader_GetNodeType(reader, &type);
1342 ok(hr == S_OK, "got %08x\n", hr);
1343 ok(type == XmlNodeType_Attribute, "got %d\n", type);
1345 reader_name(reader, L"SYSTEM");
1346 reader_value(reader, L"externalid uri");
1348 move_to_element(reader);
1349 reader_name(reader, L"testdtd");
1351 len = 0;
1352 str = NULL;
1353 hr = IXmlReader_GetQualifiedName(reader, &str, &len);
1354 ok(hr == S_OK, "got 0x%08x\n", hr);
1355 todo_wine {
1356 ok(len == lstrlenW(dtdnameW), "got %u\n", len);
1357 ok(!lstrcmpW(str, dtdnameW), "got %s\n", wine_dbgstr_w(str));
1360 read_node(reader, XmlNodeType_Comment);
1362 IXmlReader_Release(reader);
1365 static struct test_entry element_tests[] =
1367 { "<a/>", L"a", L"", S_OK },
1368 { "<a />", L"a", L"", S_OK },
1369 { "<a:b/>", L"a:b", L"", NC_E_UNDECLAREDPREFIX },
1370 { "<:a/>", NULL, NULL, NC_E_QNAMECHARACTER },
1371 { "< a/>", NULL, NULL, NC_E_QNAMECHARACTER },
1372 { "<a>", L"a", L"", S_OK },
1373 { "<a >", L"a", L"", S_OK },
1374 { "<a \r \t\n>", L"a", L"", S_OK },
1375 { "</a>", NULL, NULL, NC_E_QNAMECHARACTER },
1376 { "<a:b:c />", NULL, NULL, NC_E_QNAMECOLON },
1377 { "<:b:c />", NULL, NULL, NC_E_QNAMECHARACTER },
1378 { NULL }
1381 static void test_read_element(void)
1383 struct test_entry *test = element_tests;
1384 static const char stag[] =
1385 "<a attr1=\"_a\">"
1386 "<b attr2=\"_b\">"
1387 "text"
1388 "<c attr3=\"_c\"/>"
1389 "<d attr4=\"_d\"></d>"
1390 "</b>"
1391 "</a>";
1392 static const UINT depths[] = { 0, 1, 2, 2, 2, 3, 2, 1 };
1393 IXmlReader *reader;
1394 XmlNodeType type;
1395 unsigned int i;
1396 UINT depth;
1397 HRESULT hr;
1399 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1400 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1402 while (test->xml)
1404 set_input_string(reader, test->xml);
1406 type = XmlNodeType_None;
1407 hr = IXmlReader_Read(reader, &type);
1408 if (test->hr_broken)
1409 ok(hr == test->hr || broken(hr == test->hr_broken), "got %08x for %s\n", hr, test->xml);
1410 else
1411 todo_wine_if(test->hr == NC_E_UNDECLAREDPREFIX)
1412 ok(hr == test->hr, "got %08x for %s\n", hr, test->xml);
1413 if (hr == S_OK)
1415 const WCHAR *str;
1416 UINT len;
1418 ok(type == XmlNodeType_Element, "got %d for %s\n", type, test->xml);
1420 len = 0;
1421 str = NULL;
1422 hr = IXmlReader_GetQualifiedName(reader, &str, &len);
1423 ok(hr == S_OK, "got 0x%08x\n", hr);
1424 ok(len == lstrlenW(test->name), "got %u\n", len);
1425 ok(!lstrcmpW(str, test->name), "got %s\n", wine_dbgstr_w(str));
1427 /* value */
1428 reader_value(reader, L"");
1431 test++;
1434 /* test reader depth increment */
1435 set_input_string(reader, stag);
1437 i = 0;
1438 while (IXmlReader_Read(reader, &type) == S_OK)
1440 UINT count;
1442 ok(type == XmlNodeType_Element || type == XmlNodeType_EndElement ||
1443 type == XmlNodeType_Text, "Unexpected node type %d\n", type);
1445 depth = 123;
1446 hr = IXmlReader_GetDepth(reader, &depth);
1447 ok(hr == S_OK, "got %08x\n", hr);
1448 ok(depth == depths[i], "%u: got depth %u, expected %u\n", i, depth, depths[i]);
1450 if (type == XmlNodeType_Element || type == XmlNodeType_EndElement)
1452 const WCHAR *prefix;
1454 prefix = NULL;
1455 hr = IXmlReader_GetPrefix(reader, &prefix, NULL);
1456 ok(hr == S_OK, "got %08x\n", hr);
1457 ok(prefix != NULL, "got %p\n", prefix);
1459 if (!*prefix)
1461 const WCHAR *local, *qname;
1463 local = NULL;
1464 hr = IXmlReader_GetLocalName(reader, &local, NULL);
1465 ok(hr == S_OK, "got %08x\n", hr);
1466 ok(local != NULL, "got %p\n", local);
1468 qname = NULL;
1469 hr = IXmlReader_GetQualifiedName(reader, &qname, NULL);
1470 ok(hr == S_OK, "got %08x\n", hr);
1471 ok(qname != NULL, "got %p\n", qname);
1473 ok(local == qname, "expected same pointer\n");
1477 if (type == XmlNodeType_EndElement)
1479 count = 1;
1480 hr = IXmlReader_GetAttributeCount(reader, &count);
1481 ok(hr == S_OK, "got %08x\n", hr);
1482 ok(count == 0, "got %u\n", count);
1485 if (type == XmlNodeType_Element)
1487 count = 0;
1488 hr = IXmlReader_GetAttributeCount(reader, &count);
1489 ok(hr == S_OK, "got %08x\n", hr);
1491 /* moving to attributes increases depth */
1492 if (count)
1494 const WCHAR *value;
1496 reader_value(reader, L"");
1498 hr = IXmlReader_MoveToFirstAttribute(reader);
1499 ok(hr == S_OK, "got %08x\n", hr);
1501 hr = IXmlReader_GetValue(reader, &value, NULL);
1502 ok(*value != 0, "Unexpected value %s\n", wine_dbgstr_w(value));
1504 depth = 123;
1505 hr = IXmlReader_GetDepth(reader, &depth);
1506 ok(hr == S_OK, "got %08x\n", hr);
1507 ok(depth == depths[i] + 1, "%u: got depth %u, expected %u\n", i, depth, depths[i] + 1);
1509 move_to_element(reader);
1510 reader_value(reader, L"");
1512 depth = 123;
1513 hr = IXmlReader_GetDepth(reader, &depth);
1514 ok(hr == S_OK, "got %08x\n", hr);
1515 ok(depth == depths[i], "%u: got depth %u, expected %u\n", i, depth, depths[i]);
1519 i++;
1522 /* start/end tag mismatch */
1523 set_input_string(reader, "<a></b>");
1525 read_node(reader, XmlNodeType_Element);
1527 type = XmlNodeType_Element;
1528 hr = IXmlReader_Read(reader, &type);
1529 ok(hr == WC_E_ELEMENTMATCH, "got %08x\n", hr);
1530 ok(type == XmlNodeType_None, "got %d\n", type);
1531 TEST_READER_STATE(reader, XmlReadState_Error);
1533 IXmlReader_Release(reader);
1536 static ISequentialStream teststream = { &teststreamvtbl };
1538 static void test_read_pending(void)
1540 IXmlReader *reader;
1541 const WCHAR *value;
1542 XmlNodeType type;
1543 HRESULT hr;
1544 int c;
1546 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1547 ok(hr == S_OK, "S_OK, got 0x%08x\n", hr);
1549 hr = IXmlReader_SetInput(reader, (IUnknown*)&teststream);
1550 ok(hr == S_OK, "got 0x%08x\n", hr);
1552 /* first read call returns incomplete node, second attempt fails with E_PENDING */
1553 stream_readcall = 0;
1554 type = XmlNodeType_Element;
1555 hr = IXmlReader_Read(reader, &type);
1556 ok(hr == S_OK || broken(hr == E_PENDING), "got 0x%08x\n", hr);
1557 /* newer versions are happy when it's enough data to detect node type,
1558 older versions keep reading until it fails to read more */
1559 todo_wine
1560 ok(stream_readcall == 1 || broken(stream_readcall > 1), "got %d\n", stream_readcall);
1561 ok(type == XmlNodeType_Comment || broken(type == XmlNodeType_None), "got %d\n", type);
1563 /* newer versions' GetValue() makes an attempt to read more */
1564 c = stream_readcall;
1565 value = (void*)0xdeadbeef;
1566 hr = IXmlReader_GetValue(reader, &value, NULL);
1567 ok(hr == E_PENDING, "got 0x%08x\n", hr);
1568 ok(value == NULL || broken(value == (void*)0xdeadbeef) /* Win8 sets it to NULL */, "got %p\n", value);
1569 ok(c < stream_readcall || broken(c == stream_readcall), "got %d, expected %d\n", stream_readcall, c+1);
1571 IXmlReader_Release(reader);
1574 static void test_readvaluechunk(void)
1576 IXmlReader *reader;
1577 XmlNodeType type;
1578 WCHAR buf[64];
1579 WCHAR b;
1580 HRESULT hr;
1581 UINT c;
1583 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1584 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1586 set_input_string(reader, "<!-- comment1 --><!-- comment2 -->");
1588 hr = IXmlReader_Read(reader, &type);
1589 ok(hr == S_OK, "got %08x\n", hr);
1590 ok(type == XmlNodeType_Comment, "type = %u\n", type);
1592 read_value_char(reader, ' ');
1593 read_value_char(reader, 'c');
1595 /* portion read as chunk is skipped from resulting node value */
1596 reader_value(reader, L"omment1 ");
1598 /* once value is returned/allocated it's not possible to read by chunk */
1599 c = 0;
1600 b = 0;
1601 hr = IXmlReader_ReadValueChunk(reader, &b, 1, &c);
1602 ok(hr == S_FALSE, "got %08x\n", hr);
1603 ok(c == 0, "got %u\n", c);
1604 ok(b == 0, "got %x\n", b);
1606 c = 0xdeadbeef;
1607 hr = IXmlReader_ReadValueChunk(reader, buf, 0, &c);
1608 ok(hr == S_OK, "got %08x\n", hr);
1609 ok(!c, "c = %u\n", c);
1611 reader_value(reader, L"omment1 ");
1613 /* read comment2 */
1614 read_node(reader, XmlNodeType_Comment);
1616 c = 0xdeadbeef;
1617 hr = IXmlReader_ReadValueChunk(reader, buf, 0, &c);
1618 ok(hr == S_OK, "got %08x\n", hr);
1619 ok(!c, "c = %u\n", c);
1621 c = 0xdeadbeef;
1622 memset(buf, 0xcc, sizeof(buf));
1623 hr = IXmlReader_ReadValueChunk(reader, buf, ARRAY_SIZE(buf), &c);
1624 ok(hr == S_OK, "got %08x\n", hr);
1625 ok(c == 10, "got %u\n", c);
1626 ok(buf[c] == 0xcccc, "buffer overflow\n");
1627 buf[c] = 0;
1628 ok(!lstrcmpW(buf, L" comment2 "), "buf = %s\n", wine_dbgstr_w(buf));
1630 c = 0xdeadbeef;
1631 memset(buf, 0xcc, sizeof(buf));
1632 hr = IXmlReader_ReadValueChunk(reader, buf, ARRAY_SIZE(buf), &c);
1633 ok(hr == S_FALSE, "got %08x\n", hr);
1634 ok(!c, "got %u\n", c);
1636 /* portion read as chunk is skipped from resulting node value */
1637 reader_value(reader, L"");
1639 /* once value is returned/allocated it's not possible to read by chunk */
1640 c = 0xdeadbeef;
1641 b = 0xffff;
1642 hr = IXmlReader_ReadValueChunk(reader, &b, 1, &c);
1643 ok(hr == S_FALSE, "got %08x\n", hr);
1644 ok(c == 0, "got %u\n", c);
1645 ok(b == 0xffff, "got %x\n", b);
1647 reader_value(reader, L"");
1649 IXmlReader_Release(reader);
1652 static struct test_entry cdata_tests[] =
1654 { "<a><![CDATA[ ]]data ]]></a>", L"", L" ]]data ", S_OK },
1655 { "<a><![CDATA[<![CDATA[ data ]]]]></a>", L"", L"<![CDATA[ data ]]", S_OK },
1656 { "<a><![CDATA[\n \r\n \n\n ]]></a>", L"", L"\n \n \n\n ", S_OK, S_OK },
1657 { "<a><![CDATA[\r \r\r\n \n\n ]]></a>", L"", L"\n \n\n \n\n ", S_OK, S_OK },
1658 { "<a><![CDATA[\r\r \n\r \r \n\n ]]></a>", L"", L"\n\n \n\n \n \n\n ", S_OK },
1659 { NULL }
1662 static void test_read_cdata(void)
1664 struct test_entry *test = cdata_tests;
1665 IXmlReader *reader;
1666 HRESULT hr;
1668 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1669 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1671 while (test->xml)
1673 XmlNodeType type;
1675 set_input_string(reader, test->xml);
1677 type = XmlNodeType_None;
1678 hr = IXmlReader_Read(reader, &type);
1680 /* read one more to get to CDATA */
1681 if (type == XmlNodeType_Element)
1683 type = XmlNodeType_None;
1684 hr = IXmlReader_Read(reader, &type);
1687 if (test->hr_broken)
1688 ok(hr == test->hr || broken(hr == test->hr_broken), "got %08x for %s\n", hr, test->xml);
1689 else
1690 ok(hr == test->hr, "got %08x for %s\n", hr, test->xml);
1691 if (hr == S_OK)
1693 const WCHAR *str;
1694 UINT len;
1696 ok(type == XmlNodeType_CDATA, "got %d for %s\n", type, test->xml);
1698 reader_name(reader, L"");
1700 str = NULL;
1701 hr = IXmlReader_GetLocalName(reader, &str, NULL);
1702 ok(hr == S_OK, "got 0x%08x\n", hr);
1703 ok(*str == 0, "got %s\n", wine_dbgstr_w(str));
1705 len = 1;
1706 str = NULL;
1707 hr = IXmlReader_GetQualifiedName(reader, &str, &len);
1708 ok(hr == S_OK, "got 0x%08x\n", hr);
1709 ok(len == 0, "got %u\n", len);
1710 ok(*str == 0, "got %s\n", wine_dbgstr_w(str));
1712 str = NULL;
1713 hr = IXmlReader_GetQualifiedName(reader, &str, NULL);
1714 ok(hr == S_OK, "got 0x%08x\n", hr);
1715 ok(*str == 0, "got %s\n", wine_dbgstr_w(str));
1717 /* value */
1718 reader_value(reader, test->value);
1721 test++;
1724 IXmlReader_Release(reader);
1727 static struct test_entry text_tests[] =
1729 { "<a>simple text</a>", L"", L"simple text", S_OK },
1730 { "<a>text ]]> text</a>", L"", L"", WC_E_CDSECTEND },
1731 { "<a>\n \r\n \n\n text</a>", L"", L"\n \n \n\n text", S_OK, S_OK },
1732 { "<a>\r \r\r\n \n\n text</a>", L"", L"\n \n\n \n\n text", S_OK, S_OK },
1733 { NULL }
1736 static void test_read_text(void)
1738 struct test_entry *test = text_tests;
1739 IXmlReader *reader;
1740 HRESULT hr;
1742 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1743 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1745 while (test->xml)
1747 XmlNodeType type;
1749 set_input_string(reader, test->xml);
1751 type = XmlNodeType_None;
1752 hr = IXmlReader_Read(reader, &type);
1754 /* read one more to get to text node */
1755 if (type == XmlNodeType_Element)
1757 type = XmlNodeType_None;
1758 hr = IXmlReader_Read(reader, &type);
1760 ok(hr == test->hr, "got %08x for %s\n", hr, test->xml);
1761 if (hr == S_OK)
1763 const WCHAR *str;
1764 UINT len;
1766 ok(type == XmlNodeType_Text, "got %d for %s\n", type, test->xml);
1768 reader_name(reader, L"");
1770 str = NULL;
1771 hr = IXmlReader_GetLocalName(reader, &str, NULL);
1772 ok(hr == S_OK, "got 0x%08x\n", hr);
1773 ok(*str == 0, "got %s\n", wine_dbgstr_w(str));
1775 len = 1;
1776 str = NULL;
1777 hr = IXmlReader_GetQualifiedName(reader, &str, &len);
1778 ok(hr == S_OK, "got 0x%08x\n", hr);
1779 ok(len == 0, "got %u\n", len);
1780 ok(*str == 0, "got %s\n", wine_dbgstr_w(str));
1782 str = NULL;
1783 hr = IXmlReader_GetQualifiedName(reader, &str, NULL);
1784 ok(hr == S_OK, "got 0x%08x\n", hr);
1785 ok(*str == 0, "got %s\n", wine_dbgstr_w(str));
1787 /* value */
1788 reader_value(reader, test->value);
1791 test++;
1794 IXmlReader_Release(reader);
1797 struct test_entry_empty {
1798 const char *xml;
1799 BOOL empty;
1802 static struct test_entry_empty empty_element_tests[] = {
1803 { "<a></a>", FALSE },
1804 { "<a/>", TRUE },
1805 { NULL }
1808 static void test_isemptyelement(void)
1810 struct test_entry_empty *test = empty_element_tests;
1811 IXmlReader *reader;
1812 HRESULT hr;
1814 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1815 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1817 while (test->xml)
1819 XmlNodeType type;
1820 BOOL ret;
1822 set_input_string(reader, test->xml);
1824 type = XmlNodeType_None;
1825 hr = IXmlReader_Read(reader, &type);
1826 ok(hr == S_OK, "got 0x%08x\n", hr);
1827 ok(type == XmlNodeType_Element, "got %d\n", type);
1829 ret = IXmlReader_IsEmptyElement(reader);
1830 ok(ret == test->empty, "got %d, expected %d. xml=%s\n", ret, test->empty, test->xml);
1832 test++;
1835 IXmlReader_Release(reader);
1838 static struct test_entry attributes_tests[] =
1840 { "<a attr1=\"attrvalue\"/>", L"attr1", L"attrvalue", S_OK },
1841 { "<a attr1=\"a\'\'ttrvalue\"/>", L"attr1", L"a\'\'ttrvalue", S_OK },
1842 { "<a attr1=\'a\"ttrvalue\'/>", L"attr1", L"a\"ttrvalue", S_OK },
1843 { "<a attr1=\' \'/>", L"attr1", L" ", S_OK },
1844 { "<a attr1=\" \"/>", L"attr1", L" ", S_OK },
1845 { "<a attr1=\"\r\n \r \n \t\n\r\"/>", L"attr1", L" ", S_OK },
1846 { "<a attr1=\" val \"/>", L"attr1", L" val ", S_OK },
1847 { "<a attr1=\"\r\n\tval\n\"/>", L"attr1", L" val ", S_OK },
1848 { "<a attr1=\"val&#32;\"/>", L"attr1", L"val ", S_OK },
1849 { "<a attr1=\"val&#x20;\"/>", L"attr1", L"val ", S_OK },
1850 { "<a attr1=\"&lt;&gt;&amp;&apos;&quot;\"/>", L"attr1", L"<>&\'\"", S_OK },
1851 { "<a attr1=\"&entname;\"/>", NULL, NULL, WC_E_UNDECLAREDENTITY },
1852 { "<a attr1=\"val&#xfffe;\"/>", NULL, NULL, WC_E_XMLCHARACTER },
1853 { "<a attr1=\"val &#a;\"/>", NULL, NULL, WC_E_DIGIT, WC_E_SEMICOLON },
1854 { "<a attr1=\"val &#12a;\"/>", NULL, NULL, WC_E_SEMICOLON },
1855 { "<a attr1=\"val &#x12g;\"/>", NULL, NULL, WC_E_SEMICOLON },
1856 { "<a attr1=\"val &#xg;\"/>", NULL, NULL, WC_E_HEXDIGIT, WC_E_SEMICOLON },
1857 { "<a attr1=attrvalue/>", NULL, NULL, WC_E_QUOTE },
1858 { "<a attr1=\"attr<value\"/>", NULL, NULL, WC_E_LESSTHAN },
1859 { "<a attr1=\"&entname\"/>", NULL, NULL, WC_E_SEMICOLON },
1860 { NULL }
1863 static void test_read_attribute(void)
1865 struct test_entry *test = attributes_tests;
1866 IXmlReader *reader;
1867 HRESULT hr;
1869 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1870 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1872 while (test->xml)
1874 XmlNodeType type;
1876 set_input_string(reader, test->xml);
1878 hr = IXmlReader_Read(reader, NULL);
1880 if (test->hr_broken)
1881 ok(hr == test->hr || broken(hr == test->hr_broken), "got %08x for %s\n", hr, test->xml);
1882 else
1883 ok(hr == test->hr, "got %08x for %s\n", hr, test->xml);
1884 if (hr == S_OK)
1886 const WCHAR *str;
1887 UINT len;
1889 type = XmlNodeType_None;
1890 hr = IXmlReader_GetNodeType(reader, &type);
1891 ok(hr == S_OK, "Failed to get node type, %#x\n", hr);
1893 ok(type == XmlNodeType_Element, "got %d for %s\n", type, test->xml);
1895 hr = IXmlReader_MoveToFirstAttribute(reader);
1896 ok(hr == S_OK, "got 0x%08x\n", hr);
1898 reader_name(reader, test->name);
1900 len = 1;
1901 str = NULL;
1902 hr = IXmlReader_GetQualifiedName(reader, &str, &len);
1903 ok(hr == S_OK, "got 0x%08x\n", hr);
1904 ok(len == lstrlenW(test->name), "got %u\n", len);
1905 ok(!lstrcmpW(str, test->name), "got %s\n", wine_dbgstr_w(str));
1907 /* value */
1908 reader_value(reader, test->value);
1911 test++;
1914 IXmlReader_Release(reader);
1917 static void test_reader_properties(void)
1919 IXmlReader *reader;
1920 LONG_PTR value;
1921 HRESULT hr;
1923 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1924 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1926 value = 0;
1927 hr = IXmlReader_GetProperty(reader, XmlReaderProperty_MaxElementDepth, &value);
1928 ok(hr == S_OK, "GetProperty failed: %08x\n", hr);
1929 ok(value == 256, "Unexpected default max depth value %ld\n", value);
1931 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_MultiLanguage, 0);
1932 ok(hr == S_OK, "SetProperty failed: %08x\n", hr);
1934 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_MaxElementDepth, 0);
1935 ok(hr == S_OK, "SetProperty failed: %08x\n", hr);
1937 value = 256;
1938 hr = IXmlReader_GetProperty(reader, XmlReaderProperty_MaxElementDepth, &value);
1939 ok(hr == S_OK, "GetProperty failed: %08x\n", hr);
1940 ok(value == 0, "Unexpected max depth value %ld\n", value);
1942 IXmlReader_Release(reader);
1945 static void test_prefix(void)
1947 static const struct
1949 const char *xml;
1950 const WCHAR *prefix1;
1951 const WCHAR *prefix2;
1952 const WCHAR *prefix3;
1953 } prefix_tests[] =
1955 { "<b xmlns=\"defns\" xml:a=\"a ns\"/>", L"", L"", L"xml" },
1956 { "<c:b xmlns:c=\"c ns\" xml:a=\"a ns\"/>", L"c", L"xmlns", L"xml" },
1958 IXmlReader *reader;
1959 unsigned int i;
1960 HRESULT hr;
1962 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
1963 ok(hr == S_OK, "S_OK, got %08x\n", hr);
1965 for (i = 0; i < ARRAY_SIZE(prefix_tests); i++) {
1966 XmlNodeType type;
1968 set_input_string(reader, prefix_tests[i].xml);
1970 hr = IXmlReader_Read(reader, &type);
1971 ok(hr == S_OK, "Read() failed, %#x\n", hr);
1972 ok(type == XmlNodeType_Element, "Unexpected node type %d.\n", type);
1974 reader_prefix(reader, prefix_tests[i].prefix1);
1976 hr = IXmlReader_MoveToFirstAttribute(reader);
1977 ok(hr == S_OK, "MoveToFirstAttribute() failed, %#x.\n", hr);
1979 hr = IXmlReader_GetNodeType(reader, &type);
1980 ok(hr == S_OK, "GetNodeType() failed, %#x.\n", hr);
1981 ok(type == XmlNodeType_Attribute, "Unexpected node type %d.\n", type);
1983 reader_prefix(reader, prefix_tests[i].prefix2);
1985 next_attribute(reader);
1987 hr = IXmlReader_GetNodeType(reader, &type);
1988 ok(hr == S_OK, "GetNodeType() failed, %#x.\n", hr);
1989 ok(type == XmlNodeType_Attribute, "Unexpected node type %d.\n", type);
1991 reader_prefix(reader, prefix_tests[i].prefix3);
1993 /* back to the element, check prefix */
1994 move_to_element(reader);
1995 reader_prefix(reader, prefix_tests[i].prefix1);
1998 IXmlReader_Release(reader);
2001 static void test_namespaceuri(void)
2003 struct uri_test
2005 const char *xml;
2006 const WCHAR *uri[5];
2007 } uri_tests[] =
2009 { "<a xmlns=\"defns a\"><b xmlns=\"defns b\"><c xmlns=\"defns c\"/></b></a>",
2010 { L"defns a", L"defns b", L"defns c", L"defns b", L"defns a" }},
2011 { "<r:a xmlns=\"defns a\" xmlns:r=\"ns r\"/>",
2012 { L"ns r" }},
2013 { "<r:a xmlns=\"defns a\" xmlns:r=\"ns r\"><b/></r:a>",
2014 { L"ns r", L"defns a", L"ns r" }},
2015 { "<a xmlns=\"defns a\" xmlns:r=\"ns r\"><r:b/></a>",
2016 { L"defns a", L"ns r", L"defns a" }},
2017 { "<a><b><c/></b></a>",
2018 { L"", L"", L"", L"", L"" }},
2019 { "<a>text</a>",
2020 { L"", L"", L"" }},
2021 { "<a>\r\n</a>",
2022 { L"", L"", L"" }},
2023 { "<a><![CDATA[data]]></a>",
2024 { L"", L"", L"" }},
2025 { "<?xml version=\"1.0\" ?><a/>",
2026 { L"", L"" }},
2027 { "<a><?pi ?></a>",
2028 { L"", L"", L"" }},
2029 { "<a><!-- comment --></a>",
2030 { L"", L"", L"" }},
2032 IXmlReader *reader;
2033 XmlNodeType type;
2034 unsigned int i;
2035 HRESULT hr;
2037 hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
2038 ok(hr == S_OK, "S_OK, got %08x\n", hr);
2040 for (i = 0; i < ARRAY_SIZE(uri_tests); i++) {
2041 unsigned int j = 0;
2043 set_input_string(reader, uri_tests[i].xml);
2045 type = ~0u;
2046 while (IXmlReader_Read(reader, &type) == S_OK) {
2047 const WCHAR *local, *qname;
2048 UINT length, length2;
2050 ok(type == XmlNodeType_Element ||
2051 type == XmlNodeType_Text ||
2052 type == XmlNodeType_CDATA ||
2053 type == XmlNodeType_ProcessingInstruction ||
2054 type == XmlNodeType_Comment ||
2055 type == XmlNodeType_Whitespace ||
2056 type == XmlNodeType_EndElement ||
2057 type == XmlNodeType_XmlDeclaration, "Unexpected node type %d.\n", type);
2059 local = NULL;
2060 length = 0;
2061 hr = IXmlReader_GetLocalName(reader, &local, &length);
2062 ok(hr == S_OK, "S_OK, got %08x\n", hr);
2063 ok(local != NULL, "Unexpected NULL local name pointer\n");
2065 qname = NULL;
2066 length2 = 0;
2067 hr = IXmlReader_GetQualifiedName(reader, &qname, &length2);
2068 ok(hr == S_OK, "S_OK, got %08x\n", hr);
2069 ok(qname != NULL, "Unexpected NULL qualified name pointer\n");
2071 if (type == XmlNodeType_Element ||
2072 type == XmlNodeType_EndElement ||
2073 type == XmlNodeType_ProcessingInstruction ||
2074 type == XmlNodeType_XmlDeclaration)
2076 ok(*local != 0, "Unexpected empty local name\n");
2077 ok(length > 0, "Unexpected local name length\n");
2079 ok(*qname != 0, "Unexpected empty qualified name\n");
2080 ok(length2 > 0, "Unexpected qualified name length\n");
2083 reader_namespace(reader, uri_tests[i].uri[j]);
2085 j++;
2087 ok(type == XmlNodeType_None, "Unexpected node type %d\n", type);
2090 IXmlReader_Release(reader);
2093 static void test_read_charref(void)
2095 static const char testA[] = "<a b=\"c\">&#x1f3;&#x103;&gt;</a>";
2096 static const WCHAR chardataW[] = {0x01f3,0x0103,'>',0};
2097 const WCHAR *value;
2098 IXmlReader *reader;
2099 XmlNodeType type;
2100 HRESULT hr;
2102 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
2103 ok(hr == S_OK, "S_OK, got %08x\n", hr);
2105 set_input_string(reader, testA);
2107 hr = IXmlReader_Read(reader, &type);
2108 ok(hr == S_OK, "got %08x\n", hr);
2109 ok(type == XmlNodeType_Element, "Unexpected node type %d\n", type);
2111 hr = IXmlReader_Read(reader, &type);
2112 ok(hr == S_OK, "got %08x\n", hr);
2113 ok(type == XmlNodeType_Text, "Unexpected node type %d\n", type);
2115 hr = IXmlReader_GetValue(reader, &value, NULL);
2116 ok(hr == S_OK, "got %08x\n", hr);
2117 ok(!lstrcmpW(value, chardataW), "Text value : %s\n", wine_dbgstr_w(value));
2119 hr = IXmlReader_Read(reader, &type);
2120 ok(hr == S_OK, "got %08x\n", hr);
2121 ok(type == XmlNodeType_EndElement, "Unexpected node type %d\n", type);
2123 hr = IXmlReader_Read(reader, &type);
2124 ok(hr == S_FALSE, "got %08x\n", hr);
2125 ok(type == XmlNodeType_None, "Unexpected node type %d\n", type);
2127 IXmlReader_Release(reader);
2130 static void test_encoding_detection(void)
2132 static const struct encoding_testW
2134 WCHAR text[16];
2136 encoding_testsW[] =
2138 { { '<','?','p','i',' ','?','>',0 } },
2139 { { '<','!','-','-',' ','c','-','-','>',0 } },
2140 { { 0xfeff,'<','a','/','>',0 } },
2141 { { '<','a','/','>',0 } },
2143 static const char *encoding_testsA[] =
2145 "<?pi ?>",
2146 "<!-- comment -->",
2147 "\xef\xbb\xbf<a/>", /* UTF-8 BOM */
2148 "<a/>",
2150 IXmlReader *reader;
2151 XmlNodeType type;
2152 IStream *stream;
2153 unsigned int i;
2154 HRESULT hr;
2156 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
2157 ok(hr == S_OK, "S_OK, got %08x\n", hr);
2159 /* there's no way to query detected encoding back, so just verify that document is browsable */
2161 for (i = 0; i < ARRAY_SIZE(encoding_testsA); i++)
2163 set_input_string(reader, encoding_testsA[i]);
2165 type = XmlNodeType_None;
2166 hr = IXmlReader_Read(reader, &type);
2167 ok(hr == S_OK, "got %08x\n", hr);
2168 ok(type != XmlNodeType_None, "Unexpected node type %d\n", type);
2171 for (i = 0; i < ARRAY_SIZE(encoding_testsW); i++)
2173 stream = create_stream_on_data(encoding_testsW[i].text, lstrlenW(encoding_testsW[i].text) * sizeof(WCHAR));
2175 hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
2176 ok(hr == S_OK, "got %08x\n", hr);
2178 type = XmlNodeType_None;
2179 hr = IXmlReader_Read(reader, &type);
2180 ok(hr == S_OK, "%u: got %08x\n", i, hr);
2181 ok(type != XmlNodeType_None, "%u: unexpected node type %d\n", i, type);
2183 IStream_Release(stream);
2186 IXmlReader_Release(reader);
2189 static void test_eof_state(IXmlReader *reader, BOOL eof)
2191 LONG_PTR state;
2192 HRESULT hr;
2194 ok(IXmlReader_IsEOF(reader) == eof, "Unexpected IsEOF() result\n");
2195 hr = IXmlReader_GetProperty(reader, XmlReaderProperty_ReadState, &state);
2196 ok(hr == S_OK, "GetProperty() failed, %#x\n", hr);
2197 ok((state == XmlReadState_EndOfFile) == eof, "Unexpected EndOfFile state %ld\n", state);
2200 static void test_endoffile(void)
2202 IXmlReader *reader;
2203 XmlNodeType type;
2204 HRESULT hr;
2206 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
2207 ok(hr == S_OK, "S_OK, got %08x\n", hr);
2209 test_eof_state(reader, FALSE);
2211 set_input_string(reader, "<a/>");
2213 test_eof_state(reader, FALSE);
2215 type = XmlNodeType_None;
2216 hr = IXmlReader_Read(reader, &type);
2217 ok(hr == S_OK, "got %#x\n", hr);
2218 ok(type == XmlNodeType_Element, "Unexpected type %d\n", type);
2220 test_eof_state(reader, FALSE);
2222 type = XmlNodeType_Element;
2223 hr = IXmlReader_Read(reader, &type);
2224 ok(hr == S_FALSE, "got %#x\n", hr);
2225 ok(type == XmlNodeType_None, "Unexpected type %d\n", type);
2227 test_eof_state(reader, TRUE);
2229 hr = IXmlReader_SetInput(reader, NULL);
2230 ok(hr == S_OK, "got %08x\n", hr);
2232 test_eof_state(reader, FALSE);
2234 IXmlReader_Release(reader);
2236 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
2237 ok(hr == S_OK, "S_OK, got %08x\n", hr);
2239 set_input_string(reader, "<a/>text");
2241 type = XmlNodeType_None;
2242 hr = IXmlReader_Read(reader, &type);
2243 ok(hr == S_OK, "got %#x\n", hr);
2244 ok(type == XmlNodeType_Element, "Unexpected type %d\n", type);
2246 test_eof_state(reader, FALSE);
2248 type = XmlNodeType_Element;
2249 hr = IXmlReader_Read(reader, &type);
2250 ok(hr == WC_E_SYNTAX, "got %#x\n", hr);
2251 ok(type == XmlNodeType_None, "Unexpected type %d\n", type);
2253 test_eof_state(reader, FALSE);
2255 hr = IXmlReader_SetInput(reader, NULL);
2256 ok(hr == S_OK, "got %08x\n", hr);
2258 IXmlReader_Release(reader);
2261 static void test_max_element_depth(void)
2263 static const char *xml =
2264 "<a>"
2265 "<b attrb=\"_b\">"
2266 "<c>"
2267 "<d></d>"
2268 "</c>"
2269 "</b>"
2270 "</a>";
2271 XmlNodeType nodetype;
2272 unsigned int count;
2273 IXmlReader *reader;
2274 HRESULT hr;
2276 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
2277 ok(hr == S_OK, "S_OK, got %08x\n", hr);
2279 set_input_string(reader, xml);
2281 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_MaxElementDepth, 2);
2282 ok(hr == S_OK, "got %08x\n", hr);
2284 TEST_DEPTH(reader, 0);
2286 hr = IXmlReader_Read(reader, NULL);
2287 ok(hr == S_OK, "got %08x\n", hr);
2289 TEST_DEPTH(reader, 0);
2291 hr = IXmlReader_Read(reader, NULL);
2292 ok(hr == S_OK, "got %08x\n", hr);
2294 TEST_DEPTH(reader, 1);
2295 TEST_READER_STATE(reader, XmlReadState_Interactive);
2297 hr = IXmlReader_Read(reader, NULL);
2298 ok(hr == SC_E_MAXELEMENTDEPTH, "got %08x\n", hr);
2300 TEST_DEPTH2(reader, 0, 2);
2301 TEST_READER_STATE(reader, XmlReadState_Error);
2303 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_MaxElementDepth, 10);
2304 ok(hr == S_OK, "got %08x\n", hr);
2306 hr = IXmlReader_Read(reader, NULL);
2307 ok(hr == SC_E_MAXELEMENTDEPTH, "got %08x\n", hr);
2309 TEST_DEPTH2(reader, 0, 2);
2310 TEST_READER_STATE(reader, XmlReadState_Error);
2312 /* test if stepping into attributes enforces depth limit too */
2313 set_input_string(reader, xml);
2315 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_MaxElementDepth, 2);
2316 ok(hr == S_OK, "got %08x\n", hr);
2318 TEST_DEPTH(reader, 0);
2320 hr = IXmlReader_Read(reader, NULL);
2321 ok(hr == S_OK, "got %08x\n", hr);
2323 TEST_DEPTH(reader, 0);
2325 hr = IXmlReader_Read(reader, NULL);
2326 ok(hr == S_OK, "got %08x\n", hr);
2328 TEST_DEPTH(reader, 1);
2330 hr = IXmlReader_MoveToFirstAttribute(reader);
2331 ok(hr == S_OK, "got %08x\n", hr);
2333 TEST_DEPTH(reader, 2);
2334 TEST_READER_STATE(reader, XmlReadState_Interactive);
2336 nodetype = 123;
2337 hr = IXmlReader_Read(reader, &nodetype);
2338 ok(hr == SC_E_MAXELEMENTDEPTH, "got %08x\n", hr);
2339 ok(nodetype == XmlNodeType_None, "got node type %d\n", nodetype);
2341 nodetype = 123;
2342 hr = IXmlReader_Read(reader, &nodetype);
2343 ok(hr == SC_E_MAXELEMENTDEPTH, "got %08x\n", hr);
2344 ok(nodetype == XmlNodeType_None, "got node type %d\n", nodetype);
2346 TEST_DEPTH2(reader, 0, 2);
2347 TEST_READER_STATE(reader, XmlReadState_Error);
2349 /* set max depth to 0, this disables depth limit */
2350 set_input_string(reader, xml);
2352 hr = IXmlReader_SetProperty(reader, XmlReaderProperty_MaxElementDepth, 0);
2353 ok(hr == S_OK, "got %08x\n", hr);
2355 count = 0;
2356 while (IXmlReader_Read(reader, NULL) == S_OK)
2357 count++;
2358 ok(count == 8, "Unexpected node number %u\n", count);
2359 TEST_READER_STATE(reader, XmlReadState_EndOfFile);
2361 IXmlReader_Release(reader);
2364 static void test_reader_position(void)
2366 static const char *xml = "<c:a xmlns:c=\"nsdef c\" b=\"attr b\">\n</c:a>";
2367 IXmlReader *reader;
2368 XmlNodeType type;
2369 UINT position;
2370 HRESULT hr;
2372 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
2373 ok(hr == S_OK, "S_OK, got %08x\n", hr);
2375 TEST_READER_STATE(reader, XmlReadState_Closed);
2377 /* position methods with Null args */
2378 hr = IXmlReader_GetLineNumber(reader, NULL);
2379 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
2381 hr = IXmlReader_GetLinePosition(reader, NULL);
2382 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
2384 position = 123;
2385 hr = IXmlReader_GetLinePosition(reader, &position);
2386 ok(hr == S_FALSE, "got %#x\n", hr);
2387 ok(position == 0, "got %u\n", position);
2389 position = 123;
2390 hr = IXmlReader_GetLineNumber(reader, &position);
2391 ok(hr == S_FALSE, "got %#x\n", hr);
2392 ok(position == 0, "got %u\n", position);
2394 set_input_string(reader, xml);
2396 TEST_READER_STATE(reader, XmlReadState_Initial);
2397 TEST_READER_POSITION(reader, 0, 0);
2398 hr = IXmlReader_Read(reader, &type);
2399 ok(hr == S_OK, "got %08x\n", hr);
2400 ok(type == XmlNodeType_Element, "got type %d\n", type);
2401 TEST_READER_POSITION2(reader, 1, 2, ~0u, 34);
2403 next_attribute(reader);
2404 TEST_READER_POSITION2(reader, 1, 6, ~0u, 34);
2406 next_attribute(reader);
2407 TEST_READER_POSITION2(reader, 1, 24, ~0u, 34);
2409 move_to_element(reader);
2410 TEST_READER_POSITION2(reader, 1, 2, ~0u, 34);
2412 hr = IXmlReader_Read(reader, &type);
2413 ok(hr == S_OK, "got %08x\n", hr);
2414 ok(type == XmlNodeType_Whitespace, "got type %d\n", type);
2415 TEST_READER_POSITION2(reader, 1, 35, 2, 6);
2417 hr = IXmlReader_Read(reader, &type);
2418 ok(hr == S_OK, "got %08x\n", hr);
2419 ok(type == XmlNodeType_EndElement, "got type %d\n", type);
2420 TEST_READER_POSITION2(reader, 2, 3, 2, 6);
2422 hr = IXmlReader_SetInput(reader, NULL);
2423 ok(hr == S_OK, "got %08x\n", hr);
2424 TEST_READER_STATE2(reader, XmlReadState_Initial, XmlReadState_Closed);
2425 TEST_READER_POSITION(reader, 0, 0);
2427 IXmlReader_Release(reader);
2430 static void test_string_pointers(void)
2432 const WCHAR *ns, *nsq, *empty, *xmlns_ns, *xmlns_name, *name, *p, *q, *xml, *ptr, *value;
2433 IXmlReader *reader;
2434 HRESULT hr;
2436 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
2437 ok(hr == S_OK, "S_OK, got %08x\n", hr);
2439 set_input_string(reader, "<elem xmlns=\"myns\">myns<elem2 /></elem>");
2441 read_node(reader, XmlNodeType_Element);
2442 empty = reader_value(reader, L"");
2443 ok(empty == reader_prefix(reader, L""), "empty != prefix\n");
2444 name = reader_name(reader, L"elem");
2445 ok(name == reader_qname(reader, L"elem"), "name != qname\n");
2446 ns = reader_namespace(reader, L"myns");
2448 next_attribute(reader);
2449 ptr = reader_value(reader, L"myns");
2450 if (ns != ptr)
2452 win_skip("attr value is different than namespace pointer, assuming old xmllite\n");
2453 IXmlReader_Release(reader);
2454 return;
2456 ok(ns == ptr, "ns != value\n");
2457 ok(empty == reader_prefix(reader, L""), "empty != prefix\n");
2458 xmlns_ns = reader_namespace(reader, L"http://www.w3.org/2000/xmlns/");
2459 xmlns_name = reader_name(reader, L"xmlns");
2460 ok(xmlns_name == reader_qname(reader, L"xmlns"), "xmlns_name != qname\n");
2462 read_node(reader, XmlNodeType_Text);
2463 ok(ns != reader_value(reader, L"myns"), "ns == value\n");
2464 ok(empty == reader_prefix(reader, L""), "empty != prefix\n");
2465 ok(empty == reader_namespace(reader, L""), "empty != namespace\n");
2466 ok(empty == reader_name(reader, L""), "empty != name\n");
2467 ok(empty == reader_qname(reader, L""), "empty != qname\n");
2469 read_node(reader, XmlNodeType_Element);
2470 ok(empty == reader_prefix(reader, L""), "empty != prefix\n");
2471 ok(ns == reader_namespace(reader, L"myns"), "empty != namespace\n");
2473 read_node(reader, XmlNodeType_EndElement);
2474 ok(empty == reader_prefix(reader, L""), "empty != prefix\n");
2475 ok(name == reader_name(reader, L"elem"), "empty != name\n");
2476 ok(name == reader_qname(reader, L"elem"), "empty != qname\n");
2477 ok(ns == reader_namespace(reader, L"myns"), "empty != namespace\n");
2479 set_input_string(reader, "<elem xmlns:p=\"myns\" xmlns:q=\"mynsq\"><p:elem2 q:attr=\"\"></p:elem2></elem>");
2481 read_node(reader, XmlNodeType_Element);
2482 ok(empty == reader_prefix(reader, L""), "empty != prefix\n");
2483 name = reader_name(reader, L"elem");
2484 ok(empty == reader_namespace(reader, L""), "empty != namespace\n");
2486 next_attribute(reader);
2487 ns = reader_value(reader, L"myns");
2488 ok(xmlns_name == reader_prefix(reader, L"xmlns"), "xmlns_name != prefix\n");
2489 p = reader_name(reader, L"p");
2490 ok(xmlns_ns == reader_namespace(reader, L"http://www.w3.org/2000/xmlns/"), "xmlns_ns != namespace\n");
2492 next_attribute(reader);
2493 nsq = reader_value(reader, L"mynsq");
2494 ok(xmlns_name == reader_prefix(reader, L"xmlns"), "xmlns_name != prefix\n");
2495 q = reader_name(reader, L"q");
2496 ok(xmlns_ns == reader_namespace(reader, L"http://www.w3.org/2000/xmlns/"), "xmlns_ns != namespace\n");
2498 read_node(reader, XmlNodeType_Element);
2499 ok(p == reader_prefix(reader, L"p"), "p != prefix\n");
2500 ok(ns == reader_namespace(reader, L"myns"), "empty != namespace\n");
2501 name = reader_qname(reader, L"p:elem2");
2503 next_attribute(reader);
2504 ok(empty != reader_value(reader, L""), "empty == value\n");
2505 ok(q == reader_prefix(reader, L"q"), "q != prefix\n");
2506 ok(nsq == reader_namespace(reader, L"mynsq"), "nsq != namespace\n");
2508 read_node(reader, XmlNodeType_EndElement);
2509 ptr = reader_qname(reader, L"p:elem2"); todo_wine ok(name != ptr, "q == qname\n");
2511 set_input_string(reader, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
2513 read_node(reader, XmlNodeType_XmlDeclaration);
2514 ok(empty == reader_value(reader, L""), "empty != value\n");
2515 ok(empty == reader_prefix(reader, L""), "empty != prefix\n");
2516 xml = reader_name(reader, L"xml");
2517 ptr = reader_qname(reader, L"xml"); todo_wine ok(xml == ptr, "xml != qname\n");
2518 ok(empty == reader_namespace(reader, L""), "empty != namespace\n");
2520 next_attribute(reader);
2521 ok(empty == reader_prefix(reader, L""), "empty != prefix\n");
2522 ok(empty == reader_namespace(reader, L""), "empty != namespace\n");
2524 set_input_string(reader, "<elem xmlns:p=\"myns\"><p:elem2 attr=\"\" /></elem>");
2526 read_node(reader, XmlNodeType_Element);
2527 next_attribute(reader);
2528 read_value_char(reader, 'm');
2529 p = reader_value(reader, L"yns");
2531 read_node(reader, XmlNodeType_Element);
2532 ns = reader_namespace(reader, L"myns");
2533 ok(ns+1 == p, "ns+1 != p\n");
2535 set_input_string(reader, "<elem attr=\"value\"></elem>");
2537 read_node(reader, XmlNodeType_Element);
2538 next_attribute(reader);
2539 name = reader_name(reader, L"attr");
2540 value = reader_value(reader, L"value");
2542 move_to_element(reader);
2543 next_attribute(reader);
2544 ok(name == reader_name(reader, L"attr"), "attr pointer changed\n");
2545 ok(value == reader_value(reader, L"value"), "value pointer changed\n");
2547 IXmlReader_Release(reader);
2550 static void test_attribute_by_name(void)
2552 static const char *xml = "<a><elem xmlns=\"myns\" a=\"value a\" b=\"value b\" xmlns:ns=\"ns uri\" "
2553 "ns:c=\"value c\" c=\"value c2\"/></a>";
2554 static const WCHAR xmlns_uriW[] = {'h','t','t','p',':','/','/','w','w','w','.','w','3','.','o','r','g','/',
2555 '2','0','0','0','/','x','m','l','n','s','/',0};
2556 static const WCHAR nsuriW[] = {'n','s',' ','u','r','i',0};
2557 static const WCHAR xmlnsW[] = {'x','m','l','n','s',0};
2558 static const WCHAR mynsW[] = {'m','y','n','s',0};
2559 static const WCHAR nsW[] = {'n','s',0};
2560 static const WCHAR emptyW[] = {0};
2561 static const WCHAR aW[] = {'a',0};
2562 static const WCHAR bW[] = {'b',0};
2563 static const WCHAR cW[] = {'c',0};
2564 IXmlReader *reader;
2565 HRESULT hr;
2567 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
2568 ok(hr == S_OK, "Failed to create reader, hr %#x.\n", hr);
2570 set_input_string(reader, xml);
2572 hr = IXmlReader_MoveToAttributeByName(reader, NULL, NULL);
2573 ok(hr == E_INVALIDARG || broken(hr == S_FALSE) /* WinXP */, "Unexpected hr %#x.\n", hr);
2575 hr = IXmlReader_MoveToAttributeByName(reader, emptyW, NULL);
2576 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
2578 read_node(reader, XmlNodeType_Element);
2580 hr = IXmlReader_MoveToAttributeByName(reader, emptyW, NULL);
2581 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
2583 read_node(reader, XmlNodeType_Element);
2585 hr = IXmlReader_MoveToAttributeByName(reader, NULL, NULL);
2586 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2588 hr = IXmlReader_MoveToAttributeByName(reader, NULL, xmlns_uriW);
2589 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2591 hr = IXmlReader_MoveToAttributeByName(reader, emptyW, xmlns_uriW);
2592 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
2594 hr = IXmlReader_MoveToAttributeByName(reader, xmlnsW, NULL);
2595 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
2597 hr = IXmlReader_MoveToAttributeByName(reader, xmlnsW, xmlns_uriW);
2598 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2599 reader_value(reader, L"myns");
2601 hr = IXmlReader_MoveToAttributeByName(reader, aW, NULL);
2602 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2603 reader_value(reader, L"value a");
2605 hr = IXmlReader_MoveToAttributeByName(reader, bW, NULL);
2606 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2607 reader_value(reader, L"value b");
2609 hr = IXmlReader_MoveToAttributeByName(reader, aW, mynsW);
2610 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
2612 hr = IXmlReader_MoveToAttributeByName(reader, nsW, NULL);
2613 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
2615 hr = IXmlReader_MoveToAttributeByName(reader, nsW, xmlns_uriW);
2616 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2617 reader_value(reader, L"ns uri");
2619 hr = IXmlReader_MoveToAttributeByName(reader, bW, emptyW);
2620 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2621 reader_value(reader, L"value b");
2623 hr = IXmlReader_MoveToAttributeByName(reader, cW, NULL);
2624 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2625 reader_value(reader, L"value c2");
2627 hr = IXmlReader_MoveToAttributeByName(reader, cW, nsuriW);
2628 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2629 reader_value(reader, L"value c");
2631 IXmlReader_Release(reader);
2634 START_TEST(reader)
2636 test_reader_create();
2637 test_readerinput();
2638 test_reader_state();
2639 test_read_attribute();
2640 test_read_cdata();
2641 test_read_comment();
2642 test_read_pi();
2643 test_read_system_dtd();
2644 test_read_public_dtd();
2645 test_read_element();
2646 test_isemptyelement();
2647 test_read_text();
2648 test_read_full();
2649 test_read_pending();
2650 test_readvaluechunk();
2651 test_read_xmldeclaration();
2652 test_reader_properties();
2653 test_prefix();
2654 test_namespaceuri();
2655 test_read_charref();
2656 test_encoding_detection();
2657 test_endoffile();
2658 test_max_element_depth();
2659 test_reader_position();
2660 test_string_pointers();
2661 test_attribute_by_name();