ReactOS 0.4.15-dev-7788-g1ad9096
saxreader.c
Go to the documentation of this file.
1/*
2 * SAXReader/MXWriter tests
3 *
4 * Copyright 2008 Piotr Caban
5 * Copyright 2011 Thomas Mullaly
6 * Copyright 2012 Nikolay Sivov
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23#define COBJMACROS
24#define CONST_VTABLE
25
26#include <stdio.h>
27#include <assert.h>
28
29#include "windows.h"
30#include "ole2.h"
31#include "msxml2.h"
32#include "msxml2did.h"
33#include "ocidl.h"
34#include "dispex.h"
35
36#include "wine/heap.h"
37#include "wine/test.h"
38
39static const WCHAR emptyW[] = {0};
40
41#define EXPECT_HR(hr,hr_exp) \
42 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
43
44#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
45static void _expect_ref(IUnknown* obj, ULONG ref, int line)
46{
47 ULONG rc;
48 IUnknown_AddRef(obj);
49 rc = IUnknown_Release(obj);
50 ok_(__FILE__, line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
51}
52
53static LONG get_refcount(void *iface)
54{
55 IUnknown *unk = iface;
56 LONG ref;
57
58 ref = IUnknown_AddRef(unk);
59 IUnknown_Release(unk);
60 return ref-1;
61}
62
64{
65 const GUID *clsid;
66 const char *name;
68};
69
71{
72 while (table->clsid)
73 {
74 if (table->clsid == clsid) return table->supported;
75 table++;
76 }
77 return FALSE;
78}
79
80static BSTR alloc_str_from_narrow(const char *str)
81{
82 int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
83 BSTR ret = SysAllocStringLen(NULL, len - 1); /* NUL character added automatically */
85 return ret;
86}
87
88static BSTR alloced_bstrs[512];
90
91static BSTR _bstr_(const char *str)
92{
96}
97
98static void free_bstrs(void)
99{
100 int i;
101 for (i = 0; i < alloced_bstrs_count; i++)
104}
105
106static void test_saxstr(const char *file, unsigned line, BSTR str, const char *expected, BOOL todo, int *failcount)
107{
108 int len, lenexp, cmp;
109 WCHAR buf[1024];
110
112
113 if (!expected) {
114 if (str && todo)
115 {
116 (*failcount)++;
118 ok_(file, line) (!str, "got %p, expected null str\n", str);
119 }
120 else
121 ok_(file, line) (!str, "got %p, expected null str\n", str);
122
123 if (len && todo)
124 {
125 (*failcount)++;
127 ok_(file, line) (len == 0, "got len %d, expected 0\n", len);
128 }
129 else
130 ok_(file, line) (len == 0, "got len %d, expected 0\n", len);
131 return;
132 }
133
134 lenexp = strlen(expected);
135 if (lenexp != len && todo)
136 {
137 (*failcount)++;
139 ok_(file, line) (lenexp == len, "len %d (%s), expected %d (%s)\n", len, wine_dbgstr_wn(str, len), lenexp, expected);
140 }
141 else
142 ok_(file, line) (lenexp == len, "len %d (%s), expected %d (%s)\n", len, wine_dbgstr_wn(str, len), lenexp, expected);
143
144 /* exit earlier on length mismatch */
145 if (lenexp != len) return;
146
148
149 cmp = memcmp(str, buf, lenexp*sizeof(WCHAR));
150 if (cmp && todo)
151 {
152 (*failcount)++;
154 ok_(file, line) (!cmp, "unexpected str %s, expected %s\n",
156 }
157 else
158 ok_(file, line) (!cmp, "unexpected str %s, expected %s\n",
160}
161
162typedef enum _CH {
182
183static const char *event_names[EVENT_LAST] = {
184 "endtest",
185 "putDocumentLocator",
186 "startDocument",
187 "endDocument",
188 "startPrefixMapping",
189 "endPrefixMapping",
190 "startElement",
191 "endElement",
192 "characters",
193 "ignorableWhitespace",
194 "processingInstruction",
195 "skippedEntity",
196 "startCDATA",
197 "endCDATA",
198 "error",
199 "fatalError",
200 "ignorableWarning"
201};
202
204 const char *uri;
205 const char *local;
206 const char *qname;
207 const char *value;
208
209 /* used for actual call data only, null for expected call data */
214};
215
218 int line;
221 const char *arg1;
222 const char *arg2;
223 const char *arg3;
224
225 /* allocated once at startElement callback */
228
229 /* used for actual call data only, null for expected call data */
233};
234
236{
237 int count;
238 int size;
240};
241
242#define CONTENT_HANDLER_INDEX 0
243#define NUM_CALL_SEQUENCES 1
245
246static void init_call_entry(ISAXLocator *locator, struct call_entry *call)
247{
248 memset(call, 0, sizeof(*call));
249 ISAXLocator_getLineNumber(locator, &call->line);
250 ISAXLocator_getColumnNumber(locator, &call->column);
251}
252
253static void add_call(struct call_sequence **seq, int sequence_index,
254 const struct call_entry *call)
255{
256 struct call_sequence *call_seq = seq[sequence_index];
257
258 if (!call_seq->sequence)
259 {
260 call_seq->size = 10;
261 call_seq->sequence = heap_alloc(call_seq->size * sizeof (struct call_entry));
262 }
263
264 if (call_seq->count == call_seq->size)
265 {
266 call_seq->size *= 2;
267 call_seq->sequence = heap_realloc(call_seq->sequence, call_seq->size * sizeof (struct call_entry));
268 }
269
270 assert(call_seq->sequence);
271
272 call_seq->sequence[call_seq->count].id = call->id;
273 call_seq->sequence[call_seq->count].line = call->line;
274 call_seq->sequence[call_seq->count].column = call->column;
275 call_seq->sequence[call_seq->count].arg1W = call->arg1W;
276 call_seq->sequence[call_seq->count].arg2W = call->arg2W;
277 call_seq->sequence[call_seq->count].arg3W = call->arg3W;
278 call_seq->sequence[call_seq->count].ret = call->ret;
279 call_seq->sequence[call_seq->count].attr_count = call->attr_count;
280 call_seq->sequence[call_seq->count].attributes = call->attributes;
281
282 call_seq->count++;
283}
284
285static inline void flush_sequence(struct call_sequence **seg, int sequence_index)
286{
287 int i;
288
289 struct call_sequence *call_seq = seg[sequence_index];
290
291 for (i = 0; i < call_seq->count; i++)
292 {
293 int j;
294
295 for (j = 0; j < call_seq->sequence[i].attr_count; j++)
296 {
297 SysFreeString(call_seq->sequence[i].attributes[j].uriW);
298 SysFreeString(call_seq->sequence[i].attributes[j].localW);
299 SysFreeString(call_seq->sequence[i].attributes[j].qnameW);
300 SysFreeString(call_seq->sequence[i].attributes[j].valueW);
301 }
302 heap_free(call_seq->sequence[i].attributes);
303 call_seq->sequence[i].attr_count = 0;
304
305 SysFreeString(call_seq->sequence[i].arg1W);
306 SysFreeString(call_seq->sequence[i].arg2W);
307 SysFreeString(call_seq->sequence[i].arg3W);
308 }
309
310 heap_free(call_seq->sequence);
311 call_seq->sequence = NULL;
312 call_seq->count = call_seq->size = 0;
313}
314
315static const char *get_event_name(CH event)
316{
317 return event_names[event];
318}
319
320static void compare_attributes(const struct call_entry *actual, const struct call_entry *expected, const char *context,
321 BOOL todo, const char *file, int line, int *failcount)
322{
323 int i, lenexp = 0;
324
325 /* attribute count is not stored for expected data */
326 if (expected->attributes)
327 {
328 struct attribute_entry *ptr = expected->attributes;
329 while (ptr->uri) { lenexp++; ptr++; };
330 }
331
332 /* check count first and exit earlier */
333 if (actual->attr_count != lenexp && todo)
334 {
335 (*failcount)++;
337 ok_(file, line) (FALSE, "%s: in event %s expecting attr count %d got %d\n",
338 context, get_event_name(actual->id), lenexp, actual->attr_count);
339 }
340 else
341 ok_(file, line) (actual->attr_count == lenexp, "%s: in event %s expecting attr count %d got %d\n",
342 context, get_event_name(actual->id), lenexp, actual->attr_count);
343
344 if (actual->attr_count != lenexp) return;
345
346 /* now compare all attributes strings */
347 for (i = 0; i < actual->attr_count; i++)
348 {
349 test_saxstr(file, line, actual->attributes[i].uriW, expected->attributes[i].uri, todo, failcount);
350 test_saxstr(file, line, actual->attributes[i].localW, expected->attributes[i].local, todo, failcount);
351 test_saxstr(file, line, actual->attributes[i].qnameW, expected->attributes[i].qname, todo, failcount);
352 test_saxstr(file, line, actual->attributes[i].valueW, expected->attributes[i].value, todo, failcount);
353 }
354}
355
356static void ok_sequence_(struct call_sequence **seq, int sequence_index,
357 const struct call_entry *expected, const char *context, BOOL todo,
358 const char *file, int line)
359{
360 struct call_sequence *call_seq = seq[sequence_index];
361 static const struct call_entry end_of_sequence = { CH_ENDTEST };
362 const struct call_entry *actual, *sequence;
363 int failcount = 0;
364
365 add_call(seq, sequence_index, &end_of_sequence);
366
367 sequence = call_seq->sequence;
368 actual = sequence;
369
370 while (expected->id != CH_ENDTEST && actual->id != CH_ENDTEST)
371 {
372 if (expected->id == actual->id)
373 {
374 if (expected->line != -1)
375 {
376 /* always test position data */
377 if (expected->line != actual->line && todo)
378 {
380 {
381 failcount++;
382 ok_(file, line) (FALSE,
383 "%s: in event %s expecting line %d got %d\n",
384 context, get_event_name(actual->id), expected->line, actual->line);
385 }
386 }
387 else
388 {
389 ok_(file, line) (expected->line == actual->line,
390 "%s: in event %s expecting line %d got %d\n",
391 context, get_event_name(actual->id), expected->line, actual->line);
392 }
393 }
394
395
396 if (expected->column != -1)
397 {
398 if (expected->column != actual->column && todo)
399 {
401 {
402 failcount++;
403 ok_(file, line) (FALSE,
404 "%s: in event %s expecting column %d got %d\n",
405 context, get_event_name(actual->id), expected->column, actual->column);
406 }
407 }
408 else
409 {
410 ok_(file, line) (expected->column == actual->column,
411 "%s: in event %s expecting column %d got %d\n",
412 context, get_event_name(actual->id), expected->column, actual->column);
413 }
414 }
415
416 switch (actual->id)
417 {
419 case CH_STARTDOCUMENT:
420 case CH_ENDDOCUMENT:
421 case LH_STARTCDATA:
422 case LH_ENDCDATA:
423 break;
425 /* prefix, uri */
426 test_saxstr(file, line, actual->arg1W, expected->arg1, todo, &failcount);
427 test_saxstr(file, line, actual->arg2W, expected->arg2, todo, &failcount);
428 break;
430 /* prefix */
431 test_saxstr(file, line, actual->arg1W, expected->arg1, todo, &failcount);
432 break;
433 case CH_STARTELEMENT:
434 /* compare attributes */
435 compare_attributes(actual, expected, context, todo, file, line, &failcount);
436 /* fallthrough */
437 case CH_ENDELEMENT:
438 /* uri, localname, qname */
439 test_saxstr(file, line, actual->arg1W, expected->arg1, todo, &failcount);
440 test_saxstr(file, line, actual->arg2W, expected->arg2, todo, &failcount);
441 test_saxstr(file, line, actual->arg3W, expected->arg3, todo, &failcount);
442 break;
443 case CH_CHARACTERS:
445 /* char data */
446 test_saxstr(file, line, actual->arg1W, expected->arg1, todo, &failcount);
447 break;
449 /* target, data */
450 test_saxstr(file, line, actual->arg1W, expected->arg1, todo, &failcount);
451 test_saxstr(file, line, actual->arg2W, expected->arg2, todo, &failcount);
452 break;
453 case CH_SKIPPEDENTITY:
454 /* name */
455 test_saxstr(file, line, actual->arg1W, expected->arg1, todo, &failcount);
456 break;
457 case EH_FATALERROR:
458 /* test return value only */
459 if (expected->ret != actual->ret && todo)
460 {
461 failcount++;
462 ok_(file, line) (FALSE,
463 "%s: in event %s expecting ret 0x%08x got 0x%08x\n",
464 context, get_event_name(actual->id), expected->ret, actual->ret);
465 }
466 else
467 ok_(file, line) (expected->ret == actual->ret,
468 "%s: in event %s expecting ret 0x%08x got 0x%08x\n",
469 context, get_event_name(actual->id), expected->ret, actual->ret);
470 break;
471 case EH_ERROR:
473 default:
474 ok(0, "%s: callback not handled, %s\n", context, get_event_name(actual->id));
475 }
476 expected++;
477 actual++;
478 }
479 else if (todo)
480 {
481 failcount++;
483 {
484 ok_(file, line) (FALSE, "%s: call %s was expected, but got call %s instead\n",
486 }
487
488 flush_sequence(seq, sequence_index);
489 return;
490 }
491 else
492 {
493 ok_(file, line) (FALSE, "%s: call %s was expected, but got call %s instead\n",
495 expected++;
496 actual++;
497 }
498 }
499
500 if (todo)
501 {
503 {
504 if (expected->id != CH_ENDTEST || actual->id != CH_ENDTEST)
505 {
506 failcount++;
507 ok_(file, line) (FALSE, "%s: the call sequence is not complete: expected %s - actual %s\n",
509 }
510 }
511 }
512 else if (expected->id != CH_ENDTEST || actual->id != CH_ENDTEST)
513 {
514 ok_(file, line) (FALSE, "%s: the call sequence is not complete: expected %s - actual %s\n",
516 }
517
518 if (todo && !failcount) /* succeeded yet marked todo */
519 {
521 {
522 ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
523 }
524 }
525
526 flush_sequence(seq, sequence_index);
527}
528
529#define ok_sequence(seq, index, exp, contx, todo) \
530 ok_sequence_(seq, index, (exp), (contx), (todo), __FILE__, __LINE__)
531
532static void init_call_sequences(struct call_sequence **seq, int n)
533{
534 int i;
535
536 for (i = 0; i < n; i++)
537 seq[i] = heap_alloc_zero(sizeof(struct call_sequence));
538}
539
540static const WCHAR szSimpleXML[] = {
541'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\"','1','.','0','\"',' ','?','>','\n',
542'<','B','a','n','k','A','c','c','o','u','n','t','>','\n',
543' ',' ',' ','<','N','u','m','b','e','r','>','1','2','3','4','<','/','N','u','m','b','e','r','>','\n',
544' ',' ',' ','<','N','a','m','e','>','C','a','p','t','a','i','n',' ','A','h','a','b','<','/','N','a','m','e','>','\n',
545'<','/','B','a','n','k','A','c','c','o','u','n','t','>','\n','\0'
546};
547
548static const WCHAR carriage_ret_test[] = {
549'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"','?','>','\r','\n',
550'<','B','a','n','k','A','c','c','o','u','n','t','>','\r','\n',
551'\t','<','N','u','m','b','e','r','>','1','2','3','4','<','/','N','u','m','b','e','r','>','\r','\n',
552'\t','<','N','a','m','e','>','C','a','p','t','a','i','n',' ','A','h','a','b','<','/','N','a','m','e','>','\r','\n',
553'<','/','B','a','n','k','A','c','c','o','u','n','t','>','\r','\n','\0'
554};
555
556static const WCHAR szUtf16XML[] = {
557'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"',' ',
558'e','n','c','o','d','i','n','g','=','"','U','T','F','-','1','6','"',' ',
559's','t','a','n','d','a','l','o','n','e','=','"','n','o','"','?','>','\r','\n'
560};
561
562static const CHAR szUtf16BOM[] = {0xff, 0xfe};
563
564static const CHAR szUtf8XML[] =
565"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n";
566
567static const char utf8xml2[] =
568"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\r\n";
569
570static const char testXML[] =
571"<?xml version=\"1.0\" ?>\n"
572"<BankAccount>\n"
573" <Number>1234</Number>\n"
574" <Name>Captain Ahab</Name>\n"
575"</BankAccount>\n";
576
577static const char test_attributes[] =
578"<?xml version=\"1.0\" ?>\n"
579"<document xmlns:test=\"prefix_test\" xmlns=\"prefix\" test:arg1=\"arg1\" arg2=\"arg2\" test:ar3=\"arg3\">\n"
580"<node1 xmlns:p=\"test\" />"
581"</document>\n";
582
583static const char test_cdata_xml[] =
584"<?xml version=\"1.0\" ?>"
585"<a><![CDATA[Some \r\ntext\n\r\ndata\n\n]]></a>";
586
587static const char test2_cdata_xml[] =
588"<?xml version=\"1.0\" ?>"
589"<a><![CDATA[\n\r\nSome \r\ntext\n\r\ndata\n\n]]></a>";
590
591static const char test3_cdata_xml[] =
592"<?xml version=\"1.0\" ?><a><![CDATA[Some text data]]></a>";
593
595 { CH_PUTDOCUMENTLOCATOR, 0, 0, S_OK },
596 { CH_STARTDOCUMENT, 0, 0, S_OK },
597 { CH_STARTELEMENT, 2, 14, S_OK, "", "BankAccount", "BankAccount" },
598 { CH_CHARACTERS, 2, 14, S_OK, "\n " },
599 { CH_STARTELEMENT, 3, 12, S_OK, "", "Number", "Number" },
600 { CH_CHARACTERS, 3, 12, S_OK, "1234" },
601 { CH_ENDELEMENT, 3, 18, S_OK, "", "Number", "Number" },
602 { CH_CHARACTERS, 3, 25, S_OK, "\n " },
603 { CH_STARTELEMENT, 4, 10, S_OK, "", "Name", "Name" },
604 { CH_CHARACTERS, 4, 10, S_OK, "Captain Ahab" },
605 { CH_ENDELEMENT, 4, 24, S_OK, "", "Name", "Name" },
606 { CH_CHARACTERS, 4, 29, S_OK, "\n" },
607 { CH_ENDELEMENT, 5, 3, S_OK, "", "BankAccount", "BankAccount" },
608 { CH_ENDDOCUMENT, 0, 0, S_OK},
609 { CH_ENDTEST }
610};
611
612/* applies to versions 4 and 6 */
614 { CH_PUTDOCUMENTLOCATOR, 1, 0, S_OK },
615 { CH_STARTDOCUMENT, 1, 22, S_OK },
616 { CH_STARTELEMENT, 2, 13, S_OK, "", "BankAccount", "BankAccount" },
617 { CH_CHARACTERS, 3, 4, S_OK, "\n " },
618 { CH_STARTELEMENT, 3, 11, S_OK, "", "Number", "Number" },
619 { CH_CHARACTERS, 3, 16, S_OK, "1234" },
620 { CH_ENDELEMENT, 3, 24, S_OK, "", "Number", "Number" },
621 { CH_CHARACTERS, 4, 4, S_OK, "\n " },
622 { CH_STARTELEMENT, 4, 9, S_OK, "", "Name", "Name" },
623 { CH_CHARACTERS, 4, 22, S_OK, "Captain Ahab" },
624 { CH_ENDELEMENT, 4, 28, S_OK, "", "Name", "Name" },
625 { CH_CHARACTERS, 5, 1, S_OK, "\n" },
626 { CH_ENDELEMENT, 5, 14, S_OK, "", "BankAccount", "BankAccount" },
627 { CH_ENDDOCUMENT, 6, 0, S_OK },
628 { CH_ENDTEST }
629};
630
632 { CH_PUTDOCUMENTLOCATOR, 0, 0, S_OK },
633 { CH_STARTDOCUMENT, 0, 0, S_OK },
634 { CH_STARTELEMENT, 2, 14, S_OK, "", "BankAccount", "BankAccount" },
635 { CH_CHARACTERS, 2, 14, S_OK, "\n" },
636 { CH_CHARACTERS, 2, 16, S_OK, "\t" },
637 { CH_STARTELEMENT, 3, 10, S_OK, "", "Number", "Number" },
638 { CH_CHARACTERS, 3, 10, S_OK, "1234" },
639 { CH_ENDELEMENT, 3, 16, S_OK, "", "Number", "Number" },
640 { CH_CHARACTERS, 3, 23, S_OK, "\n" },
641 { CH_CHARACTERS, 3, 25, S_OK, "\t" },
642 { CH_STARTELEMENT, 4, 8, S_OK, "", "Name", "Name" },
643 { CH_CHARACTERS, 4, 8, S_OK, "Captain Ahab" },
644 { CH_ENDELEMENT, 4, 22, S_OK, "", "Name", "Name" },
645 { CH_CHARACTERS, 4, 27, S_OK, "\n" },
646 { CH_ENDELEMENT, 5, 3, S_OK, "", "BankAccount", "BankAccount" },
647 { CH_ENDDOCUMENT, 0, 0, S_OK },
648 { CH_ENDTEST }
649};
650
652 { CH_PUTDOCUMENTLOCATOR, 1, 0, S_OK },
653 { CH_STARTDOCUMENT, 1, 21, S_OK },
654 { CH_STARTELEMENT, 2, 13, S_OK, "", "BankAccount", "BankAccount" },
655 { CH_CHARACTERS, 3, 0, S_OK, "\n" },
656 { CH_CHARACTERS, 3, 2, S_OK, "\t" },
657 { CH_STARTELEMENT, 3, 9, S_OK, "", "Number", "Number" },
658 { CH_CHARACTERS, 3, 14, S_OK, "1234" },
659 { CH_ENDELEMENT, 3, 22, S_OK, "", "Number", "Number" },
660 { CH_CHARACTERS, 4, 0, S_OK, "\n" },
661 { CH_CHARACTERS, 4, 2, S_OK, "\t" },
662 { CH_STARTELEMENT, 4, 7, S_OK, "", "Name", "Name" },
663 { CH_CHARACTERS, 4, 20, S_OK, "Captain Ahab" },
664 { CH_ENDELEMENT, 4, 26, S_OK, "", "Name", "Name" },
665 { CH_CHARACTERS, 5, 0, S_OK, "\n" },
666 { CH_ENDELEMENT, 5, 14, S_OK, "", "BankAccount", "BankAccount" },
667 { CH_ENDDOCUMENT, 6, 0, S_OK },
668 { CH_ENDTEST }
669};
670
672 { CH_PUTDOCUMENTLOCATOR, 0, 0, E_FAIL },
673 { EH_FATALERROR, 0, 0, E_FAIL },
674 { CH_ENDTEST }
675};
676
678 { CH_PUTDOCUMENTLOCATOR, 1, 0, E_FAIL },
679 { EH_FATALERROR, 1, 0, E_FAIL },
680 { CH_ENDTEST }
681};
682
685 { CH_STARTDOCUMENT, 0, 0, S_FALSE },
686 { EH_FATALERROR, 0, 0, S_FALSE },
687 { CH_ENDTEST }
688};
689
692 { CH_STARTDOCUMENT, 1, 22, S_FALSE },
693 { CH_STARTELEMENT, 2, 13, S_FALSE, "", "BankAccount", "BankAccount" },
694 { CH_CHARACTERS, 3, 4, S_FALSE, "\n " },
695 { CH_STARTELEMENT, 3, 11, S_FALSE, "", "Number", "Number" },
696 { CH_CHARACTERS, 3, 16, S_FALSE, "1234" },
697 { CH_ENDELEMENT, 3, 24, S_FALSE, "", "Number", "Number" },
698 { CH_CHARACTERS, 4, 4, S_FALSE, "\n " },
699 { CH_STARTELEMENT, 4, 9, S_FALSE, "", "Name", "Name" },
700 { CH_CHARACTERS, 4, 22, S_FALSE, "Captain Ahab" },
701 { CH_ENDELEMENT, 4, 28, S_FALSE, "", "Name", "Name" },
702 { CH_CHARACTERS, 5, 1, S_FALSE, "\n" },
703 { CH_ENDELEMENT, 5, 14, S_FALSE, "", "BankAccount", "BankAccount" },
704 { CH_ENDDOCUMENT, 6, 0, S_FALSE },
705 { CH_ENDTEST }
706};
707
709 { "", "", "xmlns:test", "prefix_test" },
710 { "", "", "xmlns", "prefix" },
711 { "prefix_test", "arg1", "test:arg1", "arg1" },
712 { "", "arg2", "arg2", "arg2" },
713 { "prefix_test", "ar3", "test:ar3", "arg3" },
714 { NULL }
715};
716
718 { "", "", "xmlns:p", "test" },
719 { NULL }
720};
721
723 { CH_PUTDOCUMENTLOCATOR, 0, 0, S_OK },
724 { CH_STARTDOCUMENT, 0, 0, S_OK },
725 { CH_STARTPREFIXMAPPING, 2, 96, S_OK, "test", "prefix_test" },
726 { CH_STARTPREFIXMAPPING, 2, 96, S_OK, "", "prefix" },
727 { CH_STARTELEMENT, 2, 96, S_OK, "prefix", "document", "document", ch_attributes1 },
728 { CH_CHARACTERS, 2, 96, S_OK, "\n" },
729 { CH_STARTPREFIXMAPPING, 3, 25, S_OK, "p", "test" },
730 { CH_STARTELEMENT, 3, 25, S_OK, "prefix", "node1", "node1", ch_attributes2 },
731 { CH_ENDELEMENT, 3, 25, S_OK, "prefix", "node1", "node1" },
732 { CH_ENDPREFIXMAPPING, 3, 25, S_OK, "p" },
733 { CH_ENDELEMENT, 3, 27, S_OK, "prefix", "document", "document" },
734 { CH_ENDPREFIXMAPPING, 3, 27, S_OK, "" },
735 { CH_ENDPREFIXMAPPING, 3, 27, S_OK, "test" },
736 { CH_ENDDOCUMENT, 0, 0 },
737 { CH_ENDTEST }
738};
739
741 { "prefix_test", "arg1", "test:arg1", "arg1" },
742 { "", "arg2", "arg2", "arg2" },
743 { "prefix_test", "ar3", "test:ar3", "arg3" },
744 { "", "", "xmlns:test", "prefix_test" },
745 { "", "", "xmlns", "prefix" },
746 { NULL }
747};
748
750 { CH_PUTDOCUMENTLOCATOR, 1, 0, S_OK },
751 { CH_STARTDOCUMENT, 1, 22, S_OK },
752 { CH_STARTPREFIXMAPPING, 2, 95, S_OK, "test", "prefix_test" },
753 { CH_STARTPREFIXMAPPING, 2, 95, S_OK, "", "prefix" },
754 { CH_STARTELEMENT, 2, 95, S_OK, "prefix", "document", "document", ch_attributes_alt_4 },
755 { CH_CHARACTERS, 3, 1, S_OK, "\n" },
756 { CH_STARTPREFIXMAPPING, 3, 24, S_OK, "p", "test" },
757 { CH_STARTELEMENT, 3, 24, S_OK, "prefix", "node1", "node1", ch_attributes2 },
758 { CH_ENDELEMENT, 3, 24, S_OK, "prefix", "node1", "node1" },
759 { CH_ENDPREFIXMAPPING, 3, 24, S_OK, "p" },
760 { CH_ENDELEMENT, 3, 35, S_OK, "prefix", "document", "document" },
761 { CH_ENDPREFIXMAPPING, 3, 35, S_OK, "test" },
762 { CH_ENDPREFIXMAPPING, 3, 35, S_OK, "" },
763 { CH_ENDDOCUMENT, 4, 0, S_OK },
764 { CH_ENDTEST }
765};
766
767/* 'namespace' feature switched off */
769 { "", "", "xmlns:test", "prefix_test" },
770 { "", "", "xmlns", "prefix" },
771 { "", "", "test:arg1", "arg1" },
772 { "", "", "arg2", "arg2" },
773 { "", "", "test:ar3", "arg3" },
774 { NULL }
775};
776
778 { CH_PUTDOCUMENTLOCATOR, 1, 0, S_OK },
779 { CH_STARTDOCUMENT, 1, 22, S_OK },
780 { CH_STARTELEMENT, 2, 95, S_OK, "", "", "document", ch_attributes_alt_no_ns },
781 { CH_CHARACTERS, 3, 1, S_OK, "\n" },
782 { CH_STARTELEMENT, 3, 24, S_OK, "", "", "node1", ch_attributes2 },
783 { CH_ENDELEMENT, 3, 24, S_OK, "", "", "node1" },
784 { CH_ENDELEMENT, 3, 35, S_OK, "", "", "document" },
785 { CH_ENDDOCUMENT, 4, 0, S_OK },
786 { CH_ENDTEST }
787};
788
790 { "prefix_test", "arg1", "test:arg1", "arg1" },
791 { "", "arg2", "arg2", "arg2" },
792 { "prefix_test", "ar3", "test:ar3", "arg3" },
793 { "http://www.w3.org/2000/xmlns/", "", "xmlns:test", "prefix_test" },
794 { "http://www.w3.org/2000/xmlns/", "", "xmlns", "prefix" },
795 { NULL }
796};
797
799 { "http://www.w3.org/2000/xmlns/", "", "xmlns:p", "test" },
800 { NULL }
801};
802
804 { CH_PUTDOCUMENTLOCATOR, 1, 0, S_OK },
805 { CH_STARTDOCUMENT, 1, 22, S_OK },
806 { CH_STARTPREFIXMAPPING, 2, 95, S_OK, "test", "prefix_test" },
807 { CH_STARTPREFIXMAPPING, 2, 95, S_OK, "", "prefix" },
808 { CH_STARTELEMENT, 2, 95, S_OK, "prefix", "document", "document", ch_attributes_alt_6 },
809 { CH_CHARACTERS, 3, 1, S_OK, "\n" },
810 { CH_STARTPREFIXMAPPING, 3, 24, S_OK, "p", "test" },
811 { CH_STARTELEMENT, 3, 24, S_OK, "prefix", "node1", "node1", ch_attributes2_6 },
812 { CH_ENDELEMENT, 3, 24, S_OK, "prefix", "node1", "node1" },
813 { CH_ENDPREFIXMAPPING, 3, 24, S_OK, "p" },
814 { CH_ENDELEMENT, 3, 35, S_OK, "prefix", "document", "document" },
815 { CH_ENDPREFIXMAPPING, 3, 35, S_OK, "test" },
816 { CH_ENDPREFIXMAPPING, 3, 35, S_OK, "" },
817 { CH_ENDDOCUMENT, 4, 0, S_OK },
818 { CH_ENDTEST }
819};
820
821/* 'namespaces' is on, 'namespace-prefixes' if off */
823 { "prefix_test", "arg1", "test:arg1", "arg1" },
824 { "", "arg2", "arg2", "arg2" },
825 { "prefix_test", "ar3", "test:ar3", "arg3" },
826 { NULL }
827};
828
830 { CH_PUTDOCUMENTLOCATOR, 1, 0, S_OK },
831 { CH_STARTDOCUMENT, 1, 22, S_OK },
832 { CH_STARTPREFIXMAPPING, 2, 95, S_OK, "test", "prefix_test" },
833 { CH_STARTPREFIXMAPPING, 2, 95, S_OK, "", "prefix" },
834 { CH_STARTELEMENT, 2, 95, S_OK, "prefix", "document", "document", ch_attributes_no_prefix },
835 { CH_CHARACTERS, 3, 1, S_OK, "\n" },
836 { CH_STARTPREFIXMAPPING, 3, 24, S_OK, "p", "test" },
837 { CH_STARTELEMENT, 3, 24, S_OK, "prefix", "node1", "node1", NULL },
838 { CH_ENDELEMENT, 3, 24, S_OK, "prefix", "node1", "node1" },
839 { CH_ENDPREFIXMAPPING, 3, 24, S_OK, "p" },
840 { CH_ENDELEMENT, 3, 35, S_OK, "prefix", "document", "document" },
841 { CH_ENDPREFIXMAPPING, 3, 35, S_OK, "test" },
842 { CH_ENDPREFIXMAPPING, 3, 35, S_OK, "" },
843 { CH_ENDDOCUMENT, 4, 0, S_OK },
844 { CH_ENDTEST }
845};
846
848 { CH_PUTDOCUMENTLOCATOR, 0, 0, S_OK },
849 { CH_STARTDOCUMENT, 0, 0, S_OK },
850 { CH_STARTPREFIXMAPPING, 2, 96, S_OK, "test", "prefix_test" },
851 { CH_STARTPREFIXMAPPING, 2, 96, S_OK, "", "prefix" },
852 { CH_STARTELEMENT, 2, 96, S_OK, "prefix", "document", "document", ch_attributes_no_prefix },
853 { CH_CHARACTERS, 2, 96, S_OK, "\n" },
854 { CH_STARTPREFIXMAPPING, 3, 25, S_OK, "p", "test" },
855 { CH_STARTELEMENT, 3, 25, S_OK, "prefix", "node1", "node1", NULL },
856 { CH_ENDELEMENT, 3, 25, S_OK, "prefix", "node1", "node1" },
857 { CH_ENDPREFIXMAPPING, 3, 25, S_OK, "p" },
858 { CH_ENDELEMENT, 3, 27, S_OK, "prefix", "document", "document" },
859 { CH_ENDPREFIXMAPPING, 3, 27, S_OK, "" },
860 { CH_ENDPREFIXMAPPING, 3, 27, S_OK, "test" },
861 { CH_ENDDOCUMENT, 0, 0 },
862 { CH_ENDTEST }
863};
864
866 { "http://www.w3.org/XML/1998/namespace", "space", "xml:space", "preserve" },
867 { NULL }
868};
869
870static struct call_entry xmlspaceattr_test[] = {
871 { CH_PUTDOCUMENTLOCATOR, 0, 0, S_OK },
872 { CH_STARTDOCUMENT, 0, 0, S_OK },
873 { CH_STARTELEMENT, 1, 64, S_OK, "", "a", "a", xmlspace_attrs },
874 { CH_CHARACTERS, 1, 64, S_OK, " Some text data " },
875 { CH_ENDELEMENT, 1, 82, S_OK, "", "a", "a" },
876 { CH_ENDDOCUMENT, 0, 0, S_OK },
877 { CH_ENDTEST }
878};
879
881 { CH_PUTDOCUMENTLOCATOR, 1, 0, S_OK },
882 { CH_STARTDOCUMENT, 1, 39, S_OK },
883 { CH_STARTELEMENT, 1, 63, S_OK, "", "a", "a", xmlspace_attrs },
884 { CH_CHARACTERS, 1, 80, S_OK, " Some text data " },
885 { CH_ENDELEMENT, 1, 83, S_OK, "", "a", "a" },
886 { CH_ENDDOCUMENT, 1, 83, S_OK },
887 { CH_ENDTEST }
888};
889
890/* attribute value normalization test */
891static const char attribute_normalize[] =
892 "<?xml version=\"1.0\" ?>\n"
893 "<a attr1=\" \r \n \tattr_value &#65; &#38; &amp;\t \r \n\r\n \n\"/>\n";
894
896 { "", "attr1", "attr1", " attr_value A & & " },
897 { NULL }
898};
899
900static struct call_entry attribute_norm[] = {
901 { CH_PUTDOCUMENTLOCATOR, 0, 0, S_OK },
902 { CH_STARTDOCUMENT, 0, 0, S_OK },
903 { CH_STARTELEMENT, 6, 4, S_OK, "", "a", "a", attribute_norm_attrs },
904 { CH_ENDELEMENT, 6, 4, S_OK, "", "a", "a" },
905 { CH_ENDDOCUMENT, 0, 0, S_OK },
906 { CH_ENDTEST }
907};
908
910 { CH_PUTDOCUMENTLOCATOR, 1, 0, S_OK },
911 { CH_STARTDOCUMENT, 1, 22, S_OK },
912 { CH_STARTELEMENT, 8, 3, S_OK, "", "a", "a", attribute_norm_attrs },
913 { CH_ENDELEMENT, 8, 3, S_OK, "", "a", "a" },
914 { CH_ENDDOCUMENT, 9, 0, S_OK },
915 { CH_ENDTEST }
916};
917
918static struct call_entry cdata_test[] = {
919 { CH_PUTDOCUMENTLOCATOR, 0, 0, S_OK },
920 { CH_STARTDOCUMENT, 0, 0, S_OK },
921 { CH_STARTELEMENT, 1, 26, S_OK, "", "a", "a" },
922 { LH_STARTCDATA, 1, 35, S_OK },
923 { CH_CHARACTERS, 1, 35, S_OK, "Some \n" },
924 { CH_CHARACTERS, 1, 42, S_OK, "text\n\n" },
925 { CH_CHARACTERS, 1, 49, S_OK, "data\n\n" },
926 { LH_ENDCDATA, 1, 49, S_OK },
927 { CH_ENDELEMENT, 6, 6, S_OK, "", "a", "a" },
928 { CH_ENDDOCUMENT, 0, 0, S_OK },
929 { CH_ENDTEST }
930};
931
932static struct call_entry cdata_test2[] = {
933 { CH_PUTDOCUMENTLOCATOR, 0, 0, S_OK },
934 { CH_STARTDOCUMENT, 0, 0, S_OK },
935 { CH_STARTELEMENT, 1, 26, S_OK, "", "a", "a" },
936 { LH_STARTCDATA, 1, 35, S_OK },
937 { CH_CHARACTERS, 1, 35, S_OK, "\n\n" },
938 { CH_CHARACTERS, 1, 38, S_OK, "Some \n" },
939 { CH_CHARACTERS, 1, 45, S_OK, "text\n\n" },
940 { CH_CHARACTERS, 1, 52, S_OK, "data\n\n" },
941 { LH_ENDCDATA, 1, 52, S_OK },
942 { CH_ENDELEMENT, 8, 6, S_OK, "", "a", "a" },
943 { CH_ENDDOCUMENT, 0, 0, S_OK },
944 { CH_ENDTEST }
945};
946
947static struct call_entry cdata_test3[] = {
948 { CH_PUTDOCUMENTLOCATOR, 0, 0, S_OK },
949 { CH_STARTDOCUMENT, 0, 0, S_OK },
950 { CH_STARTELEMENT, 1, 26, S_OK, "", "a", "a" },
951 { LH_STARTCDATA, 1, 35, S_OK },
952 { CH_CHARACTERS, 1, 35, S_OK, "Some text data" },
953 { LH_ENDCDATA, 1, 35, S_OK },
954 { CH_ENDELEMENT, 1, 54, S_OK, "", "a", "a" },
955 { CH_ENDDOCUMENT, 0, 0, S_OK },
956 { CH_ENDTEST }
957};
958
959/* this is what MSXML6 does */
960static struct call_entry cdata_test_alt[] = {
961 { CH_PUTDOCUMENTLOCATOR, 1, 0, S_OK },
962 { CH_STARTDOCUMENT, 1, 22, S_OK },
963 { CH_STARTELEMENT, 1, 25, S_OK, "", "a", "a" },
964 { LH_STARTCDATA, 1, 34, S_OK },
965 { CH_CHARACTERS, 1, 40, S_OK, "Some " },
966 { CH_CHARACTERS, 2, 0, S_OK, "\n" },
967 { CH_CHARACTERS, 3, 1, S_OK, "text\n" },
968 { CH_CHARACTERS, 4, 0, S_OK, "\n" },
969 { CH_CHARACTERS, 6, 3, S_OK, "data\n\n" },
970 { LH_ENDCDATA, 6, 3, S_OK },
971 { CH_ENDELEMENT, 6, 7, S_OK, "", "a", "a" },
972 { CH_ENDDOCUMENT, 6, 7, S_OK },
973 { CH_ENDTEST }
974};
975
976static struct call_entry cdata_test2_alt[] = {
977 { CH_PUTDOCUMENTLOCATOR, 1, 0, S_OK },
978 { CH_STARTDOCUMENT, 1, 22, S_OK },
979 { CH_STARTELEMENT, 1, 25, S_OK, "", "a", "a" },
980 { LH_STARTCDATA, 1, 34, S_OK },
981 { CH_CHARACTERS, 2, 1, S_OK, "\n" },
982 { CH_CHARACTERS, 3, 0, S_OK, "\n" },
983 { CH_CHARACTERS, 3, 6, S_OK, "Some " },
984 { CH_CHARACTERS, 4, 0, S_OK, "\n" },
985 { CH_CHARACTERS, 5, 1, S_OK, "text\n" },
986 { CH_CHARACTERS, 6, 0, S_OK, "\n" },
987 { CH_CHARACTERS, 8, 3, S_OK, "data\n\n" },
988 { LH_ENDCDATA, 8, 3, S_OK },
989 { CH_ENDELEMENT, 8, 7, S_OK, "", "a", "a" },
990 { CH_ENDDOCUMENT, 8, 7, S_OK },
991 { CH_ENDTEST }
992};
993
994static struct call_entry cdata_test3_alt[] = {
995 { CH_PUTDOCUMENTLOCATOR, 1, 0, S_OK },
996 { CH_STARTDOCUMENT, 1, 22, S_OK },
997 { CH_STARTELEMENT, 1, 25, S_OK, "", "a", "a" },
998 { LH_STARTCDATA, 1, 34, S_OK },
999 { CH_CHARACTERS, 1, 51, S_OK, "Some text data" },
1000 { LH_ENDCDATA, 1, 51, S_OK },
1001 { CH_ENDELEMENT, 1, 55, S_OK, "", "a", "a" },
1002 { CH_ENDDOCUMENT, 1, 55, S_OK },
1003 { CH_ENDTEST }
1004};
1005
1007 { "", "attr", "attr", "val" },
1008 { NULL }
1009};
1010
1011static struct call_entry read_test_seq[] = {
1012 { CH_PUTDOCUMENTLOCATOR, -1, 0, S_OK },
1013 { CH_STARTDOCUMENT, -1, -1, S_OK },
1014 { CH_STARTELEMENT, -1, -1, S_OK, "", "rootelem", "rootelem" },
1015 { CH_STARTELEMENT, -1, -1, S_OK, "", "elem", "elem", read_test_attrs },
1016 { CH_CHARACTERS, -1, -1, S_OK, "text" },
1017 { CH_ENDELEMENT, -1, -1, S_OK, "", "elem", "elem" },
1018 { CH_STARTELEMENT, -1, -1, S_OK, "", "elem", "elem", read_test_attrs },
1019 { CH_CHARACTERS, -1, -1, S_OK, "text" },
1020 { CH_ENDELEMENT, -1, -1, S_OK, "", "elem", "elem" },
1021 { CH_STARTELEMENT, -1, -1, S_OK, "", "elem", "elem", read_test_attrs },
1022 { CH_CHARACTERS, -1, -1, S_OK, "text" },
1023 { CH_ENDELEMENT, -1, -1, S_OK, "", "elem", "elem" },
1024 { CH_STARTELEMENT, -1, -1, S_OK, "", "elem", "elem", read_test_attrs },
1025 { CH_CHARACTERS, -1, -1, S_OK, "text" },
1026 { CH_ENDELEMENT, -1, -1, S_OK, "", "elem", "elem" },
1027 { CH_ENDELEMENT, -1, -1, S_OK, "", "rootelem", "rootelem" },
1028 { CH_ENDDOCUMENT, -1, -1, S_OK},
1029 { CH_ENDTEST }
1030};
1031
1032static const char xmlspace_attr[] =
1033 "<?xml version=\"1.0\" encoding=\"UTF-16\"?>"
1034 "<a xml:space=\"preserve\"> Some text data </a>";
1035
1036static struct call_entry *expectCall;
1037static ISAXLocator *locator;
1038static ISAXXMLReader *g_reader;
1040
1042{
1044}
1045
1046/* to be called once on each tested callback return */
1048{
1049 HRESULT hr = expectCall->ret;
1050 if (expectCall->id != CH_ENDTEST) expectCall++;
1051 return hr;
1052}
1053
1055 ISAXContentHandler* iface,
1056 REFIID riid,
1057 void **ppvObject)
1058{
1059 *ppvObject = NULL;
1060
1061 if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ISAXContentHandler))
1062 {
1063 *ppvObject = iface;
1064 }
1065 else
1066 {
1067 return E_NOINTERFACE;
1068 }
1069
1070 return S_OK;
1071}
1072
1074 ISAXContentHandler* iface)
1075{
1076 return 2;
1077}
1078
1080 ISAXContentHandler* iface)
1081{
1082 return 1;
1083}
1084
1086 ISAXContentHandler* iface,
1087 ISAXLocator *pLocator)
1088{
1089 struct call_entry call;
1090 IUnknown *unk;
1091 HRESULT hr;
1092
1093 locator = pLocator;
1094
1095 init_call_entry(locator, &call);
1098
1099 hr = ISAXLocator_QueryInterface(pLocator, &IID_IVBSAXLocator, (void**)&unk);
1101
1102 if (msxml_version >= 6) {
1103 ISAXAttributes *attr, *attr1;
1104 IMXAttributes *mxattr;
1105
1106 EXPECT_REF(pLocator, 1);
1107 hr = ISAXLocator_QueryInterface(pLocator, &IID_ISAXAttributes, (void**)&attr);
1108 EXPECT_HR(hr, S_OK);
1109 EXPECT_REF(pLocator, 2);
1110 hr = ISAXLocator_QueryInterface(pLocator, &IID_ISAXAttributes, (void**)&attr1);
1111 EXPECT_HR(hr, S_OK);
1112 EXPECT_REF(pLocator, 3);
1113 ok(attr == attr1, "got %p, %p\n", attr, attr1);
1114
1115 hr = ISAXAttributes_QueryInterface(attr, &IID_IVBSAXAttributes, (void**)&unk);
1117
1118 hr = ISAXLocator_QueryInterface(pLocator, &IID_IVBSAXAttributes, (void**)&unk);
1120
1121 hr = ISAXAttributes_QueryInterface(attr, &IID_IMXAttributes, (void**)&mxattr);
1123
1124 ISAXAttributes_Release(attr);
1125 ISAXAttributes_Release(attr1);
1126 }
1127
1128 return get_expected_ret();
1129}
1130
1131static ISAXAttributes *test_attr_ptr;
1133 ISAXContentHandler* iface)
1134{
1135 struct call_entry call;
1136
1137 init_call_entry(locator, &call);
1138 call.id = CH_STARTDOCUMENT;
1140
1142
1143 return get_expected_ret();
1144}
1145
1147 ISAXContentHandler* iface)
1148{
1149 struct call_entry call;
1150
1151 init_call_entry(locator, &call);
1152 call.id = CH_ENDDOCUMENT;
1154
1155 return get_expected_ret();
1156}
1157
1159 ISAXContentHandler* iface,
1160 const WCHAR *prefix, int prefix_len,
1161 const WCHAR *uri, int uri_len)
1162{
1163 struct call_entry call;
1164
1165 ok(prefix != NULL, "prefix == NULL\n");
1166 ok(uri != NULL, "uri == NULL\n");
1167
1168 init_call_entry(locator, &call);
1170 call.arg1W = SysAllocStringLen(prefix, prefix_len);
1171 call.arg2W = SysAllocStringLen(uri, uri_len);
1173
1174 return get_expected_ret();
1175}
1176
1178 ISAXContentHandler* iface,
1179 const WCHAR *prefix, int len)
1180{
1181 struct call_entry call;
1182
1183 ok(prefix != NULL, "prefix == NULL\n");
1184
1185 init_call_entry(locator, &call);
1186 call.id = CH_ENDPREFIXMAPPING;
1187 call.arg1W = SysAllocStringLen(prefix, len);
1189
1190 return get_expected_ret();
1191}
1192
1194 ISAXContentHandler* iface,
1195 const WCHAR *uri, int uri_len,
1196 const WCHAR *localname, int local_len,
1197 const WCHAR *qname, int qname_len,
1198 ISAXAttributes *saxattr)
1199{
1200 struct call_entry call;
1201 IMXAttributes *mxattr;
1202 HRESULT hr;
1203 int len;
1204
1205 ok(uri != NULL, "uri == NULL\n");
1206 ok(localname != NULL, "localname == NULL\n");
1207 ok(qname != NULL, "qname == NULL\n");
1208
1209 hr = ISAXAttributes_QueryInterface(saxattr, &IID_IMXAttributes, (void**)&mxattr);
1211
1212 init_call_entry(locator, &call);
1213 call.id = CH_STARTELEMENT;
1214 call.arg1W = SysAllocStringLen(uri, uri_len);
1215 call.arg2W = SysAllocStringLen(localname, local_len);
1216 call.arg3W = SysAllocStringLen(qname, qname_len);
1217
1218 if(!test_attr_ptr)
1219 test_attr_ptr = saxattr;
1220 ok(test_attr_ptr == saxattr, "Multiple ISAXAttributes instances are used (%p %p)\n", test_attr_ptr, saxattr);
1221
1222 /* store actual attributes */
1223 len = 0;
1224 hr = ISAXAttributes_getLength(saxattr, &len);
1225 EXPECT_HR(hr, S_OK);
1226
1227 if (len)
1228 {
1230 int i;
1231
1232 struct attribute_entry *attr;
1233 attr = heap_alloc_zero(len * sizeof(*attr));
1234
1235 v = VARIANT_TRUE;
1236 hr = ISAXXMLReader_getFeature(g_reader, _bstr_("http://xml.org/sax/features/namespaces"), &v);
1237 EXPECT_HR(hr, S_OK);
1238
1239 for (i = 0; i < len; i++)
1240 {
1241 const WCHAR *value;
1242 int value_len;
1243
1244 hr = ISAXAttributes_getName(saxattr, i, &uri, &uri_len,
1245 &localname, &local_len, &qname, &qname_len);
1246 EXPECT_HR(hr, S_OK);
1247
1248 hr = ISAXAttributes_getValue(saxattr, i, &value, &value_len);
1249 EXPECT_HR(hr, S_OK);
1250
1251 /* if 'namespaces' switched off uri and local name contains garbage */
1252 if (v == VARIANT_FALSE && msxml_version > 0)
1253 {
1254 attr[i].uriW = SysAllocStringLen(NULL, 0);
1255 attr[i].localW = SysAllocStringLen(NULL, 0);
1256 }
1257 else
1258 {
1259 attr[i].uriW = SysAllocStringLen(uri, uri_len);
1260 attr[i].localW = SysAllocStringLen(localname, local_len);
1261 }
1262
1263 attr[i].qnameW = SysAllocStringLen(qname, qname_len);
1264 attr[i].valueW = SysAllocStringLen(value, value_len);
1265 }
1266
1267 call.attributes = attr;
1268 call.attr_count = len;
1269 }
1270
1272
1273 return get_expected_ret();
1274}
1275
1277 ISAXContentHandler* iface,
1278 const WCHAR *uri, int uri_len,
1279 const WCHAR *localname, int local_len,
1280 const WCHAR *qname, int qname_len)
1281{
1282 struct call_entry call;
1283
1284 ok(uri != NULL, "uri == NULL\n");
1285 ok(localname != NULL, "localname == NULL\n");
1286 ok(qname != NULL, "qname == NULL\n");
1287
1288 init_call_entry(locator, &call);
1289 call.id = CH_ENDELEMENT;
1290 call.arg1W = SysAllocStringLen(uri, uri_len);
1291 call.arg2W = SysAllocStringLen(localname, local_len);
1292 call.arg3W = SysAllocStringLen(qname, qname_len);
1294
1295 return get_expected_ret();
1296}
1297
1299 ISAXContentHandler* iface,
1300 const WCHAR *chars,
1301 int len)
1302{
1303 struct call_entry call;
1304
1305 ok(chars != NULL, "chars == NULL\n");
1306
1307 init_call_entry(locator, &call);
1308 call.id = CH_CHARACTERS;
1309 call.arg1W = SysAllocStringLen(chars, len);
1311
1312 return get_expected_ret();
1313}
1314
1316 ISAXContentHandler* iface,
1317 const WCHAR *chars, int len)
1318{
1319 struct call_entry call;
1320
1321 ok(chars != NULL, "chars == NULL\n");
1322
1323 init_call_entry(locator, &call);
1325 call.arg1W = SysAllocStringLen(chars, len);
1327
1328 return get_expected_ret();
1329}
1330
1332 ISAXContentHandler* iface,
1333 const WCHAR *target, int target_len,
1334 const WCHAR *data, int data_len)
1335{
1336 struct call_entry call;
1337
1338 ok(target != NULL, "target == NULL\n");
1339 ok(data != NULL, "data == NULL\n");
1340
1341 init_call_entry(locator, &call);
1343 call.arg1W = SysAllocStringLen(target, target_len);
1344 call.arg2W = SysAllocStringLen(data, data_len);
1346
1347 return get_expected_ret();
1348}
1349
1351 ISAXContentHandler* iface,
1352 const WCHAR *name, int len)
1353{
1354 struct call_entry call;
1355
1356 ok(name != NULL, "name == NULL\n");
1357
1358 init_call_entry(locator, &call);
1359 call.id = CH_SKIPPEDENTITY;
1362
1363 return get_expected_ret();
1364}
1365
1366static const ISAXContentHandlerVtbl contentHandlerVtbl =
1367{
1382};
1383
1384static ISAXContentHandler contentHandler = { &contentHandlerVtbl };
1385
1387 ISAXErrorHandler* iface,
1388 REFIID riid,
1389 void **ppvObject)
1390{
1391 *ppvObject = NULL;
1392
1393 if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ISAXErrorHandler))
1394 {
1395 *ppvObject = iface;
1396 }
1397 else
1398 {
1399 return E_NOINTERFACE;
1400 }
1401
1402 return S_OK;
1403}
1404
1406 ISAXErrorHandler* iface)
1407{
1408 return 2;
1409}
1410
1412 ISAXErrorHandler* iface)
1413{
1414 return 1;
1415}
1416
1418 ISAXErrorHandler* iface,
1419 ISAXLocator *pLocator,
1420 const WCHAR *pErrorMessage,
1421 HRESULT hrErrorCode)
1422{
1423 ok(0, "unexpected call\n");
1424 return S_OK;
1425}
1426
1428 ISAXErrorHandler* iface,
1429 ISAXLocator *pLocator,
1430 const WCHAR *message,
1431 HRESULT hr)
1432{
1433 struct call_entry call;
1434
1435 init_call_entry(locator, &call);
1436 call.id = EH_FATALERROR;
1437 call.ret = hr;
1438
1440
1442 return S_OK;
1443}
1444
1446 ISAXErrorHandler* iface,
1447 ISAXLocator *pLocator,
1448 const WCHAR *pErrorMessage,
1449 HRESULT hrErrorCode)
1450{
1451 ok(0, "unexpected call\n");
1452 return S_OK;
1453}
1454
1455static const ISAXErrorHandlerVtbl errorHandlerVtbl =
1456{
1463};
1464
1465static ISAXErrorHandler errorHandler = { &errorHandlerVtbl };
1466
1468 ISAXAttributes* iface,
1469 REFIID riid,
1470 void **ppvObject)
1471{
1472 *ppvObject = NULL;
1473
1474 if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ISAXAttributes))
1475 {
1476 *ppvObject = iface;
1477 }
1478 else
1479 {
1480 return E_NOINTERFACE;
1481 }
1482
1483 return S_OK;
1484}
1485
1486static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes* iface)
1487{
1488 return 2;
1489}
1490
1491static ULONG WINAPI isaxattributes_Release(ISAXAttributes* iface)
1492{
1493 return 1;
1494}
1495
1496static HRESULT WINAPI isaxattributes_getLength(ISAXAttributes* iface, int *length)
1497{
1498 *length = 3;
1499 return S_OK;
1500}
1501
1503 ISAXAttributes* iface,
1504 int nIndex,
1505 const WCHAR **pUrl,
1506 int *pUriSize)
1507{
1508 ok(0, "unexpected call\n");
1509 return E_NOTIMPL;
1510}
1511
1513 ISAXAttributes* iface,
1514 int nIndex,
1515 const WCHAR **pLocalName,
1516 int *pLocalNameLength)
1517{
1518 ok(0, "unexpected call\n");
1519 return E_NOTIMPL;
1520}
1521
1523 ISAXAttributes* iface,
1524 int index,
1525 const WCHAR **QName,
1526 int *QNameLength)
1527{
1528 static const WCHAR attrqnamesW[][15] = {{'a',':','a','t','t','r','1','j','u','n','k',0},
1529 {'a','t','t','r','2','j','u','n','k',0},
1530 {'a','t','t','r','3',0}};
1531 static const int attrqnamelen[] = {7, 5, 5};
1532
1533 ok(index >= 0 && index <= 2, "invalid index received %d\n", index);
1534
1535 if (index >= 0 && index <= 2) {
1536 *QName = attrqnamesW[index];
1537 *QNameLength = attrqnamelen[index];
1538 } else {
1539 *QName = NULL;
1540 *QNameLength = 0;
1541 }
1542
1543 return S_OK;
1544}
1545
1547 ISAXAttributes* iface,
1548 int nIndex,
1549 const WCHAR **pUri,
1550 int * pUriLength,
1551 const WCHAR ** pLocalName,
1552 int * pLocalNameSize,
1553 const WCHAR ** pQName,
1554 int * pQNameLength)
1555{
1556 ok(0, "unexpected call\n");
1557 return E_NOTIMPL;
1558}
1559
1561 ISAXAttributes* iface,
1562 const WCHAR * pUri,
1563 int cUriLength,
1564 const WCHAR * pLocalName,
1565 int cocalNameLength,
1566 int * index)
1567{
1568 ok(0, "unexpected call\n");
1569 return E_NOTIMPL;
1570}
1571
1573 ISAXAttributes* iface,
1574 const WCHAR * pQName,
1575 int nQNameLength,
1576 int * index)
1577{
1578 ok(0, "unexpected call\n");
1579 return E_NOTIMPL;
1580}
1581
1583 ISAXAttributes* iface,
1584 int nIndex,
1585 const WCHAR ** pType,
1586 int * pTypeLength)
1587{
1588 ok(0, "unexpected call\n");
1589 return E_NOTIMPL;
1590}
1591
1593 ISAXAttributes* iface,
1594 const WCHAR * pUri,
1595 int nUri,
1596 const WCHAR * pLocalName,
1597 int nLocalName,
1598 const WCHAR ** pType,
1599 int * nType)
1600{
1601 ok(0, "unexpected call\n");
1602 return E_NOTIMPL;
1603}
1604
1606 ISAXAttributes* iface,
1607 const WCHAR * pQName,
1608 int nQName,
1609 const WCHAR ** pType,
1610 int * nType)
1611{
1612 ok(0, "unexpected call\n");
1613 return E_NOTIMPL;
1614}
1615
1616static HRESULT WINAPI isaxattributes_getValue(ISAXAttributes* iface, int index,
1617 const WCHAR **value, int *nValue)
1618{
1619 static const WCHAR attrvaluesW[][10] = {{'a','1','j','u','n','k',0},
1620 {'a','2','j','u','n','k',0},
1621 {'<','&','"','>','\'',0}};
1622 static const int attrvalueslen[] = {2, 2, 5};
1623
1624 ok(index >= 0 && index <= 2, "invalid index received %d\n", index);
1625
1626 if (index >= 0 && index <= 2) {
1627 *value = attrvaluesW[index];
1628 *nValue = attrvalueslen[index];
1629 } else {
1630 *value = NULL;
1631 *nValue = 0;
1632 }
1633
1634 return S_OK;
1635}
1636
1638 ISAXAttributes* iface,
1639 const WCHAR * pUri,
1640 int nUri,
1641 const WCHAR * pLocalName,
1642 int nLocalName,
1643 const WCHAR ** pValue,
1644 int * nValue)
1645{
1646 ok(0, "unexpected call\n");
1647 return E_NOTIMPL;
1648}
1649
1651 ISAXAttributes* iface,
1652 const WCHAR * pQName,
1653 int nQName,
1654 const WCHAR ** pValue,
1655 int * nValue)
1656{
1657 ok(0, "unexpected call\n");
1658 return E_NOTIMPL;
1659}
1660
1661static const ISAXAttributesVtbl SAXAttributesVtbl =
1662{
1679};
1680
1681static ISAXAttributes saxattributes = { &SAXAttributesVtbl };
1682
1684{
1685 ISAXLexicalHandler ISAXLexicalHandler_iface;
1687
1688 HRESULT qi_hr; /* ret value for QueryInterface for handler riid */
1689};
1690
1691static inline struct saxlexicalhandler *impl_from_ISAXLexicalHandler( ISAXLexicalHandler *iface )
1692{
1694}
1695
1696static HRESULT WINAPI isaxlexical_QueryInterface(ISAXLexicalHandler* iface, REFIID riid, void **out)
1697{
1699
1700 *out = NULL;
1701
1703 {
1704 *out = iface;
1705 ok(0, "got unexpected IID_IUnknown query\n");
1706 }
1707 else if (IsEqualGUID(riid, &IID_ISAXLexicalHandler))
1708 {
1709 if (handler->qi_hr == E_NOINTERFACE) return handler->qi_hr;
1710 *out = iface;
1711 }
1712
1713 if (*out)
1714 ISAXLexicalHandler_AddRef(iface);
1715 else
1716 return E_NOINTERFACE;
1717
1718 return S_OK;
1719}
1720
1721static ULONG WINAPI isaxlexical_AddRef(ISAXLexicalHandler* iface)
1722{
1724 return InterlockedIncrement(&handler->ref);
1725}
1726
1727static ULONG WINAPI isaxlexical_Release(ISAXLexicalHandler* iface)
1728{
1730 return InterlockedDecrement(&handler->ref);
1731}
1732
1733static HRESULT WINAPI isaxlexical_startDTD(ISAXLexicalHandler* iface,
1734 const WCHAR * pName, int nName, const WCHAR * pPublicId,
1735 int nPublicId, const WCHAR * pSystemId, int nSystemId)
1736{
1737 ok(0, "call not expected\n");
1738 return E_NOTIMPL;
1739}
1740
1741static HRESULT WINAPI isaxlexical_endDTD(ISAXLexicalHandler* iface)
1742{
1743 ok(0, "call not expected\n");
1744 return E_NOTIMPL;
1745}
1746
1747static HRESULT WINAPI isaxlexical_startEntity(ISAXLexicalHandler *iface,
1748 const WCHAR * pName, int nName)
1749{
1750 ok(0, "call not expected\n");
1751 return E_NOTIMPL;
1752}
1753
1754static HRESULT WINAPI isaxlexical_endEntity(ISAXLexicalHandler *iface,
1755 const WCHAR * pName, int nName)
1756{
1757 ok(0, "call not expected\n");
1758 return E_NOTIMPL;
1759}
1760
1761static HRESULT WINAPI isaxlexical_startCDATA(ISAXLexicalHandler *iface)
1762{
1763 struct call_entry call;
1764
1765 init_call_entry(locator, &call);
1766 call.id = LH_STARTCDATA;
1768
1769 return get_expected_ret();
1770}
1771
1772static HRESULT WINAPI isaxlexical_endCDATA(ISAXLexicalHandler *iface)
1773{
1774 struct call_entry call;
1775
1776 init_call_entry(locator, &call);
1777 call.id = LH_ENDCDATA;
1779
1780 return get_expected_ret();
1781}
1782
1783static HRESULT WINAPI isaxlexical_comment(ISAXLexicalHandler *iface,
1784 const WCHAR * pChars, int nChars)
1785{
1786 ok(0, "call not expected\n");
1787 return E_NOTIMPL;
1788}
1789
1790static const ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl =
1791{
1802};
1803
1805{
1806 handler->ISAXLexicalHandler_iface.lpVtbl = &SAXLexicalHandlerVtbl;
1807 handler->ref = 1;
1808 handler->qi_hr = hr;
1809}
1810
1812{
1813 ISAXDeclHandler ISAXDeclHandler_iface;
1815
1816 HRESULT qi_hr; /* ret value for QueryInterface for handler riid */
1817};
1818
1819static inline struct saxdeclhandler *impl_from_ISAXDeclHandler( ISAXDeclHandler *iface )
1820{
1822}
1823
1824static HRESULT WINAPI isaxdecl_QueryInterface(ISAXDeclHandler* iface, REFIID riid, void **out)
1825{
1827
1828 *out = NULL;
1829
1831 {
1832 *out = iface;
1833 ok(0, "got unexpected IID_IUnknown query\n");
1834 }
1835 else if (IsEqualGUID(riid, &IID_ISAXDeclHandler))
1836 {
1837 if (handler->qi_hr == E_NOINTERFACE) return handler->qi_hr;
1838 *out = iface;
1839 }
1840
1841 if (*out)
1842 ISAXDeclHandler_AddRef(iface);
1843 else
1844 return E_NOINTERFACE;
1845
1846 return S_OK;
1847}
1848
1849static ULONG WINAPI isaxdecl_AddRef(ISAXDeclHandler* iface)
1850{
1852 return InterlockedIncrement(&handler->ref);
1853}
1854
1855static ULONG WINAPI isaxdecl_Release(ISAXDeclHandler* iface)
1856{
1858 return InterlockedDecrement(&handler->ref);
1859}
1860
1861static HRESULT WINAPI isaxdecl_elementDecl(ISAXDeclHandler* iface,
1862 const WCHAR * pName, int nName, const WCHAR * pModel, int nModel)
1863{
1864 ok(0, "call not expected\n");
1865 return E_NOTIMPL;
1866}
1867
1868static HRESULT WINAPI isaxdecl_attributeDecl(ISAXDeclHandler* iface,
1869 const WCHAR * pElementName, int nElementName, const WCHAR * pAttributeName,
1870 int nAttributeName, const WCHAR * pType, int nType, const WCHAR * pValueDefault,
1871 int nValueDefault, const WCHAR * pValue, int nValue)
1872{
1873 ok(0, "call not expected\n");
1874 return E_NOTIMPL;
1875}
1876
1877static HRESULT WINAPI isaxdecl_internalEntityDecl(ISAXDeclHandler* iface,
1878 const WCHAR * pName, int nName, const WCHAR * pValue, int nValue)
1879{
1880 ok(0, "call not expected\n");
1881 return E_NOTIMPL;
1882}
1883
1884static HRESULT WINAPI isaxdecl_externalEntityDecl(ISAXDeclHandler* iface,
1885 const WCHAR * pName, int nName, const WCHAR * pPublicId, int nPublicId,
1886 const WCHAR * pSystemId, int nSystemId)
1887{
1888 ok(0, "call not expected\n");
1889 return E_NOTIMPL;
1890}
1891
1892static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl =
1893{
1901};
1902
1904{
1905 handler->ISAXDeclHandler_iface.lpVtbl = &SAXDeclHandlerVtbl;
1906 handler->ref = 1;
1907 handler->qi_hr = hr;
1908}
1909
1912 const BYTE *data;
1917
1920 const char *encoding;
1923
1926
1928{
1929 *ppvObject = NULL;
1930
1931 ok(!IsEqualGUID(riid, &IID_IPersistStream), "Did not expect QI for IPersistStream\n");
1932
1933 if(IsEqualGUID(riid, &IID_IStream) || IsEqualGUID(riid, &IID_IUnknown))
1934 *ppvObject = iface;
1935 else
1936 return E_NOINTERFACE;
1937
1938 return S_OK;
1939}
1940
1942{
1943 return 2;
1944}
1945
1947{
1948 return 1;
1949}
1950
1951static HRESULT WINAPI istream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
1952{
1953 ok(0, "unexpected call\n");
1954 return E_NOTIMPL;
1955}
1956
1957static HRESULT WINAPI istream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
1958{
1959 ok(0, "unexpected call\n");
1960 return E_NOTIMPL;
1961}
1962
1963static HRESULT WINAPI istream_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin,
1964 ULARGE_INTEGER *plibNewPosition)
1965{
1966 ok(0, "unexpected call\n");
1967 return E_NOTIMPL;
1968}
1969
1971{
1972 ok(0, "unexpected call\n");
1973 return E_NOTIMPL;
1974}
1975
1977 ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *plibWritten)
1978{
1979 ok(0, "unexpected call\n");
1980 return E_NOTIMPL;
1981}
1982
1983static HRESULT WINAPI istream_Commit(IStream *iface, DWORD grfCommitFlags)
1984{
1985 ok(0, "unexpected call\n");
1986 return E_NOTIMPL;
1987}
1988
1990{
1991 ok(0, "unexpected call\n");
1992 return E_NOTIMPL;
1993}
1994
1996 ULARGE_INTEGER cb, DWORD dwLockType)
1997{
1998 ok(0, "unexpected call\n");
1999 return E_NOTIMPL;
2000}
2001
2003 ULARGE_INTEGER cb, DWORD dwLockType)
2004{
2005 ok(0, "unexpected call\n");
2006 return E_NOTIMPL;
2007}
2008
2009static HRESULT WINAPI istream_Stat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag)
2010{
2011 return E_NOTIMPL;
2012}
2013
2015{
2016 ok(0, "unexpected call\n");
2017 return E_NOTIMPL;
2018}
2019
2020static HRESULT WINAPI mxstream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
2021{
2022 BOOL fail = FALSE;
2023
2024 ok(pv != NULL, "pv == NULL\n");
2025
2027 ok(0, "Too many Write calls made on test %d\n", current_stream_test_index);
2028 return E_FAIL;
2029 }
2030
2032
2033 ok(current_write_test->cb == cb, "Expected %d, but got %d on test %d\n",
2035
2036 if(!pcbWritten)
2037 ok(current_write_test->null_written, "pcbWritten was NULL on test %d\n", current_stream_test_index);
2038 else
2039 ok(!memcmp(current_write_test->data, pv, cb), "Unexpected data on test %d\n", current_stream_test_index);
2040
2042
2043 if(pcbWritten)
2044 *pcbWritten = cb;
2045
2046 return fail ? E_FAIL : S_OK;
2047}
2048
2049static const IStreamVtbl mxstreamVtbl = {
2064};
2065
2067
2068static int read_cnt;
2069
2070static HRESULT WINAPI instream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
2071{
2072 static const char *ret_str;
2073
2074 if(!read_cnt)
2075 ret_str = "<?xml version=\"1.0\" ?>\n<rootelem>";
2076 else if(read_cnt < 5)
2077 ret_str = "<elem attr=\"val\">text</elem>";
2078 else if(read_cnt == 5)
2079 ret_str = "</rootelem>\n";
2080 else
2081 ret_str = "";
2082
2083 read_cnt++;
2084 strcpy(pv, ret_str);
2085 *pcbRead = strlen(ret_str);
2086 return S_OK;
2087}
2088
2089static const IStreamVtbl instreamVtbl = {
2104};
2105
2107
2109{
2110 { &CLSID_SAXXMLReader, "SAXReader" },
2111 { &CLSID_SAXXMLReader30, "SAXReader30" },
2112 { &CLSID_SAXXMLReader40, "SAXReader40" },
2113 { &CLSID_SAXXMLReader60, "SAXReader60" },
2114 { NULL }
2115};
2116
2119
2120static IStream *create_test_stream(const char *data, int len)
2121{
2124 IStream *stream;
2125 ULONG written;
2126
2127 if (len == -1) len = strlen(data);
2129 size.QuadPart = len;
2130 IStream_SetSize(stream, size);
2131 IStream_Write(stream, data, len, &written);
2132 pos.QuadPart = 0;
2133 IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
2134
2135 return stream;
2136}
2137
2138static void test_saxreader(void)
2139{
2141 HRESULT hr;
2142 ISAXXMLReader *reader = NULL;
2143 VARIANT var;
2144 ISAXContentHandler *content;
2145 ISAXErrorHandler *lpErrorHandler;
2146 SAFEARRAY *sa;
2147 SAFEARRAYBOUND SADim[1];
2148 char *ptr = NULL;
2149 IStream *stream;
2150 ULONG written;
2151 HANDLE file;
2152 static const CHAR testXmlA[] = "test.xml";
2153 static const WCHAR testXmlW[] = {'t','e','s','t','.','x','m','l',0};
2154 IXMLDOMDocument *doc;
2155 char seqname[50];
2157
2158 while (table->clsid)
2159 {
2160 struct call_entry *test_seq;
2161 ISAXEntityResolver *resolver;
2162 BSTR str;
2163
2165 {
2166 table++;
2167 continue;
2168 }
2169
2170 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_ISAXXMLReader, (void**)&reader);
2171 EXPECT_HR(hr, S_OK);
2172 g_reader = reader;
2173
2174 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40))
2175 msxml_version = 4;
2176 else if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2177 msxml_version = 6;
2178 else
2179 msxml_version = 0;
2180
2181 /* crashes on old versions */
2182 if (!IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) &&
2183 !IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2184 {
2185 hr = ISAXXMLReader_getContentHandler(reader, NULL);
2187
2188 hr = ISAXXMLReader_getErrorHandler(reader, NULL);
2190 }
2191
2192 hr = ISAXXMLReader_getContentHandler(reader, &content);
2193 EXPECT_HR(hr, S_OK);
2194 ok(content == NULL, "Expected %p, got %p\n", NULL, content);
2195
2196 hr = ISAXXMLReader_getErrorHandler(reader, &lpErrorHandler);
2197 EXPECT_HR(hr, S_OK);
2198 ok(lpErrorHandler == NULL, "Expected %p, got %p\n", NULL, lpErrorHandler);
2199
2200 hr = ISAXXMLReader_putContentHandler(reader, NULL);
2201 EXPECT_HR(hr, S_OK);
2202
2203 hr = ISAXXMLReader_putContentHandler(reader, &contentHandler);
2204 EXPECT_HR(hr, S_OK);
2205
2206 hr = ISAXXMLReader_putErrorHandler(reader, &errorHandler);
2207 EXPECT_HR(hr, S_OK);
2208
2209 hr = ISAXXMLReader_getContentHandler(reader, &content);
2210 EXPECT_HR(hr, S_OK);
2211 ok(content == &contentHandler, "Expected %p, got %p\n", &contentHandler, content);
2212
2213 V_VT(&var) = VT_BSTR;
2215
2216 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
2217 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2219 else
2220 test_seq = content_handler_test1;
2221 set_expected_seq(test_seq);
2222 hr = ISAXXMLReader_parse(reader, var);
2223 EXPECT_HR(hr, S_OK);
2224 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "content test 1", FALSE);
2225
2226 VariantClear(&var);
2227
2228 SADim[0].lLbound = 0;
2229 SADim[0].cElements = sizeof(testXML)-1;
2230 sa = SafeArrayCreate(VT_UI1, 1, SADim);
2231 SafeArrayAccessData(sa, (void**)&ptr);
2232 memcpy(ptr, testXML, sizeof(testXML)-1);
2234 V_VT(&var) = VT_ARRAY|VT_UI1;
2235 V_ARRAY(&var) = sa;
2236
2237 set_expected_seq(test_seq);
2238 hr = ISAXXMLReader_parse(reader, var);
2239 EXPECT_HR(hr, S_OK);
2240 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "content test 1: from safe array", FALSE);
2241
2243
2244 V_VT(&var) = VT_UNKNOWN;
2245 V_UNKNOWN(&var) = NULL;
2246 hr = ISAXXMLReader_parse(reader, var);
2247 ok(hr == E_INVALIDARG, "got %#x\n", hr);
2248
2249 V_VT(&var) = VT_DISPATCH;
2250 V_DISPATCH(&var) = NULL;
2251 hr = ISAXXMLReader_parse(reader, var);
2252 ok(hr == E_INVALIDARG, "got %#x\n", hr);
2253
2255 V_VT(&var) = VT_UNKNOWN;
2257
2258 set_expected_seq(test_seq);
2259 hr = ISAXXMLReader_parse(reader, var);
2260 EXPECT_HR(hr, S_OK);
2261 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "content test 1: from stream", FALSE);
2262
2263 IStream_Release(stream);
2264
2266 V_VT(&var) = VT_UNKNOWN;
2268
2269 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40))
2271 else if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2273 else
2275
2276 set_expected_seq(test_seq);
2277 hr = ISAXXMLReader_parse(reader, var);
2278 EXPECT_HR(hr, S_OK);
2279
2280 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
2281 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2282 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "content test attributes", FALSE);
2283 else
2284 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "content test attributes", TRUE);
2285
2286 IStream_Release(stream);
2287
2288 V_VT(&var) = VT_UNKNOWN;
2290
2291 test_seq = read_test_seq;
2292 read_cnt = 0;
2293 set_expected_seq(test_seq);
2294 hr = ISAXXMLReader_parse(reader, var);
2295 EXPECT_HR(hr, S_OK);
2296 ok(read_cnt == 7, "read_cnt = %d\n", read_cnt);
2297 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "Read call test", FALSE);
2298
2299 V_VT(&var) = VT_BSTR;
2301
2302 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
2303 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2305 else
2306 test_seq = content_handler_test2;
2307
2308 set_expected_seq(test_seq);
2309 hr = ISAXXMLReader_parse(reader, var);
2310 EXPECT_HR(hr, S_OK);
2311 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "content test 2", FALSE);
2312
2313 VariantClear(&var);
2314
2315 /* from file url */
2317 ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
2318 WriteFile(file, testXML, sizeof(testXML)-1, &written, NULL);
2320
2321 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
2322 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2324 else
2325 test_seq = content_handler_test1;
2326 set_expected_seq(test_seq);
2327 hr = ISAXXMLReader_parseURL(reader, testXmlW);
2328 EXPECT_HR(hr, S_OK);
2329 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "content test 1: from file url", FALSE);
2330
2331 /* error handler */
2332 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
2333 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2335 else
2336 test_seq = content_handler_testerror;
2337 set_expected_seq(test_seq);
2338 hr = ISAXXMLReader_parseURL(reader, testXmlW);
2340 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "content test error", FALSE);
2341
2342 /* callback ret values */
2343 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
2344 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2345 {
2347 set_expected_seq(test_seq);
2348 hr = ISAXXMLReader_parseURL(reader, testXmlW);
2349 EXPECT_HR(hr, S_OK);
2350 }
2351 else
2352 {
2354 set_expected_seq(test_seq);
2355 hr = ISAXXMLReader_parseURL(reader, testXmlW);
2357 }
2358 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "content callback ret values", FALSE);
2359
2360 DeleteFileA(testXmlA);
2361
2362 /* parse from IXMLDOMDocument */
2363 hr = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
2364 &IID_IXMLDOMDocument, (void**)&doc);
2365 EXPECT_HR(hr, S_OK);
2366
2368 hr = IXMLDOMDocument_loadXML(doc, str, &v);
2369 EXPECT_HR(hr, S_OK);
2371
2372 V_VT(&var) = VT_UNKNOWN;
2373 V_UNKNOWN(&var) = (IUnknown*)doc;
2374
2375 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
2376 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2378 else
2379 test_seq = content_handler_test2;
2380
2381 set_expected_seq(test_seq);
2382 hr = ISAXXMLReader_parse(reader, var);
2383 EXPECT_HR(hr, S_OK);
2384 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "parse from IXMLDOMDocument", FALSE);
2385 IXMLDOMDocument_Release(doc);
2386
2387 /* xml:space test */
2388 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
2389 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2390 {
2391 test_seq = xmlspaceattr_test_alternate;
2392 }
2393 else
2394 test_seq = xmlspaceattr_test;
2395
2396 set_expected_seq(test_seq);
2397 V_VT(&var) = VT_BSTR;
2399 hr = ISAXXMLReader_parse(reader, var);
2400 EXPECT_HR(hr, S_OK);
2401
2402 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
2403 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2404 {
2405 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "xml:space handling", TRUE);
2406 }
2407 else
2408 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "xml:space handling", FALSE);
2409
2410 /* switch off 'namespaces' feature */
2411 hr = ISAXXMLReader_putFeature(reader, _bstr_("http://xml.org/sax/features/namespaces"), VARIANT_FALSE);
2412 EXPECT_HR(hr, S_OK);
2413
2415 V_VT(&var) = VT_UNKNOWN;
2417
2418 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
2419 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2420 {
2422 }
2423 else
2425
2426 set_expected_seq(test_seq);
2427 hr = ISAXXMLReader_parse(reader, var);
2428 EXPECT_HR(hr, S_OK);
2429 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "content test attributes", TRUE);
2430 IStream_Release(stream);
2431 hr = ISAXXMLReader_putFeature(reader, _bstr_("http://xml.org/sax/features/namespaces"), VARIANT_TRUE);
2432 EXPECT_HR(hr, S_OK);
2433
2434 /* switch off 'namespace-prefixes' feature */
2435 hr = ISAXXMLReader_putFeature(reader, _bstr_("http://xml.org/sax/features/namespace-prefixes"), VARIANT_FALSE);
2436 EXPECT_HR(hr, S_OK);
2437
2439 V_VT(&var) = VT_UNKNOWN;
2441
2442 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
2443 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2444 {
2446 }
2447 else
2449
2450 set_expected_seq(test_seq);
2451 hr = ISAXXMLReader_parse(reader, var);
2452 EXPECT_HR(hr, S_OK);
2453 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "content test attributes", FALSE);
2454 IStream_Release(stream);
2455
2456 hr = ISAXXMLReader_putFeature(reader, _bstr_("http://xml.org/sax/features/namespace-prefixes"), VARIANT_TRUE);
2457 EXPECT_HR(hr, S_OK);
2458
2459 /* attribute normalization */
2461 V_VT(&var) = VT_UNKNOWN;
2463
2464 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
2465 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
2466 {
2467 test_seq = attribute_norm_alt;
2468 }
2469 else
2470 test_seq = attribute_norm;
2471
2472 set_expected_seq(test_seq);
2473 hr = ISAXXMLReader_parse(reader, var);
2474 EXPECT_HR(hr, S_OK);
2475 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "attribute value normalization", TRUE);
2476 IStream_Release(stream);
2477
2478 resolver = (void*)0xdeadbeef;
2479 hr = ISAXXMLReader_getEntityResolver(reader, &resolver);
2480 ok(hr == S_OK, "got 0x%08x\n", hr);
2481 ok(resolver == NULL, "got %p\n", resolver);
2482
2483 hr = ISAXXMLReader_putEntityResolver(reader, NULL);
2484 ok(hr == S_OK || broken(hr == E_FAIL), "got 0x%08x\n", hr);
2485
2486 /* CDATA sections */
2488
2489 V_VT(&var) = VT_UNKNOWN;
2490 V_UNKNOWN(&var) = (IUnknown*)&lexicalhandler.ISAXLexicalHandler_iface;
2491 hr = ISAXXMLReader_putProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), var);
2492 ok(hr == S_OK, "got 0x%08x\n", hr);
2493
2495 V_VT(&var) = VT_UNKNOWN;
2497
2498 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60) ||
2499 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40))
2500 test_seq = cdata_test_alt;
2501 else
2502 test_seq = cdata_test;
2503
2504 set_expected_seq(test_seq);
2505 hr = ISAXXMLReader_parse(reader, var);
2506 ok(hr == S_OK, "got 0x%08x\n", hr);
2507 sprintf(seqname, "%s: cdata test", table->name);
2508 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, seqname, TRUE);
2509
2510 IStream_Release(stream);
2511
2512 /* 2. CDATA sections */
2514 V_VT(&var) = VT_UNKNOWN;
2516
2517 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60) ||
2518 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40))
2519 test_seq = cdata_test2_alt;
2520 else
2521 test_seq = cdata_test2;
2522
2523 set_expected_seq(test_seq);
2524 hr = ISAXXMLReader_parse(reader, var);
2525 ok(hr == S_OK, "got 0x%08x\n", hr);
2526 sprintf(seqname, "%s: cdata test 2", table->name);
2527 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, seqname, TRUE);
2528
2529 IStream_Release(stream);
2530
2531 /* 3. CDATA sections */
2533 V_VT(&var) = VT_UNKNOWN;
2535
2536 if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60) ||
2537 IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40))
2538 test_seq = cdata_test3_alt;
2539 else
2540 test_seq = cdata_test3;
2541
2542 set_expected_seq(test_seq);
2543 hr = ISAXXMLReader_parse(reader, var);
2544 ok(hr == S_OK, "got 0x%08x\n", hr);
2545 sprintf(seqname, "%s: cdata test 3", table->name);
2546 ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, seqname, TRUE);
2547
2548 IStream_Release(stream);
2549
2550 ISAXXMLReader_Release(reader);
2551 table++;
2552 }
2553
2554 free_bstrs();
2555}
2556
2558{
2559 const char *prop_name;
2561};
2562
2564 { "http://xml.org/sax/properties/lexical-handler", (IUnknown*)&lexicalhandler.ISAXLexicalHandler_iface },
2565 { "http://xml.org/sax/properties/declaration-handler", (IUnknown*)&declhandler.ISAXDeclHandler_iface },
2566 { 0 }
2567};
2568
2570{
2572 ISAXXMLReader *reader;
2573 HRESULT hr;
2574 VARIANT v;
2575 BSTR str;
2576
2577 hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER,
2578 &IID_ISAXXMLReader, (void**)&reader);
2579 EXPECT_HR(hr, S_OK);
2580
2581 hr = ISAXXMLReader_getProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), NULL);
2583
2584 while (ptr->prop_name)
2585 {
2586 VARIANT varref;
2587 LONG ref;
2588
2591
2592 V_VT(&v) = VT_EMPTY;
2593 V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
2594 hr = ISAXXMLReader_getProperty(reader, _bstr_(ptr->prop_name), &v);
2595 EXPECT_HR(hr, S_OK);
2596 ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
2597 ok(V_UNKNOWN(&v) == NULL, "got %p\n", V_UNKNOWN(&v));
2598
2599 /* VT_UNKNOWN */
2600 V_VT(&v) = VT_UNKNOWN;
2601 V_UNKNOWN(&v) = ptr->iface;
2602 ref = get_refcount(ptr->iface);
2603 hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
2604 EXPECT_HR(hr, S_OK);
2605 ok(ref < get_refcount(ptr->iface), "expected inreased refcount\n");
2606
2607 /* VT_DISPATCH */
2608 V_VT(&v) = VT_DISPATCH;
2609 V_UNKNOWN(&v) = ptr->iface;
2610 ref = get_refcount(ptr->iface);
2611 hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
2612 EXPECT_HR(hr, S_OK);
2613 ok(ref == get_refcount(ptr->iface), "got wrong refcount %d, expected %d\n", get_refcount(ptr->iface), ref);
2614
2615 /* VT_VARIANT|VT_BYREF with VT_UNKNOWN in referenced variant */
2616 V_VT(&varref) = VT_UNKNOWN;
2617 V_UNKNOWN(&varref) = ptr->iface;
2618
2620 V_VARIANTREF(&v) = &varref;
2621 ref = get_refcount(ptr->iface);
2622 hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
2623 EXPECT_HR(hr, S_OK);
2624 ok(ref == get_refcount(ptr->iface), "got wrong refcount %d, expected %d\n", get_refcount(ptr->iface), ref);
2625
2626 /* VT_VARIANT|VT_BYREF with VT_DISPATCH in referenced variant */
2627 V_VT(&varref) = VT_DISPATCH;
2628 V_UNKNOWN(&varref) = ptr->iface;
2629
2631 V_VARIANTREF(&v) = &varref;
2632 ref = get_refcount(ptr->iface);
2633 hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
2634 EXPECT_HR(hr, S_OK);
2635 ok(ref == get_refcount(ptr->iface), "got wrong refcount %d, expected %d\n", get_refcount(ptr->iface), ref);
2636
2637 V_VT(&v) = VT_EMPTY;
2638 V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
2639
2640 ref = get_refcount(ptr->iface);
2641 hr = ISAXXMLReader_getProperty(reader, _bstr_(ptr->prop_name), &v);
2642 EXPECT_HR(hr, S_OK);
2643 ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
2644 ok(V_UNKNOWN(&v) == ptr->iface, "got %p\n", V_UNKNOWN(&v));
2645 ok(ref < get_refcount(ptr->iface), "expected inreased refcount\n");
2646 VariantClear(&v);
2647
2648 V_VT(&v) = VT_EMPTY;
2649 V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
2650 hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
2651 EXPECT_HR(hr, S_OK);
2652
2653 V_VT(&v) = VT_EMPTY;
2654 V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
2655 hr = ISAXXMLReader_getProperty(reader, _bstr_(ptr->prop_name), &v);
2656 EXPECT_HR(hr, S_OK);
2657 ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
2658 ok(V_UNKNOWN(&v) == NULL, "got %p\n", V_UNKNOWN(&v));
2659
2660 V_VT(&v) = VT_UNKNOWN;
2661 V_UNKNOWN(&v) = ptr->iface;
2662 hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
2663 EXPECT_HR(hr, S_OK);
2664
2665 /* only VT_EMPTY seems to be valid to reset property */
2666 V_VT(&v) = VT_I4;
2667 V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
2668 hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
2670
2671 V_VT(&v) = VT_EMPTY;
2672 V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
2673 hr = ISAXXMLReader_getProperty(reader, _bstr_(ptr->prop_name), &v);
2674 EXPECT_HR(hr, S_OK);
2675 ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
2676 ok(V_UNKNOWN(&v) == ptr->iface, "got %p\n", V_UNKNOWN(&v));
2677 VariantClear(&v);
2678
2679 V_VT(&v) = VT_UNKNOWN;
2680 V_UNKNOWN(&v) = NULL;
2681 hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
2682 EXPECT_HR(hr, S_OK);
2683
2684 V_VT(&v) = VT_EMPTY;
2685 V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
2686 hr = ISAXXMLReader_getProperty(reader, _bstr_(ptr->prop_name), &v);
2687 EXPECT_HR(hr, S_OK);
2688 ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
2689 ok(V_UNKNOWN(&v) == NULL, "got %p\n", V_UNKNOWN(&v));
2690
2691 /* block QueryInterface on handler riid */
2692 V_VT(&v) = VT_UNKNOWN;
2693 V_UNKNOWN(&v) = ptr->iface;
2694 hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
2695 EXPECT_HR(hr, S_OK);
2696
2699
2700 V_VT(&v) = VT_UNKNOWN;
2701 V_UNKNOWN(&v) = ptr->iface;
2702 EXPECT_REF(ptr->iface, 1);
2703 ref = get_refcount(ptr->iface);
2704 hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
2706 EXPECT_REF(ptr->iface, 1);
2707
2708 V_VT(&v) = VT_EMPTY;
2709 V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
2710 hr = ISAXXMLReader_getProperty(reader, _bstr_(ptr->prop_name), &v);
2711 EXPECT_HR(hr, S_OK);
2712 ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
2713 ok(V_UNKNOWN(&v) != NULL, "got %p\n", V_UNKNOWN(&v));
2714
2715 ptr++;
2716 free_bstrs();
2717 }
2718
2719 ISAXXMLReader_Release(reader);
2720
2721 if (!is_clsid_supported(&CLSID_SAXXMLReader40, reader_support_data))
2722 return;
2723
2724 hr = CoCreateInstance(&CLSID_SAXXMLReader40, NULL, CLSCTX_INPROC_SERVER,
2725 &IID_ISAXXMLReader, (void**)&reader);
2726 EXPECT_HR(hr, S_OK);
2727
2728 /* xmldecl-version property */
2729 V_VT(&v) = VT_EMPTY;
2730 V_BSTR(&v) = (void*)0xdeadbeef;
2731 hr = ISAXXMLReader_getProperty(reader, _bstr_("xmldecl-version"), &v);
2732 EXPECT_HR(hr, S_OK);
2733 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
2734 ok(V_BSTR(&v) == NULL, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
2735
2736 /* stream without declaration */
2737 V_VT(&v) = VT_BSTR;
2738 V_BSTR(&v) = _bstr_("<element></element>");
2739 hr = ISAXXMLReader_parse(reader, v);
2740 EXPECT_HR(hr, S_OK);
2741
2742 V_VT(&v) = VT_EMPTY;
2743 V_BSTR(&v) = (void*)0xdeadbeef;
2744 hr = ISAXXMLReader_getProperty(reader, _bstr_("xmldecl-version"), &v);
2745 EXPECT_HR(hr, S_OK);
2746 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
2747 ok(V_BSTR(&v) == NULL, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
2748
2749 /* stream with declaration */
2750 V_VT(&v) = VT_BSTR;
2751 V_BSTR(&v) = _bstr_("<?xml version=\"1.0\"?><element></element>");
2752 hr = ISAXXMLReader_parse(reader, v);
2753 EXPECT_HR(hr, S_OK);
2754
2755 /* VT_BSTR|VT_BYREF input type */
2756 str = _bstr_("<?xml version=\"1.0\"?><element></element>");
2757 V_VT(&v) = VT_BSTR|VT_BYREF;
2758 V_BSTRREF(&v) = &str;
2759 hr = ISAXXMLReader_parse(reader, v);
2760 EXPECT_HR(hr, S_OK);
2761
2762 V_VT(&v) = VT_EMPTY;
2763 V_BSTR(&v) = (void*)0xdeadbeef;
2764 hr = ISAXXMLReader_getProperty(reader, _bstr_("xmldecl-version"), &v);
2765 EXPECT_HR(hr, S_OK);
2766 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
2767 ok(!lstrcmpW(V_BSTR(&v), _bstr_("1.0")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
2768 VariantClear(&v);
2769
2770 ISAXXMLReader_Release(reader);
2771 free_bstrs();
2772}
2773
2775 const GUID *guid;
2776 const char *clsid;
2778 VARIANT_BOOL value2; /* feature value after feature set to 0xc */
2779};
2780
2782 { &CLSID_SAXXMLReader, "CLSID_SAXXMLReader", VARIANT_TRUE, VARIANT_FALSE },
2783 { &CLSID_SAXXMLReader30, "CLSID_SAXXMLReader30", VARIANT_TRUE, VARIANT_FALSE },
2784 { &CLSID_SAXXMLReader40, "CLSID_SAXXMLReader40", VARIANT_TRUE, VARIANT_TRUE },
2785 { &CLSID_SAXXMLReader60, "CLSID_SAXXMLReader60", VARIANT_TRUE, VARIANT_TRUE },
2786 { 0 }
2787};
2788
2789static const char *feature_names[] = {
2790 "http://xml.org/sax/features/namespaces",
2791 "http://xml.org/sax/features/namespace-prefixes",
2792 0
2793};
2794
2796{
2798 ISAXXMLReader *reader;
2799
2800 while (entry->guid)
2801 {
2803 const char **name;
2804 HRESULT hr;
2805
2806 hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_ISAXXMLReader, (void**)&reader);
2807 if (hr != S_OK)
2808 {
2809 win_skip("can't create %s instance\n", entry->clsid);
2810 entry++;
2811 continue;
2812 }
2813
2814 if (IsEqualGUID(entry->guid, &CLSID_SAXXMLReader40) ||
2815 IsEqualGUID(entry->guid, &CLSID_SAXXMLReader60))
2816 {
2817 value = VARIANT_TRUE;
2818 hr = ISAXXMLReader_getFeature(reader, _bstr_("exhaustive-errors"), &value);
2819 ok(hr == S_OK, "Failed to get feature value, hr %#x.\n", hr);
2820 ok(value == VARIANT_FALSE, "Unexpected default feature value.\n");
2821 hr = ISAXXMLReader_putFeature(reader, _bstr_("exhaustive-errors"), VARIANT_FALSE);
2822 ok(hr == S_OK, "Failed to put feature value, hr %#x.\n", hr);
2823
2824 value = VARIANT_TRUE;
2825 hr = ISAXXMLReader_getFeature(reader, _bstr_("schema-validation"), &value);
2826 ok(hr == S_OK, "Failed to get feature value, hr %#x.\n", hr);
2827 ok(value == VARIANT_FALSE, "Unexpected default feature value.\n");
2828 hr = ISAXXMLReader_putFeature(reader, _bstr_("exhaustive-errors"), VARIANT_FALSE);
2829 ok(hr == S_OK, "Failed to put feature value, hr %#x.\n", hr);
2830 }
2831 else
2832 {
2833 value = 123;
2834 hr = ISAXXMLReader_getFeature(reader, _bstr_("exhaustive-errors"), &value);
2835 ok(hr == E_INVALIDARG, "Failed to get feature value, hr %#x.\n", hr);
2836 ok(value == 123, "Unexpected value %d.\n", value);
2837
2838 value = 123;
2839 hr = ISAXXMLReader_getFeature(reader, _bstr_("schema-validation"), &value);
2840 ok(hr == E_INVALIDARG, "Failed to get feature value, hr %#x.\n", hr);
2841 ok(value == 123, "Unexpected value %d.\n", value);
2842 }
2843
2845 while (*name)
2846 {
2847 value = 0xc;
2848 hr = ISAXXMLReader_getFeature(reader, _bstr_(*name), &value);
2849 EXPECT_HR(hr, S_OK);
2850 ok(entry->value == value, "%s: got wrong default value %x, expected %x\n", entry->clsid, value, entry->value);
2851
2852 value = 0xc;
2853 hr = ISAXXMLReader_putFeature(reader, _bstr_(*name), value);
2854 EXPECT_HR(hr, S_OK);
2855
2856 value = 0xd;
2857 hr = ISAXXMLReader_getFeature(reader, _bstr_(*name), &value);
2858 EXPECT_HR(hr, S_OK);
2859 ok(entry->value2 == value, "%s: got wrong value %x, expected %x\n", entry->clsid, value, entry->value2);
2860
2861 hr = ISAXXMLReader_putFeature(reader, _bstr_(*name), VARIANT_FALSE);
2862 EXPECT_HR(hr, S_OK);
2863 value = 0xd;
2864 hr = ISAXXMLReader_getFeature(reader, _bstr_(*name), &value);
2865 EXPECT_HR(hr, S_OK);
2866 ok(value == VARIANT_FALSE, "%s: got wrong value %x, expected VARIANT_FALSE\n", entry->clsid, value);
2867
2868 hr = ISAXXMLReader_putFeature(reader, _bstr_(*name), VARIANT_TRUE);
2869 EXPECT_HR(hr, S_OK);
2870 value = 0xd;
2871 hr = ISAXXMLReader_getFeature(reader, _bstr_(*name), &value);
2872 EXPECT_HR(hr, S_OK);
2873 ok(value == VARIANT_TRUE, "%s: got wrong value %x, expected VARIANT_TRUE\n", entry->clsid, value);
2874
2875 name++;
2876 }
2877
2878 ISAXXMLReader_Release(reader);
2879
2880 entry++;
2881 }
2882}
2883
2884/* UTF-8 data with UTF-8 BOM and UTF-16 in prolog */
2885static const CHAR UTF8BOMTest[] =
2886"\xEF\xBB\xBF<?xml version = \"1.0\" encoding = \"UTF-16\"?>\n"
2887"<a></a>\n";
2888
2890 const GUID *guid;
2891 const char *clsid;
2892 const char *data;
2895};
2896
2897static const struct enc_test_entry_t encoding_test_data[] = {
2898 { &CLSID_SAXXMLReader, "CLSID_SAXXMLReader", UTF8BOMTest, 0xc00ce56f, TRUE },
2899 { &CLSID_SAXXMLReader30, "CLSID_SAXXMLReader30", UTF8BOMTest, 0xc00ce56f, TRUE },
2900 { &CLSID_SAXXMLReader40, "CLSID_SAXXMLReader40", UTF8BOMTest, S_OK, FALSE },
2901 { &CLSID_SAXXMLReader60, "CLSID_SAXXMLReader60", UTF8BOMTest, S_OK, FALSE },
2902 { 0 }
2903};
2904
2906{
2908 static const WCHAR testXmlW[] = {'t','e','s','t','.','x','m','l',0};
2909 static const CHAR testXmlA[] = "test.xml";
2910
2911 while (entry->guid)
2912 {
2913 ISAXXMLReader *reader;
2914 VARIANT input;
2915 DWORD written;
2916 HANDLE file;
2917 HRESULT hr;
2918
2919 hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_ISAXXMLReader, (void**)&reader);
2920 if (hr != S_OK)
2921 {
2922 win_skip("can't create %s instance\n", entry->clsid);
2923 entry++;
2924 continue;
2925 }
2926
2928 ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
2929 WriteFile(file, UTF8BOMTest, sizeof(UTF8BOMTest)-1, &written, NULL);
2931
2932 hr = ISAXXMLReader_parseURL(reader, testXmlW);
2933 todo_wine_if(entry->todo)
2934 ok(hr == entry->hr, "Expected 0x%08x, got 0x%08x. CLSID %s\n", entry->hr, hr, entry->clsid);
2935
2936 DeleteFileA(testXmlA);
2937
2938 /* try BSTR input with no BOM or '<?xml' instruction */
2939 V_VT(&input) = VT_BSTR;
2940 V_BSTR(&input) = _bstr_("<element></element>");
2941 hr = ISAXXMLReader_parse(reader, input);
2942 EXPECT_HR(hr, S_OK);
2943
2944 ISAXXMLReader_Release(reader);
2945
2946 free_bstrs();
2947 entry++;
2948 }
2949}
2950
2951static void test_mxwriter_handlers(void)
2952{
2953 IMXWriter *writer;
2954 HRESULT hr;
2955 int i;
2956
2957 static REFIID riids[] =
2958 {
2959 &IID_ISAXContentHandler,
2960 &IID_ISAXLexicalHandler,
2961 &IID_ISAXDeclHandler,
2962 &IID_ISAXDTDHandler,
2963 &IID_ISAXErrorHandler,
2964 &IID_IVBSAXDeclHandler,
2965 &IID_IVBSAXLexicalHandler,
2966 &IID_IVBSAXContentHandler,
2967 &IID_IVBSAXDTDHandler,
2968 &IID_IVBSAXErrorHandler
2969 };
2970
2971 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
2972 &IID_IMXWriter, (void**)&writer);
2973 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
2974
2975 EXPECT_REF(writer, 1);
2976
2977 for (i = 0; i < ARRAY_SIZE(riids); i++)
2978 {
2980 IMXWriter *writer2;
2981
2982 /* handler from IMXWriter */
2983 hr = IMXWriter_QueryInterface(writer, riids[i], (void**)&handler);
2984 ok(hr == S_OK, "%s, expected S_OK, got %08x\n", wine_dbgstr_guid(riids[i]), hr);
2985 EXPECT_REF(writer, 2);
2986 EXPECT_REF(handler, 2);
2987
2988 /* IMXWriter from a handler */
2989 hr = IUnknown_QueryInterface(handler, &IID_IMXWriter, (void**)&writer2);
2990 ok(hr == S_OK, "%s, expected S_OK, got %08x\n", wine_dbgstr_guid(riids[i]), hr);
2991 ok(writer2 == writer, "got %p, expected %p\n", writer2, writer);
2992 EXPECT_REF(writer, 3);
2993 IMXWriter_Release(writer2);
2994 IUnknown_Release(handler);
2995 }
2996
2997 IMXWriter_Release(writer);
2998}
2999
3001{
3002 { &CLSID_MXXMLWriter, "MXXMLWriter" },
3003 { &CLSID_MXXMLWriter30, "MXXMLWriter30" },
3004 { &CLSID_MXXMLWriter40, "MXXMLWriter40" },
3005 { &CLSID_MXXMLWriter60, "MXXMLWriter60" },
3006 { NULL }
3007};
3008
3010{
3011 { &CLSID_SAXAttributes, "SAXAttributes" },
3012 { &CLSID_SAXAttributes30, "SAXAttributes30" },
3013 { &CLSID_SAXAttributes40, "SAXAttributes40" },
3014 { &CLSID_SAXAttributes60, "SAXAttributes60" },
3015 { NULL }
3016};
3017
3019{
3020 const GUID *clsid;
3026 const char *encoding;
3027};
3028
3030{
3031 { &CLSID_MXXMLWriter, VARIANT_TRUE, VARIANT_FALSE, VARIANT_FALSE, VARIANT_FALSE, VARIANT_FALSE, "UTF-16" },
3032 { &CLSID_MXXMLWriter30, VARIANT_TRUE, VARIANT_FALSE, VARIANT_FALSE, VARIANT_FALSE, VARIANT_FALSE, "UTF-16" },
3033 { &CLSID_MXXMLWriter40, VARIANT_TRUE, VARIANT_FALSE, VARIANT_FALSE, VARIANT_FALSE, VARIANT_FALSE, "UTF-16" },
3034 { &CLSID_MXXMLWriter60, VARIANT_TRUE, VARIANT_FALSE, VARIANT_FALSE, VARIANT_FALSE, VARIANT_FALSE, "UTF-16" },
3035 { NULL }
3036};
3037
3039{
3040 int i = 0;
3041
3042 while (table->clsid)
3043 {
3044 IMXWriter *writer;
3046 BSTR encoding;
3047 HRESULT hr;
3048
3050 {
3051 table++;
3052 i++;
3053 continue;
3054 }
3055
3056 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER,
3057 &IID_IMXWriter, (void**)&writer);
3058 EXPECT_HR(hr, S_OK);
3059
3060 b = !table->bom;
3061 hr = IMXWriter_get_byteOrderMark(writer, &b);
3062 EXPECT_HR(hr, S_OK);
3063 ok(table->bom == b, "test %d: got BOM %d, expected %d\n", i, b, table->bom);
3064
3065 b = !table->disable_escape;
3066 hr = IMXWriter_get_disableOutputEscaping(writer, &b);
3067 EXPECT_HR(hr, S_OK);
3068 ok(table->disable_escape == b, "test %d: got disable escape %d, expected %d\n", i, b,
3069 table->disable_escape);
3070
3071 b = !table->indent;
3072 hr = IMXWriter_get_indent(writer, &b);
3073 EXPECT_HR(hr, S_OK);
3074 ok(table->indent == b, "test %d: got indent %d, expected %d\n", i, b, table->indent);
3075
3076 b = !table->omitdecl;
3077 hr = IMXWriter_get_omitXMLDeclaration(writer, &b);
3078 EXPECT_HR(hr, S_OK);
3079 ok(table->omitdecl == b, "test %d: got omitdecl %d, expected %d\n", i, b, table->omitdecl);
3080
3081 b = !table->standalone;
3082 hr = IMXWriter_get_standalone(writer, &b);
3083 EXPECT_HR(hr, S_OK);
3084 ok(table->standalone == b, "test %d: got standalone %d, expected %d\n", i, b, table->standalone);
3085
3086 hr = IMXWriter_get_encoding(writer, &encoding);
3087 EXPECT_HR(hr, S_OK);
3088 ok(!lstrcmpW(encoding, _bstr_(table->encoding)), "test %d: got encoding %s, expected %s\n",
3089 i, wine_dbgstr_w(encoding), table->encoding);
3091
3092 IMXWriter_Release(writer);
3093
3094 table++;
3095 i++;
3096 }
3097}
3098
3100{
3101 static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
3102 static const WCHAR testW[] = {'t','e','s','t',0};
3103 ISAXContentHandler *content;
3104 IMXWriter *writer;
3106 HRESULT hr;
3107 BSTR str, str2;
3108 VARIANT dest;
3109
3111
3112 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
3113 &IID_IMXWriter, (void**)&writer);
3114 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3115
3116 hr = IMXWriter_get_disableOutputEscaping(writer, NULL);
3117 ok(hr == E_POINTER, "got %08x\n", hr);
3118
3119 hr = IMXWriter_get_byteOrderMark(writer, NULL);
3120 ok(hr == E_POINTER, "got %08x\n", hr);
3121
3122 hr = IMXWriter_get_indent(writer, NULL);
3123 ok(hr == E_POINTER, "got %08x\n", hr);
3124
3125 hr = IMXWriter_get_omitXMLDeclaration(writer, NULL);
3126 ok(hr == E_POINTER, "got %08x\n", hr);
3127
3128 hr = IMXWriter_get_standalone(writer, NULL);
3129 ok(hr == E_POINTER, "got %08x\n", hr);
3130
3131 /* set and check */
3132 hr = IMXWriter_put_standalone(writer, VARIANT_TRUE);
3133 ok(hr == S_OK, "got %08x\n", hr);
3134
3135 b = VARIANT_FALSE;
3136 hr = IMXWriter_get_standalone(writer, &b);
3137 ok(hr == S_OK, "got %08x\n", hr);
3138 ok(b == VARIANT_TRUE, "got %d\n", b);
3139
3140 hr = IMXWriter_get_encoding(writer, NULL);
3142
3143 /* UTF-16 is a default setting apparently */
3144 str = (void*)0xdeadbeef;
3145 hr = IMXWriter_get_encoding(writer, &str);
3146 EXPECT_HR(hr, S_OK);
3147 ok(lstrcmpW(str, utf16W) == 0, "expected empty string, got %s\n", wine_dbgstr_w(str));
3148
3149 str2 = (void*)0xdeadbeef;
3150 hr = IMXWriter_get_encoding(writer, &str2);
3151 ok(hr == S_OK, "got %08x\n", hr);
3152 ok(str != str2, "expected newly allocated, got same %p\n", str);
3153
3154 SysFreeString(str2);
3156
3157 /* put empty string */
3159 hr = IMXWriter_put_encoding(writer, str);
3160 ok(hr == E_INVALIDARG, "got %08x\n", hr);
3162
3163 str = (void*)0xdeadbeef;
3164 hr = IMXWriter_get_encoding(writer, &str);
3165 EXPECT_HR(hr, S_OK);
3166 ok(!lstrcmpW(str, _bstr_("UTF-16")), "got %s\n", wine_dbgstr_w(str));
3168
3169 /* invalid encoding name */
3171 hr = IMXWriter_put_encoding(writer, str);
3172 ok(hr == E_INVALIDARG, "got %08x\n", hr);
3174
3175 /* test case sensivity */
3176 hr = IMXWriter_put_encoding(writer, _bstr_("utf-8"));
3177 EXPECT_HR(hr, S_OK);
3178 str = (void*)0xdeadbeef;
3179 hr = IMXWriter_get_encoding(writer, &str);
3180 EXPECT_HR(hr, S_OK);
3181 ok(!lstrcmpW(str, _bstr_("utf-8")), "got %s\n", wine_dbgstr_w(str));
3183
3184 hr = IMXWriter_put_encoding(writer, _bstr_("uTf-16"));
3185 EXPECT_HR(hr, S_OK);
3186 str = (void*)0xdeadbeef;
3187 hr = IMXWriter_get_encoding(writer, &str);
3188 EXPECT_HR(hr, S_OK);
3189 ok(!lstrcmpW(str, _bstr_("uTf-16")), "got %s\n", wine_dbgstr_w(str));
3191
3192 /* how it affects document creation */
3193 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
3194 EXPECT_HR(hr, S_OK);
3195
3196 hr = ISAXContentHandler_startDocument(content);
3197 EXPECT_HR(hr, S_OK);
3198 hr = ISAXContentHandler_endDocument(content);
3199 EXPECT_HR(hr, S_OK);
3200
3201 V_VT(&dest) = VT_EMPTY;
3202 hr = IMXWriter_get_output(writer, &dest);
3203 EXPECT_HR(hr, S_OK);
3204 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3205 ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\"?>\r\n"),
3206 V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
3208 ISAXContentHandler_Release(content);
3209
3210 hr = IMXWriter_get_version(writer, NULL);
3211 ok(hr == E_POINTER, "got %08x\n", hr);
3212 /* default version is 'surprisingly' 1.0 */
3213 hr = IMXWriter_get_version(writer, &str);
3214 ok(hr == S_OK, "got %08x\n", hr);
3215 ok(!lstrcmpW(str, _bstr_("1.0")), "got %s\n", wine_dbgstr_w(str));
3217
3218 /* store version string as is */
3219 hr = IMXWriter_put_version(writer, NULL);
3220 ok(hr == E_INVALIDARG, "got %08x\n", hr);
3221
3222 hr = IMXWriter_put_version(writer, _bstr_("1.0"));
3223 ok(hr == S_OK, "got %08x\n", hr);
3224
3225 hr = IMXWriter_put_version(writer, _bstr_(""));
3226 ok(hr == S_OK, "got %08x\n", hr);
3227 hr = IMXWriter_get_version(writer, &str);
3228 ok(hr == S_OK, "got %08x\n", hr);
3229 ok(!lstrcmpW(str, _bstr_("")), "got %s\n", wine_dbgstr_w(str));
3231
3232 hr = IMXWriter_put_version(writer, _bstr_("a.b"));
3233 ok(hr == S_OK, "got %08x\n", hr);
3234 hr = IMXWriter_get_version(writer, &str);
3235 ok(hr == S_OK, "got %08x\n", hr);
3236 ok(!lstrcmpW(str, _bstr_("a.b")), "got %s\n", wine_dbgstr_w(str));
3238
3239 hr = IMXWriter_put_version(writer, _bstr_("2.0"));
3240 ok(hr == S_OK, "got %08x\n", hr);
3241 hr = IMXWriter_get_version(writer, &str);
3242 ok(hr == S_OK, "got %08x\n", hr);
3243 ok(!lstrcmpW(str, _bstr_("2.0")), "got %s\n", wine_dbgstr_w(str));
3245
3246 IMXWriter_Release(writer);
3247 free_bstrs();
3248}
3249
3250static void test_mxwriter_flush(void)
3251{
3252 ISAXContentHandler *content;
3253 IMXWriter *writer;
3255 ULARGE_INTEGER pos2;
3256 IStream *stream;
3257 VARIANT dest;
3258 HRESULT hr;
3259 char *buff;
3260 LONG ref;
3261 int len;
3262
3263 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
3264 &IID_IMXWriter, (void**)&writer);
3265 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3266
3268 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3269 EXPECT_REF(stream, 1);
3270
3271 /* detach when nothing was attached */
3272 V_VT(&dest) = VT_EMPTY;
3273 hr = IMXWriter_put_output(writer, dest);
3274 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3275
3276 /* attach stream */
3277 V_VT(&dest) = VT_UNKNOWN;
3279 hr = IMXWriter_put_output(writer, dest);
3280 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3282
3283 /* detach setting VT_EMPTY destination */
3284 V_VT(&dest) = VT_EMPTY;
3285 hr = IMXWriter_put_output(writer, dest);
3286 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3287 EXPECT_REF(stream, 1);
3288
3289 V_VT(&dest) = VT_UNKNOWN;
3291 hr = IMXWriter_put_output(writer, dest);
3292 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3293
3294 /* flush() doesn't detach a stream */
3295 hr = IMXWriter_flush(writer);
3296 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3298
3299 pos.QuadPart = 0;
3300 hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
3301 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3302 ok(pos2.QuadPart == 0, "expected stream beginning\n");
3303
3304 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
3305 ok(hr == S_OK, "got %08x\n", hr);
3306
3307 hr = ISAXContentHandler_startDocument(content);
3308 ok(hr == S_OK, "got %08x\n", hr);
3309
3310 pos.QuadPart = 0;
3311 hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
3312 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3313 ok(pos2.QuadPart != 0, "expected stream beginning\n");
3314
3315 /* already started */
3316 hr = ISAXContentHandler_startDocument(content);
3317 ok(hr == S_OK, "got %08x\n", hr);
3318
3319 hr = ISAXContentHandler_endDocument(content);
3320 ok(hr == S_OK, "got %08x\n", hr);
3321
3322 /* flushed on endDocument() */
3323 pos.QuadPart = 0;
3324 hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
3325 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3326 ok(pos2.QuadPart != 0, "expected stream position moved\n");
3327
3328 IStream_Release(stream);
3329
3330 /* auto-flush feature */
3332 EXPECT_HR(hr, S_OK);
3333 EXPECT_REF(stream, 1);
3334
3335 V_VT(&dest) = VT_UNKNOWN;
3337 hr = IMXWriter_put_output(writer, dest);
3338 EXPECT_HR(hr, S_OK);
3339
3340 hr = IMXWriter_put_byteOrderMark(writer, VARIANT_FALSE);
3341 EXPECT_HR(hr, S_OK);
3342
3343 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
3344 EXPECT_HR(hr, S_OK);
3345
3346 hr = ISAXContentHandler_startDocument(content);
3347 EXPECT_HR(hr, S_OK);
3348
3349 hr = ISAXContentHandler_startElement(content, emptyW, 0, emptyW, 0, _bstr_("a"), -1, NULL);
3350 EXPECT_HR(hr, S_OK);
3351
3352 /* internal buffer is flushed automatically on certain threshold */
3353 pos.QuadPart = 0;
3354 pos2.QuadPart = 1;
3355 hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
3356 EXPECT_HR(hr, S_OK);
3357 ok(pos2.QuadPart == 0, "expected stream beginning\n");
3358
3359 len = 2048;
3360 buff = heap_alloc(len + 1);
3361 memset(buff, 'A', len);
3362 buff[len] = 0;
3363 hr = ISAXContentHandler_characters(content, _bstr_(buff), len);
3364 EXPECT_HR(hr, S_OK);
3365
3366 pos.QuadPart = 0;
3367 pos2.QuadPart = 0;
3368 hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
3369 EXPECT_HR(hr, S_OK);
3370 ok(pos2.QuadPart != 0, "unexpected stream beginning\n");
3371
3372 hr = IMXWriter_get_output(writer, NULL);
3374
3376 V_VT(&dest) = VT_EMPTY;
3377 hr = IMXWriter_get_output(writer, &dest);
3378 EXPECT_HR(hr, S_OK);
3379 ok(V_VT(&dest) == VT_UNKNOWN, "got vt type %d\n", V_VT(&dest));
3380 ok(V_UNKNOWN(&dest) == (IUnknown*)stream, "got pointer %p\n", V_UNKNOWN(&dest));
3381 ok(ref+1 == get_refcount(stream), "expected increased refcount\n");
3383
3384 hr = ISAXContentHandler_endDocument(content);
3385 EXPECT_HR(hr, S_OK);
3386
3387 IStream_Release(stream);
3388
3389 /* test char count lower than threshold */
3391 EXPECT_HR(hr, S_OK);
3392 EXPECT_REF(stream, 1);
3393
3394 hr = ISAXContentHandler_startDocument(content);
3395 EXPECT_HR(hr, S_OK);
3396
3397 hr = ISAXContentHandler_startElement(content, emptyW, 0, emptyW, 0, _bstr_("a"), -1, NULL);
3398 EXPECT_HR(hr, S_OK);
3399
3400 pos.QuadPart = 0;
3401 pos2.QuadPart = 1;
3402 hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
3403 EXPECT_HR(hr, S_OK);
3404 ok(pos2.QuadPart == 0, "expected stream beginning\n");
3405
3406 memset(buff, 'A', len);
3407 buff[len] = 0;
3408 hr = ISAXContentHandler_characters(content, _bstr_(buff), len - 8);
3409 EXPECT_HR(hr, S_OK);
3410
3411 pos.QuadPart = 0;
3412 pos2.QuadPart = 1;
3413 hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
3414 EXPECT_HR(hr, S_OK);
3415 ok(pos2.QuadPart == 0, "expected stream beginning\n");
3416
3417 hr = ISAXContentHandler_endDocument(content);
3418 EXPECT_HR(hr, S_OK);
3419
3420 /* test auto-flush function when stream is not set */
3421 V_VT(&dest) = VT_EMPTY;
3422 hr = IMXWriter_put_output(writer, dest);
3423 EXPECT_HR(hr, S_OK);
3424
3425 hr = ISAXContentHandler_startDocument(content);
3426 EXPECT_HR(hr, S_OK);
3427
3428 hr = ISAXContentHandler_startElement(content, emptyW, 0, emptyW, 0, _bstr_("a"), -1, NULL);
3429 EXPECT_HR(hr, S_OK);
3430
3431 memset(buff, 'A', len);
3432 buff[len] = 0;
3433 hr = ISAXContentHandler_characters(content, _bstr_(buff), len);
3434 EXPECT_HR(hr, S_OK);
3435
3436 V_VT(&dest) = VT_EMPTY;
3437 hr = IMXWriter_get_output(writer, &dest);
3438 EXPECT_HR(hr, S_OK);
3439 len += strlen("<a>");
3440 ok(SysStringLen(V_BSTR(&dest)) == len, "got len=%d, expected %d\n", SysStringLen(V_BSTR(&dest)), len);
3442
3443 heap_free(buff);
3444 ISAXContentHandler_Release(content);
3445 IStream_Release(stream);
3446 IMXWriter_Release(writer);
3447 free_bstrs();
3448}
3449
3451{
3452 ISAXContentHandler *content;
3453 IMXWriter *writer;
3454 VARIANT dest;
3455 HRESULT hr;
3456
3457 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
3458 &IID_IMXWriter, (void**)&writer);
3459 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3460
3461 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
3462 ok(hr == S_OK, "got %08x\n", hr);
3463
3464 hr = ISAXContentHandler_startDocument(content);
3465 ok(hr == S_OK, "got %08x\n", hr);
3466
3467 hr = ISAXContentHandler_endDocument(content);
3468 ok(hr == S_OK, "got %08x\n", hr);
3469
3470 V_VT(&dest) = VT_EMPTY;
3471 hr = IMXWriter_get_output(writer, &dest);
3472 ok(hr == S_OK, "got %08x\n", hr);
3473 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3474 ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"), V_BSTR(&dest)),
3475 "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
3477
3478 /* now try another startDocument */
3479 hr = ISAXContentHandler_startDocument(content);
3480 ok(hr == S_OK, "got %08x\n", hr);
3481 /* and get duplicated prolog */
3482 V_VT(&dest) = VT_EMPTY;
3483 hr = IMXWriter_get_output(writer, &dest);
3484 ok(hr == S_OK, "got %08x\n", hr);
3485 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3486 ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"
3487 "<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"), V_BSTR(&dest)),
3488 "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
3490
3491 ISAXContentHandler_Release(content);
3492 IMXWriter_Release(writer);
3493
3494 /* now with omitted declaration */
3495 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
3496 &IID_IMXWriter, (void**)&writer);
3497 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3498
3499 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
3500 ok(hr == S_OK, "got %08x\n", hr);
3501
3502 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
3503 ok(hr == S_OK, "got %08x\n", hr);
3504
3505 hr = ISAXContentHandler_startDocument(content);
3506 ok(hr == S_OK, "got %08x\n", hr);
3507
3508 hr = ISAXContentHandler_endDocument(content);
3509 ok(hr == S_OK, "got %08x\n", hr);
3510
3511 V_VT(&dest) = VT_EMPTY;
3512 hr = IMXWriter_get_output(writer, &dest);
3513 ok(hr == S_OK, "got %08x\n", hr);
3514 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3515 ok(!lstrcmpW(_bstr_(""), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
3517
3518 ISAXContentHandler_Release(content);
3519 IMXWriter_Release(writer);
3520
3521 free_bstrs();
3522}
3523
3525{
3527 EndElement = 0x010,
3529 DisableEscaping = 0x100
3531
3533 const GUID *clsid;
3535 const char *uri;
3536 const char *local_name;
3537 const char *qname;
3538 const char *output;
3540 ISAXAttributes *attr;
3541};
3542
3543static const char startelement_xml[] = "<uri:local a:attr1=\"a1\" attr2=\"a2\" attr3=\"&lt;&amp;&quot;&gt;\'\">";
3544static const char startendelement_xml[] = "<uri:local a:attr1=\"a1\" attr2=\"a2\" attr3=\"&lt;&amp;&quot;&gt;\'\"/>";
3545static const char startendelement_noescape_xml[] = "<uri:local a:attr1=\"a1\" attr2=\"a2\" attr3=\"<&\">\'\"/>";
3546
3548 /* 0 */
3549 { &CLSID_MXXMLWriter, StartElement, NULL, NULL, NULL, NULL, E_INVALIDARG },
3550 { &CLSID_MXXMLWriter30, StartElement, NULL, NULL, NULL, NULL, E_INVALIDARG },
3551 { &CLSID_MXXMLWriter40, StartElement, NULL, NULL, NULL, NULL, E_INVALIDARG },
3552 { &CLSID_MXXMLWriter60, StartElement, NULL, NULL, NULL, "<>", S_OK },
3553 { &CLSID_MXXMLWriter, StartElement, "uri", NULL, NULL, NULL, E_INVALIDARG },
3554 /* 5 */
3555 { &CLSID_MXXMLWriter30, StartElement, "uri", NULL, NULL, NULL, E_INVALIDARG },
3556 { &CLSID_MXXMLWriter40, StartElement, "uri", NULL, NULL, NULL, E_INVALIDARG },
3557 { &CLSID_MXXMLWriter60, StartElement, "uri", NULL, NULL, "<>", S_OK },
3558 { &CLSID_MXXMLWriter, StartElement, NULL, "local", NULL, NULL, E_INVALIDARG },
3559 { &CLSID_MXXMLWriter30, StartElement, NULL, "local", NULL, NULL, E_INVALIDARG },
3560 /* 10 */
3561 { &CLSID_MXXMLWriter40, StartElement, NULL, "local", NULL, NULL, E_INVALIDARG },
3562 { &CLSID_MXXMLWriter60, StartElement, NULL, "local", NULL, "<>", S_OK },
3563 { &CLSID_MXXMLWriter, StartElement, NULL, NULL, "qname", NULL, E_INVALIDARG },
3564 { &CLSID_MXXMLWriter30, StartElement, NULL, NULL, "qname", NULL, E_INVALIDARG },
3565 { &CLSID_MXXMLWriter40, StartElement, NULL, NULL, "qname", NULL, E_INVALIDARG },
3566 /* 15 */
3567 { &CLSID_MXXMLWriter60, StartElement, NULL, NULL, "qname", "<qname>", S_OK },
3568 { &CLSID_MXXMLWriter, StartElement, "uri", "local", "qname", "<qname>", S_OK },
3569 { &CLSID_MXXMLWriter30, StartElement, "uri", "local", "qname", "<qname>", S_OK },
3570 { &CLSID_MXXMLWriter40, StartElement, "uri", "local", "qname", "<qname>", S_OK },
3571 { &CLSID_MXXMLWriter60, StartElement, "uri", "local", "qname", "<qname>", S_OK },
3572 /* 20 */
3573 { &CLSID_MXXMLWriter, StartElement, "uri", "local", NULL, NULL, E_INVALIDARG },
3574 { &CLSID_MXXMLWriter30, StartElement, "uri", "local", NULL, NULL, E_INVALIDARG },
3575 { &CLSID_MXXMLWriter40, StartElement, "uri", "local", NULL, NULL, E_INVALIDARG },
3576 { &CLSID_MXXMLWriter60, StartElement, "uri", "local", NULL, "<>", S_OK },
3577 { &CLSID_MXXMLWriter, StartElement, "uri", "local", "uri:local", "<uri:local>", S_OK },
3578 /* 25 */
3579 { &CLSID_MXXMLWriter30, StartElement, "uri", "local", "uri:local", "<uri:local>", S_OK },
3580 { &CLSID_MXXMLWriter40, StartElement, "uri", "local", "uri:local", "<uri:local>", S_OK },
3581 { &CLSID_MXXMLWriter60, StartElement, "uri", "local", "uri:local", "<uri:local>", S_OK },
3582 { &CLSID_MXXMLWriter, StartElement, "uri", "local", "uri:local2", "<uri:local2>", S_OK },
3583 { &CLSID_MXXMLWriter30, StartElement, "uri", "local", "uri:local2", "<uri:local2>", S_OK },
3584 /* 30 */
3585 { &CLSID_MXXMLWriter40, StartElement, "uri", "local", "uri:local2", "<uri:local2>", S_OK },
3586 { &CLSID_MXXMLWriter60, StartElement, "uri", "local", "uri:local2", "<uri:local2>", S_OK },
3587 /* endElement tests */
3588 { &CLSID_MXXMLWriter, EndElement, NULL, NULL, NULL, NULL, E_INVALIDARG },
3589 { &CLSID_MXXMLWriter30, EndElement, NULL, NULL, NULL, NULL, E_INVALIDARG },
3590 { &CLSID_MXXMLWriter40, EndElement, NULL, NULL, NULL, NULL, E_INVALIDARG },
3591 /* 35 */
3592 { &CLSID_MXXMLWriter60, EndElement, NULL, NULL, NULL, "</>", S_OK },
3593 { &CLSID_MXXMLWriter, EndElement, "uri", NULL, NULL, NULL, E_INVALIDARG },
3594 { &CLSID_MXXMLWriter30, EndElement, "uri", NULL, NULL, NULL, E_INVALIDARG },
3595 { &CLSID_MXXMLWriter40, EndElement, "uri", NULL, NULL, NULL, E_INVALIDARG },
3596 { &CLSID_MXXMLWriter60, EndElement, "uri", NULL, NULL, "</>", S_OK },
3597 /* 40 */
3598 { &CLSID_MXXMLWriter, EndElement, NULL, "local", NULL, NULL, E_INVALIDARG },
3599 { &CLSID_MXXMLWriter30, EndElement, NULL, "local", NULL, NULL, E_INVALIDARG },
3600 { &CLSID_MXXMLWriter40, EndElement, NULL, "local", NULL, NULL, E_INVALIDARG },
3601 { &CLSID_MXXMLWriter60, EndElement, NULL, "local", NULL, "</>", S_OK },
3602 { &CLSID_MXXMLWriter, EndElement, NULL, NULL, "qname", NULL, E_INVALIDARG },
3603 /* 45 */
3604 { &CLSID_MXXMLWriter30, EndElement, NULL, NULL, "qname", NULL, E_INVALIDARG },
3605 { &CLSID_MXXMLWriter40, EndElement, NULL, NULL, "qname", NULL, E_INVALIDARG },
3606 { &CLSID_MXXMLWriter60, EndElement, NULL, NULL, "qname", "</qname>", S_OK },
3607 { &CLSID_MXXMLWriter, EndElement, "uri", "local", "qname", "</qname>", S_OK },
3608 { &CLSID_MXXMLWriter30, EndElement, "uri", "local", "qname", "</qname>", S_OK },
3609 /* 50 */
3610 { &CLSID_MXXMLWriter40, EndElement, "uri", "local", "qname", "</qname>", S_OK },
3611 { &CLSID_MXXMLWriter60, EndElement, "uri", "local", "qname", "</qname>", S_OK },
3612 { &CLSID_MXXMLWriter, EndElement, "uri", "local", NULL, NULL, E_INVALIDARG },
3613 { &CLSID_MXXMLWriter30, EndElement, "uri", "local", NULL, NULL, E_INVALIDARG },
3614 { &CLSID_MXXMLWriter40, EndElement, "uri", "local", NULL, NULL, E_INVALIDARG },
3615 /* 55 */
3616 { &CLSID_MXXMLWriter60, EndElement, "uri", "local", NULL, "</>", S_OK },
3617 { &CLSID_MXXMLWriter, EndElement, "uri", "local", "uri:local", "</uri:local>", S_OK },
3618 { &CLSID_MXXMLWriter30, EndElement, "uri", "local", "uri:local", "</uri:local>", S_OK },
3619 { &CLSID_MXXMLWriter40, EndElement, "uri", "local", "uri:local", "</uri:local>", S_OK },
3620 { &CLSID_MXXMLWriter60, EndElement, "uri", "local", "uri:local", "</uri:local>", S_OK },
3621 /* 60 */
3622 { &CLSID_MXXMLWriter, EndElement, "uri", "local", "uri:local2", "</uri:local2>", S_OK },
3623 { &CLSID_MXXMLWriter30, EndElement, "uri", "local", "uri:local2", "</uri:local2>", S_OK },
3624 { &CLSID_MXXMLWriter40, EndElement, "uri", "local", "uri:local2", "</uri:local2>", S_OK },
3625 { &CLSID_MXXMLWriter60, EndElement, "uri", "local", "uri:local2", "</uri:local2>", S_OK },
3626
3627 /* with attributes */
3628 { &CLSID_MXXMLWriter, StartElement, "uri", "local", "uri:local", startelement_xml, S_OK, &saxattributes },
3629 /* 65 */
3630 { &CLSID_MXXMLWriter30, StartElement, "uri", "local", "uri:local", startelement_xml, S_OK, &saxattributes },
3631 { &CLSID_MXXMLWriter40, StartElement, "uri", "local", "uri:local", startelement_xml, S_OK, &saxattributes },
3632 { &CLSID_MXXMLWriter60, StartElement, "uri", "local", "uri:local", startelement_xml, S_OK, &saxattributes },
3633 /* empty elements */
3634 { &CLSID_MXXMLWriter, StartEndElement, "uri", "local", "uri:local", startendelement_xml, S_OK, &saxattributes },
3635 { &CLSID_MXXMLWriter30, StartEndElement, "uri", "local", "uri:local", startendelement_xml, S_OK, &saxattributes },
3636 /* 70 */
3637 { &CLSID_MXXMLWriter40, StartEndElement, "uri", "local", "uri:local", startendelement_xml, S_OK, &saxattributes },
3638 { &CLSID_MXXMLWriter60, StartEndElement, "uri", "local", "uri:local", startendelement_xml, S_OK, &saxattributes },
3639 { &CLSID_MXXMLWriter, StartEndElement, "", "", "", "</>", S_OK },
3640 { &CLSID_MXXMLWriter30, StartEndElement, "", "", "", "</>", S_OK },
3641 { &CLSID_MXXMLWriter40, StartEndElement, "", "", "", "</>", S_OK },
3642 /* 75 */
3643 { &CLSID_MXXMLWriter60, StartEndElement, "", "", "", "</>", S_OK },
3644
3645 /* with disabled output escaping */
3646 { &CLSID_MXXMLWriter, StartEndElement | DisableEscaping, "uri", "local", "uri:local", startendelement_noescape_xml, S_OK, &saxattributes },
3647 { &CLSID_MXXMLWriter30, StartEndElement | DisableEscaping, "uri", "local", "uri:local", startendelement_noescape_xml, S_OK, &saxattributes },
3648 { &CLSID_MXXMLWriter40, StartEndElement | DisableEscaping, "uri", "local", "uri:local", startendelement_xml, S_OK, &saxattributes },
3649 { &CLSID_MXXMLWriter60, StartEndElement | DisableEscaping, "uri", "local", "uri:local", startendelement_xml, S_OK, &saxattributes },
3650
3651 { NULL }
3652};
3653
3655{
3656 while (table->clsid)
3657 {
3658 IUnknown *unk;
3659 HRESULT hr;
3660
3661 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER, riid, (void**)&unk);
3662 if (hr == S_OK) IUnknown_Release(unk);
3663
3664 table->supported = hr == S_OK;
3665 if (hr != S_OK) win_skip("class %s not supported\n", table->name);
3666
3667 table++;
3668 }
3669}
3670
3672{
3673 int i = 0;
3674
3675 while (table->clsid)
3676 {
3677 ISAXContentHandler *content;
3678 IMXWriter *writer;
3679 HRESULT hr;
3680
3682 {
3683 table++;
3684 i++;
3685 continue;
3686 }
3687
3688 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER,
3689 &IID_IMXWriter, (void**)&writer);
3690 EXPECT_HR(hr, S_OK);
3691
3692 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
3693 EXPECT_HR(hr, S_OK);
3694
3695 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
3696 EXPECT_HR(hr, S_OK);
3697
3698 hr = ISAXContentHandler_startDocument(content);
3699 EXPECT_HR(hr, S_OK);
3700
3701 if (table->type & DisableEscaping)
3702 {
3703 hr = IMXWriter_put_disableOutputEscaping(writer, VARIANT_TRUE);
3704 EXPECT_HR(hr, S_OK);
3705 }
3706
3707 if (table->type & StartElement)
3708 {
3709 hr = ISAXContentHandler_startElement(content, _bstr_(table->uri), table->uri ? strlen(table->uri) : 0,
3710 _bstr_(table->local_name), table->local_name ? strlen(table->local_name) : 0, _bstr_(table->qname),
3711 table->qname ? strlen(table->qname) : 0, table->attr);
3712 ok(hr == table->hr, "test %d: got 0x%08x, expected 0x%08x\n", i, hr, table->hr);
3713 }
3714
3715 if (table->type & EndElement)
3716 {
3717 hr = ISAXContentHandler_endElement(content, _bstr_(table->uri), table->uri ? strlen(table->uri) : 0,
3718 _bstr_(table->local_name), table->local_name ? strlen(table->local_name) : 0, _bstr_(table->qname),
3719 table->qname ? strlen(table->qname) : 0);
3720 ok(hr == table->hr, "test %d: got 0x%08x, expected 0x%08x\n", i, hr, table->hr);
3721 }
3722
3723 /* test output */
3724 if (hr == S_OK)
3725 {
3726 VARIANT dest;
3727
3728 V_VT(&dest) = VT_EMPTY;
3729 hr = IMXWriter_get_output(writer, &dest);
3730 EXPECT_HR(hr, S_OK);
3731 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3732 ok(!lstrcmpW(_bstr_(table->output), V_BSTR(&dest)),
3733 "test %d: got wrong content %s, expected %s\n", i, wine_dbgstr_w(V_BSTR(&dest)), table->output);
3735 }
3736
3737 ISAXContentHandler_Release(content);
3738 IMXWriter_Release(writer);
3739
3740 table++;
3741 i++;
3742 }
3743
3744 free_bstrs();
3745}
3746
3747/* point of these test is to start/end element with different names and name lengths */
3749 const GUID *clsid;
3750 const char *qnamestart;
3752 const char *qnameend;
3754 const char *output;
3756};
3757
3759 { &CLSID_MXXMLWriter, "a", -1, "b", -1, "<a/>", S_OK },
3760 { &CLSID_MXXMLWriter30, "a", -1, "b", -1, "<a/>", S_OK },
3761 { &CLSID_MXXMLWriter40, "a", -1, "b", -1, "<a/>", S_OK },
3762 /* -1 length is not allowed for version 6 */
3763 { &CLSID_MXXMLWriter60, "a", -1, "b", -1, "<a/>", E_INVALIDARG },
3764
3765 { &CLSID_MXXMLWriter, "a", 1, "b", 1, "<a/>", S_OK },
3766 { &CLSID_MXXMLWriter30, "a", 1, "b", 1, "<a/>", S_OK },
3767 { &CLSID_MXXMLWriter40, "a", 1, "b", 1, "<a/>", S_OK },
3768 { &CLSID_MXXMLWriter60, "a", 1, "b", 1, "<a/>", S_OK },
3769 { NULL }
3770};
3771
3773{
3774 int i = 0;
3775
3776 while (table->clsid)
3777 {
3778 ISAXContentHandler *content;
3779 IMXWriter *writer;
3780 HRESULT hr;
3781
3783 {
3784 table++;
3785 i++;
3786 continue;
3787 }
3788
3789 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER,
3790 &IID_IMXWriter, (void**)&writer);
3791 EXPECT_HR(hr, S_OK);
3792
3793 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
3794 EXPECT_HR(hr, S_OK);
3795
3796 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
3797 EXPECT_HR(hr, S_OK);
3798
3799 hr = ISAXContentHandler_startDocument(content);
3800 EXPECT_HR(hr, S_OK);
3801
3802 hr = ISAXContentHandler_startElement(content, _bstr_(""), 0, _bstr_(""), 0,
3803 _bstr_(table->qnamestart), table->qnamestart_len, NULL);
3804 ok(hr == table->hr, "test %d: got 0x%08x, expected 0x%08x\n", i, hr, table->hr);
3805
3806 hr = ISAXContentHandler_endElement(content, _bstr_(""), 0, _bstr_(""), 0,
3807 _bstr_(table->qnameend), table->qnameend_len);
3808 ok(hr == table->hr, "test %d: got 0x%08x, expected 0x%08x\n", i, hr, table->hr);
3809
3810 /* test output */
3811 if (hr == S_OK)
3812 {
3813 VARIANT dest;
3814
3815 V_VT(&dest) = VT_EMPTY;
3816 hr = IMXWriter_get_output(writer, &dest);
3817 EXPECT_HR(hr, S_OK);
3818 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3819 ok(!lstrcmpW(_bstr_(table->output), V_BSTR(&dest)),
3820 "test %d: got wrong content %s, expected %s\n", i, wine_dbgstr_w(V_BSTR(&dest)), table->output);
3822 }
3823
3824 ISAXContentHandler_Release(content);
3825 IMXWriter_Release(writer);
3826
3827 table++;
3828 i++;
3829
3830 free_bstrs();
3831 }
3832}
3833
3834
3836{
3837 ISAXContentHandler *content;
3838 IMXWriter *writer;
3839 VARIANT dest;
3840 HRESULT hr;
3841
3844
3845 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
3846 &IID_IMXWriter, (void**)&writer);
3847 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
3848
3849 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
3850 ok(hr == S_OK, "got %08x\n", hr);
3851
3852 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
3853 ok(hr == S_OK, "got %08x\n", hr);
3854
3855 hr = ISAXContentHandler_startDocument(content);
3856 ok(hr == S_OK, "got %08x\n", hr);
3857
3858 /* all string pointers should be not null */
3859 hr = ISAXContentHandler_startElement(content, _bstr_(""), 0, _bstr_("b"), 1, _bstr_(""), 0, NULL);
3860 ok(hr == S_OK, "got %08x\n", hr);
3861
3862 V_VT(&dest) = VT_EMPTY;
3863 hr = IMXWriter_get_output(writer, &dest);
3864 ok(hr == S_OK, "got %08x\n", hr);
3865 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3866 ok(!lstrcmpW(_bstr_("<>"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
3868
3869 hr = ISAXContentHandler_startElement(content, _bstr_(""), 0, _bstr_(""), 0, _bstr_("b"), 1, NULL);
3870 ok(hr == S_OK, "got %08x\n", hr);
3871
3872 V_VT(&dest) = VT_EMPTY;
3873 hr = IMXWriter_get_output(writer, &dest);
3874 ok(hr == S_OK, "got %08x\n", hr);
3875 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3876 ok(!lstrcmpW(_bstr_("<><b>"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
3878
3879 hr = ISAXContentHandler_endElement(content, NULL, 0, NULL, 0, _bstr_("a:b"), 3);
3881
3882 hr = ISAXContentHandler_endElement(content, NULL, 0, _bstr_("b"), 1, _bstr_("a:b"), 3);
3884
3885 /* only local name is an error too */
3886 hr = ISAXContentHandler_endElement(content, NULL, 0, _bstr_("b"), 1, NULL, 0);
3888
3889 hr = ISAXContentHandler_endElement(content, _bstr_(""), 0, _bstr_(""), 0, _bstr_("b"), 1);
3890 EXPECT_HR(hr, S_OK);
3891
3892 V_VT(&dest) = VT_EMPTY;
3893 hr = IMXWriter_get_output(writer, &dest);
3894 EXPECT_HR(hr, S_OK);
3895 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3896 ok(!lstrcmpW(_bstr_("<><b></b>"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
3898
3899 hr = ISAXContentHandler_endDocument(content);
3900 EXPECT_HR(hr, S_OK);
3901
3902 V_VT(&dest) = VT_EMPTY;
3903 hr = IMXWriter_put_output(writer, dest);
3904 EXPECT_HR(hr, S_OK);
3905
3906 V_VT(&dest) = VT_EMPTY;
3907 hr = IMXWriter_get_output(writer, &dest);
3908 EXPECT_HR(hr, S_OK);
3909 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3910 ok(!lstrcmpW(_bstr_(""), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
3912
3913 hr = ISAXContentHandler_startDocument(content);
3914 EXPECT_HR(hr, S_OK);
3915
3916 hr = ISAXContentHandler_startElement(content, _bstr_(""), 0, _bstr_(""), 0, _bstr_("abcdef"), 3, NULL);
3917 EXPECT_HR(hr, S_OK);
3918
3919 V_VT(&dest) = VT_EMPTY;
3920 hr = IMXWriter_get_output(writer, &dest);
3921 EXPECT_HR(hr, S_OK);
3922 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3923 ok(!lstrcmpW(_bstr_("<abc>"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
3925
3926 hr = ISAXContentHandler_endDocument(content);
3927 EXPECT_HR(hr, S_OK);
3928 IMXWriter_flush(writer);
3929
3930 hr = ISAXContentHandler_endElement(content, _bstr_(""), 0, _bstr_(""), 0, _bstr_("abdcdef"), 3);
3931 EXPECT_HR(hr, S_OK);
3932 V_VT(&dest) = VT_EMPTY;
3933 hr = IMXWriter_get_output(writer, &dest);
3934 EXPECT_HR(hr, S_OK);
3935 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3936 ok(!lstrcmpW(_bstr_("<abc></abd>"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
3938
3939 V_VT(&dest) = VT_EMPTY;
3940 hr = IMXWriter_put_output(writer, dest);
3941 EXPECT_HR(hr, S_OK);
3942
3943 /* length -1 */
3944 hr = ISAXContentHandler_startElement(content, _bstr_(""), 0, _bstr_(""), 0, _bstr_("a"), -1, NULL);
3945 EXPECT_HR(hr, S_OK);
3946 V_VT(&dest) = VT_EMPTY;
3947 hr = IMXWriter_get_output(writer, &dest);
3948 EXPECT_HR(hr, S_OK);
3949 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
3950 ok(!lstrcmpW(_bstr_("<a>"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
3952
3953 ISAXContentHandler_Release(content);
3954 IMXWriter_Release(writer);
3955 free_bstrs();
3956}
3957
3959 const GUID *clsid;
3960 const char *data;
3961 const char *output;
3962};
3963
3965 { &CLSID_MXXMLWriter, "< > & \" \'", "&lt; &gt; &amp; \" \'" },
3966 { &CLSID_MXXMLWriter30, "< > & \" \'", "&lt; &gt; &amp; \" \'" },
3967 { &CLSID_MXXMLWriter40, "< > & \" \'", "&lt; &gt; &amp; \" \'" },
3968 { &CLSID_MXXMLWriter60, "< > & \" \'", "&lt; &gt; &amp; \" \'" },
3969 { NULL }
3970};
3971
3973{
3974 static const WCHAR chardataW[] = {'T','E','S','T','C','H','A','R','D','A','T','A',' ','.',0};
3975 static const WCHAR embedded_nullbytes[] = {'a',0,'b',0,0,0,'c',0};
3977 IVBSAXContentHandler *vb_content;
3978 ISAXContentHandler *content;
3979 IMXWriter *writer;
3980 VARIANT dest;
3981 BSTR str;
3982 HRESULT hr;
3983 int i = 0;
3984
3985 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
3986 &IID_IMXWriter, (void**)&writer);
3987 EXPECT_HR(hr, S_OK);
3988
3989 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
3990 EXPECT_HR(hr, S_OK);
3991
3992 hr = IMXWriter_QueryInterface(writer, &IID_IVBSAXContentHandler, (void**)&vb_content);
3993 EXPECT_HR(hr, S_OK);
3994
3995 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
3996 EXPECT_HR(hr, S_OK);
3997
3998 hr = ISAXContentHandler_startDocument(content);
3999 EXPECT_HR(hr, S_OK);
4000
4001 hr = ISAXContentHandler_characters(content, NULL, 0);
4003
4004 hr = ISAXContentHandler_characters(content, chardataW, 0);
4005 EXPECT_HR(hr, S_OK);
4006
4007 str = _bstr_("VbChars");
4008 hr = IVBSAXContentHandler_characters(vb_content, &str);
4009 EXPECT_HR(hr, S_OK);
4010
4011 hr = ISAXContentHandler_characters(content, chardataW, ARRAY_SIZE(chardataW) - 1);
4012 EXPECT_HR(hr, S_OK);
4013
4014 V_VT(&dest) = VT_EMPTY;
4015 hr = IMXWriter_get_output(writer, &dest);
4016 EXPECT_HR(hr, S_OK);
4017 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4018 ok(!lstrcmpW(_bstr_("VbCharsTESTCHARDATA ."), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4020
4021 hr = ISAXContentHandler_endDocument(content);
4022 EXPECT_HR(hr, S_OK);
4023
4024 ISAXContentHandler_Release(content);
4025 IVBSAXContentHandler_Release(vb_content);
4026 IMXWriter_Release(writer);
4027
4028 /* try empty characters data to see if element is closed */
4029 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
4030 &IID_IMXWriter, (void**)&writer);
4031 EXPECT_HR(hr, S_OK);
4032
4033 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
4034 EXPECT_HR(hr, S_OK);
4035
4036 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
4037 EXPECT_HR(hr, S_OK);
4038
4039 hr = ISAXContentHandler_startDocument(content);
4040 EXPECT_HR(hr, S_OK);
4041
4042 hr = ISAXContentHandler_startElement(content, _bstr_(""), 0, _bstr_(""), 0, _bstr_("a"), 1, NULL);
4043 EXPECT_HR(hr, S_OK);
4044
4045 hr = ISAXContentHandler_characters(content, chardataW, 0);
4046 EXPECT_HR(hr, S_OK);
4047
4048 hr = ISAXContentHandler_endElement(content, _bstr_(""), 0, _bstr_(""), 0, _bstr_("a"), 1);
4049 EXPECT_HR(hr, S_OK);
4050
4051 V_VT(&dest) = VT_EMPTY;
4052 hr = IMXWriter_get_output(writer, &dest);
4053 EXPECT_HR(hr, S_OK);
4054 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4055 ok(!lstrcmpW(_bstr_("<a></a>"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4057
4058 ISAXContentHandler_Release(content);
4059 IMXWriter_Release(writer);
4060
4061 /* test embedded null bytes */
4062 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
4063 &IID_IMXWriter, (void**)&writer);
4064 EXPECT_HR(hr, S_OK);
4065
4066 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
4067 EXPECT_HR(hr, S_OK);
4068
4069 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
4070 EXPECT_HR(hr, S_OK);
4071
4072 hr = ISAXContentHandler_startDocument(content);
4073 EXPECT_HR(hr, S_OK);
4074
4075 hr = ISAXContentHandler_characters(content, embedded_nullbytes, ARRAY_SIZE(embedded_nullbytes));
4076 EXPECT_HR(hr, S_OK);
4077
4078 V_VT(&dest) = VT_EMPTY;
4079 hr = IMXWriter_get_output(writer, &dest);
4080 EXPECT_HR(hr, S_OK);
4081 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4082 ok(SysStringLen(V_BSTR(&dest)) == ARRAY_SIZE(embedded_nullbytes), "unexpected len %d\n", SysStringLen(V_BSTR(&dest)));
4083 ok(!memcmp(V_BSTR(&dest), embedded_nullbytes, ARRAY_SIZE(embedded_nullbytes)),
4084 "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4086
4087 ISAXContentHandler_Release(content);
4088 IMXWriter_Release(writer);
4089
4090 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
4091 &IID_IMXWriter, (void**)&writer);
4092 EXPECT_HR(hr, S_OK);
4093
4094 hr = IMXWriter_QueryInterface(writer, &IID_IVBSAXContentHandler, (void**)&vb_content);
4095 EXPECT_HR(hr, S_OK);
4096
4097 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
4098 EXPECT_HR(hr, S_OK);
4099
4100 hr = IVBSAXContentHandler_startDocument(vb_content);
4101 EXPECT_HR(hr, S_OK);
4102
4103 str = SysAllocStringLen(embedded_nullbytes, ARRAY_SIZE(embedded_nullbytes));
4104 hr = IVBSAXContentHandler_characters(vb_content, &str);
4105 EXPECT_HR(hr, S_OK);
4107
4108 V_VT(&dest) = VT_EMPTY;
4109 hr = IMXWriter_get_output(writer, &dest);
4110 EXPECT_HR(hr, S_OK);
4111 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4112 ok(SysStringLen(V_BSTR(&dest)) == ARRAY_SIZE(embedded_nullbytes), "unexpected len %d\n", SysStringLen(V_BSTR(&dest)));
4113 ok(!memcmp(V_BSTR(&dest), embedded_nullbytes, ARRAY_SIZE(embedded_nullbytes)),
4114 "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4116
4117 IVBSAXContentHandler_Release(vb_content);
4118 IMXWriter_Release(writer);
4119
4120 /* batch tests */
4121 while (table->clsid)
4122 {
4123 ISAXContentHandler *content;
4124 IMXWriter *writer;
4125 VARIANT dest;
4126 HRESULT hr;
4127
4129 {
4130 table++;
4131 i++;
4132 continue;
4133 }
4134
4135 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER,
4136 &IID_IMXWriter, (void**)&writer);
4137 EXPECT_HR(hr, S_OK);
4138
4139 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
4140 EXPECT_HR(hr, S_OK);
4141
4142 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
4143 EXPECT_HR(hr, S_OK);
4144
4145 hr = ISAXContentHandler_startDocument(content);
4146 EXPECT_HR(hr, S_OK);
4147
4148 hr = ISAXContentHandler_characters(content, _bstr_(table->data), strlen(table->data));
4149 EXPECT_HR(hr, S_OK);
4150
4151 /* test output */
4152 if (hr == S_OK)
4153 {
4154 V_VT(&dest) = VT_EMPTY;
4155 hr = IMXWriter_get_output(writer, &dest);
4156 EXPECT_HR(hr, S_OK);
4157 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4158 ok(!lstrcmpW(_bstr_(table->output), V_BSTR(&dest)),
4159 "test %d: got wrong content %s, expected \"%s\"\n", i, wine_dbgstr_w(V_BSTR(&dest)), table->output);
4161 }
4162
4163 /* with disabled escaping */
4164 V_VT(&dest) = VT_EMPTY;
4165 hr = IMXWriter_put_output(writer, dest);
4166 EXPECT_HR(hr, S_OK);
4167
4168 hr = IMXWriter_put_disableOutputEscaping(writer, VARIANT_TRUE);
4169 EXPECT_HR(hr, S_OK);
4170
4171 hr = ISAXContentHandler_characters(content, _bstr_(table->data), strlen(table->data));
4172 EXPECT_HR(hr, S_OK);
4173
4174 /* test output */
4175 if (hr == S_OK)
4176 {
4177 V_VT(&dest) = VT_EMPTY;
4178 hr = IMXWriter_get_output(writer, &dest);
4179 EXPECT_HR(hr, S_OK);
4180 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4182 "test %d: got wrong content %s, expected \"%s\"\n", i, wine_dbgstr_w(V_BSTR(&dest)), table->data);
4184 }
4185
4186 ISAXContentHandler_Release(content);
4187 IMXWriter_Release(writer);
4188
4189 table++;
4190 i++;
4191 }
4192
4193 free_bstrs();
4194}
4195
4197 {
4198 VARIANT_TRUE,"UTF-16",
4199 {
4200 {FALSE,(const BYTE*)szUtf16BOM,sizeof(szUtf16BOM),TRUE},
4201 {FALSE,(const BYTE*)szUtf16XML,sizeof(szUtf16XML)},
4202 {TRUE}
4203 }
4204 },
4205 {
4206 VARIANT_FALSE,"UTF-16",
4207 {
4208 {FALSE,(const BYTE*)szUtf16XML,sizeof(szUtf16XML)},
4209 {TRUE}
4210 }
4211 },
4212 {
4213 VARIANT_TRUE,"UTF-8",
4214 {
4215 {FALSE,(const BYTE*)szUtf8XML,sizeof(szUtf8XML)-1},
4216 /* For some reason Windows makes an empty write call when UTF-8 encoding is used
4217 * and the writer is released.
4218 */
4219 {FALSE,NULL,0},
4220 {TRUE}
4221 }
4222 },
4223 {
4224 VARIANT_TRUE,"utf-8",
4225 {
4226 {FALSE,(const BYTE*)utf8xml2,sizeof(utf8xml2)-1},
4227 /* For some reason Windows makes an empty write call when UTF-8 encoding is used
4228 * and the writer is released.
4229 */
4230 {FALSE,NULL,0},
4231 {TRUE}
4232 }
4233 },
4234 {
4235 VARIANT_TRUE,"UTF-16",
4236 {
4237 {FALSE,(const BYTE*)szUtf16BOM,sizeof(szUtf16BOM),TRUE},
4238 {FALSE,(const BYTE*)szUtf16XML,sizeof(szUtf16XML)},
4239 {TRUE}
4240 }
4241 },
4242 {
4243 VARIANT_TRUE,"UTF-16",
4244 {
4245 {FALSE,(const BYTE*)szUtf16BOM,sizeof(szUtf16BOM),TRUE,TRUE},
4246 {FALSE,(const BYTE*)szUtf16XML,sizeof(szUtf16XML)},
4247 {TRUE}
4248 }
4249 }
4250};
4251
4252static void test_mxwriter_stream(void)
4253{
4254 IMXWriter *writer;
4255 ISAXContentHandler *content;
4256 HRESULT hr;
4257 VARIANT dest;
4258 IStream *stream;
4260 ULARGE_INTEGER pos2;
4262
4265
4266 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
4267 &IID_IMXWriter, (void**)&writer);
4268 ok(hr == S_OK, "CoCreateInstance failed: %08x\n", hr);
4269
4270 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
4271 ok(hr == S_OK, "QueryInterface(ISAXContentHandler) failed: %08x\n", hr);
4272
4273 hr = IMXWriter_put_encoding(writer, _bstr_(test->encoding));
4274 ok(hr == S_OK, "put_encoding failed with %08x on test %d\n", hr, current_stream_test_index);
4275
4276 V_VT(&dest) = VT_UNKNOWN;
4278 hr = IMXWriter_put_output(writer, dest);
4279 ok(hr == S_OK, "put_output failed with %08x on test %d\n", hr, current_stream_test_index);
4280
4281 hr = IMXWriter_put_byteOrderMark(writer, test->bom);
4282 ok(hr == S_OK, "put_byteOrderMark failed with %08x on test %d\n", hr, current_stream_test_index);
4283
4284 current_write_test = test->expected_writes;
4285
4286 hr = ISAXContentHandler_startDocument(content);
4287 ok(hr == S_OK, "startDocument failed with %08x on test %d\n", hr, current_stream_test_index);
4288
4289 hr = ISAXContentHandler_endDocument(content);
4290 ok(hr == S_OK, "endDocument failed with %08x on test %d\n", hr, current_stream_test_index);
4291
4292 ISAXContentHandler_Release(content);
4293 IMXWriter_Release(writer);
4294
4295 ok(current_write_test->last, "The last %d write calls on test %d were missed\n",
4296 (int)(current_write_test-test->expected_writes), current_stream_test_index);
4297 }
4298
4299 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
4300 &IID_IMXWriter, (void**)&writer);
4301 ok(hr == S_OK, "CoCreateInstance failed: %08x\n", hr);
4302
4304 ok(hr == S_OK, "CreateStreamOnHGlobal failed: %08x\n", hr);
4305
4306 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
4307 ok(hr == S_OK, "QueryInterface(ISAXContentHandler) failed: %08x\n", hr);
4308
4309 hr = IMXWriter_put_encoding(writer, _bstr_("UTF-8"));
4310 ok(hr == S_OK, "put_encoding failed: %08x\n", hr);
4311
4312 V_VT(&dest) = VT_UNKNOWN;
4314 hr = IMXWriter_put_output(writer, dest);
4315 ok(hr == S_OK, "put_output failed: %08x\n", hr);
4316
4317 hr = ISAXContentHandler_startDocument(content);
4318 ok(hr == S_OK, "startDocument failed: %08x\n", hr);
4319
4320 /* Setting output of the mxwriter causes the current output to be flushed,
4321 * and the writer to start over.
4322 */
4323 V_VT(&dest) = VT_EMPTY;
4324 hr = IMXWriter_put_output(writer, dest);
4325 ok(hr == S_OK, "put_output failed: %08x\n", hr);
4326
4327 pos.QuadPart = 0;
4328 hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
4329 ok(hr == S_OK, "Seek failed: %08x\n", hr);
4330 ok(pos2.QuadPart != 0, "expected stream position moved\n");
4331
4332 hr = ISAXContentHandler_startDocument(content);
4333 ok(hr == S_OK, "startDocument failed: %08x\n", hr);
4334
4335 hr = ISAXContentHandler_endDocument(content);
4336 ok(hr == S_OK, "endDocument failed: %08x\n", hr);
4337
4338 V_VT(&dest) = VT_EMPTY;
4339 hr = IMXWriter_get_output(writer, &dest);
4340 ok(hr == S_OK, "get_output failed: %08x\n", hr);
4341 ok(V_VT(&dest) == VT_BSTR, "Expected VT_BSTR, got %d\n", V_VT(&dest));
4342 ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"), V_BSTR(&dest)),
4343 "Got wrong content: %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4345
4346 /* test when BOM is written to output stream */
4347 V_VT(&dest) = VT_EMPTY;
4348 hr = IMXWriter_put_output(writer, dest);
4349 EXPECT_HR(hr, S_OK);
4350
4351 pos.QuadPart = 0;
4352 hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
4353 EXPECT_HR(hr, S_OK);
4354
4355 V_VT(&dest) = VT_UNKNOWN;
4357 hr = IMXWriter_put_output(writer, dest);
4358 EXPECT_HR(hr, S_OK);
4359
4360 hr = IMXWriter_put_byteOrderMark(writer, VARIANT_TRUE);
4361 EXPECT_HR(hr, S_OK);
4362
4363 hr = IMXWriter_put_encoding(writer, _bstr_("UTF-16"));
4364 EXPECT_HR(hr, S_OK);
4365
4366 hr = ISAXContentHandler_startDocument(content);
4367 EXPECT_HR(hr, S_OK);
4368
4369 pos.QuadPart = 0;
4370 pos2.QuadPart = 0;
4371 hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
4372 EXPECT_HR(hr, S_OK);
4373 ok(pos2.QuadPart == 2, "got wrong position\n");
4374
4375 IStream_Release(stream);
4376 ISAXContentHandler_Release(content);
4377 IMXWriter_Release(writer);
4378
4379 free_bstrs();
4380}
4381
4382static const char *encoding_names[] = {
4383 "iso-8859-1",
4384 "iso-8859-2",
4385 "iso-8859-3",
4386 "iso-8859-4",
4387 "iso-8859-5",
4388 "iso-8859-7",
4389 "iso-8859-9",
4390 "iso-8859-13",
4391 "iso-8859-15",
4392 NULL
4393};
4394
4395static void test_mxwriter_encoding(void)
4396{
4397 ISAXContentHandler *content;
4398 IMXWriter *writer;
4399 IStream *stream;
4400 const char *enc;
4401 VARIANT dest;
4402 HRESULT hr;
4403 HGLOBAL g;
4404 char *ptr;
4405 BSTR s;
4406 int i;
4407
4408 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
4409 &IID_IMXWriter, (void**)&writer);
4410 EXPECT_HR(hr, S_OK);
4411
4412 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
4413 EXPECT_HR(hr, S_OK);
4414
4415 hr = IMXWriter_put_encoding(writer, _bstr_("UTF-8"));
4416 EXPECT_HR(hr, S_OK);
4417
4418 hr = ISAXContentHandler_startDocument(content);
4419 EXPECT_HR(hr, S_OK);
4420
4421 hr = ISAXContentHandler_endDocument(content);
4422 EXPECT_HR(hr, S_OK);
4423
4424 /* The content is always re-encoded to UTF-16 when the output is
4425 * retrieved as a BSTR.
4426 */
4427 V_VT(&dest) = VT_EMPTY;
4428 hr = IMXWriter_get_output(writer, &dest);
4429 EXPECT_HR(hr, S_OK);
4430 ok(V_VT(&dest) == VT_BSTR, "Expected VT_BSTR, got %d\n", V_VT(&dest));
4431 ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"), V_BSTR(&dest)),
4432 "got wrong content: %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4434
4435 /* switch encoding when something is written already */
4437 EXPECT_HR(hr, S_OK);
4438
4439 V_VT(&dest) = VT_UNKNOWN;
4441 hr = IMXWriter_put_output(writer, dest);
4442 EXPECT_HR(hr, S_OK);
4443
4444 hr = IMXWriter_put_encoding(writer, _bstr_("UTF-8"));
4445 EXPECT_HR(hr, S_OK);
4446
4447 /* write empty element */
4448 hr = ISAXContentHandler_startElement(content, _bstr_(""), 0, _bstr_(""), 0, _bstr_("a"), 1, NULL);
4449 EXPECT_HR(hr, S_OK);
4450
4451 hr = ISAXContentHandler_endElement(content, _bstr_(""), 0, _bstr_(""), 0, _bstr_("a"), 1);
4452 EXPECT_HR(hr, S_OK);
4453
4454 /* switch */
4455 hr = IMXWriter_put_encoding(writer, _bstr_("UTF-16"));
4456 EXPECT_HR(hr, S_OK);
4457
4458 hr = IMXWriter_flush(writer);
4459 EXPECT_HR(hr, S_OK);
4460
4462 EXPECT_HR(hr, S_OK);
4463
4464 ptr = GlobalLock(g);
4465 ok(!strncmp(ptr, "<a/>", 4), "got %c%c%c%c\n", ptr[0],ptr[1],ptr[2],ptr[3]);
4466 GlobalUnlock(g);
4467
4468 /* so output is unaffected, encoding name is stored however */
4469 hr = IMXWriter_get_encoding(writer, &s);
4470 EXPECT_HR(hr, S_OK);
4471 ok(!lstrcmpW(s, _bstr_("UTF-16")), "got %s\n", wine_dbgstr_w(s));
4473
4474 IStream_Release(stream);
4475
4476 i = 0;
4477 enc = encoding_names[i];
4478 while (enc)
4479 {
4480 char expectedA[200];
4481
4483 EXPECT_HR(hr, S_OK);
4484
4485 V_VT(&dest) = VT_UNKNOWN;
4487 hr = IMXWriter_put_output(writer, dest);
4488 EXPECT_HR(hr, S_OK);
4489
4490 hr = IMXWriter_put_encoding(writer, _bstr_(enc));
4491 ok(hr == S_OK || broken(hr != S_OK) /* old win versions do not support certain encodings */,
4492 "%s: encoding not accepted\n", enc);
4493 if (hr != S_OK)
4494 {
4495 enc = encoding_names[++i];
4496 IStream_Release(stream);
4497 continue;
4498 }
4499
4500 hr = ISAXContentHandler_startDocument(content);
4501 EXPECT_HR(hr, S_OK);
4502
4503 hr = ISAXContentHandler_endDocument(content);
4504 EXPECT_HR(hr, S_OK);
4505
4506 hr = IMXWriter_flush(writer);
4507 EXPECT_HR(hr, S_OK);
4508
4509 /* prepare expected string */
4510 *expectedA = 0;
4511 strcat(expectedA, "<?xml version=\"1.0\" encoding=\"");
4512 strcat(expectedA, enc);
4513 strcat(expectedA, "\" standalone=\"no\"?>\r\n");
4514
4516 EXPECT_HR(hr, S_OK);
4517
4518 ptr = GlobalLock(g);
4519 ok(!strncmp(ptr, expectedA, strlen(expectedA)), "%s: got %s, expected %.50s\n", enc, ptr, expectedA);
4520 GlobalUnlock(g);
4521
4522 V_VT(&dest) = VT_EMPTY;
4523 hr = IMXWriter_put_output(writer, dest);
4524 EXPECT_HR(hr, S_OK);
4525
4526 IStream_Release(stream);
4527
4528 enc = encoding_names[++i];
4529 }
4530
4531 ISAXContentHandler_Release(content);
4532 IMXWriter_Release(writer);
4533
4534 free_bstrs();
4535}
4536
4538{
4539 static const WCHAR testW[] = {'t','e','s','t','p','r','o','p',0};
4540 static const WCHAR starW[] = {'*',0};
4542 IDispatchEx *dispex;
4543 IUnknown *unk;
4544 DWORD props;
4545 UINT ticnt;
4546 HRESULT hr;
4547 BSTR name;
4548 DISPID did;
4549
4550 hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
4551 EXPECT_HR(hr, S_OK);
4552 if (FAILED(hr)) return;
4553
4554 ticnt = 0;
4555 hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
4556 EXPECT_HR(hr, S_OK);
4557 ok(ticnt == 1, "ticnt=%u\n", ticnt);
4558
4560 hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
4563
4564 hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
4566
4567 props = 0;
4568 hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
4570 ok(props == 0, "expected 0 got %d\n", props);
4571
4572 hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
4575
4576 hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_SAX_XMLREADER_GETFEATURE, &dispid);
4578
4579 unk = (IUnknown*)0xdeadbeef;
4580 hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
4582 ok(unk == (IUnknown*)0xdeadbeef, "got %p\n", unk);
4583
4585 hr = IDispatchEx_GetDispID(dispex, name, fdexNameEnsure, &did);
4586 ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr);
4588
4589 IDispatchEx_Release(dispex);
4590}
4591
4592static void test_saxreader_dispex(void)
4593{
4594 IVBSAXXMLReader *vbreader;
4595 ISAXXMLReader *reader;
4596 DISPPARAMS dispparams;
4597 DISPID dispid;
4598 IUnknown *unk;
4599 VARIANT arg;
4600 HRESULT hr;
4601
4602 hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER,
4603 &IID_ISAXXMLReader, (void**)&reader);
4604 EXPECT_HR(hr, S_OK);
4605
4606 hr = ISAXXMLReader_QueryInterface(reader, &IID_IUnknown, (void**)&unk);
4607 EXPECT_HR(hr, S_OK);
4608 test_obj_dispex(unk);
4609 IUnknown_Release(unk);
4610
4611 hr = ISAXXMLReader_QueryInterface(reader, &IID_IVBSAXXMLReader, (void**)&vbreader);
4612 EXPECT_HR(hr, S_OK);
4613 hr = IVBSAXXMLReader_QueryInterface(vbreader, &IID_IUnknown, (void**)&unk);
4614 EXPECT_HR(hr, S_OK);
4615 test_obj_dispex(unk);
4616 IUnknown_Release(unk);
4617
4618 dispid = DISPID_PROPERTYPUT;
4619 dispparams.cArgs = 1;
4620 dispparams.cNamedArgs = 1;
4621 dispparams.rgdispidNamedArgs = &dispid;
4622 dispparams.rgvarg = &arg;
4623
4624 V_VT(&arg) = VT_DISPATCH;
4625 V_DISPATCH(&arg) = NULL;
4626
4627 /* propputref is callable as PROPERTYPUT and PROPERTYPUTREF */
4628 hr = IVBSAXXMLReader_Invoke(vbreader,
4630 &IID_NULL,
4631 0,
4633 &dispparams,
4634 NULL,
4635 NULL,
4636 NULL);
4637 ok(hr == S_OK, "got 0x%08x\n", hr);
4638
4639 hr = IVBSAXXMLReader_Invoke(vbreader,
4641 &IID_NULL,
4642 0,
4644 &dispparams,
4645 NULL,
4646 NULL,
4647 NULL);
4648 ok(hr == S_OK, "got 0x%08x\n", hr);
4649
4650 IVBSAXXMLReader_Release(vbreader);
4651 ISAXXMLReader_Release(reader);
4652
4653 if (is_clsid_supported(&CLSID_SAXXMLReader60, reader_support_data))
4654 {
4655 hr = CoCreateInstance(&CLSID_SAXXMLReader60, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&unk);
4656 ok(hr == S_OK, "got 0x%08x\n", hr);
4657 test_obj_dispex(unk);
4658 IUnknown_Release(unk);
4659 }
4660}
4661
4662static void test_mxwriter_dispex(void)
4663{
4664 IDispatchEx *dispex;
4665 IMXWriter *writer;
4666 IUnknown *unk;
4667 HRESULT hr;
4668
4669 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
4670 &IID_IMXWriter, (void**)&writer);
4671 EXPECT_HR(hr, S_OK);
4672
4673 hr = IMXWriter_QueryInterface(writer, &IID_IDispatchEx, (void**)&dispex);
4674 EXPECT_HR(hr, S_OK);
4675 hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
4676 test_obj_dispex(unk);
4677 IUnknown_Release(unk);
4678 IDispatchEx_Release(dispex);
4679 IMXWriter_Release(writer);
4680
4681 if (is_clsid_supported(&CLSID_MXXMLWriter60, mxwriter_support_data))
4682 {
4683 hr = CoCreateInstance(&CLSID_MXXMLWriter60, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&unk);
4684 ok(hr == S_OK, "got 0x%08x\n", hr);
4685 test_obj_dispex(unk);
4686 IUnknown_Release(unk);
4687 }
4688}
4689
4690static void test_mxwriter_comment(void)
4691{
4692 static const WCHAR commentW[] = {'c','o','m','m','e','n','t',0};
4693 IVBSAXLexicalHandler *vblexical;
4694 ISAXContentHandler *content;
4695 ISAXLexicalHandler *lexical;
4696 IMXWriter *writer;
4697 VARIANT dest;
4698 HRESULT hr;
4699
4700 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
4701 &IID_IMXWriter, (void**)&writer);
4702 EXPECT_HR(hr, S_OK);
4703
4704 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
4705 EXPECT_HR(hr, S_OK);
4706
4707 hr = IMXWriter_QueryInterface(writer, &IID_ISAXLexicalHandler, (void**)&lexical);
4708 EXPECT_HR(hr, S_OK);
4709
4710 hr = IMXWriter_QueryInterface(writer, &IID_IVBSAXLexicalHandler, (void**)&vblexical);
4711 EXPECT_HR(hr, S_OK);
4712
4713 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
4714 EXPECT_HR(hr, S_OK);
4715
4716 hr = ISAXContentHandler_startDocument(content);
4717 EXPECT_HR(hr, S_OK);
4718
4719 hr = ISAXLexicalHandler_comment(lexical, NULL, 0);
4721
4722 hr = IVBSAXLexicalHandler_comment(vblexical, NULL);
4724
4725 hr = ISAXLexicalHandler_comment(lexical, commentW, 0);
4726 EXPECT_HR(hr, S_OK);
4727
4728 V_VT(&dest) = VT_EMPTY;
4729 hr = IMXWriter_get_output(writer, &dest);
4730 EXPECT_HR(hr, S_OK);
4731 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4732 ok(!lstrcmpW(_bstr_("<!---->\r\n"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4734
4735 hr = ISAXLexicalHandler_comment(lexical, commentW, ARRAY_SIZE(commentW) - 1);
4736 EXPECT_HR(hr, S_OK);
4737
4738 V_VT(&dest) = VT_EMPTY;
4739 hr = IMXWriter_get_output(writer, &dest);
4740 EXPECT_HR(hr, S_OK);
4741 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4742 ok(!lstrcmpW(_bstr_("<!---->\r\n<!--comment-->\r\n"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4744
4745 ISAXContentHandler_Release(content);
4746 ISAXLexicalHandler_Release(lexical);
4747 IVBSAXLexicalHandler_Release(vblexical);
4748 IMXWriter_Release(writer);
4749 free_bstrs();
4750}
4751
4752static void test_mxwriter_cdata(void)
4753{
4754 IVBSAXLexicalHandler *vblexical;
4755 ISAXContentHandler *content;
4756 ISAXLexicalHandler *lexical;
4757 IMXWriter *writer;
4758 VARIANT dest;
4759 HRESULT hr;
4760
4761 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
4762 &IID_IMXWriter, (void**)&writer);
4763 EXPECT_HR(hr, S_OK);
4764
4765 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
4766 EXPECT_HR(hr, S_OK);
4767
4768 hr = IMXWriter_QueryInterface(writer, &IID_ISAXLexicalHandler, (void**)&lexical);
4769 EXPECT_HR(hr, S_OK);
4770
4771 hr = IMXWriter_QueryInterface(writer, &IID_IVBSAXLexicalHandler, (void**)&vblexical);
4772 EXPECT_HR(hr, S_OK);
4773
4774 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
4775 EXPECT_HR(hr, S_OK);
4776
4777 hr = ISAXContentHandler_startDocument(content);
4778 EXPECT_HR(hr, S_OK);
4779
4780 hr = ISAXLexicalHandler_startCDATA(lexical);
4781 EXPECT_HR(hr, S_OK);
4782
4783 V_VT(&dest) = VT_EMPTY;
4784 hr = IMXWriter_get_output(writer, &dest);
4785 EXPECT_HR(hr, S_OK);
4786 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4787 ok(!lstrcmpW(_bstr_("<![CDATA["), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4789
4790 hr = IVBSAXLexicalHandler_startCDATA(vblexical);
4791 EXPECT_HR(hr, S_OK);
4792
4793 /* all these are escaped for text nodes */
4794 hr = ISAXContentHandler_characters(content, _bstr_("< > & \""), 7);
4795 EXPECT_HR(hr, S_OK);
4796
4797 hr = ISAXLexicalHandler_endCDATA(lexical);
4798 EXPECT_HR(hr, S_OK);
4799
4800 V_VT(&dest) = VT_EMPTY;
4801 hr = IMXWriter_get_output(writer, &dest);
4802 EXPECT_HR(hr, S_OK);
4803 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4804 ok(!lstrcmpW(_bstr_("<![CDATA[<![CDATA[< > & \"]]>"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4806
4807 ISAXContentHandler_Release(content);
4808 ISAXLexicalHandler_Release(lexical);
4809 IVBSAXLexicalHandler_Release(vblexical);
4810 IMXWriter_Release(writer);
4811 free_bstrs();
4812}
4813
4814static void test_mxwriter_pi(void)
4815{
4816 static const WCHAR targetW[] = {'t','a','r','g','e','t',0};
4817 static const WCHAR dataW[] = {'d','a','t','a',0};
4818 ISAXContentHandler *content;
4819 IMXWriter *writer;
4820 VARIANT dest;
4821 HRESULT hr;
4822
4823 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
4824 &IID_IMXWriter, (void**)&writer);
4825 EXPECT_HR(hr, S_OK);
4826
4827 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
4828 EXPECT_HR(hr, S_OK);
4829
4830 hr = ISAXContentHandler_processingInstruction(content, NULL, 0, NULL, 0);
4832
4833 hr = ISAXContentHandler_processingInstruction(content, targetW, 0, NULL, 0);
4834 EXPECT_HR(hr, S_OK);
4835
4836 hr = ISAXContentHandler_processingInstruction(content, targetW, 6, NULL, 0);
4837 EXPECT_HR(hr, S_OK);
4838
4839 V_VT(&dest) = VT_EMPTY;
4840 hr = IMXWriter_get_output(writer, &dest);
4841 EXPECT_HR(hr, S_OK);
4842 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4843 ok(!lstrcmpW(_bstr_("<?\?>\r\n<?target?>\r\n"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4845
4846 hr = ISAXContentHandler_processingInstruction(content, targetW, 4, dataW, 4);
4847 EXPECT_HR(hr, S_OK);
4848
4849 V_VT(&dest) = VT_EMPTY;
4850 hr = IMXWriter_get_output(writer, &dest);
4851 EXPECT_HR(hr, S_OK);
4852 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4853 ok(!lstrcmpW(_bstr_("<?\?>\r\n<?target?>\r\n<?targ data?>\r\n"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4855
4856 V_VT(&dest) = VT_EMPTY;
4857 hr = IMXWriter_put_output(writer, dest);
4858 EXPECT_HR(hr, S_OK);
4859
4860 hr = ISAXContentHandler_processingInstruction(content, targetW, 6, dataW, 0);
4861 EXPECT_HR(hr, S_OK);
4862
4863 V_VT(&dest) = VT_EMPTY;
4864 hr = IMXWriter_get_output(writer, &dest);
4865 EXPECT_HR(hr, S_OK);
4866 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4867 ok(!lstrcmpW(_bstr_("<?target?>\r\n"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4869
4870
4871 ISAXContentHandler_Release(content);
4872 IMXWriter_Release(writer);
4873}
4874
4876{
4877 static const WCHAR dataW[] = {'d','a','t','a',0};
4878 ISAXContentHandler *content;
4879 IMXWriter *writer;
4880 VARIANT dest;
4881 HRESULT hr;
4882
4883 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
4884 &IID_IMXWriter, (void**)&writer);
4885 EXPECT_HR(hr, S_OK);
4886
4887 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
4888 EXPECT_HR(hr, S_OK);
4889
4890 hr = ISAXContentHandler_ignorableWhitespace(content, NULL, 0);
4892
4893 hr = ISAXContentHandler_ignorableWhitespace(content, dataW, 0);
4894 EXPECT_HR(hr, S_OK);
4895
4896 hr = ISAXContentHandler_ignorableWhitespace(content, dataW, 4);
4897 EXPECT_HR(hr, S_OK);
4898
4899 hr = ISAXContentHandler_ignorableWhitespace(content, dataW, 1);
4900 EXPECT_HR(hr, S_OK);
4901
4902 V_VT(&dest) = VT_EMPTY;
4903 hr = IMXWriter_get_output(writer, &dest);
4904 EXPECT_HR(hr, S_OK);
4905 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4906 ok(!lstrcmpW(_bstr_("datad"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4908
4909 ISAXContentHandler_Release(content);
4910 IMXWriter_Release(writer);
4911}
4912
4913static void test_mxwriter_dtd(void)
4914{
4915 static const WCHAR contentW[] = {'c','o','n','t','e','n','t'};
4916 static const WCHAR nameW[] = {'n','a','m','e'};
4917 static const WCHAR pubW[] = {'p','u','b'};
4918 static const WCHAR sysW[] = {'s','y','s'};
4919 IVBSAXLexicalHandler *vblexical;
4920 ISAXContentHandler *content;
4921 ISAXLexicalHandler *lexical;
4922 IVBSAXDeclHandler *vbdecl;
4923 ISAXDeclHandler *decl;
4924 ISAXDTDHandler *dtd;
4925 IMXWriter *writer;
4926 VARIANT dest;
4927 HRESULT hr;
4928
4929 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
4930 &IID_IMXWriter, (void**)&writer);
4931 EXPECT_HR(hr, S_OK);
4932
4933 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
4934 EXPECT_HR(hr, S_OK);
4935
4936 hr = IMXWriter_QueryInterface(writer, &IID_ISAXLexicalHandler, (void**)&lexical);
4937 EXPECT_HR(hr, S_OK);
4938
4939 hr = IMXWriter_QueryInterface(writer, &IID_ISAXDeclHandler, (void**)&decl);
4940 EXPECT_HR(hr, S_OK);
4941
4942 hr = IMXWriter_QueryInterface(writer, &IID_IVBSAXDeclHandler, (void**)&vbdecl);
4943 EXPECT_HR(hr, S_OK);
4944
4945 hr = IMXWriter_QueryInterface(writer, &IID_IVBSAXLexicalHandler, (void**)&vblexical);
4946 EXPECT_HR(hr, S_OK);
4947
4948 hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
4949 EXPECT_HR(hr, S_OK);
4950
4951 hr = ISAXContentHandler_startDocument(content);
4952 EXPECT_HR(hr, S_OK);
4953
4954 hr = ISAXLexicalHandler_startDTD(lexical, NULL, 0, NULL, 0, NULL, 0);
4956
4957 hr = IVBSAXLexicalHandler_startDTD(vblexical, NULL, NULL, NULL);
4959
4960 hr = ISAXLexicalHandler_startDTD(lexical, NULL, 0, pubW, ARRAY_SIZE(pubW), NULL, 0);
4962
4963 hr = ISAXLexicalHandler_startDTD(lexical, NULL, 0, NULL, 0, sysW, ARRAY_SIZE(sysW));
4965
4966 hr = ISAXLexicalHandler_startDTD(lexical, NULL, 0, pubW, ARRAY_SIZE(pubW), sysW, ARRAY_SIZE(sysW));
4968
4969 hr = ISAXLexicalHandler_startDTD(lexical, nameW, ARRAY_SIZE(nameW), NULL, 0, NULL, 0);
4970 EXPECT_HR(hr, S_OK);
4971
4972 V_VT(&dest) = VT_EMPTY;
4973 hr = IMXWriter_get_output(writer, &dest);
4974 EXPECT_HR(hr, S_OK);
4975 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4976 ok(!lstrcmpW(_bstr_("<!DOCTYPE name [\r\n"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4978
4979 /* system id is required if public is present */
4980 hr = ISAXLexicalHandler_startDTD(lexical, nameW, ARRAY_SIZE(nameW), pubW, ARRAY_SIZE(pubW), NULL, 0);
4982
4983 hr = ISAXLexicalHandler_startDTD(lexical, nameW, ARRAY_SIZE(nameW),
4984 pubW, ARRAY_SIZE(pubW), sysW, ARRAY_SIZE(sysW));
4985 EXPECT_HR(hr, S_OK);
4986
4987 V_VT(&dest) = VT_EMPTY;
4988 hr = IMXWriter_get_output(writer, &dest);
4989 EXPECT_HR(hr, S_OK);
4990 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
4991 ok(!lstrcmpW(_bstr_("<!DOCTYPE name [\r\n<!DOCTYPE name PUBLIC \"pub\""
4992 "<!DOCTYPE name PUBLIC \"pub\" \"sys\" [\r\n"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
4994
4995 hr = ISAXLexicalHandler_endDTD(lexical);
4996 EXPECT_HR(hr, S_OK);
4997
4998 hr = IVBSAXLexicalHandler_endDTD(vblexical);
4999 EXPECT_HR(hr, S_OK);
5000
5001 V_VT(&dest) = VT_EMPTY;
5002 hr = IMXWriter_get_output(writer, &dest);
5003 EXPECT_HR(hr, S_OK);
5004 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
5005 ok(!lstrcmpW(_bstr_("<!DOCTYPE name [\r\n<!DOCTYPE name PUBLIC \"pub\""
5006 "<!DOCTYPE name PUBLIC \"pub\" \"sys\" [\r\n]>\r\n]>\r\n"),
5007 V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
5009
5010 /* element declaration */
5011 V_VT(&dest) = VT_EMPTY;
5012 hr = IMXWriter_put_output(writer, dest);
5013 EXPECT_HR(hr, S_OK);
5014
5015 hr = ISAXDeclHandler_elementDecl(decl, NULL, 0, NULL, 0);
5017
5018 hr = IVBSAXDeclHandler_elementDecl(vbdecl, NULL, NULL);
5020
5021 hr = ISAXDeclHandler_elementDecl(decl, nameW, ARRAY_SIZE(nameW), NULL, 0);
5023
5024 hr = ISAXDeclHandler_elementDecl(decl, nameW, ARRAY_SIZE(nameW), contentW, ARRAY_SIZE(contentW));
5025 EXPECT_HR(hr, S_OK);
5026
5027 V_VT(&dest) = VT_EMPTY;
5028 hr = IMXWriter_get_output(writer, &dest);
5029 EXPECT_HR(hr, S_OK);
5030 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
5031 ok(!lstrcmpW(_bstr_("<!ELEMENT name content>\r\n"),
5032 V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
5034
5035 V_VT(&dest) = VT_EMPTY;
5036 hr = IMXWriter_put_output(writer, dest);
5037 EXPECT_HR(hr, S_OK);
5038
5039 hr = ISAXDeclHandler_elementDecl(decl, nameW, ARRAY_SIZE(nameW), contentW, 0);
5040 EXPECT_HR(hr, S_OK);
5041
5042 V_VT(&dest) = VT_EMPTY;
5043 hr = IMXWriter_get_output(writer, &dest);
5044 EXPECT_HR(hr, S_OK);
5045 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
5046 ok(!lstrcmpW(_bstr_("<!ELEMENT name >\r\n"),
5047 V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
5049
5050 /* attribute declaration */
5051 V_VT(&dest) = VT_EMPTY;
5052 hr = IMXWriter_put_output(writer, dest);
5053 EXPECT_HR(hr, S_OK);
5054
5055 hr = ISAXDeclHandler_attributeDecl(decl, _bstr_("element"), strlen("element"),
5056 _bstr_("attribute"), strlen("attribute"), _bstr_("CDATA"), strlen("CDATA"),
5057 _bstr_("#REQUIRED"), strlen("#REQUIRED"), _bstr_("value"), strlen("value"));
5058 EXPECT_HR(hr, S_OK);
5059
5060 V_VT(&dest) = VT_EMPTY;
5061 hr = IMXWriter_get_output(writer, &dest);
5062 EXPECT_HR(hr, S_OK);
5063 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
5064 ok(!lstrcmpW(_bstr_("<!ATTLIST element attribute CDATA #REQUIRED \"value\">\r\n"),
5065 V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
5067
5068 hr = ISAXDeclHandler_attributeDecl(decl, _bstr_("element"), strlen("element"),
5069 _bstr_("attribute2"), strlen("attribute2"), _bstr_("CDATA"), strlen("CDATA"),
5070 _bstr_("#REQUIRED"), strlen("#REQUIRED"), _bstr_("value2"), strlen("value2"));
5071 EXPECT_HR(hr, S_OK);
5072
5073 hr = ISAXDeclHandler_attributeDecl(decl, _bstr_("element2"), strlen("element2"),
5074 _bstr_("attribute3"), strlen("attribute3"), _bstr_("CDATA"), strlen("CDATA"),
5075 _bstr_("#REQUIRED"), strlen("#REQUIRED"), _bstr_("value3"), strlen("value3"));
5076 EXPECT_HR(hr, S_OK);
5077
5078 V_VT(&dest) = VT_EMPTY;
5079 hr = IMXWriter_get_output(writer, &dest);
5080 EXPECT_HR(hr, S_OK);
5081 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
5082 ok(!lstrcmpW(_bstr_("<!ATTLIST element attribute CDATA #REQUIRED \"value\">\r\n"
5083 "<!ATTLIST element attribute2 CDATA #REQUIRED \"value2\">\r\n"
5084 "<!ATTLIST element2 attribute3 CDATA #REQUIRED \"value3\">\r\n"),
5085 V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
5087
5088 /* internal entities */
5089 V_VT(&dest) = VT_EMPTY;
5090 hr = IMXWriter_put_output(writer, dest);
5091 EXPECT_HR(hr, S_OK);
5092
5093 hr = ISAXDeclHandler_internalEntityDecl(decl, NULL, 0, NULL, 0);
5095
5096 hr = IVBSAXDeclHandler_internalEntityDecl(vbdecl, NULL, NULL);
5098
5099 hr = ISAXDeclHandler_internalEntityDecl(decl, _bstr_("name"), -1, NULL, 0);
5101
5102 hr = ISAXDeclHandler_internalEntityDecl(decl, _bstr_("name"), strlen("name"), _bstr_("value"), strlen("value"));
5103 EXPECT_HR(hr, S_OK);
5104
5105 V_VT(&dest) = VT_EMPTY;
5106 hr = IMXWriter_get_output(writer, &dest);
5107 EXPECT_HR(hr, S_OK);
5108 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
5109 ok(!lstrcmpW(_bstr_("<!ENTITY name \"value\">\r\n"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
5111
5112 /* external entities */
5113 V_VT(&dest) = VT_EMPTY;
5114 hr = IMXWriter_put_output(writer, dest);
5115 ok(hr == S_OK, "got 0x%08x\n", hr);
5116
5117 hr = ISAXDeclHandler_externalEntityDecl(decl, NULL, 0, NULL, 0, NULL, 0);
5118 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
5119
5120 hr = IVBSAXDeclHandler_externalEntityDecl(vbdecl, NULL, NULL, NULL);
5121 ok(hr == E_POINTER, "got 0x%08x\n", hr);
5122
5123 hr = ISAXDeclHandler_externalEntityDecl(decl, _bstr_("name"), 0, NULL, 0, NULL, 0);
5124 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
5125
5126 hr = ISAXDeclHandler_externalEntityDecl(decl, _bstr_("name"), -1, NULL, 0, NULL, 0);
5127 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
5128
5129 hr = ISAXDeclHandler_externalEntityDecl(decl, _bstr_("name"), strlen("name"), _bstr_("pubid"), strlen("pubid"),
5130 _bstr_("sysid"), strlen("sysid"));
5131 ok(hr == S_OK, "got 0x%08x\n", hr);
5132
5133 hr = ISAXDeclHandler_externalEntityDecl(decl, _bstr_("name"), strlen("name"), NULL, 0, _bstr_("sysid"), strlen("sysid"));
5134 ok(hr == S_OK, "got 0x%08x\n", hr);
5135
5136 hr = ISAXDeclHandler_externalEntityDecl(decl, _bstr_("name"), strlen("name"), _bstr_("pubid"), strlen("pubid"),
5137 NULL, 0);
5138 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
5139
5140 V_VT(&dest) = VT_EMPTY;
5141 hr = IMXWriter_get_output(writer, &dest);
5142 ok(hr == S_OK, "got 0x%08x\n", hr);
5143 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
5145 "<!ENTITY name PUBLIC \"pubid\" \"sysid\">\r\n"
5146 "<!ENTITY name SYSTEM \"sysid\">\r\n"),
5147 V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
5148
5150
5151 /* notation declaration */
5152 hr = IMXWriter_QueryInterface(writer, &IID_ISAXDTDHandler, (void**)&dtd);
5153 ok(hr == S_OK, "got 0x%08x\n", hr);
5154
5155 V_VT(&dest) = VT_EMPTY;
5156 hr = IMXWriter_put_output(writer, dest);
5157 ok(hr == S_OK, "got 0x%08x\n", hr);
5158
5159 hr = ISAXDTDHandler_notationDecl(dtd, NULL, 0, NULL, 0, NULL, 0);
5160 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
5161
5162 hr = ISAXDTDHandler_notationDecl(dtd, _bstr_("name"), strlen("name"), NULL, 0, NULL, 0);
5163 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
5164
5165 hr = ISAXDTDHandler_notationDecl(dtd, _bstr_("name"), strlen("name"), _bstr_("pubid"), strlen("pubid"), NULL, 0);
5166 ok(hr == S_OK, "got 0x%08x\n", hr);
5167
5168 hr = ISAXDTDHandler_notationDecl(dtd, _bstr_("name"), strlen("name"), _bstr_("pubid"), strlen("pubid"), _bstr_("sysid"), strlen("sysid"));
5169 ok(hr == S_OK, "got 0x%08x\n", hr);
5170
5171 hr = ISAXDTDHandler_notationDecl(dtd, _bstr_("name"), strlen("name"), NULL, 0, _bstr_("sysid"), strlen("sysid"));
5172 ok(hr == S_OK, "got 0x%08x\n", hr);
5173
5174 hr = IMXWriter_get_output(writer, &dest);
5175 ok(hr == S_OK, "got 0x%08x\n", hr);
5176 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
5178 "<!NOTATION name"
5179 "<!NOTATION name PUBLIC \"pubid\">\r\n"
5180 "<!NOTATION name PUBLIC \"pubid\" \"sysid\">\r\n"
5181 "<!NOTATION name SYSTEM \"sysid\">\r\n"),
5182 V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
5183
5185
5186 ISAXDTDHandler_Release(dtd);
5187
5188 ISAXContentHandler_Release(content);
5189 ISAXLexicalHandler_Release(lexical);
5190 IVBSAXLexicalHandler_Release(vblexical);
5191 IVBSAXDeclHandler_Release(vbdecl);
5192 ISAXDeclHandler_Release(decl);
5193 IMXWriter_Release(writer);
5194 free_bstrs();
5195}
5196
5197typedef struct {
5198 const CLSID *clsid;
5199 const char *uri;
5200 const char *local;
5201 const char *qname;
5202 const char *type;
5203 const char *value;
5206
5208 { &CLSID_SAXAttributes, NULL, NULL, "ns:qname", NULL, "value", E_INVALIDARG },
5209 { &CLSID_SAXAttributes30, NULL, NULL, "ns:qname", NULL, "value", E_INVALIDARG },
5210 { &CLSID_SAXAttributes40, NULL, NULL, "ns:qname", NULL, "value", E_INVALIDARG },
5211 { &CLSID_SAXAttributes60, NULL, NULL, "ns:qname", NULL, "value", S_OK },
5212
5213 { &CLSID_SAXAttributes, NULL, "qname", "ns:qname", NULL, "value", E_INVALIDARG },
5214 { &CLSID_SAXAttributes30, NULL, "qname", "ns:qname", NULL, "value", E_INVALIDARG },
5215 { &CLSID_SAXAttributes40, NULL, "qname", "ns:qname", NULL, "value", E_INVALIDARG },
5216 { &CLSID_SAXAttributes60, NULL, "qname", "ns:qname", NULL, "value", S_OK },
5217
5218 { &CLSID_SAXAttributes, "uri", "qname", "ns:qname", NULL, "value", E_INVALIDARG },
5219 { &CLSID_SAXAttributes30, "uri", "qname", "ns:qname", NULL, "value", E_INVALIDARG },
5220 { &CLSID_SAXAttributes40, "uri", "qname", "ns:qname", NULL, "value", E_INVALIDARG },
5221 { &CLSID_SAXAttributes60, "uri", "qname", "ns:qname", NULL, "value", S_OK },
5222
5223 { &CLSID_SAXAttributes, "uri", "qname", "ns:qname", "type", "value", S_OK },
5224 { &CLSID_SAXAttributes30, "uri", "qname", "ns:qname", "type", "value", S_OK },
5225 { &CLSID_SAXAttributes40, "uri", "qname", "ns:qname", "type", "value", S_OK },
5226 { &CLSID_SAXAttributes60, "uri", "qname", "ns:qname", "type", "value", S_OK },
5227
5228 { NULL }
5229};
5230
5232{
5234 int i = 0;
5235
5236 while (table->clsid)
5237 {
5238 ISAXAttributes *saxattr;
5239 IMXAttributes *mxattr;
5240 const WCHAR *value;
5241 int len, index;
5242 HRESULT hr;
5243
5245 {
5246 table++;
5247 i++;
5248 continue;
5249 }
5250
5251 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER,
5252 &IID_IMXAttributes, (void**)&mxattr);
5253 EXPECT_HR(hr, S_OK);
5254
5255 hr = IMXAttributes_QueryInterface(mxattr, &IID_ISAXAttributes, (void**)&saxattr);
5256 EXPECT_HR(hr, S_OK);
5257
5258 /* SAXAttributes40 and SAXAttributes60 both crash on this test */
5259 if (IsEqualGUID(table->clsid, &CLSID_SAXAttributes) ||
5260 IsEqualGUID(table->clsid, &CLSID_SAXAttributes30))
5261 {
5262 hr = ISAXAttributes_getLength(saxattr, NULL);
5264 }
5265
5266 len = -1;
5267 hr = ISAXAttributes_getLength(saxattr, &len);
5268 EXPECT_HR(hr, S_OK);
5269 ok(len == 0, "got %d\n", len);
5270
5271 hr = ISAXAttributes_getValue(saxattr, 0, &value, &len);
5273
5274 hr = ISAXAttributes_getValue(saxattr, 0, NULL, &len);
5275 ok(hr == E_POINTER /* win8 */ || hr == E_INVALIDARG, "got 0x%08x\n", hr);
5276
5277 hr = ISAXAttributes_getValue(saxattr, 0, &value, NULL);
5278 ok(hr == E_POINTER /* win8 */ || hr == E_INVALIDARG, "got 0x%08x\n", hr);
5279
5280 hr = ISAXAttributes_getValue(saxattr, 0, NULL, NULL);
5281 ok(hr == E_POINTER /* win8 */ || hr == E_INVALIDARG, "got 0x%08x\n", hr);
5282
5283 hr = ISAXAttributes_getType(saxattr, 0, &value, &len);
5285
5286 hr = ISAXAttributes_getType(saxattr, 0, NULL, &len);
5287 ok(hr == E_POINTER /* win8 */ || hr == E_INVALIDARG, "got 0x%08x\n", hr);
5288
5289 hr = ISAXAttributes_getType(saxattr, 0, &value, NULL);
5290 ok(hr == E_POINTER /* win8 */ || hr == E_INVALIDARG, "got 0x%08x\n", hr);
5291
5292 hr = ISAXAttributes_getType(saxattr, 0, NULL, NULL);
5293 ok(hr == E_POINTER /* win8 */ || hr == E_INVALIDARG, "got 0x%08x\n", hr);
5294
5295 hr = IMXAttributes_addAttribute(mxattr, _bstr_(table->uri), _bstr_(table->local),
5296 _bstr_(table->qname), _bstr_(table->type), _bstr_(table->value));
5297 ok(hr == table->hr, "%d: got 0x%08x, expected 0x%08x\n", i, hr, table->hr);
5298
5299 if (hr == S_OK)
5300 {
5301 /* SAXAttributes40 and SAXAttributes60 both crash on this test */
5302 if (IsEqualGUID(table->clsid, &CLSID_SAXAttributes) ||
5303 IsEqualGUID(table->clsid, &CLSID_SAXAttributes30))
5304 {
5305 hr = ISAXAttributes_getValue(saxattr, 0, NULL, &len);
5307
5308 hr = ISAXAttributes_getValue(saxattr, 0, &value, NULL);
5310
5311 hr = ISAXAttributes_getValue(saxattr, 0, NULL, NULL);
5313
5314 hr = ISAXAttributes_getType(saxattr, 0, NULL, &len);
5316
5317 hr = ISAXAttributes_getType(saxattr, 0, &value, NULL);
5319
5320 hr = ISAXAttributes_getType(saxattr, 0, NULL, NULL);
5322 }
5323
5324 len = -1;
5325 hr = ISAXAttributes_getValue(saxattr, 0, &value, &len);
5326 EXPECT_HR(hr, S_OK);
5327 ok(!lstrcmpW(_bstr_(table->value), value), "%d: got %s, expected %s\n", i, wine_dbgstr_w(value),
5328 table->value);
5329 ok(lstrlenW(value) == len, "%d: got wrong value length %d\n", i, len);
5330
5331 len = -1;
5332 value = (void*)0xdeadbeef;
5333 hr = ISAXAttributes_getType(saxattr, 0, &value, &len);
5334 EXPECT_HR(hr, S_OK);
5335
5336 if (table->type)
5337 {
5338 ok(!lstrcmpW(_bstr_(table->type), value), "%d: got %s, expected %s\n", i, wine_dbgstr_w(value),
5339 table->type);
5340 ok(lstrlenW(value) == len, "%d: got wrong type value length %d\n", i, len);
5341 }
5342 else
5343 {
5344 ok(*value == 0, "%d: got type value %s\n", i, wine_dbgstr_w(value));
5345 ok(len == 0, "%d: got wrong type value length %d\n", i, len);
5346 }
5347
5348 hr = ISAXAttributes_getIndexFromQName(saxattr, NULL, 0, NULL);
5349 if (IsEqualGUID(table->clsid, &CLSID_SAXAttributes) ||
5350 IsEqualGUID(table->clsid, &CLSID_SAXAttributes30))
5351 {
5353 }
5354 else
5356
5357 hr = ISAXAttributes_getIndexFromQName(saxattr, NULL, 0, &index);
5359
5360 index = -1;
5361 hr = ISAXAttributes_getIndexFromQName(saxattr, _bstr_("nonexistent"), 11, &index);
5363 ok(index == -1, "%d: got wrong index %d\n", i, index);
5364
5365 index = -1;
5366 hr = ISAXAttributes_getIndexFromQName(saxattr, _bstr_(table->qname), 0, &index);
5368 ok(index == -1, "%d: got wrong index %d\n", i, index);
5369
5370 index = -1;
5371 hr = ISAXAttributes_getIndexFromQName(saxattr, _bstr_(table->qname), strlen(table->qname), &index);
5372 EXPECT_HR(hr, S_OK);
5373 ok(index == 0, "%d: got wrong index %d\n", i, index);
5374
5375 index = -1;
5376 hr = ISAXAttributes_getIndexFromQName(saxattr, _bstr_(table->qname), strlen(table->qname)-1, &index);
5378 ok(index == -1, "%d: got wrong index %d\n", i, index);
5379
5380 if (IsEqualGUID(table->clsid, &CLSID_SAXAttributes40) ||
5381 IsEqualGUID(table->clsid, &CLSID_SAXAttributes60))
5382 {
5383 hr = ISAXAttributes_getValueFromQName(saxattr, NULL, 0, NULL, NULL);
5384 ok(hr == E_POINTER /* win8 */ || hr == E_INVALIDARG, "got 0x%08x\n", hr);
5385
5386 hr = ISAXAttributes_getValueFromQName(saxattr, _bstr_(table->qname), 0, NULL, NULL);
5387 ok(hr == E_POINTER /* win8 */ || hr == E_INVALIDARG, "got 0x%08x\n", hr);
5388
5389 hr = ISAXAttributes_getValueFromQName(saxattr, _bstr_(table->qname), 0, &value, NULL);
5390 ok(hr == E_POINTER /* win8 */ || hr == E_INVALIDARG, "got 0x%08x\n", hr);
5391
5392 hr = ISAXAttributes_getValueFromName(saxattr, NULL, 0, NULL, 0, NULL, NULL);
5393 ok(hr == E_POINTER /* win8 */ || hr == E_INVALIDARG, "got 0x%08x\n", hr);
5394
5395 hr = ISAXAttributes_getValueFromName(saxattr, _bstr_(table->uri), 0, NULL, 0, NULL, NULL);
5396 ok(hr == E_POINTER /* win8 */ || hr == E_INVALIDARG, "got 0x%08x\n", hr);
5397
5398 hr = ISAXAttributes_getValueFromName(saxattr, _bstr_(table->uri), 0, NULL, 0, &value, NULL);
5399 ok(hr == E_POINTER /* win8 */ || hr == E_INVALIDARG, "got 0x%08x\n", hr);
5400 }
5401 else
5402 {
5403 hr = ISAXAttributes_getValueFromQName(saxattr, NULL, 0, NULL, NULL);
5405
5406 hr = ISAXAttributes_getValueFromQName(saxattr, _bstr_(table->qname), 0, NULL, NULL);
5408
5409 hr = ISAXAttributes_getValueFromQName(saxattr, _bstr_(table->qname), 0, &value, NULL);
5411
5412 /* versions 4 and 6 crash */
5413 hr = ISAXAttributes_getValueFromQName(saxattr, _bstr_(table->qname), strlen(table->qname), NULL, NULL);
5415
5416 hr = ISAXAttributes_getValueFromQName(saxattr, _bstr_(table->qname), strlen(table->qname), NULL, &len);
5418
5419 hr = ISAXAttributes_getValueFromName(saxattr, NULL, 0, NULL, 0, NULL, NULL);
5421
5422 hr = ISAXAttributes_getValueFromName(saxattr, _bstr_(table->uri), 0, NULL, 0, NULL, NULL);
5424
5425 hr = ISAXAttributes_getValueFromName(saxattr, _bstr_(table->uri), 0, NULL, 0, &value, NULL);
5427
5428 hr = ISAXAttributes_getValueFromName(saxattr, _bstr_(table->uri), 0, _bstr_(table->local), 0, &value, NULL);
5430
5431 hr = ISAXAttributes_getValueFromName(saxattr, _bstr_(table->uri), 0, _bstr_(table->local), 0, NULL, &len);
5433
5434 hr = ISAXAttributes_getValueFromName(saxattr, _bstr_(table->uri), strlen(table->uri), _bstr_(table->local),
5435 strlen(table->local), NULL, NULL);
5437 }
5438
5439 hr = ISAXAttributes_getValueFromQName(saxattr, _bstr_(table->qname), strlen(table->qname), &value, &len);
5440 EXPECT_HR(hr, S_OK);
5441 ok(!lstrcmpW(_bstr_(table->value), value), "%d: got %s, expected %s\n", i, wine_dbgstr_w(value),
5442 table->value);
5443 ok(lstrlenW(value) == len, "%d: got wrong value length %d\n", i, len);
5444
5445 if (table->uri) {
5446 hr = ISAXAttributes_getValueFromName(saxattr, _bstr_(table->uri), strlen(table->uri),
5447 _bstr_(table->local), strlen(table->local), &value, &len);
5448 EXPECT_HR(hr, S_OK);
5449 ok(!lstrcmpW(_bstr_(table->value), value), "%d: got %s, expected %s\n", i, wine_dbgstr_w(value),
5450 table->value);
5451 ok(lstrlenW(value) == len, "%d: got wrong value length %d\n", i, len);
5452 }
5453 }
5454
5455 len = -1;
5456 hr = ISAXAttributes_getLength(saxattr, &len);
5457 EXPECT_HR(hr, S_OK);
5458 if (table->hr == S_OK)
5459 ok(len == 1, "%d: got %d length, expected 1\n", i, len);
5460 else
5461 ok(len == 0, "%d: got %d length, expected 0\n", i, len);
5462
5463 ISAXAttributes_Release(saxattr);
5464 IMXAttributes_Release(mxattr);
5465
5466 table++;
5467 i++;
5468 }
5469
5470 free_bstrs();
5471}
5472
5473static void test_mxattr_clear(void)
5474{
5475 ISAXAttributes *saxattr;
5476 IMXAttributes *mxattr;
5477 const WCHAR *ptr;
5478 HRESULT hr;
5479 int len;
5480
5481 hr = CoCreateInstance(&CLSID_SAXAttributes, NULL, CLSCTX_INPROC_SERVER,
5482 &IID_IMXAttributes, (void**)&mxattr);
5483 EXPECT_HR(hr, S_OK);
5484
5485 hr = IMXAttributes_QueryInterface(mxattr, &IID_ISAXAttributes, (void**)&saxattr);
5486 EXPECT_HR(hr, S_OK);
5487
5488 hr = ISAXAttributes_getQName(saxattr, 0, NULL, NULL);
5490
5491 hr = ISAXAttributes_getQName(saxattr, 0, &ptr, &len);
5493
5494 hr = IMXAttributes_clear(mxattr);
5495 EXPECT_HR(hr, S_OK);
5496
5497 hr = IMXAttributes_addAttribute(mxattr, _bstr_("uri"), _bstr_("local"),
5498 _bstr_("qname"), _bstr_("type"), _bstr_("value"));
5499 EXPECT_HR(hr, S_OK);
5500
5501 len = -1;
5502 hr = ISAXAttributes_getLength(saxattr, &len);
5503 EXPECT_HR(hr, S_OK);
5504 ok(len == 1, "got %d\n", len);
5505
5506 len = -1;
5507 hr = ISAXAttributes_getQName(saxattr, 0, NULL, &len);
5509 ok(len == -1, "got %d\n", len);
5510
5511 ptr = (void*)0xdeadbeef;
5512 hr = ISAXAttributes_getQName(saxattr, 0, &ptr, NULL);
5514 ok(ptr == (void*)0xdeadbeef, "got %p\n", ptr);
5515
5516 len = 0;
5517 hr = ISAXAttributes_getQName(saxattr, 0, &ptr, &len);
5518 EXPECT_HR(hr, S_OK);
5519 ok(len == 5, "got %d\n", len);
5520 ok(!lstrcmpW(ptr, _bstr_("qname")), "got %s\n", wine_dbgstr_w(ptr));
5521
5522 hr = IMXAttributes_clear(mxattr);
5523 EXPECT_HR(hr, S_OK);
5524
5525 len = -1;
5526 hr = ISAXAttributes_getLength(saxattr, &len);
5527 EXPECT_HR(hr, S_OK);
5528 ok(len == 0, "got %d\n", len);
5529
5530 len = -1;
5531 ptr = (void*)0xdeadbeef;
5532 hr = ISAXAttributes_getQName(saxattr, 0, &ptr, &len);
5534 ok(len == -1, "got %d\n", len);
5535 ok(ptr == (void*)0xdeadbeef, "got %p\n", ptr);
5536
5537 IMXAttributes_Release(mxattr);
5538 ISAXAttributes_Release(saxattr);
5539 free_bstrs();
5540}
5541
5542static void test_mxattr_dispex(void)
5543{
5544 IMXAttributes *mxattr;
5545 IDispatchEx *dispex;
5546 IUnknown *unk;
5547 HRESULT hr;
5548
5549 hr = CoCreateInstance(&CLSID_SAXAttributes, NULL, CLSCTX_INPROC_SERVER,
5550 &IID_IMXAttributes, (void**)&mxattr);
5551 EXPECT_HR(hr, S_OK);
5552
5553 hr = IMXAttributes_QueryInterface(mxattr, &IID_IDispatchEx, (void**)&dispex);
5554 EXPECT_HR(hr, S_OK);
5555 hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
5556 test_obj_dispex(unk);
5557 IUnknown_Release(unk);
5558 IDispatchEx_Release(dispex);
5559
5560 IMXAttributes_Release(mxattr);
5561}
5562
5563static void test_mxattr_qi(void)
5564{
5565 IVBSAXAttributes *vbsaxattr, *vbsaxattr2;
5566 ISAXAttributes *saxattr;
5567 IMXAttributes *mxattr;
5568 HRESULT hr;
5569
5570 hr = CoCreateInstance(&CLSID_SAXAttributes, NULL, CLSCTX_INPROC_SERVER,
5571 &IID_IMXAttributes, (void**)&mxattr);
5572 EXPECT_HR(hr, S_OK);
5573
5574 EXPECT_REF(mxattr, 1);
5575 hr = IMXAttributes_QueryInterface(mxattr, &IID_ISAXAttributes, (void**)&saxattr);
5576 EXPECT_HR(hr, S_OK);
5577
5578 EXPECT_REF(mxattr, 2);
5579 EXPECT_REF(saxattr, 2);
5580
5581 hr = IMXAttributes_QueryInterface(mxattr, &IID_IVBSAXAttributes, (void**)&vbsaxattr);
5582 EXPECT_HR(hr, S_OK);
5583
5584 EXPECT_REF(vbsaxattr, 3);
5585 EXPECT_REF(mxattr, 3);
5586 EXPECT_REF(saxattr, 3);
5587
5588 hr = ISAXAttributes_QueryInterface(saxattr, &IID_IVBSAXAttributes, (void**)&vbsaxattr2);
5589 EXPECT_HR(hr, S_OK);
5590
5591 EXPECT_REF(vbsaxattr, 4);
5592 EXPECT_REF(mxattr, 4);
5593 EXPECT_REF(saxattr, 4);
5594
5595 IMXAttributes_Release(mxattr);
5596 ISAXAttributes_Release(saxattr);
5597 IVBSAXAttributes_Release(vbsaxattr);
5598 IVBSAXAttributes_Release(vbsaxattr2);
5599}
5600
5602{
5603 { &CLSID_SAXAttributes, "SAXAttributes" },
5604 { &CLSID_SAXAttributes30, "SAXAttributes30" },
5605 { &CLSID_SAXAttributes40, "SAXAttributes40" },
5606 { &CLSID_SAXAttributes60, "SAXAttributes60" },
5607 { NULL }
5608};
5609
5610static void test_mxattr_localname(void)
5611{
5612 static const WCHAR localname1W[] = {'l','o','c','a','l','n','a','m','e','1',0};
5613 static const WCHAR localnameW[] = {'l','o','c','a','l','n','a','m','e',0};
5614 static const WCHAR uri1W[] = {'u','r','i','1',0};
5615 static const WCHAR uriW[] = {'u','r','i',0};
5616
5618
5619 while (table->clsid)
5620 {
5621 ISAXAttributes *saxattr;
5622 IMXAttributes *mxattr;
5623 HRESULT hr;
5624 int index;
5625
5627 {
5628 table++;
5629 continue;
5630 }
5631
5632 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER,
5633 &IID_IMXAttributes, (void**)&mxattr);
5634 EXPECT_HR(hr, S_OK);
5635
5636 hr = IMXAttributes_QueryInterface(mxattr, &IID_ISAXAttributes, (void**)&saxattr);
5637 EXPECT_HR(hr, S_OK);
5638
5639 hr = ISAXAttributes_getIndexFromName(saxattr, NULL, 0, NULL, 0, &index);
5641
5642 /* add some ambiguos attribute names */
5643 hr = IMXAttributes_addAttribute(mxattr, _bstr_("uri"), _bstr_("localname"),
5644 _bstr_("a:localname"), _bstr_(""), _bstr_("value"));
5645 EXPECT_HR(hr, S_OK);
5646 hr = IMXAttributes_addAttribute(mxattr, _bstr_("uri"), _bstr_("localname"),
5647 _bstr_("b:localname"), _bstr_(""), _bstr_("value"));
5648 EXPECT_HR(hr, S_OK);
5649
5650 index = -1;
5651 hr = ISAXAttributes_getIndexFromName(saxattr, uriW, lstrlenW(uriW), localnameW, lstrlenW(localnameW), &index);
5652 EXPECT_HR(hr, S_OK);
5653 ok(index == 0, "%s: got index %d\n", table->name, index);
5654
5655 index = -1;
5656 hr = ISAXAttributes_getIndexFromName(saxattr, uri1W, lstrlenW(uri1W), localnameW, lstrlenW(localnameW), &index);
5658 ok(index == -1, "%s: got index %d\n", table->name, index);
5659
5660 index = -1;
5661 hr = ISAXAttributes_getIndexFromName(saxattr, uriW, lstrlenW(uriW), localname1W, lstrlenW(localname1W), &index);
5663 ok(index == -1, "%s: got index %d\n", table->name, index);
5664
5665 if (IsEqualGUID(table->clsid, &CLSID_SAXAttributes) ||
5666 IsEqualGUID(table->clsid, &CLSID_SAXAttributes30))
5667 {
5668 hr = ISAXAttributes_getIndexFromName(saxattr, NULL, 0, NULL, 0, NULL);
5670
5671 hr = ISAXAttributes_getIndexFromName(saxattr, uriW, lstrlenW(uriW), localname1W, lstrlenW(localname1W), NULL);
5673 }
5674 else
5675 {
5676 hr = ISAXAttributes_getIndexFromName(saxattr, NULL, 0, NULL, 0, NULL);
5678
5679 hr = ISAXAttributes_getIndexFromName(saxattr, uriW, lstrlenW(uriW), localname1W, lstrlenW(localname1W), NULL);
5681 }
5682
5683 hr = ISAXAttributes_getIndexFromName(saxattr, uriW, lstrlenW(uriW), NULL, 0, &index);
5685
5686 hr = ISAXAttributes_getIndexFromName(saxattr, NULL, 0, localname1W, lstrlenW(localname1W), &index);
5688
5689 table++;
5690
5691 ISAXAttributes_Release(saxattr);
5692 IMXAttributes_Release(mxattr);
5693 free_bstrs();
5694 }
5695}
5696
5697static void test_mxwriter_indent(void)
5698{
5699 ISAXContentHandler *content;
5700 IMXWriter *writer;
5701 VARIANT dest;
5702 HRESULT hr;
5703
5704 hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER, &IID_IMXWriter, (void**)&writer);
5705 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
5706
5707 hr = IMXWriter_put_indent(writer, VARIANT_TRUE);
5708 ok(hr == S_OK, "got %08x\n", hr);
5709
5710 hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
5711 ok(hr == S_OK, "got %08x\n", hr);
5712
5713 hr = ISAXContentHandler_startDocument(content);
5714 ok(hr == S_OK, "got %08x\n", hr);
5715
5716 hr = ISAXContentHandler_startElement(content, emptyW, 0, emptyW, 0, _bstr_("a"), -1, NULL);
5717 ok(hr == S_OK, "got %08x\n", hr);
5718
5719 hr = ISAXContentHandler_characters(content, _bstr_(""), 0);
5720 ok(hr == S_OK, "got %08x\n", hr);
5721
5722 hr = ISAXContentHandler_startElement(content, emptyW, 0, emptyW, 0, _bstr_("b"), -1, NULL);
5723 ok(hr == S_OK, "got %08x\n", hr);
5724
5725 hr = ISAXContentHandler_startElement(content, emptyW, 0, emptyW, 0, _bstr_("c"), -1, NULL);
5726 ok(hr == S_OK, "got %08x\n", hr);
5727
5728 hr = ISAXContentHandler_endElement(content, emptyW, 0, emptyW, 0, _bstr_("c"), -1);
5729 ok(hr == S_OK, "got %08x\n", hr);
5730
5731 hr = ISAXContentHandler_endElement(content, emptyW, 0, emptyW, 0, _bstr_("b"), -1);
5732 ok(hr == S_OK, "got %08x\n", hr);
5733
5734 hr = ISAXContentHandler_endElement(content, emptyW, 0, emptyW, 0, _bstr_("a"), -1);
5735 ok(hr == S_OK, "got %08x\n", hr);
5736
5737 hr = ISAXContentHandler_endDocument(content);
5738 ok(hr == S_OK, "got %08x\n", hr);
5739
5740 V_VT(&dest) = VT_EMPTY;
5741 hr = IMXWriter_get_output(writer, &dest);
5742 ok(hr == S_OK, "got %08x\n", hr);
5743 ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
5744 ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n<a><b>\r\n\t\t<c/>\r\n\t</b>\r\n</a>"), V_BSTR(&dest)),
5745 "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
5747
5748 ISAXContentHandler_Release(content);
5749 IMXWriter_Release(writer);
5750
5751 free_bstrs();
5752}
5753
5754START_TEST(saxreader)
5755{
5756 ISAXXMLReader *reader;
5757 HRESULT hr;
5758
5759 hr = CoInitialize(NULL);
5760 ok(hr == S_OK, "failed to init com\n");
5761
5762 hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER,
5763 &IID_ISAXXMLReader, (void**)&reader);
5764
5765 if(FAILED(hr))
5766 {
5767 win_skip("Failed to create SAXXMLReader instance\n");
5769 return;
5770 }
5771 ISAXXMLReader_Release(reader);
5772
5774
5775 get_class_support_data(reader_support_data, &IID_ISAXXMLReader);
5776
5782
5783 /* MXXMLWriter tests */
5785 if (is_clsid_supported(&CLSID_MXXMLWriter, mxwriter_support_data))
5786 {
5802 }
5803 else
5804 win_skip("MXXMLWriter not supported\n");
5805
5806 /* SAXAttributes tests */
5808 if (is_clsid_supported(&CLSID_SAXAttributes, mxattributes_support_data))
5809 {
5815 }
5816 else
5817 win_skip("SAXAttributes not supported\n");
5818
5820}
static void flush_sequence(void)
Definition: SystemMenu.c:184
static struct recvd_message * sequence
Definition: SystemMenu.c:63
#define broken(x)
Definition: _sntprintf.h:21
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
static const WCHAR nameW[]
Definition: main.c:46
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:33
const GUID IID_IUnknown
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
content
Definition: atl_ax.c:994
const char * wine_dbgstr_wn(const WCHAR *str, int n)
Definition: compat.c:367
#define CloseHandle
Definition: compat.h:739
#define CP_ACP
Definition: compat.h:109
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
OLECHAR * BSTR
Definition: compat.h:2293
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
short VARIANT_BOOL
Definition: compat.h:2290
#define MultiByteToWideChar
Definition: compat.h:110
@ VT_BSTR
Definition: compat.h:2303
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_BYREF
Definition: compat.h:2342
@ VT_ARRAY
Definition: compat.h:2341
@ VT_VARIANT
Definition: compat.h:2307
@ VT_I4
Definition: compat.h:2298
@ VT_EMPTY
Definition: compat.h:2295
@ VT_DISPATCH
Definition: compat.h:2304
@ VT_UI1
Definition: compat.h:2311
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7482
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI GetHGlobalFromStream(IStream *pstm, HGLOBAL *phglobal)
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:600
#define assert(x)
Definition: debug.h:53
static const WCHAR commentW[]
Definition: reader.c:97
static unsigned char buff[32768]
Definition: fatten.c:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
PWCHAR pValue
const GLdouble * v
Definition: gl.h:2040
GLdouble s
Definition: gl.h:2039
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
struct _cl_event * event
Definition: glext.h:7739
GLdouble n
Definition: glext.h:7729
GLuint index
Definition: glext.h:6031
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLboolean GLboolean g
Definition: glext.h:6204
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLenum target
Definition: glext.h:7315
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
static const WCHAR testW[]
Definition: jsregexp.c:44
#define b
Definition: ke_i.h:79
#define wine_dbgstr_w
Definition: kernel32.h:34
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define CREATE_ALWAYS
Definition: disk.h:72
static PVOID ptr
Definition: dispmode.c:27
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static LPSTR pName
Definition: security.c:75
BOOL todo
Definition: filedlg.c:313
BOOL expected
Definition: store.c:2063
const char * var
Definition: shader.c:5666
UINT test_count
Definition: shader.c:5671
static IStream * create_test_stream(void)
Definition: mimeole.c:459
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
#define todo_wine_if(is_todo)
Definition: custom.c:76
#define todo_wine
Definition: custom.c:79
static HRESULT get_expected_ret(void)
Definition: saxreader.c:1047
static const mxwriter_write_test * current_write_test
Definition: saxreader.c:1924
static struct attribute_entry read_test_attrs[]
Definition: saxreader.c:1006
static struct call_entry xmlspaceattr_test[]
Definition: saxreader.c:870
static ISAXAttributes saxattributes
Definition: saxreader.c:1681
static HRESULT WINAPI contentHandler_startElement(ISAXContentHandler *iface, const WCHAR *uri, int uri_len, const WCHAR *localname, int local_len, const WCHAR *qname, int qname_len, ISAXAttributes *saxattr)
Definition: saxreader.c:1193
static struct call_entry cdata_test3_alt[]
Definition: saxreader.c:994
static struct call_entry attribute_norm[]
Definition: saxreader.c:900
static int read_cnt
Definition: saxreader.c:2068
static HRESULT WINAPI contentHandler_endDocument(ISAXContentHandler *iface)
Definition: saxreader.c:1146
static struct call_entry content_handler_test_attributes_alternate_6[]
Definition: saxreader.c:803
static ULONG WINAPI isaxerrorHandler_Release(ISAXErrorHandler *iface)
Definition: saxreader.c:1411
static const struct writer_startendelement2_t writer_startendelement2[]
Definition: saxreader.c:3758
static BSTR _bstr_(const char *str)
Definition: saxreader.c:91
static void test_mxwriter_dispex(void)
Definition: saxreader.c:4662
static struct call_entry cdata_test[]
Definition: saxreader.c:918
static void test_mxattr_qi(void)
Definition: saxreader.c:5563
static HRESULT WINAPI istream_Commit(IStream *iface, DWORD grfCommitFlags)
Definition: saxreader.c:1983
static const struct saxreader_props_test_t props_test_data[]
Definition: saxreader.c:2563
static const char * get_event_name(CH event)
Definition: saxreader.c:315
static HRESULT WINAPI isaxattributes_getTypeFromQName(ISAXAttributes *iface, const WCHAR *pQName, int nQName, const WCHAR **pType, int *nType)
Definition: saxreader.c:1605
static HRESULT WINAPI isaxlexical_QueryInterface(ISAXLexicalHandler *iface, REFIID riid, void **out)
Definition: saxreader.c:1696
static const char test2_cdata_xml[]
Definition: saxreader.c:587
static const char startendelement_noescape_xml[]
Definition: saxreader.c:3545
static void test_mxwriter_pi(void)
Definition: saxreader.c:4814
static void test_mxwriter_handlers(void)
Definition: saxreader.c:2951
static ISAXContentHandler contentHandler
Definition: saxreader.c:1384
static HRESULT WINAPI contentHandler_skippedEntity(ISAXContentHandler *iface, const WCHAR *name, int len)
Definition: saxreader.c:1350
static ISAXErrorHandler errorHandler
Definition: saxreader.c:1465
static const char * encoding_names[]
Definition: saxreader.c:4382
static struct call_entry content_handler_test_attributes_alt_no_ns[]
Definition: saxreader.c:777
static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes *iface)
Definition: saxreader.c:1486
static ULONG WINAPI istream_Release(IStream *iface)
Definition: saxreader.c:1946
static HRESULT WINAPI isaxattributes_getLength(ISAXAttributes *iface, int *length)
Definition: saxreader.c:1496
static void test_mxwriter_flush(void)
Definition: saxreader.c:3250
static struct msxmlsupported_data_t mxwriter_support_data[]
Definition: saxreader.c:3000
static IStream mxstream
Definition: saxreader.c:2066
static const struct mxwriter_props_t mxwriter_default_props[]
Definition: saxreader.c:3029
static struct call_entry content_handler_testerror[]
Definition: saxreader.c:671
static struct msxmlsupported_data_t reader_support_data[]
Definition: saxreader.c:2108
static const char test3_cdata_xml[]
Definition: saxreader.c:591
static void test_saxreader_properties(void)
Definition: saxreader.c:2569
static const struct enc_test_entry_t encoding_test_data[]
Definition: saxreader.c:2897
static void test_saxstr(const char *file, unsigned line, BSTR str, const char *expected, BOOL todo, int *failcount)
Definition: saxreader.c:106
static void init_saxdeclhandler(struct saxdeclhandler *handler, HRESULT hr)
Definition: saxreader.c:1903
static void test_mxwriter_properties(void)
Definition: saxreader.c:3099
#define EXPECT_HR(hr, hr_exp)
Definition: saxreader.c:41
static HRESULT WINAPI istream_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: saxreader.c:2002
static void test_mxattr_clear(void)
Definition: saxreader.c:5473
static ULONG WINAPI isaxattributes_Release(ISAXAttributes *iface)
Definition: saxreader.c:1491
static BSTR alloc_str_from_narrow(const char *str)
Definition: saxreader.c:80
enum _CH CH
static HRESULT WINAPI istream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
Definition: saxreader.c:1957
static ULONG WINAPI contentHandler_AddRef(ISAXContentHandler *iface)
Definition: saxreader.c:1073
static HRESULT WINAPI contentHandler_endPrefixMapping(ISAXContentHandler *iface, const WCHAR *prefix, int len)
Definition: saxreader.c:1177
static HRESULT WINAPI isaxerrorHandler_QueryInterface(ISAXErrorHandler *iface, REFIID riid, void **ppvObject)
Definition: saxreader.c:1386
static struct call_entry cdata_test2_alt[]
Definition: saxreader.c:976
static void test_mxwriter_startendelement_batch(const struct writer_startendelement_t *table)
Definition: saxreader.c:3671
static struct msxmlsupported_data_t mxattributes_support_data[]
Definition: saxreader.c:3009
static void test_mxwriter_startenddocument(void)
Definition: saxreader.c:3450
static struct call_entry content_handler_test_attributes_no_prefix[]
Definition: saxreader.c:847
static ISAXXMLReader * g_reader
Definition: saxreader.c:1038
static const char * event_names[EVENT_LAST]
Definition: saxreader.c:183
_CH
Definition: saxreader.c:162
@ CH_PROCESSINGINSTRUCTION
Definition: saxreader.c:173
@ CH_ENDELEMENT
Definition: saxreader.c:170
@ CH_SKIPPEDENTITY
Definition: saxreader.c:174
@ CH_STARTPREFIXMAPPING
Definition: saxreader.c:167
@ EH_ERROR
Definition: saxreader.c:177
@ CH_IGNORABLEWHITESPACE
Definition: saxreader.c:172
@ CH_ENDDOCUMENT
Definition: saxreader.c:166
@ EH_IGNORABLEWARNING
Definition: saxreader.c:179
@ LH_STARTCDATA
Definition: saxreader.c:175
@ CH_ENDTEST
Definition: saxreader.c:163
@ EH_FATALERROR
Definition: saxreader.c:178
@ EVENT_LAST
Definition: saxreader.c:180
@ CH_PUTDOCUMENTLOCATOR
Definition: saxreader.c:164
@ LH_ENDCDATA
Definition: saxreader.c:176
@ CH_STARTELEMENT
Definition: saxreader.c:169
@ CH_CHARACTERS
Definition: saxreader.c:171
@ CH_ENDPREFIXMAPPING
Definition: saxreader.c:168
@ CH_STARTDOCUMENT
Definition: saxreader.c:165
static ULONG WINAPI isaxdecl_Release(ISAXDeclHandler *iface)
Definition: saxreader.c:1855
static HRESULT WINAPI instream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
Definition: saxreader.c:2070
static struct call_entry cdata_test3[]
Definition: saxreader.c:947
static const CHAR UTF8BOMTest[]
Definition: saxreader.c:2885
static const struct writer_characters_t writer_characters[]
Definition: saxreader.c:3964
static DWORD current_stream_test_index
Definition: saxreader.c:1925
static HRESULT WINAPI isaxerrorHandler_fatalError(ISAXErrorHandler *iface, ISAXLocator *pLocator, const WCHAR *message, HRESULT hr)
Definition: saxreader.c:1427
static const mxwriter_stream_test mxwriter_stream_tests[]
Definition: saxreader.c:4196
#define CONTENT_HANDLER_INDEX
Definition: saxreader.c:242
static const CHAR szUtf16BOM[]
Definition: saxreader.c:562
static HRESULT WINAPI isaxlexical_endCDATA(ISAXLexicalHandler *iface)
Definition: saxreader.c:1772
static HRESULT WINAPI contentHandler_characters(ISAXContentHandler *iface, const WCHAR *chars, int len)
Definition: saxreader.c:1298
static void _expect_ref(IUnknown *obj, ULONG ref, int line)
Definition: saxreader.c:45
static struct saxlexicalhandler * impl_from_ISAXLexicalHandler(ISAXLexicalHandler *iface)
Definition: saxreader.c:1691
static void add_call(struct call_sequence **seq, int sequence_index, const struct call_entry *call)
Definition: saxreader.c:253
static struct saxdeclhandler declhandler
Definition: saxreader.c:2118
static void test_mxwriter_comment(void)
Definition: saxreader.c:4690
static struct attribute_entry attribute_norm_attrs[]
Definition: saxreader.c:895
static HRESULT WINAPI mxstream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
Definition: saxreader.c:2020
static const char attribute_normalize[]
Definition: saxreader.c:891
static const char startelement_xml[]
Definition: saxreader.c:3543
static HRESULT WINAPI istream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
Definition: saxreader.c:1951
static struct attribute_entry ch_attributes1[]
Definition: saxreader.c:708
static void test_mxattr_localname(void)
Definition: saxreader.c:5610
static int alloced_bstrs_count
Definition: saxreader.c:89
static struct call_entry content_handler_test_callback_rets[]
Definition: saxreader.c:683
static HRESULT WINAPI isaxattributes_getValue(ISAXAttributes *iface, int index, const WCHAR **value, int *nValue)
Definition: saxreader.c:1616
static HRESULT WINAPI isaxattributes_getValueFromQName(ISAXAttributes *iface, const WCHAR *pQName, int nQName, const WCHAR **pValue, int *nValue)
Definition: saxreader.c:1650
static ULONG WINAPI isaxerrorHandler_AddRef(ISAXErrorHandler *iface)
Definition: saxreader.c:1405
static HRESULT WINAPI isaxattributes_getValueFromName(ISAXAttributes *iface, const WCHAR *pUri, int nUri, const WCHAR *pLocalName, int nLocalName, const WCHAR **pValue, int *nValue)
Definition: saxreader.c:1637
static void free_bstrs(void)
Definition: saxreader.c:98
static HRESULT WINAPI isaxattributes_getIndexFromName(ISAXAttributes *iface, const WCHAR *pUri, int cUriLength, const WCHAR *pLocalName, int cocalNameLength, int *index)
Definition: saxreader.c:1560
static HRESULT WINAPI contentHandler_ignorableWhitespace(ISAXContentHandler *iface, const WCHAR *chars, int len)
Definition: saxreader.c:1315
static const char xmlspace_attr[]
Definition: saxreader.c:1032
static struct attribute_entry xmlspace_attrs[]
Definition: saxreader.c:865
static void test_saxreader(void)
Definition: saxreader.c:2138
static HRESULT WINAPI isaxdecl_internalEntityDecl(ISAXDeclHandler *iface, const WCHAR *pName, int nName, const WCHAR *pValue, int nValue)
Definition: saxreader.c:1877
static HRESULT WINAPI isaxerrorHandler_ignorableWarning(ISAXErrorHandler *iface, ISAXLocator *pLocator, const WCHAR *pErrorMessage, HRESULT hrErrorCode)
Definition: saxreader.c:1445
static struct call_entry content_handler_test_attributes_alt_no_prefix[]
Definition: saxreader.c:829
static void test_mxwriter_characters(void)
Definition: saxreader.c:3972
static struct call_entry content_handler_test1[]
Definition: saxreader.c:594
static struct call_entry cdata_test_alt[]
Definition: saxreader.c:960
static struct call_entry xmlspaceattr_test_alternate[]
Definition: saxreader.c:880
static HRESULT WINAPI contentHandler_QueryInterface(ISAXContentHandler *iface, REFIID riid, void **ppvObject)
Definition: saxreader.c:1054
static const char * feature_names[]
Definition: saxreader.c:2789
static void init_call_sequences(struct call_sequence **seq, int n)
Definition: saxreader.c:532
static HRESULT WINAPI istream_Revert(IStream *iface)
Definition: saxreader.c:1989
static void test_mxattr_addAttribute(void)
Definition: saxreader.c:5231
static struct attribute_entry ch_attributes_alt_no_ns[]
Definition: saxreader.c:768
static const char startendelement_xml[]
Definition: saxreader.c:3544
static struct saxdeclhandler * impl_from_ISAXDeclHandler(ISAXDeclHandler *iface)
Definition: saxreader.c:1819
static const WCHAR carriage_ret_test[]
Definition: saxreader.c:548
static struct call_entry content_handler_test_callback_rets_alt[]
Definition: saxreader.c:690
static HRESULT WINAPI istream_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
Definition: saxreader.c:1963
static HRESULT WINAPI isaxdecl_QueryInterface(ISAXDeclHandler *iface, REFIID riid, void **out)
Definition: saxreader.c:1824
static const char test_cdata_xml[]
Definition: saxreader.c:583
static HRESULT WINAPI contentHandler_startPrefixMapping(ISAXContentHandler *iface, const WCHAR *prefix, int prefix_len, const WCHAR *uri, int uri_len)
Definition: saxreader.c:1158
static void test_mxwriter_startendelement_batch2(const struct writer_startendelement2_t *table)
Definition: saxreader.c:3772
struct mxwriter_stream_test_t mxwriter_stream_test
static const addattribute_test_t addattribute_data[]
Definition: saxreader.c:5207
static void test_mxwriter_encoding(void)
Definition: saxreader.c:4395
static const ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl
Definition: saxreader.c:1790
static LONG get_refcount(void *iface)
Definition: saxreader.c:53
static struct call_entry * expectCall
Definition: saxreader.c:1036
static HRESULT WINAPI contentHandler_putDocumentLocator(ISAXContentHandler *iface, ISAXLocator *pLocator)
Definition: saxreader.c:1085
static HRESULT WINAPI isaxattributes_getQName(ISAXAttributes *iface, int index, const WCHAR **QName, int *QNameLength)
Definition: saxreader.c:1522
#define ok_sequence(seq, index, exp, contx, todo)
Definition: saxreader.c:529
static struct msxmlsupported_data_t saxattr_support_data[]
Definition: saxreader.c:5601
static HRESULT WINAPI isaxattributes_getType(ISAXAttributes *iface, int nIndex, const WCHAR **pType, int *pTypeLength)
Definition: saxreader.c:1582
static const CHAR szUtf8XML[]
Definition: saxreader.c:564
static ULONG WINAPI istream_AddRef(IStream *iface)
Definition: saxreader.c:1941
static ISAXLocator * locator
Definition: saxreader.c:1037
static struct call_entry content_handler_test2[]
Definition: saxreader.c:631
static const WCHAR szUtf16XML[]
Definition: saxreader.c:556
static void ok_sequence_(struct call_sequence **seq, int sequence_index, const struct call_entry *expected, const char *context, BOOL todo, const char *file, int line)
Definition: saxreader.c:356
static struct saxlexicalhandler lexicalhandler
Definition: saxreader.c:2117
static const IStreamVtbl instreamVtbl
Definition: saxreader.c:2089
static void test_mxwriter_stream(void)
Definition: saxreader.c:4252
static const WCHAR emptyW[]
Definition: saxreader.c:39
static ULONG WINAPI isaxlexical_Release(ISAXLexicalHandler *iface)
Definition: saxreader.c:1727
static HRESULT WINAPI isaxlexical_endDTD(ISAXLexicalHandler *iface)
Definition: saxreader.c:1741
static struct call_entry attribute_norm_alt[]
Definition: saxreader.c:909
static struct attribute_entry ch_attributes_alt_6[]
Definition: saxreader.c:789
static HRESULT WINAPI isaxattributes_QueryInterface(ISAXAttributes *iface, REFIID riid, void **ppvObject)
Definition: saxreader.c:1467
static HRESULT WINAPI istream_Clone(IStream *iface, IStream **ppstm)
Definition: saxreader.c:2014
static HRESULT WINAPI isaxattributes_getName(ISAXAttributes *iface, int nIndex, const WCHAR **pUri, int *pUriLength, const WCHAR **pLocalName, int *pLocalNameSize, const WCHAR **pQName, int *pQNameLength)
Definition: saxreader.c:1546
static const ISAXContentHandlerVtbl contentHandlerVtbl
Definition: saxreader.c:1366
static HRESULT WINAPI isaxdecl_elementDecl(ISAXDeclHandler *iface, const WCHAR *pName, int nName, const WCHAR *pModel, int nModel)
Definition: saxreader.c:1861
static const ISAXErrorHandlerVtbl errorHandlerVtbl
Definition: saxreader.c:1455
static void test_saxreader_features(void)
Definition: saxreader.c:2795
static void test_saxreader_encoding(void)
Definition: saxreader.c:2905
#define EXPECT_REF(obj, ref)
Definition: saxreader.c:44
static HRESULT WINAPI isaxattributes_getIndexFromQName(ISAXAttributes *iface, const WCHAR *pQName, int nQNameLength, int *index)
Definition: saxreader.c:1572
static const char utf8xml2[]
Definition: saxreader.c:567
struct mxwriter_write_test_t mxwriter_write_test
static void test_mxwriter_ignorablespaces(void)
Definition: saxreader.c:4875
#define NUM_CALL_SEQUENCES
Definition: saxreader.c:243
static BSTR alloced_bstrs[512]
Definition: saxreader.c:88
static HRESULT WINAPI isaxlexical_startDTD(ISAXLexicalHandler *iface, const WCHAR *pName, int nName, const WCHAR *pPublicId, int nPublicId, const WCHAR *pSystemId, int nSystemId)
Definition: saxreader.c:1733
static struct call_entry content_handler_testerror_alternate[]
Definition: saxreader.c:677
static const IStreamVtbl mxstreamVtbl
Definition: saxreader.c:2049
static struct call_entry content_handler_test1_alternate[]
Definition: saxreader.c:613
static void test_mxwriter_indent(void)
Definition: saxreader.c:5697
static void init_saxlexicalhandler(struct saxlexicalhandler *handler, HRESULT hr)
Definition: saxreader.c:1804
static void get_class_support_data(struct msxmlsupported_data_t *table, REFIID riid)
Definition: saxreader.c:3654
static ULONG WINAPI isaxdecl_AddRef(ISAXDeclHandler *iface)
Definition: saxreader.c:1849
static HRESULT WINAPI istream_QueryInterface(IStream *iface, REFIID riid, void **ppvObject)
Definition: saxreader.c:1927
static ULONG WINAPI isaxlexical_AddRef(ISAXLexicalHandler *iface)
Definition: saxreader.c:1721
static HRESULT WINAPI contentHandler_endElement(ISAXContentHandler *iface, const WCHAR *uri, int uri_len, const WCHAR *localname, int local_len, const WCHAR *qname, int qname_len)
Definition: saxreader.c:1276
static HRESULT WINAPI isaxattributes_getLocalName(ISAXAttributes *iface, int nIndex, const WCHAR **pLocalName, int *pLocalNameLength)
Definition: saxreader.c:1512
static HRESULT WINAPI isaxattributes_getTypeFromName(ISAXAttributes *iface, const WCHAR *pUri, int nUri, const WCHAR *pLocalName, int nLocalName, const WCHAR **pType, int *nType)
Definition: saxreader.c:1592
static struct attribute_entry ch_attributes2[]
Definition: saxreader.c:717
static struct call_entry content_handler_test2_alternate[]
Definition: saxreader.c:651
static HRESULT WINAPI contentHandler_processingInstruction(ISAXContentHandler *iface, const WCHAR *target, int target_len, const WCHAR *data, int data_len)
Definition: saxreader.c:1331
static HRESULT WINAPI isaxerrorHandler_error(ISAXErrorHandler *iface, ISAXLocator *pLocator, const WCHAR *pErrorMessage, HRESULT hrErrorCode)
Definition: saxreader.c:1417
static void test_mxwriter_startendelement(void)
Definition: saxreader.c:3835
static HRESULT WINAPI istream_CopyTo(IStream *iface, IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *plibWritten)
Definition: saxreader.c:1976
static void init_call_entry(ISAXLocator *locator, struct call_entry *call)
Definition: saxreader.c:246
startendtype
Definition: saxreader.c:3525
@ StartEndElement
Definition: saxreader.c:3528
@ StartElement
Definition: saxreader.c:3526
@ DisableEscaping
Definition: saxreader.c:3529
@ EndElement
Definition: saxreader.c:3527
static const struct writer_startendelement_t writer_startendelement[]
Definition: saxreader.c:3547
static HRESULT WINAPI isaxdecl_attributeDecl(ISAXDeclHandler *iface, const WCHAR *pElementName, int nElementName, const WCHAR *pAttributeName, int nAttributeName, const WCHAR *pType, int nType, const WCHAR *pValueDefault, int nValueDefault, const WCHAR *pValue, int nValue)
Definition: saxreader.c:1868
static struct attribute_entry ch_attributes_no_prefix[]
Definition: saxreader.c:822
static HRESULT WINAPI isaxdecl_externalEntityDecl(ISAXDeclHandler *iface, const WCHAR *pName, int nName, const WCHAR *pPublicId, int nPublicId, const WCHAR *pSystemId, int nSystemId)
Definition: saxreader.c:1884
static HRESULT WINAPI isaxattributes_getURI(ISAXAttributes *iface, int nIndex, const WCHAR **pUrl, int *pUriSize)
Definition: saxreader.c:1502
static void test_saxreader_dispex(void)
Definition: saxreader.c:4592
static void test_mxwriter_dtd(void)
Definition: saxreader.c:4913
static const WCHAR szSimpleXML[]
Definition: saxreader.c:540
static struct attribute_entry ch_attributes2_6[]
Definition: saxreader.c:798
static struct call_entry read_test_seq[]
Definition: saxreader.c:1011
static const char test_attributes[]
Definition: saxreader.c:577
int msxml_version
Definition: saxreader.c:1039
static struct call_entry cdata_test2[]
Definition: saxreader.c:932
static void test_mxwriter_default_properties(const struct mxwriter_props_t *table)
Definition: saxreader.c:3038
static HRESULT WINAPI istream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
Definition: saxreader.c:1970
static void test_mxwriter_cdata(void)
Definition: saxreader.c:4752
static HRESULT WINAPI contentHandler_startDocument(ISAXContentHandler *iface)
Definition: saxreader.c:1132
static struct call_sequence * sequences[NUM_CALL_SEQUENCES]
Definition: saxreader.c:244
static struct attribute_entry ch_attributes_alt_4[]
Definition: saxreader.c:740
static HRESULT WINAPI istream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: saxreader.c:1995
static void compare_attributes(const struct call_entry *actual, const struct call_entry *expected, const char *context, BOOL todo, const char *file, int line, int *failcount)
Definition: saxreader.c:320
static void test_obj_dispex(IUnknown *obj)
Definition: saxreader.c:4537
static HRESULT WINAPI istream_Stat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag)
Definition: saxreader.c:2009
static const ISAXAttributesVtbl SAXAttributesVtbl
Definition: saxreader.c:1661
static HRESULT WINAPI isaxlexical_startCDATA(ISAXLexicalHandler *iface)
Definition: saxreader.c:1761
static HRESULT WINAPI isaxlexical_comment(ISAXLexicalHandler *iface, const WCHAR *pChars, int nChars)
Definition: saxreader.c:1783
static struct call_entry content_handler_test_attributes_alternate_4[]
Definition: saxreader.c:749
static void set_expected_seq(struct call_entry *expected)
Definition: saxreader.c:1041
static BOOL is_clsid_supported(const GUID *clsid, const struct msxmlsupported_data_t *table)
Definition: saxreader.c:70
static void test_mxattr_dispex(void)
Definition: saxreader.c:5542
static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl
Definition: saxreader.c:1892
static IStream instream
Definition: saxreader.c:2106
static const struct feature_ns_entry_t feature_ns_entry_data[]
Definition: saxreader.c:2781
static struct call_entry content_handler_test_attributes[]
Definition: saxreader.c:722
static const char testXML[]
Definition: saxreader.c:570
static ULONG WINAPI contentHandler_Release(ISAXContentHandler *iface)
Definition: saxreader.c:1079
static HRESULT WINAPI isaxlexical_startEntity(ISAXLexicalHandler *iface, const WCHAR *pName, int nName)
Definition: saxreader.c:1747
static HRESULT WINAPI isaxlexical_endEntity(ISAXLexicalHandler *iface, const WCHAR *pName, int nName)
Definition: saxreader.c:1754
static ISAXAttributes * test_attr_ptr
Definition: saxreader.c:1131
#define cmp(status, error)
Definition: error.c:114
static char * dest
Definition: rtl.c:135
static const WCHAR sysW[]
Definition: richole.c:40
static VARIANTARG static DISPID
Definition: ordinal.c:52
const char * uri
Definition: sec_mgr.c:1588
REFCLSID clsid
Definition: msctf.c:82
#define DISPID_SAX_XMLREADER_GETFEATURE
Definition: msxml2did.h:342
#define DISPID_SAX_XMLREADER_CONTENTHANDLER
Definition: msxml2did.h:347
const struct _GUID CLSID_DOMDocument
static const WCHAR utf16W[]
Definition: mxwriter.c:85
unsigned int UINT
Definition: ndis.h:50
#define GENERIC_WRITE
Definition: nt_native.h:90
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_BSTRREF(A)
Definition: oleauto.h:227
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008
#define V_VARIANTREF(A)
Definition: oleauto.h:283
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_DISPATCH(A)
Definition: oleauto.h:239
#define DISPATCH_PROPERTYPUTREF
Definition: oleauto.h:1009
long LONG
Definition: pedump.c:60
const GUID IID_IPersistStream
Definition: proxy.cpp:13
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define IID_NULL
Definition: guiddef.h:98
static FILE * out
Definition: regtests2xml.c:44
#define test
Definition: rosglue.h:37
const WCHAR * str
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
#define win_skip
Definition: test.h:160
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
const CLSID * clsid
Definition: saxreader.c:5198
const char * qname
Definition: saxreader.c:5201
const char * value
Definition: saxreader.c:5203
const char * type
Definition: saxreader.c:5202
const char * local
Definition: saxreader.c:5200
const char * uri
Definition: saxreader.c:5199
Definition: cookie.c:202
Definition: saxreader.c:203
const char * value
Definition: saxreader.c:207
BSTR qnameW
Definition: saxreader.c:212
BSTR valueW
Definition: saxreader.c:213
const char * uri
Definition: saxreader.c:204
const char * local
Definition: saxreader.c:205
BSTR localW
Definition: saxreader.c:211
const char * qname
Definition: saxreader.c:206
BSTR uriW
Definition: saxreader.c:210
Definition: saxreader.c:216
BSTR arg3W
Definition: saxreader.c:232
int column
Definition: saxreader.c:219
CH id
Definition: saxreader.c:217
const char * arg2
Definition: saxreader.c:222
const char * arg1
Definition: saxreader.c:221
BSTR arg1W
Definition: saxreader.c:230
int attr_count
Definition: saxreader.c:227
BSTR arg2W
Definition: saxreader.c:231
HRESULT ret
Definition: saxreader.c:220
const char * arg3
Definition: saxreader.c:223
int line
Definition: saxreader.c:218
struct attribute_entry * attributes
Definition: saxreader.c:226
struct call_entry * sequence
Definition: saxreader.c:239
Definition: http.c:7252
Definition: saxreader.c:2889
const char * data
Definition: saxreader.c:2892
HRESULT hr
Definition: saxreader.c:2893
const GUID * guid
Definition: saxreader.c:2890
BOOL todo
Definition: saxreader.c:2894
const char * clsid
Definition: saxreader.c:2891
Definition: saxreader.c:2774
VARIANT_BOOL value2
Definition: saxreader.c:2778
VARIANT_BOOL value
Definition: saxreader.c:2777
const GUID * guid
Definition: saxreader.c:2775
const char * clsid
Definition: saxreader.c:2776
Definition: fci.c:127
Definition: parser.c:49
Definition: tftpd.h:60
BOOL supported[3]
Definition: domdoc.c:59
const char * name
Definition: domdoc.c:57
const GUID * clsid
Definition: domdoc.c:56
VARIANT_BOOL omitdecl
Definition: saxreader.c:3024
VARIANT_BOOL disable_escape
Definition: saxreader.c:3022
const char * encoding
Definition: saxreader.c:3026
VARIANT_BOOL indent
Definition: saxreader.c:3023
VARIANT_BOOL bom
Definition: saxreader.c:3021
const GUID * clsid
Definition: saxreader.c:3020
VARIANT_BOOL standalone
Definition: saxreader.c:3025
mxwriter_write_test expected_writes[4]
Definition: saxreader.c:1921
const char * encoding
Definition: saxreader.c:1920
const BYTE * data
Definition: saxreader.c:1912
Definition: name.c:39
Definition: reader.h:84
Definition: send.c:48
ISAXDeclHandler ISAXDeclHandler_iface
Definition: saxreader.c:1813
HRESULT qi_hr
Definition: saxreader.c:1816
ISAXLexicalHandler ISAXLexicalHandler_iface
Definition: saxreader.c:1685
const char * prop_name
Definition: saxreader.c:2559
Definition: parse.h:23
const WCHAR * name
BYTE * data
const char * output
Definition: saxreader.c:3961
const GUID * clsid
Definition: saxreader.c:3959
const char * data
Definition: saxreader.c:3960
const char * local_name
Definition: saxreader.c:3536
ISAXAttributes * attr
Definition: saxreader.c:3540
enum startendtype type
Definition: saxreader.c:3534
static const WCHAR starW[]
Definition: symbol.c:41
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:94
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
static const WCHAR props[]
Definition: wbemdisp.c:288
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_POINTER
Definition: winerror.h:2365
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
static char * encoding
Definition: xmllint.c:155
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193