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 utf16W
[] = {'U','T','F','-','1','6',0};
43 static const WCHAR emptyW
[] = {0};
44 static const WCHAR spaceW
[] = {' '};
45 static const WCHAR quotW
[] = {'\"'};
56 OutputBuffer_Native
= 0x001,
57 OutputBuffer_Encoded
= 0x010,
58 OutputBuffer_Both
= 0x100
64 MXWriter_DisableEscaping
,
80 unsigned int allocated
;
87 encoded_buffer encoded
;
94 IMXWriter IMXWriter_iface
;
95 ISAXContentHandler ISAXContentHandler_iface
;
96 ISAXLexicalHandler ISAXLexicalHandler_iface
;
97 ISAXDeclHandler ISAXDeclHandler_iface
;
100 MSXML_VERSION class_version
;
102 VARIANT_BOOL props
[MXWriter_LastProp
];
108 BSTR encoding
; /* exact property value */
109 xml_encoding xml_enc
;
111 /* contains a pending (or not closed yet) element name or NULL if
112 we don't have to close */
118 output_buffer
*buffer
;
133 IMXAttributes IMXAttributes_iface
;
134 ISAXAttributes ISAXAttributes_iface
;
135 IVBSAXAttributes IVBSAXAttributes_iface
;
138 MSXML_VERSION class_version
;
145 static inline mxattributes
*impl_from_IMXAttributes( IMXAttributes
*iface
)
147 return CONTAINING_RECORD(iface
, mxattributes
, IMXAttributes_iface
);
150 static inline mxattributes
*impl_from_ISAXAttributes( ISAXAttributes
*iface
)
152 return CONTAINING_RECORD(iface
, mxattributes
, ISAXAttributes_iface
);
155 static inline mxattributes
*impl_from_IVBSAXAttributes( IVBSAXAttributes
*iface
)
157 return CONTAINING_RECORD(iface
, mxattributes
, IVBSAXAttributes_iface
);
160 static HRESULT
mxattributes_grow(mxattributes
*This
)
162 if (This
->length
< This
->allocated
) return S_OK
;
164 This
->allocated
*= 2;
165 This
->attr
= heap_realloc(This
->attr
, This
->allocated
*sizeof(mxattribute
));
167 return This
->attr
? S_OK
: E_OUTOFMEMORY
;
170 static xml_encoding
parse_encoding_name(const WCHAR
*encoding
)
172 static const WCHAR utf8W
[] = {'U','T','F','-','8',0};
173 if (!strcmpiW(encoding
, utf8W
)) return XmlEncoding_UTF8
;
174 if (!strcmpiW(encoding
, utf16W
)) return XmlEncoding_UTF16
;
175 return XmlEncoding_Unknown
;
178 static HRESULT
init_encoded_buffer(encoded_buffer
*buffer
)
180 const int initial_len
= 0x2000;
181 buffer
->data
= heap_alloc(initial_len
);
182 if (!buffer
->data
) return E_OUTOFMEMORY
;
184 memset(buffer
->data
, 0, 4);
185 buffer
->allocated
= initial_len
;
191 static void free_encoded_buffer(encoded_buffer
*buffer
)
193 heap_free(buffer
->data
);
196 static HRESULT
get_code_page(xml_encoding encoding
, UINT
*cp
)
200 case XmlEncoding_UTF8
:
203 case XmlEncoding_UTF16
:
207 FIXME("unsupported encoding %d\n", encoding
);
214 static HRESULT
alloc_output_buffer(xml_encoding encoding
, output_buffer
**buffer
)
219 ret
= heap_alloc(sizeof(*ret
));
220 if (!ret
) return E_OUTOFMEMORY
;
222 hr
= get_code_page(encoding
, &ret
->code_page
);
228 hr
= init_encoded_buffer(&ret
->utf16
);
234 if (ret
->code_page
== CP_UTF8
) {
235 hr
= init_encoded_buffer(&ret
->encoded
);
237 free_encoded_buffer(&ret
->utf16
);
243 memset(&ret
->encoded
, 0, sizeof(ret
->encoded
));
250 static void free_output_buffer(output_buffer
*buffer
)
252 free_encoded_buffer(&buffer
->encoded
);
253 free_encoded_buffer(&buffer
->utf16
);
257 static void grow_buffer(encoded_buffer
*buffer
, int length
)
259 /* grow if needed, plus 4 bytes to be sure null terminator will fit in */
260 if (buffer
->allocated
< buffer
->written
+ length
+ 4)
262 int grown_size
= max(2*buffer
->allocated
, buffer
->allocated
+ length
);
263 buffer
->data
= heap_realloc(buffer
->data
, grown_size
);
264 buffer
->allocated
= grown_size
;
268 static HRESULT
write_output_buffer_mode(output_buffer
*buffer
, output_mode mode
, const WCHAR
*data
, int len
)
273 if (mode
& (OutputBuffer_Encoded
| OutputBuffer_Both
)) {
274 if (buffer
->code_page
== CP_UTF8
)
276 length
= WideCharToMultiByte(buffer
->code_page
, 0, data
, len
, NULL
, 0, NULL
, NULL
);
277 grow_buffer(&buffer
->encoded
, length
);
278 ptr
= buffer
->encoded
.data
+ buffer
->encoded
.written
;
279 length
= WideCharToMultiByte(buffer
->code_page
, 0, data
, len
, ptr
, length
, NULL
, NULL
);
280 buffer
->encoded
.written
+= len
== -1 ? length
-1 : length
;
284 if (mode
& (OutputBuffer_Native
| OutputBuffer_Both
)) {
285 /* WCHAR data just copied */
286 length
= len
== -1 ? strlenW(data
) : len
;
289 length
*= sizeof(WCHAR
);
291 grow_buffer(&buffer
->utf16
, length
);
292 ptr
= buffer
->utf16
.data
+ buffer
->utf16
.written
;
294 memcpy(ptr
, data
, length
);
295 buffer
->utf16
.written
+= length
;
297 /* null termination */
298 memset(ptr
, 0, sizeof(WCHAR
));
305 static HRESULT
write_output_buffer(output_buffer
*buffer
, const WCHAR
*data
, int len
)
307 return write_output_buffer_mode(buffer
, OutputBuffer_Both
, data
, len
);
310 static HRESULT
write_output_buffer_quoted(output_buffer
*buffer
, const WCHAR
*data
, int len
)
312 write_output_buffer(buffer
, quotW
, 1);
313 write_output_buffer(buffer
, data
, len
);
314 write_output_buffer(buffer
, quotW
, 1);
319 /* frees buffer data, reallocates with a default lengths */
320 static void close_output_buffer(mxwriter
*This
)
322 heap_free(This
->buffer
->utf16
.data
);
323 heap_free(This
->buffer
->encoded
.data
);
324 init_encoded_buffer(&This
->buffer
->utf16
);
325 init_encoded_buffer(&This
->buffer
->encoded
);
326 get_code_page(This
->xml_enc
, &This
->buffer
->code_page
);
329 /* escapes special characters like:
335 static WCHAR
*get_escaped_string(const WCHAR
*str
, escape_mode mode
, int *len
)
337 static const WCHAR ltW
[] = {'&','l','t',';'};
338 static const WCHAR ampW
[] = {'&','a','m','p',';'};
339 static const WCHAR equotW
[] = {'&','q','u','o','t',';'};
340 static const WCHAR gtW
[] = {'&','g','t',';'};
342 const int default_alloc
= 100;
343 const int grow_thresh
= 10;
344 int p
= *len
, conv_len
;
347 /* default buffer size to something if length is unknown */
348 conv_len
= *len
== -1 ? default_alloc
: max(2**len
, default_alloc
);
349 ptr
= ret
= heap_alloc(conv_len
*sizeof(WCHAR
));
353 if (ptr
- ret
> conv_len
- grow_thresh
)
355 int written
= ptr
- ret
;
357 ptr
= ret
= heap_realloc(ret
, conv_len
*sizeof(WCHAR
));
364 memcpy(ptr
, ltW
, sizeof(ltW
));
365 ptr
+= sizeof(ltW
)/sizeof(WCHAR
);
368 memcpy(ptr
, ampW
, sizeof(ampW
));
369 ptr
+= sizeof(ampW
)/sizeof(WCHAR
);
372 memcpy(ptr
, gtW
, sizeof(gtW
));
373 ptr
+= sizeof(gtW
)/sizeof(WCHAR
);
376 if (mode
== EscapeValue
)
378 memcpy(ptr
, equotW
, sizeof(equotW
));
379 ptr
+= sizeof(equotW
)/sizeof(WCHAR
);
382 /* fallthrough for text mode */
392 if (*len
!= -1) *len
= ptr
-ret
;
398 static void write_prolog_buffer(const mxwriter
*This
)
400 static const WCHAR versionW
[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','='};
401 static const WCHAR encodingW
[] = {' ','e','n','c','o','d','i','n','g','=','\"'};
402 static const WCHAR standaloneW
[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
403 static const WCHAR yesW
[] = {'y','e','s','\"','?','>'};
404 static const WCHAR noW
[] = {'n','o','\"','?','>'};
405 static const WCHAR crlfW
[] = {'\r','\n'};
408 write_output_buffer(This
->buffer
, versionW
, sizeof(versionW
)/sizeof(WCHAR
));
409 write_output_buffer_quoted(This
->buffer
, This
->version
, -1);
412 write_output_buffer(This
->buffer
, encodingW
, sizeof(encodingW
)/sizeof(WCHAR
));
414 /* always write UTF-16 to WCHAR buffer */
415 write_output_buffer_mode(This
->buffer
, OutputBuffer_Native
, utf16W
, sizeof(utf16W
)/sizeof(WCHAR
) - 1);
416 write_output_buffer_mode(This
->buffer
, OutputBuffer_Encoded
, This
->encoding
, -1);
417 write_output_buffer(This
->buffer
, quotW
, 1);
420 write_output_buffer(This
->buffer
, standaloneW
, sizeof(standaloneW
)/sizeof(WCHAR
));
421 if (This
->props
[MXWriter_Standalone
] == VARIANT_TRUE
)
422 write_output_buffer(This
->buffer
, yesW
, sizeof(yesW
)/sizeof(WCHAR
));
424 write_output_buffer(This
->buffer
, noW
, sizeof(noW
)/sizeof(WCHAR
));
426 write_output_buffer(This
->buffer
, crlfW
, sizeof(crlfW
)/sizeof(WCHAR
));
429 /* Attempts to the write data from the mxwriter's buffer to
430 * the destination stream (if there is one).
432 static HRESULT
write_data_to_stream(mxwriter
*This
)
434 encoded_buffer
*buffer
;
441 if (This
->xml_enc
!= XmlEncoding_UTF16
)
442 buffer
= &This
->buffer
->encoded
;
444 buffer
= &This
->buffer
->utf16
;
446 if (This
->dest_written
> buffer
->written
) {
447 ERR("Failed sanity check! Not sure what to do... (%d > %d)\n", This
->dest_written
, buffer
->written
);
449 } else if (This
->dest_written
== buffer
->written
&& This
->xml_enc
!= XmlEncoding_UTF8
)
450 /* Windows seems to make an empty write call when the encoding is UTF-8 and
451 * all the data has been written to the stream. It doesn't seem make this call
452 * for any other encodings.
456 /* Write the current content from the output buffer into 'dest'.
457 * TODO: Check what Windows does if the IStream doesn't write all of
458 * the data we give it at once.
460 hr
= IStream_Write(This
->dest
, buffer
->data
+This
->dest_written
,
461 buffer
->written
-This
->dest_written
, &written
);
463 WARN("Failed to write data to IStream (0x%08x)\n", hr
);
467 This
->dest_written
+= written
;
471 /* Newly added element start tag left unclosed cause for empty elements
472 we have to close it differently. */
473 static void close_element_starttag(const mxwriter
*This
)
475 static const WCHAR gtW
[] = {'>'};
476 if (!This
->element
) return;
477 write_output_buffer(This
->buffer
, gtW
, 1);
480 static void set_element_name(mxwriter
*This
, const WCHAR
*name
, int len
)
482 SysFreeString(This
->element
);
483 This
->element
= name
? SysAllocStringLen(name
, len
) : NULL
;
486 static inline HRESULT
flush_output_buffer(mxwriter
*This
)
488 close_element_starttag(This
);
489 set_element_name(This
, NULL
, 0);
491 return write_data_to_stream(This
);
494 /* Resets the mxwriter's output buffer by closing it, then creating a new
495 * output buffer using the given encoding.
497 static inline void reset_output_buffer(mxwriter
*This
)
499 close_output_buffer(This
);
500 This
->dest_written
= 0;
503 static HRESULT
writer_set_property(mxwriter
*writer
, mxwriter_prop property
, VARIANT_BOOL value
)
505 writer
->props
[property
] = value
;
506 writer
->prop_changed
= TRUE
;
510 static HRESULT
writer_get_property(const mxwriter
*writer
, mxwriter_prop property
, VARIANT_BOOL
*value
)
512 if (!value
) return E_POINTER
;
513 *value
= writer
->props
[property
];
517 static inline mxwriter
*impl_from_IMXWriter(IMXWriter
*iface
)
519 return CONTAINING_RECORD(iface
, mxwriter
, IMXWriter_iface
);
522 static inline mxwriter
*impl_from_ISAXContentHandler(ISAXContentHandler
*iface
)
524 return CONTAINING_RECORD(iface
, mxwriter
, ISAXContentHandler_iface
);
527 static inline mxwriter
*impl_from_ISAXLexicalHandler(ISAXLexicalHandler
*iface
)
529 return CONTAINING_RECORD(iface
, mxwriter
, ISAXLexicalHandler_iface
);
532 static inline mxwriter
*impl_from_ISAXDeclHandler(ISAXDeclHandler
*iface
)
534 return CONTAINING_RECORD(iface
, mxwriter
, ISAXDeclHandler_iface
);
537 static HRESULT WINAPI
mxwriter_QueryInterface(IMXWriter
*iface
, REFIID riid
, void **obj
)
539 mxwriter
*This
= impl_from_IMXWriter( iface
);
541 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
545 if ( IsEqualGUID( riid
, &IID_IMXWriter
) ||
546 IsEqualGUID( riid
, &IID_IDispatch
) ||
547 IsEqualGUID( riid
, &IID_IUnknown
) )
549 *obj
= &This
->IMXWriter_iface
;
551 else if ( IsEqualGUID( riid
, &IID_ISAXContentHandler
) )
553 *obj
= &This
->ISAXContentHandler_iface
;
555 else if ( IsEqualGUID( riid
, &IID_ISAXLexicalHandler
) )
557 *obj
= &This
->ISAXLexicalHandler_iface
;
559 else if ( IsEqualGUID( riid
, &IID_ISAXDeclHandler
) )
561 *obj
= &This
->ISAXDeclHandler_iface
;
563 else if (dispex_query_interface(&This
->dispex
, riid
, obj
))
565 return *obj
? S_OK
: E_NOINTERFACE
;
569 ERR("interface %s not implemented\n", debugstr_guid(riid
));
571 return E_NOINTERFACE
;
574 IMXWriter_AddRef(iface
);
578 static ULONG WINAPI
mxwriter_AddRef(IMXWriter
*iface
)
580 mxwriter
*This
= impl_from_IMXWriter( iface
);
581 LONG ref
= InterlockedIncrement(&This
->ref
);
583 TRACE("(%p)->(%d)\n", This
, ref
);
588 static ULONG WINAPI
mxwriter_Release(IMXWriter
*iface
)
590 mxwriter
*This
= impl_from_IMXWriter( iface
);
591 ULONG ref
= InterlockedDecrement(&This
->ref
);
593 TRACE("(%p)->(%d)\n", This
, ref
);
597 /* Windows flushes the buffer when the interface is destroyed. */
598 flush_output_buffer(This
);
599 free_output_buffer(This
->buffer
);
601 if (This
->dest
) IStream_Release(This
->dest
);
602 SysFreeString(This
->version
);
603 SysFreeString(This
->encoding
);
605 SysFreeString(This
->element
);
606 release_dispex(&This
->dispex
);
613 static HRESULT WINAPI
mxwriter_GetTypeInfoCount(IMXWriter
*iface
, UINT
* pctinfo
)
615 mxwriter
*This
= impl_from_IMXWriter( iface
);
616 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
619 static HRESULT WINAPI
mxwriter_GetTypeInfo(
621 UINT iTInfo
, LCID lcid
,
622 ITypeInfo
** ppTInfo
)
624 mxwriter
*This
= impl_from_IMXWriter( iface
);
625 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
626 iTInfo
, lcid
, ppTInfo
);
629 static HRESULT WINAPI
mxwriter_GetIDsOfNames(
631 REFIID riid
, LPOLESTR
* rgszNames
,
632 UINT cNames
, LCID lcid
, DISPID
* rgDispId
)
634 mxwriter
*This
= impl_from_IMXWriter( iface
);
635 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
636 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
639 static HRESULT WINAPI
mxwriter_Invoke(
641 DISPID dispIdMember
, REFIID riid
, LCID lcid
,
642 WORD wFlags
, DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
643 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
645 mxwriter
*This
= impl_from_IMXWriter( iface
);
646 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
647 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
650 static HRESULT WINAPI
mxwriter_put_output(IMXWriter
*iface
, VARIANT dest
)
652 mxwriter
*This
= impl_from_IMXWriter( iface
);
655 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&dest
));
657 hr
= flush_output_buffer(This
);
665 if (This
->dest
) IStream_Release(This
->dest
);
667 reset_output_buffer(This
);
674 hr
= IUnknown_QueryInterface(V_UNKNOWN(&dest
), &IID_IStream
, (void**)&stream
);
677 /* Recreate the output buffer to make sure it's using the correct encoding. */
678 reset_output_buffer(This
);
680 if (This
->dest
) IStream_Release(This
->dest
);
685 FIXME("unhandled interface type for VT_UNKNOWN destination\n");
689 FIXME("unhandled destination type %s\n", debugstr_variant(&dest
));
696 static HRESULT WINAPI
mxwriter_get_output(IMXWriter
*iface
, VARIANT
*dest
)
698 mxwriter
*This
= impl_from_IMXWriter( iface
);
700 TRACE("(%p)->(%p)\n", This
, dest
);
704 HRESULT hr
= flush_output_buffer(This
);
708 V_VT(dest
) = VT_BSTR
;
709 V_BSTR(dest
) = SysAllocString((WCHAR
*)This
->buffer
->utf16
.data
);
714 FIXME("not implemented when stream is set up\n");
719 static HRESULT WINAPI
mxwriter_put_encoding(IMXWriter
*iface
, BSTR encoding
)
721 mxwriter
*This
= impl_from_IMXWriter( iface
);
725 TRACE("(%p)->(%s)\n", This
, debugstr_w(encoding
));
727 enc
= parse_encoding_name(encoding
);
728 if (enc
== XmlEncoding_Unknown
)
730 FIXME("unsupported encoding %s\n", debugstr_w(encoding
));
734 hr
= flush_output_buffer(This
);
738 SysReAllocString(&This
->encoding
, encoding
);
741 TRACE("got encoding %d\n", This
->xml_enc
);
742 reset_output_buffer(This
);
746 static HRESULT WINAPI
mxwriter_get_encoding(IMXWriter
*iface
, BSTR
*encoding
)
748 mxwriter
*This
= impl_from_IMXWriter( iface
);
750 TRACE("(%p)->(%p)\n", This
, encoding
);
752 if (!encoding
) return E_POINTER
;
754 *encoding
= SysAllocString(This
->encoding
);
755 if (!*encoding
) return E_OUTOFMEMORY
;
760 static HRESULT WINAPI
mxwriter_put_byteOrderMark(IMXWriter
*iface
, VARIANT_BOOL value
)
762 mxwriter
*This
= impl_from_IMXWriter( iface
);
764 TRACE("(%p)->(%d)\n", This
, value
);
765 return writer_set_property(This
, MXWriter_BOM
, value
);
768 static HRESULT WINAPI
mxwriter_get_byteOrderMark(IMXWriter
*iface
, VARIANT_BOOL
*value
)
770 mxwriter
*This
= impl_from_IMXWriter( iface
);
772 TRACE("(%p)->(%p)\n", This
, value
);
773 return writer_get_property(This
, MXWriter_BOM
, value
);
776 static HRESULT WINAPI
mxwriter_put_indent(IMXWriter
*iface
, VARIANT_BOOL value
)
778 mxwriter
*This
= impl_from_IMXWriter( iface
);
780 TRACE("(%p)->(%d)\n", This
, value
);
781 return writer_set_property(This
, MXWriter_Indent
, value
);
784 static HRESULT WINAPI
mxwriter_get_indent(IMXWriter
*iface
, VARIANT_BOOL
*value
)
786 mxwriter
*This
= impl_from_IMXWriter( iface
);
788 TRACE("(%p)->(%p)\n", This
, value
);
789 return writer_get_property(This
, MXWriter_Indent
, value
);
792 static HRESULT WINAPI
mxwriter_put_standalone(IMXWriter
*iface
, VARIANT_BOOL value
)
794 mxwriter
*This
= impl_from_IMXWriter( iface
);
796 TRACE("(%p)->(%d)\n", This
, value
);
797 return writer_set_property(This
, MXWriter_Standalone
, value
);
800 static HRESULT WINAPI
mxwriter_get_standalone(IMXWriter
*iface
, VARIANT_BOOL
*value
)
802 mxwriter
*This
= impl_from_IMXWriter( iface
);
804 TRACE("(%p)->(%p)\n", This
, value
);
805 return writer_get_property(This
, MXWriter_Standalone
, value
);
808 static HRESULT WINAPI
mxwriter_put_omitXMLDeclaration(IMXWriter
*iface
, VARIANT_BOOL value
)
810 mxwriter
*This
= impl_from_IMXWriter( iface
);
812 TRACE("(%p)->(%d)\n", This
, value
);
813 return writer_set_property(This
, MXWriter_OmitXmlDecl
, value
);
816 static HRESULT WINAPI
mxwriter_get_omitXMLDeclaration(IMXWriter
*iface
, VARIANT_BOOL
*value
)
818 mxwriter
*This
= impl_from_IMXWriter( iface
);
820 TRACE("(%p)->(%p)\n", This
, value
);
821 return writer_get_property(This
, MXWriter_OmitXmlDecl
, value
);
824 static HRESULT WINAPI
mxwriter_put_version(IMXWriter
*iface
, BSTR version
)
826 mxwriter
*This
= impl_from_IMXWriter( iface
);
828 TRACE("(%p)->(%s)\n", This
, debugstr_w(version
));
830 if (!version
) return E_INVALIDARG
;
832 SysFreeString(This
->version
);
833 This
->version
= SysAllocString(version
);
838 static HRESULT WINAPI
mxwriter_get_version(IMXWriter
*iface
, BSTR
*version
)
840 mxwriter
*This
= impl_from_IMXWriter( iface
);
842 TRACE("(%p)->(%p)\n", This
, version
);
844 if (!version
) return E_POINTER
;
846 return return_bstr(This
->version
, version
);
849 static HRESULT WINAPI
mxwriter_put_disableOutputEscaping(IMXWriter
*iface
, VARIANT_BOOL value
)
851 mxwriter
*This
= impl_from_IMXWriter( iface
);
853 TRACE("(%p)->(%d)\n", This
, value
);
854 return writer_set_property(This
, MXWriter_DisableEscaping
, value
);
857 static HRESULT WINAPI
mxwriter_get_disableOutputEscaping(IMXWriter
*iface
, VARIANT_BOOL
*value
)
859 mxwriter
*This
= impl_from_IMXWriter( iface
);
861 TRACE("(%p)->(%p)\n", This
, value
);
862 return writer_get_property(This
, MXWriter_DisableEscaping
, value
);
865 static HRESULT WINAPI
mxwriter_flush(IMXWriter
*iface
)
867 mxwriter
*This
= impl_from_IMXWriter( iface
);
868 TRACE("(%p)\n", This
);
869 return flush_output_buffer(This
);
872 static const struct IMXWriterVtbl MXWriterVtbl
=
874 mxwriter_QueryInterface
,
877 mxwriter_GetTypeInfoCount
,
878 mxwriter_GetTypeInfo
,
879 mxwriter_GetIDsOfNames
,
883 mxwriter_put_encoding
,
884 mxwriter_get_encoding
,
885 mxwriter_put_byteOrderMark
,
886 mxwriter_get_byteOrderMark
,
889 mxwriter_put_standalone
,
890 mxwriter_get_standalone
,
891 mxwriter_put_omitXMLDeclaration
,
892 mxwriter_get_omitXMLDeclaration
,
893 mxwriter_put_version
,
894 mxwriter_get_version
,
895 mxwriter_put_disableOutputEscaping
,
896 mxwriter_get_disableOutputEscaping
,
900 /*** ISAXContentHandler ***/
901 static HRESULT WINAPI
SAXContentHandler_QueryInterface(
902 ISAXContentHandler
*iface
,
906 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
907 return IMXWriter_QueryInterface(&This
->IMXWriter_iface
, riid
, obj
);
910 static ULONG WINAPI
SAXContentHandler_AddRef(ISAXContentHandler
*iface
)
912 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
913 return IMXWriter_AddRef(&This
->IMXWriter_iface
);
916 static ULONG WINAPI
SAXContentHandler_Release(ISAXContentHandler
*iface
)
918 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
919 return IMXWriter_Release(&This
->IMXWriter_iface
);
922 static HRESULT WINAPI
SAXContentHandler_putDocumentLocator(
923 ISAXContentHandler
*iface
,
924 ISAXLocator
*locator
)
926 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
927 FIXME("(%p)->(%p)\n", This
, locator
);
931 static HRESULT WINAPI
SAXContentHandler_startDocument(ISAXContentHandler
*iface
)
933 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
935 TRACE("(%p)\n", This
);
937 /* If properties have been changed since the last "endDocument" call
938 * we need to reset the output buffer. If we don't the output buffer
939 * could end up with multiple XML documents in it, plus this seems to
940 * be how Windows works.
942 if (This
->prop_changed
) {
943 reset_output_buffer(This
);
944 This
->prop_changed
= FALSE
;
947 if (This
->props
[MXWriter_OmitXmlDecl
] == VARIANT_TRUE
) return S_OK
;
949 write_prolog_buffer(This
);
951 if (This
->dest
&& This
->xml_enc
== XmlEncoding_UTF16
) {
952 static const char utf16BOM
[] = {0xff,0xfe};
954 if (This
->props
[MXWriter_BOM
] == VARIANT_TRUE
)
955 /* Windows passes a NULL pointer as the pcbWritten parameter and
956 * ignores any error codes returned from this Write call.
958 IStream_Write(This
->dest
, utf16BOM
, sizeof(utf16BOM
), NULL
);
964 static HRESULT WINAPI
SAXContentHandler_endDocument(ISAXContentHandler
*iface
)
966 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
967 TRACE("(%p)\n", This
);
968 This
->prop_changed
= FALSE
;
969 return flush_output_buffer(This
);
972 static HRESULT WINAPI
SAXContentHandler_startPrefixMapping(
973 ISAXContentHandler
*iface
,
979 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
980 FIXME("(%p)->(%s %s)\n", This
, debugstr_wn(prefix
, nprefix
), debugstr_wn(uri
, nuri
));
984 static HRESULT WINAPI
SAXContentHandler_endPrefixMapping(
985 ISAXContentHandler
*iface
,
989 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
990 FIXME("(%p)->(%s)\n", This
, debugstr_wn(prefix
, nprefix
));
994 static HRESULT WINAPI
SAXContentHandler_startElement(
995 ISAXContentHandler
*iface
,
996 const WCHAR
*namespaceUri
,
998 const WCHAR
*local_name
,
1002 ISAXAttributes
*attr
)
1004 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1005 static const WCHAR ltW
[] = {'<'};
1007 TRACE("(%p)->(%s %s %s %p)\n", This
, debugstr_wn(namespaceUri
, nnamespaceUri
),
1008 debugstr_wn(local_name
, nlocal_name
), debugstr_wn(QName
, nQName
), attr
);
1010 if ((!namespaceUri
|| !local_name
|| !QName
) && This
->class_version
!= MSXML6
)
1011 return E_INVALIDARG
;
1013 close_element_starttag(This
);
1014 set_element_name(This
, QName
? QName
: emptyW
,
1015 QName
? nQName
: 0);
1017 write_output_buffer(This
->buffer
, ltW
, 1);
1018 write_output_buffer(This
->buffer
, QName
, nQName
);
1026 hr
= ISAXAttributes_getLength(attr
, &length
);
1027 if (FAILED(hr
)) return hr
;
1029 for (i
= 0; i
< length
; i
++)
1031 static const WCHAR eqW
[] = {'='};
1036 hr
= ISAXAttributes_getQName(attr
, i
, &str
, &len
);
1037 if (FAILED(hr
)) return hr
;
1039 /* space separator in front of every attribute */
1040 write_output_buffer(This
->buffer
, spaceW
, 1);
1041 write_output_buffer(This
->buffer
, str
, len
);
1043 write_output_buffer(This
->buffer
, eqW
, 1);
1046 hr
= ISAXAttributes_getValue(attr
, i
, &str
, &len
);
1047 if (FAILED(hr
)) return hr
;
1049 escaped
= get_escaped_string(str
, EscapeValue
, &len
);
1050 write_output_buffer_quoted(This
->buffer
, escaped
, len
);
1058 static HRESULT WINAPI
SAXContentHandler_endElement(
1059 ISAXContentHandler
*iface
,
1060 const WCHAR
*namespaceUri
,
1062 const WCHAR
* local_name
,
1067 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1069 TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This
, debugstr_wn(namespaceUri
, nnamespaceUri
), nnamespaceUri
,
1070 debugstr_wn(local_name
, nlocal_name
), nlocal_name
, debugstr_wn(QName
, nQName
), nQName
);
1072 if ((!namespaceUri
|| !local_name
|| !QName
) && This
->class_version
!= MSXML6
)
1073 return E_INVALIDARG
;
1075 if (This
->element
&& QName
&& !strncmpW(This
->element
, QName
, nQName
))
1077 static const WCHAR closeW
[] = {'/','>'};
1079 write_output_buffer(This
->buffer
, closeW
, 2);
1083 static const WCHAR closetagW
[] = {'<','/'};
1084 static const WCHAR gtW
[] = {'>'};
1086 write_output_buffer(This
->buffer
, closetagW
, 2);
1087 write_output_buffer(This
->buffer
, QName
, nQName
);
1088 write_output_buffer(This
->buffer
, gtW
, 1);
1091 set_element_name(This
, NULL
, 0);
1096 static HRESULT WINAPI
SAXContentHandler_characters(
1097 ISAXContentHandler
*iface
,
1101 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1103 TRACE("(%p)->(%s:%d)\n", This
, debugstr_wn(chars
, nchars
), nchars
);
1105 if (!chars
) return E_INVALIDARG
;
1107 close_element_starttag(This
);
1108 set_element_name(This
, NULL
, 0);
1113 write_output_buffer(This
->buffer
, chars
, nchars
);
1119 escaped
= get_escaped_string(chars
, EscapeText
, &len
);
1120 write_output_buffer(This
->buffer
, escaped
, len
);
1128 static HRESULT WINAPI
SAXContentHandler_ignorableWhitespace(
1129 ISAXContentHandler
*iface
,
1133 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1135 TRACE("(%p)->(%s)\n", This
, debugstr_wn(chars
, nchars
));
1137 if (!chars
) return E_INVALIDARG
;
1139 write_output_buffer(This
->buffer
, chars
, nchars
);
1144 static HRESULT WINAPI
SAXContentHandler_processingInstruction(
1145 ISAXContentHandler
*iface
,
1146 const WCHAR
*target
,
1151 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1152 static const WCHAR openpiW
[] = {'<','?'};
1153 static const WCHAR closepiW
[] = {'?','>','\r','\n'};
1155 TRACE("(%p)->(%s %s)\n", This
, debugstr_wn(target
, ntarget
), debugstr_wn(data
, ndata
));
1157 if (!target
) return E_INVALIDARG
;
1159 write_output_buffer(This
->buffer
, openpiW
, sizeof(openpiW
)/sizeof(WCHAR
));
1162 write_output_buffer(This
->buffer
, target
, ntarget
);
1164 if (data
&& *data
&& ndata
)
1166 write_output_buffer(This
->buffer
, spaceW
, 1);
1167 write_output_buffer(This
->buffer
, data
, ndata
);
1170 write_output_buffer(This
->buffer
, closepiW
, sizeof(closepiW
)/sizeof(WCHAR
));
1175 static HRESULT WINAPI
SAXContentHandler_skippedEntity(
1176 ISAXContentHandler
*iface
,
1180 mxwriter
*This
= impl_from_ISAXContentHandler( iface
);
1181 FIXME("(%p)->(%s)\n", This
, debugstr_wn(name
, nname
));
1185 static const struct ISAXContentHandlerVtbl SAXContentHandlerVtbl
=
1187 SAXContentHandler_QueryInterface
,
1188 SAXContentHandler_AddRef
,
1189 SAXContentHandler_Release
,
1190 SAXContentHandler_putDocumentLocator
,
1191 SAXContentHandler_startDocument
,
1192 SAXContentHandler_endDocument
,
1193 SAXContentHandler_startPrefixMapping
,
1194 SAXContentHandler_endPrefixMapping
,
1195 SAXContentHandler_startElement
,
1196 SAXContentHandler_endElement
,
1197 SAXContentHandler_characters
,
1198 SAXContentHandler_ignorableWhitespace
,
1199 SAXContentHandler_processingInstruction
,
1200 SAXContentHandler_skippedEntity
1203 /*** ISAXLexicalHandler ***/
1204 static HRESULT WINAPI
SAXLexicalHandler_QueryInterface(ISAXLexicalHandler
*iface
,
1205 REFIID riid
, void **obj
)
1207 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1208 return IMXWriter_QueryInterface(&This
->IMXWriter_iface
, riid
, obj
);
1211 static ULONG WINAPI
SAXLexicalHandler_AddRef(ISAXLexicalHandler
*iface
)
1213 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1214 return IMXWriter_AddRef(&This
->IMXWriter_iface
);
1217 static ULONG WINAPI
SAXLexicalHandler_Release(ISAXLexicalHandler
*iface
)
1219 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1220 return IMXWriter_Release(&This
->IMXWriter_iface
);
1223 static HRESULT WINAPI
SAXLexicalHandler_startDTD(ISAXLexicalHandler
*iface
,
1224 const WCHAR
*name
, int name_len
, const WCHAR
*publicId
, int publicId_len
,
1225 const WCHAR
*systemId
, int systemId_len
)
1227 static const WCHAR doctypeW
[] = {'<','!','D','O','C','T','Y','P','E',' '};
1228 static const WCHAR openintW
[] = {'[','\r','\n'};
1230 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1232 TRACE("(%p)->(%s %s %s)\n", This
, debugstr_wn(name
, name_len
), debugstr_wn(publicId
, publicId_len
),
1233 debugstr_wn(systemId
, systemId_len
));
1235 if (!name
) return E_INVALIDARG
;
1237 write_output_buffer(This
->buffer
, doctypeW
, sizeof(doctypeW
)/sizeof(WCHAR
));
1241 write_output_buffer(This
->buffer
, name
, name_len
);
1242 write_output_buffer(This
->buffer
, spaceW
, 1);
1247 static const WCHAR publicW
[] = {'P','U','B','L','I','C',' '};
1249 write_output_buffer(This
->buffer
, publicW
, sizeof(publicW
)/sizeof(WCHAR
));
1250 write_output_buffer_quoted(This
->buffer
, publicId
, publicId_len
);
1252 if (!systemId
) return E_INVALIDARG
;
1255 write_output_buffer(This
->buffer
, spaceW
, 1);
1257 write_output_buffer_quoted(This
->buffer
, systemId
, systemId_len
);
1260 write_output_buffer(This
->buffer
, spaceW
, 1);
1264 static const WCHAR systemW
[] = {'S','Y','S','T','E','M',' '};
1266 write_output_buffer(This
->buffer
, systemW
, sizeof(systemW
)/sizeof(WCHAR
));
1267 write_output_buffer_quoted(This
->buffer
, systemId
, systemId_len
);
1269 write_output_buffer(This
->buffer
, spaceW
, 1);
1272 write_output_buffer(This
->buffer
, openintW
, sizeof(openintW
)/sizeof(WCHAR
));
1277 static HRESULT WINAPI
SAXLexicalHandler_endDTD(ISAXLexicalHandler
*iface
)
1279 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1280 static const WCHAR closedtdW
[] = {']','>','\r','\n'};
1282 TRACE("(%p)\n", This
);
1284 write_output_buffer(This
->buffer
, closedtdW
, sizeof(closedtdW
)/sizeof(WCHAR
));
1289 static HRESULT WINAPI
SAXLexicalHandler_startEntity(ISAXLexicalHandler
*iface
, const WCHAR
*name
, int len
)
1291 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1292 FIXME("(%p)->(%s): stub\n", This
, debugstr_wn(name
, len
));
1296 static HRESULT WINAPI
SAXLexicalHandler_endEntity(ISAXLexicalHandler
*iface
, const WCHAR
*name
, int len
)
1298 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1299 FIXME("(%p)->(%s): stub\n", This
, debugstr_wn(name
, len
));
1303 static HRESULT WINAPI
SAXLexicalHandler_startCDATA(ISAXLexicalHandler
*iface
)
1305 static const WCHAR scdataW
[] = {'<','!','[','C','D','A','T','A','['};
1306 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1308 TRACE("(%p)\n", This
);
1310 write_output_buffer(This
->buffer
, scdataW
, sizeof(scdataW
)/sizeof(WCHAR
));
1316 static HRESULT WINAPI
SAXLexicalHandler_endCDATA(ISAXLexicalHandler
*iface
)
1318 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1319 static const WCHAR ecdataW
[] = {']',']','>'};
1321 TRACE("(%p)\n", This
);
1323 write_output_buffer(This
->buffer
, ecdataW
, sizeof(ecdataW
)/sizeof(WCHAR
));
1324 This
->cdata
= FALSE
;
1329 static HRESULT WINAPI
SAXLexicalHandler_comment(ISAXLexicalHandler
*iface
, const WCHAR
*chars
, int nchars
)
1331 mxwriter
*This
= impl_from_ISAXLexicalHandler( iface
);
1332 static const WCHAR copenW
[] = {'<','!','-','-'};
1333 static const WCHAR ccloseW
[] = {'-','-','>','\r','\n'};
1335 TRACE("(%p)->(%s:%d)\n", This
, debugstr_wn(chars
, nchars
), nchars
);
1337 if (!chars
) return E_INVALIDARG
;
1339 close_element_starttag(This
);
1341 write_output_buffer(This
->buffer
, copenW
, sizeof(copenW
)/sizeof(WCHAR
));
1343 write_output_buffer(This
->buffer
, chars
, nchars
);
1344 write_output_buffer(This
->buffer
, ccloseW
, sizeof(ccloseW
)/sizeof(WCHAR
));
1349 static const struct ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl
=
1351 SAXLexicalHandler_QueryInterface
,
1352 SAXLexicalHandler_AddRef
,
1353 SAXLexicalHandler_Release
,
1354 SAXLexicalHandler_startDTD
,
1355 SAXLexicalHandler_endDTD
,
1356 SAXLexicalHandler_startEntity
,
1357 SAXLexicalHandler_endEntity
,
1358 SAXLexicalHandler_startCDATA
,
1359 SAXLexicalHandler_endCDATA
,
1360 SAXLexicalHandler_comment
1363 /*** ISAXDeclHandler ***/
1364 static HRESULT WINAPI
SAXDeclHandler_QueryInterface(ISAXDeclHandler
*iface
,
1365 REFIID riid
, void **obj
)
1367 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1368 return IMXWriter_QueryInterface(&This
->IMXWriter_iface
, riid
, obj
);
1371 static ULONG WINAPI
SAXDeclHandler_AddRef(ISAXDeclHandler
*iface
)
1373 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1374 return IMXWriter_AddRef(&This
->IMXWriter_iface
);
1377 static ULONG WINAPI
SAXDeclHandler_Release(ISAXDeclHandler
*iface
)
1379 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1380 return IMXWriter_Release(&This
->IMXWriter_iface
);
1383 static HRESULT WINAPI
SAXDeclHandler_elementDecl(ISAXDeclHandler
*iface
,
1384 const WCHAR
*name
, int n_name
, const WCHAR
*model
, int n_model
)
1386 static const WCHAR elementW
[] = {'<','!','E','L','E','M','E','N','T',' '};
1387 static const WCHAR closeelementW
[] = {'>','\r','\n'};
1388 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1390 TRACE("(%p)->(%s:%d %s:%d)\n", This
, debugstr_wn(name
, n_name
), n_name
,
1391 debugstr_wn(model
, n_model
), n_model
);
1393 if (!name
|| !model
) return E_INVALIDARG
;
1395 write_output_buffer(This
->buffer
, elementW
, sizeof(elementW
)/sizeof(WCHAR
));
1397 write_output_buffer(This
->buffer
, name
, n_name
);
1398 write_output_buffer(This
->buffer
, spaceW
, sizeof(spaceW
)/sizeof(WCHAR
));
1401 write_output_buffer(This
->buffer
, model
, n_model
);
1402 write_output_buffer(This
->buffer
, closeelementW
, sizeof(closeelementW
)/sizeof(WCHAR
));
1407 static HRESULT WINAPI
SAXDeclHandler_attributeDecl(ISAXDeclHandler
*iface
,
1408 const WCHAR
*element
, int n_element
, const WCHAR
*attr
, int n_attr
,
1409 const WCHAR
*type
, int n_type
, const WCHAR
*Default
, int n_default
,
1410 const WCHAR
*value
, int n_value
)
1412 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1413 FIXME("(%p)->(%s:%d %s:%d %s:%d %s:%d %s:%d): stub\n", This
, debugstr_wn(element
, n_element
), n_element
,
1414 debugstr_wn(attr
, n_attr
), n_attr
, debugstr_wn(type
, n_type
), n_type
, debugstr_wn(Default
, n_default
), n_default
,
1415 debugstr_wn(value
, n_value
), n_value
);
1419 static HRESULT WINAPI
SAXDeclHandler_internalEntityDecl(ISAXDeclHandler
*iface
,
1420 const WCHAR
*name
, int n_name
, const WCHAR
*value
, int n_value
)
1422 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1423 FIXME("(%p)->(%s:%d %s:%d): stub\n", This
, debugstr_wn(name
, n_name
), n_name
,
1424 debugstr_wn(value
, n_value
), n_value
);
1428 static HRESULT WINAPI
SAXDeclHandler_externalEntityDecl(ISAXDeclHandler
*iface
,
1429 const WCHAR
*name
, int n_name
, const WCHAR
*publicId
, int n_publicId
,
1430 const WCHAR
*systemId
, int n_systemId
)
1432 mxwriter
*This
= impl_from_ISAXDeclHandler( iface
);
1433 FIXME("(%p)->(%s:%d %s:%d %s:%d): stub\n", This
, debugstr_wn(name
, n_name
), n_name
,
1434 debugstr_wn(publicId
, n_publicId
), n_publicId
, debugstr_wn(systemId
, n_systemId
), n_systemId
);
1438 static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl
= {
1439 SAXDeclHandler_QueryInterface
,
1440 SAXDeclHandler_AddRef
,
1441 SAXDeclHandler_Release
,
1442 SAXDeclHandler_elementDecl
,
1443 SAXDeclHandler_attributeDecl
,
1444 SAXDeclHandler_internalEntityDecl
,
1445 SAXDeclHandler_externalEntityDecl
1448 static const tid_t mxwriter_iface_tids
[] = {
1453 static dispex_static_data_t mxwriter_dispex
= {
1460 HRESULT
MXWriter_create(MSXML_VERSION version
, IUnknown
*outer
, void **ppObj
)
1462 static const WCHAR version10W
[] = {'1','.','0',0};
1466 TRACE("(%p, %p)\n", outer
, ppObj
);
1468 if (outer
) FIXME("support aggregation, outer\n");
1470 This
= heap_alloc( sizeof (*This
) );
1472 return E_OUTOFMEMORY
;
1474 This
->IMXWriter_iface
.lpVtbl
= &MXWriterVtbl
;
1475 This
->ISAXContentHandler_iface
.lpVtbl
= &SAXContentHandlerVtbl
;
1476 This
->ISAXLexicalHandler_iface
.lpVtbl
= &SAXLexicalHandlerVtbl
;
1477 This
->ISAXDeclHandler_iface
.lpVtbl
= &SAXDeclHandlerVtbl
;
1479 This
->class_version
= version
;
1481 This
->props
[MXWriter_BOM
] = VARIANT_TRUE
;
1482 This
->props
[MXWriter_DisableEscaping
] = VARIANT_FALSE
;
1483 This
->props
[MXWriter_Indent
] = VARIANT_FALSE
;
1484 This
->props
[MXWriter_OmitXmlDecl
] = VARIANT_FALSE
;
1485 This
->props
[MXWriter_Standalone
] = VARIANT_FALSE
;
1486 This
->prop_changed
= FALSE
;
1487 This
->encoding
= SysAllocString(utf16W
);
1488 This
->version
= SysAllocString(version10W
);
1489 This
->xml_enc
= XmlEncoding_UTF16
;
1491 This
->element
= NULL
;
1492 This
->cdata
= FALSE
;
1495 This
->dest_written
= 0;
1497 hr
= alloc_output_buffer(This
->xml_enc
, &This
->buffer
);
1499 SysFreeString(This
->encoding
);
1500 SysFreeString(This
->version
);
1505 init_dispex(&This
->dispex
, (IUnknown
*)&This
->IMXWriter_iface
, &mxwriter_dispex
);
1507 *ppObj
= &This
->IMXWriter_iface
;
1509 TRACE("returning iface %p\n", *ppObj
);
1514 static HRESULT WINAPI
MXAttributes_QueryInterface(IMXAttributes
*iface
, REFIID riid
, void **ppObj
)
1516 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1518 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( riid
), ppObj
);
1522 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
1523 IsEqualGUID( riid
, &IID_IDispatch
) ||
1524 IsEqualGUID( riid
, &IID_IMXAttributes
))
1528 else if ( IsEqualGUID( riid
, &IID_ISAXAttributes
))
1530 *ppObj
= &This
->ISAXAttributes_iface
;
1532 else if ( IsEqualGUID( riid
, &IID_IVBSAXAttributes
))
1534 *ppObj
= &This
->IVBSAXAttributes_iface
;
1536 else if (dispex_query_interface(&This
->dispex
, riid
, ppObj
))
1538 return *ppObj
? S_OK
: E_NOINTERFACE
;
1542 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
1543 return E_NOINTERFACE
;
1546 IMXAttributes_AddRef( iface
);
1551 static ULONG WINAPI
MXAttributes_AddRef(IMXAttributes
*iface
)
1553 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1554 ULONG ref
= InterlockedIncrement( &This
->ref
);
1555 TRACE("(%p)->(%d)\n", This
, ref
);
1559 static ULONG WINAPI
MXAttributes_Release(IMXAttributes
*iface
)
1561 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1562 LONG ref
= InterlockedDecrement( &This
->ref
);
1564 TRACE("(%p)->(%d)\n", This
, ref
);
1570 for (i
= 0; i
< This
->length
; i
++)
1572 SysFreeString(This
->attr
[i
].qname
);
1573 SysFreeString(This
->attr
[i
].local
);
1574 SysFreeString(This
->attr
[i
].uri
);
1575 SysFreeString(This
->attr
[i
].type
);
1576 SysFreeString(This
->attr
[i
].value
);
1579 release_dispex(&This
->dispex
);
1580 heap_free(This
->attr
);
1587 static HRESULT WINAPI
MXAttributes_GetTypeInfoCount(IMXAttributes
*iface
, UINT
* pctinfo
)
1589 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1590 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1593 static HRESULT WINAPI
MXAttributes_GetTypeInfo(IMXAttributes
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
1595 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1596 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1599 static HRESULT WINAPI
MXAttributes_GetIDsOfNames(
1600 IMXAttributes
*iface
,
1602 LPOLESTR
* rgszNames
,
1607 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1608 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
1609 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
1612 static HRESULT WINAPI
MXAttributes_Invoke(
1613 IMXAttributes
*iface
,
1614 DISPID dispIdMember
,
1618 DISPPARAMS
* pDispParams
,
1619 VARIANT
* pVarResult
,
1620 EXCEPINFO
* pExcepInfo
,
1623 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1624 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
1625 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1628 static HRESULT WINAPI
MXAttributes_addAttribute(IMXAttributes
*iface
,
1629 BSTR uri
, BSTR localName
, BSTR QName
, BSTR type
, BSTR value
)
1631 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1635 TRACE("(%p)->(%s %s %s %s %s)\n", This
, debugstr_w(uri
), debugstr_w(localName
),
1636 debugstr_w(QName
), debugstr_w(type
), debugstr_w(value
));
1638 if ((!uri
|| !localName
|| !QName
|| !type
|| !value
) && This
->class_version
!= MSXML6
)
1639 return E_INVALIDARG
;
1641 /* ensure array is large enough */
1642 hr
= mxattributes_grow(This
);
1643 if (hr
!= S_OK
) return hr
;
1645 attr
= &This
->attr
[This
->length
];
1647 attr
->qname
= SysAllocString(QName
);
1648 attr
->local
= SysAllocString(localName
);
1649 attr
->uri
= SysAllocString(uri
);
1650 attr
->type
= SysAllocString(type
? type
: emptyW
);
1651 attr
->value
= SysAllocString(value
);
1657 static HRESULT WINAPI
MXAttributes_addAttributeFromIndex(IMXAttributes
*iface
,
1658 VARIANT atts
, int index
)
1660 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1661 FIXME("(%p)->(%s %d): stub\n", This
, debugstr_variant(&atts
), index
);
1665 static HRESULT WINAPI
MXAttributes_clear(IMXAttributes
*iface
)
1667 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1668 FIXME("(%p): stub\n", This
);
1672 static HRESULT WINAPI
MXAttributes_removeAttribute(IMXAttributes
*iface
, int index
)
1674 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1675 FIXME("(%p)->(%d): stub\n", This
, index
);
1679 static HRESULT WINAPI
MXAttributes_setAttribute(IMXAttributes
*iface
, int index
,
1680 BSTR uri
, BSTR localName
, BSTR QName
, BSTR type
, BSTR value
)
1682 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1683 FIXME("(%p)->(%d %s %s %s %s %s): stub\n", This
, index
, debugstr_w(uri
),
1684 debugstr_w(localName
), debugstr_w(QName
), debugstr_w(type
), debugstr_w(value
));
1688 static HRESULT WINAPI
MXAttributes_setAttributes(IMXAttributes
*iface
, VARIANT atts
)
1690 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1691 FIXME("(%p)->(%s): stub\n", This
, debugstr_variant(&atts
));
1695 static HRESULT WINAPI
MXAttributes_setLocalName(IMXAttributes
*iface
, int index
,
1698 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1699 FIXME("(%p)->(%d %s): stub\n", This
, index
, debugstr_w(localName
));
1703 static HRESULT WINAPI
MXAttributes_setQName(IMXAttributes
*iface
, int index
, BSTR QName
)
1705 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1706 FIXME("(%p)->(%d %s): stub\n", This
, index
, debugstr_w(QName
));
1710 static HRESULT WINAPI
MXAttributes_setURI(IMXAttributes
*iface
, int index
, BSTR uri
)
1712 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1713 FIXME("(%p)->(%d %s): stub\n", This
, index
, debugstr_w(uri
));
1717 static HRESULT WINAPI
MXAttributes_setValue(IMXAttributes
*iface
, int index
, BSTR value
)
1719 mxattributes
*This
= impl_from_IMXAttributes( iface
);
1720 FIXME("(%p)->(%d %s): stub\n", This
, index
, debugstr_w(value
));
1724 static const IMXAttributesVtbl MXAttributesVtbl
= {
1725 MXAttributes_QueryInterface
,
1726 MXAttributes_AddRef
,
1727 MXAttributes_Release
,
1728 MXAttributes_GetTypeInfoCount
,
1729 MXAttributes_GetTypeInfo
,
1730 MXAttributes_GetIDsOfNames
,
1731 MXAttributes_Invoke
,
1732 MXAttributes_addAttribute
,
1733 MXAttributes_addAttributeFromIndex
,
1735 MXAttributes_removeAttribute
,
1736 MXAttributes_setAttribute
,
1737 MXAttributes_setAttributes
,
1738 MXAttributes_setLocalName
,
1739 MXAttributes_setQName
,
1740 MXAttributes_setURI
,
1741 MXAttributes_setValue
1744 static HRESULT WINAPI
SAXAttributes_QueryInterface(ISAXAttributes
*iface
, REFIID riid
, void **ppObj
)
1746 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1747 return IMXAttributes_QueryInterface(&This
->IMXAttributes_iface
, riid
, ppObj
);
1750 static ULONG WINAPI
SAXAttributes_AddRef(ISAXAttributes
*iface
)
1752 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1753 return IMXAttributes_AddRef(&This
->IMXAttributes_iface
);
1756 static ULONG WINAPI
SAXAttributes_Release(ISAXAttributes
*iface
)
1758 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1759 return IMXAttributes_Release(&This
->IMXAttributes_iface
);
1762 static HRESULT WINAPI
SAXAttributes_getLength(ISAXAttributes
*iface
, int *length
)
1764 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1765 TRACE("(%p)->(%p)\n", This
, length
);
1767 if (!length
&& (This
->class_version
== MSXML_DEFAULT
|| This
->class_version
== MSXML3
))
1770 *length
= This
->length
;
1775 static HRESULT WINAPI
SAXAttributes_getURI(ISAXAttributes
*iface
, int nIndex
, const WCHAR
**pUrl
,
1778 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1779 FIXME("(%p)->(%d %p %p): stub\n", This
, nIndex
, pUrl
, pUriSize
);
1783 static HRESULT WINAPI
SAXAttributes_getLocalName(ISAXAttributes
*iface
, int nIndex
, const WCHAR
**localName
,
1786 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1787 FIXME("(%p)->(%d %p %p): stub\n", This
, nIndex
, localName
, length
);
1791 static HRESULT WINAPI
SAXAttributes_getQName(ISAXAttributes
*iface
, int index
, const WCHAR
**qname
, int *length
)
1793 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1795 TRACE("(%p)->(%d %p %p)\n", This
, index
, qname
, length
);
1797 if (index
>= This
->length
) return E_INVALIDARG
;
1798 if (!qname
|| !length
) return E_POINTER
;
1800 *qname
= This
->attr
[index
].qname
;
1801 *length
= SysStringLen(This
->attr
[index
].qname
);
1806 static HRESULT WINAPI
SAXAttributes_getName(ISAXAttributes
*iface
, int nIndex
, const WCHAR
**pUri
, int *pUriLength
,
1807 const WCHAR
** pLocalName
, int * pLocalNameSize
, const WCHAR
** pQName
, int * pQNameLength
)
1809 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1810 FIXME("(%p)->(%d %p %p %p %p %p %p): stub\n", This
, nIndex
, pUri
, pUriLength
, pLocalName
, pLocalNameSize
,
1811 pQName
, pQNameLength
);
1815 static HRESULT WINAPI
SAXAttributes_getIndexFromName(ISAXAttributes
*iface
, const WCHAR
* pUri
, int cUriLength
,
1816 const WCHAR
* pLocalName
, int cocalNameLength
, int * index
)
1818 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1819 FIXME("(%p)->(%s:%d %s:%d %p): stub\n", This
, debugstr_wn(pUri
, cUriLength
), cUriLength
,
1820 debugstr_wn(pLocalName
, cocalNameLength
), cocalNameLength
, index
);
1824 static HRESULT WINAPI
SAXAttributes_getIndexFromQName(ISAXAttributes
*iface
, const WCHAR
*qname
,
1825 int len
, int *index
)
1827 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1830 TRACE("(%p)->(%s:%d %p)\n", This
, debugstr_wn(qname
, len
), len
, index
);
1832 if (!index
&& (This
->class_version
== MSXML_DEFAULT
|| This
->class_version
== MSXML3
))
1835 if (!qname
|| !index
|| !len
) return E_INVALIDARG
;
1837 for (i
= 0; i
< This
->length
; i
++)
1839 if (len
!= SysStringLen(This
->attr
[i
].qname
)) continue;
1840 if (strncmpW(qname
, This
->attr
[i
].qname
, len
)) continue;
1846 return E_INVALIDARG
;
1849 static HRESULT WINAPI
SAXAttributes_getType(ISAXAttributes
*iface
, int index
, const WCHAR
**type
,
1852 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1854 TRACE("(%p)->(%d %p %p)\n", This
, index
, type
, len
);
1856 if (index
>= This
->length
) return E_INVALIDARG
;
1858 if ((!type
|| !len
) && (This
->class_version
== MSXML_DEFAULT
|| This
->class_version
== MSXML3
))
1861 *type
= This
->attr
[index
].type
;
1862 *len
= SysStringLen(This
->attr
[index
].type
);
1867 static HRESULT WINAPI
SAXAttributes_getTypeFromName(ISAXAttributes
*iface
, const WCHAR
* pUri
, int nUri
,
1868 const WCHAR
* pLocalName
, int nLocalName
, const WCHAR
** pType
, int * nType
)
1870 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1871 FIXME("(%p)->(%s:%d %s:%d %p %p): stub\n", This
, debugstr_wn(pUri
, nUri
), nUri
,
1872 debugstr_wn(pLocalName
, nLocalName
), nLocalName
, pType
, nType
);
1876 static HRESULT WINAPI
SAXAttributes_getTypeFromQName(ISAXAttributes
*iface
, const WCHAR
* pQName
,
1877 int nQName
, const WCHAR
** pType
, int * nType
)
1879 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1880 FIXME("(%p)->(%s:%d %p %p): stub\n", This
, debugstr_wn(pQName
, nQName
), nQName
, pType
, nType
);
1884 static HRESULT WINAPI
SAXAttributes_getValue(ISAXAttributes
*iface
, int index
, const WCHAR
**value
,
1887 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1889 TRACE("(%p)->(%d %p %p)\n", This
, index
, value
, len
);
1891 if (index
>= This
->length
) return E_INVALIDARG
;
1893 if ((!value
|| !len
) && (This
->class_version
== MSXML_DEFAULT
|| This
->class_version
== MSXML3
))
1896 *value
= This
->attr
[index
].value
;
1897 *len
= SysStringLen(This
->attr
[index
].value
);
1902 static HRESULT WINAPI
SAXAttributes_getValueFromName(ISAXAttributes
*iface
, const WCHAR
* pUri
,
1903 int nUri
, const WCHAR
* pLocalName
, int nLocalName
, const WCHAR
** pValue
, int * nValue
)
1905 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1906 FIXME("(%p)->(%s:%d %s:%d %p %p): stub\n", This
, debugstr_wn(pUri
, nUri
), nUri
,
1907 debugstr_wn(pLocalName
, nLocalName
), nLocalName
, pValue
, nValue
);
1911 static HRESULT WINAPI
SAXAttributes_getValueFromQName(ISAXAttributes
*iface
, const WCHAR
*qname
,
1912 int qname_len
, const WCHAR
**value
, int *value_len
)
1914 mxattributes
*This
= impl_from_ISAXAttributes( iface
);
1918 TRACE("(%p)->(%s:%d %p %p)\n", This
, debugstr_wn(qname
, qname_len
), qname_len
, value
, value_len
);
1920 if (!qname
|| !value
|| !value_len
)
1921 return (This
->class_version
== MSXML_DEFAULT
|| This
->class_version
== MSXML3
) ? E_POINTER
: E_INVALIDARG
;
1923 hr
= ISAXAttributes_getIndexFromQName(iface
, qname
, qname_len
, &index
);
1925 hr
= ISAXAttributes_getValue(iface
, index
, value
, value_len
);
1930 static const ISAXAttributesVtbl SAXAttributesVtbl
= {
1931 SAXAttributes_QueryInterface
,
1932 SAXAttributes_AddRef
,
1933 SAXAttributes_Release
,
1934 SAXAttributes_getLength
,
1935 SAXAttributes_getURI
,
1936 SAXAttributes_getLocalName
,
1937 SAXAttributes_getQName
,
1938 SAXAttributes_getName
,
1939 SAXAttributes_getIndexFromName
,
1940 SAXAttributes_getIndexFromQName
,
1941 SAXAttributes_getType
,
1942 SAXAttributes_getTypeFromName
,
1943 SAXAttributes_getTypeFromQName
,
1944 SAXAttributes_getValue
,
1945 SAXAttributes_getValueFromName
,
1946 SAXAttributes_getValueFromQName
1949 static HRESULT WINAPI
VBSAXAttributes_QueryInterface(
1950 IVBSAXAttributes
* iface
,
1954 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
1955 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
1956 return ISAXAttributes_QueryInterface(&This
->ISAXAttributes_iface
, riid
, ppvObject
);
1959 static ULONG WINAPI
VBSAXAttributes_AddRef(IVBSAXAttributes
* iface
)
1961 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
1962 return ISAXAttributes_AddRef(&This
->ISAXAttributes_iface
);
1965 static ULONG WINAPI
VBSAXAttributes_Release(IVBSAXAttributes
* iface
)
1967 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
1968 return ISAXAttributes_Release(&This
->ISAXAttributes_iface
);
1971 static HRESULT WINAPI
VBSAXAttributes_GetTypeInfoCount( IVBSAXAttributes
*iface
, UINT
* pctinfo
)
1973 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
1975 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1982 static HRESULT WINAPI
VBSAXAttributes_GetTypeInfo(
1983 IVBSAXAttributes
*iface
,
1984 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
1986 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
1987 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1988 return get_typeinfo(IVBSAXAttributes_tid
, ppTInfo
);
1991 static HRESULT WINAPI
VBSAXAttributes_GetIDsOfNames(
1992 IVBSAXAttributes
*iface
,
1994 LPOLESTR
* rgszNames
,
1999 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2000 ITypeInfo
*typeinfo
;
2003 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
2006 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
2007 return E_INVALIDARG
;
2009 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
2012 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2013 ITypeInfo_Release(typeinfo
);
2019 static HRESULT WINAPI
VBSAXAttributes_Invoke(
2020 IVBSAXAttributes
*iface
,
2021 DISPID dispIdMember
,
2025 DISPPARAMS
* pDispParams
,
2026 VARIANT
* pVarResult
,
2027 EXCEPINFO
* pExcepInfo
,
2030 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2031 ITypeInfo
*typeinfo
;
2034 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2035 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2037 hr
= get_typeinfo(IVBSAXAttributes_tid
, &typeinfo
);
2040 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBSAXAttributes_iface
, dispIdMember
, wFlags
,
2041 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2042 ITypeInfo_Release(typeinfo
);
2048 static HRESULT WINAPI
VBSAXAttributes_get_length(IVBSAXAttributes
* iface
, int *len
)
2050 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2051 return ISAXAttributes_getLength(&This
->ISAXAttributes_iface
, len
);
2054 static HRESULT WINAPI
VBSAXAttributes_getURI(IVBSAXAttributes
* iface
, int index
, BSTR
*uri
)
2056 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2059 return ISAXAttributes_getURI(&This
->ISAXAttributes_iface
, index
, (const WCHAR
**)uri
, &len
);
2062 static HRESULT WINAPI
VBSAXAttributes_getLocalName(IVBSAXAttributes
* iface
, int index
, BSTR
*name
)
2064 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2067 return ISAXAttributes_getLocalName(&This
->ISAXAttributes_iface
, index
, (const WCHAR
**)name
, &len
);
2070 static HRESULT WINAPI
VBSAXAttributes_getQName(IVBSAXAttributes
* iface
, int index
, BSTR
*qname
)
2072 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2075 return ISAXAttributes_getQName(&This
->ISAXAttributes_iface
, index
, (const WCHAR
**)qname
, &len
);
2078 static HRESULT WINAPI
VBSAXAttributes_getIndexFromName(IVBSAXAttributes
* iface
, BSTR uri
, BSTR name
, int *index
)
2080 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2081 return ISAXAttributes_getIndexFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
2082 name
, SysStringLen(name
), index
);
2085 static HRESULT WINAPI
VBSAXAttributes_getIndexFromQName(IVBSAXAttributes
* iface
, BSTR qname
, int *index
)
2087 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2088 return ISAXAttributes_getIndexFromQName(&This
->ISAXAttributes_iface
, qname
,
2089 SysStringLen(qname
), index
);
2092 static HRESULT WINAPI
VBSAXAttributes_getType(IVBSAXAttributes
* iface
, int index
,BSTR
*type
)
2094 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2097 return ISAXAttributes_getType(&This
->ISAXAttributes_iface
, index
, (const WCHAR
**)type
, &len
);
2100 static HRESULT WINAPI
VBSAXAttributes_getTypeFromName(IVBSAXAttributes
* iface
, BSTR uri
,
2101 BSTR name
, BSTR
*type
)
2103 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2106 return ISAXAttributes_getTypeFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
2107 name
, SysStringLen(name
), (const WCHAR
**)type
, &len
);
2110 static HRESULT WINAPI
VBSAXAttributes_getTypeFromQName(IVBSAXAttributes
* iface
, BSTR qname
, BSTR
*type
)
2112 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2115 return ISAXAttributes_getTypeFromQName(&This
->ISAXAttributes_iface
, qname
, SysStringLen(qname
),
2116 (const WCHAR
**)type
, &len
);
2119 static HRESULT WINAPI
VBSAXAttributes_getValue(IVBSAXAttributes
* iface
, int index
, BSTR
*value
)
2121 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2124 return ISAXAttributes_getValue(&This
->ISAXAttributes_iface
, index
, (const WCHAR
**)value
, &len
);
2127 static HRESULT WINAPI
VBSAXAttributes_getValueFromName(IVBSAXAttributes
* iface
, BSTR uri
, BSTR name
,
2130 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2133 return ISAXAttributes_getValueFromName(&This
->ISAXAttributes_iface
, uri
, SysStringLen(uri
),
2134 name
, SysStringLen(name
), (const WCHAR
**)value
, &len
);
2137 static HRESULT WINAPI
VBSAXAttributes_getValueFromQName(IVBSAXAttributes
* iface
, BSTR qname
, BSTR
*value
)
2139 mxattributes
*This
= impl_from_IVBSAXAttributes( iface
);
2142 return ISAXAttributes_getValueFromQName(&This
->ISAXAttributes_iface
, qname
, SysStringLen(qname
),
2143 (const WCHAR
**)value
, &len
);
2146 static const struct IVBSAXAttributesVtbl VBSAXAttributesVtbl
=
2148 VBSAXAttributes_QueryInterface
,
2149 VBSAXAttributes_AddRef
,
2150 VBSAXAttributes_Release
,
2151 VBSAXAttributes_GetTypeInfoCount
,
2152 VBSAXAttributes_GetTypeInfo
,
2153 VBSAXAttributes_GetIDsOfNames
,
2154 VBSAXAttributes_Invoke
,
2155 VBSAXAttributes_get_length
,
2156 VBSAXAttributes_getURI
,
2157 VBSAXAttributes_getLocalName
,
2158 VBSAXAttributes_getQName
,
2159 VBSAXAttributes_getIndexFromName
,
2160 VBSAXAttributes_getIndexFromQName
,
2161 VBSAXAttributes_getType
,
2162 VBSAXAttributes_getTypeFromName
,
2163 VBSAXAttributes_getTypeFromQName
,
2164 VBSAXAttributes_getValue
,
2165 VBSAXAttributes_getValueFromName
,
2166 VBSAXAttributes_getValueFromQName
2169 static const tid_t mxattrs_iface_tids
[] = {
2174 static dispex_static_data_t mxattrs_dispex
= {
2181 HRESULT
SAXAttributes_create(MSXML_VERSION version
, IUnknown
*outer
, void **ppObj
)
2183 static const int default_count
= 10;
2186 TRACE("(%p, %p)\n", outer
, ppObj
);
2188 This
= heap_alloc( sizeof (*This
) );
2190 return E_OUTOFMEMORY
;
2192 This
->IMXAttributes_iface
.lpVtbl
= &MXAttributesVtbl
;
2193 This
->ISAXAttributes_iface
.lpVtbl
= &SAXAttributesVtbl
;
2194 This
->IVBSAXAttributes_iface
.lpVtbl
= &VBSAXAttributesVtbl
;
2197 This
->class_version
= version
;
2199 This
->attr
= heap_alloc(default_count
*sizeof(mxattribute
));
2201 This
->allocated
= default_count
;
2203 *ppObj
= &This
->IMXAttributes_iface
;
2205 init_dispex(&This
->dispex
, (IUnknown
*)&This
->IMXAttributes_iface
, &mxattrs_dispex
);
2207 TRACE("returning iface %p\n", *ppObj
);