4 * Copyright 2008 Piotr Caban
5 * Copyright 2011 Thomas Mullaly
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "msxml2did.h"
35 #include "wine/test.h"
37 #define EXPECT_HR(hr,hr_exp) \
38 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
40 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
41 static void _expect_ref(IUnknown
* obj
, ULONG ref
, int line
)
43 ULONG rc
= IUnknown_AddRef(obj
);
44 IUnknown_Release(obj
);
45 ok_(__FILE__
,line
)(rc
-1 == ref
, "expected refcount %d, got %d\n", ref
, rc
-1);
48 static BSTR
alloc_str_from_narrow(const char *str
)
50 int len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
51 BSTR ret
= SysAllocStringLen(NULL
, len
- 1); /* NUL character added automatically */
52 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, len
);
56 static BSTR alloced_bstrs
[512];
57 static int alloced_bstrs_count
;
59 static BSTR
_bstr_(const char *str
)
61 assert(alloced_bstrs_count
< sizeof(alloced_bstrs
)/sizeof(alloced_bstrs
[0]));
62 alloced_bstrs
[alloced_bstrs_count
] = alloc_str_from_narrow(str
);
63 return alloced_bstrs
[alloced_bstrs_count
++];
66 static void free_bstrs(void)
69 for (i
= 0; i
< alloced_bstrs_count
; i
++)
70 SysFreeString(alloced_bstrs
[i
]);
71 alloced_bstrs_count
= 0;
76 CH_PUTDOCUMENTLOCATOR
,
79 CH_STARTPREFIXMAPPING
,
84 CH_IGNORABLEWHITESPACE
,
85 CH_PROCESSINGINSTRUCTION
,
92 static const WCHAR szSimpleXML
[] = {
93 '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\"','1','.','0','\"',' ','?','>','\n',
94 '<','B','a','n','k','A','c','c','o','u','n','t','>','\n',
95 ' ',' ',' ','<','N','u','m','b','e','r','>','1','2','3','4','<','/','N','u','m','b','e','r','>','\n',
96 ' ',' ',' ','<','N','a','m','e','>','C','a','p','t','a','i','n',' ','A','h','a','b','<','/','N','a','m','e','>','\n',
97 '<','/','B','a','n','k','A','c','c','o','u','n','t','>','\n','\0'
100 static const WCHAR szCarriageRetTest
[] = {
101 '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"','?','>','\r','\n',
102 '<','B','a','n','k','A','c','c','o','u','n','t','>','\r','\n',
103 '\t','<','N','u','m','b','e','r','>','1','2','3','4','<','/','N','u','m','b','e','r','>','\r','\n',
104 '\t','<','N','a','m','e','>','C','a','p','t','a','i','n',' ','A','h','a','b','<','/','N','a','m','e','>','\r','\n',
105 '<','/','B','a','n','k','A','c','c','o','u','n','t','>','\r','\n','\0'
108 static const WCHAR szUtf16XML
[] = {
109 '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"',' ',
110 'e','n','c','o','d','i','n','g','=','"','U','T','F','-','1','6','"',' ',
111 's','t','a','n','d','a','l','o','n','e','=','"','n','o','"','?','>','\r','\n'
114 static const CHAR szUtf16BOM
[] = {0xff, 0xfe};
116 static const CHAR szUtf8XML
[] =
117 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n";
119 static const char utf8xml2
[] =
120 "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\r\n";
122 static const CHAR szTestXML
[] =
123 "<?xml version=\"1.0\" ?>\n"
125 " <Number>1234</Number>\n"
126 " <Name>Captain Ahab</Name>\n"
129 static const CHAR szTestAttributes
[] =
130 "<?xml version=\"1.0\" ?>\n"
131 "<document xmlns:test=\"prefix_test\" xmlns=\"prefix\" test:arg1=\"arg1\" arg2=\"arg2\" test:ar3=\"arg3\">\n"
132 "<node1 xmlns:p=\"test\" />"
135 typedef struct _contenthandlercheck
{
145 } content_handler_test
;
147 static content_handler_test contentHandlerTest1
[] = {
148 { CH_PUTDOCUMENTLOCATOR
, 0, 0, 1, 0 },
149 { CH_STARTDOCUMENT
, 0, 0, 1, 22 },
150 { CH_STARTELEMENT
, 2, 14, 2, 13, "", "BankAccount", "BankAccount" },
151 { CH_CHARACTERS
, 2, 14, 3, 4, "\n " },
152 { CH_STARTELEMENT
, 3, 12, 3, 11, "", "Number", "Number" },
153 { CH_CHARACTERS
, 3, 12, 3, 16, "1234" },
154 { CH_ENDELEMENT
, 3, 18, 3, 24, "", "Number", "Number" },
155 { CH_CHARACTERS
, 3, 25, 4, 4, "\n " },
156 { CH_STARTELEMENT
, 4, 10, 4, 9, "", "Name", "Name" },
157 { CH_CHARACTERS
, 4, 10, 4, 22, "Captain Ahab" },
158 { CH_ENDELEMENT
, 4, 24, 4, 28, "", "Name", "Name" },
159 { CH_CHARACTERS
, 4, 29, 5, 1, "\n" },
160 { CH_ENDELEMENT
, 5, 3, 5, 14, "", "BankAccount", "BankAccount" },
161 { CH_ENDDOCUMENT
, 0, 0, 6, 0 },
165 static content_handler_test contentHandlerTest2
[] = {
166 { CH_PUTDOCUMENTLOCATOR
, 0, 0, 1, 0 },
167 { CH_STARTDOCUMENT
, 0, 0, 1, 21 },
168 { CH_STARTELEMENT
, 2, 14, 2, 13, "", "BankAccount", "BankAccount" },
169 { CH_CHARACTERS
, 2, 14, 3, 0, "\n" },
170 { CH_CHARACTERS
, 2, 16, 3, 2, "\t" },
171 { CH_STARTELEMENT
, 3, 10, 3, 9, "", "Number", "Number" },
172 { CH_CHARACTERS
, 3, 10, 3, 14, "1234" },
173 { CH_ENDELEMENT
, 3, 16, 3, 22, "", "Number", "Number" },
174 { CH_CHARACTERS
, 3, 23, 4, 0, "\n" },
175 { CH_CHARACTERS
, 3, 25, 4, 2, "\t" },
176 { CH_STARTELEMENT
, 4, 8, 4, 7, "", "Name", "Name" },
177 { CH_CHARACTERS
, 4, 8, 4, 20, "Captain Ahab" },
178 { CH_ENDELEMENT
, 4, 22, 4, 26, "", "Name", "Name" },
179 { CH_CHARACTERS
, 4, 27, 5, 0, "\n" },
180 { CH_ENDELEMENT
, 5, 3, 5, 14, "", "BankAccount", "BankAccount" },
181 { CH_ENDDOCUMENT
, 0, 0, 6, 0 },
185 static content_handler_test contentHandlerTestError
[] = {
186 { CH_PUTDOCUMENTLOCATOR
, 0, 0, 1, 0, NULL
, NULL
, NULL
, E_FAIL
},
187 { EH_FATALERROR
, 0, 0, 0, 0, NULL
, NULL
, NULL
, E_FAIL
},
191 static content_handler_test contentHandlerTestCallbackResults
[] = {
192 { CH_PUTDOCUMENTLOCATOR
, 0, 0, 1, 0, NULL
, NULL
, NULL
, S_FALSE
},
193 { CH_STARTDOCUMENT
, 0, 0, 1, 22, NULL
, NULL
, NULL
, S_FALSE
},
194 { EH_FATALERROR
, 0, 0, 0, 0, NULL
, NULL
, NULL
, S_FALSE
},
198 static content_handler_test contentHandlerTestCallbackResult6
[] = {
199 { CH_PUTDOCUMENTLOCATOR
, 0, 0, 1, 0, NULL
, NULL
, NULL
, S_FALSE
},
200 { CH_STARTDOCUMENT
, 0, 0, 1, 22, NULL
, NULL
, NULL
, S_FALSE
},
201 { CH_STARTELEMENT
, 2, 14, 2, 13, "", "BankAccount", "BankAccount", S_FALSE
},
202 { CH_CHARACTERS
, 2, 14, 3, 4, "\n ", NULL
, NULL
, S_FALSE
},
203 { CH_STARTELEMENT
, 3, 12, 3, 11, "", "Number", "Number", S_FALSE
},
204 { CH_CHARACTERS
, 3, 12, 3, 16, "1234", NULL
, NULL
, S_FALSE
},
205 { CH_ENDELEMENT
, 3, 18, 3, 24, "", "Number", "Number", S_FALSE
},
206 { CH_CHARACTERS
, 3, 25, 4, 4, "\n ", NULL
, NULL
, S_FALSE
},
207 { CH_STARTELEMENT
, 4, 10, 4, 9, "", "Name", "Name", S_FALSE
},
208 { CH_CHARACTERS
, 4, 10, 4, 22, "Captain Ahab", NULL
, NULL
, S_FALSE
},
209 { CH_ENDELEMENT
, 4, 24, 4, 28, "", "Name", "Name", S_FALSE
},
210 { CH_CHARACTERS
, 4, 29, 5, 1, "\n", NULL
, NULL
, S_FALSE
},
211 { CH_ENDELEMENT
, 5, 3, 5, 14, "", "BankAccount", "BankAccount", S_FALSE
},
212 { CH_ENDDOCUMENT
, 0, 0, 6, 0, NULL
, NULL
, NULL
, S_FALSE
},
216 static content_handler_test contentHandlerTestAttributes
[] = {
217 { CH_PUTDOCUMENTLOCATOR
, 0, 0, 1, 0 },
218 { CH_STARTDOCUMENT
, 0, 0, 1, 22 },
219 { CH_STARTPREFIXMAPPING
, 2, 96, 2, 95, "test", "prefix_test" },
220 { CH_STARTPREFIXMAPPING
, 2, 96, 2, 95, "", "prefix" },
221 { CH_STARTELEMENT
, 2, 96, 2, 95, "prefix", "document", "document" },
222 { CH_CHARACTERS
, 2, 96, 3, 1, "\n" },
223 { CH_STARTPREFIXMAPPING
, 3, 25, 3, 24, "p", "test" },
224 { CH_STARTELEMENT
, 3, 25, 3, 24, "prefix", "node1", "node1" },
225 { CH_ENDELEMENT
, 3, 25, 3, 24, "prefix", "node1", "node1" },
226 { CH_ENDPREFIXMAPPING
, 3, 25, 3, 24, "p" },
227 { CH_ENDELEMENT
, 3, 27, 3, 35, "prefix", "document", "document" },
228 { CH_ENDPREFIXMAPPING
, 3, 27, 3, 35, "" },
229 { CH_ENDPREFIXMAPPING
, 3, 27, 3, 35, "test" },
230 { CH_ENDDOCUMENT
, 0, 0, 4, 0 },
234 static content_handler_test contentHandlerTestAttributes6
[] = {
235 { CH_PUTDOCUMENTLOCATOR
, 0, 0, 1, 0 },
236 { CH_STARTDOCUMENT
, 0, 0, 1, 22 },
237 { CH_STARTPREFIXMAPPING
, 2, 96, 2, 95, "test", "prefix_test" },
238 { CH_STARTPREFIXMAPPING
, 2, 96, 2, 95, "", "prefix" },
239 { CH_STARTELEMENT
, 2, 96, 2, 95, "prefix", "document", "document" },
240 { CH_CHARACTERS
, 2, 96, 3, 1, "\n" },
241 { CH_STARTPREFIXMAPPING
, 3, 25, 3, 24, "p", "test" },
242 { CH_STARTELEMENT
, 3, 25, 3, 24, "prefix", "node1", "node1" },
243 { CH_ENDELEMENT
, 3, 25, 3, 24, "prefix", "node1", "node1" },
244 { CH_ENDPREFIXMAPPING
, 3, 25, 3, 24, "p" },
245 { CH_ENDELEMENT
, 3, 27, 3, 35, "prefix", "document", "document" },
246 { CH_ENDPREFIXMAPPING
, 3, 27, 3, 35, "test" },
247 { CH_ENDPREFIXMAPPING
, 3, 27, 3, 35, "" },
248 { CH_ENDDOCUMENT
, 0, 0, 4, 0 },
252 static content_handler_test xmlspaceattr_test
[] = {
253 { CH_PUTDOCUMENTLOCATOR
, 0, 0, 1, 0 },
254 { CH_STARTDOCUMENT
, 0, 0, 1, 39 },
255 { CH_STARTELEMENT
, 1, 64, 1, 63, "", "a", "a" },
256 { CH_CHARACTERS
, 1, 64, 1, 80, " Some text data " },
257 { CH_ENDELEMENT
, 1, 82, 1, 83, "", "a", "a" },
258 { CH_ENDDOCUMENT
, 0, 0, 1, 83 },
262 static const char xmlspace_attr
[] =
263 "<?xml version=\"1.0\" encoding=\"UTF-16\"?>"
264 "<a xml:space=\"preserve\"> Some text data </a>";
266 static content_handler_test
*expectCall
;
267 static ISAXLocator
*locator
;
270 static void test_saxstr(unsigned line
, const WCHAR
*szStr
, int nStr
, const char *szTest
)
276 ok_(__FILE__
,line
) (szStr
== NULL
, "szStr != NULL\n");
277 ok_(__FILE__
,line
) (nStr
== 0, "nStr = %d, expected 0\n", nStr
);
281 len
= strlen(szTest
);
282 ok_(__FILE__
,line
) (len
== nStr
, "nStr = %d, expected %d (%s)\n", nStr
, len
, szTest
);
284 ok_(__FILE__
,line
)(0, "got string %s, expected %s\n", wine_dbgstr_wn(szStr
, nStr
), szTest
);
288 MultiByteToWideChar(CP_ACP
, 0, szTest
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
289 ok_(__FILE__
,line
) (!memcmp(szStr
, buf
, len
*sizeof(WCHAR
)), "unexpected szStr %s, expected %s\n",
290 wine_dbgstr_wn(szStr
, nStr
), szTest
);
293 static BOOL
test_expect_call(CH id
)
295 ok(expectCall
->id
== id
, "unexpected call %d, expected %d\n", id
, expectCall
->id
);
296 return expectCall
->id
== id
;
299 static void test_locator(unsigned line
, int loc_line
, int loc_column
)
302 ISAXLocator_getLineNumber(locator
, &rline
);
303 ISAXLocator_getColumnNumber(locator
, &rcolumn
);
305 ok_(__FILE__
,line
) (rline
== loc_line
,
306 "unexpected line %d, expected %d\n", rline
, loc_line
);
307 ok_(__FILE__
,line
) (rcolumn
== loc_column
,
308 "unexpected column %d, expected %d\n", rcolumn
, loc_column
);
311 static HRESULT WINAPI
contentHandler_QueryInterface(
312 ISAXContentHandler
* iface
,
318 if(IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_ISAXContentHandler
))
324 return E_NOINTERFACE
;
330 static ULONG WINAPI
contentHandler_AddRef(
331 ISAXContentHandler
* iface
)
336 static ULONG WINAPI
contentHandler_Release(
337 ISAXContentHandler
* iface
)
342 static HRESULT WINAPI
contentHandler_putDocumentLocator(
343 ISAXContentHandler
* iface
,
344 ISAXLocator
*pLocator
)
348 if(!test_expect_call(CH_PUTDOCUMENTLOCATOR
))
352 test_locator(__LINE__
, msxml_version
>=6 ? expectCall
->line_v6
: expectCall
->line
,
353 msxml_version
>=6 ? expectCall
->column_v6
: expectCall
->column
);
355 if(msxml_version
>= 6) {
356 ISAXAttributes
*attr
, *attr1
;
357 IMXAttributes
*mxattr
;
359 EXPECT_REF(pLocator
, 1);
360 hr
= ISAXLocator_QueryInterface(pLocator
, &IID_ISAXAttributes
, (void**)&attr
);
362 EXPECT_REF(pLocator
, 2);
363 hr
= ISAXLocator_QueryInterface(pLocator
, &IID_ISAXAttributes
, (void**)&attr1
);
365 EXPECT_REF(pLocator
, 3);
366 ok(attr
== attr1
, "got %p, %p\n", attr
, attr1
);
368 hr
= ISAXAttributes_QueryInterface(attr
, &IID_IMXAttributes
, (void**)&mxattr
);
369 EXPECT_HR(hr
, E_NOINTERFACE
);
371 ISAXAttributes_Release(attr
);
372 ISAXAttributes_Release(attr1
);
375 return (expectCall
++)->ret
;
378 static ISAXAttributes
*test_attr_ptr
;
379 static HRESULT WINAPI
contentHandler_startDocument(
380 ISAXContentHandler
* iface
)
382 if(!test_expect_call(CH_STARTDOCUMENT
))
385 test_attr_ptr
= NULL
;
386 test_locator(__LINE__
, msxml_version
>=6 ? expectCall
->line_v6
: expectCall
->line
,
387 msxml_version
>=6 ? expectCall
->column_v6
: expectCall
->column
);
389 return (expectCall
++)->ret
;
392 static HRESULT WINAPI
contentHandler_endDocument(
393 ISAXContentHandler
* iface
)
395 if(!test_expect_call(CH_ENDDOCUMENT
))
398 if(expectCall
== xmlspaceattr_test
+5 && msxml_version
>=6) {
400 test_locator(__LINE__
, expectCall
->line_v6
, expectCall
->column_v6
);
403 test_locator(__LINE__
, msxml_version
>=6 ? expectCall
->line_v6
: expectCall
->line
,
404 msxml_version
>=6 ? expectCall
->column_v6
: expectCall
->column
);
406 return (expectCall
++)->ret
;
409 static HRESULT WINAPI
contentHandler_startPrefixMapping(
410 ISAXContentHandler
* iface
,
411 const WCHAR
*pPrefix
,
416 if(!test_expect_call(CH_STARTPREFIXMAPPING
))
419 test_saxstr(__LINE__
, pPrefix
, nPrefix
, expectCall
->arg1
);
420 test_saxstr(__LINE__
, pUri
, nUri
, expectCall
->arg2
);
421 test_locator(__LINE__
, msxml_version
>=6 ? expectCall
->line_v6
: expectCall
->line
,
422 msxml_version
>=6 ? expectCall
->column_v6
: expectCall
->column
);
424 return (expectCall
++)->ret
;
427 static HRESULT WINAPI
contentHandler_endPrefixMapping(
428 ISAXContentHandler
* iface
,
429 const WCHAR
*pPrefix
,
432 if(!test_expect_call(CH_ENDPREFIXMAPPING
))
435 test_saxstr(__LINE__
, pPrefix
, nPrefix
, expectCall
->arg1
);
436 test_locator(__LINE__
, msxml_version
>=6 ? expectCall
->line_v6
: expectCall
->line
,
437 msxml_version
>=6 ? expectCall
->column_v6
: expectCall
->column
);
439 return (expectCall
++)->ret
;
442 static HRESULT WINAPI
contentHandler_startElement(
443 ISAXContentHandler
* iface
,
444 const WCHAR
*pNamespaceUri
,
446 const WCHAR
*pLocalName
,
450 ISAXAttributes
*pAttr
)
455 if(!test_expect_call(CH_STARTELEMENT
))
458 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, expectCall
->arg1
);
459 test_saxstr(__LINE__
, pLocalName
, nLocalName
, expectCall
->arg2
);
460 test_saxstr(__LINE__
, pQName
, nQName
, expectCall
->arg3
);
461 test_locator(__LINE__
, msxml_version
>=6 ? expectCall
->line_v6
: expectCall
->line
,
462 msxml_version
>=6 ? expectCall
->column_v6
: expectCall
->column
);
465 test_attr_ptr
= pAttr
;
466 ok(test_attr_ptr
== pAttr
, "Multiple ISAXAttributes instances are used (%p %p)\n", test_attr_ptr
, pAttr
);
468 if(expectCall
== contentHandlerTestAttributes
+4) {
469 const WCHAR
*uri_ptr
= NULL
;
471 /* msxml3 returns attributes and namespaces in the input order */
472 hres
= ISAXAttributes_getLength(pAttr
, &len
);
473 ok(hres
== S_OK
, "getLength returned %x\n", hres
);
474 ok(len
== 5, "Incorrect number of attributes: %d\n", len
);
475 ok(msxml_version
< 6, "wrong msxml_version: %d\n", msxml_version
);
477 for(i
=0; i
<len
; i
++) {
478 hres
= ISAXAttributes_getName(pAttr
, i
, &pNamespaceUri
, &nNamespaceUri
,
479 &pLocalName
, &nLocalName
, &pQName
, &nQName
);
480 ok(hres
== S_OK
, "getName returned %x\n", hres
);
483 todo_wine
ok(i
==3, "Incorrect attributes order\n");
484 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, "");
485 test_saxstr(__LINE__
, pLocalName
, nLocalName
, "arg2");
486 test_saxstr(__LINE__
, pQName
, nQName
, "arg2");
487 } else if(nQName
== 5) {
488 todo_wine
ok(i
==1, "Incorrect attributes order\n");
489 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, "");
490 test_saxstr(__LINE__
, pLocalName
, nLocalName
, "");
491 test_saxstr(__LINE__
, pQName
, nQName
, "xmlns");
492 } else if(nQName
== 8) {
493 todo_wine
ok(i
==4, "Incorrect attributes order\n");
494 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, "prefix_test");
495 test_saxstr(__LINE__
, pLocalName
, nLocalName
, "ar3");
496 test_saxstr(__LINE__
, pQName
, nQName
, "test:ar3");
497 ok(uri_ptr
== pNamespaceUri
, "Incorrect NamespaceUri pointer\n");
498 } else if(nQName
== 9) {
499 todo_wine
ok(i
==2, "Incorrect attributes order\n");
500 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, "prefix_test");
501 test_saxstr(__LINE__
, pLocalName
, nLocalName
, "arg1");
502 test_saxstr(__LINE__
, pQName
, nQName
, "test:arg1");
503 uri_ptr
= pNamespaceUri
;
504 } else if(nQName
== 10) {
505 todo_wine
ok(i
==0, "Incorrect attributes order\n");
506 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, "");
507 test_saxstr(__LINE__
, pLocalName
, nLocalName
, "");
508 test_saxstr(__LINE__
, pQName
, nQName
, "xmlns:test");
510 ok(0, "Unexpected attribute\n");
513 } else if(expectCall
== contentHandlerTestAttributes6
+4) {
514 const WCHAR
*uri_ptr
;
516 /* msxml6 returns attributes first and then namespaces */
517 hres
= ISAXAttributes_getLength(pAttr
, &len
);
518 ok(hres
== S_OK
, "getLength returned %x\n", hres
);
519 ok(len
== 5, "Incorrect number of attributes: %d\n", len
);
520 ok(msxml_version
>= 6, "wrong msxml_version: %d\n", msxml_version
);
522 hres
= ISAXAttributes_getName(pAttr
, 0, &pNamespaceUri
, &nNamespaceUri
,
523 &pLocalName
, &nLocalName
, &pQName
, &nQName
);
524 ok(hres
== S_OK
, "getName returned %x\n", hres
);
525 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, "prefix_test");
526 test_saxstr(__LINE__
, pLocalName
, nLocalName
, "arg1");
527 test_saxstr(__LINE__
, pQName
, nQName
, "test:arg1");
528 uri_ptr
= pNamespaceUri
;
530 hres
= ISAXAttributes_getName(pAttr
, 1, &pNamespaceUri
, &nNamespaceUri
,
531 &pLocalName
, &nLocalName
, &pQName
, &nQName
);
532 ok(hres
== S_OK
, "getName returned %x\n", hres
);
533 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, "");
534 test_saxstr(__LINE__
, pLocalName
, nLocalName
, "arg2");
535 test_saxstr(__LINE__
, pQName
, nQName
, "arg2");
537 hres
= ISAXAttributes_getName(pAttr
, 2, &pNamespaceUri
, &nNamespaceUri
,
538 &pLocalName
, &nLocalName
, &pQName
, &nQName
);
539 ok(hres
== S_OK
, "getName returned %x\n", hres
);
540 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, "prefix_test");
541 test_saxstr(__LINE__
, pLocalName
, nLocalName
, "ar3");
542 test_saxstr(__LINE__
, pQName
, nQName
, "test:ar3");
543 ok(uri_ptr
== pNamespaceUri
, "Incorrect NamespaceUri pointer\n");
545 hres
= ISAXAttributes_getName(pAttr
, 3, &pNamespaceUri
, &nNamespaceUri
,
546 &pLocalName
, &nLocalName
, &pQName
, &nQName
);
547 ok(hres
== S_OK
, "getName returned %x\n", hres
);
548 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, "http://www.w3.org/2000/xmlns/");
549 test_saxstr(__LINE__
, pLocalName
, nLocalName
, "");
550 test_saxstr(__LINE__
, pQName
, nQName
, "xmlns:test");
552 hres
= ISAXAttributes_getName(pAttr
, 4, &pNamespaceUri
, &nNamespaceUri
,
553 &pLocalName
, &nLocalName
, &pQName
, &nQName
);
554 ok(hres
== S_OK
, "getName returned %x\n", hres
);
555 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, "http://www.w3.org/2000/xmlns/");
556 test_saxstr(__LINE__
, pLocalName
, nLocalName
, "");
557 test_saxstr(__LINE__
, pQName
, nQName
, "xmlns");
558 } else if(expectCall
== xmlspaceattr_test
+2) {
562 hres
= ISAXAttributes_getLength(pAttr
, &len
);
563 EXPECT_HR(hres
, S_OK
);
564 ok(len
== 1, "Incorrect number of attributes: %d\n", len
);
566 hres
= ISAXAttributes_getName(pAttr
, 0, &pNamespaceUri
, &nNamespaceUri
,
567 &pLocalName
, &nLocalName
, &pQName
, &nQName
);
568 EXPECT_HR(hres
, S_OK
);
569 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, "http://www.w3.org/XML/1998/namespace");
570 test_saxstr(__LINE__
, pLocalName
, nLocalName
, "space");
571 test_saxstr(__LINE__
, pQName
, nQName
, "xml:space");
573 hres
= ISAXAttributes_getValue(pAttr
, 0, &value
, &valuelen
);
574 EXPECT_HR(hres
, S_OK
);
575 test_saxstr(__LINE__
, value
, valuelen
, "preserve");
578 return (expectCall
++)->ret
;
581 static HRESULT WINAPI
contentHandler_endElement(
582 ISAXContentHandler
* iface
,
583 const WCHAR
*pNamespaceUri
,
585 const WCHAR
*pLocalName
,
590 if(!test_expect_call(CH_ENDELEMENT
))
593 test_saxstr(__LINE__
, pNamespaceUri
, nNamespaceUri
, expectCall
->arg1
);
594 test_saxstr(__LINE__
, pLocalName
, nLocalName
, expectCall
->arg2
);
595 test_saxstr(__LINE__
, pQName
, nQName
, expectCall
->arg3
);
596 test_locator(__LINE__
, msxml_version
>=6 ? expectCall
->line_v6
: expectCall
->line
,
597 msxml_version
>=6 ? expectCall
->column_v6
: expectCall
->column
);
599 return (expectCall
++)->ret
;
602 static HRESULT WINAPI
contentHandler_characters(
603 ISAXContentHandler
* iface
,
607 if(!test_expect_call(CH_CHARACTERS
))
610 test_saxstr(__LINE__
, pChars
, nChars
, expectCall
->arg1
);
611 test_locator(__LINE__
, msxml_version
>=6 ? expectCall
->line_v6
: expectCall
->line
,
612 msxml_version
>=6 ? expectCall
->column_v6
: expectCall
->column
);
614 return (expectCall
++)->ret
;
617 static HRESULT WINAPI
contentHandler_ignorableWhitespace(
618 ISAXContentHandler
* iface
,
622 if(!test_expect_call(CH_IGNORABLEWHITESPACE
))
625 test_saxstr(__LINE__
, pChars
, nChars
, expectCall
->arg1
);
626 test_locator(__LINE__
, msxml_version
>=6 ? expectCall
->line_v6
: expectCall
->line
,
627 msxml_version
>=6 ? expectCall
->column_v6
: expectCall
->column
);
629 return (expectCall
++)->ret
;
632 static HRESULT WINAPI
contentHandler_processingInstruction(
633 ISAXContentHandler
* iface
,
634 const WCHAR
*pTarget
,
639 if(!test_expect_call(CH_PROCESSINGINSTRUCTION
))
642 test_saxstr(__LINE__
, pTarget
, nTarget
, expectCall
->arg1
);
643 test_saxstr(__LINE__
, pData
, nData
, expectCall
->arg2
);
644 test_locator(__LINE__
, msxml_version
>=6 ? expectCall
->line_v6
: expectCall
->line
,
645 msxml_version
>=6 ? expectCall
->column_v6
: expectCall
->column
);
647 return (expectCall
++)->ret
;
650 static HRESULT WINAPI
contentHandler_skippedEntity(
651 ISAXContentHandler
* iface
,
655 if(!test_expect_call(CH_SKIPPEDENTITY
))
658 test_saxstr(__LINE__
, pName
, nName
, expectCall
->arg1
);
659 test_locator(__LINE__
, msxml_version
>=6 ? expectCall
->line_v6
: expectCall
->line
,
660 msxml_version
>=6 ? expectCall
->column_v6
: expectCall
->column
);
662 return (expectCall
++)->ret
;
666 static const ISAXContentHandlerVtbl contentHandlerVtbl
=
668 contentHandler_QueryInterface
,
669 contentHandler_AddRef
,
670 contentHandler_Release
,
671 contentHandler_putDocumentLocator
,
672 contentHandler_startDocument
,
673 contentHandler_endDocument
,
674 contentHandler_startPrefixMapping
,
675 contentHandler_endPrefixMapping
,
676 contentHandler_startElement
,
677 contentHandler_endElement
,
678 contentHandler_characters
,
679 contentHandler_ignorableWhitespace
,
680 contentHandler_processingInstruction
,
681 contentHandler_skippedEntity
684 static ISAXContentHandler contentHandler
= { &contentHandlerVtbl
};
686 static HRESULT WINAPI
isaxerrorHandler_QueryInterface(
687 ISAXErrorHandler
* iface
,
693 if(IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_ISAXErrorHandler
))
699 return E_NOINTERFACE
;
705 static ULONG WINAPI
isaxerrorHandler_AddRef(
706 ISAXErrorHandler
* iface
)
711 static ULONG WINAPI
isaxerrorHandler_Release(
712 ISAXErrorHandler
* iface
)
717 static HRESULT WINAPI
isaxerrorHandler_error(
718 ISAXErrorHandler
* iface
,
719 ISAXLocator
*pLocator
,
720 const WCHAR
*pErrorMessage
,
723 ok(0, "unexpected call\n");
727 static HRESULT WINAPI
isaxerrorHandler_fatalError(
728 ISAXErrorHandler
* iface
,
729 ISAXLocator
*pLocator
,
730 const WCHAR
*pErrorMessage
,
733 if(!test_expect_call(EH_FATALERROR
))
736 ok(hrErrorCode
== expectCall
->ret
, "hrErrorCode = %x, expected %x\n", hrErrorCode
, expectCall
->ret
);
742 static HRESULT WINAPI
isaxerrorHanddler_ignorableWarning(
743 ISAXErrorHandler
* iface
,
744 ISAXLocator
*pLocator
,
745 const WCHAR
*pErrorMessage
,
748 ok(0, "unexpected call\n");
752 static const ISAXErrorHandlerVtbl errorHandlerVtbl
=
754 isaxerrorHandler_QueryInterface
,
755 isaxerrorHandler_AddRef
,
756 isaxerrorHandler_Release
,
757 isaxerrorHandler_error
,
758 isaxerrorHandler_fatalError
,
759 isaxerrorHanddler_ignorableWarning
762 static ISAXErrorHandler errorHandler
= { &errorHandlerVtbl
};
764 static HRESULT WINAPI
isaxattributes_QueryInterface(
765 ISAXAttributes
* iface
,
771 if(IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_ISAXAttributes
))
777 return E_NOINTERFACE
;
783 static ULONG WINAPI
isaxattributes_AddRef(ISAXAttributes
* iface
)
788 static ULONG WINAPI
isaxattributes_Release(ISAXAttributes
* iface
)
793 static HRESULT WINAPI
isaxattributes_getLength(ISAXAttributes
* iface
, int *length
)
799 static HRESULT WINAPI
isaxattributes_getURI(
800 ISAXAttributes
* iface
,
805 ok(0, "unexpected call\n");
809 static HRESULT WINAPI
isaxattributes_getLocalName(
810 ISAXAttributes
* iface
,
812 const WCHAR
**pLocalName
,
813 int *pLocalNameLength
)
815 ok(0, "unexpected call\n");
819 static HRESULT WINAPI
isaxattributes_getQName(
820 ISAXAttributes
* iface
,
825 static const WCHAR attrqnamesW
[][15] = {{'a',':','a','t','t','r','1','j','u','n','k',0},
826 {'a','t','t','r','2','j','u','n','k',0},
827 {'a','t','t','r','3',0}};
828 static const int attrqnamelen
[] = {7, 5, 5};
830 ok(index
>= 0 && index
<= 2, "invalid index received %d\n", index
);
832 *QName
= attrqnamesW
[index
];
833 *QNameLength
= attrqnamelen
[index
];
838 static HRESULT WINAPI
isaxattributes_getName(
839 ISAXAttributes
* iface
,
843 const WCHAR
** pLocalName
,
844 int * pLocalNameSize
,
845 const WCHAR
** pQName
,
848 ok(0, "unexpected call\n");
852 static HRESULT WINAPI
isaxattributes_getIndexFromName(
853 ISAXAttributes
* iface
,
856 const WCHAR
* pLocalName
,
860 ok(0, "unexpected call\n");
864 static HRESULT WINAPI
isaxattributes_getIndexFromQName(
865 ISAXAttributes
* iface
,
866 const WCHAR
* pQName
,
870 ok(0, "unexpected call\n");
874 static HRESULT WINAPI
isaxattributes_getType(
875 ISAXAttributes
* iface
,
877 const WCHAR
** pType
,
880 ok(0, "unexpected call\n");
884 static HRESULT WINAPI
isaxattributes_getTypeFromName(
885 ISAXAttributes
* iface
,
888 const WCHAR
* pLocalName
,
890 const WCHAR
** pType
,
893 ok(0, "unexpected call\n");
897 static HRESULT WINAPI
isaxattributes_getTypeFromQName(
898 ISAXAttributes
* iface
,
899 const WCHAR
* pQName
,
901 const WCHAR
** pType
,
904 ok(0, "unexpected call\n");
908 static HRESULT WINAPI
isaxattributes_getValue(ISAXAttributes
* iface
, int index
,
909 const WCHAR
**value
, int *nValue
)
911 static const WCHAR attrvaluesW
[][10] = {{'a','1','j','u','n','k',0},
912 {'a','2','j','u','n','k',0},
913 {'<','&','"','>',0}};
914 static const int attrvalueslen
[] = {2, 2, 4};
916 ok(index
>= 0 && index
<= 2, "invalid index received %d\n", index
);
918 *value
= attrvaluesW
[index
];
919 *nValue
= attrvalueslen
[index
];
924 static HRESULT WINAPI
isaxattributes_getValueFromName(
925 ISAXAttributes
* iface
,
928 const WCHAR
* pLocalName
,
930 const WCHAR
** pValue
,
933 ok(0, "unexpected call\n");
937 static HRESULT WINAPI
isaxattributes_getValueFromQName(
938 ISAXAttributes
* iface
,
939 const WCHAR
* pQName
,
941 const WCHAR
** pValue
,
944 ok(0, "unexpected call\n");
948 static const ISAXAttributesVtbl SAXAttributesVtbl
=
950 isaxattributes_QueryInterface
,
951 isaxattributes_AddRef
,
952 isaxattributes_Release
,
953 isaxattributes_getLength
,
954 isaxattributes_getURI
,
955 isaxattributes_getLocalName
,
956 isaxattributes_getQName
,
957 isaxattributes_getName
,
958 isaxattributes_getIndexFromName
,
959 isaxattributes_getIndexFromQName
,
960 isaxattributes_getType
,
961 isaxattributes_getTypeFromName
,
962 isaxattributes_getTypeFromQName
,
963 isaxattributes_getValue
,
964 isaxattributes_getValueFromName
,
965 isaxattributes_getValueFromQName
968 static ISAXAttributes saxattributes
= { &SAXAttributesVtbl
};
970 static int handler_addrefcalled
;
972 static HRESULT WINAPI
isaxlexical_QueryInterface(ISAXLexicalHandler
* iface
, REFIID riid
, void **ppvObject
)
976 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
977 IsEqualGUID(riid
, &IID_ISAXLexicalHandler
))
983 return E_NOINTERFACE
;
989 static ULONG WINAPI
isaxlexical_AddRef(ISAXLexicalHandler
* iface
)
991 handler_addrefcalled
++;
995 static ULONG WINAPI
isaxlexical_Release(ISAXLexicalHandler
* iface
)
1000 static HRESULT WINAPI
isaxlexical_startDTD(ISAXLexicalHandler
* iface
,
1001 const WCHAR
* pName
, int nName
, const WCHAR
* pPublicId
,
1002 int nPublicId
, const WCHAR
* pSystemId
, int nSystemId
)
1004 ok(0, "call not expected\n");
1008 static HRESULT WINAPI
isaxlexical_endDTD(ISAXLexicalHandler
* iface
)
1010 ok(0, "call not expected\n");
1014 static HRESULT WINAPI
isaxlexical_startEntity(ISAXLexicalHandler
*iface
,
1015 const WCHAR
* pName
, int nName
)
1017 ok(0, "call not expected\n");
1021 static HRESULT WINAPI
isaxlexical_endEntity(ISAXLexicalHandler
*iface
,
1022 const WCHAR
* pName
, int nName
)
1024 ok(0, "call not expected\n");
1028 static HRESULT WINAPI
isaxlexical_startCDATA(ISAXLexicalHandler
*iface
)
1030 ok(0, "call not expected\n");
1034 static HRESULT WINAPI
isaxlexical_endCDATA(ISAXLexicalHandler
*iface
)
1036 ok(0, "call not expected\n");
1040 static HRESULT WINAPI
isaxlexical_comment(ISAXLexicalHandler
*iface
,
1041 const WCHAR
* pChars
, int nChars
)
1043 ok(0, "call not expected\n");
1047 static const ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl
=
1049 isaxlexical_QueryInterface
,
1051 isaxlexical_Release
,
1052 isaxlexical_startDTD
,
1054 isaxlexical_startEntity
,
1055 isaxlexical_endEntity
,
1056 isaxlexical_startCDATA
,
1057 isaxlexical_endCDATA
,
1061 static ISAXLexicalHandler saxlexicalhandler
= { &SAXLexicalHandlerVtbl
};
1063 static HRESULT WINAPI
isaxdecl_QueryInterface(ISAXDeclHandler
* iface
, REFIID riid
, void **ppvObject
)
1067 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
1068 IsEqualGUID(riid
, &IID_ISAXDeclHandler
))
1074 return E_NOINTERFACE
;
1080 static ULONG WINAPI
isaxdecl_AddRef(ISAXDeclHandler
* iface
)
1082 handler_addrefcalled
++;
1086 static ULONG WINAPI
isaxdecl_Release(ISAXDeclHandler
* iface
)
1091 static HRESULT WINAPI
isaxdecl_elementDecl(ISAXDeclHandler
* iface
,
1092 const WCHAR
* pName
, int nName
, const WCHAR
* pModel
, int nModel
)
1094 ok(0, "call not expected\n");
1098 static HRESULT WINAPI
isaxdecl_attributeDecl(ISAXDeclHandler
* iface
,
1099 const WCHAR
* pElementName
, int nElementName
, const WCHAR
* pAttributeName
,
1100 int nAttributeName
, const WCHAR
* pType
, int nType
, const WCHAR
* pValueDefault
,
1101 int nValueDefault
, const WCHAR
* pValue
, int nValue
)
1103 ok(0, "call not expected\n");
1107 static HRESULT WINAPI
isaxdecl_internalEntityDecl(ISAXDeclHandler
* iface
,
1108 const WCHAR
* pName
, int nName
, const WCHAR
* pValue
, int nValue
)
1110 ok(0, "call not expected\n");
1114 static HRESULT WINAPI
isaxdecl_externalEntityDecl(ISAXDeclHandler
* iface
,
1115 const WCHAR
* pName
, int nName
, const WCHAR
* pPublicId
, int nPublicId
,
1116 const WCHAR
* pSystemId
, int nSystemId
)
1118 ok(0, "call not expected\n");
1122 static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl
=
1124 isaxdecl_QueryInterface
,
1127 isaxdecl_elementDecl
,
1128 isaxdecl_attributeDecl
,
1129 isaxdecl_internalEntityDecl
,
1130 isaxdecl_externalEntityDecl
1133 static ISAXDeclHandler saxdeclhandler
= { &SAXDeclHandlerVtbl
};
1135 typedef struct mxwriter_write_test_t
{
1141 } mxwriter_write_test
;
1143 typedef struct mxwriter_stream_test_t
{
1145 const char *encoding
;
1146 mxwriter_write_test expected_writes
[4];
1147 } mxwriter_stream_test
;
1149 static const mxwriter_write_test
*current_write_test
;
1150 static DWORD current_stream_test_index
;
1152 static HRESULT WINAPI
istream_QueryInterface(IStream
*iface
, REFIID riid
, void **ppvObject
)
1156 if(IsEqualGUID(riid
, &IID_IStream
) || IsEqualGUID(riid
, &IID_IUnknown
))
1159 return E_NOINTERFACE
;
1164 static ULONG WINAPI
istream_AddRef(IStream
*iface
)
1169 static ULONG WINAPI
istream_Release(IStream
*iface
)
1174 static HRESULT WINAPI
istream_Read(IStream
*iface
, void *pv
, ULONG cb
, ULONG
*pcbRead
)
1176 ok(0, "unexpected call\n");
1180 static HRESULT WINAPI
istream_Write(IStream
*iface
, const void *pv
, ULONG cb
, ULONG
*pcbWritten
)
1184 ok(pv
!= NULL
, "pv == NULL\n");
1186 if(current_write_test
->last
) {
1187 ok(0, "Too many Write calls made on test %d\n", current_stream_test_index
);
1191 fail
= current_write_test
->fail_write
;
1193 ok(current_write_test
->cb
== cb
, "Expected %d, but got %d on test %d\n",
1194 current_write_test
->cb
, cb
, current_stream_test_index
);
1197 ok(current_write_test
->null_written
, "pcbWritten was NULL on test %d\n", current_stream_test_index
);
1199 ok(!memcmp(current_write_test
->data
, pv
, cb
), "Unexpected data on test %d\n", current_stream_test_index
);
1201 ++current_write_test
;
1206 return fail
? E_FAIL
: S_OK
;
1209 static HRESULT WINAPI
istream_Seek(IStream
*iface
, LARGE_INTEGER dlibMove
, DWORD dwOrigin
,
1210 ULARGE_INTEGER
*plibNewPosition
)
1212 ok(0, "unexpected call\n");
1216 static HRESULT WINAPI
istream_SetSize(IStream
*iface
, ULARGE_INTEGER libNewSize
)
1218 ok(0, "unexpected call\n");
1222 static HRESULT WINAPI
istream_CopyTo(IStream
*iface
, IStream
*pstm
, ULARGE_INTEGER cb
,
1223 ULARGE_INTEGER
*pcbRead
, ULARGE_INTEGER
*plibWritten
)
1225 ok(0, "unexpected call\n");
1229 static HRESULT WINAPI
istream_Commit(IStream
*iface
, DWORD grfCommitFlags
)
1231 ok(0, "unexpected call\n");
1235 static HRESULT WINAPI
istream_Revert(IStream
*iface
)
1237 ok(0, "unexpected call\n");
1241 static HRESULT WINAPI
istream_LockRegion(IStream
*iface
, ULARGE_INTEGER libOffset
,
1242 ULARGE_INTEGER cb
, DWORD dwLockType
)
1244 ok(0, "unexpected call\n");
1248 static HRESULT WINAPI
istream_UnlockRegion(IStream
*iface
, ULARGE_INTEGER libOffset
,
1249 ULARGE_INTEGER cb
, DWORD dwLockType
)
1251 ok(0, "unexpected call\n");
1255 static HRESULT WINAPI
istream_Stat(IStream
*iface
, STATSTG
*pstatstg
, DWORD grfStatFlag
)
1257 ok(0, "unexpected call\n");
1261 static HRESULT WINAPI
istream_Clone(IStream
*iface
, IStream
**ppstm
)
1263 ok(0, "unexpected call\n");
1267 static const IStreamVtbl StreamVtbl
= {
1268 istream_QueryInterface
,
1279 istream_UnlockRegion
,
1284 static IStream mxstream
= { &StreamVtbl
};
1286 static void test_saxreader(int version
)
1289 ISAXXMLReader
*reader
= NULL
;
1291 ISAXContentHandler
*lpContentHandler
;
1292 ISAXErrorHandler
*lpErrorHandler
;
1294 SAFEARRAYBOUND SADim
[1];
1295 char *pSAData
= NULL
;
1297 ULARGE_INTEGER liSize
;
1298 LARGE_INTEGER liPos
;
1301 static const CHAR testXmlA
[] = "test.xml";
1302 static const WCHAR testXmlW
[] = {'t','e','s','t','.','x','m','l',0};
1303 IXMLDOMDocument
*domDocument
;
1307 msxml_version
= version
;
1309 hr
= CoCreateInstance(&CLSID_SAXXMLReader30
, NULL
, CLSCTX_INPROC_SERVER
,
1310 &IID_ISAXXMLReader
, (LPVOID
*)&reader
);
1311 } else if(version
== 6) {
1312 hr
= CoCreateInstance(&CLSID_SAXXMLReader60
, NULL
, CLSCTX_INPROC_SERVER
,
1313 &IID_ISAXXMLReader
, (LPVOID
*)&reader
);
1314 if(hr
== REGDB_E_CLASSNOTREG
) {
1315 win_skip("SAXXMLReader6 not registered\n");
1319 hr
= CoCreateInstance(&CLSID_SAXXMLReader
, NULL
, CLSCTX_INPROC_SERVER
,
1320 &IID_ISAXXMLReader
, (LPVOID
*)&reader
);
1322 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1325 hr
= ISAXXMLReader_getContentHandler(reader
, NULL
);
1326 ok(hr
== E_POINTER
, "Expected E_POINTER, got %08x\n", hr
);
1328 hr
= ISAXXMLReader_getErrorHandler(reader
, NULL
);
1329 ok(hr
== E_POINTER
, "Expected E_POINTER, got %08x\n", hr
);
1332 hr
= ISAXXMLReader_getContentHandler(reader
, &lpContentHandler
);
1333 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1334 ok(lpContentHandler
== NULL
, "Expected %p, got %p\n", NULL
, lpContentHandler
);
1336 hr
= ISAXXMLReader_getErrorHandler(reader
, &lpErrorHandler
);
1337 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1338 ok(lpErrorHandler
== NULL
, "Expected %p, got %p\n", NULL
, lpErrorHandler
);
1340 hr
= ISAXXMLReader_putContentHandler(reader
, NULL
);
1341 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1343 hr
= ISAXXMLReader_putContentHandler(reader
, &contentHandler
);
1344 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1346 hr
= ISAXXMLReader_putErrorHandler(reader
, &errorHandler
);
1347 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1349 hr
= ISAXXMLReader_getContentHandler(reader
, &lpContentHandler
);
1350 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1351 ok(lpContentHandler
== &contentHandler
, "Expected %p, got %p\n", &contentHandler
, lpContentHandler
);
1353 V_VT(&var
) = VT_BSTR
;
1354 V_BSTR(&var
) = SysAllocString(szSimpleXML
);
1356 expectCall
= contentHandlerTest1
;
1357 hr
= ISAXXMLReader_parse(reader
, var
);
1358 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1359 test_expect_call(CH_ENDTEST
);
1363 SADim
[0].lLbound
= 0;
1364 SADim
[0].cElements
= sizeof(szTestXML
)-1;
1365 pSA
= SafeArrayCreate(VT_UI1
, 1, SADim
);
1366 SafeArrayAccessData(pSA
, (void**)&pSAData
);
1367 memcpy(pSAData
, szTestXML
, sizeof(szTestXML
)-1);
1368 SafeArrayUnaccessData(pSA
);
1369 V_VT(&var
) = VT_ARRAY
|VT_UI1
;
1370 V_ARRAY(&var
) = pSA
;
1372 expectCall
= contentHandlerTest1
;
1373 hr
= ISAXXMLReader_parse(reader
, var
);
1374 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1375 test_expect_call(CH_ENDTEST
);
1377 SafeArrayDestroy(pSA
);
1379 CreateStreamOnHGlobal(NULL
, TRUE
, &iStream
);
1380 liSize
.QuadPart
= strlen(szTestXML
);
1381 IStream_SetSize(iStream
, liSize
);
1382 IStream_Write(iStream
, szTestXML
, strlen(szTestXML
), &bytesWritten
);
1384 IStream_Seek(iStream
, liPos
, STREAM_SEEK_SET
, NULL
);
1385 V_VT(&var
) = VT_UNKNOWN
|VT_DISPATCH
;
1386 V_UNKNOWN(&var
) = (IUnknown
*)iStream
;
1388 expectCall
= contentHandlerTest1
;
1389 hr
= ISAXXMLReader_parse(reader
, var
);
1390 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1391 test_expect_call(CH_ENDTEST
);
1393 IStream_Release(iStream
);
1395 CreateStreamOnHGlobal(NULL
, TRUE
, &iStream
);
1396 liSize
.QuadPart
= strlen(szTestAttributes
);
1397 IStream_SetSize(iStream
, liSize
);
1398 IStream_Write(iStream
, szTestAttributes
, strlen(szTestAttributes
), &bytesWritten
);
1400 IStream_Seek(iStream
, liPos
, STREAM_SEEK_SET
, NULL
);
1401 V_VT(&var
) = VT_UNKNOWN
|VT_DISPATCH
;
1402 V_UNKNOWN(&var
) = (IUnknown
*)iStream
;
1405 expectCall
= contentHandlerTestAttributes6
;
1407 expectCall
= contentHandlerTestAttributes
;
1408 hr
= ISAXXMLReader_parse(reader
, var
);
1409 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1410 test_expect_call(CH_ENDTEST
);
1412 IStream_Release(iStream
);
1414 V_VT(&var
) = VT_BSTR
;
1415 V_BSTR(&var
) = SysAllocString(szCarriageRetTest
);
1417 expectCall
= contentHandlerTest2
;
1418 hr
= ISAXXMLReader_parse(reader
, var
);
1419 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1420 test_expect_call(CH_ENDTEST
);
1424 file
= CreateFileA(testXmlA
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1425 ok(file
!= INVALID_HANDLE_VALUE
, "Could not create file: %u\n", GetLastError());
1426 WriteFile(file
, szTestXML
, sizeof(szTestXML
)-1, &bytesWritten
, NULL
);
1429 expectCall
= contentHandlerTest1
;
1430 hr
= ISAXXMLReader_parseURL(reader
, testXmlW
);
1431 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1432 test_expect_call(CH_ENDTEST
);
1434 expectCall
= contentHandlerTestError
;
1435 hr
= ISAXXMLReader_parseURL(reader
, testXmlW
);
1436 ok(hr
== E_FAIL
, "Expected E_FAIL, got %08x\n", hr
);
1437 test_expect_call(CH_ENDTEST
);
1440 expectCall
= contentHandlerTestCallbackResult6
;
1442 expectCall
= contentHandlerTestCallbackResults
;
1443 hr
= ISAXXMLReader_parseURL(reader
, testXmlW
);
1444 ok(hr
== (version
>=6 ? S_OK
: S_FALSE
), "Expected S_FALSE, got %08x\n", hr
);
1445 test_expect_call(CH_ENDTEST
);
1447 DeleteFileA(testXmlA
);
1449 hr
= CoCreateInstance(&CLSID_DOMDocument
, NULL
, CLSCTX_INPROC_SERVER
,
1450 &IID_IXMLDOMDocument
, (LPVOID
*)&domDocument
);
1453 skip("Failed to create DOMDocument instance\n");
1456 bstrData
= SysAllocString(szSimpleXML
);
1457 hr
= IXMLDOMDocument_loadXML(domDocument
, bstrData
, &vBool
);
1458 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1459 V_VT(&var
) = VT_UNKNOWN
;
1460 V_UNKNOWN(&var
) = (IUnknown
*)domDocument
;
1462 expectCall
= contentHandlerTest2
;
1463 hr
= ISAXXMLReader_parse(reader
, var
);
1464 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1465 test_expect_call(CH_ENDTEST
);
1466 IXMLDOMDocument_Release(domDocument
);
1468 expectCall
= xmlspaceattr_test
;
1469 V_VT(&var
) = VT_BSTR
;
1470 V_BSTR(&var
) = _bstr_(xmlspace_attr
);
1471 hr
= ISAXXMLReader_parse(reader
, var
);
1472 EXPECT_HR(hr
, S_OK
);
1473 test_expect_call(CH_ENDTEST
);
1475 ISAXXMLReader_Release(reader
);
1476 SysFreeString(bstrData
);
1480 struct saxreader_props_test_t
1482 const char *prop_name
;
1486 static const struct saxreader_props_test_t props_test_data
[] = {
1487 { "http://xml.org/sax/properties/lexical-handler", (IUnknown
*)&saxlexicalhandler
},
1488 { "http://xml.org/sax/properties/declaration-handler", (IUnknown
*)&saxdeclhandler
},
1492 static void test_saxreader_properties(void)
1494 const struct saxreader_props_test_t
*ptr
= props_test_data
;
1495 ISAXXMLReader
*reader
;
1498 hr
= CoCreateInstance(&CLSID_SAXXMLReader
, NULL
, CLSCTX_INPROC_SERVER
,
1499 &IID_ISAXXMLReader
, (void**)&reader
);
1500 EXPECT_HR(hr
, S_OK
);
1502 hr
= ISAXXMLReader_getProperty(reader
, _bstr_("http://xml.org/sax/properties/lexical-handler"), NULL
);
1503 EXPECT_HR(hr
, E_POINTER
);
1505 while (ptr
->prop_name
)
1509 V_VT(&v
) = VT_EMPTY
;
1510 V_UNKNOWN(&v
) = (IUnknown
*)0xdeadbeef;
1511 hr
= ISAXXMLReader_getProperty(reader
, _bstr_(ptr
->prop_name
), &v
);
1512 EXPECT_HR(hr
, S_OK
);
1513 ok(V_VT(&v
) == VT_UNKNOWN
, "got %d\n", V_VT(&v
));
1514 ok(V_UNKNOWN(&v
) == NULL
, "got %p\n", V_UNKNOWN(&v
));
1516 V_VT(&v
) = VT_UNKNOWN
;
1517 V_UNKNOWN(&v
) = ptr
->iface
;
1518 hr
= ISAXXMLReader_putProperty(reader
, _bstr_(ptr
->prop_name
), v
);
1519 EXPECT_HR(hr
, S_OK
);
1521 V_VT(&v
) = VT_EMPTY
;
1522 V_UNKNOWN(&v
) = (IUnknown
*)0xdeadbeef;
1523 handler_addrefcalled
= 0;
1524 hr
= ISAXXMLReader_getProperty(reader
, _bstr_(ptr
->prop_name
), &v
);
1525 EXPECT_HR(hr
, S_OK
);
1526 ok(V_VT(&v
) == VT_UNKNOWN
, "got %d\n", V_VT(&v
));
1527 ok(V_UNKNOWN(&v
) == ptr
->iface
, "got %p\n", V_UNKNOWN(&v
));
1528 ok(handler_addrefcalled
== 1, "AddRef called %d times\n", handler_addrefcalled
);
1531 V_VT(&v
) = VT_EMPTY
;
1532 V_UNKNOWN(&v
) = (IUnknown
*)0xdeadbeef;
1533 hr
= ISAXXMLReader_putProperty(reader
, _bstr_(ptr
->prop_name
), v
);
1534 EXPECT_HR(hr
, S_OK
);
1536 V_VT(&v
) = VT_EMPTY
;
1537 V_UNKNOWN(&v
) = (IUnknown
*)0xdeadbeef;
1538 hr
= ISAXXMLReader_getProperty(reader
, _bstr_(ptr
->prop_name
), &v
);
1539 EXPECT_HR(hr
, S_OK
);
1540 ok(V_VT(&v
) == VT_UNKNOWN
, "got %d\n", V_VT(&v
));
1541 ok(V_UNKNOWN(&v
) == NULL
, "got %p\n", V_UNKNOWN(&v
));
1543 V_VT(&v
) = VT_UNKNOWN
;
1544 V_UNKNOWN(&v
) = ptr
->iface
;
1545 hr
= ISAXXMLReader_putProperty(reader
, _bstr_(ptr
->prop_name
), v
);
1546 EXPECT_HR(hr
, S_OK
);
1548 /* only VT_EMPTY seems to be valid to reset property */
1550 V_UNKNOWN(&v
) = (IUnknown
*)0xdeadbeef;
1551 hr
= ISAXXMLReader_putProperty(reader
, _bstr_(ptr
->prop_name
), v
);
1552 EXPECT_HR(hr
, E_INVALIDARG
);
1554 V_VT(&v
) = VT_EMPTY
;
1555 V_UNKNOWN(&v
) = (IUnknown
*)0xdeadbeef;
1556 hr
= ISAXXMLReader_getProperty(reader
, _bstr_(ptr
->prop_name
), &v
);
1557 EXPECT_HR(hr
, S_OK
);
1558 ok(V_VT(&v
) == VT_UNKNOWN
, "got %d\n", V_VT(&v
));
1559 ok(V_UNKNOWN(&v
) == ptr
->iface
, "got %p\n", V_UNKNOWN(&v
));
1562 V_VT(&v
) = VT_UNKNOWN
;
1563 V_UNKNOWN(&v
) = NULL
;
1564 hr
= ISAXXMLReader_putProperty(reader
, _bstr_(ptr
->prop_name
), v
);
1565 EXPECT_HR(hr
, S_OK
);
1567 V_VT(&v
) = VT_EMPTY
;
1568 V_UNKNOWN(&v
) = (IUnknown
*)0xdeadbeef;
1569 hr
= ISAXXMLReader_getProperty(reader
, _bstr_(ptr
->prop_name
), &v
);
1570 EXPECT_HR(hr
, S_OK
);
1571 ok(V_VT(&v
) == VT_UNKNOWN
, "got %d\n", V_VT(&v
));
1572 ok(V_UNKNOWN(&v
) == NULL
, "got %p\n", V_UNKNOWN(&v
));
1577 ISAXXMLReader_Release(reader
);
1581 struct feature_ns_entry_t
{
1587 static const struct feature_ns_entry_t feature_ns_entry_data
[] = {
1588 { &CLSID_SAXXMLReader
, "CLSID_SAXXMLReader", VARIANT_TRUE
},
1589 { &CLSID_SAXXMLReader30
, "CLSID_SAXXMLReader30", VARIANT_TRUE
},
1590 { &CLSID_SAXXMLReader40
, "CLSID_SAXXMLReader40", VARIANT_TRUE
},
1591 { &CLSID_SAXXMLReader60
, "CLSID_SAXXMLReader60", VARIANT_TRUE
},
1595 static void test_saxreader_features(void)
1597 const struct feature_ns_entry_t
*entry
= feature_ns_entry_data
;
1598 ISAXXMLReader
*reader
;
1605 hr
= CoCreateInstance(entry
->guid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_ISAXXMLReader
, (void**)&reader
);
1608 win_skip("can't create %s instance\n", entry
->clsid
);
1614 hr
= ISAXXMLReader_getFeature(reader
, _bstr_("http://xml.org/sax/features/namespaces"), &value
);
1615 EXPECT_HR(hr
, S_OK
);
1617 ok(entry
->value
== value
, "%s: got wrong default value %x, expected %x\n", entry
->clsid
, value
, entry
->value
);
1619 ISAXXMLReader_Release(reader
);
1625 /* UTF-8 data with UTF-8 BOM and UTF-16 in prolog */
1626 static const CHAR UTF8BOMTest
[] =
1627 "\xEF\xBB\xBF<?xml version = \"1.0\" encoding = \"UTF-16\"?>\n"
1630 struct enc_test_entry_t
{
1638 static const struct enc_test_entry_t encoding_test_data
[] = {
1639 { &CLSID_SAXXMLReader
, "CLSID_SAXXMLReader", UTF8BOMTest
, 0xc00ce56f, 1 },
1640 { &CLSID_SAXXMLReader30
, "CLSID_SAXXMLReader30", UTF8BOMTest
, 0xc00ce56f, 1 },
1641 { &CLSID_SAXXMLReader40
, "CLSID_SAXXMLReader40", UTF8BOMTest
, S_OK
, 0 },
1642 { &CLSID_SAXXMLReader60
, "CLSID_SAXXMLReader60", UTF8BOMTest
, S_OK
, 0 },
1646 static void test_encoding(void)
1648 const struct enc_test_entry_t
*entry
= encoding_test_data
;
1649 static const WCHAR testXmlW
[] = {'t','e','s','t','.','x','m','l',0};
1650 static const CHAR testXmlA
[] = "test.xml";
1651 ISAXXMLReader
*reader
;
1658 hr
= CoCreateInstance(entry
->guid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_ISAXXMLReader
, (void**)&reader
);
1661 win_skip("can't create %s instance\n", entry
->clsid
);
1666 file
= CreateFileA(testXmlA
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1667 ok(file
!= INVALID_HANDLE_VALUE
, "Could not create file: %u\n", GetLastError());
1668 WriteFile(file
, UTF8BOMTest
, sizeof(UTF8BOMTest
)-1, &written
, NULL
);
1671 hr
= ISAXXMLReader_parseURL(reader
, testXmlW
);
1673 todo_wine
ok(hr
== entry
->hr
, "Expected 0x%08x, got 0x%08x. CLSID %s\n", entry
->hr
, hr
, entry
->clsid
);
1675 ok(hr
== entry
->hr
, "Expected 0x%08x, got 0x%08x. CLSID %s\n", entry
->hr
, hr
, entry
->clsid
);
1677 DeleteFileA(testXmlA
);
1678 ISAXXMLReader_Release(reader
);
1684 static void test_mxwriter_handlers(void)
1686 ISAXContentHandler
*handler
;
1687 IMXWriter
*writer
, *writer2
;
1688 ISAXLexicalHandler
*lh
;
1691 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
1692 &IID_IMXWriter
, (void**)&writer
);
1693 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1695 EXPECT_REF(writer
, 1);
1697 /* ISAXContentHandler */
1698 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&handler
);
1699 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1700 EXPECT_REF(writer
, 2);
1701 EXPECT_REF(handler
, 2);
1703 hr
= ISAXContentHandler_QueryInterface(handler
, &IID_IMXWriter
, (void**)&writer2
);
1704 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1705 ok(writer2
== writer
, "got %p, expected %p\n", writer2
, writer
);
1706 EXPECT_REF(writer
, 3);
1707 EXPECT_REF(writer2
, 3);
1708 IMXWriter_Release(writer2
);
1709 ISAXContentHandler_Release(handler
);
1711 /* ISAXLexicalHandler */
1712 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXLexicalHandler
, (void**)&lh
);
1713 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1714 EXPECT_REF(writer
, 2);
1717 hr
= ISAXLexicalHandler_QueryInterface(lh
, &IID_IMXWriter
, (void**)&writer2
);
1718 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1719 ok(writer2
== writer
, "got %p, expected %p\n", writer2
, writer
);
1720 EXPECT_REF(writer
, 3);
1721 EXPECT_REF(writer2
, 3);
1722 IMXWriter_Release(writer2
);
1724 IMXWriter_Release(writer
);
1727 struct msxmlsupported_data_t
1734 static struct msxmlsupported_data_t mxwriter_support_data
[] =
1736 { &CLSID_MXXMLWriter
, "MXXMLWriter" },
1737 { &CLSID_MXXMLWriter30
, "MXXMLWriter30" },
1738 { &CLSID_MXXMLWriter40
, "MXXMLWriter40" },
1739 { &CLSID_MXXMLWriter60
, "MXXMLWriter60" },
1743 static struct msxmlsupported_data_t mxattributes_support_data
[] =
1745 { &CLSID_SAXAttributes
, "SAXAttributes" },
1746 { &CLSID_SAXAttributes30
, "SAXAttributes30" },
1747 { &CLSID_SAXAttributes40
, "SAXAttributes40" },
1748 { &CLSID_SAXAttributes60
, "SAXAttributes60" },
1752 static BOOL
is_clsid_supported(const GUID
*clsid
, const struct msxmlsupported_data_t
*table
)
1754 while (table
->clsid
)
1756 if (table
->clsid
== clsid
) return table
->supported
;
1762 struct mxwriter_props_t
1766 VARIANT_BOOL disable_escape
;
1767 VARIANT_BOOL indent
;
1768 VARIANT_BOOL omitdecl
;
1769 VARIANT_BOOL standalone
;
1770 const char *encoding
;
1773 static const struct mxwriter_props_t mxwriter_default_props
[] =
1775 { &CLSID_MXXMLWriter
, VARIANT_TRUE
, VARIANT_FALSE
, VARIANT_FALSE
, VARIANT_FALSE
, VARIANT_FALSE
, "UTF-16" },
1776 { &CLSID_MXXMLWriter30
, VARIANT_TRUE
, VARIANT_FALSE
, VARIANT_FALSE
, VARIANT_FALSE
, VARIANT_FALSE
, "UTF-16" },
1777 { &CLSID_MXXMLWriter40
, VARIANT_TRUE
, VARIANT_FALSE
, VARIANT_FALSE
, VARIANT_FALSE
, VARIANT_FALSE
, "UTF-16" },
1778 { &CLSID_MXXMLWriter60
, VARIANT_TRUE
, VARIANT_FALSE
, VARIANT_FALSE
, VARIANT_FALSE
, VARIANT_FALSE
, "UTF-16" },
1782 static void test_mxwriter_default_properties(const struct mxwriter_props_t
*table
)
1786 while (table
->clsid
)
1793 if (!is_clsid_supported(table
->clsid
, mxwriter_support_data
))
1800 hr
= CoCreateInstance(table
->clsid
, NULL
, CLSCTX_INPROC_SERVER
,
1801 &IID_IMXWriter
, (void**)&writer
);
1802 EXPECT_HR(hr
, S_OK
);
1805 hr
= IMXWriter_get_byteOrderMark(writer
, &b
);
1806 EXPECT_HR(hr
, S_OK
);
1807 ok(table
->bom
== b
, "test %d: got BOM %d, expected %d\n", i
, b
, table
->bom
);
1809 b
= !table
->disable_escape
;
1810 hr
= IMXWriter_get_disableOutputEscaping(writer
, &b
);
1811 EXPECT_HR(hr
, S_OK
);
1812 ok(table
->disable_escape
== b
, "test %d: got disable escape %d, expected %d\n", i
, b
,
1813 table
->disable_escape
);
1816 hr
= IMXWriter_get_indent(writer
, &b
);
1817 EXPECT_HR(hr
, S_OK
);
1818 ok(table
->indent
== b
, "test %d: got indent %d, expected %d\n", i
, b
, table
->indent
);
1820 b
= !table
->omitdecl
;
1821 hr
= IMXWriter_get_omitXMLDeclaration(writer
, &b
);
1822 EXPECT_HR(hr
, S_OK
);
1823 ok(table
->omitdecl
== b
, "test %d: got omitdecl %d, expected %d\n", i
, b
, table
->omitdecl
);
1825 b
= !table
->standalone
;
1826 hr
= IMXWriter_get_standalone(writer
, &b
);
1827 EXPECT_HR(hr
, S_OK
);
1828 ok(table
->standalone
== b
, "test %d: got standalone %d, expected %d\n", i
, b
, table
->standalone
);
1830 hr
= IMXWriter_get_encoding(writer
, &encoding
);
1831 EXPECT_HR(hr
, S_OK
);
1832 ok(!lstrcmpW(encoding
, _bstr_(table
->encoding
)), "test %d: got encoding %s, expected %s\n",
1833 i
, wine_dbgstr_w(encoding
), table
->encoding
);
1834 SysFreeString(encoding
);
1836 IMXWriter_Release(writer
);
1843 static void test_mxwriter_properties(void)
1845 static const WCHAR utf16W
[] = {'U','T','F','-','1','6',0};
1846 static const WCHAR emptyW
[] = {0};
1847 static const WCHAR testW
[] = {'t','e','s','t',0};
1848 ISAXContentHandler
*content
;
1855 test_mxwriter_default_properties(mxwriter_default_props
);
1857 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
1858 &IID_IMXWriter
, (void**)&writer
);
1859 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
1861 hr
= IMXWriter_get_disableOutputEscaping(writer
, NULL
);
1862 ok(hr
== E_POINTER
, "got %08x\n", hr
);
1864 hr
= IMXWriter_get_byteOrderMark(writer
, NULL
);
1865 ok(hr
== E_POINTER
, "got %08x\n", hr
);
1867 hr
= IMXWriter_get_indent(writer
, NULL
);
1868 ok(hr
== E_POINTER
, "got %08x\n", hr
);
1870 hr
= IMXWriter_get_omitXMLDeclaration(writer
, NULL
);
1871 ok(hr
== E_POINTER
, "got %08x\n", hr
);
1873 hr
= IMXWriter_get_standalone(writer
, NULL
);
1874 ok(hr
== E_POINTER
, "got %08x\n", hr
);
1877 hr
= IMXWriter_put_standalone(writer
, VARIANT_TRUE
);
1878 ok(hr
== S_OK
, "got %08x\n", hr
);
1881 hr
= IMXWriter_get_standalone(writer
, &b
);
1882 ok(hr
== S_OK
, "got %08x\n", hr
);
1883 ok(b
== VARIANT_TRUE
, "got %d\n", b
);
1885 hr
= IMXWriter_get_encoding(writer
, NULL
);
1886 EXPECT_HR(hr
, E_POINTER
);
1888 /* UTF-16 is a default setting apparently */
1889 str
= (void*)0xdeadbeef;
1890 hr
= IMXWriter_get_encoding(writer
, &str
);
1891 EXPECT_HR(hr
, S_OK
);
1892 ok(lstrcmpW(str
, utf16W
) == 0, "expected empty string, got %s\n", wine_dbgstr_w(str
));
1894 str2
= (void*)0xdeadbeef;
1895 hr
= IMXWriter_get_encoding(writer
, &str2
);
1896 ok(hr
== S_OK
, "got %08x\n", hr
);
1897 ok(str
!= str2
, "expected newly allocated, got same %p\n", str
);
1899 SysFreeString(str2
);
1902 /* put empty string */
1903 str
= SysAllocString(emptyW
);
1904 hr
= IMXWriter_put_encoding(writer
, str
);
1905 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
1908 str
= (void*)0xdeadbeef;
1909 hr
= IMXWriter_get_encoding(writer
, &str
);
1910 EXPECT_HR(hr
, S_OK
);
1911 ok(!lstrcmpW(str
, _bstr_("UTF-16")), "got %s\n", wine_dbgstr_w(str
));
1914 /* invalid encoding name */
1915 str
= SysAllocString(testW
);
1916 hr
= IMXWriter_put_encoding(writer
, str
);
1917 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
1920 /* test case sensivity */
1921 hr
= IMXWriter_put_encoding(writer
, _bstr_("utf-8"));
1922 EXPECT_HR(hr
, S_OK
);
1923 str
= (void*)0xdeadbeef;
1924 hr
= IMXWriter_get_encoding(writer
, &str
);
1925 EXPECT_HR(hr
, S_OK
);
1926 ok(!lstrcmpW(str
, _bstr_("utf-8")), "got %s\n", wine_dbgstr_w(str
));
1929 hr
= IMXWriter_put_encoding(writer
, _bstr_("uTf-16"));
1930 EXPECT_HR(hr
, S_OK
);
1931 str
= (void*)0xdeadbeef;
1932 hr
= IMXWriter_get_encoding(writer
, &str
);
1933 EXPECT_HR(hr
, S_OK
);
1934 ok(!lstrcmpW(str
, _bstr_("uTf-16")), "got %s\n", wine_dbgstr_w(str
));
1937 /* how it affects document creation */
1938 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
1939 EXPECT_HR(hr
, S_OK
);
1941 hr
= ISAXContentHandler_startDocument(content
);
1942 EXPECT_HR(hr
, S_OK
);
1943 hr
= ISAXContentHandler_endDocument(content
);
1944 EXPECT_HR(hr
, S_OK
);
1946 V_VT(&dest
) = VT_EMPTY
;
1947 hr
= IMXWriter_get_output(writer
, &dest
);
1948 EXPECT_HR(hr
, S_OK
);
1949 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
1950 ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\"?>\r\n"),
1951 V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
1952 VariantClear(&dest
);
1953 ISAXContentHandler_Release(content
);
1955 hr
= IMXWriter_get_version(writer
, NULL
);
1956 ok(hr
== E_POINTER
, "got %08x\n", hr
);
1957 /* default version is 'surprisingly' 1.0 */
1958 hr
= IMXWriter_get_version(writer
, &str
);
1959 ok(hr
== S_OK
, "got %08x\n", hr
);
1960 ok(!lstrcmpW(str
, _bstr_("1.0")), "got %s\n", wine_dbgstr_w(str
));
1963 /* store version string as is */
1964 hr
= IMXWriter_put_version(writer
, NULL
);
1965 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
1967 hr
= IMXWriter_put_version(writer
, _bstr_("1.0"));
1968 ok(hr
== S_OK
, "got %08x\n", hr
);
1970 hr
= IMXWriter_put_version(writer
, _bstr_(""));
1971 ok(hr
== S_OK
, "got %08x\n", hr
);
1972 hr
= IMXWriter_get_version(writer
, &str
);
1973 ok(hr
== S_OK
, "got %08x\n", hr
);
1974 ok(!lstrcmpW(str
, _bstr_("")), "got %s\n", wine_dbgstr_w(str
));
1977 hr
= IMXWriter_put_version(writer
, _bstr_("a.b"));
1978 ok(hr
== S_OK
, "got %08x\n", hr
);
1979 hr
= IMXWriter_get_version(writer
, &str
);
1980 ok(hr
== S_OK
, "got %08x\n", hr
);
1981 ok(!lstrcmpW(str
, _bstr_("a.b")), "got %s\n", wine_dbgstr_w(str
));
1984 hr
= IMXWriter_put_version(writer
, _bstr_("2.0"));
1985 ok(hr
== S_OK
, "got %08x\n", hr
);
1986 hr
= IMXWriter_get_version(writer
, &str
);
1987 ok(hr
== S_OK
, "got %08x\n", hr
);
1988 ok(!lstrcmpW(str
, _bstr_("2.0")), "got %s\n", wine_dbgstr_w(str
));
1991 IMXWriter_Release(writer
);
1995 static void test_mxwriter_flush(void)
1997 ISAXContentHandler
*content
;
2000 ULARGE_INTEGER pos2
;
2005 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
2006 &IID_IMXWriter
, (void**)&writer
);
2007 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2009 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
2010 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2011 EXPECT_REF(stream
, 1);
2013 /* detach when nothing was attached */
2014 V_VT(&dest
) = VT_EMPTY
;
2015 hr
= IMXWriter_put_output(writer
, dest
);
2016 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2019 V_VT(&dest
) = VT_UNKNOWN
;
2020 V_UNKNOWN(&dest
) = (IUnknown
*)stream
;
2021 hr
= IMXWriter_put_output(writer
, dest
);
2022 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2023 todo_wine
EXPECT_REF(stream
, 3);
2025 /* detach setting VT_EMPTY destination */
2026 V_VT(&dest
) = VT_EMPTY
;
2027 hr
= IMXWriter_put_output(writer
, dest
);
2028 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2029 EXPECT_REF(stream
, 1);
2031 V_VT(&dest
) = VT_UNKNOWN
;
2032 V_UNKNOWN(&dest
) = (IUnknown
*)stream
;
2033 hr
= IMXWriter_put_output(writer
, dest
);
2034 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2036 /* flush() doesn't detach a stream */
2037 hr
= IMXWriter_flush(writer
);
2038 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2039 todo_wine
EXPECT_REF(stream
, 3);
2042 hr
= IStream_Seek(stream
, pos
, STREAM_SEEK_CUR
, &pos2
);
2043 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2044 ok(pos2
.QuadPart
== 0, "expected stream beginning\n");
2046 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
2047 ok(hr
== S_OK
, "got %08x\n", hr
);
2049 hr
= ISAXContentHandler_startDocument(content
);
2050 ok(hr
== S_OK
, "got %08x\n", hr
);
2053 hr
= IStream_Seek(stream
, pos
, STREAM_SEEK_CUR
, &pos2
);
2054 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2055 ok(pos2
.QuadPart
!= 0, "expected stream beginning\n");
2057 /* already started */
2058 hr
= ISAXContentHandler_startDocument(content
);
2059 ok(hr
== S_OK
, "got %08x\n", hr
);
2061 hr
= ISAXContentHandler_endDocument(content
);
2062 ok(hr
== S_OK
, "got %08x\n", hr
);
2064 /* flushed on endDocument() */
2066 hr
= IStream_Seek(stream
, pos
, STREAM_SEEK_CUR
, &pos2
);
2067 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2068 ok(pos2
.QuadPart
!= 0, "expected stream position moved\n");
2070 ISAXContentHandler_Release(content
);
2071 IStream_Release(stream
);
2072 IMXWriter_Release(writer
);
2075 static void test_mxwriter_startenddocument(void)
2077 ISAXContentHandler
*content
;
2082 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
2083 &IID_IMXWriter
, (void**)&writer
);
2084 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2086 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
2087 ok(hr
== S_OK
, "got %08x\n", hr
);
2089 hr
= ISAXContentHandler_startDocument(content
);
2090 ok(hr
== S_OK
, "got %08x\n", hr
);
2092 hr
= ISAXContentHandler_endDocument(content
);
2093 ok(hr
== S_OK
, "got %08x\n", hr
);
2095 V_VT(&dest
) = VT_EMPTY
;
2096 hr
= IMXWriter_get_output(writer
, &dest
);
2097 ok(hr
== S_OK
, "got %08x\n", hr
);
2098 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2099 ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"), V_BSTR(&dest
)),
2100 "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2101 VariantClear(&dest
);
2103 /* now try another startDocument */
2104 hr
= ISAXContentHandler_startDocument(content
);
2105 ok(hr
== S_OK
, "got %08x\n", hr
);
2106 /* and get duplicated prolog */
2107 V_VT(&dest
) = VT_EMPTY
;
2108 hr
= IMXWriter_get_output(writer
, &dest
);
2109 ok(hr
== S_OK
, "got %08x\n", hr
);
2110 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2111 ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"
2112 "<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"), V_BSTR(&dest
)),
2113 "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2114 VariantClear(&dest
);
2116 ISAXContentHandler_Release(content
);
2117 IMXWriter_Release(writer
);
2119 /* now with omitted declaration */
2120 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
2121 &IID_IMXWriter
, (void**)&writer
);
2122 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2124 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
2125 ok(hr
== S_OK
, "got %08x\n", hr
);
2127 hr
= IMXWriter_put_omitXMLDeclaration(writer
, VARIANT_TRUE
);
2128 ok(hr
== S_OK
, "got %08x\n", hr
);
2130 hr
= ISAXContentHandler_startDocument(content
);
2131 ok(hr
== S_OK
, "got %08x\n", hr
);
2133 hr
= ISAXContentHandler_endDocument(content
);
2134 ok(hr
== S_OK
, "got %08x\n", hr
);
2136 V_VT(&dest
) = VT_EMPTY
;
2137 hr
= IMXWriter_get_output(writer
, &dest
);
2138 ok(hr
== S_OK
, "got %08x\n", hr
);
2139 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2140 ok(!lstrcmpW(_bstr_(""), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2141 VariantClear(&dest
);
2143 ISAXContentHandler_Release(content
);
2144 IMXWriter_Release(writer
);
2156 struct writer_startendelement_t
{
2158 enum startendtype type
;
2160 const char *local_name
;
2164 ISAXAttributes
*attr
;
2167 static const char startelement_xml
[] = "<uri:local a:attr1=\"a1\" attr2=\"a2\" attr3=\"<&">\">";
2168 static const char startendelement_xml
[] = "<uri:local a:attr1=\"a1\" attr2=\"a2\" attr3=\"<&">\"/>";
2170 static const struct writer_startendelement_t writer_startendelement
[] = {
2172 { &CLSID_MXXMLWriter
, StartElement
, NULL
, NULL
, NULL
, NULL
, E_INVALIDARG
},
2173 { &CLSID_MXXMLWriter30
, StartElement
, NULL
, NULL
, NULL
, NULL
, E_INVALIDARG
},
2174 { &CLSID_MXXMLWriter40
, StartElement
, NULL
, NULL
, NULL
, NULL
, E_INVALIDARG
},
2175 { &CLSID_MXXMLWriter60
, StartElement
, NULL
, NULL
, NULL
, "<>", S_OK
},
2176 { &CLSID_MXXMLWriter
, StartElement
, "uri", NULL
, NULL
, NULL
, E_INVALIDARG
},
2178 { &CLSID_MXXMLWriter30
, StartElement
, "uri", NULL
, NULL
, NULL
, E_INVALIDARG
},
2179 { &CLSID_MXXMLWriter40
, StartElement
, "uri", NULL
, NULL
, NULL
, E_INVALIDARG
},
2180 { &CLSID_MXXMLWriter60
, StartElement
, "uri", NULL
, NULL
, "<>", S_OK
},
2181 { &CLSID_MXXMLWriter
, StartElement
, NULL
, "local", NULL
, NULL
, E_INVALIDARG
},
2182 { &CLSID_MXXMLWriter30
, StartElement
, NULL
, "local", NULL
, NULL
, E_INVALIDARG
},
2184 { &CLSID_MXXMLWriter40
, StartElement
, NULL
, "local", NULL
, NULL
, E_INVALIDARG
},
2185 { &CLSID_MXXMLWriter60
, StartElement
, NULL
, "local", NULL
, "<>", S_OK
},
2186 { &CLSID_MXXMLWriter
, StartElement
, NULL
, NULL
, "qname", NULL
, E_INVALIDARG
},
2187 { &CLSID_MXXMLWriter30
, StartElement
, NULL
, NULL
, "qname", NULL
, E_INVALIDARG
},
2188 { &CLSID_MXXMLWriter40
, StartElement
, NULL
, NULL
, "qname", NULL
, E_INVALIDARG
},
2190 { &CLSID_MXXMLWriter60
, StartElement
, NULL
, NULL
, "qname", "<qname>", S_OK
},
2191 { &CLSID_MXXMLWriter
, StartElement
, "uri", "local", "qname", "<qname>", S_OK
},
2192 { &CLSID_MXXMLWriter30
, StartElement
, "uri", "local", "qname", "<qname>", S_OK
},
2193 { &CLSID_MXXMLWriter40
, StartElement
, "uri", "local", "qname", "<qname>", S_OK
},
2194 { &CLSID_MXXMLWriter60
, StartElement
, "uri", "local", "qname", "<qname>", S_OK
},
2196 { &CLSID_MXXMLWriter
, StartElement
, "uri", "local", NULL
, NULL
, E_INVALIDARG
},
2197 { &CLSID_MXXMLWriter30
, StartElement
, "uri", "local", NULL
, NULL
, E_INVALIDARG
},
2198 { &CLSID_MXXMLWriter40
, StartElement
, "uri", "local", NULL
, NULL
, E_INVALIDARG
},
2199 { &CLSID_MXXMLWriter60
, StartElement
, "uri", "local", NULL
, "<>", S_OK
},
2200 { &CLSID_MXXMLWriter
, StartElement
, "uri", "local", "uri:local", "<uri:local>", S_OK
},
2202 { &CLSID_MXXMLWriter30
, StartElement
, "uri", "local", "uri:local", "<uri:local>", S_OK
},
2203 { &CLSID_MXXMLWriter40
, StartElement
, "uri", "local", "uri:local", "<uri:local>", S_OK
},
2204 { &CLSID_MXXMLWriter60
, StartElement
, "uri", "local", "uri:local", "<uri:local>", S_OK
},
2205 { &CLSID_MXXMLWriter
, StartElement
, "uri", "local", "uri:local2", "<uri:local2>", S_OK
},
2206 { &CLSID_MXXMLWriter30
, StartElement
, "uri", "local", "uri:local2", "<uri:local2>", S_OK
},
2208 { &CLSID_MXXMLWriter40
, StartElement
, "uri", "local", "uri:local2", "<uri:local2>", S_OK
},
2209 { &CLSID_MXXMLWriter60
, StartElement
, "uri", "local", "uri:local2", "<uri:local2>", S_OK
},
2210 /* endElement tests */
2211 { &CLSID_MXXMLWriter
, EndElement
, NULL
, NULL
, NULL
, NULL
, E_INVALIDARG
},
2212 { &CLSID_MXXMLWriter30
, EndElement
, NULL
, NULL
, NULL
, NULL
, E_INVALIDARG
},
2213 { &CLSID_MXXMLWriter40
, EndElement
, NULL
, NULL
, NULL
, NULL
, E_INVALIDARG
},
2215 { &CLSID_MXXMLWriter60
, EndElement
, NULL
, NULL
, NULL
, "</>", S_OK
},
2216 { &CLSID_MXXMLWriter
, EndElement
, "uri", NULL
, NULL
, NULL
, E_INVALIDARG
},
2217 { &CLSID_MXXMLWriter30
, EndElement
, "uri", NULL
, NULL
, NULL
, E_INVALIDARG
},
2218 { &CLSID_MXXMLWriter40
, EndElement
, "uri", NULL
, NULL
, NULL
, E_INVALIDARG
},
2219 { &CLSID_MXXMLWriter60
, EndElement
, "uri", NULL
, NULL
, "</>", S_OK
},
2221 { &CLSID_MXXMLWriter
, EndElement
, NULL
, "local", NULL
, NULL
, E_INVALIDARG
},
2222 { &CLSID_MXXMLWriter30
, EndElement
, NULL
, "local", NULL
, NULL
, E_INVALIDARG
},
2223 { &CLSID_MXXMLWriter40
, EndElement
, NULL
, "local", NULL
, NULL
, E_INVALIDARG
},
2224 { &CLSID_MXXMLWriter60
, EndElement
, NULL
, "local", NULL
, "</>", S_OK
},
2225 { &CLSID_MXXMLWriter
, EndElement
, NULL
, NULL
, "qname", NULL
, E_INVALIDARG
},
2227 { &CLSID_MXXMLWriter30
, EndElement
, NULL
, NULL
, "qname", NULL
, E_INVALIDARG
},
2228 { &CLSID_MXXMLWriter40
, EndElement
, NULL
, NULL
, "qname", NULL
, E_INVALIDARG
},
2229 { &CLSID_MXXMLWriter60
, EndElement
, NULL
, NULL
, "qname", "</qname>", S_OK
},
2230 { &CLSID_MXXMLWriter
, EndElement
, "uri", "local", "qname", "</qname>", S_OK
},
2231 { &CLSID_MXXMLWriter30
, EndElement
, "uri", "local", "qname", "</qname>", S_OK
},
2233 { &CLSID_MXXMLWriter40
, EndElement
, "uri", "local", "qname", "</qname>", S_OK
},
2234 { &CLSID_MXXMLWriter60
, EndElement
, "uri", "local", "qname", "</qname>", S_OK
},
2235 { &CLSID_MXXMLWriter
, EndElement
, "uri", "local", NULL
, NULL
, E_INVALIDARG
},
2236 { &CLSID_MXXMLWriter30
, EndElement
, "uri", "local", NULL
, NULL
, E_INVALIDARG
},
2237 { &CLSID_MXXMLWriter40
, EndElement
, "uri", "local", NULL
, NULL
, E_INVALIDARG
},
2239 { &CLSID_MXXMLWriter60
, EndElement
, "uri", "local", NULL
, "</>", S_OK
},
2240 { &CLSID_MXXMLWriter
, EndElement
, "uri", "local", "uri:local", "</uri:local>", S_OK
},
2241 { &CLSID_MXXMLWriter30
, EndElement
, "uri", "local", "uri:local", "</uri:local>", S_OK
},
2242 { &CLSID_MXXMLWriter40
, EndElement
, "uri", "local", "uri:local", "</uri:local>", S_OK
},
2243 { &CLSID_MXXMLWriter60
, EndElement
, "uri", "local", "uri:local", "</uri:local>", S_OK
},
2245 { &CLSID_MXXMLWriter
, EndElement
, "uri", "local", "uri:local2", "</uri:local2>", S_OK
},
2246 { &CLSID_MXXMLWriter30
, EndElement
, "uri", "local", "uri:local2", "</uri:local2>", S_OK
},
2247 { &CLSID_MXXMLWriter40
, EndElement
, "uri", "local", "uri:local2", "</uri:local2>", S_OK
},
2248 { &CLSID_MXXMLWriter60
, EndElement
, "uri", "local", "uri:local2", "</uri:local2>", S_OK
},
2250 /* with attributes */
2251 { &CLSID_MXXMLWriter
, StartElement
, "uri", "local", "uri:local", startelement_xml
, S_OK
, &saxattributes
},
2253 { &CLSID_MXXMLWriter30
, StartElement
, "uri", "local", "uri:local", startelement_xml
, S_OK
, &saxattributes
},
2254 { &CLSID_MXXMLWriter40
, StartElement
, "uri", "local", "uri:local", startelement_xml
, S_OK
, &saxattributes
},
2255 { &CLSID_MXXMLWriter60
, StartElement
, "uri", "local", "uri:local", startelement_xml
, S_OK
, &saxattributes
},
2256 /* empty elements */
2257 { &CLSID_MXXMLWriter
, StartEndElement
, "uri", "local", "uri:local", startendelement_xml
, S_OK
, &saxattributes
},
2258 { &CLSID_MXXMLWriter30
, StartEndElement
, "uri", "local", "uri:local", startendelement_xml
, S_OK
, &saxattributes
},
2260 { &CLSID_MXXMLWriter40
, StartEndElement
, "uri", "local", "uri:local", startendelement_xml
, S_OK
, &saxattributes
},
2261 { &CLSID_MXXMLWriter60
, StartEndElement
, "uri", "local", "uri:local", startendelement_xml
, S_OK
, &saxattributes
},
2262 { &CLSID_MXXMLWriter
, StartEndElement
, "", "", "", "</>", S_OK
},
2263 { &CLSID_MXXMLWriter30
, StartEndElement
, "", "", "", "</>", S_OK
},
2264 { &CLSID_MXXMLWriter40
, StartEndElement
, "", "", "", "</>", S_OK
},
2266 { &CLSID_MXXMLWriter60
, StartEndElement
, "", "", "", "</>", S_OK
},
2270 static void get_mxwriter_support_data(struct msxmlsupported_data_t
*table
)
2272 while (table
->clsid
)
2277 hr
= CoCreateInstance(table
->clsid
, NULL
, CLSCTX_INPROC_SERVER
,
2278 &IID_IMXWriter
, (void**)&writer
);
2279 if (hr
== S_OK
) IMXWriter_Release(writer
);
2281 table
->supported
= hr
== S_OK
;
2282 if (hr
!= S_OK
) win_skip("class %s not supported\n", table
->name
);
2288 static void get_mxattributes_support_data(struct msxmlsupported_data_t
*table
)
2290 while (table
->clsid
)
2292 IMXAttributes
*attr
;
2295 hr
= CoCreateInstance(table
->clsid
, NULL
, CLSCTX_INPROC_SERVER
,
2296 &IID_IMXAttributes
, (void**)&attr
);
2297 if (hr
== S_OK
) IMXAttributes_Release(attr
);
2299 table
->supported
= hr
== S_OK
;
2300 if (hr
!= S_OK
) skip("class %s not supported\n", table
->name
);
2306 static void test_mxwriter_startendelement_batch(const struct writer_startendelement_t
*table
)
2310 while (table
->clsid
)
2312 ISAXContentHandler
*content
;
2316 if (!is_clsid_supported(table
->clsid
, mxwriter_support_data
))
2323 hr
= CoCreateInstance(table
->clsid
, NULL
, CLSCTX_INPROC_SERVER
,
2324 &IID_IMXWriter
, (void**)&writer
);
2325 EXPECT_HR(hr
, S_OK
);
2327 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
2328 EXPECT_HR(hr
, S_OK
);
2330 hr
= IMXWriter_put_omitXMLDeclaration(writer
, VARIANT_TRUE
);
2331 EXPECT_HR(hr
, S_OK
);
2333 hr
= ISAXContentHandler_startDocument(content
);
2334 EXPECT_HR(hr
, S_OK
);
2336 if (table
->type
== StartElement
)
2338 hr
= ISAXContentHandler_startElement(content
, _bstr_(table
->uri
), lstrlen(table
->uri
),
2339 _bstr_(table
->local_name
), lstrlen(table
->local_name
), _bstr_(table
->qname
), lstrlen(table
->qname
), table
->attr
);
2340 ok(hr
== table
->hr
, "test %d: got 0x%08x, expected 0x%08x\n", i
, hr
, table
->hr
);
2342 else if (table
->type
== EndElement
)
2344 hr
= ISAXContentHandler_endElement(content
, _bstr_(table
->uri
), lstrlen(table
->uri
),
2345 _bstr_(table
->local_name
), lstrlen(table
->local_name
), _bstr_(table
->qname
), lstrlen(table
->qname
));
2346 ok(hr
== table
->hr
, "test %d: got 0x%08x, expected 0x%08x\n", i
, hr
, table
->hr
);
2350 hr
= ISAXContentHandler_startElement(content
, _bstr_(table
->uri
), lstrlen(table
->uri
),
2351 _bstr_(table
->local_name
), lstrlen(table
->local_name
), _bstr_(table
->qname
), lstrlen(table
->qname
), table
->attr
);
2352 ok(hr
== table
->hr
, "test %d: got 0x%08x, expected 0x%08x\n", i
, hr
, table
->hr
);
2353 hr
= ISAXContentHandler_endElement(content
, _bstr_(table
->uri
), lstrlen(table
->uri
),
2354 _bstr_(table
->local_name
), lstrlen(table
->local_name
), _bstr_(table
->qname
), lstrlen(table
->qname
));
2355 ok(hr
== table
->hr
, "test %d: got 0x%08x, expected 0x%08x\n", i
, hr
, table
->hr
);
2363 V_VT(&dest
) = VT_EMPTY
;
2364 hr
= IMXWriter_get_output(writer
, &dest
);
2365 EXPECT_HR(hr
, S_OK
);
2366 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2367 ok(!lstrcmpW(_bstr_(table
->output
), V_BSTR(&dest
)),
2368 "test %d: got wrong content %s, expected %s\n", i
, wine_dbgstr_w(V_BSTR(&dest
)), table
->output
);
2369 VariantClear(&dest
);
2372 ISAXContentHandler_Release(content
);
2373 IMXWriter_Release(writer
);
2382 static void test_mxwriter_startendelement(void)
2384 ISAXContentHandler
*content
;
2389 test_mxwriter_startendelement_batch(writer_startendelement
);
2391 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
2392 &IID_IMXWriter
, (void**)&writer
);
2393 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2395 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
2396 ok(hr
== S_OK
, "got %08x\n", hr
);
2398 hr
= IMXWriter_put_omitXMLDeclaration(writer
, VARIANT_TRUE
);
2399 ok(hr
== S_OK
, "got %08x\n", hr
);
2401 hr
= ISAXContentHandler_startDocument(content
);
2402 ok(hr
== S_OK
, "got %08x\n", hr
);
2404 /* all string pointers should be not null */
2405 hr
= ISAXContentHandler_startElement(content
, _bstr_(""), 0, _bstr_("b"), 1, _bstr_(""), 0, NULL
);
2406 ok(hr
== S_OK
, "got %08x\n", hr
);
2408 V_VT(&dest
) = VT_EMPTY
;
2409 hr
= IMXWriter_get_output(writer
, &dest
);
2410 ok(hr
== S_OK
, "got %08x\n", hr
);
2411 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2412 ok(!lstrcmpW(_bstr_("<>"), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2413 VariantClear(&dest
);
2415 hr
= ISAXContentHandler_startElement(content
, _bstr_(""), 0, _bstr_(""), 0, _bstr_("b"), 1, NULL
);
2416 ok(hr
== S_OK
, "got %08x\n", hr
);
2418 V_VT(&dest
) = VT_EMPTY
;
2419 hr
= IMXWriter_get_output(writer
, &dest
);
2420 ok(hr
== S_OK
, "got %08x\n", hr
);
2421 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2422 ok(!lstrcmpW(_bstr_("<><b>"), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2423 VariantClear(&dest
);
2425 hr
= ISAXContentHandler_endElement(content
, NULL
, 0, NULL
, 0, _bstr_("a:b"), 3);
2426 EXPECT_HR(hr
, E_INVALIDARG
);
2428 hr
= ISAXContentHandler_endElement(content
, NULL
, 0, _bstr_("b"), 1, _bstr_("a:b"), 3);
2429 EXPECT_HR(hr
, E_INVALIDARG
);
2431 /* only local name is an error too */
2432 hr
= ISAXContentHandler_endElement(content
, NULL
, 0, _bstr_("b"), 1, NULL
, 0);
2433 EXPECT_HR(hr
, E_INVALIDARG
);
2435 hr
= ISAXContentHandler_endElement(content
, _bstr_(""), 0, _bstr_(""), 0, _bstr_("b"), 1);
2436 EXPECT_HR(hr
, S_OK
);
2438 V_VT(&dest
) = VT_EMPTY
;
2439 hr
= IMXWriter_get_output(writer
, &dest
);
2440 EXPECT_HR(hr
, S_OK
);
2441 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2442 ok(!lstrcmpW(_bstr_("<><b></b>"), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2443 VariantClear(&dest
);
2445 hr
= ISAXContentHandler_endDocument(content
);
2446 EXPECT_HR(hr
, S_OK
);
2448 V_VT(&dest
) = VT_EMPTY
;
2449 hr
= IMXWriter_put_output(writer
, dest
);
2450 EXPECT_HR(hr
, S_OK
);
2452 V_VT(&dest
) = VT_EMPTY
;
2453 hr
= IMXWriter_get_output(writer
, &dest
);
2454 EXPECT_HR(hr
, S_OK
);
2455 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2456 ok(!lstrcmpW(_bstr_(""), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2457 VariantClear(&dest
);
2459 hr
= ISAXContentHandler_startDocument(content
);
2460 EXPECT_HR(hr
, S_OK
);
2462 hr
= ISAXContentHandler_startElement(content
, _bstr_(""), 0, _bstr_(""), 0, _bstr_("abcdef"), 3, NULL
);
2463 EXPECT_HR(hr
, S_OK
);
2465 V_VT(&dest
) = VT_EMPTY
;
2466 hr
= IMXWriter_get_output(writer
, &dest
);
2467 EXPECT_HR(hr
, S_OK
);
2468 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2469 ok(!lstrcmpW(_bstr_("<abc>"), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2470 VariantClear(&dest
);
2472 ISAXContentHandler_endDocument(content
);
2473 IMXWriter_flush(writer
);
2475 hr
= ISAXContentHandler_endElement(content
, _bstr_(""), 0, _bstr_(""), 0, _bstr_("abdcdef"), 3);
2476 EXPECT_HR(hr
, S_OK
);
2477 V_VT(&dest
) = VT_EMPTY
;
2478 hr
= IMXWriter_get_output(writer
, &dest
);
2479 EXPECT_HR(hr
, S_OK
);
2480 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2481 ok(!lstrcmpW(_bstr_("<abc></abd>"), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2482 VariantClear(&dest
);
2484 ISAXContentHandler_Release(content
);
2485 IMXWriter_Release(writer
);
2489 struct writer_characters_t
{
2495 static const struct writer_characters_t writer_characters
[] = {
2496 { &CLSID_MXXMLWriter
, "< > & \"", "< > & \"" },
2497 { &CLSID_MXXMLWriter30
, "< > & \"", "< > & \"" },
2498 { &CLSID_MXXMLWriter40
, "< > & \"", "< > & \"" },
2499 { &CLSID_MXXMLWriter60
, "< > & \"", "< > & \"" },
2503 static void test_mxwriter_characters(void)
2505 static const WCHAR chardataW
[] = {'T','E','S','T','C','H','A','R','D','A','T','A',' ','.',0};
2506 const struct writer_characters_t
*table
= writer_characters
;
2507 ISAXContentHandler
*content
;
2513 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
2514 &IID_IMXWriter
, (void**)&writer
);
2515 EXPECT_HR(hr
, S_OK
);
2517 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
2518 EXPECT_HR(hr
, S_OK
);
2520 hr
= IMXWriter_put_omitXMLDeclaration(writer
, VARIANT_TRUE
);
2521 EXPECT_HR(hr
, S_OK
);
2523 hr
= ISAXContentHandler_startDocument(content
);
2524 EXPECT_HR(hr
, S_OK
);
2526 hr
= ISAXContentHandler_characters(content
, NULL
, 0);
2527 EXPECT_HR(hr
, E_INVALIDARG
);
2529 hr
= ISAXContentHandler_characters(content
, chardataW
, 0);
2530 EXPECT_HR(hr
, S_OK
);
2532 hr
= ISAXContentHandler_characters(content
, chardataW
, sizeof(chardataW
)/sizeof(WCHAR
) - 1);
2533 EXPECT_HR(hr
, S_OK
);
2535 V_VT(&dest
) = VT_EMPTY
;
2536 hr
= IMXWriter_get_output(writer
, &dest
);
2537 EXPECT_HR(hr
, S_OK
);
2538 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2539 ok(!lstrcmpW(_bstr_("TESTCHARDATA ."), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2540 VariantClear(&dest
);
2542 hr
= ISAXContentHandler_endDocument(content
);
2543 EXPECT_HR(hr
, S_OK
);
2545 ISAXContentHandler_Release(content
);
2546 IMXWriter_Release(writer
);
2548 /* try empty characters data to see if element is closed */
2549 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
2550 &IID_IMXWriter
, (void**)&writer
);
2551 EXPECT_HR(hr
, S_OK
);
2553 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
2554 EXPECT_HR(hr
, S_OK
);
2556 hr
= IMXWriter_put_omitXMLDeclaration(writer
, VARIANT_TRUE
);
2557 EXPECT_HR(hr
, S_OK
);
2559 hr
= ISAXContentHandler_startDocument(content
);
2560 EXPECT_HR(hr
, S_OK
);
2562 hr
= ISAXContentHandler_startElement(content
, _bstr_(""), 0, _bstr_(""), 0, _bstr_("a"), 1, NULL
);
2563 EXPECT_HR(hr
, S_OK
);
2565 hr
= ISAXContentHandler_characters(content
, chardataW
, 0);
2566 EXPECT_HR(hr
, S_OK
);
2568 hr
= ISAXContentHandler_endElement(content
, _bstr_(""), 0, _bstr_(""), 0, _bstr_("a"), 1);
2569 EXPECT_HR(hr
, S_OK
);
2571 V_VT(&dest
) = VT_EMPTY
;
2572 hr
= IMXWriter_get_output(writer
, &dest
);
2573 EXPECT_HR(hr
, S_OK
);
2574 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2575 ok(!lstrcmpW(_bstr_("<a></a>"), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2576 VariantClear(&dest
);
2578 ISAXContentHandler_Release(content
);
2579 IMXWriter_Release(writer
);
2582 while (table
->clsid
)
2584 ISAXContentHandler
*content
;
2588 if (!is_clsid_supported(table
->clsid
, mxwriter_support_data
))
2595 hr
= CoCreateInstance(table
->clsid
, NULL
, CLSCTX_INPROC_SERVER
,
2596 &IID_IMXWriter
, (void**)&writer
);
2597 EXPECT_HR(hr
, S_OK
);
2599 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
2600 EXPECT_HR(hr
, S_OK
);
2602 hr
= IMXWriter_put_omitXMLDeclaration(writer
, VARIANT_TRUE
);
2603 EXPECT_HR(hr
, S_OK
);
2605 hr
= ISAXContentHandler_startDocument(content
);
2606 EXPECT_HR(hr
, S_OK
);
2608 hr
= ISAXContentHandler_characters(content
, _bstr_(table
->data
), strlen(table
->data
));
2609 EXPECT_HR(hr
, S_OK
);
2616 V_VT(&dest
) = VT_EMPTY
;
2617 hr
= IMXWriter_get_output(writer
, &dest
);
2618 EXPECT_HR(hr
, S_OK
);
2619 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
2620 ok(!lstrcmpW(_bstr_(table
->output
), V_BSTR(&dest
)),
2621 "test %d: got wrong content %s, expected %s\n", i
, wine_dbgstr_w(V_BSTR(&dest
)), table
->output
);
2622 VariantClear(&dest
);
2632 static const mxwriter_stream_test mxwriter_stream_tests
[] = {
2634 VARIANT_TRUE
,"UTF-16",
2636 {FALSE
,(const BYTE
*)szUtf16BOM
,sizeof(szUtf16BOM
),TRUE
},
2637 {FALSE
,(const BYTE
*)szUtf16XML
,sizeof(szUtf16XML
)},
2642 VARIANT_FALSE
,"UTF-16",
2644 {FALSE
,(const BYTE
*)szUtf16XML
,sizeof(szUtf16XML
)},
2649 VARIANT_TRUE
,"UTF-8",
2651 {FALSE
,(const BYTE
*)szUtf8XML
,sizeof(szUtf8XML
)-1},
2652 /* For some reason Windows makes an empty write call when UTF-8 encoding is used
2653 * and the writer is released.
2660 VARIANT_TRUE
,"utf-8",
2662 {FALSE
,(const BYTE
*)utf8xml2
,sizeof(utf8xml2
)-1},
2663 /* For some reason Windows makes an empty write call when UTF-8 encoding is used
2664 * and the writer is released.
2671 VARIANT_TRUE
,"UTF-16",
2673 {FALSE
,(const BYTE
*)szUtf16BOM
,sizeof(szUtf16BOM
),TRUE
},
2674 {FALSE
,(const BYTE
*)szUtf16XML
,sizeof(szUtf16XML
)},
2679 VARIANT_TRUE
,"UTF-16",
2681 {FALSE
,(const BYTE
*)szUtf16BOM
,sizeof(szUtf16BOM
),TRUE
,TRUE
},
2682 {FALSE
,(const BYTE
*)szUtf16XML
,sizeof(szUtf16XML
)},
2688 static void test_mxwriter_stream(void)
2691 ISAXContentHandler
*content
;
2696 ULARGE_INTEGER pos2
;
2697 DWORD test_count
= sizeof(mxwriter_stream_tests
)/sizeof(mxwriter_stream_tests
[0]);
2699 for(current_stream_test_index
= 0; current_stream_test_index
< test_count
; ++current_stream_test_index
) {
2700 const mxwriter_stream_test
*test
= mxwriter_stream_tests
+current_stream_test_index
;
2702 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
2703 &IID_IMXWriter
, (void**)&writer
);
2704 ok(hr
== S_OK
, "CoCreateInstance failed: %08x\n", hr
);
2706 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
2707 ok(hr
== S_OK
, "QueryInterface(ISAXContentHandler) failed: %08x\n", hr
);
2709 hr
= IMXWriter_put_encoding(writer
, _bstr_(test
->encoding
));
2710 ok(hr
== S_OK
, "put_encoding failed with %08x on test %d\n", hr
, current_stream_test_index
);
2712 V_VT(&dest
) = VT_UNKNOWN
;
2713 V_UNKNOWN(&dest
) = (IUnknown
*)&mxstream
;
2714 hr
= IMXWriter_put_output(writer
, dest
);
2715 ok(hr
== S_OK
, "put_output failed with %08x on test %d\n", hr
, current_stream_test_index
);
2716 VariantClear(&dest
);
2718 hr
= IMXWriter_put_byteOrderMark(writer
, test
->bom
);
2719 ok(hr
== S_OK
, "put_byteOrderMark failed with %08x on test %d\n", hr
, current_stream_test_index
);
2721 current_write_test
= test
->expected_writes
;
2723 hr
= ISAXContentHandler_startDocument(content
);
2724 ok(hr
== S_OK
, "startDocument failed with %08x on test %d\n", hr
, current_stream_test_index
);
2726 hr
= ISAXContentHandler_endDocument(content
);
2727 ok(hr
== S_OK
, "endDocument failed with %08x on test %d\n", hr
, current_stream_test_index
);
2729 ISAXContentHandler_Release(content
);
2730 IMXWriter_Release(writer
);
2732 ok(current_write_test
->last
, "The last %d write calls on test %d were missed\n",
2733 (int)(current_write_test
-test
->expected_writes
), current_stream_test_index
);
2736 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
2737 &IID_IMXWriter
, (void**)&writer
);
2738 ok(hr
== S_OK
, "CoCreateInstance failed: %08x\n", hr
);
2740 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
2741 ok(hr
== S_OK
, "CreateStreamOnHGlobal failed: %08x\n", hr
);
2743 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
2744 ok(hr
== S_OK
, "QueryInterface(ISAXContentHandler) failed: %08x\n", hr
);
2746 hr
= IMXWriter_put_encoding(writer
, _bstr_("UTF-8"));
2747 ok(hr
== S_OK
, "put_encoding failed: %08x\n", hr
);
2749 V_VT(&dest
) = VT_UNKNOWN
;
2750 V_UNKNOWN(&dest
) = (IUnknown
*)stream
;
2751 hr
= IMXWriter_put_output(writer
, dest
);
2752 ok(hr
== S_OK
, "put_output failed: %08x\n", hr
);
2754 hr
= ISAXContentHandler_startDocument(content
);
2755 ok(hr
== S_OK
, "startDocument failed: %08x\n", hr
);
2757 /* Setting output of the mxwriter causes the current output to be flushed,
2758 * and the writer to start over.
2760 V_VT(&dest
) = VT_EMPTY
;
2761 hr
= IMXWriter_put_output(writer
, dest
);
2762 ok(hr
== S_OK
, "put_output failed: %08x\n", hr
);
2765 hr
= IStream_Seek(stream
, pos
, STREAM_SEEK_CUR
, &pos2
);
2766 ok(hr
== S_OK
, "Seek failed: %08x\n", hr
);
2767 ok(pos2
.QuadPart
!= 0, "expected stream position moved\n");
2769 hr
= ISAXContentHandler_startDocument(content
);
2770 ok(hr
== S_OK
, "startDocument failed: %08x\n", hr
);
2772 hr
= ISAXContentHandler_endDocument(content
);
2773 ok(hr
== S_OK
, "endDocument failed: %08x\n", hr
);
2775 V_VT(&dest
) = VT_EMPTY
;
2776 hr
= IMXWriter_get_output(writer
, &dest
);
2777 ok(hr
== S_OK
, "get_output failed: %08x\n", hr
);
2778 ok(V_VT(&dest
) == VT_BSTR
, "Expected VT_BSTR, got %d\n", V_VT(&dest
));
2779 ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"), V_BSTR(&dest
)),
2780 "Got wrong content: %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2781 VariantClear(&dest
);
2783 /* test when BOM is written to output stream */
2784 V_VT(&dest
) = VT_EMPTY
;
2785 hr
= IMXWriter_put_output(writer
, dest
);
2786 EXPECT_HR(hr
, S_OK
);
2789 hr
= IStream_Seek(stream
, pos
, STREAM_SEEK_SET
, NULL
);
2790 EXPECT_HR(hr
, S_OK
);
2792 V_VT(&dest
) = VT_UNKNOWN
;
2793 V_UNKNOWN(&dest
) = (IUnknown
*)stream
;
2794 hr
= IMXWriter_put_output(writer
, dest
);
2795 EXPECT_HR(hr
, S_OK
);
2797 hr
= IMXWriter_put_byteOrderMark(writer
, VARIANT_TRUE
);
2798 EXPECT_HR(hr
, S_OK
);
2800 hr
= IMXWriter_put_encoding(writer
, _bstr_("UTF-16"));
2801 EXPECT_HR(hr
, S_OK
);
2803 hr
= ISAXContentHandler_startDocument(content
);
2804 EXPECT_HR(hr
, S_OK
);
2808 hr
= IStream_Seek(stream
, pos
, STREAM_SEEK_CUR
, &pos2
);
2809 EXPECT_HR(hr
, S_OK
);
2810 ok(pos2
.QuadPart
== 2, "got wrong position\n");
2812 ISAXContentHandler_Release(content
);
2813 IMXWriter_Release(writer
);
2818 static void test_mxwriter_encoding(void)
2820 ISAXContentHandler
*content
;
2829 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
2830 &IID_IMXWriter
, (void**)&writer
);
2831 EXPECT_HR(hr
, S_OK
);
2833 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
2834 EXPECT_HR(hr
, S_OK
);
2836 hr
= IMXWriter_put_encoding(writer
, _bstr_("UTF-8"));
2837 EXPECT_HR(hr
, S_OK
);
2839 hr
= ISAXContentHandler_startDocument(content
);
2840 EXPECT_HR(hr
, S_OK
);
2842 hr
= ISAXContentHandler_endDocument(content
);
2843 EXPECT_HR(hr
, S_OK
);
2845 /* The content is always re-encoded to UTF-16 when the output is
2846 * retrieved as a BSTR.
2848 V_VT(&dest
) = VT_EMPTY
;
2849 hr
= IMXWriter_get_output(writer
, &dest
);
2850 EXPECT_HR(hr
, S_OK
);
2851 ok(V_VT(&dest
) == VT_BSTR
, "Expected VT_BSTR, got %d\n", V_VT(&dest
));
2852 ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"), V_BSTR(&dest
)),
2853 "got wrong content: %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
2854 VariantClear(&dest
);
2856 /* switch encoding when something is written already */
2857 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
2858 EXPECT_HR(hr
, S_OK
);
2860 V_VT(&dest
) = VT_UNKNOWN
;
2861 V_UNKNOWN(&dest
) = (IUnknown
*)stream
;
2862 hr
= IMXWriter_put_output(writer
, dest
);
2863 EXPECT_HR(hr
, S_OK
);
2865 hr
= IMXWriter_put_encoding(writer
, _bstr_("UTF-8"));
2866 EXPECT_HR(hr
, S_OK
);
2868 /* write empty element */
2869 hr
= ISAXContentHandler_startElement(content
, _bstr_(""), 0, _bstr_(""), 0, _bstr_("a"), 1, NULL
);
2870 EXPECT_HR(hr
, S_OK
);
2872 hr
= ISAXContentHandler_endElement(content
, _bstr_(""), 0, _bstr_(""), 0, _bstr_("a"), 1);
2873 EXPECT_HR(hr
, S_OK
);
2876 hr
= IMXWriter_put_encoding(writer
, _bstr_("UTF-16"));
2877 EXPECT_HR(hr
, S_OK
);
2879 hr
= IMXWriter_flush(writer
);
2880 EXPECT_HR(hr
, S_OK
);
2882 hr
= GetHGlobalFromStream(stream
, &g
);
2883 EXPECT_HR(hr
, S_OK
);
2885 ptr
= GlobalLock(g
);
2886 ok(!strncmp(ptr
, "<a/>", 4), "got %c%c%c%c\n", ptr
[0],ptr
[1],ptr
[2],ptr
[3]);
2889 /* so output is unaffected, encoding name is stored however */
2890 hr
= IMXWriter_get_encoding(writer
, &s
);
2891 EXPECT_HR(hr
, S_OK
);
2892 ok(!lstrcmpW(s
, _bstr_("UTF-16")), "got %s\n", wine_dbgstr_w(s
));
2895 IStream_Release(stream
);
2897 ISAXContentHandler_Release(content
);
2898 IMXWriter_Release(writer
);
2903 static void test_obj_dispex(IUnknown
*obj
)
2905 static const WCHAR starW
[] = {'*',0};
2906 DISPID dispid
= DISPID_SAX_XMLREADER_GETFEATURE
;
2907 IDispatchEx
*dispex
;
2914 hr
= IUnknown_QueryInterface(obj
, &IID_IDispatchEx
, (void**)&dispex
);
2915 EXPECT_HR(hr
, S_OK
);
2916 if (FAILED(hr
)) return;
2919 hr
= IDispatchEx_GetTypeInfoCount(dispex
, &ticnt
);
2920 EXPECT_HR(hr
, S_OK
);
2921 ok(ticnt
== 1, "ticnt=%u\n", ticnt
);
2923 name
= SysAllocString(starW
);
2924 hr
= IDispatchEx_DeleteMemberByName(dispex
, name
, fdexNameCaseSensitive
);
2925 EXPECT_HR(hr
, E_NOTIMPL
);
2926 SysFreeString(name
);
2928 hr
= IDispatchEx_DeleteMemberByDispID(dispex
, dispid
);
2929 EXPECT_HR(hr
, E_NOTIMPL
);
2932 hr
= IDispatchEx_GetMemberProperties(dispex
, dispid
, grfdexPropCanAll
, &props
);
2933 EXPECT_HR(hr
, E_NOTIMPL
);
2934 ok(props
== 0, "expected 0 got %d\n", props
);
2936 hr
= IDispatchEx_GetMemberName(dispex
, dispid
, &name
);
2937 EXPECT_HR(hr
, E_NOTIMPL
);
2938 if (SUCCEEDED(hr
)) SysFreeString(name
);
2940 hr
= IDispatchEx_GetNextDispID(dispex
, fdexEnumDefault
, DISPID_SAX_XMLREADER_GETFEATURE
, &dispid
);
2941 EXPECT_HR(hr
, E_NOTIMPL
);
2943 hr
= IDispatchEx_GetNameSpaceParent(dispex
, &unk
);
2944 EXPECT_HR(hr
, E_NOTIMPL
);
2945 if (hr
== S_OK
&& unk
) IUnknown_Release(unk
);
2947 IDispatchEx_Release(dispex
);
2950 static void test_dispex(void)
2952 IVBSAXXMLReader
*vbreader
;
2953 ISAXXMLReader
*reader
;
2957 hr
= CoCreateInstance(&CLSID_SAXXMLReader
, NULL
, CLSCTX_INPROC_SERVER
,
2958 &IID_ISAXXMLReader
, (void**)&reader
);
2959 EXPECT_HR(hr
, S_OK
);
2961 hr
= ISAXXMLReader_QueryInterface(reader
, &IID_IUnknown
, (void**)&unk
);
2962 EXPECT_HR(hr
, S_OK
);
2963 test_obj_dispex(unk
);
2964 IUnknown_Release(unk
);
2966 hr
= ISAXXMLReader_QueryInterface(reader
, &IID_IVBSAXXMLReader
, (void**)&vbreader
);
2967 EXPECT_HR(hr
, S_OK
);
2968 hr
= IVBSAXXMLReader_QueryInterface(vbreader
, &IID_IUnknown
, (void**)&unk
);
2969 EXPECT_HR(hr
, S_OK
);
2970 test_obj_dispex(unk
);
2971 IUnknown_Release(unk
);
2972 IVBSAXXMLReader_Release(vbreader
);
2974 ISAXXMLReader_Release(reader
);
2977 static void test_mxwriter_dispex(void)
2979 IDispatchEx
*dispex
;
2984 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
2985 &IID_IMXWriter
, (void**)&writer
);
2986 EXPECT_HR(hr
, S_OK
);
2988 hr
= IMXWriter_QueryInterface(writer
, &IID_IDispatchEx
, (void**)&dispex
);
2989 EXPECT_HR(hr
, S_OK
);
2990 hr
= IDispatchEx_QueryInterface(dispex
, &IID_IUnknown
, (void**)&unk
);
2991 test_obj_dispex(unk
);
2992 IUnknown_Release(unk
);
2993 IDispatchEx_Release(dispex
);
2995 IMXWriter_Release(writer
);
2998 static void test_mxwriter_comment(void)
3000 static const WCHAR commentW
[] = {'c','o','m','m','e','n','t',0};
3001 ISAXContentHandler
*content
;
3002 ISAXLexicalHandler
*lexical
;
3007 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
3008 &IID_IMXWriter
, (void**)&writer
);
3009 EXPECT_HR(hr
, S_OK
);
3011 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
3012 EXPECT_HR(hr
, S_OK
);
3014 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXLexicalHandler
, (void**)&lexical
);
3015 EXPECT_HR(hr
, S_OK
);
3017 hr
= IMXWriter_put_omitXMLDeclaration(writer
, VARIANT_TRUE
);
3018 EXPECT_HR(hr
, S_OK
);
3020 hr
= ISAXContentHandler_startDocument(content
);
3021 EXPECT_HR(hr
, S_OK
);
3023 hr
= ISAXLexicalHandler_comment(lexical
, NULL
, 0);
3024 EXPECT_HR(hr
, E_INVALIDARG
);
3026 hr
= ISAXLexicalHandler_comment(lexical
, commentW
, 0);
3027 EXPECT_HR(hr
, S_OK
);
3029 V_VT(&dest
) = VT_EMPTY
;
3030 hr
= IMXWriter_get_output(writer
, &dest
);
3031 EXPECT_HR(hr
, S_OK
);
3032 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
3033 ok(!lstrcmpW(_bstr_("<!---->\r\n"), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
3034 VariantClear(&dest
);
3036 hr
= ISAXLexicalHandler_comment(lexical
, commentW
, sizeof(commentW
)/sizeof(WCHAR
)-1);
3037 EXPECT_HR(hr
, S_OK
);
3039 V_VT(&dest
) = VT_EMPTY
;
3040 hr
= IMXWriter_get_output(writer
, &dest
);
3041 EXPECT_HR(hr
, S_OK
);
3042 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
3043 ok(!lstrcmpW(_bstr_("<!---->\r\n<!--comment-->\r\n"), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
3044 VariantClear(&dest
);
3046 ISAXContentHandler_Release(content
);
3047 ISAXLexicalHandler_Release(lexical
);
3048 IMXWriter_Release(writer
);
3052 static void test_mxwriter_cdata(void)
3054 ISAXContentHandler
*content
;
3055 ISAXLexicalHandler
*lexical
;
3060 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
3061 &IID_IMXWriter
, (void**)&writer
);
3062 EXPECT_HR(hr
, S_OK
);
3064 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
3065 EXPECT_HR(hr
, S_OK
);
3067 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXLexicalHandler
, (void**)&lexical
);
3068 EXPECT_HR(hr
, S_OK
);
3070 hr
= IMXWriter_put_omitXMLDeclaration(writer
, VARIANT_TRUE
);
3071 EXPECT_HR(hr
, S_OK
);
3073 hr
= ISAXContentHandler_startDocument(content
);
3074 EXPECT_HR(hr
, S_OK
);
3076 hr
= ISAXLexicalHandler_startCDATA(lexical
);
3077 EXPECT_HR(hr
, S_OK
);
3079 V_VT(&dest
) = VT_EMPTY
;
3080 hr
= IMXWriter_get_output(writer
, &dest
);
3081 EXPECT_HR(hr
, S_OK
);
3082 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
3083 ok(!lstrcmpW(_bstr_("<![CDATA["), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
3084 VariantClear(&dest
);
3086 hr
= ISAXLexicalHandler_startCDATA(lexical
);
3087 EXPECT_HR(hr
, S_OK
);
3089 /* all these are escaped for text nodes */
3090 hr
= ISAXContentHandler_characters(content
, _bstr_("< > & \""), 7);
3091 EXPECT_HR(hr
, S_OK
);
3093 hr
= ISAXLexicalHandler_endCDATA(lexical
);
3094 EXPECT_HR(hr
, S_OK
);
3096 V_VT(&dest
) = VT_EMPTY
;
3097 hr
= IMXWriter_get_output(writer
, &dest
);
3098 EXPECT_HR(hr
, S_OK
);
3099 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
3100 ok(!lstrcmpW(_bstr_("<![CDATA[<![CDATA[< > & \"]]>"), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
3101 VariantClear(&dest
);
3103 ISAXContentHandler_Release(content
);
3104 ISAXLexicalHandler_Release(lexical
);
3105 IMXWriter_Release(writer
);
3109 static void test_mxwriter_dtd(void)
3111 static const WCHAR nameW
[] = {'n','a','m','e'};
3112 static const WCHAR pubW
[] = {'p','u','b'};
3113 static const WCHAR sysW
[] = {'s','y','s'};
3114 ISAXContentHandler
*content
;
3115 ISAXLexicalHandler
*lexical
;
3120 hr
= CoCreateInstance(&CLSID_MXXMLWriter
, NULL
, CLSCTX_INPROC_SERVER
,
3121 &IID_IMXWriter
, (void**)&writer
);
3122 EXPECT_HR(hr
, S_OK
);
3124 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXContentHandler
, (void**)&content
);
3125 EXPECT_HR(hr
, S_OK
);
3127 hr
= IMXWriter_QueryInterface(writer
, &IID_ISAXLexicalHandler
, (void**)&lexical
);
3128 EXPECT_HR(hr
, S_OK
);
3130 hr
= IMXWriter_put_omitXMLDeclaration(writer
, VARIANT_TRUE
);
3131 EXPECT_HR(hr
, S_OK
);
3133 hr
= ISAXContentHandler_startDocument(content
);
3134 EXPECT_HR(hr
, S_OK
);
3136 hr
= ISAXLexicalHandler_startDTD(lexical
, NULL
, 0, NULL
, 0, NULL
, 0);
3137 EXPECT_HR(hr
, E_INVALIDARG
);
3139 hr
= ISAXLexicalHandler_startDTD(lexical
, NULL
, 0, pubW
, sizeof(pubW
)/sizeof(WCHAR
), NULL
, 0);
3140 EXPECT_HR(hr
, E_INVALIDARG
);
3142 hr
= ISAXLexicalHandler_startDTD(lexical
, NULL
, 0, NULL
, 0, sysW
, sizeof(sysW
)/sizeof(WCHAR
));
3143 EXPECT_HR(hr
, E_INVALIDARG
);
3145 hr
= ISAXLexicalHandler_startDTD(lexical
, NULL
, 0, pubW
, sizeof(pubW
)/sizeof(WCHAR
), sysW
, sizeof(sysW
)/sizeof(WCHAR
));
3146 EXPECT_HR(hr
, E_INVALIDARG
);
3148 hr
= ISAXLexicalHandler_startDTD(lexical
, nameW
, sizeof(nameW
)/sizeof(WCHAR
), NULL
, 0, NULL
, 0);
3149 EXPECT_HR(hr
, S_OK
);
3151 V_VT(&dest
) = VT_EMPTY
;
3152 hr
= IMXWriter_get_output(writer
, &dest
);
3153 EXPECT_HR(hr
, S_OK
);
3154 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
3155 ok(!lstrcmpW(_bstr_("<!DOCTYPE name [\r\n"), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
3156 VariantClear(&dest
);
3158 /* system id is required if public is present */
3159 hr
= ISAXLexicalHandler_startDTD(lexical
, nameW
, sizeof(nameW
)/sizeof(WCHAR
), pubW
, sizeof(pubW
)/sizeof(WCHAR
), NULL
, 0);
3160 EXPECT_HR(hr
, E_INVALIDARG
);
3162 hr
= ISAXLexicalHandler_startDTD(lexical
, nameW
, sizeof(nameW
)/sizeof(WCHAR
),
3163 pubW
, sizeof(pubW
)/sizeof(WCHAR
), sysW
, sizeof(sysW
)/sizeof(WCHAR
));
3164 EXPECT_HR(hr
, S_OK
);
3166 V_VT(&dest
) = VT_EMPTY
;
3167 hr
= IMXWriter_get_output(writer
, &dest
);
3168 EXPECT_HR(hr
, S_OK
);
3169 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
3170 ok(!lstrcmpW(_bstr_("<!DOCTYPE name [\r\n<!DOCTYPE name PUBLIC \"pub\""
3171 "<!DOCTYPE name PUBLIC \"pub\" \"sys\" [\r\n"), V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
3172 VariantClear(&dest
);
3174 hr
= ISAXLexicalHandler_endDTD(lexical
);
3175 EXPECT_HR(hr
, S_OK
);
3177 hr
= ISAXLexicalHandler_endDTD(lexical
);
3178 EXPECT_HR(hr
, S_OK
);
3180 V_VT(&dest
) = VT_EMPTY
;
3181 hr
= IMXWriter_get_output(writer
, &dest
);
3182 EXPECT_HR(hr
, S_OK
);
3183 ok(V_VT(&dest
) == VT_BSTR
, "got %d\n", V_VT(&dest
));
3184 ok(!lstrcmpW(_bstr_("<!DOCTYPE name [\r\n<!DOCTYPE name PUBLIC \"pub\""
3185 "<!DOCTYPE name PUBLIC \"pub\" \"sys\" [\r\n]>\r\n]>\r\n"),
3186 V_BSTR(&dest
)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest
)));
3187 VariantClear(&dest
);
3189 ISAXContentHandler_Release(content
);
3190 ISAXLexicalHandler_Release(lexical
);
3191 IMXWriter_Release(writer
);
3203 } addattribute_test_t
;
3205 static const addattribute_test_t addattribute_data
[] = {
3206 { &CLSID_SAXAttributes
, NULL
, NULL
, "ns:qname", NULL
, "value", E_INVALIDARG
},
3207 { &CLSID_SAXAttributes30
, NULL
, NULL
, "ns:qname", NULL
, "value", E_INVALIDARG
},
3208 { &CLSID_SAXAttributes40
, NULL
, NULL
, "ns:qname", NULL
, "value", E_INVALIDARG
},
3209 { &CLSID_SAXAttributes60
, NULL
, NULL
, "ns:qname", NULL
, "value", S_OK
},
3211 { &CLSID_SAXAttributes
, NULL
, "qname", "ns:qname", NULL
, "value", E_INVALIDARG
},
3212 { &CLSID_SAXAttributes30
, NULL
, "qname", "ns:qname", NULL
, "value", E_INVALIDARG
},
3213 { &CLSID_SAXAttributes40
, NULL
, "qname", "ns:qname", NULL
, "value", E_INVALIDARG
},
3214 { &CLSID_SAXAttributes60
, NULL
, "qname", "ns:qname", NULL
, "value", S_OK
},
3216 { &CLSID_SAXAttributes
, "uri", "qname", "ns:qname", NULL
, "value", E_INVALIDARG
},
3217 { &CLSID_SAXAttributes30
, "uri", "qname", "ns:qname", NULL
, "value", E_INVALIDARG
},
3218 { &CLSID_SAXAttributes40
, "uri", "qname", "ns:qname", NULL
, "value", E_INVALIDARG
},
3219 { &CLSID_SAXAttributes60
, "uri", "qname", "ns:qname", NULL
, "value", S_OK
},
3221 { &CLSID_SAXAttributes
, "uri", "qname", "ns:qname", "type", "value", S_OK
},
3222 { &CLSID_SAXAttributes30
, "uri", "qname", "ns:qname", "type", "value", S_OK
},
3223 { &CLSID_SAXAttributes40
, "uri", "qname", "ns:qname", "type", "value", S_OK
},
3224 { &CLSID_SAXAttributes60
, "uri", "qname", "ns:qname", "type", "value", S_OK
},
3229 static void test_mxattr_addAttribute(void)
3231 const addattribute_test_t
*table
= addattribute_data
;
3234 while (table
->clsid
)
3236 ISAXAttributes
*saxattr
;
3237 IMXAttributes
*mxattr
;
3241 if (!is_clsid_supported(table
->clsid
, mxattributes_support_data
))
3248 hr
= CoCreateInstance(table
->clsid
, NULL
, CLSCTX_INPROC_SERVER
,
3249 &IID_IMXAttributes
, (void**)&mxattr
);
3250 EXPECT_HR(hr
, S_OK
);
3252 hr
= IMXAttributes_QueryInterface(mxattr
, &IID_ISAXAttributes
, (void**)&saxattr
);
3253 EXPECT_HR(hr
, S_OK
);
3255 /* SAXAttributes30 and SAXAttributes60 both crash on this test */
3256 if (IsEqualGUID(table
->clsid
, &CLSID_SAXAttributes
) ||
3257 IsEqualGUID(table
->clsid
, &CLSID_SAXAttributes30
))
3259 hr
= ISAXAttributes_getLength(saxattr
, NULL
);
3260 EXPECT_HR(hr
, E_POINTER
);
3264 hr
= ISAXAttributes_getLength(saxattr
, &len
);
3265 EXPECT_HR(hr
, S_OK
);
3266 ok(len
== 0, "got %d\n", len
);
3268 hr
= IMXAttributes_addAttribute(mxattr
, _bstr_(table
->uri
), _bstr_(table
->local
),
3269 _bstr_(table
->qname
), _bstr_(table
->type
), _bstr_(table
->value
));
3270 ok(hr
== table
->hr
, "%d: got 0x%08x, expected 0x%08x\n", i
, hr
, table
->hr
);
3273 hr
= ISAXAttributes_getLength(saxattr
, &len
);
3274 EXPECT_HR(hr
, S_OK
);
3275 if (table
->hr
== S_OK
)
3276 ok(len
== 1, "%d: got %d length, expected 0\n", i
, len
);
3278 ok(len
== 0, "%d: got %d length, expected 1\n", i
, len
);
3280 ISAXAttributes_Release(saxattr
);
3281 IMXAttributes_Release(mxattr
);
3290 static void test_mxattr_clear(void)
3292 ISAXAttributes
*saxattr
;
3293 IMXAttributes
*mxattr
;
3298 hr
= CoCreateInstance(&CLSID_SAXAttributes
, NULL
, CLSCTX_INPROC_SERVER
,
3299 &IID_IMXAttributes
, (void**)&mxattr
);
3300 EXPECT_HR(hr
, S_OK
);
3302 hr
= IMXAttributes_QueryInterface(mxattr
, &IID_ISAXAttributes
, (void**)&saxattr
);
3303 EXPECT_HR(hr
, S_OK
);
3305 hr
= ISAXAttributes_getQName(saxattr
, 0, NULL
, NULL
);
3306 EXPECT_HR(hr
, E_INVALIDARG
);
3308 hr
= ISAXAttributes_getQName(saxattr
, 0, &ptr
, &len
);
3309 EXPECT_HR(hr
, E_INVALIDARG
);
3311 hr
= IMXAttributes_addAttribute(mxattr
, _bstr_("uri"), _bstr_("local"),
3312 _bstr_("qname"), _bstr_("type"), _bstr_("value"));
3313 EXPECT_HR(hr
, S_OK
);
3316 hr
= ISAXAttributes_getLength(saxattr
, &len
);
3317 EXPECT_HR(hr
, S_OK
);
3318 ok(len
== 1, "got %d\n", len
);
3321 hr
= ISAXAttributes_getQName(saxattr
, 0, NULL
, &len
);
3322 EXPECT_HR(hr
, E_POINTER
);
3323 ok(len
== -1, "got %d\n", len
);
3325 ptr
= (void*)0xdeadbeef;
3326 hr
= ISAXAttributes_getQName(saxattr
, 0, &ptr
, NULL
);
3327 EXPECT_HR(hr
, E_POINTER
);
3328 ok(ptr
== (void*)0xdeadbeef, "got %p\n", ptr
);
3331 hr
= ISAXAttributes_getQName(saxattr
, 0, &ptr
, &len
);
3332 EXPECT_HR(hr
, S_OK
);
3333 ok(len
== 5, "got %d\n", len
);
3334 ok(!lstrcmpW(ptr
, _bstr_("qname")), "got %s\n", wine_dbgstr_w(ptr
));
3336 hr
= IMXAttributes_clear(mxattr
);
3337 EXPECT_HR(hr
, S_OK
);
3340 hr
= ISAXAttributes_getLength(saxattr
, &len
);
3341 EXPECT_HR(hr
, S_OK
);
3342 ok(len
== 0, "got %d\n", len
);
3345 ptr
= (void*)0xdeadbeef;
3346 hr
= ISAXAttributes_getQName(saxattr
, 0, &ptr
, &len
);
3347 EXPECT_HR(hr
, E_INVALIDARG
);
3348 ok(len
== -1, "got %d\n", len
);
3349 ok(ptr
== (void*)0xdeadbeef, "got %p\n", ptr
);
3351 IMXAttributes_Release(mxattr
);
3352 ISAXAttributes_Release(saxattr
);
3356 START_TEST(saxreader
)
3358 ISAXXMLReader
*reader
;
3361 hr
= CoInitialize(NULL
);
3362 ok(hr
== S_OK
, "failed to init com\n");
3364 hr
= CoCreateInstance(&CLSID_SAXXMLReader
, NULL
, CLSCTX_INPROC_SERVER
,
3365 &IID_ISAXXMLReader
, (void**)&reader
);
3369 skip("Failed to create SAXXMLReader instance\n");
3373 ISAXXMLReader_Release(reader
);
3378 test_saxreader_properties();
3379 test_saxreader_features();
3383 /* MXXMLWriter tests */
3384 get_mxwriter_support_data(mxwriter_support_data
);
3385 if (is_clsid_supported(&CLSID_MXXMLWriter
, mxwriter_support_data
))
3387 test_mxwriter_handlers();
3388 test_mxwriter_startenddocument();
3389 test_mxwriter_startendelement();
3390 test_mxwriter_characters();
3391 test_mxwriter_comment();
3392 test_mxwriter_cdata();
3393 test_mxwriter_dtd();
3394 test_mxwriter_properties();
3395 test_mxwriter_flush();
3396 test_mxwriter_stream();
3397 test_mxwriter_encoding();
3398 test_mxwriter_dispex();
3401 win_skip("MXXMLWriter not supported\n");
3403 /* SAXAttributes tests */
3404 get_mxattributes_support_data(mxattributes_support_data
);
3405 if (is_clsid_supported(&CLSID_SAXAttributes
, mxattributes_support_data
))
3407 test_mxattr_addAttribute();
3408 test_mxattr_clear();
3411 skip("SAXAttributes not supported\n");