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