2 * MXWriter implementation
4 * Copyright 2011-2012 Nikolay Sivov for CodeWeavers
5 * Copyright 2011 Thomas Mullaly
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 # include <libxml/parser.h>
36 #include "wine/debug.h"
38 #include "msxml_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
42 static const WCHAR emptyW
[] = {0};
43 static const WCHAR spaceW
[] = {' '};
44 static const WCHAR quotW
[] = {'\"'};
45 static const WCHAR closetagW
[] = {'>','\r','\n'};
47 /* should be ordered as encoding names are sorted */
50 XmlEncoding_ISO_8859_1
= 0,
51 XmlEncoding_ISO_8859_13
,
52 XmlEncoding_ISO_8859_15
,
53 XmlEncoding_ISO_8859_2
,
54 XmlEncoding_ISO_8859_3
,
55 XmlEncoding_ISO_8859_4
,
56 XmlEncoding_ISO_8859_5
,
57 XmlEncoding_ISO_8859_7
,
58 XmlEncoding_ISO_8859_9
,
64 struct xml_encoding_data
66 const WCHAR
*encoding
;
71 static const WCHAR iso_8859_1W
[] = {'i','s','o','-','8','8','5','9','-','1',0};
72 static const WCHAR iso_8859_2W
[] = {'i','s','o','-','8','8','5','9','-','2',0};
73 static const WCHAR iso_8859_3W
[] = {'i','s','o','-','8','8','5','9','-','3',0};
74 static const WCHAR iso_8859_4W
[] = {'i','s','o','-','8','8','5','9','-','4',0};
75 static const WCHAR iso_8859_5W
[] = {'i','s','o','-','8','8','5','9','-','5',0};
76 static const WCHAR iso_8859_7W
[] = {'i','s','o','-','8','8','5','9','-','7',0};
77 static const WCHAR iso_8859_9W
[] = {'i','s','o','-','8','8','5','9','-','9',0};
78 static const WCHAR iso_8859_13W
[] = {'i','s','o','-','8','8','5','9','-','1','3',0};
79 static const WCHAR iso_8859_15W
[] = {'i','s','o','-','8','8','5','9','-','1','5',0};
80 static const WCHAR utf16W
[] = {'U','T','F','-','1','6',0};
81 static const WCHAR utf8W
[] = {'U','T','F','-','8',0};
83 static const struct xml_encoding_data xml_encoding_map
[] = {
84 { iso_8859_1W
, XmlEncoding_ISO_8859_1
, 28591 },
85 { iso_8859_13W
, XmlEncoding_ISO_8859_13
, 28603 },
86 { iso_8859_15W
, XmlEncoding_ISO_8859_15
, 28605 },
87 { iso_8859_2W
, XmlEncoding_ISO_8859_2
, 28592 },
88 { iso_8859_3W
, XmlEncoding_ISO_8859_3
, 28593 },
89 { iso_8859_4W
, XmlEncoding_ISO_8859_4
, 28594 },
90 { iso_8859_5W
, XmlEncoding_ISO_8859_5
, 28595 },
91 { iso_8859_7W
, XmlEncoding_ISO_8859_7
, 28597 },
92 { iso_8859_9W
, XmlEncoding_ISO_8859_9
, 28599 },
93 { utf16W
, XmlEncoding_UTF16
, ~0 },
94 { utf8W
, XmlEncoding_UTF8
, CP_UTF8
}
99 OutputBuffer_Native
= 0x001,
100 OutputBuffer_Encoded
= 0x010,
101 OutputBuffer_Both
= 0x100
107 MXWriter_DisableEscaping
,
109 MXWriter_OmitXmlDecl
,
123 unsigned int allocated
;
124 unsigned int written
;
129 encoded_buffer utf16
;
130 encoded_buffer encoded
;
137 IMXWriter IMXWriter_iface
;
138 ISAXContentHandler ISAXContentHandler_iface
;
139 ISAXLexicalHandler ISAXLexicalHandler_iface
;
140 ISAXDeclHandler ISAXDeclHandler_iface
;
143 MSXML_VERSION class_version
;
145 VARIANT_BOOL props
[MXWriter_LastProp
];
151 BSTR encoding
; /* exact property value */
152 xml_encoding xml_enc
;
154 /* contains a pending (or not closed yet) element name or NULL if
155 we don't have to close */
161 output_buffer
*buffer
;
176 IMXAttributes IMXAttributes_iface
;
177 ISAXAttributes ISAXAttributes_iface
;
178 IVBSAXAttributes IVBSAXAttributes_iface
;
181 MSXML_VERSION class_version
;
188 static inline mxattributes
*impl_from_IMXAttributes( IMXAttributes
*iface
)
190 return CONTAINING_RECORD(iface
, mxattributes
, IMXAttributes_iface
);
193 static inline mxattributes
*impl_from_ISAXAttributes( ISAXAttributes
*iface
)
195 return CONTAINING_RECORD(iface
, mxattributes
, ISAXAttributes_iface
);
198 static inline mxattributes
*impl_from_IVBSAXAttributes( IVBSAXAttributes
*iface
)
200 return CONTAINING_RECORD(iface
, mxattributes
, IVBSAXAttributes_iface
);
203 static HRESULT
mxattributes_grow(mxattributes
*This
)
205 if (This
->length
< This
->allocated
) return S_OK
;
207 This
->allocated
*= 2;
208 This
->attr
= heap_realloc(This
->attr
, This
->allocated
*sizeof(mxattribute
));
210 return This
->attr
? S_OK
: E_OUTOFMEMORY
;
213 static xml_encoding
parse_encoding_name(const WCHAR
*encoding
)
218 max
= sizeof(xml_encoding_map
)/sizeof(struct xml_encoding_data
) - 1;
224 c
= strcmpiW(xml_encoding_map
[n
].encoding
, encoding
);
226 return xml_encoding_map
[n
].enc
;
234 return XmlEncoding_Unknown
;
237 static HRESULT
init_encoded_buffer(encoded_buffer
*buffer
)
239 const int initial_len
= 0x2000;
240 buffer
->data
= heap_alloc(initial_len
);
241 if (!buffer
->data
) return E_OUTOFMEMORY
;
243 memset(buffer
->data
, 0, 4);
244 buffer
->allocated
= initial_len
;
250 static void free_encoded_buffer(encoded_buffer
*buffer
)
252 heap_free(buffer
->data
);
255 static HRESULT
get_code_page(xml_encoding encoding
, UINT
*cp
)
257 const struct xml_encoding_data
*data
;
259 if (encoding
== XmlEncoding_Unknown
)
261 FIXME("unsupported encoding %d\n", encoding
);
265 data
= &xml_encoding_map
[encoding
];
271 static HRESULT
alloc_output_buffer(xml_encoding encoding
, output_buffer
**buffer
)
276 ret
= heap_alloc(sizeof(*ret
));
277 if (!ret
) return E_OUTOFMEMORY
;
279 hr
= get_code_page(encoding
, &ret
->code_page
);
285 hr
= init_encoded_buffer(&ret
->utf16
);
291 if (ret
->code_page
== CP_UTF8
) {
292 hr
= init_encoded_buffer(&ret
->encoded
);
294 free_encoded_buffer(&ret
->utf16
);
300 memset(&ret
->encoded
, 0, sizeof(ret
->encoded
));
307 static void free_output_buffer(output_buffer
*buffer
)
309 free_encoded_buffer(&buffer
->encoded
);
310 free_encoded_buffer(&buffer
->utf16
);
314 static void grow_buffer(encoded_buffer
*buffer
, int length
)
316 /* grow if needed, plus 4 bytes to be sure null terminator will fit in */
317 if (buffer
->allocated
< buffer
->written
+ length
+ 4)
319 int grown_size
= max(2*buffer
->allocated
, buffer
->allocated
+ length
);
320 buffer
->data
= heap_realloc(buffer
->data
, grown_size
);
321 buffer
->allocated
= grown_size
;
325 static HRESULT
write_output_buffer_mode(output_buffer
*buffer
, output_mode mode
, const WCHAR
*data
, int len
)
330 if (mode
& (OutputBuffer_Encoded
| OutputBuffer_Both
)) {
331 if (buffer
->code_page
!= ~0)
333 length
= WideCharToMultiByte(buffer
->code_page
, 0, data
, len
, NULL
, 0, NULL
, NULL
);
334 grow_buffer(&buffer
->encoded
, length
);
335 ptr
= buffer
->encoded
.data
+ buffer
->encoded
.written
;
336 length
= WideCharToMultiByte(buffer
->code_page
, 0, data
, len
, ptr
, length
, NULL
, NULL
);
337 buffer
->encoded
.written
+= len
== -1 ? length
-1 : length
;
341 if (mode
& (OutputBuffer_Native
| OutputBuffer_Both
)) {
342 /* WCHAR data just copied */
343 length
= len
== -1 ? strlenW(data
) : len
;
346 length
*= sizeof(WCHAR
);
348 grow_buffer(&buffer
->utf16
, length
);
349 ptr
= buffer
->utf16
.data
+ buffer
->utf16
.written
;
351 memcpy(ptr
, data
, length
);
352 buffer
->utf16
.written
+= length
;
354 /* null termination */
355 memset(ptr
, 0, sizeof(WCHAR
));
362 static HRESULT
write_output_buffer(output_buffer
*buffer
, const WCHAR
*data
, int len
)
364 return write_output_buffer_mode(buffer
, OutputBuffer_Both
, data
, len
);
367 static HRESULT
write_output_buffer_quoted(output_buffer
*buffer
, const WCHAR
*data
, int len
)
369 write_output_buffer(buffer
, quotW
, 1);
370 write_output_buffer(buffer
, data
, len
);
371 write_output_buffer(buffer
, quotW
, 1);
376 /* frees buffer data, reallocates with a default lengths */
377 static void close_output_buffer(mxwriter
*This
)
379 heap_free(This
->buffer
->utf16
.data
);
380 heap_free(This
->buffer
->encoded
.data
);
381 init_encoded_buffer(&This
->buffer
->utf16
);
382 init_encoded_buffer(&This
->buffer
->encoded
);
383 get_code_page(This
->xml_enc
, &This
->buffer
->code_page
);
386 /* escapes special characters like:
392 static WCHAR
*get_escaped_string(const WCHAR
*str
, escape_mode mode
, int *len
)
394 static const WCHAR ltW
[] = {'&','l','t',';'};
395 static const WCHAR ampW
[] = {'&','a','m','p',';'};
396 static const WCHAR equotW
[] = {'&','q','u','o','t',';'};
397 static const WCHAR gtW
[] = {'&','g','t',';'};
399 const int default_alloc
= 100;
400 const int grow_thresh
= 10;
401 int p
= *len
, conv_len
;
404 /* default buffer size to something if length is unknown */
405 conv_len
= *len
== -1 ? default_alloc
: max(2**len
, default_alloc
);
406 ptr
= ret
= heap_alloc(conv_len
*sizeof(WCHAR
));
410 if (ptr
- ret
> conv_len
- grow_thresh
)
412 int written
= ptr
- ret
;
414 ptr
= ret
= heap_realloc(ret
, conv_len
*sizeof(WCHAR
));
421 memcpy(ptr
, ltW
, sizeof(ltW
));
422 ptr
+= sizeof(ltW
)/sizeof(WCHAR
);
425 memcpy(ptr
, ampW
, sizeof(ampW
));
426 ptr
+= sizeof(ampW
)/sizeof(WCHAR
);
429 memcpy(ptr
, gtW
, sizeof(gtW
));
430 ptr
+= sizeof(gtW
)/sizeof(WCHAR
);
433 if (mode
== EscapeValue
)
435 memcpy(ptr
, equotW
, sizeof(equotW
));
436 ptr
+= sizeof(equotW
)/sizeof(WCHAR
);
439 /* fallthrough for text mode */
449 if (*len
!= -1) *len
= ptr
-ret
;
455 static void write_prolog_buffer(const mxwriter
*This
)
457 static const WCHAR versionW
[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','='};
458 static const WCHAR encodingW
[] = {' ','e','n','c','o','d','i','n','g','=','\"'};
459 static const WCHAR standaloneW
[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
460 static const WCHAR yesW
[] = {'y','e','s','\"','?','>'};
461 static const WCHAR noW
[] = {'n','o','\"','?','>'};
462 static const WCHAR crlfW
[] = {'\r','\n'};
465 write_output_buffer(This
->buffer
, versionW
, sizeof(versionW
)/sizeof(WCHAR
));
466 write_output_buffer_quoted(This
->buffer
, This
->version
, -1);
469 write_output_buffer(This
->buffer
, encodingW
, sizeof(encodingW
)/sizeof(WCHAR
));
471 /* always write UTF-16 to WCHAR buffer */
472 write_output_buffer_mode(This
->buffer
, OutputBuffer_Native
, utf16W
, sizeof(utf16W
)/sizeof(WCHAR
) - 1);
473 write_output_buffer_mode(This
->buffer
, OutputBuffer_Encoded
, This
->encoding
, -1);
474 write_output_buffer(This
->buffer
, quotW
, 1);
477 write_output_buffer(This
->buffer
, standaloneW
, sizeof(standaloneW
)/sizeof(WCHAR
));
478 if (This
->props
[MXWriter_Standalone
] == VARIANT_TRUE
)
479 write_output_buffer(This
->buffer
, yesW
, sizeof(yesW
)/sizeof(WCHAR
));
481 write_output_buffer(This
->buffer
, noW
, sizeof(noW
)/sizeof(WCHAR
));
483 write_output_buffer(This
->buffer
, crlfW
, sizeof(crlfW
)/sizeof(WCHAR
));
486 /* Attempts to the write data from the mxwriter's buffer to
487 * the destination stream (if there is one).
489 static HRESULT
write_data_to_stream(mxwriter
*This
)
491 encoded_buffer
*buffer
;
498 if (This
->xml_enc
!= XmlEncoding_UTF16
)
499 buffer
= &This
->buffer
->encoded
;
501 buffer
= &This
->buffer
->utf16
;
503 if (This
->dest_written
> buffer
->written
) {
504 ERR("Failed sanity check! Not sure what to do... (%d > %d)\n", This
->dest_written
, buffer
->written
);
506 } else if (This
->dest_written
== buffer
->written
&& This
->xml_enc
!= XmlEncoding_UTF8
)
507 /* Windows seems to make an empty write call when the encoding is UTF-8 and
508 * all the data has been written to the stream. It doesn't seem make this call
509 * for any other encodings.
513 /* Write the current content from the output buffer into 'dest'.
514 * TODO: Check what Windows does if the IStream doesn't write all of
515 * the data we give it at once.
517 hr
= IStream_Write(This
->dest
, buffer
->data
+This
->dest_written
,
518 buffer
->written
-This
->dest_written
, &written
);
520 WARN("Failed to write data to IStream (0x%08x)\n", hr
);
524 This
->dest_written
+= written
;
528 /* Newly added element start tag left unclosed cause for empty elements
529 we have to close it differently. */
530 static void close_element_starttag(const mxwriter
*This
)
532 static const WCHAR gtW
[] = {'>'};
533 if (!This
->element
) return;
534 write_output_buffer(This
->buffer
, gtW
, 1);
537 static void set_element_name(mxwriter
*This
, const WCHAR
*name
, int len
)
539 SysFreeString(This
->element
);
541 This
->element
= len
!= -1 ? SysAllocStringLen(name
, len
) : SysAllocString(name
);
543 This
->element
= NULL
;
546 static inline HRESULT
flush_output_buffer(mxwriter
*This
)
548 close_element_starttag(This
);
549 set_element_name(This
, NULL
, 0);
551 return write_data_to_stream(This
);
554 /* Resets the mxwriter's output buffer by closing it, then creating a new
555 * output buffer using the given encoding.
557 static inline void reset_output_buffer(mxwriter
*This
)
559 close_output_buffer(This
);
560 This
->dest_written
= 0;
563 static HRESULT
writer_set_property(mxwriter
*writer
, mxwriter_prop property
, VARIANT_BOOL value
)
565 writer
->props
[property
] = value
;
566 writer
->prop_changed
= TRUE
;
570 static HRESULT
writer_get_property(const mxwriter
*writer
, mxwriter_prop property
, VARIANT_BOOL
*value
)
572 if (!value
) return E_POINTER
;
573 *value
= writer
->props
[property
];
577 static inline mxwriter
*impl_from_IMXWriter(IMXWriter
*iface
)
579 return CONTAINING_RECORD(iface
, mxwriter
, IMXWriter_iface
);
582 static inline mxwriter
*impl_from_ISAXContentHandler(ISAXContentHandler
*iface
)
584 return CONTAINING_RECORD(iface
, mxwriter
, ISAXContentHandler_iface
);
587 static inline mxwriter
*impl_from_ISAXLexicalHandler(ISAXLexicalHandler
*iface
)
589 return CONTAINING_RECORD(iface
, mxwriter
, ISAXLexicalHandler_iface
);
592 static inline mxwriter
*impl_from_ISAXDeclHandler(ISAXDeclHandler
*iface
)
594 return CONTAINING_RECORD(iface
, mxwriter
, ISAXDeclHandler_iface
);
597 static HRESULT WINAPI
mxwriter_QueryInterface(IMXWriter
*iface
, REFIID riid
, void **obj
)
599 mxwriter
*This
= impl_from_IMXWriter( iface
);
601 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
605 if ( IsEqualGUID( riid
, &IID_IMXWriter
) ||
606 IsEqualGUID( riid
, &IID_IDispatch
) ||
607 IsEqualGUID( riid
, &IID_IUnknown
) )
609 *obj
= &This
->IMXWriter_iface
;
611 else if ( IsEqualGUID( riid
, &IID_ISAXContentHandler
) )
613 *obj
= &This
->ISAXContentHandler_iface
;
615 else if ( IsEqualGUID( riid
, &IID_ISAXLexicalHandler
) )
617 *obj
= &This
->ISAXLexicalHandler_iface
;
619 else if ( IsEqualGUID( riid
, &IID_ISAXDeclHandler
) )
621 *obj
= &This
->ISAXDeclHandler_iface
;
623 else if (dispex_query_interface(&This
->dispex
, riid
, obj
))
625 return *obj
? S_OK
: E_NOINTERFACE
;
629 ERR("interface %s not implemented\n", debugstr_guid(riid
));
631 return E_NOINTERFACE
;
634 IMXWriter_AddRef(iface
);
638 static ULONG WINAPI
mxwriter_AddRef(IMXWriter
*iface
)
640 mxwriter
*This
= impl_from_IMXWriter( iface
);
641 LONG ref
= InterlockedIncrement(&This
->ref
);
643 TRACE("(%p)->(%d)\n", This
, ref
);
648 static ULONG WINAPI
mxwriter_Release(IMXWriter
*iface
)
650 mxwriter
*This
= impl_from_IMXWriter( iface
);
651 ULONG ref
= InterlockedDecrement(&This
->ref
);
653 TRACE("(%p)->(%d)\n", This
, ref
);
657 /* Windows flushes the buffer when the interface is destroyed. */
658 flush_output_buffer(This
);
659 free_output_buffer(This
->buffer
);
661 if (This
->dest
) IStream_Release(This
->dest
);
662 SysFreeString(This
->version
);
663 SysFreeString(This
->encoding
);
665 SysFreeString(This
->element
);
666 release_dispex(&This
->dispex
);
673 static HRESULT WINAPI
mxwriter_GetTypeInfoCount(IMXWriter
*iface
, UINT
* pctinfo
)
675 mxwriter
*This
= impl_from_IMXWriter( iface
);
676 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
679 static HRESULT WINAPI
mxwriter_GetTypeInfo(
681 UINT iTInfo
, LCID lcid
,
682 ITypeInfo
** ppTInfo
)
684 mxwriter
*This
= impl_from_IMXWriter( iface
);
685 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
686 iTInfo
, lcid
, ppTInfo
);
689 static HRESULT WINAPI
mxwriter_GetIDsOfNames(
691 REFIID riid
, LPOLESTR
* rgszNames
,
692 UINT cNames
, LCID lcid
, DISPID
* rgDispId
)
694 mxwriter
*This
= impl_from_IMXWriter( iface
);
695 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
696 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
699 static HRESULT WINAPI
mxwriter_Invoke(
701 DISPID dispIdMember
, REFIID riid
, LCID lcid
,
702 WORD wFlags
, DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
703 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
705 mxwriter
*This
= impl_from_IMXWriter( iface
);
706 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
707 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
710 static HRESULT WINAPI
mxwriter_put_output(IMXWriter
*iface
, VARIANT dest
)
712 mxwriter
*This
= impl_from_IMXWriter( iface
);
715 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&dest
));
717 hr
= flush_output_buffer(This
);
725 if (This
->dest
) IStream_Release(This
->dest
);
727 reset_output_buffer(This
);
734 hr
= IUnknown_QueryInterface(V_UNKNOWN(&dest
), &IID_IStream
, (void**)&stream
);
737 /* Recreate the output buffer to make sure it's using the correct encoding. */
738 reset_output_buffer(This
);
740 if (This
->dest
) IStream_Release(This
->dest
);
745 FIXME("unhandled interface type for VT_UNKNOWN destination\n");
749 FIXME("unhandled destination type %s\n", debugstr_variant(&dest
));
756 static HRESULT WINAPI
mxwriter_get_output(IMXWriter
*iface
, VARIANT
*dest
)
758 mxwriter
*This
= impl_from_IMXWriter( iface
);
760 TRACE("(%p)->(%p)\n", This
, dest
);
762 if (!dest
) return E_POINTER
;
766 HRESULT hr
= flush_output_buffer(This
);
770 V_VT(dest
) = VT_BSTR
;
771 V_BSTR(dest
) = SysAllocString((WCHAR
*)This
->buffer
->utf16
.data
);
776 /* we only support IStream output so far */
777 V_VT(dest
) = VT_UNKNOWN
;
778 V_UNKNOWN(dest
) = (IUnknown
*)This
->dest
;
779 IStream_AddRef(This
->dest
);
784 static HRESULT WINAPI
mxwriter_put_encoding(IMXWriter
*iface
, BSTR encoding
)
786 mxwriter
*This
= impl_from_IMXWriter( iface
);
790 TRACE("(%p)->(%s)\n", This
, debugstr_w(encoding
));
792 enc
= parse_encoding_name(encoding
);
793 if (enc
== XmlEncoding_Unknown
)
795 FIXME("unsupported encoding %s\n", debugstr_w(encoding
));
799 hr
= flush_output_buffer(This
);
803 SysReAllocString(&This
->encoding
, encoding
);
806 TRACE("got encoding %d\n", This
->xml_enc
);
807 reset_output_buffer(This
);
811 static HRESULT WINAPI
mxwriter_get_encoding(IMXWriter
*iface
, BSTR
*encoding
)
813 mxwriter
*This
= impl_from_IMXWriter( iface
);
815 TRACE("(%p)->(%p)\n", This
, encoding
);
817 if (!encoding
) return E_POINTER
;
819 *encoding
= SysAllocString(This
->encoding
);
820 if (!*encoding
) return E_OUTOFMEMORY
;
825 static HRESULT WINAPI
mxwriter_put_byteOrderMark(IMXWriter
*iface
, VARIANT_BOOL value
)
827 mxwriter
*This
= impl_from_IMXWriter( iface
);
829 TRACE("(%p)->(%d)\n", This
, value
);
830 return writer_set_property(This
, MXWriter_BOM
, value
);
833 static HRESULT WINAPI
mxwriter_get_byteOrderMark(IMXWriter
*iface
, VARIANT_BOOL
*value
)
835 mxwriter
*This
= impl_from_IMXWriter( iface
);
837 TRACE("(%p)->(%p)\n", This
, value
);
838 return writer_get_property(This
, MXWriter_BOM
, value
);
841 static HRESULT WINAPI
mxwriter_put_indent(IMXWriter
*iface
, VARIANT_BOOL value
)
843 mxwriter
*This
= impl_from_IMXWriter( iface
);
845 TRACE("(%p)->(%d)\n", This
, value
);
846 return writer_set_property(This
, MXWriter_Indent
, value
);
849 static HRESULT WINAPI
mxwriter_get_indent(IMXWriter
*iface
, VARIANT_BOOL
*value
)
851 mxwriter
*This
= impl_from_IMXWriter( iface
);
853 TRACE("(%p)->(%p)\n", This
, value
);
854 return writer_get_property(This
, MXWriter_Indent
, value
);
857 static HRESULT WINAPI
mxwriter_put_standalone(IMXWriter
*iface
, VARIANT_BOOL value
)
859 mxwriter
*This
= impl_from_IMXWriter( iface
);
861 TRACE("(%p)->(%d)\n", This
, value
);
862 return writer_set_property(This
, MXWriter_Standalone
, value
);
865 static HRESULT WINAPI
mxwriter_get_standalone(IMXWriter
*iface
, VARIANT_BOOL
*value
)
867 mxwriter
*This
= impl_from_IMXWriter( iface
);
869 TRACE("(%p)->(%p)\n", This
, value
);
870 return writer_get_property(This
, MXWriter_Standalone
, value
);
873 static HRESULT WINAPI
mxwriter_put_omitXMLDeclaration(IMXWriter
*iface
, VARIANT_BOOL value
)
875 mxwriter
*This
= impl_from_IMXWriter( iface
);
877 TRACE("(%p)->(%d)\n", This
, value
);
878 return writer_set_property(This
, MXWriter_OmitXmlDecl
, value
);
881 static HRESULT WINAPI
mxwriter_get_omitXMLDeclaration(IMXWriter
*iface
, VARIANT_BOOL
*value
)
883 mxwriter
*This
= impl_from_IMXWriter( iface
);
885 TRACE("(%p)->(%p)\n", This
, value
);
886 return writer_get_property(This
, MXWriter_OmitXmlDecl
, value
);
889 static HRESULT WINAPI
mxwriter_put_version(IMXWriter
*iface
, BSTR version
)
891 mxwriter
*This
= impl_from_IMXWriter( iface
);
893 TRACE("(%p)->(%s)\n", This
, debugstr_w(version
));
895 if (!version
) return E_INVALIDARG
;
897 SysFreeString(This
->version
);
898 This
->version
= SysAllocString(version
);
903 static HRESULT WINAPI
mxwriter_get_version(IMXWriter
*iface
, BSTR
*version
)
905 mxwriter
*This
= impl_from_IMXWriter( iface
);
907 TRACE("(%p)->(%p)\n", This
, version
);
909 if (!version
) return E_POINTER
;
911 return return_bstr(This
->version
, version
);
914 static HRESULT WINAPI
mxwriter_put_disableOutputEscaping(IMXWriter
*iface
, VARIANT_BOOL value
)
916 mxwriter
*This
= impl_from_IMXWriter( iface
);
918 TRACE("(%p)->(%d)\n", This
, value
);
919 return writer_set_property(This
, MXWriter_DisableEscaping
, value
);
922 static HRESULT WINAPI
mxwriter_get_disableOutputEscaping(IMXWriter
*iface
, VARIANT_BOOL
*value
)
924 mxwriter
*This
= impl_from_IMXWriter( iface
);
926 TRACE("(%p)->(%p)\n", This
, value
);
927 return writer_get_property(This
, MXWriter_DisableEscaping
, value
);
930 static HRESULT WINAPI
mxwriter_flush(IMXWriter
*iface
)
932 mxwriter
*This
= impl_from_IMXWriter( iface
);
933 TRACE("(%p)\n", This
);
934 return flush_output_buffer(This
);
937 static const struct IMXWriterVtbl MXWriterVtbl
=
939 mxwriter_QueryInterface
,
942 mxwriter_GetTypeInfoCount
,
943 mxwriter_GetTypeInfo
,
944 mxwriter_GetIDsOfNames
,
948 mxwriter_put_encoding
,
949 mxwriter_get_encoding
,
950 mxwriter_put_byteOrderMark
,
951 mxwriter_get_byteOrderMark
,
954 mxwriter_put_standalone
,
955 mxwriter_get_standalone
,
956 mxwriter_put_omitXMLDeclaration
,
957 mxwriter_get_omitXMLDeclaration
,
958 mxwriter_put_version
,
959 mxwriter_get_version
,
960 mxwriter_put_disableOutputEscaping
,
961 mxwriter_get_disableOutputEscaping
,
965 /*** ISAXContentHandler ***/
966 static HRESULT WINAPI
SAXContentHandler_QueryInterface(
967 ISAXContentHandler
*iface
,
971 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
972 return IMXWriter_QueryInterface(&This
->IMXWriter_iface
, riid
, obj
);
975 static ULONG WINAPI
SAXContentHandler_AddRef(ISAXContentHandler
*iface
)
977 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
978 return IMXWriter_AddRef(&This
->IMXWriter_iface
);
981 static ULONG WINAPI
SAXContentHandler_Release(ISAXContentHandler
*iface
)
983 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
984 return IMXWriter_Release(&This
->IMXWriter_iface
);
987 static HRESULT WINAPI
SAXContentHandler_putDocumentLocator(
988 ISAXContentHandler
*iface
,
989 ISAXLocator
*locator
)
991 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
992 FIXME("(%p)->(%p)\n", This
, locator
);
996 static HRESULT WINAPI
SAXContentHandler_startDocument(ISAXContentHandler
*iface
)
998 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1000 TRACE("(%p)\n", This
);
1002 /* If properties have been changed since the last "endDocument" call
1003 * we need to reset the output buffer. If we don't the output buffer
1004 * could end up with multiple XML documents in it, plus this seems to
1005 * be how Windows works.
1007 if (This
->prop_changed
) {
1008 reset_output_buffer(This
);
1009 This
->prop_changed
= FALSE
;
1012 if (This
->props
[MXWriter_OmitXmlDecl
] == VARIANT_TRUE
) return S_OK
;
1014 write_prolog_buffer(This
);
1016 if (This
->dest
&& This
->xml_enc
== XmlEncoding_UTF16
) {
1017 static const char utf16BOM
[] = {0xff,0xfe};
1019 if (This
->props
[MXWriter_BOM
] == VARIANT_TRUE
)
1020 /* Windows passes a NULL pointer as the pcbWritten parameter and
1021 * ignores any error codes returned from this Write call.
1023 IStream_Write(This
->dest
, utf16BOM
, sizeof(utf16BOM
), NULL
);
1029 static HRESULT WINAPI
SAXContentHandler_endDocument(ISAXContentHandler
*iface
)
1031 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1032 TRACE("(%p)\n", This
);
1033 This
->prop_changed
= FALSE
;
1034 return flush_output_buffer(This
);
1037 static HRESULT WINAPI
SAXContentHandler_startPrefixMapping(
1038 ISAXContentHandler
*iface
,
1039 const WCHAR
*prefix
,
1044 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1045 FIXME("(%p)->(%s %s)\n", This
, debugstr_wn(prefix
, nprefix
), debugstr_wn(uri
, nuri
));
1049 static HRESULT WINAPI
SAXContentHandler_endPrefixMapping(
1050 ISAXContentHandler
*iface
,
1051 const WCHAR
*prefix
,
1054 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1055 FIXME("(%p)->(%s)\n", This
, debugstr_wn(prefix
, nprefix
));
1059 static HRESULT WINAPI
SAXContentHandler_startElement(
1060 ISAXContentHandler
*iface
,
1061 const WCHAR
*namespaceUri
,
1063 const WCHAR
*local_name
,
1067 ISAXAttributes
*attr
)
1069 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1070 static const WCHAR ltW
[] = {'<'};
1072 TRACE("(%p)->(%s %s %s %p)\n", This
, debugstr_wn(namespaceUri
, nnamespaceUri
),
1073 debugstr_wn(local_name
, nlocal_name
), debugstr_wn(QName
, nQName
), attr
);
1075 if (((!namespaceUri
|| !local_name
|| !QName
) && This
->class_version
!= MSXML6
) ||
1076 (nQName
== -1 && This
->class_version
== MSXML6
))
1077 return E_INVALIDARG
;
1079 close_element_starttag(This
);
1080 set_element_name(This
, QName
? QName
: emptyW
,
1081 QName
? nQName
: 0);
1083 write_output_buffer(This
->buffer
, ltW
, 1);
1084 write_output_buffer(This
->buffer
, QName
, nQName
);
1088 int length
, i
, escape
;
1091 hr
= ISAXAttributes_getLength(attr
, &length
);
1092 if (FAILED(hr
)) return hr
;
1094 escape
= This
->props
[MXWriter_DisableEscaping
] == VARIANT_FALSE
||
1095 (This
->class_version
== MSXML4
|| This
->class_version
== MSXML6
);
1097 for (i
= 0; i
< length
; i
++)
1099 static const WCHAR eqW
[] = {'='};
1103 hr
= ISAXAttributes_getQName(attr
, i
, &str
, &len
);
1104 if (FAILED(hr
)) return hr
;
1106 /* space separator in front of every attribute */
1107 write_output_buffer(This
->buffer
, spaceW
, 1);
1108 write_output_buffer(This
->buffer
, str
, len
);
1110 write_output_buffer(This
->buffer
, eqW
, 1);
1113 hr
= ISAXAttributes_getValue(attr
, i
, &str
, &len
);
1114 if (FAILED(hr
)) return hr
;
1118 WCHAR
*escaped
= get_escaped_string(str
, EscapeValue
, &len
);
1119 write_output_buffer_quoted(This
->buffer
, escaped
, len
);
1123 write_output_buffer_quoted(This
->buffer
, str
, len
);
1130 static HRESULT WINAPI
SAXContentHandler_endElement(
1131 ISAXContentHandler
*iface
,
1132 const WCHAR
*namespaceUri
,
1134 const WCHAR
* local_name
,
1139 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1141 TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This
, debugstr_wn(namespaceUri
, nnamespaceUri
), nnamespaceUri
,
1142 debugstr_wn(local_name
, nlocal_name
), nlocal_name
, debugstr_wn(QName
, nQName
), nQName
);
1144 if (((!namespaceUri
|| !local_name
|| !QName
) && This
->class_version
!= MSXML6
) ||
1145 (nQName
== -1 && This
->class_version
== MSXML6
))
1146 return E_INVALIDARG
;
1150 static const WCHAR closeW
[] = {'/','>'};
1151 write_output_buffer(This
->buffer
, closeW
, 2);
1155 static const WCHAR closetagW
[] = {'<','/'};
1156 static const WCHAR gtW
[] = {'>'};
1158 write_output_buffer(This
->buffer
, closetagW
, 2);
1159 write_output_buffer(This
->buffer
, QName
, nQName
);
1160 write_output_buffer(This
->buffer
, gtW
, 1);
1163 set_element_name(This
, NULL
, 0);
1168 static HRESULT WINAPI
SAXContentHandler_characters(
1169 ISAXContentHandler
*iface
,
1173 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1175 TRACE("(%p)->(%s:%d)\n", This
, debugstr_wn(chars
, nchars
), nchars
);
1177 if (!chars
) return E_INVALIDARG
;
1179 close_element_starttag(This
);
1180 set_element_name(This
, NULL
, 0);
1184 if (This
->cdata
|| This
->props
[MXWriter_DisableEscaping
] == VARIANT_TRUE
)
1185 write_output_buffer(This
->buffer
, chars
, nchars
);
1191 escaped
= get_escaped_string(chars
, EscapeText
, &len
);
1192 write_output_buffer(This
->buffer
, escaped
, len
);
1200 static HRESULT WINAPI
SAXContentHandler_ignorableWhitespace(
1201 ISAXContentHandler
*iface
,
1205 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1207 TRACE("(%p)->(%s)\n", This
, debugstr_wn(chars
, nchars
));
1209 if (!chars
) return E_INVALIDARG
;
1211 write_output_buffer(This
->buffer
, chars
, nchars
);
1216 static HRESULT WINAPI
SAXContentHandler_processingInstruction(
1217 ISAXContentHandler
*iface
,
1218 const WCHAR
*target
,
1223 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1224 static const WCHAR openpiW
[] = {'<','?'};
1225 static const WCHAR closepiW
[] = {'?','>','\r','\n'};
1227 TRACE("(%p)->(%s %s)\n", This
, debugstr_wn(target
, ntarget
), debugstr_wn(data
, ndata
));
1229 if (!target
) return E_INVALIDARG
;
1231 write_output_buffer(This
->buffer
, openpiW
, sizeof(openpiW
)/sizeof(WCHAR
));
1234 write_output_buffer(This
->buffer
, target
, ntarget
);
1236 if (data
&& *data
&& ndata
)
1238 write_output_buffer(This
->buffer
, spaceW
, 1);
1239 write_output_buffer(This
->buffer
, data
, ndata
);
1242 write_output_buffer(This
->buffer
, closepiW
, sizeof(closepiW
)/sizeof(WCHAR
));
1247 static HRESULT WINAPI
SAXContentHandler_skippedEntity(
1248 ISAXContentHandler
*iface
,
1252 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1253 FIXME("(%p)->(%s)\n", This
, debugstr_wn(name
, nname
));
1257 static const struct ISAXContentHandlerVtbl SAXContentHandlerVtbl
=
1259 SAXContentHandler_QueryInterface
,
1260 SAXContentHandler_AddRef
,
1261 SAXContentHandler_Release
,
1262 SAXContentHandler_putDocumentLocator
,
1263 SAXContentHandler_startDocument
,
1264 SAXContentHandler_endDocument
,
1265 SAXContentHandler_startPrefixMapping
,
1266 SAXContentHandler_endPrefixMapping
,
1267 SAXContentHandler_startElement
,
1268 SAXContentHandler_endElement
,
1269 SAXContentHandler_characters
,
1270 SAXContentHandler_ignorableWhitespace
,
1271 SAXContentHandler_processingInstruction
,
1272 SAXContentHandler_skippedEntity
1275 /*** ISAXLexicalHandler ***/
1276 static HRESULT WINAPI
SAXLexicalHandler_QueryInterface(ISAXLexicalHandler
*iface
,
1277 REFIID riid
, void **obj
)
1279 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1280 return IMXWriter_QueryInterface(&This
->IMXWriter_iface
, riid
, obj
);
1283 static ULONG WINAPI
SAXLexicalHandler_AddRef(ISAXLexicalHandler
*iface
)
1285 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1286 return IMXWriter_AddRef(&This
->IMXWriter_iface
);
1289 static ULONG WINAPI
SAXLexicalHandler_Release(ISAXLexicalHandler
*iface
)
1291 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1292 return IMXWriter_Release(&This
->IMXWriter_iface
);
1295 static HRESULT WINAPI
SAXLexicalHandler_startDTD(ISAXLexicalHandler
*iface
,
1296 const WCHAR
*name
, int name_len
, const WCHAR
*publicId
, int publicId_len
,
1297 const WCHAR
*systemId
, int systemId_len
)
1299 static const WCHAR doctypeW
[] = {'<','!','D','O','C','T','Y','P','E',' '};
1300 static const WCHAR openintW
[] = {'[','\r','\n'};
1302 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1304 TRACE("(%p)->(%s %s %s)\n", This
, debugstr_wn(name
, name_len
), debugstr_wn(publicId
, publicId_len
),
1305 debugstr_wn(systemId
, systemId_len
));
1307 if (!name
) return E_INVALIDARG
;
1309 write_output_buffer(This
->buffer
, doctypeW
, sizeof(doctypeW
)/sizeof(WCHAR
));
1313 write_output_buffer(This
->buffer
, name
, name_len
);
1314 write_output_buffer(This
->buffer
, spaceW
, 1);
1319 static const WCHAR publicW
[] = {'P','U','B','L','I','C',' '};
1321 write_output_buffer(This
->buffer
, publicW
, sizeof(publicW
)/sizeof(WCHAR
));
1322 write_output_buffer_quoted(This
->buffer
, publicId
, publicId_len
);
1324 if (!systemId
) return E_INVALIDARG
;
1327 write_output_buffer(This
->buffer
, spaceW
, 1);
1329 write_output_buffer_quoted(This
->buffer
, systemId
, systemId_len
);
1332 write_output_buffer(This
->buffer
, spaceW
, 1);
1336 static const WCHAR systemW
[] = {'S','Y','S','T','E','M',' '};
1338 write_output_buffer(This
->buffer
, systemW
, sizeof(systemW
)/sizeof(WCHAR
));
1339 write_output_buffer_quoted(This
->buffer
, systemId
, systemId_len
);
1341 write_output_buffer(This
->buffer
, spaceW
, 1);
1344 write_output_buffer(This
->buffer
, openintW
, sizeof(openintW
)/sizeof(WCHAR
));
1349 static HRESULT WINAPI
SAXLexicalHandler_endDTD(ISAXLexicalHandler
*iface
)
1351 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1352 static const WCHAR closedtdW
[] = {']','>','\r','\n'};
1354 TRACE("(%p)\n", This
);
1356 write_output_buffer(This
->buffer
, closedtdW
, sizeof(closedtdW
)/sizeof(WCHAR
));
1361 static HRESULT WINAPI
SAXLexicalHandler_startEntity(ISAXLexicalHandler
*iface
, const WCHAR
*name
, int len
)
1363 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1364 FIXME("(%p)->(%s): stub\n", This
, debugstr_wn(name
, len
));
1368 static HRESULT WINAPI
SAXLexicalHandler_endEntity(ISAXLexicalHandler
*iface
, const WCHAR
*name
, int len
)
1370 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1371 FIXME("(%p)->(%s): stub\n", This
, debugstr_wn(name
, len
));
1375 static HRESULT WINAPI
SAXLexicalHandler_startCDATA(ISAXLexicalHandler
*iface
)
1377 static const WCHAR scdataW
[] = {'<','!','[','C','D','A','T','A','['};
1378 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1380 TRACE("(%p)\n", This
);
1382 write_output_buffer(This
->buffer
, scdataW
, sizeof(scdataW
)/sizeof(WCHAR
));
1388 static HRESULT WINAPI
SAXLexicalHandler_endCDATA(ISAXLexicalHandler
*iface
)
1390 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1391 static const WCHAR ecdataW
[] = {']',']','>'};
1393 TRACE("(%p)\n", This
);
1395 write_output_buffer(This
->buffer
, ecdataW
, sizeof(ecdataW
)/sizeof(WCHAR
));
1396 This
->cdata
= FALSE
;
1401 static HRESULT WINAPI
SAXLexicalHandler_comment(ISAXLexicalHandler
*iface
, const WCHAR
*chars
, int nchars
)
1403 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1404 static const WCHAR copenW
[] = {'<','!','-','-'};
1405 static const WCHAR ccloseW
[] = {'-','-','>','\r','\n'};
1407 TRACE("(%p)->(%s:%d)\n", This
, debugstr_wn(chars
, nchars
), nchars
);
1409 if (!chars
) return E_INVALIDARG
;
1411 close_element_starttag(This
);
1413 write_output_buffer(This
->buffer
, copenW
, sizeof(copenW
)/sizeof(WCHAR
));
1415 write_output_buffer(This
->buffer
, chars
, nchars
);
1416 write_output_buffer(This
->buffer
, ccloseW
, sizeof(ccloseW
)/sizeof(WCHAR
));
1421 static const struct ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl
=
1423 SAXLexicalHandler_QueryInterface
,
1424 SAXLexicalHandler_AddRef
,
1425 SAXLexicalHandler_Release
,
1426 SAXLexicalHandler_startDTD
,
1427 SAXLexicalHandler_endDTD
,
1428 SAXLexicalHandler_startEntity
,
1429 SAXLexicalHandler_endEntity
,
1430 SAXLexicalHandler_startCDATA
,
1431 SAXLexicalHandler_endCDATA
,
1432 SAXLexicalHandler_comment
1435 /*** ISAXDeclHandler ***/
1436 static HRESULT WINAPI
SAXDeclHandler_QueryInterface(ISAXDeclHandler
*iface
,
1437 REFIID riid
, void **obj
)
1439 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1440 return IMXWriter_QueryInterface(&This
->IMXWriter_iface
, riid
, obj
);
1443 static ULONG WINAPI
SAXDeclHandler_AddRef(ISAXDeclHandler
*iface
)
1445 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1446 return IMXWriter_AddRef(&This
->IMXWriter_iface
);
1449 static ULONG WINAPI
SAXDeclHandler_Release(ISAXDeclHandler
*iface
)
1451 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1452 return IMXWriter_Release(&This
->IMXWriter_iface
);
1455 static HRESULT WINAPI
SAXDeclHandler_elementDecl(ISAXDeclHandler
*iface
,
1456 const WCHAR
*name
, int n_name
, const WCHAR
*model
, int n_model
)
1458 static const WCHAR elementW
[] = {'<','!','E','L','E','M','E','N','T',' '};
1459 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1461 TRACE("(%p)->(%s:%d %s:%d)\n", This
, debugstr_wn(name
, n_name
), n_name
,
1462 debugstr_wn(model
, n_model
), n_model
);
1464 if (!name
|| !model
) return E_INVALIDARG
;
1466 write_output_buffer(This
->buffer
, elementW
, sizeof(elementW
)/sizeof(WCHAR
));
1468 write_output_buffer(This
->buffer
, name
, n_name
);
1469 write_output_buffer(This
->buffer
, spaceW
, sizeof(spaceW
)/sizeof(WCHAR
));
1472 write_output_buffer(This
->buffer
, model
, n_model
);
1473 write_output_buffer(This
->buffer
, closetagW
, sizeof(closetagW
)/sizeof(WCHAR
));
1478 static HRESULT WINAPI
SAXDeclHandler_attributeDecl(ISAXDeclHandler
*iface
,
1479 const WCHAR
*element
, int n_element
, const WCHAR
*attr
, int n_attr
,
1480 const WCHAR
*type
, int n_type
, const WCHAR
*Default
, int n_default
,
1481 const WCHAR
*value
, int n_value
)
1483 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1484 static const WCHAR attlistW
[] = {'<','!','A','T','T','L','I','S','T',' '};
1485 static const WCHAR closetagW
[] = {'>','\r','\n'};
1487 TRACE("(%p)->(%s:%d %s:%d %s:%d %s:%d %s:%d)\n", This
, debugstr_wn(element
, n_element
), n_element
,
1488 debugstr_wn(attr
, n_attr
), n_attr
, debugstr_wn(type
, n_type
), n_type
, debugstr_wn(Default
, n_default
), n_default
,
1489 debugstr_wn(value
, n_value
), n_value
);
1491 write_output_buffer(This
->buffer
, attlistW
, sizeof(attlistW
)/sizeof(WCHAR
));
1493 write_output_buffer(This
->buffer
, element
, n_element
);
1494 write_output_buffer(This
->buffer
, spaceW
, sizeof(spaceW
)/sizeof(WCHAR
));
1498 write_output_buffer(This
->buffer
, attr
, n_attr
);
1499 write_output_buffer(This
->buffer
, spaceW
, sizeof(spaceW
)/sizeof(WCHAR
));
1503 write_output_buffer(This
->buffer
, type
, n_type
);
1504 write_output_buffer(This
->buffer
, spaceW
, sizeof(spaceW
)/sizeof(WCHAR
));
1508 write_output_buffer(This
->buffer
, Default
, n_default
);
1509 write_output_buffer(This
->buffer
, spaceW
, sizeof(spaceW
)/sizeof(WCHAR
));
1513 write_output_buffer_quoted(This
->buffer
, value
, n_value
);
1515 write_output_buffer(This
->buffer
, closetagW
, sizeof(closetagW
)/sizeof(WCHAR
));
1520 static HRESULT WINAPI
SAXDeclHandler_internalEntityDecl(ISAXDeclHandler
*iface
,
1521 const WCHAR
*name
, int n_name
, const WCHAR
*value
, int n_value
)
1523 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1524 static const WCHAR entityW
[] = {'<','!','E','N','T','I','T','Y',' '};
1526 TRACE("(%p)->(%s:%d %s:%d)\n", This
, debugstr_wn(name
, n_name
), n_name
,
1527 debugstr_wn(value
, n_value
), n_value
);
1529 if (!name
|| !value
) return E_INVALIDARG
;
1531 write_output_buffer(This
->buffer
, entityW
, sizeof(entityW
)/sizeof(WCHAR
));
1533 write_output_buffer(This
->buffer
, name
, n_name
);
1534 write_output_buffer(This
->buffer
, spaceW
, sizeof(spaceW
)/sizeof(WCHAR
));
1538 write_output_buffer_quoted(This
->buffer
, value
, n_value
);
1540 write_output_buffer(This
->buffer
, closetagW
, sizeof(closetagW
)/sizeof(WCHAR
));
1545 static HRESULT WINAPI
SAXDeclHandler_externalEntityDecl(ISAXDeclHandler
*iface
,
1546 const WCHAR
*name
, int n_name
, const WCHAR
*publicId
, int n_publicId
,
1547 const WCHAR
*systemId
, int n_systemId
)
1549 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1550 FIXME("(%p)->(%s:%d %s:%d %s:%d): stub\n", This
, debugstr_wn(name
, n_name
), n_name
,
1551 debugstr_wn(publicId
, n_publicId
), n_publicId
, debugstr_wn(systemId
, n_systemId
), n_systemId
);
1555 static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl
= {
1556 SAXDeclHandler_QueryInterface
,
1557 SAXDeclHandler_AddRef
,
1558 SAXDeclHandler_Release
,
1559 SAXDeclHandler_elementDecl
,
1560 SAXDeclHandler_attributeDecl
,
1561 SAXDeclHandler_internalEntityDecl
,
1562 SAXDeclHandler_externalEntityDecl
1565 static const tid_t mxwriter_iface_tids
[] = {
1570 static dispex_static_data_t mxwriter_dispex
= {
1577 HRESULT
MXWriter_create(MSXML_VERSION version
, IUnknown
*outer
, void **ppObj
)
1579 static const WCHAR version10W
[] = {'1','.','0',0};
1583 TRACE("(%p, %p)\n", outer
, ppObj
);
1585 if (outer
) FIXME("support aggregation, outer\n");
1587 This
= heap_alloc( sizeof (*This
) );
1589 return E_OUTOFMEMORY
;
1591 This
->IMXWriter_iface
.lpVtbl
= &MXWriterVtbl
;
1592 This
->ISAXContentHandler_iface
.lpVtbl
= &SAXContentHandlerVtbl
;
1593 This
->ISAXLexicalHandler_iface
.lpVtbl
= &SAXLexicalHandlerVtbl
;
1594 This
->ISAXDeclHandler_iface
.lpVtbl
= &SAXDeclHandlerVtbl
;
1596 This
->class_version
= version
;
1598 This
->props
[MXWriter_BOM
] = VARIANT_TRUE
;
1599 This
->props
[MXWriter_DisableEscaping
] = VARIANT_FALSE
;
1600 This
->props
[MXWriter_Indent
] = VARIANT_FALSE
;
1601 This
->props
[MXWriter_OmitXmlDecl
] = VARIANT_FALSE
;
1602 This
->props
[MXWriter_Standalone
] = VARIANT_FALSE
;
1603 This
->prop_changed
= FALSE
;
1604 This
->encoding
= SysAllocString(utf16W
);
1605 This
->version
= SysAllocString(version10W
);
1606 This
->xml_enc
= XmlEncoding_UTF16
;
1608 This
->element
= NULL
;
1609 This
->cdata
= FALSE
;
1612 This
->dest_written
= 0;
1614 hr
= alloc_output_buffer(This
->xml_enc
, &This
->buffer
);
1616 SysFreeString(This
->encoding
);
1617 SysFreeString(This
->version
);
1622 init_dispex(&This
->dispex
, (IUnknown
*)&This
->IMXWriter_iface
, &mxwriter_dispex
);
1624 *ppObj
= &This
->IMXWriter_iface
;
1626 TRACE("returning iface %p\n", *ppObj
);
1631 static HRESULT WINAPI
MXAttributes_QueryInterface(IMXAttributes
*iface
, REFIID riid
, void **ppObj
)
1633 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1635 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( riid
), ppObj
);
1639 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
1640 IsEqualGUID( riid
, &IID_IDispatch
) ||
1641 IsEqualGUID( riid
, &IID_IMXAttributes
))
1645 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
1647 *ppObj
= &This
->ISAXAttributes_iface
;
1649 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
1651 *ppObj
= &This
->IVBSAXAttributes_iface
;
1653 else if (dispex_query_interface(&This
->dispex
, riid
, ppObj
))
1655 return *ppObj
? S_OK
: E_NOINTERFACE
;
1659 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
1660 return E_NOINTERFACE
;
1663 IMXAttributes_AddRef( iface
);
1668 static ULONG WINAPI
MXAttributes_AddRef(IMXAttributes
*iface
)
1670 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1671 ULONG ref
= InterlockedIncrement( &This
->ref
);
1672 TRACE("(%p)->(%d)\n", This
, ref
);
1676 static ULONG WINAPI
MXAttributes_Release(IMXAttributes
*iface
)
1678 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1679 LONG ref
= InterlockedDecrement( &This
->ref
);
1681 TRACE("(%p)->(%d)\n", This
, ref
);
1687 for (i
= 0; i
< This
->length
; i
++)
1689 SysFreeString(This
->attr
[i
].qname
);
1690 SysFreeString(This
->attr
[i
].local
);
1691 SysFreeString(This
->attr
[i
].uri
);
1692 SysFreeString(This
->attr
[i
].type
);
1693 SysFreeString(This
->attr
[i
].value
);
1696 release_dispex(&This
->dispex
);
1697 heap_free(This
->attr
);
1704 static HRESULT WINAPI
MXAttributes_GetTypeInfoCount(IMXAttributes
*iface
, UINT
* pctinfo
)
1706 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1707 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1710 static HRESULT WINAPI
MXAttributes_GetTypeInfo(IMXAttributes
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
1712 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1713 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1716 static HRESULT WINAPI
MXAttributes_GetIDsOfNames(
1717 IMXAttributes
*iface
,
1719 LPOLESTR
* rgszNames
,
1724 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1725 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
1726 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
1729 static HRESULT WINAPI
MXAttributes_Invoke(
1730 IMXAttributes
*iface
,
1731 DISPID dispIdMember
,
1735 DISPPARAMS
* pDispParams
,
1736 VARIANT
* pVarResult
,
1737 EXCEPINFO
* pExcepInfo
,
1740 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1741 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
1742 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1745 static HRESULT WINAPI
MXAttributes_addAttribute(IMXAttributes
*iface
,
1746 BSTR uri
, BSTR localName
, BSTR QName
, BSTR type
, BSTR value
)
1748 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1752 TRACE("(%p)->(%s %s %s %s %s)\n", This
, debugstr_w(uri
), debugstr_w(localName
),
1753 debugstr_w(QName
), debugstr_w(type
), debugstr_w(value
));
1755 if ((!uri
|| !localName
|| !QName
|| !type
|| !value
) && This
->class_version
!= MSXML6
)
1756 return E_INVALIDARG
;
1758 /* ensure array is large enough */
1759 hr
= mxattributes_grow(This
);
1760 if (hr
!= S_OK
) return hr
;
1762 attr
= &This
->attr
[This
->length
];
1764 attr
->qname
= SysAllocString(QName
);
1765 attr
->local
= SysAllocString(localName
);
1766 attr
->uri
= SysAllocString(uri
);
1767 attr
->type
= SysAllocString(type
? type
: emptyW
);
1768 attr
->value
= SysAllocString(value
);
1774 static HRESULT WINAPI
MXAttributes_addAttributeFromIndex(IMXAttributes
*iface
,
1775 VARIANT atts
, int index
)
1777 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1778 FIXME("(%p)->(%s %d): stub\n", This
, debugstr_variant(&atts
), index
);
1782 static HRESULT WINAPI
MXAttributes_clear(IMXAttributes
*iface
)
1784 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1787 TRACE("(%p)\n", This
);
1789 for (i
= 0; i
< This
->length
; i
++)
1791 SysFreeString(This
->attr
[i
].qname
);
1792 SysFreeString(This
->attr
[i
].local
);
1793 SysFreeString(This
->attr
[i
].uri
);
1794 SysFreeString(This
->attr
[i
].type
);
1795 SysFreeString(This
->attr
[i
].value
);
1796 memset(&This
->attr
[i
], 0, sizeof(mxattribute
));
1804 static HRESULT WINAPI
MXAttributes_removeAttribute(IMXAttributes
*iface
, int index
)
1806 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1807 FIXME("(%p)->(%d): stub\n", This
, index
);
1811 static HRESULT WINAPI
MXAttributes_setAttribute(IMXAttributes
*iface
, int index
,
1812 BSTR uri
, BSTR localName
, BSTR QName
, BSTR type
, BSTR value
)
1814 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1815 FIXME("(%p)->(%d %s %s %s %s %s): stub\n", This
, index
, debugstr_w(uri
),
1816 debugstr_w(localName
), debugstr_w(QName
), debugstr_w(type
), debugstr_w(value
));
1820 static HRESULT WINAPI
MXAttributes_setAttributes(IMXAttributes
*iface
, VARIANT atts
)
1822 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1823 FIXME("(%p)->(%s): stub\n", This
, debugstr_variant(&atts
));
1827 static HRESULT WINAPI
MXAttributes_setLocalName(IMXAttributes
*iface
, int index
,
1830 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1831 FIXME("(%p)->(%d %s): stub\n", This
, index
, debugstr_w(localName
));
1835 static HRESULT WINAPI
MXAttributes_setQName(IMXAttributes
*iface
, int index
, BSTR QName
)
1837 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1838 FIXME("(%p)->(%d %s): stub\n", This
, index
, debugstr_w(QName
));
1842 static HRESULT WINAPI
MXAttributes_setURI(IMXAttributes
*iface
, int index
, BSTR uri
)
1844 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1845 FIXME("(%p)->(%d %s): stub\n", This
, index
, debugstr_w(uri
));
1849 static HRESULT WINAPI
MXAttributes_setValue(IMXAttributes
*iface
, int index
, BSTR value
)
1851 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1852 FIXME("(%p)->(%d %s): stub\n", This
, index
, debugstr_w(value
));
1856 static const IMXAttributesVtbl MXAttributesVtbl
= {
1857 MXAttributes_QueryInterface
,
1858 MXAttributes_AddRef
,
1859 MXAttributes_Release
,
1860 MXAttributes_GetTypeInfoCount
,
1861 MXAttributes_GetTypeInfo
,
1862 MXAttributes_GetIDsOfNames
,
1863 MXAttributes_Invoke
,
1864 MXAttributes_addAttribute
,
1865 MXAttributes_addAttributeFromIndex
,
1867 MXAttributes_removeAttribute
,
1868 MXAttributes_setAttribute
,
1869 MXAttributes_setAttributes
,
1870 MXAttributes_setLocalName
,
1871 MXAttributes_setQName
,
1872 MXAttributes_setURI
,
1873 MXAttributes_setValue
1876 static HRESULT WINAPI
SAXAttributes_QueryInterface(ISAXAttributes
*iface
, REFIID riid
, void **ppObj
)
1878 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1879 return IMXAttributes_QueryInterface(&This
->IMXAttributes_iface
, riid
, ppObj
);
1882 static ULONG WINAPI
SAXAttributes_AddRef(ISAXAttributes
*iface
)
1884 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1885 return IMXAttributes_AddRef(&This
->IMXAttributes_iface
);
1888 static ULONG WINAPI
SAXAttributes_Release(ISAXAttributes
*iface
)
1890 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1891 return IMXAttributes_Release(&This
->IMXAttributes_iface
);
1894 static HRESULT WINAPI
SAXAttributes_getLength(ISAXAttributes
*iface
, int *length
)
1896 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1897 TRACE("(%p)->(%p)\n", This
, length
);
1899 if (!length
&& (This
->class_version
== MSXML_DEFAULT
|| This
->class_version
== MSXML3
))
1902 *length
= This
->length
;
1907 static HRESULT WINAPI
SAXAttributes_getURI(ISAXAttributes
*iface
, int index
, const WCHAR
**uri
,
1910 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1912 TRACE("(%p)->(%d %p %p)\n", This
, index
, uri
, len
);
1914 if (index
>= This
->length
|| index
< 0) return E_INVALIDARG
;
1915 if (!uri
|| !len
) return E_POINTER
;
1917 *len
= SysStringLen(This
->attr
[index
].uri
);
1918 *uri
= This
->attr
[index
].uri
;
1923 static HRESULT WINAPI
SAXAttributes_getLocalName(ISAXAttributes
*iface
, int index
, const WCHAR
**name
,
1926 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1928 TRACE("(%p)->(%d %p %p)\n", This
, index
, name
, len
);
1930 if (index
>= This
->length
|| index
< 0) return E_INVALIDARG
;
1931 if (!name
|| !len
) return E_POINTER
;
1933 *len
= SysStringLen(This
->attr
[index
].local
);
1934 *name
= This
->attr
[index
].local
;
1939 static HRESULT WINAPI
SAXAttributes_getQName(ISAXAttributes
*iface
, int index
, const WCHAR
**qname
, int *length
)
1941 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1943 TRACE("(%p)->(%d %p %p)\n", This
, index
, qname
, length
);
1945 if (index
>= This
->length
) return E_INVALIDARG
;
1946 if (!qname
|| !length
) return E_POINTER
;
1948 *qname
= This
->attr
[index
].qname
;
1949 *length
= SysStringLen(This
->attr
[index
].qname
);
1954 static HRESULT WINAPI
SAXAttributes_getName(ISAXAttributes
*iface
, int index
, const WCHAR
**uri
, int *uri_len
,
1955 const WCHAR
**local
, int *local_len
, const WCHAR
**qname
, int *qname_len
)
1957 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1959 TRACE("(%p)->(%d %p %p %p %p %p %p)\n", This
, index
, uri
, uri_len
, local
, local_len
, qname
, qname_len
);
1961 if (index
>= This
->length
|| index
< 0)
1962 return E_INVALIDARG
;
1964 if (!uri
|| !uri_len
|| !local
|| !local_len
|| !qname
|| !qname_len
)
1967 *uri_len
= SysStringLen(This
->attr
[index
].uri
);
1968 *uri
= This
->attr
[index
].uri
;
1970 *local_len
= SysStringLen(This
->attr
[index
].local
);
1971 *local
= This
->attr
[index
].local
;
1973 *qname_len
= SysStringLen(This
->attr
[index
].qname
);
1974 *qname
= This
->attr
[index
].qname
;
1976 TRACE("(%s, %s, %s)\n", debugstr_w(*uri
), debugstr_w(*local
), debugstr_w(*qname
));
1981 static HRESULT WINAPI
SAXAttributes_getIndexFromName(ISAXAttributes
*iface
, const WCHAR
*uri
, int uri_len
,
1982 const WCHAR
*name
, int len
, int *index
)
1984 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1987 TRACE("(%p)->(%s:%d %s:%d %p)\n", This
, debugstr_wn(uri
, uri_len
), uri_len
,
1988 debugstr_wn(name
, len
), len
, index
);
1990 if (!index
&& (This
->class_version
== MSXML_DEFAULT
|| This
->class_version
== MSXML3
))
1993 if (!uri
|| !name
|| !index
) return E_INVALIDARG
;
1995 for (i
= 0; i
< This
->length
; i
++)
1997 if (uri_len
!= SysStringLen(This
->attr
[i
].uri
)) continue;
1998 if (strncmpW(uri
, This
->attr
[i
].uri
, uri_len
)) continue;
2000 if (len
!= SysStringLen(This
->attr
[i
].local
)) continue;
2001 if (strncmpW(name
, This
->attr
[i
].local
, len
)) continue;
2007 return E_INVALIDARG
;
2010 static HRESULT WINAPI
SAXAttributes_getIndexFromQName(ISAXAttributes
*iface
, const WCHAR
*qname
,
2011 int len
, int *index
)
2013 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
2016 TRACE("(%p)->(%s:%d %p)\n", This
, debugstr_wn(qname
, len
), len
, index
);
2018 if (!index
&& (This
->class_version
== MSXML_DEFAULT
|| This
->class_version
== MSXML3
))
2021 if (!qname
|| !index
|| !len
) return E_INVALIDARG
;
2023 for (i
= 0; i
< This
->length
; i
++)
2025 if (len
!= SysStringLen(This
->attr
[i
].qname
)) continue;
2026 if (strncmpW(qname
, This
->attr
[i
].qname
, len
)) continue;
2032 return E_INVALIDARG
;
2035 static HRESULT WINAPI
SAXAttributes_getType(ISAXAttributes
*iface
, int index
, const WCHAR
**type
,
2038 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
2040 TRACE("(%p)->(%d %p %p)\n", This
, index
, type
, len
);
2042 if (index
>= This
->length
) return E_INVALIDARG
;
2044 if ((!type
|| !len
) && (This
->class_version
== MSXML_DEFAULT
|| This
->class_version
== MSXML3
))
2047 *type
= This
->attr
[index
].type
;
2048 *len
= SysStringLen(This
->attr
[index
].type
);
2053 static HRESULT WINAPI
SAXAttributes_getTypeFromName(ISAXAttributes
*iface
, const WCHAR
* pUri
, int nUri
,
2054 const WCHAR
* pLocalName
, int nLocalName
, const WCHAR
** pType
, int * nType
)
2056 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
2057 FIXME("(%p)->(%s:%d %s:%d %p %p): stub\n", This
, debugstr_wn(pUri
, nUri
), nUri
,
2058 debugstr_wn(pLocalName
, nLocalName
), nLocalName
, pType
, nType
);
2062 static HRESULT WINAPI
SAXAttributes_getTypeFromQName(ISAXAttributes
*iface
, const WCHAR
* pQName
,
2063 int nQName
, const WCHAR
** pType
, int * nType
)
2065 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
2066 FIXME("(%p)->(%s:%d %p %p): stub\n", This
, debugstr_wn(pQName
, nQName
), nQName
, pType
, nType
);
2070 static HRESULT WINAPI
SAXAttributes_getValue(ISAXAttributes
*iface
, int index
, const WCHAR
**value
,
2073 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
2075 TRACE("(%p)->(%d %p %p)\n", This
, index
, value
, len
);
2077 if (index
>= This
->length
) return E_INVALIDARG
;
2079 if ((!value
|| !len
) && (This
->class_version
== MSXML_DEFAULT
|| This
->class_version
== MSXML3
))
2082 *value
= This
->attr
[index
].value
;
2083 *len
= SysStringLen(This
->attr
[index
].value
);
2088 static HRESULT WINAPI
SAXAttributes_getValueFromName(ISAXAttributes
*iface
, const WCHAR
*uri
,
2089 int uri_len
, const WCHAR
*name
, int name_len
, const WCHAR
**value
, int *value_len
)
2091 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
2095 TRACE("(%p)->(%s:%d %s:%d %p %p)\n", This
, debugstr_wn(uri
, uri_len
), uri_len
,
2096 debugstr_wn(name
, name_len
), name_len
, value
, value_len
);
2098 if (!uri
|| !name
|| !value
|| !value_len
)
2099 return (This
->class_version
== MSXML_DEFAULT
|| This
->class_version
== MSXML3
) ? E_POINTER
: E_INVALIDARG
;
2101 hr
= ISAXAttributes_getIndexFromName(iface
, uri
, uri_len
, name
, name_len
, &index
);
2103 hr
= ISAXAttributes_getValue(iface
, index
, value
, value_len
);
2108 static HRESULT WINAPI
SAXAttributes_getValueFromQName(ISAXAttributes
*iface
, const WCHAR
*qname
,
2109 int qname_len
, const WCHAR
**value
, int *value_len
)
2111 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
2115 TRACE("(%p)->(%s:%d %p %p)\n", This
, debugstr_wn(qname
, qname_len
), qname_len
, value
, value_len
);
2117 if (!qname
|| !value
|| !value_len
)
2118 return (This
->class_version
== MSXML_DEFAULT
|| This
->class_version
== MSXML3
) ? E_POINTER
: E_INVALIDARG
;
2120 hr
= ISAXAttributes_getIndexFromQName(iface
, qname
, qname_len
, &index
);
2122 hr
= ISAXAttributes_getValue(iface
, index
, value
, value_len
);
2127 static const ISAXAttributesVtbl SAXAttributesVtbl
= {
2128 SAXAttributes_QueryInterface
,
2129 SAXAttributes_AddRef
,
2130 SAXAttributes_Release
,
2131 SAXAttributes_getLength
,
2132 SAXAttributes_getURI
,
2133 SAXAttributes_getLocalName
,
2134 SAXAttributes_getQName
,
2135 SAXAttributes_getName
,
2136 SAXAttributes_getIndexFromName
,
2137 SAXAttributes_getIndexFromQName
,
2138 SAXAttributes_getType
,
2139 SAXAttributes_getTypeFromName
,
2140 SAXAttributes_getTypeFromQName
,
2141 SAXAttributes_getValue
,
2142 SAXAttributes_getValueFromName
,
2143 SAXAttributes_getValueFromQName
2146 static HRESULT WINAPI
VBSAXAttributes_QueryInterface(
2147 IVBSAXAttributes
* iface
,
2151 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2152 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
2153 return ISAXAttributes_QueryInterface(&This
->ISAXAttributes_iface
, riid
, ppvObject
);
2156 static ULONG WINAPI
VBSAXAttributes_AddRef(IVBSAXAttributes
* iface
)
2158 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2159 return ISAXAttributes_AddRef(&This
->ISAXAttributes_iface
);
2162 static ULONG WINAPI
VBSAXAttributes_Release(IVBSAXAttributes
* iface
)
2164 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2165 return ISAXAttributes_Release(&This
->ISAXAttributes_iface
);
2168 static HRESULT WINAPI
VBSAXAttributes_GetTypeInfoCount( IVBSAXAttributes
*iface
, UINT
* pctinfo
)
2170 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2172 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2179 static HRESULT WINAPI
VBSAXAttributes_GetTypeInfo(
2180 IVBSAXAttributes
*iface
,
2181 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2183 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2184 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2185 return get_typeinfo(IVBSAXAttributes_tid
, ppTInfo
);
2188 static HRESULT WINAPI
VBSAXAttributes_GetIDsOfNames(
2189 IVBSAXAttributes
*iface
,
2191 LPOLESTR
* rgszNames
,
2196 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2197 ITypeInfo
*typeinfo
;
2200 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
2203 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2204 return E_INVALIDARG
;
2206 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
2209 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2210 ITypeInfo_Release(typeinfo
);
2216 static HRESULT WINAPI
VBSAXAttributes_Invoke(
2217 IVBSAXAttributes
*iface
,
2218 DISPID dispIdMember
,
2222 DISPPARAMS
* pDispParams
,
2223 VARIANT
* pVarResult
,
2224 EXCEPINFO
* pExcepInfo
,
2227 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2228 ITypeInfo
*typeinfo
;
2231 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2232 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2234 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
2237 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXAttributes_iface
, dispIdMember
, wFlags
,
2238 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2239 ITypeInfo_Release(typeinfo
);
2245 static HRESULT WINAPI
VBSAXAttributes_get_length(IVBSAXAttributes
* iface
, int *len
)
2247 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2248 return ISAXAttributes_getLength(&This
->ISAXAttributes_iface
, len
);
2251 static HRESULT WINAPI
VBSAXAttributes_getURI(IVBSAXAttributes
* iface
, int index
, BSTR
*uri
)
2253 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2256 return ISAXAttributes_getURI(&This
->ISAXAttributes_iface
, index
, (const WCHAR
**)uri
, &len
);
2259 static HRESULT WINAPI
VBSAXAttributes_getLocalName(IVBSAXAttributes
* iface
, int index
, BSTR
*name
)
2261 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2264 return ISAXAttributes_getLocalName(&This
->ISAXAttributes_iface
, index
, (const WCHAR
**)name
, &len
);
2267 static HRESULT WINAPI
VBSAXAttributes_getQName(IVBSAXAttributes
* iface
, int index
, BSTR
*qname
)
2269 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2272 return ISAXAttributes_getQName(&This
->ISAXAttributes_iface
, index
, (const WCHAR
**)qname
, &len
);
2275 static HRESULT WINAPI
VBSAXAttributes_getIndexFromName(IVBSAXAttributes
* iface
, BSTR uri
, BSTR name
, int *index
)
2277 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2278 return ISAXAttributes_getIndexFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
2279 name
, SysStringLen(name
), index
);
2282 static HRESULT WINAPI
VBSAXAttributes_getIndexFromQName(IVBSAXAttributes
* iface
, BSTR qname
, int *index
)
2284 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2285 return ISAXAttributes_getIndexFromQName(&This
->ISAXAttributes_iface
, qname
,
2286 SysStringLen(qname
), index
);
2289 static HRESULT WINAPI
VBSAXAttributes_getType(IVBSAXAttributes
* iface
, int index
,BSTR
*type
)
2291 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2294 return ISAXAttributes_getType(&This
->ISAXAttributes_iface
, index
, (const WCHAR
**)type
, &len
);
2297 static HRESULT WINAPI
VBSAXAttributes_getTypeFromName(IVBSAXAttributes
* iface
, BSTR uri
,
2298 BSTR name
, BSTR
*type
)
2300 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2303 return ISAXAttributes_getTypeFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
2304 name
, SysStringLen(name
), (const WCHAR
**)type
, &len
);
2307 static HRESULT WINAPI
VBSAXAttributes_getTypeFromQName(IVBSAXAttributes
* iface
, BSTR qname
, BSTR
*type
)
2309 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2312 return ISAXAttributes_getTypeFromQName(&This
->ISAXAttributes_iface
, qname
, SysStringLen(qname
),
2313 (const WCHAR
**)type
, &len
);
2316 static HRESULT WINAPI
VBSAXAttributes_getValue(IVBSAXAttributes
* iface
, int index
, BSTR
*value
)
2318 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2321 return ISAXAttributes_getValue(&This
->ISAXAttributes_iface
, index
, (const WCHAR
**)value
, &len
);
2324 static HRESULT WINAPI
VBSAXAttributes_getValueFromName(IVBSAXAttributes
* iface
, BSTR uri
, BSTR name
,
2327 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2330 return ISAXAttributes_getValueFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
2331 name
, SysStringLen(name
), (const WCHAR
**)value
, &len
);
2334 static HRESULT WINAPI
VBSAXAttributes_getValueFromQName(IVBSAXAttributes
* iface
, BSTR qname
, BSTR
*value
)
2336 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2339 return ISAXAttributes_getValueFromQName(&This
->ISAXAttributes_iface
, qname
, SysStringLen(qname
),
2340 (const WCHAR
**)value
, &len
);
2343 static const struct IVBSAXAttributesVtbl VBSAXAttributesVtbl
=
2345 VBSAXAttributes_QueryInterface
,
2346 VBSAXAttributes_AddRef
,
2347 VBSAXAttributes_Release
,
2348 VBSAXAttributes_GetTypeInfoCount
,
2349 VBSAXAttributes_GetTypeInfo
,
2350 VBSAXAttributes_GetIDsOfNames
,
2351 VBSAXAttributes_Invoke
,
2352 VBSAXAttributes_get_length
,
2353 VBSAXAttributes_getURI
,
2354 VBSAXAttributes_getLocalName
,
2355 VBSAXAttributes_getQName
,
2356 VBSAXAttributes_getIndexFromName
,
2357 VBSAXAttributes_getIndexFromQName
,
2358 VBSAXAttributes_getType
,
2359 VBSAXAttributes_getTypeFromName
,
2360 VBSAXAttributes_getTypeFromQName
,
2361 VBSAXAttributes_getValue
,
2362 VBSAXAttributes_getValueFromName
,
2363 VBSAXAttributes_getValueFromQName
2366 static const tid_t mxattrs_iface_tids
[] = {
2371 static dispex_static_data_t mxattrs_dispex
= {
2378 HRESULT
SAXAttributes_create(MSXML_VERSION version
, IUnknown
*outer
, void **ppObj
)
2380 static const int default_count
= 10;
2383 TRACE("(%p, %p)\n", outer
, ppObj
);
2385 This
= heap_alloc( sizeof (*This
) );
2387 return E_OUTOFMEMORY
;
2389 This
->IMXAttributes_iface
.lpVtbl
= &MXAttributesVtbl
;
2390 This
->ISAXAttributes_iface
.lpVtbl
= &SAXAttributesVtbl
;
2391 This
->IVBSAXAttributes_iface
.lpVtbl
= &VBSAXAttributesVtbl
;
2394 This
->class_version
= version
;
2396 This
->attr
= heap_alloc(default_count
*sizeof(mxattribute
));
2398 This
->allocated
= default_count
;
2400 *ppObj
= &This
->IMXAttributes_iface
;
2402 init_dispex(&This
->dispex
, (IUnknown
*)&This
->IMXAttributes_iface
, &mxattrs_dispex
);
2404 TRACE("returning iface %p\n", *ppObj
);