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 WIN32_NO_STATUS
23 #define COM_NO_WINDOWS_H
37 #include <wine/test.h>
39 DEFINE_GUID(IID_IXmlReaderInput
, 0x0b3ccc9b, 0x9214, 0x428b, 0xa2, 0xae, 0xef, 0x3a, 0xa8, 0x71, 0xaf, 0xda);
41 static WCHAR
*a2w(const char *str
)
43 int len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
44 WCHAR
*ret
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
45 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, len
);
49 static void free_str(WCHAR
*str
)
51 HeapFree(GetProcessHeap(), 0, str
);
54 static int strcmp_wa(const WCHAR
*str1
, const char *stra
)
56 WCHAR
*str2
= a2w(stra
);
57 int r
= lstrcmpW(str1
, str2
);
62 static const char xmldecl_full
[] = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
63 static const char xmldecl_short
[] = "<?xml version=\"1.0\"?><RegistrationInfo/>";
65 static IStream
*create_stream_on_data(const void *data
, unsigned int size
)
67 IStream
*stream
= NULL
;
72 hglobal
= GlobalAlloc(GHND
, size
);
73 ptr
= GlobalLock(hglobal
);
75 memcpy(ptr
, data
, size
);
77 hr
= CreateStreamOnHGlobal(hglobal
, TRUE
, &stream
);
78 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
79 ok(stream
!= NULL
, "Expected non-NULL stream\n");
81 GlobalUnlock(hglobal
);
86 static void test_reader_pos(IXmlReader
*reader
, UINT line
, UINT pos
, UINT line_broken
,
87 UINT pos_broken
, int _line_
)
89 UINT l
= ~0u, p
= ~0u;
92 IXmlReader_GetLineNumber(reader
, &l
);
93 IXmlReader_GetLinePosition(reader
, &p
);
95 if (line_broken
== ~0u && pos_broken
== ~0u)
98 broken_state
= broken((line_broken
== ~0u ? line
: line_broken
) == l
&&
99 (pos_broken
== ~0u ? pos
: pos_broken
) == p
);
101 ok_(__FILE__
, _line_
)((l
== line
&& pos
== p
) || broken_state
,
102 "Expected (%d,%d), got (%d,%d)\n", line
, pos
, l
, p
);
104 #define TEST_READER_POSITION(reader, line, pos) \
105 test_reader_pos(reader, line, pos, ~0u, ~0u, __LINE__)
106 #define TEST_READER_POSITION2(reader, line, pos, line_broken, pos_broken) \
107 test_reader_pos(reader, line, pos, line_broken, pos_broken, __LINE__)
109 typedef struct input_iids_t
{
114 static const IID
*setinput_full
[] = {
115 &IID_IXmlReaderInput
,
117 &IID_ISequentialStream
,
121 /* this applies to early xmllite versions */
122 static const IID
*setinput_full_old
[] = {
123 &IID_IXmlReaderInput
,
124 &IID_ISequentialStream
,
129 /* after ::SetInput(IXmlReaderInput*) */
130 static const IID
*setinput_readerinput
[] = {
132 &IID_ISequentialStream
,
136 static const IID
*empty_seq
[] = {
140 static input_iids_t input_iids
;
142 static void ok_iids_(const input_iids_t
*iids
, const IID
**expected
, const IID
**exp_broken
, BOOL todo
, int line
)
146 while (expected
[i
++]) size
++;
149 ok_(__FILE__
, line
)(iids
->count
== size
, "Sequence size mismatch (%d), got (%d)\n", size
, iids
->count
);
151 if (iids
->count
!= size
) return;
153 for (i
= 0; i
< size
; i
++) {
154 ok_(__FILE__
, line
)(IsEqualGUID(&iids
->iids
[i
], expected
[i
]) ||
155 (exp_broken
? broken(IsEqualGUID(&iids
->iids
[i
], exp_broken
[i
])) : FALSE
),
156 "Wrong IID(%d), got %s\n", i
, wine_dbgstr_guid(&iids
->iids
[i
]));
159 #define ok_iids(got, exp, brk, todo) ok_iids_(got, exp, brk, todo, __LINE__)
161 static const char *state_to_str(XmlReadState state
)
163 static const char* state_names
[] = {
164 "XmlReadState_Initial",
165 "XmlReadState_Interactive",
166 "XmlReadState_Error",
167 "XmlReadState_EndOfFile",
168 "XmlReadState_Closed"
171 static const char unknown
[] = "unknown";
175 case XmlReadState_Initial
:
176 case XmlReadState_Interactive
:
177 case XmlReadState_Error
:
178 case XmlReadState_EndOfFile
:
179 case XmlReadState_Closed
:
180 return state_names
[state
];
186 static const char *type_to_str(XmlNodeType type
)
188 static const char* type_names
[] = {
190 "XmlNodeType_Element",
191 "XmlNodeType_Attribute",
195 "XmlNodeType_ProcessingInstruction",
196 "XmlNodeType_Comment",
198 "XmlNodeType_DocumentType",
200 "XmlNodeType_Whitespace",
202 "XmlNodeType_EndElement",
204 "XmlNodeType_XmlDeclaration"
207 static const char unknown
[] = "unknown";
211 case XmlNodeType_None
:
212 case XmlNodeType_Element
:
213 case XmlNodeType_Attribute
:
214 case XmlNodeType_Text
:
215 case XmlNodeType_CDATA
:
216 case XmlNodeType_ProcessingInstruction
:
217 case XmlNodeType_Comment
:
218 case XmlNodeType_DocumentType
:
219 case XmlNodeType_Whitespace
:
220 case XmlNodeType_EndElement
:
221 case XmlNodeType_XmlDeclaration
:
222 return type_names
[type
];
228 #define set_input_string(a,b) _set_input_string(__LINE__,a,b);
229 static void _set_input_string(unsigned line
, IXmlReader
*reader
, const char *xml
)
234 stream
= create_stream_on_data(xml
, strlen(xml
));
236 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
237 ok_(__FILE__
,line
)(hr
== S_OK
, "got %08x\n", hr
);
239 IStream_Release(stream
);
242 #define read_node(a,b) _read_node(__LINE__,a,b)
243 static void _read_node(unsigned line
, IXmlReader
*reader
, XmlNodeType expected_type
)
248 hr
= IXmlReader_Read(reader
, &type
);
249 if (expected_type
== XmlNodeType_None
)
250 ok_(__FILE__
,line
)(hr
== S_FALSE
, "Read returned %08x, expected S_FALSE\n", hr
);
252 ok_(__FILE__
,line
)(hr
== S_OK
, "Read returned %08x\n", hr
);
253 ok_(__FILE__
,line
)(type
== expected_type
, "read type %d, expected %d\n", type
, expected_type
);
256 #define next_attribute(a) _next_attribute(__LINE__,a)
257 static void _next_attribute(unsigned line
, IXmlReader
*reader
)
260 hr
= IXmlReader_MoveToNextAttribute(reader
);
261 ok_(__FILE__
,line
)(hr
== S_OK
, "MoveToNextAttribute returned %08x\n", hr
);
264 #define move_to_element(a) _move_to_element(__LINE__,a)
265 static void _move_to_element(unsigned line
, IXmlReader
*reader
)
268 hr
= IXmlReader_MoveToElement(reader
);
269 ok_(__FILE__
,line
)(hr
== S_OK
, "MoveToElement failed: %08x\n", hr
);
272 static void test_read_state(IXmlReader
*reader
, XmlReadState expected
,
273 XmlReadState exp_broken
, int line
)
278 state
= -1; /* invalid state value */
279 IXmlReader_GetProperty(reader
, XmlReaderProperty_ReadState
, &state
);
281 if (exp_broken
== -1)
282 broken_state
= FALSE
;
284 broken_state
= broken(exp_broken
== state
);
286 ok_(__FILE__
, line
)(state
== expected
|| broken_state
, "Expected (%s), got (%s)\n",
287 state_to_str(expected
), state_to_str(state
));
290 #define TEST_READER_STATE(reader, state) test_read_state(reader, state, -1, __LINE__)
291 #define TEST_READER_STATE2(reader, state, brk) test_read_state(reader, state, brk, __LINE__)
293 #define reader_value(a,b) _reader_value(__LINE__,a,b)
294 static const WCHAR
*_reader_value(unsigned line
, IXmlReader
*reader
, const char *expect
)
296 const WCHAR
*str
= (void*)0xdeadbeef;
297 ULONG len
= 0xdeadbeef;
300 hr
= IXmlReader_GetValue(reader
, &str
, &len
);
301 ok_(__FILE__
,line
)(hr
== S_OK
, "GetValue returned %08x\n", hr
);
302 ok_(__FILE__
,line
)(len
== lstrlenW(str
), "len = %u\n", len
);
303 ok_(__FILE__
,line
)(!strcmp_wa(str
, expect
), "value = %s\n", wine_dbgstr_w(str
));
307 #define reader_name(a,b) _reader_name(__LINE__,a,b)
308 static const WCHAR
*_reader_name(unsigned line
, IXmlReader
*reader
, const char *expect
)
310 const WCHAR
*str
= (void*)0xdeadbeef;
311 ULONG len
= 0xdeadbeef;
314 hr
= IXmlReader_GetLocalName(reader
, &str
, &len
);
315 ok_(__FILE__
,line
)(hr
== S_OK
, "GetLocalName returned %08x\n", hr
);
316 ok_(__FILE__
,line
)(len
== lstrlenW(str
), "len = %u\n", len
);
317 ok_(__FILE__
,line
)(!strcmp_wa(str
, expect
), "name = %s\n", wine_dbgstr_w(str
));
321 #define reader_prefix(a,b) _reader_prefix(__LINE__,a,b)
322 static const WCHAR
*_reader_prefix(unsigned line
, IXmlReader
*reader
, const char *expect
)
324 const WCHAR
*str
= (void*)0xdeadbeef;
325 ULONG len
= 0xdeadbeef;
328 hr
= IXmlReader_GetPrefix(reader
, &str
, &len
);
329 ok_(__FILE__
,line
)(hr
== S_OK
, "GetPrefix returned %08x\n", hr
);
330 ok_(__FILE__
,line
)(len
== lstrlenW(str
), "len = %u\n", len
);
331 ok_(__FILE__
,line
)(!strcmp_wa(str
, expect
), "prefix = %s\n", wine_dbgstr_w(str
));
335 #define reader_namespace(a,b) _reader_namespace(__LINE__,a,b)
336 static const WCHAR
*_reader_namespace(unsigned line
, IXmlReader
*reader
, const char *expect
)
338 const WCHAR
*str
= (void*)0xdeadbeef;
339 ULONG len
= 0xdeadbeef;
342 hr
= IXmlReader_GetNamespaceUri(reader
, &str
, &len
);
343 ok_(__FILE__
,line
)(hr
== S_OK
, "GetNamespaceUri returned %08x\n", hr
);
344 ok_(__FILE__
,line
)(len
== lstrlenW(str
), "len = %u\n", len
);
345 ok_(__FILE__
,line
)(!strcmp_wa(str
, expect
), "namespace = %s\n", wine_dbgstr_w(str
));
349 #define reader_qname(a,b) _reader_qname(a,b,__LINE__)
350 static const WCHAR
*_reader_qname(IXmlReader
*reader
, const char *expect
, unsigned line
)
352 const WCHAR
*str
= (void*)0xdeadbeef;
353 ULONG len
= 0xdeadbeef;
356 hr
= IXmlReader_GetQualifiedName(reader
, &str
, &len
);
357 ok_(__FILE__
,line
)(hr
== S_OK
, "GetQualifiedName returned %08x\n", hr
);
358 ok_(__FILE__
,line
)(len
== lstrlenW(str
), "len = %u\n", len
);
359 ok_(__FILE__
,line
)(!strcmp_wa(str
, expect
), "name = %s\n", wine_dbgstr_w(str
));
363 #define read_value_char(a,b) _read_value_char(a,b,__LINE__)
364 static void _read_value_char(IXmlReader
*reader
, WCHAR expected_char
, unsigned line
)
370 hr
= IXmlReader_ReadValueChunk(reader
, &c
, 1, &count
);
371 ok_(__FILE__
,line
)(hr
== S_OK
, "got %08x\n", hr
);
372 ok_(__FILE__
,line
)(count
== 1, "got %u\n", c
);
373 ok_(__FILE__
,line
)(c
== expected_char
, "got %x\n", c
);
376 typedef struct _testinput
378 IUnknown IUnknown_iface
;
382 static inline testinput
*impl_from_IUnknown(IUnknown
*iface
)
384 return CONTAINING_RECORD(iface
, testinput
, IUnknown_iface
);
387 static HRESULT WINAPI
testinput_QueryInterface(IUnknown
*iface
, REFIID riid
, void** ppvObj
)
389 if (IsEqualGUID( riid
, &IID_IUnknown
))
392 IUnknown_AddRef(iface
);
396 input_iids
.iids
[input_iids
.count
++] = *riid
;
400 return E_NOINTERFACE
;
403 static ULONG WINAPI
testinput_AddRef(IUnknown
*iface
)
405 testinput
*This
= impl_from_IUnknown(iface
);
406 return InterlockedIncrement(&This
->ref
);
409 static ULONG WINAPI
testinput_Release(IUnknown
*iface
)
411 testinput
*This
= impl_from_IUnknown(iface
);
414 ref
= InterlockedDecrement(&This
->ref
);
417 HeapFree(GetProcessHeap(), 0, This
);
423 static const struct IUnknownVtbl testinput_vtbl
=
425 testinput_QueryInterface
,
430 static HRESULT
testinput_createinstance(void **ppObj
)
434 input
= HeapAlloc(GetProcessHeap(), 0, sizeof (*input
));
435 if(!input
) return E_OUTOFMEMORY
;
437 input
->IUnknown_iface
.lpVtbl
= &testinput_vtbl
;
440 *ppObj
= &input
->IUnknown_iface
;
445 static HRESULT WINAPI
teststream_QueryInterface(ISequentialStream
*iface
, REFIID riid
, void **obj
)
447 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_ISequentialStream
))
454 return E_NOINTERFACE
;
457 static ULONG WINAPI
teststream_AddRef(ISequentialStream
*iface
)
462 static ULONG WINAPI
teststream_Release(ISequentialStream
*iface
)
467 static int stream_readcall
;
469 static HRESULT WINAPI
teststream_Read(ISequentialStream
*iface
, void *pv
, ULONG cb
, ULONG
*pread
)
471 static const char xml
[] = "<!-- comment -->";
473 if (stream_readcall
++)
479 *pread
= sizeof(xml
) / 2;
480 memcpy(pv
, xml
, *pread
);
484 static HRESULT WINAPI
teststream_Write(ISequentialStream
*iface
, const void *pv
, ULONG cb
, ULONG
*written
)
486 ok(0, "unexpected call\n");
490 static const ISequentialStreamVtbl teststreamvtbl
=
492 teststream_QueryInterface
,
499 static HRESULT WINAPI
resolver_QI(IXmlResolver
*iface
, REFIID riid
, void **obj
)
501 ok(0, "unexpected call, riid %s\n", wine_dbgstr_guid(riid
));
503 if (IsEqualIID(riid
, &IID_IXmlResolver
) || IsEqualIID(riid
, &IID_IUnknown
))
506 IXmlResolver_AddRef(iface
);
511 return E_NOINTERFACE
;
514 static ULONG WINAPI
resolver_AddRef(IXmlResolver
*iface
)
519 static ULONG WINAPI
resolver_Release(IXmlResolver
*iface
)
524 static HRESULT WINAPI
resolver_ResolveUri(IXmlResolver
*iface
, const WCHAR
*base_uri
,
525 const WCHAR
*public_id
, const WCHAR
*system_id
, IUnknown
**input
)
527 ok(0, "unexpected call\n");
531 static const IXmlResolverVtbl resolvervtbl
=
539 static IXmlResolver testresolver
= { &resolvervtbl
};
541 static void test_reader_create(void)
543 IXmlResolver
*resolver
;
544 IUnknown
*input
, *unk
;
547 XmlNodeType nodetype
;
553 CreateXmlReader(&IID_IXmlReader
, NULL
, NULL
);
554 CreateXmlReader(NULL
, (void**)&reader
, NULL
);
557 hr
= CreateXmlReader(&IID_IStream
, (void **)&unk
, NULL
);
558 ok(hr
== E_NOINTERFACE
, "got %08x\n", hr
);
560 hr
= CreateXmlReader(&IID_IUnknown
, (void **)&unk
, NULL
);
561 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
562 hr
= IUnknown_QueryInterface(unk
, &IID_IXmlReader
, (void **)&reader
);
563 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
564 ok(unk
== (IUnknown
*)reader
, "unexpected interface\n");
565 IXmlReader_Release(reader
);
566 IUnknown_Release(unk
);
568 hr
= CreateXmlReader(&IID_IUnknown
, (void **)&reader
, NULL
);
569 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
570 IXmlReader_Release(reader
);
572 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
573 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
575 TEST_READER_STATE(reader
, XmlReadState_Closed
);
577 nodetype
= XmlNodeType_Element
;
578 hr
= IXmlReader_GetNodeType(reader
, &nodetype
);
579 ok(hr
== S_FALSE
, "got %08x\n", hr
);
580 ok(nodetype
== XmlNodeType_None
, "got %d\n", nodetype
);
582 /* crashes on XP, 2k3, works on newer versions */
585 hr
= IXmlReader_GetNodeType(reader
, NULL
);
586 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
589 resolver
= (void*)0xdeadbeef;
590 hr
= IXmlReader_GetProperty(reader
, XmlReaderProperty_XmlResolver
, (LONG_PTR
*)&resolver
);
591 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
592 ok(resolver
== NULL
, "got %p\n", resolver
);
594 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_XmlResolver
, 0);
595 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
597 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_XmlResolver
, (LONG_PTR
)&testresolver
);
598 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
601 hr
= IXmlReader_GetProperty(reader
, XmlReaderProperty_XmlResolver
, (LONG_PTR
*)&resolver
);
602 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
603 ok(resolver
== &testresolver
, "got %p\n", resolver
);
604 IXmlResolver_Release(resolver
);
606 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_XmlResolver
, 0);
607 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
610 hr
= IXmlReader_GetProperty(reader
, XmlReaderProperty_DtdProcessing
, (LONG_PTR
*)&dtd
);
611 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
612 ok(dtd
== DtdProcessing_Prohibit
, "got %d\n", dtd
);
615 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_DtdProcessing
, dtd
);
616 ok(hr
== E_INVALIDARG
, "Expected E_INVALIDARG, got %08x\n", hr
);
618 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_DtdProcessing
, -1);
619 ok(hr
== E_INVALIDARG
, "Expected E_INVALIDARG, got %08x\n", hr
);
621 /* Null input pointer, releases previous input */
622 hr
= IXmlReader_SetInput(reader
, NULL
);
623 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
625 TEST_READER_STATE2(reader
, XmlReadState_Initial
, XmlReadState_Closed
);
627 /* test input interface selection sequence */
628 hr
= testinput_createinstance((void**)&input
);
629 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
633 input_iids
.count
= 0;
634 hr
= IXmlReader_SetInput(reader
, input
);
635 ok(hr
== E_NOINTERFACE
, "Expected E_NOINTERFACE, got %08x\n", hr
);
636 ok_iids(&input_iids
, setinput_full
, setinput_full_old
, FALSE
);
637 IUnknown_Release(input
);
639 IXmlReader_Release(reader
);
642 static void test_readerinput(void)
644 IXmlReaderInput
*reader_input
;
645 IXmlReader
*reader
, *reader2
;
646 IUnknown
*obj
, *input
;
647 IStream
*stream
, *stream2
;
648 XmlNodeType nodetype
;
652 hr
= CreateXmlReaderInputWithEncodingName(NULL
, NULL
, NULL
, FALSE
, NULL
, NULL
);
653 ok(hr
== E_INVALIDARG
, "Expected E_INVALIDARG, got %08x\n", hr
);
654 hr
= CreateXmlReaderInputWithEncodingName(NULL
, NULL
, NULL
, FALSE
, NULL
, &reader_input
);
655 ok(hr
== E_INVALIDARG
, "Expected E_INVALIDARG, got %08x\n", hr
);
657 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
658 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
660 ref
= IStream_AddRef(stream
);
661 ok(ref
== 2, "Expected 2, got %d\n", ref
);
662 IStream_Release(stream
);
663 hr
= CreateXmlReaderInputWithEncodingName((IUnknown
*)stream
, NULL
, NULL
, FALSE
, NULL
, &reader_input
);
664 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
666 hr
= IUnknown_QueryInterface(reader_input
, &IID_IStream
, (void**)&stream2
);
667 ok(hr
== E_NOINTERFACE
, "Expected S_OK, got %08x\n", hr
);
669 hr
= IUnknown_QueryInterface(reader_input
, &IID_ISequentialStream
, (void**)&stream2
);
670 ok(hr
== E_NOINTERFACE
, "Expected S_OK, got %08x\n", hr
);
672 /* IXmlReaderInput grabs a stream reference */
673 ref
= IStream_AddRef(stream
);
674 ok(ref
== 3, "Expected 3, got %d\n", ref
);
675 IStream_Release(stream
);
677 /* try ::SetInput() with valid IXmlReaderInput */
678 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
679 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
681 ref
= IUnknown_AddRef(reader_input
);
682 ok(ref
== 2, "Expected 2, got %d\n", ref
);
683 IUnknown_Release(reader_input
);
685 hr
= IXmlReader_SetInput(reader
, reader_input
);
686 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
688 TEST_READER_STATE(reader
, XmlReadState_Initial
);
690 nodetype
= XmlNodeType_Element
;
691 hr
= IXmlReader_GetNodeType(reader
, &nodetype
);
692 ok(hr
== S_OK
, "got %08x\n", hr
);
693 ok(nodetype
== XmlNodeType_None
, "got %d\n", nodetype
);
695 /* IXmlReader grabs a IXmlReaderInput reference */
696 ref
= IUnknown_AddRef(reader_input
);
697 ok(ref
== 3, "Expected 3, got %d\n", ref
);
698 IUnknown_Release(reader_input
);
700 ref
= IStream_AddRef(stream
);
701 ok(ref
== 4, "Expected 4, got %d\n", ref
);
702 IStream_Release(stream
);
704 /* reset input and check state */
705 hr
= IXmlReader_SetInput(reader
, NULL
);
706 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
708 TEST_READER_STATE2(reader
, XmlReadState_Initial
, XmlReadState_Closed
);
710 IXmlReader_Release(reader
);
712 ref
= IStream_AddRef(stream
);
713 ok(ref
== 3, "Expected 3, got %d\n", ref
);
714 IStream_Release(stream
);
716 ref
= IUnknown_AddRef(reader_input
);
717 ok(ref
== 2, "Expected 2, got %d\n", ref
);
718 IUnknown_Release(reader_input
);
720 /* IID_IXmlReaderInput */
721 /* it returns a kind of private undocumented vtable incompatible with IUnknown,
722 so it's not a COM interface actually.
723 Such query will be used only to check if input is really IXmlReaderInput */
724 obj
= (IUnknown
*)0xdeadbeef;
725 hr
= IUnknown_QueryInterface(reader_input
, &IID_IXmlReaderInput
, (void**)&obj
);
726 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
727 ref
= IUnknown_AddRef(reader_input
);
728 ok(ref
== 3, "Expected 3, got %d\n", ref
);
729 IUnknown_Release(reader_input
);
731 IUnknown_Release(reader_input
);
732 IUnknown_Release(reader_input
);
733 IStream_Release(stream
);
735 /* test input interface selection sequence */
737 hr
= testinput_createinstance((void**)&input
);
738 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
740 input_iids
.count
= 0;
741 ref
= IUnknown_AddRef(input
);
742 ok(ref
== 2, "Expected 2, got %d\n", ref
);
743 IUnknown_Release(input
);
744 hr
= CreateXmlReaderInputWithEncodingName(input
, NULL
, NULL
, FALSE
, NULL
, &reader_input
);
745 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
746 ok_iids(&input_iids
, empty_seq
, NULL
, FALSE
);
747 /* IXmlReaderInput stores stream interface as IUnknown */
748 ref
= IUnknown_AddRef(input
);
749 ok(ref
== 3, "Expected 3, got %d\n", ref
);
750 IUnknown_Release(input
);
752 hr
= CreateXmlReader(&IID_IXmlReader
, (LPVOID
*)&reader
, NULL
);
753 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
755 input_iids
.count
= 0;
756 ref
= IUnknown_AddRef(reader_input
);
757 ok(ref
== 2, "Expected 2, got %d\n", ref
);
758 IUnknown_Release(reader_input
);
759 ref
= IUnknown_AddRef(input
);
760 ok(ref
== 3, "Expected 3, got %d\n", ref
);
761 IUnknown_Release(input
);
762 hr
= IXmlReader_SetInput(reader
, reader_input
);
763 ok(hr
== E_NOINTERFACE
, "Expected E_NOINTERFACE, got %08x\n", hr
);
764 ok_iids(&input_iids
, setinput_readerinput
, NULL
, FALSE
);
766 TEST_READER_STATE(reader
, XmlReadState_Closed
);
768 ref
= IUnknown_AddRef(input
);
769 ok(ref
== 3, "Expected 3, got %d\n", ref
);
770 IUnknown_Release(input
);
772 ref
= IUnknown_AddRef(reader_input
);
773 ok(ref
== 3 || broken(ref
== 2) /* versions 1.0.x and 1.1.x - XP, Vista */,
774 "Expected 3, got %d\n", ref
);
775 IUnknown_Release(reader_input
);
776 /* repeat another time, no check or caching here */
777 input_iids
.count
= 0;
778 hr
= IXmlReader_SetInput(reader
, reader_input
);
779 ok(hr
== E_NOINTERFACE
, "Expected E_NOINTERFACE, got %08x\n", hr
);
780 ok_iids(&input_iids
, setinput_readerinput
, NULL
, FALSE
);
783 hr
= CreateXmlReader(&IID_IXmlReader
, (LPVOID
*)&reader2
, NULL
);
784 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
786 /* resolving from IXmlReaderInput to IStream/ISequentialStream is done at
787 ::SetInput() level, each time it's called */
788 input_iids
.count
= 0;
789 hr
= IXmlReader_SetInput(reader2
, reader_input
);
790 ok(hr
== E_NOINTERFACE
, "Expected E_NOINTERFACE, got %08x\n", hr
);
791 ok_iids(&input_iids
, setinput_readerinput
, NULL
, FALSE
);
793 IXmlReader_Release(reader2
);
794 IXmlReader_Release(reader
);
796 IUnknown_Release(reader_input
);
797 IUnknown_Release(input
);
800 static void test_reader_state(void)
802 XmlNodeType nodetype
;
807 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
808 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
810 /* invalid arguments */
811 hr
= IXmlReader_GetProperty(reader
, XmlReaderProperty_ReadState
, NULL
);
812 ok(hr
== E_INVALIDARG
, "Expected E_INVALIDARG, got %08x\n", hr
);
814 /* attempt to read on closed reader */
815 TEST_READER_STATE(reader
, XmlReadState_Closed
);
819 /* newer versions crash here, probably because no input was set */
820 hr
= IXmlReader_Read(reader
, &nodetype
);
821 ok(hr
== S_FALSE
, "got %08x\n", hr
);
824 stream
= create_stream_on_data("xml", sizeof("xml"));
826 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
827 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
829 TEST_READER_STATE(reader
, XmlReadState_Initial
);
831 nodetype
= XmlNodeType_Element
;
832 hr
= IXmlReader_Read(reader
, &nodetype
);
834 ok(FAILED(hr
), "got %08x\n", hr
);
835 ok(nodetype
== XmlNodeType_None
, "Unexpected node type %d\n", nodetype
);
838 TEST_READER_STATE(reader
, XmlReadState_Error
);
840 nodetype
= XmlNodeType_Element
;
841 hr
= IXmlReader_Read(reader
, &nodetype
);
843 ok(FAILED(hr
), "got %08x\n", hr
);
844 ok(nodetype
== XmlNodeType_None
, "Unexpected node type %d\n", nodetype
);
846 IStream_Release(stream
);
847 IXmlReader_Release(reader
);
850 static void test_reader_depth(IXmlReader
*reader
, UINT depth
, UINT brk
, int line
)
855 IXmlReader_GetDepth(reader
, &d
);
857 condition
= d
== depth
;
859 condition
|= broken(d
== brk
);
860 ok_(__FILE__
, line
)(condition
, "Unexpected nesting depth %u, expected %u\n", d
, depth
);
863 #define TEST_DEPTH(reader, depth) test_reader_depth(reader, depth, ~0u, __LINE__)
864 #define TEST_DEPTH2(reader, depth, brk) test_reader_depth(reader, depth, brk, __LINE__)
866 static void test_read_xmldeclaration(void)
874 { {'v','e','r','s','i','o','n',0}, {'1','.','0',0} },
875 { {'e','n','c','o','d','i','n','g',0}, {'U','T','F','-','8',0} },
876 { {'s','t','a','n','d','a','l','o','n','e',0}, {'y','e','s',0} }
882 UINT count
= 0, len
, i
;
886 hr
= CreateXmlReader(&IID_IXmlReader
, (LPVOID
*)&reader
, NULL
);
887 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
889 stream
= create_stream_on_data(xmldecl_full
, sizeof(xmldecl_full
));
891 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
892 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
894 hr
= IXmlReader_GetAttributeCount(reader
, &count
);
895 ok(hr
== S_OK
, "got %08x\n", hr
);
896 ok(count
== 0, "got %d\n", count
);
898 /* try to move without attributes */
899 hr
= IXmlReader_MoveToElement(reader
);
900 ok(hr
== S_FALSE
, "got %08x\n", hr
);
902 hr
= IXmlReader_MoveToNextAttribute(reader
);
903 ok(hr
== S_FALSE
, "got %08x\n", hr
);
905 hr
= IXmlReader_MoveToFirstAttribute(reader
);
906 ok(hr
== S_FALSE
, "got %08x\n", hr
);
908 TEST_READER_POSITION(reader
, 0, 0);
910 read_node(reader
, XmlNodeType_XmlDeclaration
);
912 /* new version 1.2.x and 1.3.x properly update position for <?xml ?> */
913 TEST_READER_POSITION2(reader
, 1, 3, ~0u, 55);
915 TEST_DEPTH(reader
, 0);
916 TEST_READER_STATE(reader
, XmlReadState_Interactive
);
918 reader_value(reader
, "");
920 /* check attributes */
921 next_attribute(reader
);
923 TEST_DEPTH(reader
, 1);
925 type
= XmlNodeType_None
;
926 hr
= IXmlReader_GetNodeType(reader
, &type
);
927 ok(hr
== S_OK
, "got %08x\n", hr
);
928 ok(type
== XmlNodeType_Attribute
, "got %d\n", type
);
930 TEST_READER_POSITION2(reader
, 1, 7, ~0u, 55);
932 /* try to move from last attribute */
933 next_attribute(reader
);
934 next_attribute(reader
);
935 hr
= IXmlReader_MoveToNextAttribute(reader
);
936 ok(hr
== S_FALSE
, "got %08x\n", hr
);
938 type
= XmlNodeType_None
;
939 hr
= IXmlReader_GetNodeType(reader
, &type
);
940 ok(hr
== S_OK
, "got %08x\n", hr
);
941 ok(type
== XmlNodeType_Attribute
, "got %d\n", type
);
943 hr
= IXmlReader_MoveToFirstAttribute(reader
);
944 ok(hr
== S_OK
, "got %08x\n", hr
);
945 TEST_READER_POSITION2(reader
, 1, 7, ~0u, 55);
947 hr
= IXmlReader_GetAttributeCount(reader
, NULL
);
948 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
950 hr
= IXmlReader_GetAttributeCount(reader
, &count
);
951 ok(hr
== S_OK
, "got %08x\n", hr
);
952 ok(count
== 3, "Expected 3, got %d\n", count
);
954 for (i
= 0; i
< count
; i
++)
957 hr
= IXmlReader_GetLocalName(reader
, &val
, &len
);
958 ok(hr
== S_OK
, "got %08x\n", hr
);
959 ok(len
== lstrlenW(name_val
[i
].name
), "expected %u, got %u\n", lstrlenW(name_val
[i
].name
), len
);
960 ok(!lstrcmpW(name_val
[i
].name
, val
), "expected %s, got %s\n", wine_dbgstr_w(name_val
[i
].name
), wine_dbgstr_w(val
));
963 hr
= IXmlReader_GetValue(reader
, &val
, &len
);
964 ok(hr
== S_OK
, "got %08x\n", hr
);
965 ok(len
== lstrlenW(name_val
[i
].val
), "expected %u, got %u\n", lstrlenW(name_val
[i
].val
), len
);
966 ok(!lstrcmpW(name_val
[i
].val
, val
), "expected %s, got %s\n", wine_dbgstr_w(name_val
[i
].val
), wine_dbgstr_w(val
));
968 hr
= IXmlReader_MoveToNextAttribute(reader
);
969 ok(hr
== ((i
< count
- 1) ? S_OK
: S_FALSE
), "got %08x\n", hr
);
972 TEST_DEPTH(reader
, 1);
974 move_to_element(reader
);
975 TEST_READER_POSITION2(reader
, 1, 3, ~0u, 55);
977 type
= XmlNodeType_None
;
978 hr
= IXmlReader_GetNodeType(reader
, &type
);
979 ok(hr
== S_OK
, "got %08x\n", hr
);
980 ok(type
== XmlNodeType_XmlDeclaration
, "got %d\n", type
);
982 type
= XmlNodeType_XmlDeclaration
;
983 hr
= IXmlReader_Read(reader
, &type
);
984 /* newer versions return syntax error here cause document is incomplete,
985 it makes more sense than invalid char error */
987 ok(hr
== WC_E_SYNTAX
|| broken(hr
== WC_E_XMLCHARACTER
), "got 0x%08x\n", hr
);
988 ok(type
== XmlNodeType_None
, "got %d\n", type
);
990 IStream_Release(stream
);
992 /* test short variant */
993 stream
= create_stream_on_data(xmldecl_short
, sizeof(xmldecl_short
));
995 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
996 ok(hr
== S_OK
, "expected S_OK, got %08x\n", hr
);
998 read_node(reader
, XmlNodeType_XmlDeclaration
);
999 TEST_READER_POSITION2(reader
, 1, 3, ~0u, 21);
1000 TEST_READER_STATE(reader
, XmlReadState_Interactive
);
1002 hr
= IXmlReader_GetAttributeCount(reader
, &count
);
1003 ok(hr
== S_OK
, "expected S_OK, got %08x\n", hr
);
1004 ok(count
== 1, "expected 1, got %d\n", count
);
1006 ret
= IXmlReader_IsEmptyElement(reader
);
1007 ok(!ret
, "element should not be empty\n");
1009 reader_value(reader
, "");
1010 reader_name(reader
, "xml");
1012 reader_qname(reader
, "xml");
1014 /* check attributes */
1015 next_attribute(reader
);
1018 hr
= IXmlReader_GetNodeType(reader
, &type
);
1019 ok(hr
== S_OK
, "expected S_OK, got %08x\n", hr
);
1020 ok(type
== XmlNodeType_Attribute
, "got %d\n", type
);
1021 TEST_READER_POSITION2(reader
, 1, 7, ~0u, 21);
1023 /* try to move from last attribute */
1024 hr
= IXmlReader_MoveToNextAttribute(reader
);
1025 ok(hr
== S_FALSE
, "expected S_FALSE, got %08x\n", hr
);
1027 read_node(reader
, XmlNodeType_Element
);
1028 TEST_READER_POSITION2(reader
, 1, 23, ~0u, 40);
1029 TEST_READER_STATE(reader
, XmlReadState_Interactive
);
1031 hr
= IXmlReader_GetAttributeCount(reader
, &count
);
1032 ok(hr
== S_OK
, "expected S_OK, got %08x\n", hr
);
1033 ok(count
== 0, "expected 0, got %d\n", count
);
1035 ret
= IXmlReader_IsEmptyElement(reader
);
1036 ok(ret
, "element should be empty\n");
1038 reader_value(reader
, "");
1039 reader_name(reader
, "RegistrationInfo");
1042 hr
= IXmlReader_Read(reader
, &type
);
1044 ok(hr
== WC_E_SYNTAX
|| hr
== WC_E_XMLCHARACTER
/* XP */, "expected WC_E_SYNTAX, got %08x\n", hr
);
1045 ok(type
== XmlNodeType_None
, "expected XmlNodeType_None, got %s\n", type_to_str(type
));
1046 TEST_READER_POSITION(reader
, 1, 41);
1048 TEST_READER_STATE(reader
, XmlReadState_Error
);
1050 IStream_Release(stream
);
1051 IXmlReader_Release(reader
);
1059 HRESULT hr_broken
; /* this is set to older version results */
1063 static struct test_entry comment_tests
[] = {
1064 { "<!-- comment -->", "", " comment ", S_OK
},
1065 { "<!-- - comment-->", "", " - comment", S_OK
},
1066 { "<!-- -- comment-->", NULL
, NULL
, WC_E_COMMENT
, WC_E_GREATERTHAN
},
1067 { "<!-- -- comment--->", NULL
, NULL
, WC_E_COMMENT
, WC_E_GREATERTHAN
},
1071 static void test_read_comment(void)
1073 static const char *teststr
= "<a>text<!-- comment --></a>";
1074 struct test_entry
*test
= comment_tests
;
1075 static const XmlNodeType types
[] =
1077 XmlNodeType_Element
,
1079 XmlNodeType_Comment
,
1080 XmlNodeType_EndElement
,
1087 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1088 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
1090 set_input_string(reader
, teststr
);
1092 while (IXmlReader_Read(reader
, &type
) == S_OK
)
1096 ok(type
== types
[i
], "%d: unexpected node type %d\n", i
, type
);
1098 if (type
== XmlNodeType_Text
|| type
== XmlNodeType_Comment
)
1100 hr
= IXmlReader_GetValue(reader
, &value
, NULL
);
1101 ok(hr
== S_OK
, "got %08x\n", hr
);
1102 ok(*value
!= 0, "Expected node value\n");
1109 set_input_string(reader
, test
->xml
);
1111 type
= XmlNodeType_None
;
1112 hr
= IXmlReader_Read(reader
, &type
);
1113 if (test
->hr_broken
)
1114 ok(hr
== test
->hr
|| broken(hr
== test
->hr_broken
), "got %08x for %s\n", hr
, test
->xml
);
1116 ok(hr
== test
->hr
, "got %08x for %s\n", hr
, test
->xml
);
1121 ok(type
== XmlNodeType_Comment
, "got %d for %s\n", type
, test
->xml
);
1123 reader_name(reader
, "");
1126 hr
= IXmlReader_GetLocalName(reader
, &str
, NULL
);
1127 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1128 ok(*str
== 0, "got %s\n", wine_dbgstr_w(str
));
1130 reader_qname(reader
, "");
1133 hr
= IXmlReader_GetQualifiedName(reader
, &str
, NULL
);
1134 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1135 ok(*str
== 0, "got %s\n", wine_dbgstr_w(str
));
1138 reader_value(reader
, test
->value
);
1144 IXmlReader_Release(reader
);
1147 static struct test_entry pi_tests
[] = {
1148 { "<?pi?>", "pi", "", S_OK
},
1149 { "<?pi ?>", "pi", "", S_OK
},
1150 { "<?pi ?>", "pi", "", S_OK
},
1151 { "<?pi pi data?>", "pi", "pi data", S_OK
},
1152 { "<?pi pi data ?>", "pi", "pi data ", S_OK
},
1153 { "<?pi data ?>", "pi", "data ", S_OK
},
1154 { "<?pi:pi?>", NULL
, NULL
, NC_E_NAMECOLON
, WC_E_NAMECHARACTER
},
1155 { "<?:pi ?>", NULL
, NULL
, WC_E_PI
, WC_E_NAMECHARACTER
},
1156 { "<?-pi ?>", NULL
, NULL
, WC_E_PI
, WC_E_NAMECHARACTER
},
1157 { "<?xml-stylesheet ?>", "xml-stylesheet", "", S_OK
},
1161 static void test_read_pi(void)
1163 struct test_entry
*test
= pi_tests
;
1167 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1168 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
1174 set_input_string(reader
, test
->xml
);
1176 type
= XmlNodeType_None
;
1177 hr
= IXmlReader_Read(reader
, &type
);
1178 if (test
->hr_broken
)
1179 ok(hr
== test
->hr
|| broken(hr
== test
->hr_broken
), "got %08x for %s\n", hr
, test
->xml
);
1181 ok(hr
== test
->hr
, "got %08x for %s\n", hr
, test
->xml
);
1188 ok(type
== XmlNodeType_ProcessingInstruction
, "got %d for %s\n", type
, test
->xml
);
1190 reader_name(reader
, test
->name
);
1194 hr
= IXmlReader_GetQualifiedName(reader
, &str
, &len
);
1195 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1196 ok(len
== strlen(test
->name
), "got %u\n", len
);
1197 str_exp
= a2w(test
->name
);
1198 ok(!lstrcmpW(str
, str_exp
), "got %s\n", wine_dbgstr_w(str
));
1202 reader_value(reader
, test
->value
);
1208 IXmlReader_Release(reader
);
1219 static const char misc_test_xml
[] =
1237 static struct nodes_test misc_test
= {
1240 {XmlNodeType_Comment
, " comment1 "},
1241 {XmlNodeType_Comment
, " comment2 "},
1242 {XmlNodeType_ProcessingInstruction
, "pi1body "},
1243 {XmlNodeType_Comment
, " comment3 "},
1244 {XmlNodeType_Whitespace
, " \t \n \n"},
1245 {XmlNodeType_Comment
, " comment4 "},
1246 {XmlNodeType_Element
, ""},
1247 {XmlNodeType_Whitespace
, "\n\t"},
1248 {XmlNodeType_Element
, ""},
1249 {XmlNodeType_Text
, "text"},
1250 {XmlNodeType_Comment
, " comment "},
1251 {XmlNodeType_Text
, "text2"},
1252 {XmlNodeType_ProcessingInstruction
, "pibody "},
1253 {XmlNodeType_Whitespace
, "\n"},
1254 {XmlNodeType_EndElement
, ""},
1255 {XmlNodeType_None
, ""}
1259 static void test_read_full(void)
1261 struct nodes_test
*test
= &misc_test
;
1266 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1267 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
1269 set_input_string(reader
, test
->xml
);
1274 read_node(reader
, test
->nodes
[i
].type
);
1275 reader_value(reader
, test
->nodes
[i
].value
);
1276 } while(test
->nodes
[i
++].type
!= XmlNodeType_None
);
1278 IXmlReader_Release(reader
);
1281 static const char test_public_dtd
[] =
1282 "<!DOCTYPE testdtd PUBLIC \"pubid\" \"externalid uri\" >";
1284 static void test_read_public_dtd(void)
1286 static const WCHAR dtdnameW
[] = {'t','e','s','t','d','t','d',0};
1294 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1295 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
1297 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_DtdProcessing
, DtdProcessing_Parse
);
1298 ok(hr
== S_OK
, "got 0x%8x\n", hr
);
1300 stream
= create_stream_on_data(test_public_dtd
, sizeof(test_public_dtd
));
1301 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
1302 ok(hr
== S_OK
, "got %08x\n", hr
);
1304 read_node(reader
, XmlNodeType_DocumentType
);
1307 hr
= IXmlReader_GetAttributeCount(reader
, &count
);
1308 ok(hr
== S_OK
, "got %08x\n", hr
);
1309 ok(count
== 2, "got %d\n", count
);
1311 hr
= IXmlReader_MoveToFirstAttribute(reader
);
1312 ok(hr
== S_OK
, "got %08x\n", hr
);
1314 type
= XmlNodeType_None
;
1315 hr
= IXmlReader_GetNodeType(reader
, &type
);
1316 ok(hr
== S_OK
, "got %08x\n", hr
);
1317 ok(type
== XmlNodeType_Attribute
, "got %d\n", type
);
1319 reader_name(reader
, "PUBLIC");
1320 reader_value(reader
, "pubid");
1322 next_attribute(reader
);
1324 type
= XmlNodeType_None
;
1325 hr
= IXmlReader_GetNodeType(reader
, &type
);
1326 ok(hr
== S_OK
, "got %08x\n", hr
);
1327 ok(type
== XmlNodeType_Attribute
, "got %d\n", type
);
1329 reader_name(reader
, "SYSTEM");
1330 reader_value(reader
, "externalid uri");
1332 move_to_element(reader
);
1333 reader_name(reader
, "testdtd");
1337 hr
= IXmlReader_GetQualifiedName(reader
, &str
, &len
);
1338 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1340 ok(len
== lstrlenW(dtdnameW
), "got %u\n", len
);
1341 ok(!lstrcmpW(str
, dtdnameW
), "got %s\n", wine_dbgstr_w(str
));
1343 IStream_Release(stream
);
1344 IXmlReader_Release(reader
);
1347 static const char test_system_dtd
[] =
1348 "<!DOCTYPE testdtd SYSTEM \"externalid uri\" >"
1351 static void test_read_system_dtd(void)
1353 static const WCHAR dtdnameW
[] = {'t','e','s','t','d','t','d',0};
1361 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1362 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
1364 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_DtdProcessing
, DtdProcessing_Parse
);
1365 ok(hr
== S_OK
, "got 0x%8x\n", hr
);
1367 stream
= create_stream_on_data(test_system_dtd
, sizeof(test_system_dtd
));
1368 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
1369 ok(hr
== S_OK
, "got %08x\n", hr
);
1371 read_node(reader
, XmlNodeType_DocumentType
);
1374 hr
= IXmlReader_GetAttributeCount(reader
, &count
);
1375 ok(hr
== S_OK
, "got %08x\n", hr
);
1376 ok(count
== 1, "got %d\n", count
);
1378 hr
= IXmlReader_MoveToFirstAttribute(reader
);
1379 ok(hr
== S_OK
, "got %08x\n", hr
);
1381 type
= XmlNodeType_None
;
1382 hr
= IXmlReader_GetNodeType(reader
, &type
);
1383 ok(hr
== S_OK
, "got %08x\n", hr
);
1384 ok(type
== XmlNodeType_Attribute
, "got %d\n", type
);
1386 reader_name(reader
, "SYSTEM");
1387 reader_value(reader
, "externalid uri");
1389 move_to_element(reader
);
1390 reader_name(reader
, "testdtd");
1394 hr
= IXmlReader_GetQualifiedName(reader
, &str
, &len
);
1395 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1397 ok(len
== lstrlenW(dtdnameW
), "got %u\n", len
);
1398 ok(!lstrcmpW(str
, dtdnameW
), "got %s\n", wine_dbgstr_w(str
));
1401 read_node(reader
, XmlNodeType_Comment
);
1403 IStream_Release(stream
);
1404 IXmlReader_Release(reader
);
1407 static struct test_entry element_tests
[] = {
1408 { "<a/>", "a", "", S_OK
},
1409 { "<a />", "a", "", S_OK
},
1410 { "<a:b/>", "a:b", "", NC_E_UNDECLAREDPREFIX
},
1411 { "<:a/>", NULL
, NULL
, NC_E_QNAMECHARACTER
},
1412 { "< a/>", NULL
, NULL
, NC_E_QNAMECHARACTER
},
1413 { "<a>", "a", "", S_OK
},
1414 { "<a >", "a", "", S_OK
},
1415 { "<a \r \t\n>", "a", "", S_OK
},
1416 { "</a>", NULL
, NULL
, NC_E_QNAMECHARACTER
},
1417 { "<a:b:c />", NULL
, NULL
, NC_E_QNAMECOLON
},
1418 { "<:b:c />", NULL
, NULL
, NC_E_QNAMECHARACTER
},
1422 static void test_read_element(void)
1424 struct test_entry
*test
= element_tests
;
1425 static const char stag
[] =
1430 "<d attr4=\"_d\"></d>"
1433 static const UINT depths
[] = { 0, 1, 2, 2, 2, 3, 2, 1 };
1440 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1441 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
1445 set_input_string(reader
, test
->xml
);
1447 type
= XmlNodeType_None
;
1448 hr
= IXmlReader_Read(reader
, &type
);
1449 if (test
->hr_broken
)
1450 ok(hr
== test
->hr
|| broken(hr
== test
->hr_broken
), "got %08x for %s\n", hr
, test
->xml
);
1452 todo_wine_if(test
->hr
== NC_E_UNDECLAREDPREFIX
)
1453 ok(hr
== test
->hr
, "got %08x for %s\n", hr
, test
->xml
);
1460 ok(type
== XmlNodeType_Element
, "got %d for %s\n", type
, test
->xml
);
1464 hr
= IXmlReader_GetQualifiedName(reader
, &str
, &len
);
1465 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1466 ok(len
== strlen(test
->name
), "got %u\n", len
);
1467 str_exp
= a2w(test
->name
);
1468 ok(!lstrcmpW(str
, str_exp
), "got %s\n", wine_dbgstr_w(str
));
1472 reader_value(reader
, "");
1478 /* test reader depth increment */
1479 set_input_string(reader
, stag
);
1482 while (IXmlReader_Read(reader
, &type
) == S_OK
)
1486 ok(type
== XmlNodeType_Element
|| type
== XmlNodeType_EndElement
||
1487 type
== XmlNodeType_Text
, "Unexpected node type %d\n", type
);
1490 hr
= IXmlReader_GetDepth(reader
, &depth
);
1491 ok(hr
== S_OK
, "got %08x\n", hr
);
1492 ok(depth
== depths
[i
], "%u: got depth %u, expected %u\n", i
, depth
, depths
[i
]);
1494 if (type
== XmlNodeType_Element
|| type
== XmlNodeType_EndElement
)
1496 const WCHAR
*prefix
;
1499 hr
= IXmlReader_GetPrefix(reader
, &prefix
, NULL
);
1500 ok(hr
== S_OK
, "got %08x\n", hr
);
1501 ok(prefix
!= NULL
, "got %p\n", prefix
);
1505 const WCHAR
*local
, *qname
;
1508 hr
= IXmlReader_GetLocalName(reader
, &local
, NULL
);
1509 ok(hr
== S_OK
, "got %08x\n", hr
);
1510 ok(local
!= NULL
, "got %p\n", local
);
1513 hr
= IXmlReader_GetQualifiedName(reader
, &qname
, NULL
);
1514 ok(hr
== S_OK
, "got %08x\n", hr
);
1515 ok(qname
!= NULL
, "got %p\n", qname
);
1517 ok(local
== qname
, "expected same pointer\n");
1521 if (type
== XmlNodeType_EndElement
)
1524 hr
= IXmlReader_GetAttributeCount(reader
, &count
);
1525 ok(hr
== S_OK
, "got %08x\n", hr
);
1526 ok(count
== 0, "got %u\n", count
);
1529 if (type
== XmlNodeType_Element
)
1532 hr
= IXmlReader_GetAttributeCount(reader
, &count
);
1533 ok(hr
== S_OK
, "got %08x\n", hr
);
1535 /* moving to attributes increases depth */
1540 reader_value(reader
, "");
1542 hr
= IXmlReader_MoveToFirstAttribute(reader
);
1543 ok(hr
== S_OK
, "got %08x\n", hr
);
1545 hr
= IXmlReader_GetValue(reader
, &value
, NULL
);
1546 ok(*value
!= 0, "Unexpected value %s\n", wine_dbgstr_w(value
));
1549 hr
= IXmlReader_GetDepth(reader
, &depth
);
1550 ok(hr
== S_OK
, "got %08x\n", hr
);
1551 ok(depth
== depths
[i
] + 1, "%u: got depth %u, expected %u\n", i
, depth
, depths
[i
] + 1);
1553 move_to_element(reader
);
1554 reader_value(reader
, "");
1557 hr
= IXmlReader_GetDepth(reader
, &depth
);
1558 ok(hr
== S_OK
, "got %08x\n", hr
);
1559 ok(depth
== depths
[i
], "%u: got depth %u, expected %u\n", i
, depth
, depths
[i
]);
1566 /* start/end tag mismatch */
1567 set_input_string(reader
, "<a></b>");
1569 read_node(reader
, XmlNodeType_Element
);
1571 type
= XmlNodeType_Element
;
1572 hr
= IXmlReader_Read(reader
, &type
);
1573 ok(hr
== WC_E_ELEMENTMATCH
, "got %08x\n", hr
);
1574 ok(type
== XmlNodeType_None
, "got %d\n", type
);
1575 TEST_READER_STATE(reader
, XmlReadState_Error
);
1577 IXmlReader_Release(reader
);
1580 static ISequentialStream teststream
= { &teststreamvtbl
};
1582 static void test_read_pending(void)
1590 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1591 ok(hr
== S_OK
, "S_OK, got 0x%08x\n", hr
);
1593 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)&teststream
);
1594 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1596 /* first read call returns incomplete node, second attempt fails with E_PENDING */
1597 stream_readcall
= 0;
1598 type
= XmlNodeType_Element
;
1599 hr
= IXmlReader_Read(reader
, &type
);
1600 ok(hr
== S_OK
|| broken(hr
== E_PENDING
), "got 0x%08x\n", hr
);
1601 /* newer versions are happy when it's enough data to detect node type,
1602 older versions keep reading until it fails to read more */
1604 ok(stream_readcall
== 1 || broken(stream_readcall
> 1), "got %d\n", stream_readcall
);
1605 ok(type
== XmlNodeType_Comment
|| broken(type
== XmlNodeType_None
), "got %d\n", type
);
1607 /* newer versions' GetValue() makes an attempt to read more */
1608 c
= stream_readcall
;
1609 value
= (void*)0xdeadbeef;
1610 hr
= IXmlReader_GetValue(reader
, &value
, NULL
);
1611 ok(hr
== E_PENDING
, "got 0x%08x\n", hr
);
1612 ok(value
== NULL
|| broken(value
== (void*)0xdeadbeef) /* Win8 sets it to NULL */, "got %p\n", value
);
1613 ok(c
< stream_readcall
|| broken(c
== stream_readcall
), "got %d, expected %d\n", stream_readcall
, c
+1);
1615 IXmlReader_Release(reader
);
1618 static void test_readvaluechunk(void)
1627 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1628 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
1630 set_input_string(reader
, "<!-- comment1 --><!-- comment2 -->");
1632 hr
= IXmlReader_Read(reader
, &type
);
1633 ok(hr
== S_OK
, "got %08x\n", hr
);
1634 ok(type
== XmlNodeType_Comment
, "type = %u\n", type
);
1636 read_value_char(reader
, ' ');
1637 read_value_char(reader
, 'c');
1639 /* portion read as chunk is skipped from resulting node value */
1640 reader_value(reader
, "omment1 ");
1642 /* once value is returned/allocated it's not possible to read by chunk */
1645 hr
= IXmlReader_ReadValueChunk(reader
, &b
, 1, &c
);
1646 ok(hr
== S_FALSE
, "got %08x\n", hr
);
1647 ok(c
== 0, "got %u\n", c
);
1648 ok(b
== 0, "got %x\n", b
);
1651 hr
= IXmlReader_ReadValueChunk(reader
, buf
, 0, &c
);
1652 ok(hr
== S_OK
, "got %08x\n", hr
);
1653 ok(!c
, "c = %u\n", c
);
1655 reader_value(reader
, "omment1 ");
1658 read_node(reader
, XmlNodeType_Comment
);
1661 hr
= IXmlReader_ReadValueChunk(reader
, buf
, 0, &c
);
1662 ok(hr
== S_OK
, "got %08x\n", hr
);
1663 ok(!c
, "c = %u\n", c
);
1666 memset(buf
, 0xcc, sizeof(buf
));
1667 hr
= IXmlReader_ReadValueChunk(reader
, buf
, sizeof(buf
)/sizeof(WCHAR
), &c
);
1668 ok(hr
== S_OK
, "got %08x\n", hr
);
1669 ok(c
== 10, "got %u\n", c
);
1670 ok(buf
[c
] == 0xcccc, "buffer overflow\n");
1672 ok(!strcmp_wa(buf
, " comment2 "), "buf = %s\n", wine_dbgstr_w(buf
));
1675 memset(buf
, 0xcc, sizeof(buf
));
1676 hr
= IXmlReader_ReadValueChunk(reader
, buf
, sizeof(buf
)/sizeof(WCHAR
), &c
);
1677 ok(hr
== S_FALSE
, "got %08x\n", hr
);
1678 ok(!c
, "got %u\n", c
);
1680 /* portion read as chunk is skipped from resulting node value */
1681 reader_value(reader
, "");
1683 /* once value is returned/allocated it's not possible to read by chunk */
1686 hr
= IXmlReader_ReadValueChunk(reader
, &b
, 1, &c
);
1687 ok(hr
== S_FALSE
, "got %08x\n", hr
);
1688 ok(c
== 0, "got %u\n", c
);
1689 ok(b
== 0xffff, "got %x\n", b
);
1691 reader_value(reader
, "");
1693 IXmlReader_Release(reader
);
1696 static struct test_entry cdata_tests
[] = {
1697 { "<a><![CDATA[ ]]data ]]></a>", "", " ]]data ", S_OK
},
1698 { "<a><![CDATA[<![CDATA[ data ]]]]></a>", "", "<![CDATA[ data ]]", S_OK
},
1699 { "<a><![CDATA[\n \r\n \n\n ]]></a>", "", "\n \n \n\n ", S_OK
, S_OK
},
1700 { "<a><![CDATA[\r \r\r\n \n\n ]]></a>", "", "\n \n\n \n\n ", S_OK
, S_OK
},
1701 { "<a><![CDATA[\r\r \n\r \r \n\n ]]></a>", "", "\n\n \n\n \n \n\n ", S_OK
},
1705 static void test_read_cdata(void)
1707 struct test_entry
*test
= cdata_tests
;
1711 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1712 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
1719 stream
= create_stream_on_data(test
->xml
, strlen(test
->xml
)+1);
1720 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
1721 ok(hr
== S_OK
, "got %08x\n", hr
);
1723 type
= XmlNodeType_None
;
1724 hr
= IXmlReader_Read(reader
, &type
);
1726 /* read one more to get to CDATA */
1727 if (type
== XmlNodeType_Element
)
1729 type
= XmlNodeType_None
;
1730 hr
= IXmlReader_Read(reader
, &type
);
1733 if (test
->hr_broken
)
1734 ok(hr
== test
->hr
|| broken(hr
== test
->hr_broken
), "got %08x for %s\n", hr
, test
->xml
);
1736 ok(hr
== test
->hr
, "got %08x for %s\n", hr
, test
->xml
);
1742 ok(type
== XmlNodeType_CDATA
, "got %d for %s\n", type
, test
->xml
);
1744 reader_name(reader
, "");
1747 hr
= IXmlReader_GetLocalName(reader
, &str
, NULL
);
1748 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1749 ok(*str
== 0, "got %s\n", wine_dbgstr_w(str
));
1753 hr
= IXmlReader_GetQualifiedName(reader
, &str
, &len
);
1754 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1755 ok(len
== 0, "got %u\n", len
);
1756 ok(*str
== 0, "got %s\n", wine_dbgstr_w(str
));
1759 hr
= IXmlReader_GetQualifiedName(reader
, &str
, NULL
);
1760 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1761 ok(*str
== 0, "got %s\n", wine_dbgstr_w(str
));
1764 reader_value(reader
, test
->value
);
1767 IStream_Release(stream
);
1771 IXmlReader_Release(reader
);
1774 static struct test_entry text_tests
[] = {
1775 { "<a>simple text</a>", "", "simple text", S_OK
},
1776 { "<a>text ]]> text</a>", "", "", WC_E_CDSECTEND
},
1777 { "<a>\n \r\n \n\n text</a>", "", "\n \n \n\n text", S_OK
, S_OK
},
1778 { "<a>\r \r\r\n \n\n text</a>", "", "\n \n\n \n\n text", S_OK
, S_OK
},
1782 static void test_read_text(void)
1784 struct test_entry
*test
= text_tests
;
1788 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1789 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
1796 stream
= create_stream_on_data(test
->xml
, strlen(test
->xml
)+1);
1797 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
1798 ok(hr
== S_OK
, "got %08x\n", hr
);
1800 type
= XmlNodeType_None
;
1801 hr
= IXmlReader_Read(reader
, &type
);
1803 /* read one more to get to text node */
1804 if (type
== XmlNodeType_Element
)
1806 type
= XmlNodeType_None
;
1807 hr
= IXmlReader_Read(reader
, &type
);
1809 ok(hr
== test
->hr
, "got %08x for %s\n", hr
, test
->xml
);
1815 ok(type
== XmlNodeType_Text
, "got %d for %s\n", type
, test
->xml
);
1817 reader_name(reader
, "");
1820 hr
= IXmlReader_GetLocalName(reader
, &str
, NULL
);
1821 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1822 ok(*str
== 0, "got %s\n", wine_dbgstr_w(str
));
1826 hr
= IXmlReader_GetQualifiedName(reader
, &str
, &len
);
1827 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1828 ok(len
== 0, "got %u\n", len
);
1829 ok(*str
== 0, "got %s\n", wine_dbgstr_w(str
));
1832 hr
= IXmlReader_GetQualifiedName(reader
, &str
, NULL
);
1833 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1834 ok(*str
== 0, "got %s\n", wine_dbgstr_w(str
));
1837 reader_value(reader
, test
->value
);
1840 IStream_Release(stream
);
1844 IXmlReader_Release(reader
);
1847 struct test_entry_empty
{
1852 static struct test_entry_empty empty_element_tests
[] = {
1853 { "<a></a>", FALSE
},
1858 static void test_isemptyelement(void)
1860 struct test_entry_empty
*test
= empty_element_tests
;
1864 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1865 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
1873 stream
= create_stream_on_data(test
->xml
, strlen(test
->xml
)+1);
1874 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
1875 ok(hr
== S_OK
, "got %08x\n", hr
);
1877 type
= XmlNodeType_None
;
1878 hr
= IXmlReader_Read(reader
, &type
);
1879 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1880 ok(type
== XmlNodeType_Element
, "got %d\n", type
);
1882 ret
= IXmlReader_IsEmptyElement(reader
);
1883 ok(ret
== test
->empty
, "got %d, expected %d. xml=%s\n", ret
, test
->empty
, test
->xml
);
1885 IStream_Release(stream
);
1889 IXmlReader_Release(reader
);
1892 static struct test_entry attributes_tests
[] = {
1893 { "<a attr1=\"attrvalue\"/>", "attr1", "attrvalue", S_OK
},
1894 { "<a attr1=\"a\'\'ttrvalue\"/>", "attr1", "a\'\'ttrvalue", S_OK
},
1895 { "<a attr1=\'a\"ttrvalue\'/>", "attr1", "a\"ttrvalue", S_OK
},
1896 { "<a attr1=\' \'/>", "attr1", " ", S_OK
},
1897 { "<a attr1=\" \"/>", "attr1", " ", S_OK
},
1898 { "<a attr1=\"\r\n \r \n \t\n\r\"/>", "attr1", " ", S_OK
},
1899 { "<a attr1=\" val \"/>", "attr1", " val ", S_OK
},
1900 { "<a attr1=\"\r\n\tval\n\"/>", "attr1", " val ", S_OK
},
1901 { "<a attr1=\"val \"/>", "attr1", "val ", S_OK
},
1902 { "<a attr1=\"val \"/>", "attr1", "val ", S_OK
},
1903 { "<a attr1=\"<>&'"\"/>", "attr1", "<>&\'\"", S_OK
},
1904 { "<a attr1=\"&entname;\"/>", NULL
, NULL
, WC_E_UNDECLAREDENTITY
},
1905 { "<a attr1=\"val\"/>", NULL
, NULL
, WC_E_XMLCHARACTER
},
1906 { "<a attr1=\"val &#a;\"/>", NULL
, NULL
, WC_E_DIGIT
, WC_E_SEMICOLON
},
1907 { "<a attr1=\"val a;\"/>", NULL
, NULL
, WC_E_SEMICOLON
},
1908 { "<a attr1=\"val g;\"/>", NULL
, NULL
, WC_E_SEMICOLON
},
1909 { "<a attr1=\"val &#xg;\"/>", NULL
, NULL
, WC_E_HEXDIGIT
, WC_E_SEMICOLON
},
1910 { "<a attr1=attrvalue/>", NULL
, NULL
, WC_E_QUOTE
},
1911 { "<a attr1=\"attr<value\"/>", NULL
, NULL
, WC_E_LESSTHAN
},
1912 { "<a attr1=\"&entname\"/>", NULL
, NULL
, WC_E_SEMICOLON
},
1916 static void test_read_attribute(void)
1918 struct test_entry
*test
= attributes_tests
;
1922 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1923 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
1930 stream
= create_stream_on_data(test
->xml
, strlen(test
->xml
)+1);
1931 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
1932 ok(hr
== S_OK
, "got %08x\n", hr
);
1934 hr
= IXmlReader_Read(reader
, NULL
);
1936 if (test
->hr_broken
)
1937 ok(hr
== test
->hr
|| broken(hr
== test
->hr_broken
), "got %08x for %s\n", hr
, test
->xml
);
1939 ok(hr
== test
->hr
, "got %08x for %s\n", hr
, test
->xml
);
1946 type
= XmlNodeType_None
;
1947 hr
= IXmlReader_GetNodeType(reader
, &type
);
1948 ok(hr
== S_OK
, "Failed to get node type, %#x\n", hr
);
1950 ok(type
== XmlNodeType_Element
, "got %d for %s\n", type
, test
->xml
);
1952 hr
= IXmlReader_MoveToFirstAttribute(reader
);
1953 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1955 reader_name(reader
, test
->name
);
1959 hr
= IXmlReader_GetQualifiedName(reader
, &str
, &len
);
1960 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1961 ok(len
== strlen(test
->name
), "got %u\n", len
);
1962 str_exp
= a2w(test
->name
);
1963 ok(!lstrcmpW(str
, str_exp
), "got %s\n", wine_dbgstr_w(str
));
1967 reader_value(reader
, test
->value
);
1970 IStream_Release(stream
);
1974 IXmlReader_Release(reader
);
1977 static void test_reader_properties(void)
1983 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
1984 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
1987 hr
= IXmlReader_GetProperty(reader
, XmlReaderProperty_MaxElementDepth
, &value
);
1988 ok(hr
== S_OK
, "GetProperty failed: %08x\n", hr
);
1989 ok(value
== 256, "Unexpected default max depth value %ld\n", value
);
1991 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_MultiLanguage
, 0);
1992 ok(hr
== S_OK
, "SetProperty failed: %08x\n", hr
);
1994 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_MaxElementDepth
, 0);
1995 ok(hr
== S_OK
, "SetProperty failed: %08x\n", hr
);
1998 hr
= IXmlReader_GetProperty(reader
, XmlReaderProperty_MaxElementDepth
, &value
);
1999 ok(hr
== S_OK
, "GetProperty failed: %08x\n", hr
);
2000 ok(value
== 0, "Unexpected max depth value %ld\n", value
);
2002 IXmlReader_Release(reader
);
2005 static void test_prefix(void)
2010 const char *prefix1
;
2011 const char *prefix2
;
2012 const char *prefix3
;
2015 { "<b xmlns=\"defns\" xml:a=\"a ns\"/>", "", "", "xml" },
2016 { "<c:b xmlns:c=\"c ns\" xml:a=\"a ns\"/>", "c", "xmlns", "xml" },
2022 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
2023 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
2025 for (i
= 0; i
< sizeof(prefix_tests
)/sizeof(prefix_tests
[0]); i
++) {
2029 stream
= create_stream_on_data(prefix_tests
[i
].xml
, strlen(prefix_tests
[i
].xml
) + 1);
2030 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
2031 ok(hr
== S_OK
, "got %08x\n", hr
);
2033 hr
= IXmlReader_Read(reader
, &type
);
2034 ok(hr
== S_OK
, "Read() failed, %#x\n", hr
);
2035 ok(type
== XmlNodeType_Element
, "Unexpected node type %d.\n", type
);
2037 reader_prefix(reader
, prefix_tests
[i
].prefix1
);
2039 hr
= IXmlReader_MoveToFirstAttribute(reader
);
2040 ok(hr
== S_OK
, "MoveToFirstAttribute() failed, %#x.\n", hr
);
2042 hr
= IXmlReader_GetNodeType(reader
, &type
);
2043 ok(hr
== S_OK
, "GetNodeType() failed, %#x.\n", hr
);
2044 ok(type
== XmlNodeType_Attribute
, "Unexpected node type %d.\n", type
);
2046 reader_prefix(reader
, prefix_tests
[i
].prefix2
);
2048 next_attribute(reader
);
2050 hr
= IXmlReader_GetNodeType(reader
, &type
);
2051 ok(hr
== S_OK
, "GetNodeType() failed, %#x.\n", hr
);
2052 ok(type
== XmlNodeType_Attribute
, "Unexpected node type %d.\n", type
);
2054 reader_prefix(reader
, prefix_tests
[i
].prefix3
);
2056 /* back to the element, check prefix */
2057 move_to_element(reader
);
2058 reader_prefix(reader
, prefix_tests
[i
].prefix1
);
2060 IStream_Release(stream
);
2063 IXmlReader_Release(reader
);
2066 static void test_namespaceuri(void)
2074 { "<a xmlns=\"defns a\"><b xmlns=\"defns b\"><c xmlns=\"defns c\"/></b></a>",
2075 { "defns a", "defns b", "defns c", "defns b", "defns a" }},
2076 { "<r:a xmlns=\"defns a\" xmlns:r=\"ns r\"/>",
2078 { "<r:a xmlns=\"defns a\" xmlns:r=\"ns r\"><b/></r:a>",
2079 { "ns r", "defns a", "ns r" }},
2080 { "<a xmlns=\"defns a\" xmlns:r=\"ns r\"><r:b/></a>",
2081 { "defns a", "ns r", "defns a" }},
2082 { "<a><b><c/></b></a>",
2083 { "", "", "", "", "" }},
2088 { "<a><![CDATA[data]]></a>",
2090 { "<?xml version=\"1.0\" ?><a/>",
2094 { "<a><!-- comment --></a>",
2102 hr
= CreateXmlReader(&IID_IXmlReader
, (void**)&reader
, NULL
);
2103 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
2105 for (i
= 0; i
< sizeof(uri_tests
)/sizeof(uri_tests
[0]); i
++) {
2106 IStream
*stream
= create_stream_on_data(uri_tests
[i
].xml
, strlen(uri_tests
[i
].xml
) + 1);
2109 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
2110 ok(hr
== S_OK
, "got %08x\n", hr
);
2113 while (IXmlReader_Read(reader
, &type
) == S_OK
) {
2114 const WCHAR
*local
, *qname
;
2115 UINT length
, length2
;
2117 ok(type
== XmlNodeType_Element
||
2118 type
== XmlNodeType_Text
||
2119 type
== XmlNodeType_CDATA
||
2120 type
== XmlNodeType_ProcessingInstruction
||
2121 type
== XmlNodeType_Comment
||
2122 type
== XmlNodeType_Whitespace
||
2123 type
== XmlNodeType_EndElement
||
2124 type
== XmlNodeType_XmlDeclaration
, "Unexpected node type %d.\n", type
);
2128 hr
= IXmlReader_GetLocalName(reader
, &local
, &length
);
2129 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
2130 ok(local
!= NULL
, "Unexpected NULL local name pointer\n");
2134 hr
= IXmlReader_GetQualifiedName(reader
, &qname
, &length2
);
2135 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
2136 ok(qname
!= NULL
, "Unexpected NULL qualified name pointer\n");
2138 if (type
== XmlNodeType_Element
||
2139 type
== XmlNodeType_EndElement
||
2140 type
== XmlNodeType_ProcessingInstruction
||
2141 type
== XmlNodeType_XmlDeclaration
)
2143 ok(*local
!= 0, "Unexpected empty local name\n");
2144 ok(length
> 0, "Unexpected local name length\n");
2146 ok(*qname
!= 0, "Unexpected empty qualified name\n");
2147 ok(length2
> 0, "Unexpected qualified name length\n");
2150 reader_namespace(reader
, uri_tests
[i
].uri
[j
]);
2154 ok(type
== XmlNodeType_None
, "Unexpected node type %d\n", type
);
2156 IStream_Release(stream
);
2159 IXmlReader_Release(reader
);
2162 static void test_read_charref(void)
2164 static const char testA
[] = "<a b=\"c\">dză></a>";
2165 static const WCHAR chardataW
[] = {0x01f3,0x0103,'>',0};
2171 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2172 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
2174 set_input_string(reader
, testA
);
2176 hr
= IXmlReader_Read(reader
, &type
);
2177 ok(hr
== S_OK
, "got %08x\n", hr
);
2178 ok(type
== XmlNodeType_Element
, "Unexpected node type %d\n", type
);
2180 hr
= IXmlReader_Read(reader
, &type
);
2181 ok(hr
== S_OK
, "got %08x\n", hr
);
2182 ok(type
== XmlNodeType_Text
, "Unexpected node type %d\n", type
);
2184 hr
= IXmlReader_GetValue(reader
, &value
, NULL
);
2185 ok(hr
== S_OK
, "got %08x\n", hr
);
2186 ok(!lstrcmpW(value
, chardataW
), "Text value : %s\n", wine_dbgstr_w(value
));
2188 hr
= IXmlReader_Read(reader
, &type
);
2189 ok(hr
== S_OK
, "got %08x\n", hr
);
2190 ok(type
== XmlNodeType_EndElement
, "Unexpected node type %d\n", type
);
2192 hr
= IXmlReader_Read(reader
, &type
);
2193 ok(hr
== S_FALSE
, "got %08x\n", hr
);
2194 ok(type
== XmlNodeType_None
, "Unexpected node type %d\n", type
);
2196 IXmlReader_Release(reader
);
2199 static void test_encoding_detection(void)
2201 static const struct encoding_testW
2207 { { '<','?','p','i',' ','?','>',0 } },
2208 { { '<','!','-','-',' ','c','-','-','>',0 } },
2209 { { 0xfeff,'<','a','/','>',0 } },
2210 { { '<','a','/','>',0 } },
2212 static const char *encoding_testsA
[] =
2216 "\xef\xbb\xbf<a/>", /* UTF-8 BOM */
2225 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2226 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
2228 /* there's no way to query detected encoding back, so just verify that document is browsable */
2230 for (i
= 0; i
< sizeof(encoding_testsA
)/sizeof(encoding_testsA
[0]); i
++)
2232 stream
= create_stream_on_data(encoding_testsA
[i
], strlen(encoding_testsA
[i
]));
2234 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
2235 ok(hr
== S_OK
, "got %08x\n", hr
);
2237 type
= XmlNodeType_None
;
2238 hr
= IXmlReader_Read(reader
, &type
);
2239 ok(hr
== S_OK
, "got %08x\n", hr
);
2240 ok(type
!= XmlNodeType_None
, "Unexpected node type %d\n", type
);
2242 IStream_Release(stream
);
2245 for (i
= 0; i
< sizeof(encoding_testsW
)/sizeof(encoding_testsW
[0]); i
++)
2247 stream
= create_stream_on_data(encoding_testsW
[i
].text
, lstrlenW(encoding_testsW
[i
].text
) * sizeof(WCHAR
));
2249 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
2250 ok(hr
== S_OK
, "got %08x\n", hr
);
2252 type
= XmlNodeType_None
;
2253 hr
= IXmlReader_Read(reader
, &type
);
2254 ok(hr
== S_OK
, "%u: got %08x\n", i
, hr
);
2255 ok(type
!= XmlNodeType_None
, "%u: unexpected node type %d\n", i
, type
);
2257 IStream_Release(stream
);
2260 IXmlReader_Release(reader
);
2263 static void test_eof_state(IXmlReader
*reader
, BOOL eof
)
2268 ok(IXmlReader_IsEOF(reader
) == eof
, "Unexpected IsEOF() result\n");
2269 hr
= IXmlReader_GetProperty(reader
, XmlReaderProperty_ReadState
, &state
);
2270 ok(hr
== S_OK
, "GetProperty() failed, %#x\n", hr
);
2271 ok((state
== XmlReadState_EndOfFile
) == eof
, "Unexpected EndOfFile state %ld\n", state
);
2274 static void test_endoffile(void)
2280 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2281 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
2283 test_eof_state(reader
, FALSE
);
2285 set_input_string(reader
, "<a/>");
2287 test_eof_state(reader
, FALSE
);
2289 type
= XmlNodeType_None
;
2290 hr
= IXmlReader_Read(reader
, &type
);
2291 ok(hr
== S_OK
, "got %#x\n", hr
);
2292 ok(type
== XmlNodeType_Element
, "Unexpected type %d\n", type
);
2294 test_eof_state(reader
, FALSE
);
2296 type
= XmlNodeType_Element
;
2297 hr
= IXmlReader_Read(reader
, &type
);
2298 ok(hr
== S_FALSE
, "got %#x\n", hr
);
2299 ok(type
== XmlNodeType_None
, "Unexpected type %d\n", type
);
2301 test_eof_state(reader
, TRUE
);
2303 hr
= IXmlReader_SetInput(reader
, NULL
);
2304 ok(hr
== S_OK
, "got %08x\n", hr
);
2306 test_eof_state(reader
, FALSE
);
2308 IXmlReader_Release(reader
);
2310 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2311 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
2313 set_input_string(reader
, "<a/>text");
2315 type
= XmlNodeType_None
;
2316 hr
= IXmlReader_Read(reader
, &type
);
2317 ok(hr
== S_OK
, "got %#x\n", hr
);
2318 ok(type
== XmlNodeType_Element
, "Unexpected type %d\n", type
);
2320 test_eof_state(reader
, FALSE
);
2322 type
= XmlNodeType_Element
;
2323 hr
= IXmlReader_Read(reader
, &type
);
2324 ok(hr
== WC_E_SYNTAX
, "got %#x\n", hr
);
2325 ok(type
== XmlNodeType_None
, "Unexpected type %d\n", type
);
2327 test_eof_state(reader
, FALSE
);
2329 hr
= IXmlReader_SetInput(reader
, NULL
);
2330 ok(hr
== S_OK
, "got %08x\n", hr
);
2332 IXmlReader_Release(reader
);
2335 static void test_max_element_depth(void)
2337 static const char *xml
=
2345 XmlNodeType nodetype
;
2350 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2351 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
2353 set_input_string(reader
, xml
);
2355 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_MaxElementDepth
, 2);
2356 ok(hr
== S_OK
, "got %08x\n", hr
);
2358 TEST_DEPTH(reader
, 0);
2360 hr
= IXmlReader_Read(reader
, NULL
);
2361 ok(hr
== S_OK
, "got %08x\n", hr
);
2363 TEST_DEPTH(reader
, 0);
2365 hr
= IXmlReader_Read(reader
, NULL
);
2366 ok(hr
== S_OK
, "got %08x\n", hr
);
2368 TEST_DEPTH(reader
, 1);
2369 TEST_READER_STATE(reader
, XmlReadState_Interactive
);
2371 hr
= IXmlReader_Read(reader
, NULL
);
2372 ok(hr
== SC_E_MAXELEMENTDEPTH
, "got %08x\n", hr
);
2374 TEST_DEPTH2(reader
, 0, 2);
2375 TEST_READER_STATE(reader
, XmlReadState_Error
);
2377 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_MaxElementDepth
, 10);
2378 ok(hr
== S_OK
, "got %08x\n", hr
);
2380 hr
= IXmlReader_Read(reader
, NULL
);
2381 ok(hr
== SC_E_MAXELEMENTDEPTH
, "got %08x\n", hr
);
2383 TEST_DEPTH2(reader
, 0, 2);
2384 TEST_READER_STATE(reader
, XmlReadState_Error
);
2386 /* test if stepping into attributes enforces depth limit too */
2387 set_input_string(reader
, xml
);
2389 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_MaxElementDepth
, 2);
2390 ok(hr
== S_OK
, "got %08x\n", hr
);
2392 TEST_DEPTH(reader
, 0);
2394 hr
= IXmlReader_Read(reader
, NULL
);
2395 ok(hr
== S_OK
, "got %08x\n", hr
);
2397 TEST_DEPTH(reader
, 0);
2399 hr
= IXmlReader_Read(reader
, NULL
);
2400 ok(hr
== S_OK
, "got %08x\n", hr
);
2402 TEST_DEPTH(reader
, 1);
2404 hr
= IXmlReader_MoveToFirstAttribute(reader
);
2405 ok(hr
== S_OK
, "got %08x\n", hr
);
2407 TEST_DEPTH(reader
, 2);
2408 TEST_READER_STATE(reader
, XmlReadState_Interactive
);
2411 hr
= IXmlReader_Read(reader
, &nodetype
);
2412 ok(hr
== SC_E_MAXELEMENTDEPTH
, "got %08x\n", hr
);
2413 ok(nodetype
== XmlNodeType_None
, "got node type %d\n", nodetype
);
2416 hr
= IXmlReader_Read(reader
, &nodetype
);
2417 ok(hr
== SC_E_MAXELEMENTDEPTH
, "got %08x\n", hr
);
2418 ok(nodetype
== XmlNodeType_None
, "got node type %d\n", nodetype
);
2420 TEST_DEPTH2(reader
, 0, 2);
2421 TEST_READER_STATE(reader
, XmlReadState_Error
);
2423 /* set max depth to 0, this disables depth limit */
2424 set_input_string(reader
, xml
);
2426 hr
= IXmlReader_SetProperty(reader
, XmlReaderProperty_MaxElementDepth
, 0);
2427 ok(hr
== S_OK
, "got %08x\n", hr
);
2430 while (IXmlReader_Read(reader
, NULL
) == S_OK
)
2432 ok(count
== 8, "Unexpected node number %u\n", count
);
2433 TEST_READER_STATE(reader
, XmlReadState_EndOfFile
);
2435 IXmlReader_Release(reader
);
2438 static void test_reader_position(void)
2440 static const char *xml
= "<c:a xmlns:c=\"nsdef c\" b=\"attr b\">\n</c:a>";
2446 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2447 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
2449 TEST_READER_STATE(reader
, XmlReadState_Closed
);
2451 /* position methods with Null args */
2452 hr
= IXmlReader_GetLineNumber(reader
, NULL
);
2453 ok(hr
== E_INVALIDARG
, "Expected E_INVALIDARG, got %08x\n", hr
);
2455 hr
= IXmlReader_GetLinePosition(reader
, NULL
);
2456 ok(hr
== E_INVALIDARG
, "Expected E_INVALIDARG, got %08x\n", hr
);
2459 hr
= IXmlReader_GetLinePosition(reader
, &position
);
2460 ok(hr
== S_FALSE
, "got %#x\n", hr
);
2461 ok(position
== 0, "got %u\n", position
);
2464 hr
= IXmlReader_GetLineNumber(reader
, &position
);
2465 ok(hr
== S_FALSE
, "got %#x\n", hr
);
2466 ok(position
== 0, "got %u\n", position
);
2468 set_input_string(reader
, xml
);
2470 TEST_READER_STATE(reader
, XmlReadState_Initial
);
2471 TEST_READER_POSITION(reader
, 0, 0);
2472 hr
= IXmlReader_Read(reader
, &type
);
2473 ok(hr
== S_OK
, "got %08x\n", hr
);
2474 ok(type
== XmlNodeType_Element
, "got type %d\n", type
);
2475 TEST_READER_POSITION2(reader
, 1, 2, ~0u, 34);
2477 next_attribute(reader
);
2478 TEST_READER_POSITION2(reader
, 1, 6, ~0u, 34);
2480 next_attribute(reader
);
2481 TEST_READER_POSITION2(reader
, 1, 24, ~0u, 34);
2483 move_to_element(reader
);
2484 TEST_READER_POSITION2(reader
, 1, 2, ~0u, 34);
2486 hr
= IXmlReader_Read(reader
, &type
);
2487 ok(hr
== S_OK
, "got %08x\n", hr
);
2488 ok(type
== XmlNodeType_Whitespace
, "got type %d\n", type
);
2489 TEST_READER_POSITION2(reader
, 1, 35, 2, 6);
2491 hr
= IXmlReader_Read(reader
, &type
);
2492 ok(hr
== S_OK
, "got %08x\n", hr
);
2493 ok(type
== XmlNodeType_EndElement
, "got type %d\n", type
);
2494 TEST_READER_POSITION2(reader
, 2, 3, 2, 6);
2496 hr
= IXmlReader_SetInput(reader
, NULL
);
2497 ok(hr
== S_OK
, "got %08x\n", hr
);
2498 TEST_READER_STATE2(reader
, XmlReadState_Initial
, XmlReadState_Closed
);
2499 TEST_READER_POSITION(reader
, 0, 0);
2501 IXmlReader_Release(reader
);
2504 static void test_string_pointers(void)
2506 const WCHAR
*ns
, *nsq
, *empty
, *xmlns_ns
, *xmlns_name
, *name
, *p
, *q
, *xml
, *ptr
, *value
;
2510 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2511 ok(hr
== S_OK
, "S_OK, got %08x\n", hr
);
2513 set_input_string(reader
, "<elem xmlns=\"myns\">myns<elem2 /></elem>");
2515 read_node(reader
, XmlNodeType_Element
);
2516 empty
= reader_value(reader
, "");
2517 ok(empty
== reader_prefix(reader
, ""), "empty != prefix\n");
2518 name
= reader_name(reader
, "elem");
2519 ok(name
== reader_qname(reader
, "elem"), "name != qname\n");
2520 ns
= reader_namespace(reader
, "myns");
2522 next_attribute(reader
);
2523 ptr
= reader_value(reader
, "myns");
2526 win_skip("attr value is different than namespace pointer, assuming old xmllite\n");
2527 IXmlReader_Release(reader
);
2530 ok(ns
== ptr
, "ns != value\n");
2531 ok(empty
== reader_prefix(reader
, ""), "empty != prefix\n");
2532 xmlns_ns
= reader_namespace(reader
, "http://www.w3.org/2000/xmlns/");
2533 xmlns_name
= reader_name(reader
, "xmlns");
2534 ok(xmlns_name
== reader_qname(reader
, "xmlns"), "xmlns_name != qname\n");
2536 read_node(reader
, XmlNodeType_Text
);
2537 ok(ns
!= reader_value(reader
, "myns"), "ns == value\n");
2538 ok(empty
== reader_prefix(reader
, ""), "empty != prefix\n");
2539 ok(empty
== reader_namespace(reader
, ""), "empty != namespace\n");
2540 ok(empty
== reader_name(reader
, ""), "empty != name\n");
2541 ok(empty
== reader_qname(reader
, ""), "empty != qname\n");
2543 read_node(reader
, XmlNodeType_Element
);
2544 ok(empty
== reader_prefix(reader
, ""), "empty != prefix\n");
2545 ok(ns
== reader_namespace(reader
, "myns"), "empty != namespace\n");
2547 read_node(reader
, XmlNodeType_EndElement
);
2548 ok(empty
== reader_prefix(reader
, ""), "empty != prefix\n");
2549 ok(name
== reader_name(reader
, "elem"), "empty != name\n");
2550 ok(name
== reader_qname(reader
, "elem"), "empty != qname\n");
2551 ok(ns
== reader_namespace(reader
, "myns"), "empty != namespace\n");
2553 set_input_string(reader
, "<elem xmlns:p=\"myns\" xmlns:q=\"mynsq\"><p:elem2 q:attr=\"\"></p:elem2></elem>");
2555 read_node(reader
, XmlNodeType_Element
);
2556 ok(empty
== reader_prefix(reader
, ""), "empty != prefix\n");
2557 name
= reader_name(reader
, "elem");
2558 ok(empty
== reader_namespace(reader
, ""), "empty != namespace\n");
2560 next_attribute(reader
);
2561 ns
= reader_value(reader
, "myns");
2562 ok(xmlns_name
== reader_prefix(reader
, "xmlns"), "xmlns_name != prefix\n");
2563 p
= reader_name(reader
, "p");
2564 ok(xmlns_ns
== reader_namespace(reader
, "http://www.w3.org/2000/xmlns/"), "xmlns_ns != namespace\n");
2566 next_attribute(reader
);
2567 nsq
= reader_value(reader
, "mynsq");
2568 ok(xmlns_name
== reader_prefix(reader
, "xmlns"), "xmlns_name != prefix\n");
2569 q
= reader_name(reader
, "q");
2570 ok(xmlns_ns
== reader_namespace(reader
, "http://www.w3.org/2000/xmlns/"), "xmlns_ns != namespace\n");
2572 read_node(reader
, XmlNodeType_Element
);
2573 ok(p
== reader_prefix(reader
, "p"), "p != prefix\n");
2574 ok(ns
== reader_namespace(reader
, "myns"), "empty != namespace\n");
2575 name
= reader_qname(reader
, "p:elem2");
2577 next_attribute(reader
);
2578 ok(empty
!= reader_value(reader
, ""), "empty == value\n");
2579 ok(q
== reader_prefix(reader
, "q"), "q != prefix\n");
2580 ok(nsq
== reader_namespace(reader
, "mynsq"), "nsq != namespace\n");
2582 read_node(reader
, XmlNodeType_EndElement
);
2583 ptr
= reader_qname(reader
, "p:elem2"); todo_wine
ok(name
!= ptr
, "q == qname\n");
2585 set_input_string(reader
, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
2587 read_node(reader
, XmlNodeType_XmlDeclaration
);
2588 ok(empty
== reader_value(reader
, ""), "empty != value\n");
2589 ok(empty
== reader_prefix(reader
, ""), "empty != prefix\n");
2590 xml
= reader_name(reader
, "xml");
2591 ptr
= reader_qname(reader
, "xml"); todo_wine
ok(xml
== ptr
, "xml != qname\n");
2592 ok(empty
== reader_namespace(reader
, ""), "empty != namespace\n");
2594 next_attribute(reader
);
2595 ok(empty
== reader_prefix(reader
, ""), "empty != prefix\n");
2596 ok(empty
== reader_namespace(reader
, ""), "empty != namespace\n");
2598 set_input_string(reader
, "<elem xmlns:p=\"myns\"><p:elem2 attr=\"\" /></elem>");
2600 read_node(reader
, XmlNodeType_Element
);
2601 next_attribute(reader
);
2602 read_value_char(reader
, 'm');
2603 p
= reader_value(reader
, "yns");
2605 read_node(reader
, XmlNodeType_Element
);
2606 ns
= reader_namespace(reader
, "myns");
2607 ok(ns
+1 == p
, "ns+1 != p\n");
2609 set_input_string(reader
, "<elem attr=\"value\"></elem>");
2611 read_node(reader
, XmlNodeType_Element
);
2612 next_attribute(reader
);
2613 name
= reader_name(reader
, "attr");
2614 value
= reader_value(reader
, "value");
2616 move_to_element(reader
);
2617 next_attribute(reader
);
2618 ok(name
== reader_name(reader
, "attr"), "attr pointer changed\n");
2619 ok(value
== reader_value(reader
, "value"), "value pointer changed\n");
2621 IXmlReader_Release(reader
);
2626 test_reader_create();
2628 test_reader_state();
2629 test_read_attribute();
2631 test_read_comment();
2633 test_read_system_dtd();
2634 test_read_public_dtd();
2635 test_read_element();
2636 test_isemptyelement();
2639 test_read_pending();
2640 test_readvaluechunk();
2641 test_read_xmldeclaration();
2642 test_reader_properties();
2644 test_namespaceuri();
2645 test_read_charref();
2646 test_encoding_detection();
2648 test_max_element_depth();
2649 test_reader_position();
2650 test_string_pointers();