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
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
;
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
);
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;
67 IXmlReader_GetLineNumber(reader
, &l
);
68 IXmlReader_GetLinePosition(reader
, &p
);
70 if (line_broken
== ~0u && pos_broken
== ~0u)
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
{
89 static const IID
*setinput_full
[] = {
92 &IID_ISequentialStream
,
96 /* this applies to early xmllite versions */
97 static const IID
*setinput_full_old
[] = {
99 &IID_ISequentialStream
,
104 /* after ::SetInput(IXmlReaderInput*) */
105 static const IID
*setinput_readerinput
[] = {
107 &IID_ISequentialStream
,
111 static const IID
*empty_seq
[] = {
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
)
121 while (expected
[i
++]) size
++;
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";
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
];
161 static const char *type_to_str(XmlNodeType type
)
163 static const char* type_names
[] = {
165 "XmlNodeType_Element",
166 "XmlNodeType_Attribute",
170 "XmlNodeType_ProcessingInstruction",
171 "XmlNodeType_Comment",
173 "XmlNodeType_DocumentType",
175 "XmlNodeType_Whitespace",
177 "XmlNodeType_EndElement",
179 "XmlNodeType_XmlDeclaration"
182 static const char unknown
[] = "unknown";
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
];
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
)
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
)
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
);
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
)
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
)
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
)
253 state
= -1; /* invalid state value */
254 IXmlReader_GetProperty(reader
, XmlReaderProperty_ReadState
, &state
);
256 if (exp_broken
== expected
)
257 broken_state
= FALSE
;
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;
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
));
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;
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
));
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;
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
));
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;
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
));
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;
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
));
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
)
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
;
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
))
367 IUnknown_AddRef(iface
);
371 input_iids
.iids
[input_iids
.count
++] = *riid
;
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
);
389 ref
= InterlockedDecrement(&This
->ref
);
396 static const struct IUnknownVtbl testinput_vtbl
=
398 testinput_QueryInterface
,
403 static HRESULT
testinput_createinstance(void **ppObj
)
407 input
= heap_alloc(sizeof(*input
));
408 if(!input
) return E_OUTOFMEMORY
;
410 input
->IUnknown_iface
.lpVtbl
= &testinput_vtbl
;
413 *ppObj
= &input
->IUnknown_iface
;
418 static HRESULT WINAPI
teststream_QueryInterface(ISequentialStream
*iface
, REFIID riid
, void **obj
)
420 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_ISequentialStream
))
427 return E_NOINTERFACE
;
430 static ULONG WINAPI
teststream_AddRef(ISequentialStream
*iface
)
435 static ULONG WINAPI
teststream_Release(ISequentialStream
*iface
)
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
++)
452 *pread
= sizeof(xml
) / 2;
453 memcpy(pv
, xml
, *pread
);
457 static HRESULT WINAPI
teststream_Write(ISequentialStream
*iface
, const void *pv
, ULONG cb
, ULONG
*written
)
459 ok(0, "unexpected call\n");
463 static const ISequentialStreamVtbl teststreamvtbl
=
465 teststream_QueryInterface
,
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
))
479 IXmlResolver_AddRef(iface
);
484 return E_NOINTERFACE
;
487 static ULONG WINAPI
resolver_AddRef(IXmlResolver
*iface
)
492 static ULONG WINAPI
resolver_Release(IXmlResolver
*iface
)
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");
504 static const IXmlResolverVtbl resolvervtbl
=
512 static IXmlResolver testresolver
= { &resolvervtbl
};
514 static void test_reader_create(void)
516 IXmlResolver
*resolver
;
517 IUnknown
*input
, *unk
;
520 XmlNodeType nodetype
;
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 */
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
);
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
);
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
);
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
);
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
;
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 */
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
);
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
;
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
);
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
);
801 ok(FAILED(hr
), "got %08x\n", hr
);
802 ok(nodetype
== XmlNodeType_None
, "Unexpected node type %d\n", nodetype
);
805 TEST_READER_STATE(reader
, XmlReadState_Error
);
807 nodetype
= XmlNodeType_Element
;
808 hr
= IXmlReader_Read(reader
, &nodetype
);
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
)
821 IXmlReader_GetDepth(reader
, &d
);
823 condition
= d
== depth
;
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)
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} }
848 UINT count
= 0, len
, i
;
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
++)
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
));
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 */
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
);
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");
1008 hr
= IXmlReader_Read(reader
, &type
);
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);
1014 TEST_READER_STATE(reader
, XmlReadState_Error
);
1016 IStream_Release(stream
);
1017 IXmlReader_Release(reader
);
1026 HRESULT hr_broken
; /* this is set to older version results */
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
},
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
,
1047 XmlNodeType_Comment
,
1048 XmlNodeType_EndElement
,
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
)
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");
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
);
1084 ok(hr
== test
->hr
, "got %08x for %s\n", hr
, test
->xml
);
1089 ok(type
== XmlNodeType_Comment
, "got %d for %s\n", type
, test
->xml
);
1091 reader_name(reader
, L
"");
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
"");
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
));
1106 reader_value(reader
, test
->value
);
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
},
1130 static void test_read_pi(void)
1132 struct test_entry
*test
= pi_tests
;
1136 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1137 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
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
);
1150 ok(hr
== test
->hr
, "got %08x for %s\n", hr
, test
->xml
);
1156 ok(type
== XmlNodeType_ProcessingInstruction
, "got %d for %s\n", type
, test
->xml
);
1158 reader_name(reader
, test
->name
);
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
));
1168 reader_value(reader
, test
->value
);
1174 IXmlReader_Release(reader
);
1185 static const char misc_test_xml
[] =
1203 static struct nodes_test misc_test
= {
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
;
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
);
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};
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
);
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");
1300 hr
= IXmlReader_GetQualifiedName(reader
, &str
, &len
);
1301 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
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\" >"
1313 static void test_read_system_dtd(void)
1315 static const WCHAR dtdnameW
[] = {'t','e','s','t','d','t','d',0};
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
);
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");
1353 hr
= IXmlReader_GetQualifiedName(reader
, &str
, &len
);
1354 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
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
},
1381 static void test_read_element(void)
1383 struct test_entry
*test
= element_tests
;
1384 static const char stag
[] =
1389 "<d attr4=\"_d\"></d>"
1392 static const UINT depths
[] = { 0, 1, 2, 2, 2, 3, 2, 1 };
1399 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1400 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
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
);
1411 todo_wine_if(test
->hr
== NC_E_UNDECLAREDPREFIX
)
1412 ok(hr
== test
->hr
, "got %08x for %s\n", hr
, test
->xml
);
1418 ok(type
== XmlNodeType_Element
, "got %d for %s\n", type
, test
->xml
);
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
));
1428 reader_value(reader
, L
"");
1434 /* test reader depth increment */
1435 set_input_string(reader
, stag
);
1438 while (IXmlReader_Read(reader
, &type
) == S_OK
)
1442 ok(type
== XmlNodeType_Element
|| type
== XmlNodeType_EndElement
||
1443 type
== XmlNodeType_Text
, "Unexpected node type %d\n", type
);
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
;
1455 hr
= IXmlReader_GetPrefix(reader
, &prefix
, NULL
);
1456 ok(hr
== S_OK
, "got %08x\n", hr
);
1457 ok(prefix
!= NULL
, "got %p\n", prefix
);
1461 const WCHAR
*local
, *qname
;
1464 hr
= IXmlReader_GetLocalName(reader
, &local
, NULL
);
1465 ok(hr
== S_OK
, "got %08x\n", hr
);
1466 ok(local
!= NULL
, "got %p\n", local
);
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
)
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
)
1488 hr
= IXmlReader_GetAttributeCount(reader
, &count
);
1489 ok(hr
== S_OK
, "got %08x\n", hr
);
1491 /* moving to attributes increases depth */
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
));
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
"");
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
]);
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)
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 */
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)
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 */
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
);
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 ");
1614 read_node(reader
, XmlNodeType_Comment
);
1617 hr
= IXmlReader_ReadValueChunk(reader
, buf
, 0, &c
);
1618 ok(hr
== S_OK
, "got %08x\n", hr
);
1619 ok(!c
, "c = %u\n", c
);
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");
1628 ok(!lstrcmpW(buf
, L
" comment2 "), "buf = %s\n", wine_dbgstr_w(buf
));
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 */
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
},
1662 static void test_read_cdata(void)
1664 struct test_entry
*test
= cdata_tests
;
1668 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1669 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
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
);
1690 ok(hr
== test
->hr
, "got %08x for %s\n", hr
, test
->xml
);
1696 ok(type
== XmlNodeType_CDATA
, "got %d for %s\n", type
, test
->xml
);
1698 reader_name(reader
, L
"");
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
));
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
));
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
));
1718 reader_value(reader
, test
->value
);
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
},
1736 static void test_read_text(void)
1738 struct test_entry
*test
= text_tests
;
1742 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1743 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
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
);
1766 ok(type
== XmlNodeType_Text
, "got %d for %s\n", type
, test
->xml
);
1768 reader_name(reader
, L
"");
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
));
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
));
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
));
1788 reader_value(reader
, test
->value
);
1794 IXmlReader_Release(reader
);
1797 struct test_entry_empty
{
1802 static struct test_entry_empty empty_element_tests
[] = {
1803 { "<a></a>", FALSE
},
1808 static void test_isemptyelement(void)
1810 struct test_entry_empty
*test
= empty_element_tests
;
1814 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1815 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
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
);
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 \"/>", L
"attr1", L
"val ", S_OK
},
1849 { "<a attr1=\"val \"/>", L
"attr1", L
"val ", S_OK
},
1850 { "<a attr1=\"<>&'"\"/>", L
"attr1", L
"<>&\'\"", S_OK
},
1851 { "<a attr1=\"&entname;\"/>", NULL
, NULL
, WC_E_UNDECLAREDENTITY
},
1852 { "<a attr1=\"val\"/>", NULL
, NULL
, WC_E_XMLCHARACTER
},
1853 { "<a attr1=\"val &#a;\"/>", NULL
, NULL
, WC_E_DIGIT
, WC_E_SEMICOLON
},
1854 { "<a attr1=\"val a;\"/>", NULL
, NULL
, WC_E_SEMICOLON
},
1855 { "<a attr1=\"val g;\"/>", 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
},
1863 static void test_read_attribute(void)
1865 struct test_entry
*test
= attributes_tests
;
1869 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1870 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
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
);
1883 ok(hr
== test
->hr
, "got %08x for %s\n", hr
, test
->xml
);
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
);
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
));
1908 reader_value(reader
, test
->value
);
1914 IXmlReader_Release(reader
);
1917 static void test_reader_properties(void)
1923 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1924 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
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
);
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)
1950 const WCHAR
*prefix1
;
1951 const WCHAR
*prefix2
;
1952 const WCHAR
*prefix3
;
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" },
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
++) {
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)
2006 const WCHAR
*uri
[5];
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\"/>",
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
"" }},
2023 { "<a><![CDATA[data]]></a>",
2025 { "<?xml version=\"1.0\" ?><a/>",
2029 { "<a><!-- comment --></a>",
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
++) {
2043 set_input_string(reader
, uri_tests
[i
].xml
);
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
);
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");
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
]);
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\">dză></a>";
2096 static const WCHAR chardataW
[] = {0x01f3,0x0103,'>',0};
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
2138 { { '<','?','p','i',' ','?','>',0 } },
2139 { { '<','!','-','-',' ','c','-','-','>',0 } },
2140 { { 0xfeff,'<','a','/','>',0 } },
2141 { { '<','a','/','>',0 } },
2143 static const char *encoding_testsA
[] =
2147 "\xef\xbb\xbf<a/>", /* UTF-8 BOM */
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
)
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)
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
=
2271 XmlNodeType nodetype
;
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
);
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
);
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
);
2356 while (IXmlReader_Read(reader
, NULL
) == S_OK
)
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>";
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
);
2385 hr
= IXmlReader_GetLinePosition(reader
, &position
);
2386 ok(hr
== S_FALSE
, "got %#x\n", hr
);
2387 ok(position
== 0, "got %u\n", position
);
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
;
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");
2452 win_skip("attr value is different than namespace pointer, assuming old xmllite\n");
2453 IXmlReader_Release(reader
);
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};
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
);
2636 test_reader_create();
2638 test_reader_state();
2639 test_read_attribute();
2641 test_read_comment();
2643 test_read_system_dtd();
2644 test_read_public_dtd();
2645 test_read_element();
2646 test_isemptyelement();
2649 test_read_pending();
2650 test_readvaluechunk();
2651 test_read_xmldeclaration();
2652 test_reader_properties();
2654 test_namespaceuri();
2655 test_read_charref();
2656 test_encoding_detection();
2658 test_max_element_depth();
2659 test_reader_position();
2660 test_string_pointers();
2661 test_attribute_by_name();