xref: /reactos/dll/win32/msxml3/mxwriter.c (revision eb44c20c)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  *    MXWriter implementation
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 2011-2014, 2016 Nikolay Sivov for CodeWeavers
5c2c66affSColin Finck  * Copyright 2011 Thomas Mullaly
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck  *
12c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15c2c66affSColin Finck  * Lesser General Public License for more details.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck  */
21c2c66affSColin Finck 
22bab6b90fSAmine Khaldi #define COBJMACROS
23bab6b90fSAmine Khaldi #include "config.h"
24bab6b90fSAmine Khaldi 
25bab6b90fSAmine Khaldi #include <stdarg.h>
26bab6b90fSAmine Khaldi #ifdef HAVE_LIBXML2
27bab6b90fSAmine Khaldi # include <libxml/parser.h>
28bab6b90fSAmine Khaldi #endif
29bab6b90fSAmine Khaldi 
30bab6b90fSAmine Khaldi #include "windef.h"
31bab6b90fSAmine Khaldi #include "winbase.h"
32bab6b90fSAmine Khaldi #include "ole2.h"
33bab6b90fSAmine Khaldi 
34bab6b90fSAmine Khaldi #include "msxml6.h"
35bab6b90fSAmine Khaldi 
36bab6b90fSAmine Khaldi #include "wine/debug.h"
37bab6b90fSAmine Khaldi #include "wine/list.h"
38bab6b90fSAmine Khaldi 
39bab6b90fSAmine Khaldi #include "msxml_private.h"
40bab6b90fSAmine Khaldi 
41bab6b90fSAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(msxml);
42c2c66affSColin Finck 
43c2c66affSColin Finck static const WCHAR emptyW[] = {0};
44c2c66affSColin Finck static const WCHAR spaceW[] = {' '};
45c2c66affSColin Finck static const WCHAR quotW[]  = {'\"'};
46c2c66affSColin Finck static const WCHAR closetagW[] = {'>','\r','\n'};
47c2c66affSColin Finck static const WCHAR crlfW[] = {'\r','\n'};
48c2c66affSColin Finck static const WCHAR entityW[] = {'<','!','E','N','T','I','T','Y',' '};
49c2c66affSColin Finck static const WCHAR publicW[] = {'P','U','B','L','I','C',' '};
50c2c66affSColin Finck static const WCHAR systemW[] = {'S','Y','S','T','E','M',' '};
51c2c66affSColin Finck 
52c2c66affSColin Finck /* should be ordered as encoding names are sorted */
53c2c66affSColin Finck typedef enum
54c2c66affSColin Finck {
55c2c66affSColin Finck     XmlEncoding_ISO_8859_1 = 0,
56c2c66affSColin Finck     XmlEncoding_ISO_8859_13,
57c2c66affSColin Finck     XmlEncoding_ISO_8859_15,
58c2c66affSColin Finck     XmlEncoding_ISO_8859_2,
59c2c66affSColin Finck     XmlEncoding_ISO_8859_3,
60c2c66affSColin Finck     XmlEncoding_ISO_8859_4,
61c2c66affSColin Finck     XmlEncoding_ISO_8859_5,
62c2c66affSColin Finck     XmlEncoding_ISO_8859_7,
63c2c66affSColin Finck     XmlEncoding_ISO_8859_9,
64c2c66affSColin Finck     XmlEncoding_UTF16,
65c2c66affSColin Finck     XmlEncoding_UTF8,
66c2c66affSColin Finck     XmlEncoding_Unknown
67c2c66affSColin Finck } xml_encoding;
68c2c66affSColin Finck 
69c2c66affSColin Finck struct xml_encoding_data
70c2c66affSColin Finck {
71c2c66affSColin Finck     const WCHAR *encoding;
72c2c66affSColin Finck     xml_encoding enc;
73c2c66affSColin Finck     UINT cp;
74c2c66affSColin Finck };
75c2c66affSColin Finck 
76c2c66affSColin Finck static const WCHAR iso_8859_1W[] = {'i','s','o','-','8','8','5','9','-','1',0};
77c2c66affSColin Finck static const WCHAR iso_8859_2W[] = {'i','s','o','-','8','8','5','9','-','2',0};
78c2c66affSColin Finck static const WCHAR iso_8859_3W[] = {'i','s','o','-','8','8','5','9','-','3',0};
79c2c66affSColin Finck static const WCHAR iso_8859_4W[] = {'i','s','o','-','8','8','5','9','-','4',0};
80c2c66affSColin Finck static const WCHAR iso_8859_5W[] = {'i','s','o','-','8','8','5','9','-','5',0};
81c2c66affSColin Finck static const WCHAR iso_8859_7W[] = {'i','s','o','-','8','8','5','9','-','7',0};
82c2c66affSColin Finck static const WCHAR iso_8859_9W[] = {'i','s','o','-','8','8','5','9','-','9',0};
83c2c66affSColin Finck static const WCHAR iso_8859_13W[] = {'i','s','o','-','8','8','5','9','-','1','3',0};
84c2c66affSColin Finck static const WCHAR iso_8859_15W[] = {'i','s','o','-','8','8','5','9','-','1','5',0};
85c2c66affSColin Finck static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
86c2c66affSColin Finck static const WCHAR utf8W[] = {'U','T','F','-','8',0};
87c2c66affSColin Finck 
88c2c66affSColin Finck static const struct xml_encoding_data xml_encoding_map[] = {
89c2c66affSColin Finck     { iso_8859_1W,  XmlEncoding_ISO_8859_1,  28591 },
90c2c66affSColin Finck     { iso_8859_13W, XmlEncoding_ISO_8859_13, 28603 },
91c2c66affSColin Finck     { iso_8859_15W, XmlEncoding_ISO_8859_15, 28605 },
92c2c66affSColin Finck     { iso_8859_2W,  XmlEncoding_ISO_8859_2,  28592 },
93c2c66affSColin Finck     { iso_8859_3W,  XmlEncoding_ISO_8859_3,  28593 },
94c2c66affSColin Finck     { iso_8859_4W,  XmlEncoding_ISO_8859_4,  28594 },
95c2c66affSColin Finck     { iso_8859_5W,  XmlEncoding_ISO_8859_5,  28595 },
96c2c66affSColin Finck     { iso_8859_7W,  XmlEncoding_ISO_8859_7,  28597 },
97c2c66affSColin Finck     { iso_8859_9W,  XmlEncoding_ISO_8859_9,  28599 },
98c2c66affSColin Finck     { utf16W,       XmlEncoding_UTF16,          ~0 },
99c2c66affSColin Finck     { utf8W,        XmlEncoding_UTF8,      CP_UTF8 }
100c2c66affSColin Finck };
101c2c66affSColin Finck 
102c2c66affSColin Finck typedef enum
103c2c66affSColin Finck {
104c2c66affSColin Finck     MXWriter_BOM = 0,
105c2c66affSColin Finck     MXWriter_DisableEscaping,
106c2c66affSColin Finck     MXWriter_Indent,
107c2c66affSColin Finck     MXWriter_OmitXmlDecl,
108c2c66affSColin Finck     MXWriter_Standalone,
109c2c66affSColin Finck     MXWriter_LastProp
110c2c66affSColin Finck } mxwriter_prop;
111c2c66affSColin Finck 
112c2c66affSColin Finck typedef enum
113c2c66affSColin Finck {
114c2c66affSColin Finck     EscapeValue,
115c2c66affSColin Finck     EscapeText
116c2c66affSColin Finck } escape_mode;
117c2c66affSColin Finck 
118c2c66affSColin Finck typedef struct
119c2c66affSColin Finck {
120c2c66affSColin Finck     struct list entry;
121c2c66affSColin Finck     char *data;
122c2c66affSColin Finck     unsigned int allocated;
123c2c66affSColin Finck     unsigned int written;
124c2c66affSColin Finck } encoded_buffer;
125c2c66affSColin Finck 
126c2c66affSColin Finck typedef struct
127c2c66affSColin Finck {
128c2c66affSColin Finck     encoded_buffer encoded;
129c2c66affSColin Finck     UINT code_page;
130c2c66affSColin Finck     UINT utf16_total;   /* total number of bytes written since last buffer reinitialization */
131c2c66affSColin Finck     struct list blocks; /* only used when output was not set, for BSTR case */
132c2c66affSColin Finck } output_buffer;
133c2c66affSColin Finck 
134c2c66affSColin Finck typedef struct
135c2c66affSColin Finck {
136c2c66affSColin Finck     DispatchEx dispex;
137c2c66affSColin Finck     IMXWriter IMXWriter_iface;
138c2c66affSColin Finck     ISAXContentHandler ISAXContentHandler_iface;
139c2c66affSColin Finck     ISAXLexicalHandler ISAXLexicalHandler_iface;
140c2c66affSColin Finck     ISAXDeclHandler    ISAXDeclHandler_iface;
141c2c66affSColin Finck     ISAXDTDHandler     ISAXDTDHandler_iface;
142c2c66affSColin Finck     ISAXErrorHandler   ISAXErrorHandler_iface;
143c2c66affSColin Finck     IVBSAXDeclHandler  IVBSAXDeclHandler_iface;
144c2c66affSColin Finck     IVBSAXLexicalHandler IVBSAXLexicalHandler_iface;
145c2c66affSColin Finck     IVBSAXContentHandler IVBSAXContentHandler_iface;
146c2c66affSColin Finck     IVBSAXDTDHandler     IVBSAXDTDHandler_iface;
147c2c66affSColin Finck     IVBSAXErrorHandler   IVBSAXErrorHandler_iface;
148c2c66affSColin Finck 
149c2c66affSColin Finck     LONG ref;
150c2c66affSColin Finck     MSXML_VERSION class_version;
151c2c66affSColin Finck 
152c2c66affSColin Finck     VARIANT_BOOL props[MXWriter_LastProp];
153c2c66affSColin Finck     BOOL prop_changed;
154c2c66affSColin Finck     BOOL cdata;
155c2c66affSColin Finck 
156c2c66affSColin Finck     BOOL text; /* last node was text node, so we shouldn't indent next node */
157c2c66affSColin Finck     BOOL newline; /* newline was already added as a part of previous call */
158c2c66affSColin Finck     UINT indent; /* indentation level for next node */
159c2c66affSColin Finck 
160c2c66affSColin Finck     BSTR version;
161c2c66affSColin Finck 
162c2c66affSColin Finck     BSTR encoding; /* exact property value */
163c2c66affSColin Finck     xml_encoding xml_enc;
164c2c66affSColin Finck 
165c2c66affSColin Finck     /* contains a pending (or not closed yet) element name or NULL if
166c2c66affSColin Finck        we don't have to close */
167c2c66affSColin Finck     BSTR element;
168c2c66affSColin Finck 
169c2c66affSColin Finck     IStream *dest;
170c2c66affSColin Finck 
171c2c66affSColin Finck     output_buffer buffer;
172c2c66affSColin Finck } mxwriter;
173c2c66affSColin Finck 
174c2c66affSColin Finck typedef struct
175c2c66affSColin Finck {
176c2c66affSColin Finck     BSTR qname;
177c2c66affSColin Finck     BSTR local;
178c2c66affSColin Finck     BSTR uri;
179c2c66affSColin Finck     BSTR type;
180c2c66affSColin Finck     BSTR value;
181c2c66affSColin Finck } mxattribute;
182c2c66affSColin Finck 
183c2c66affSColin Finck typedef struct
184c2c66affSColin Finck {
185c2c66affSColin Finck     DispatchEx dispex;
186c2c66affSColin Finck     IMXAttributes IMXAttributes_iface;
187c2c66affSColin Finck     ISAXAttributes ISAXAttributes_iface;
188c2c66affSColin Finck     IVBSAXAttributes IVBSAXAttributes_iface;
189c2c66affSColin Finck     LONG ref;
190c2c66affSColin Finck 
191c2c66affSColin Finck     MSXML_VERSION class_version;
192c2c66affSColin Finck 
193c2c66affSColin Finck     mxattribute *attr;
194c2c66affSColin Finck     int length;
195c2c66affSColin Finck     int allocated;
196c2c66affSColin Finck } mxattributes;
197c2c66affSColin Finck 
impl_from_IMXAttributes(IMXAttributes * iface)198c2c66affSColin Finck static inline mxattributes *impl_from_IMXAttributes( IMXAttributes *iface )
199c2c66affSColin Finck {
200c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxattributes, IMXAttributes_iface);
201c2c66affSColin Finck }
202c2c66affSColin Finck 
impl_from_ISAXAttributes(ISAXAttributes * iface)203c2c66affSColin Finck static inline mxattributes *impl_from_ISAXAttributes( ISAXAttributes *iface )
204c2c66affSColin Finck {
205c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxattributes, ISAXAttributes_iface);
206c2c66affSColin Finck }
207c2c66affSColin Finck 
impl_from_IVBSAXAttributes(IVBSAXAttributes * iface)208c2c66affSColin Finck static inline mxattributes *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
209c2c66affSColin Finck {
210c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxattributes, IVBSAXAttributes_iface);
211c2c66affSColin Finck }
212c2c66affSColin Finck 
mxattributes_grow(mxattributes * This)213c2c66affSColin Finck static HRESULT mxattributes_grow(mxattributes *This)
214c2c66affSColin Finck {
215c2c66affSColin Finck     if (This->length < This->allocated) return S_OK;
216c2c66affSColin Finck 
217c2c66affSColin Finck     This->allocated *= 2;
218c2c66affSColin Finck     This->attr = heap_realloc(This->attr, This->allocated*sizeof(mxattribute));
219c2c66affSColin Finck 
220c2c66affSColin Finck     return This->attr ? S_OK : E_OUTOFMEMORY;
221c2c66affSColin Finck }
222c2c66affSColin Finck 
parse_encoding_name(const WCHAR * encoding)223c2c66affSColin Finck static xml_encoding parse_encoding_name(const WCHAR *encoding)
224c2c66affSColin Finck {
225c2c66affSColin Finck     int min, max, n, c;
226c2c66affSColin Finck 
227c2c66affSColin Finck     min = 0;
228bab6b90fSAmine Khaldi     max = ARRAY_SIZE(xml_encoding_map) - 1;
229c2c66affSColin Finck 
230c2c66affSColin Finck     while (min <= max)
231c2c66affSColin Finck     {
232c2c66affSColin Finck         n = (min+max)/2;
233c2c66affSColin Finck 
234c2c66affSColin Finck         c = strcmpiW(xml_encoding_map[n].encoding, encoding);
235c2c66affSColin Finck         if (!c)
236c2c66affSColin Finck             return xml_encoding_map[n].enc;
237c2c66affSColin Finck 
238c2c66affSColin Finck         if (c > 0)
239c2c66affSColin Finck             max = n-1;
240c2c66affSColin Finck         else
241c2c66affSColin Finck             min = n+1;
242c2c66affSColin Finck     }
243c2c66affSColin Finck 
244c2c66affSColin Finck     return XmlEncoding_Unknown;
245c2c66affSColin Finck }
246c2c66affSColin Finck 
init_encoded_buffer(encoded_buffer * buffer)247c2c66affSColin Finck static HRESULT init_encoded_buffer(encoded_buffer *buffer)
248c2c66affSColin Finck {
249c2c66affSColin Finck     const int initial_len = 0x1000;
250c2c66affSColin Finck     buffer->data = heap_alloc(initial_len);
251c2c66affSColin Finck     if (!buffer->data) return E_OUTOFMEMORY;
252c2c66affSColin Finck 
253c2c66affSColin Finck     memset(buffer->data, 0, 4);
254c2c66affSColin Finck     buffer->allocated = initial_len;
255c2c66affSColin Finck     buffer->written = 0;
256c2c66affSColin Finck 
257c2c66affSColin Finck     return S_OK;
258c2c66affSColin Finck }
259c2c66affSColin Finck 
free_encoded_buffer(encoded_buffer * buffer)260c2c66affSColin Finck static void free_encoded_buffer(encoded_buffer *buffer)
261c2c66affSColin Finck {
262c2c66affSColin Finck     heap_free(buffer->data);
263c2c66affSColin Finck }
264c2c66affSColin Finck 
get_code_page(xml_encoding encoding,UINT * cp)265c2c66affSColin Finck static HRESULT get_code_page(xml_encoding encoding, UINT *cp)
266c2c66affSColin Finck {
267c2c66affSColin Finck     const struct xml_encoding_data *data;
268c2c66affSColin Finck 
269c2c66affSColin Finck     if (encoding == XmlEncoding_Unknown)
270c2c66affSColin Finck     {
271c2c66affSColin Finck         FIXME("unsupported encoding %d\n", encoding);
272c2c66affSColin Finck         return E_NOTIMPL;
273c2c66affSColin Finck     }
274c2c66affSColin Finck 
275c2c66affSColin Finck     data = &xml_encoding_map[encoding];
276c2c66affSColin Finck     *cp = data->cp;
277c2c66affSColin Finck 
278c2c66affSColin Finck     return S_OK;
279c2c66affSColin Finck }
280c2c66affSColin Finck 
init_output_buffer(xml_encoding encoding,output_buffer * buffer)281c2c66affSColin Finck static HRESULT init_output_buffer(xml_encoding encoding, output_buffer *buffer)
282c2c66affSColin Finck {
283c2c66affSColin Finck     HRESULT hr;
284c2c66affSColin Finck 
285c2c66affSColin Finck     hr = get_code_page(encoding, &buffer->code_page);
286c2c66affSColin Finck     if (hr != S_OK)
287c2c66affSColin Finck         return hr;
288c2c66affSColin Finck 
289c2c66affSColin Finck     hr = init_encoded_buffer(&buffer->encoded);
290c2c66affSColin Finck     if (hr != S_OK)
291c2c66affSColin Finck         return hr;
292c2c66affSColin Finck 
293c2c66affSColin Finck     list_init(&buffer->blocks);
294c2c66affSColin Finck     buffer->utf16_total = 0;
295c2c66affSColin Finck 
296c2c66affSColin Finck     return S_OK;
297c2c66affSColin Finck }
298c2c66affSColin Finck 
free_output_buffer(output_buffer * buffer)299c2c66affSColin Finck static void free_output_buffer(output_buffer *buffer)
300c2c66affSColin Finck {
301c2c66affSColin Finck     encoded_buffer *cur, *cur2;
302c2c66affSColin Finck 
303c2c66affSColin Finck     free_encoded_buffer(&buffer->encoded);
304c2c66affSColin Finck 
305c2c66affSColin Finck     LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &buffer->blocks, encoded_buffer, entry)
306c2c66affSColin Finck     {
307c2c66affSColin Finck         list_remove(&cur->entry);
308c2c66affSColin Finck         free_encoded_buffer(cur);
309c2c66affSColin Finck         heap_free(cur);
310c2c66affSColin Finck     }
311c2c66affSColin Finck }
312c2c66affSColin Finck 
write_output_buffer(mxwriter * writer,const WCHAR * data,int len)313c2c66affSColin Finck static HRESULT write_output_buffer(mxwriter *writer, const WCHAR *data, int len)
314c2c66affSColin Finck {
315c2c66affSColin Finck     output_buffer *buffer = &writer->buffer;
316c2c66affSColin Finck     encoded_buffer *buff;
317c2c66affSColin Finck     unsigned int written;
318c2c66affSColin Finck     int src_len;
319c2c66affSColin Finck 
320c2c66affSColin Finck     if (!len || !*data)
321c2c66affSColin Finck         return S_OK;
322c2c66affSColin Finck 
323c2c66affSColin Finck     src_len = len == -1 ? strlenW(data) : len;
324c2c66affSColin Finck     if (writer->dest)
325c2c66affSColin Finck     {
326c2c66affSColin Finck         buff = &buffer->encoded;
327c2c66affSColin Finck 
328c2c66affSColin Finck         if (buffer->code_page == ~0)
329c2c66affSColin Finck         {
330c2c66affSColin Finck             unsigned int avail = buff->allocated - buff->written;
331c2c66affSColin Finck 
332c2c66affSColin Finck             src_len *= sizeof(WCHAR);
333c2c66affSColin Finck             written = min(avail, src_len);
334c2c66affSColin Finck 
335c2c66affSColin Finck             /* fill internal buffer first */
336c2c66affSColin Finck             if (avail)
337c2c66affSColin Finck             {
338c2c66affSColin Finck                 memcpy(buff->data + buff->written, data, written);
339c2c66affSColin Finck                 data += written / sizeof(WCHAR);
340c2c66affSColin Finck                 buff->written += written;
341c2c66affSColin Finck                 avail -= written;
342c2c66affSColin Finck                 src_len -= written;
343c2c66affSColin Finck             }
344c2c66affSColin Finck 
345c2c66affSColin Finck             if (!avail)
346c2c66affSColin Finck             {
347c2c66affSColin Finck                 IStream_Write(writer->dest, buff->data, buff->written, &written);
348c2c66affSColin Finck                 buff->written = 0;
349c2c66affSColin Finck                 if (src_len >= buff->allocated)
350c2c66affSColin Finck                     IStream_Write(writer->dest, data, src_len, &written);
351c2c66affSColin Finck                 else if (src_len)
352c2c66affSColin Finck                 {
353c2c66affSColin Finck                     memcpy(buff->data, data, src_len);
354c2c66affSColin Finck                     buff->written += src_len;
355c2c66affSColin Finck                 }
356c2c66affSColin Finck             }
357c2c66affSColin Finck         }
358c2c66affSColin Finck         else
359c2c66affSColin Finck         {
360c2c66affSColin Finck             unsigned int avail = buff->allocated - buff->written;
361c2c66affSColin Finck             int length;
362c2c66affSColin Finck 
363c2c66affSColin Finck             length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, NULL, 0, NULL, NULL);
364c2c66affSColin Finck             if (avail >= length)
365c2c66affSColin Finck             {
366c2c66affSColin Finck                 length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, buff->data + buff->written, length, NULL, NULL);
367c2c66affSColin Finck                 buff->written += length;
368c2c66affSColin Finck             }
369c2c66affSColin Finck             else
370c2c66affSColin Finck             {
371c2c66affSColin Finck                 /* drain what we go so far */
372c2c66affSColin Finck                 if (buff->written)
373c2c66affSColin Finck                 {
374c2c66affSColin Finck                     IStream_Write(writer->dest, buff->data, buff->written, &written);
375c2c66affSColin Finck                     buff->written = 0;
376c2c66affSColin Finck                     avail = buff->allocated;
377c2c66affSColin Finck                 }
378c2c66affSColin Finck 
379c2c66affSColin Finck                 if (avail >= length)
380c2c66affSColin Finck                 {
381c2c66affSColin Finck                     length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, buff->data + buff->written, length, NULL, NULL);
382c2c66affSColin Finck                     buff->written += length;
383c2c66affSColin Finck                 }
384c2c66affSColin Finck                 else
385c2c66affSColin Finck                 {
386c2c66affSColin Finck                     char *mb;
387c2c66affSColin Finck 
388c2c66affSColin Finck                     /* if current chunk is larger than total buffer size, convert it at once using temporary allocated buffer */
389c2c66affSColin Finck                     mb = heap_alloc(length);
390c2c66affSColin Finck                     if (!mb)
391c2c66affSColin Finck                         return E_OUTOFMEMORY;
392c2c66affSColin Finck 
393c2c66affSColin Finck                     length = WideCharToMultiByte(buffer->code_page, 0, data, src_len, mb, length, NULL, NULL);
394c2c66affSColin Finck                     IStream_Write(writer->dest, mb, length, &written);
395c2c66affSColin Finck                     heap_free(mb);
396c2c66affSColin Finck                 }
397c2c66affSColin Finck             }
398c2c66affSColin Finck         }
399c2c66affSColin Finck     }
400c2c66affSColin Finck     /* When writer has no output set we have to accumulate everything to return it later in a form of BSTR.
401c2c66affSColin Finck        To achieve that:
402c2c66affSColin Finck 
403c2c66affSColin Finck        - fill a buffer already allocated as part of output buffer;
404c2c66affSColin Finck        - when current buffer is full, allocate another one and switch to it; buffers themselves never grow,
405c2c66affSColin Finck          but are linked together, with head pointing to first allocated buffer after initial one got filled;
406c2c66affSColin Finck        - later during get_output() contents are concatenated by copying one after another to destination BSTR buffer,
407c2c66affSColin Finck          that's returned to the client. */
408c2c66affSColin Finck     else
409c2c66affSColin Finck     {
410c2c66affSColin Finck         /* select last used block */
411c2c66affSColin Finck         if (list_empty(&buffer->blocks))
412c2c66affSColin Finck             buff = &buffer->encoded;
413c2c66affSColin Finck         else
414c2c66affSColin Finck             buff = LIST_ENTRY(list_tail(&buffer->blocks), encoded_buffer, entry);
415c2c66affSColin Finck 
416c2c66affSColin Finck         src_len *= sizeof(WCHAR);
417c2c66affSColin Finck         while (src_len)
418c2c66affSColin Finck         {
419c2c66affSColin Finck             unsigned int avail = buff->allocated - buff->written;
420c2c66affSColin Finck             unsigned int written = min(avail, src_len);
421c2c66affSColin Finck 
422c2c66affSColin Finck             if (avail)
423c2c66affSColin Finck             {
424c2c66affSColin Finck                 memcpy(buff->data + buff->written, data, written);
425c2c66affSColin Finck                 buff->written += written;
426c2c66affSColin Finck                 buffer->utf16_total += written;
427c2c66affSColin Finck                 src_len -= written;
428c2c66affSColin Finck             }
429c2c66affSColin Finck 
430c2c66affSColin Finck             /* alloc new block if needed and retry */
431c2c66affSColin Finck             if (src_len)
432c2c66affSColin Finck             {
433c2c66affSColin Finck                 encoded_buffer *next = heap_alloc(sizeof(*next));
434c2c66affSColin Finck                 HRESULT hr;
435c2c66affSColin Finck 
436c2c66affSColin Finck                 if (FAILED(hr = init_encoded_buffer(next))) {
437c2c66affSColin Finck                     heap_free(next);
438c2c66affSColin Finck                     return hr;
439c2c66affSColin Finck                 }
440c2c66affSColin Finck 
441c2c66affSColin Finck                 list_add_tail(&buffer->blocks, &next->entry);
442c2c66affSColin Finck                 buff = next;
443c2c66affSColin Finck             }
444c2c66affSColin Finck         }
445c2c66affSColin Finck     }
446c2c66affSColin Finck 
447c2c66affSColin Finck     return S_OK;
448c2c66affSColin Finck }
449c2c66affSColin Finck 
write_output_buffer_quoted(mxwriter * writer,const WCHAR * data,int len)450c2c66affSColin Finck static HRESULT write_output_buffer_quoted(mxwriter *writer, const WCHAR *data, int len)
451c2c66affSColin Finck {
452c2c66affSColin Finck     write_output_buffer(writer, quotW, 1);
453c2c66affSColin Finck     write_output_buffer(writer, data, len);
454c2c66affSColin Finck     write_output_buffer(writer, quotW, 1);
455c2c66affSColin Finck 
456c2c66affSColin Finck     return S_OK;
457c2c66affSColin Finck }
458c2c66affSColin Finck 
459c2c66affSColin Finck /* frees buffer data, reallocates with a default lengths */
close_output_buffer(mxwriter * writer)460c2c66affSColin Finck static void close_output_buffer(mxwriter *writer)
461c2c66affSColin Finck {
462c2c66affSColin Finck     encoded_buffer *cur, *cur2;
463c2c66affSColin Finck 
464c2c66affSColin Finck     heap_free(writer->buffer.encoded.data);
465c2c66affSColin Finck 
466c2c66affSColin Finck     LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &writer->buffer.blocks, encoded_buffer, entry)
467c2c66affSColin Finck     {
468c2c66affSColin Finck         list_remove(&cur->entry);
469c2c66affSColin Finck         free_encoded_buffer(cur);
470c2c66affSColin Finck         heap_free(cur);
471c2c66affSColin Finck     }
472c2c66affSColin Finck 
473c2c66affSColin Finck     init_encoded_buffer(&writer->buffer.encoded);
474c2c66affSColin Finck     get_code_page(writer->xml_enc, &writer->buffer.code_page);
475c2c66affSColin Finck     writer->buffer.utf16_total = 0;
476c2c66affSColin Finck     list_init(&writer->buffer.blocks);
477c2c66affSColin Finck }
478c2c66affSColin Finck 
479c2c66affSColin Finck /* Escapes special characters like:
480c2c66affSColin Finck    '<' -> "&lt;"
481c2c66affSColin Finck    '&' -> "&amp;"
482c2c66affSColin Finck    '"' -> "&quot;"
483c2c66affSColin Finck    '>' -> "&gt;"
484c2c66affSColin Finck 
485c2c66affSColin Finck    On call 'len' contains a length of 'str' in chars or -1 if it's null terminated.
486c2c66affSColin Finck    After a call it's updated with actual new length if it wasn't -1 initially.
487c2c66affSColin Finck */
get_escaped_string(const WCHAR * str,escape_mode mode,int * len)488c2c66affSColin Finck static WCHAR *get_escaped_string(const WCHAR *str, escape_mode mode, int *len)
489c2c66affSColin Finck {
490c2c66affSColin Finck     static const WCHAR ltW[]    = {'&','l','t',';'};
491c2c66affSColin Finck     static const WCHAR ampW[]   = {'&','a','m','p',';'};
492c2c66affSColin Finck     static const WCHAR equotW[] = {'&','q','u','o','t',';'};
493c2c66affSColin Finck     static const WCHAR gtW[]    = {'&','g','t',';'};
494c2c66affSColin Finck 
495c2c66affSColin Finck     const int default_alloc = 100;
496c2c66affSColin Finck     const int grow_thresh = 10;
497c2c66affSColin Finck     int p = *len, conv_len;
498c2c66affSColin Finck     WCHAR *ptr, *ret;
499c2c66affSColin Finck 
500c2c66affSColin Finck     /* default buffer size to something if length is unknown */
501*eb44c20cSAmine Khaldi     conv_len = max(2**len, default_alloc);
502c2c66affSColin Finck     ptr = ret = heap_alloc(conv_len*sizeof(WCHAR));
503c2c66affSColin Finck 
504*eb44c20cSAmine Khaldi     while (p)
505c2c66affSColin Finck     {
506c2c66affSColin Finck         if (ptr - ret > conv_len - grow_thresh)
507c2c66affSColin Finck         {
508c2c66affSColin Finck             int written = ptr - ret;
509c2c66affSColin Finck             conv_len *= 2;
510c2c66affSColin Finck             ptr = ret = heap_realloc(ret, conv_len*sizeof(WCHAR));
511c2c66affSColin Finck             ptr += written;
512c2c66affSColin Finck         }
513c2c66affSColin Finck 
514c2c66affSColin Finck         switch (*str)
515c2c66affSColin Finck         {
516c2c66affSColin Finck         case '<':
517c2c66affSColin Finck             memcpy(ptr, ltW, sizeof(ltW));
518bab6b90fSAmine Khaldi             ptr += ARRAY_SIZE(ltW);
519c2c66affSColin Finck             break;
520c2c66affSColin Finck         case '&':
521c2c66affSColin Finck             memcpy(ptr, ampW, sizeof(ampW));
522bab6b90fSAmine Khaldi             ptr += ARRAY_SIZE(ampW);
523c2c66affSColin Finck             break;
524c2c66affSColin Finck         case '>':
525c2c66affSColin Finck             memcpy(ptr, gtW, sizeof(gtW));
526bab6b90fSAmine Khaldi             ptr += ARRAY_SIZE(gtW);
527c2c66affSColin Finck             break;
528c2c66affSColin Finck         case '"':
529c2c66affSColin Finck             if (mode == EscapeValue)
530c2c66affSColin Finck             {
531c2c66affSColin Finck                 memcpy(ptr, equotW, sizeof(equotW));
532bab6b90fSAmine Khaldi                 ptr += ARRAY_SIZE(equotW);
533c2c66affSColin Finck                 break;
534c2c66affSColin Finck             }
535c2c66affSColin Finck             /* fallthrough for text mode */
536c2c66affSColin Finck         default:
537c2c66affSColin Finck             *ptr++ = *str;
538c2c66affSColin Finck             break;
539c2c66affSColin Finck         }
540c2c66affSColin Finck 
541c2c66affSColin Finck         str++;
542*eb44c20cSAmine Khaldi         p--;
543c2c66affSColin Finck     }
544c2c66affSColin Finck 
545*eb44c20cSAmine Khaldi     *len = ptr-ret;
546c2c66affSColin Finck     *++ptr = 0;
547c2c66affSColin Finck 
548c2c66affSColin Finck     return ret;
549c2c66affSColin Finck }
550c2c66affSColin Finck 
write_prolog_buffer(mxwriter * writer)551c2c66affSColin Finck static void write_prolog_buffer(mxwriter *writer)
552c2c66affSColin Finck {
553c2c66affSColin Finck     static const WCHAR versionW[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','='};
554c2c66affSColin Finck     static const WCHAR encodingW[] = {' ','e','n','c','o','d','i','n','g','=','\"'};
555c2c66affSColin Finck     static const WCHAR standaloneW[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
556c2c66affSColin Finck     static const WCHAR yesW[] = {'y','e','s','\"','?','>'};
557c2c66affSColin Finck     static const WCHAR noW[] = {'n','o','\"','?','>'};
558c2c66affSColin Finck 
559c2c66affSColin Finck     /* version */
560bab6b90fSAmine Khaldi     write_output_buffer(writer, versionW, ARRAY_SIZE(versionW));
561c2c66affSColin Finck     write_output_buffer_quoted(writer, writer->version, -1);
562c2c66affSColin Finck 
563c2c66affSColin Finck     /* encoding */
564bab6b90fSAmine Khaldi     write_output_buffer(writer, encodingW, ARRAY_SIZE(encodingW));
565c2c66affSColin Finck 
566c2c66affSColin Finck     if (writer->dest)
567c2c66affSColin Finck         write_output_buffer(writer, writer->encoding, -1);
568c2c66affSColin Finck     else
569bab6b90fSAmine Khaldi         write_output_buffer(writer, utf16W, ARRAY_SIZE(utf16W) - 1);
570c2c66affSColin Finck     write_output_buffer(writer, quotW, 1);
571c2c66affSColin Finck 
572c2c66affSColin Finck     /* standalone */
573bab6b90fSAmine Khaldi     write_output_buffer(writer, standaloneW, ARRAY_SIZE(standaloneW));
574c2c66affSColin Finck     if (writer->props[MXWriter_Standalone] == VARIANT_TRUE)
575bab6b90fSAmine Khaldi         write_output_buffer(writer, yesW, ARRAY_SIZE(yesW));
576c2c66affSColin Finck     else
577bab6b90fSAmine Khaldi         write_output_buffer(writer, noW, ARRAY_SIZE(noW));
578c2c66affSColin Finck 
579bab6b90fSAmine Khaldi     write_output_buffer(writer, crlfW, ARRAY_SIZE(crlfW));
580c2c66affSColin Finck     writer->newline = TRUE;
581c2c66affSColin Finck }
582c2c66affSColin Finck 
583c2c66affSColin Finck /* Attempts to the write data from the mxwriter's buffer to
584c2c66affSColin Finck  * the destination stream (if there is one).
585c2c66affSColin Finck  */
write_data_to_stream(mxwriter * writer)586c2c66affSColin Finck static HRESULT write_data_to_stream(mxwriter *writer)
587c2c66affSColin Finck {
588c2c66affSColin Finck     encoded_buffer *buffer = &writer->buffer.encoded;
589c2c66affSColin Finck     ULONG written = 0;
590c2c66affSColin Finck 
591c2c66affSColin Finck     if (!writer->dest)
592c2c66affSColin Finck         return S_OK;
593c2c66affSColin Finck 
594c2c66affSColin Finck     if (buffer->written == 0)
595c2c66affSColin Finck     {
596c2c66affSColin Finck         if (writer->xml_enc == XmlEncoding_UTF8)
597c2c66affSColin Finck             IStream_Write(writer->dest, buffer->data, 0, &written);
598c2c66affSColin Finck     }
599c2c66affSColin Finck     else
600c2c66affSColin Finck     {
601c2c66affSColin Finck         IStream_Write(writer->dest, buffer->data, buffer->written, &written);
602c2c66affSColin Finck         buffer->written = 0;
603c2c66affSColin Finck     }
604c2c66affSColin Finck 
605c2c66affSColin Finck     return S_OK;
606c2c66affSColin Finck }
607c2c66affSColin Finck 
608c2c66affSColin Finck /* Newly added element start tag left unclosed cause for empty elements
609c2c66affSColin Finck    we have to close it differently. */
close_element_starttag(mxwriter * writer)610c2c66affSColin Finck static void close_element_starttag(mxwriter *writer)
611c2c66affSColin Finck {
612c2c66affSColin Finck     static const WCHAR gtW[] = {'>'};
613c2c66affSColin Finck     if (!writer->element) return;
614c2c66affSColin Finck     write_output_buffer(writer, gtW, 1);
615c2c66affSColin Finck }
616c2c66affSColin Finck 
write_node_indent(mxwriter * writer)617c2c66affSColin Finck static void write_node_indent(mxwriter *writer)
618c2c66affSColin Finck {
619c2c66affSColin Finck     static const WCHAR tabW[] = {'\t'};
620c2c66affSColin Finck     int indent = writer->indent;
621c2c66affSColin Finck 
622c2c66affSColin Finck     if (!writer->props[MXWriter_Indent] || writer->text)
623c2c66affSColin Finck     {
624c2c66affSColin Finck         writer->text = FALSE;
625c2c66affSColin Finck         return;
626c2c66affSColin Finck     }
627c2c66affSColin Finck 
628c2c66affSColin Finck     /* This is to workaround PI output logic that always puts newline chars,
629c2c66affSColin Finck        document prolog PI does that too. */
630c2c66affSColin Finck     if (!writer->newline)
631bab6b90fSAmine Khaldi         write_output_buffer(writer, crlfW, ARRAY_SIZE(crlfW));
632c2c66affSColin Finck     while (indent--)
633c2c66affSColin Finck         write_output_buffer(writer, tabW, 1);
634c2c66affSColin Finck 
635c2c66affSColin Finck     writer->newline = FALSE;
636c2c66affSColin Finck     writer->text = FALSE;
637c2c66affSColin Finck }
638c2c66affSColin Finck 
writer_inc_indent(mxwriter * This)639c2c66affSColin Finck static inline void writer_inc_indent(mxwriter *This)
640c2c66affSColin Finck {
641c2c66affSColin Finck     This->indent++;
642c2c66affSColin Finck }
643c2c66affSColin Finck 
writer_dec_indent(mxwriter * This)644c2c66affSColin Finck static inline void writer_dec_indent(mxwriter *This)
645c2c66affSColin Finck {
646c2c66affSColin Finck     if (This->indent) This->indent--;
647c2c66affSColin Finck     /* depth is decreased only when element is closed, meaning it's not a text node
648c2c66affSColin Finck        at this point */
649c2c66affSColin Finck     This->text = FALSE;
650c2c66affSColin Finck }
651c2c66affSColin Finck 
set_element_name(mxwriter * This,const WCHAR * name,int len)652c2c66affSColin Finck static void set_element_name(mxwriter *This, const WCHAR *name, int len)
653c2c66affSColin Finck {
654c2c66affSColin Finck     SysFreeString(This->element);
655c2c66affSColin Finck     if (name)
656c2c66affSColin Finck         This->element = len != -1 ? SysAllocStringLen(name, len) : SysAllocString(name);
657c2c66affSColin Finck     else
658c2c66affSColin Finck         This->element = NULL;
659c2c66affSColin Finck }
660c2c66affSColin Finck 
flush_output_buffer(mxwriter * This)661c2c66affSColin Finck static inline HRESULT flush_output_buffer(mxwriter *This)
662c2c66affSColin Finck {
663c2c66affSColin Finck     close_element_starttag(This);
664c2c66affSColin Finck     set_element_name(This, NULL, 0);
665c2c66affSColin Finck     This->cdata = FALSE;
666c2c66affSColin Finck     return write_data_to_stream(This);
667c2c66affSColin Finck }
668c2c66affSColin Finck 
669c2c66affSColin Finck /* Resets the mxwriter's output buffer by closing it, then creating a new
670c2c66affSColin Finck  * output buffer using the given encoding.
671c2c66affSColin Finck  */
reset_output_buffer(mxwriter * This)672c2c66affSColin Finck static inline void reset_output_buffer(mxwriter *This)
673c2c66affSColin Finck {
674c2c66affSColin Finck     close_output_buffer(This);
675c2c66affSColin Finck }
676c2c66affSColin Finck 
writer_set_property(mxwriter * writer,mxwriter_prop property,VARIANT_BOOL value)677c2c66affSColin Finck static HRESULT writer_set_property(mxwriter *writer, mxwriter_prop property, VARIANT_BOOL value)
678c2c66affSColin Finck {
679c2c66affSColin Finck     writer->props[property] = value;
680c2c66affSColin Finck     writer->prop_changed = TRUE;
681c2c66affSColin Finck     return S_OK;
682c2c66affSColin Finck }
683c2c66affSColin Finck 
writer_get_property(const mxwriter * writer,mxwriter_prop property,VARIANT_BOOL * value)684c2c66affSColin Finck static HRESULT writer_get_property(const mxwriter *writer, mxwriter_prop property, VARIANT_BOOL *value)
685c2c66affSColin Finck {
686c2c66affSColin Finck     if (!value) return E_POINTER;
687c2c66affSColin Finck     *value = writer->props[property];
688c2c66affSColin Finck     return S_OK;
689c2c66affSColin Finck }
690c2c66affSColin Finck 
impl_from_IMXWriter(IMXWriter * iface)691c2c66affSColin Finck static inline mxwriter *impl_from_IMXWriter(IMXWriter *iface)
692c2c66affSColin Finck {
693c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxwriter, IMXWriter_iface);
694c2c66affSColin Finck }
695c2c66affSColin Finck 
impl_from_ISAXContentHandler(ISAXContentHandler * iface)696c2c66affSColin Finck static inline mxwriter *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
697c2c66affSColin Finck {
698c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxwriter, ISAXContentHandler_iface);
699c2c66affSColin Finck }
700c2c66affSColin Finck 
impl_from_IVBSAXContentHandler(IVBSAXContentHandler * iface)701c2c66affSColin Finck static inline mxwriter *impl_from_IVBSAXContentHandler(IVBSAXContentHandler *iface)
702c2c66affSColin Finck {
703c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxwriter, IVBSAXContentHandler_iface);
704c2c66affSColin Finck }
705c2c66affSColin Finck 
impl_from_ISAXLexicalHandler(ISAXLexicalHandler * iface)706c2c66affSColin Finck static inline mxwriter *impl_from_ISAXLexicalHandler(ISAXLexicalHandler *iface)
707c2c66affSColin Finck {
708c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxwriter, ISAXLexicalHandler_iface);
709c2c66affSColin Finck }
710c2c66affSColin Finck 
impl_from_IVBSAXLexicalHandler(IVBSAXLexicalHandler * iface)711c2c66affSColin Finck static inline mxwriter *impl_from_IVBSAXLexicalHandler(IVBSAXLexicalHandler *iface)
712c2c66affSColin Finck {
713c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxwriter, IVBSAXLexicalHandler_iface);
714c2c66affSColin Finck }
715c2c66affSColin Finck 
impl_from_ISAXDeclHandler(ISAXDeclHandler * iface)716c2c66affSColin Finck static inline mxwriter *impl_from_ISAXDeclHandler(ISAXDeclHandler *iface)
717c2c66affSColin Finck {
718c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxwriter, ISAXDeclHandler_iface);
719c2c66affSColin Finck }
720c2c66affSColin Finck 
impl_from_IVBSAXDeclHandler(IVBSAXDeclHandler * iface)721c2c66affSColin Finck static inline mxwriter *impl_from_IVBSAXDeclHandler(IVBSAXDeclHandler *iface)
722c2c66affSColin Finck {
723c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxwriter, IVBSAXDeclHandler_iface);
724c2c66affSColin Finck }
725c2c66affSColin Finck 
impl_from_ISAXDTDHandler(ISAXDTDHandler * iface)726c2c66affSColin Finck static inline mxwriter *impl_from_ISAXDTDHandler(ISAXDTDHandler *iface)
727c2c66affSColin Finck {
728c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxwriter, ISAXDTDHandler_iface);
729c2c66affSColin Finck }
730c2c66affSColin Finck 
impl_from_IVBSAXDTDHandler(IVBSAXDTDHandler * iface)731c2c66affSColin Finck static inline mxwriter *impl_from_IVBSAXDTDHandler(IVBSAXDTDHandler *iface)
732c2c66affSColin Finck {
733c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxwriter, IVBSAXDTDHandler_iface);
734c2c66affSColin Finck }
735c2c66affSColin Finck 
impl_from_ISAXErrorHandler(ISAXErrorHandler * iface)736c2c66affSColin Finck static inline mxwriter *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
737c2c66affSColin Finck {
738c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxwriter, ISAXErrorHandler_iface);
739c2c66affSColin Finck }
740c2c66affSColin Finck 
impl_from_IVBSAXErrorHandler(IVBSAXErrorHandler * iface)741c2c66affSColin Finck static inline mxwriter *impl_from_IVBSAXErrorHandler(IVBSAXErrorHandler *iface)
742c2c66affSColin Finck {
743c2c66affSColin Finck     return CONTAINING_RECORD(iface, mxwriter, IVBSAXErrorHandler_iface);
744c2c66affSColin Finck }
745c2c66affSColin Finck 
mxwriter_QueryInterface(IMXWriter * iface,REFIID riid,void ** obj)746c2c66affSColin Finck static HRESULT WINAPI mxwriter_QueryInterface(IMXWriter *iface, REFIID riid, void **obj)
747c2c66affSColin Finck {
748c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
749c2c66affSColin Finck 
750c2c66affSColin Finck     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
751c2c66affSColin Finck 
752c2c66affSColin Finck     *obj = NULL;
753c2c66affSColin Finck 
754c2c66affSColin Finck     if ( IsEqualGUID( riid, &IID_IMXWriter ) ||
755c2c66affSColin Finck          IsEqualGUID( riid, &IID_IDispatch ) ||
756c2c66affSColin Finck          IsEqualGUID( riid, &IID_IUnknown ) )
757c2c66affSColin Finck     {
758c2c66affSColin Finck         *obj = &This->IMXWriter_iface;
759c2c66affSColin Finck     }
760c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_ISAXContentHandler ) )
761c2c66affSColin Finck     {
762c2c66affSColin Finck         *obj = &This->ISAXContentHandler_iface;
763c2c66affSColin Finck     }
764c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_ISAXLexicalHandler ) )
765c2c66affSColin Finck     {
766c2c66affSColin Finck         *obj = &This->ISAXLexicalHandler_iface;
767c2c66affSColin Finck     }
768c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_ISAXDeclHandler ) )
769c2c66affSColin Finck     {
770c2c66affSColin Finck         *obj = &This->ISAXDeclHandler_iface;
771c2c66affSColin Finck     }
772c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_ISAXDTDHandler ) )
773c2c66affSColin Finck     {
774c2c66affSColin Finck         *obj = &This->ISAXDTDHandler_iface;
775c2c66affSColin Finck     }
776c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_ISAXErrorHandler ) )
777c2c66affSColin Finck     {
778c2c66affSColin Finck         *obj = &This->ISAXErrorHandler_iface;
779c2c66affSColin Finck     }
780c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_IVBSAXDeclHandler ) )
781c2c66affSColin Finck     {
782c2c66affSColin Finck         *obj = &This->IVBSAXDeclHandler_iface;
783c2c66affSColin Finck     }
784c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_IVBSAXLexicalHandler ) )
785c2c66affSColin Finck     {
786c2c66affSColin Finck         *obj = &This->IVBSAXLexicalHandler_iface;
787c2c66affSColin Finck     }
788c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_IVBSAXContentHandler ) )
789c2c66affSColin Finck     {
790c2c66affSColin Finck         *obj = &This->IVBSAXContentHandler_iface;
791c2c66affSColin Finck     }
792c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_IVBSAXDTDHandler ) )
793c2c66affSColin Finck     {
794c2c66affSColin Finck         *obj = &This->IVBSAXDTDHandler_iface;
795c2c66affSColin Finck     }
796c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_IVBSAXErrorHandler ) )
797c2c66affSColin Finck     {
798c2c66affSColin Finck         *obj = &This->IVBSAXErrorHandler_iface;
799c2c66affSColin Finck     }
800c2c66affSColin Finck     else if (dispex_query_interface(&This->dispex, riid, obj))
801c2c66affSColin Finck     {
802c2c66affSColin Finck         return *obj ? S_OK : E_NOINTERFACE;
803c2c66affSColin Finck     }
804c2c66affSColin Finck     else
805c2c66affSColin Finck     {
806c2c66affSColin Finck         ERR("interface %s not implemented\n", debugstr_guid(riid));
807c2c66affSColin Finck         *obj = NULL;
808c2c66affSColin Finck         return E_NOINTERFACE;
809c2c66affSColin Finck     }
810c2c66affSColin Finck 
811c2c66affSColin Finck     IMXWriter_AddRef(iface);
812c2c66affSColin Finck     return S_OK;
813c2c66affSColin Finck }
814c2c66affSColin Finck 
mxwriter_AddRef(IMXWriter * iface)815c2c66affSColin Finck static ULONG WINAPI mxwriter_AddRef(IMXWriter *iface)
816c2c66affSColin Finck {
817c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
818c2c66affSColin Finck     LONG ref = InterlockedIncrement(&This->ref);
819c2c66affSColin Finck 
820c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, ref);
821c2c66affSColin Finck 
822c2c66affSColin Finck     return ref;
823c2c66affSColin Finck }
824c2c66affSColin Finck 
mxwriter_Release(IMXWriter * iface)825c2c66affSColin Finck static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
826c2c66affSColin Finck {
827c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
828c2c66affSColin Finck     ULONG ref = InterlockedDecrement(&This->ref);
829c2c66affSColin Finck 
830c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, ref);
831c2c66affSColin Finck 
832c2c66affSColin Finck     if(!ref)
833c2c66affSColin Finck     {
834c2c66affSColin Finck         /* Windows flushes the buffer when the interface is destroyed. */
835c2c66affSColin Finck         flush_output_buffer(This);
836c2c66affSColin Finck         free_output_buffer(&This->buffer);
837c2c66affSColin Finck 
838c2c66affSColin Finck         if (This->dest) IStream_Release(This->dest);
839c2c66affSColin Finck         SysFreeString(This->version);
840c2c66affSColin Finck         SysFreeString(This->encoding);
841c2c66affSColin Finck 
842c2c66affSColin Finck         SysFreeString(This->element);
843c2c66affSColin Finck         heap_free(This);
844c2c66affSColin Finck     }
845c2c66affSColin Finck 
846c2c66affSColin Finck     return ref;
847c2c66affSColin Finck }
848c2c66affSColin Finck 
mxwriter_GetTypeInfoCount(IMXWriter * iface,UINT * pctinfo)849c2c66affSColin Finck static HRESULT WINAPI mxwriter_GetTypeInfoCount(IMXWriter *iface, UINT* pctinfo)
850c2c66affSColin Finck {
851c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
852c2c66affSColin Finck     return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
853c2c66affSColin Finck }
854c2c66affSColin Finck 
mxwriter_GetTypeInfo(IMXWriter * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)855c2c66affSColin Finck static HRESULT WINAPI mxwriter_GetTypeInfo(
856c2c66affSColin Finck     IMXWriter *iface,
857c2c66affSColin Finck     UINT iTInfo, LCID lcid,
858c2c66affSColin Finck     ITypeInfo** ppTInfo )
859c2c66affSColin Finck {
860c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
861c2c66affSColin Finck     return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
862c2c66affSColin Finck         iTInfo, lcid, ppTInfo);
863c2c66affSColin Finck }
864c2c66affSColin Finck 
mxwriter_GetIDsOfNames(IMXWriter * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)865c2c66affSColin Finck static HRESULT WINAPI mxwriter_GetIDsOfNames(
866c2c66affSColin Finck     IMXWriter *iface,
867c2c66affSColin Finck     REFIID riid, LPOLESTR* rgszNames,
868c2c66affSColin Finck     UINT cNames, LCID lcid, DISPID* rgDispId )
869c2c66affSColin Finck {
870c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
871c2c66affSColin Finck     return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
872c2c66affSColin Finck         riid, rgszNames, cNames, lcid, rgDispId);
873c2c66affSColin Finck }
874c2c66affSColin Finck 
mxwriter_Invoke(IMXWriter * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)875c2c66affSColin Finck static HRESULT WINAPI mxwriter_Invoke(
876c2c66affSColin Finck     IMXWriter *iface,
877c2c66affSColin Finck     DISPID dispIdMember, REFIID riid, LCID lcid,
878c2c66affSColin Finck     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
879c2c66affSColin Finck     EXCEPINFO* pExcepInfo, UINT* puArgErr )
880c2c66affSColin Finck {
881c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
882c2c66affSColin Finck     return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
883c2c66affSColin Finck         dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
884c2c66affSColin Finck }
885c2c66affSColin Finck 
mxwriter_put_output(IMXWriter * iface,VARIANT dest)886c2c66affSColin Finck static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
887c2c66affSColin Finck {
888c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
889c2c66affSColin Finck     HRESULT hr;
890c2c66affSColin Finck 
891c2c66affSColin Finck     TRACE("(%p)->(%s)\n", This, debugstr_variant(&dest));
892c2c66affSColin Finck 
893c2c66affSColin Finck     hr = flush_output_buffer(This);
894c2c66affSColin Finck     if (FAILED(hr))
895c2c66affSColin Finck         return hr;
896c2c66affSColin Finck 
897c2c66affSColin Finck     switch (V_VT(&dest))
898c2c66affSColin Finck     {
899c2c66affSColin Finck     case VT_EMPTY:
900c2c66affSColin Finck     {
901c2c66affSColin Finck         if (This->dest) IStream_Release(This->dest);
902c2c66affSColin Finck         This->dest = NULL;
903c2c66affSColin Finck         reset_output_buffer(This);
904c2c66affSColin Finck         break;
905c2c66affSColin Finck     }
906c2c66affSColin Finck     case VT_UNKNOWN:
907c2c66affSColin Finck     {
908c2c66affSColin Finck         IStream *stream;
909c2c66affSColin Finck 
910c2c66affSColin Finck         hr = IUnknown_QueryInterface(V_UNKNOWN(&dest), &IID_IStream, (void**)&stream);
911c2c66affSColin Finck         if (hr == S_OK)
912c2c66affSColin Finck         {
913c2c66affSColin Finck             /* Recreate the output buffer to make sure it's using the correct encoding. */
914c2c66affSColin Finck             reset_output_buffer(This);
915c2c66affSColin Finck 
916c2c66affSColin Finck             if (This->dest) IStream_Release(This->dest);
917c2c66affSColin Finck             This->dest = stream;
918c2c66affSColin Finck             break;
919c2c66affSColin Finck         }
920c2c66affSColin Finck 
921c2c66affSColin Finck         FIXME("unhandled interface type for VT_UNKNOWN destination\n");
922c2c66affSColin Finck         return E_NOTIMPL;
923c2c66affSColin Finck     }
924c2c66affSColin Finck     default:
925c2c66affSColin Finck         FIXME("unhandled destination type %s\n", debugstr_variant(&dest));
926c2c66affSColin Finck         return E_NOTIMPL;
927c2c66affSColin Finck     }
928c2c66affSColin Finck 
929c2c66affSColin Finck     return S_OK;
930c2c66affSColin Finck }
931c2c66affSColin Finck 
mxwriter_get_output(IMXWriter * iface,VARIANT * dest)932c2c66affSColin Finck static HRESULT WINAPI mxwriter_get_output(IMXWriter *iface, VARIANT *dest)
933c2c66affSColin Finck {
934c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
935c2c66affSColin Finck 
936c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, dest);
937c2c66affSColin Finck 
938c2c66affSColin Finck     if (!dest) return E_POINTER;
939c2c66affSColin Finck 
940c2c66affSColin Finck     if (This->dest)
941c2c66affSColin Finck     {
942c2c66affSColin Finck         /* we only support IStream output so far */
943c2c66affSColin Finck         V_VT(dest) = VT_UNKNOWN;
944c2c66affSColin Finck         V_UNKNOWN(dest) = (IUnknown*)This->dest;
945c2c66affSColin Finck         IStream_AddRef(This->dest);
946c2c66affSColin Finck     }
947c2c66affSColin Finck     else
948c2c66affSColin Finck     {
949c2c66affSColin Finck         encoded_buffer *buff;
950c2c66affSColin Finck         char *dest_ptr;
951c2c66affSColin Finck         HRESULT hr;
952c2c66affSColin Finck 
953c2c66affSColin Finck         hr = flush_output_buffer(This);
954c2c66affSColin Finck         if (FAILED(hr))
955c2c66affSColin Finck             return hr;
956c2c66affSColin Finck 
957c2c66affSColin Finck         V_VT(dest)   = VT_BSTR;
958c2c66affSColin Finck         V_BSTR(dest) = SysAllocStringLen(NULL, This->buffer.utf16_total / sizeof(WCHAR));
959c2c66affSColin Finck         if (!V_BSTR(dest))
960c2c66affSColin Finck             return E_OUTOFMEMORY;
961c2c66affSColin Finck 
962c2c66affSColin Finck         dest_ptr = (char*)V_BSTR(dest);
963c2c66affSColin Finck         buff = &This->buffer.encoded;
964c2c66affSColin Finck 
965c2c66affSColin Finck         if (buff->written)
966c2c66affSColin Finck         {
967c2c66affSColin Finck             memcpy(dest_ptr, buff->data, buff->written);
968c2c66affSColin Finck             dest_ptr += buff->written;
969c2c66affSColin Finck         }
970c2c66affSColin Finck 
971c2c66affSColin Finck         LIST_FOR_EACH_ENTRY(buff, &This->buffer.blocks, encoded_buffer, entry)
972c2c66affSColin Finck         {
973c2c66affSColin Finck             memcpy(dest_ptr, buff->data, buff->written);
974c2c66affSColin Finck             dest_ptr += buff->written;
975c2c66affSColin Finck         }
976c2c66affSColin Finck     }
977c2c66affSColin Finck 
978c2c66affSColin Finck     return S_OK;
979c2c66affSColin Finck }
980c2c66affSColin Finck 
mxwriter_put_encoding(IMXWriter * iface,BSTR encoding)981c2c66affSColin Finck static HRESULT WINAPI mxwriter_put_encoding(IMXWriter *iface, BSTR encoding)
982c2c66affSColin Finck {
983c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
984c2c66affSColin Finck     xml_encoding enc;
985c2c66affSColin Finck     HRESULT hr;
986c2c66affSColin Finck 
987c2c66affSColin Finck     TRACE("(%p)->(%s)\n", This, debugstr_w(encoding));
988c2c66affSColin Finck 
989c2c66affSColin Finck     enc = parse_encoding_name(encoding);
990c2c66affSColin Finck     if (enc == XmlEncoding_Unknown)
991c2c66affSColin Finck     {
992c2c66affSColin Finck         FIXME("unsupported encoding %s\n", debugstr_w(encoding));
993c2c66affSColin Finck         return E_INVALIDARG;
994c2c66affSColin Finck     }
995c2c66affSColin Finck 
996c2c66affSColin Finck     hr = flush_output_buffer(This);
997c2c66affSColin Finck     if (FAILED(hr))
998c2c66affSColin Finck         return hr;
999c2c66affSColin Finck 
1000c2c66affSColin Finck     SysReAllocString(&This->encoding, encoding);
1001c2c66affSColin Finck     This->xml_enc = enc;
1002c2c66affSColin Finck 
1003c2c66affSColin Finck     TRACE("got encoding %d\n", This->xml_enc);
1004c2c66affSColin Finck     reset_output_buffer(This);
1005c2c66affSColin Finck     return S_OK;
1006c2c66affSColin Finck }
1007c2c66affSColin Finck 
mxwriter_get_encoding(IMXWriter * iface,BSTR * encoding)1008c2c66affSColin Finck static HRESULT WINAPI mxwriter_get_encoding(IMXWriter *iface, BSTR *encoding)
1009c2c66affSColin Finck {
1010c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1011c2c66affSColin Finck 
1012c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, encoding);
1013c2c66affSColin Finck 
1014c2c66affSColin Finck     if (!encoding) return E_POINTER;
1015c2c66affSColin Finck 
1016c2c66affSColin Finck     *encoding = SysAllocString(This->encoding);
1017c2c66affSColin Finck     if (!*encoding) return E_OUTOFMEMORY;
1018c2c66affSColin Finck 
1019c2c66affSColin Finck     return S_OK;
1020c2c66affSColin Finck }
1021c2c66affSColin Finck 
mxwriter_put_byteOrderMark(IMXWriter * iface,VARIANT_BOOL value)1022c2c66affSColin Finck static HRESULT WINAPI mxwriter_put_byteOrderMark(IMXWriter *iface, VARIANT_BOOL value)
1023c2c66affSColin Finck {
1024c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1025c2c66affSColin Finck 
1026c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, value);
1027c2c66affSColin Finck     return writer_set_property(This, MXWriter_BOM, value);
1028c2c66affSColin Finck }
1029c2c66affSColin Finck 
mxwriter_get_byteOrderMark(IMXWriter * iface,VARIANT_BOOL * value)1030c2c66affSColin Finck static HRESULT WINAPI mxwriter_get_byteOrderMark(IMXWriter *iface, VARIANT_BOOL *value)
1031c2c66affSColin Finck {
1032c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1033c2c66affSColin Finck 
1034c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, value);
1035c2c66affSColin Finck     return writer_get_property(This, MXWriter_BOM, value);
1036c2c66affSColin Finck }
1037c2c66affSColin Finck 
mxwriter_put_indent(IMXWriter * iface,VARIANT_BOOL value)1038c2c66affSColin Finck static HRESULT WINAPI mxwriter_put_indent(IMXWriter *iface, VARIANT_BOOL value)
1039c2c66affSColin Finck {
1040c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1041c2c66affSColin Finck 
1042c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, value);
1043c2c66affSColin Finck     return writer_set_property(This, MXWriter_Indent, value);
1044c2c66affSColin Finck }
1045c2c66affSColin Finck 
mxwriter_get_indent(IMXWriter * iface,VARIANT_BOOL * value)1046c2c66affSColin Finck static HRESULT WINAPI mxwriter_get_indent(IMXWriter *iface, VARIANT_BOOL *value)
1047c2c66affSColin Finck {
1048c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1049c2c66affSColin Finck 
1050c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, value);
1051c2c66affSColin Finck     return writer_get_property(This, MXWriter_Indent, value);
1052c2c66affSColin Finck }
1053c2c66affSColin Finck 
mxwriter_put_standalone(IMXWriter * iface,VARIANT_BOOL value)1054c2c66affSColin Finck static HRESULT WINAPI mxwriter_put_standalone(IMXWriter *iface, VARIANT_BOOL value)
1055c2c66affSColin Finck {
1056c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1057c2c66affSColin Finck 
1058c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, value);
1059c2c66affSColin Finck     return writer_set_property(This, MXWriter_Standalone, value);
1060c2c66affSColin Finck }
1061c2c66affSColin Finck 
mxwriter_get_standalone(IMXWriter * iface,VARIANT_BOOL * value)1062c2c66affSColin Finck static HRESULT WINAPI mxwriter_get_standalone(IMXWriter *iface, VARIANT_BOOL *value)
1063c2c66affSColin Finck {
1064c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1065c2c66affSColin Finck 
1066c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, value);
1067c2c66affSColin Finck     return writer_get_property(This, MXWriter_Standalone, value);
1068c2c66affSColin Finck }
1069c2c66affSColin Finck 
mxwriter_put_omitXMLDeclaration(IMXWriter * iface,VARIANT_BOOL value)1070c2c66affSColin Finck static HRESULT WINAPI mxwriter_put_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL value)
1071c2c66affSColin Finck {
1072c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1073c2c66affSColin Finck 
1074c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, value);
1075c2c66affSColin Finck     return writer_set_property(This, MXWriter_OmitXmlDecl, value);
1076c2c66affSColin Finck }
1077c2c66affSColin Finck 
mxwriter_get_omitXMLDeclaration(IMXWriter * iface,VARIANT_BOOL * value)1078c2c66affSColin Finck static HRESULT WINAPI mxwriter_get_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL *value)
1079c2c66affSColin Finck {
1080c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1081c2c66affSColin Finck 
1082c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, value);
1083c2c66affSColin Finck     return writer_get_property(This, MXWriter_OmitXmlDecl, value);
1084c2c66affSColin Finck }
1085c2c66affSColin Finck 
mxwriter_put_version(IMXWriter * iface,BSTR version)1086c2c66affSColin Finck static HRESULT WINAPI mxwriter_put_version(IMXWriter *iface, BSTR version)
1087c2c66affSColin Finck {
1088c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1089c2c66affSColin Finck 
1090c2c66affSColin Finck     TRACE("(%p)->(%s)\n", This, debugstr_w(version));
1091c2c66affSColin Finck 
1092c2c66affSColin Finck     if (!version) return E_INVALIDARG;
1093c2c66affSColin Finck 
1094c2c66affSColin Finck     SysFreeString(This->version);
1095c2c66affSColin Finck     This->version = SysAllocString(version);
1096c2c66affSColin Finck 
1097c2c66affSColin Finck     return S_OK;
1098c2c66affSColin Finck }
1099c2c66affSColin Finck 
mxwriter_get_version(IMXWriter * iface,BSTR * version)1100c2c66affSColin Finck static HRESULT WINAPI mxwriter_get_version(IMXWriter *iface, BSTR *version)
1101c2c66affSColin Finck {
1102c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1103c2c66affSColin Finck 
1104c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, version);
1105c2c66affSColin Finck 
1106c2c66affSColin Finck     if (!version) return E_POINTER;
1107c2c66affSColin Finck 
1108c2c66affSColin Finck     return return_bstr(This->version, version);
1109c2c66affSColin Finck }
1110c2c66affSColin Finck 
mxwriter_put_disableOutputEscaping(IMXWriter * iface,VARIANT_BOOL value)1111c2c66affSColin Finck static HRESULT WINAPI mxwriter_put_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL value)
1112c2c66affSColin Finck {
1113c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1114c2c66affSColin Finck 
1115c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, value);
1116c2c66affSColin Finck     return writer_set_property(This, MXWriter_DisableEscaping, value);
1117c2c66affSColin Finck }
1118c2c66affSColin Finck 
mxwriter_get_disableOutputEscaping(IMXWriter * iface,VARIANT_BOOL * value)1119c2c66affSColin Finck static HRESULT WINAPI mxwriter_get_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL *value)
1120c2c66affSColin Finck {
1121c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1122c2c66affSColin Finck 
1123c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, value);
1124c2c66affSColin Finck     return writer_get_property(This, MXWriter_DisableEscaping, value);
1125c2c66affSColin Finck }
1126c2c66affSColin Finck 
mxwriter_flush(IMXWriter * iface)1127c2c66affSColin Finck static HRESULT WINAPI mxwriter_flush(IMXWriter *iface)
1128c2c66affSColin Finck {
1129c2c66affSColin Finck     mxwriter *This = impl_from_IMXWriter( iface );
1130c2c66affSColin Finck     TRACE("(%p)\n", This);
1131c2c66affSColin Finck     return flush_output_buffer(This);
1132c2c66affSColin Finck }
1133c2c66affSColin Finck 
1134c2c66affSColin Finck static const struct IMXWriterVtbl MXWriterVtbl =
1135c2c66affSColin Finck {
1136c2c66affSColin Finck     mxwriter_QueryInterface,
1137c2c66affSColin Finck     mxwriter_AddRef,
1138c2c66affSColin Finck     mxwriter_Release,
1139c2c66affSColin Finck     mxwriter_GetTypeInfoCount,
1140c2c66affSColin Finck     mxwriter_GetTypeInfo,
1141c2c66affSColin Finck     mxwriter_GetIDsOfNames,
1142c2c66affSColin Finck     mxwriter_Invoke,
1143c2c66affSColin Finck     mxwriter_put_output,
1144c2c66affSColin Finck     mxwriter_get_output,
1145c2c66affSColin Finck     mxwriter_put_encoding,
1146c2c66affSColin Finck     mxwriter_get_encoding,
1147c2c66affSColin Finck     mxwriter_put_byteOrderMark,
1148c2c66affSColin Finck     mxwriter_get_byteOrderMark,
1149c2c66affSColin Finck     mxwriter_put_indent,
1150c2c66affSColin Finck     mxwriter_get_indent,
1151c2c66affSColin Finck     mxwriter_put_standalone,
1152c2c66affSColin Finck     mxwriter_get_standalone,
1153c2c66affSColin Finck     mxwriter_put_omitXMLDeclaration,
1154c2c66affSColin Finck     mxwriter_get_omitXMLDeclaration,
1155c2c66affSColin Finck     mxwriter_put_version,
1156c2c66affSColin Finck     mxwriter_get_version,
1157c2c66affSColin Finck     mxwriter_put_disableOutputEscaping,
1158c2c66affSColin Finck     mxwriter_get_disableOutputEscaping,
1159c2c66affSColin Finck     mxwriter_flush
1160c2c66affSColin Finck };
1161c2c66affSColin Finck 
1162c2c66affSColin Finck /*** ISAXContentHandler ***/
SAXContentHandler_QueryInterface(ISAXContentHandler * iface,REFIID riid,void ** obj)1163c2c66affSColin Finck static HRESULT WINAPI SAXContentHandler_QueryInterface(
1164c2c66affSColin Finck     ISAXContentHandler *iface,
1165c2c66affSColin Finck     REFIID riid,
1166c2c66affSColin Finck     void **obj)
1167c2c66affSColin Finck {
1168c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1169c2c66affSColin Finck     return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1170c2c66affSColin Finck }
1171c2c66affSColin Finck 
SAXContentHandler_AddRef(ISAXContentHandler * iface)1172c2c66affSColin Finck static ULONG WINAPI SAXContentHandler_AddRef(ISAXContentHandler *iface)
1173c2c66affSColin Finck {
1174c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1175c2c66affSColin Finck     return IMXWriter_AddRef(&This->IMXWriter_iface);
1176c2c66affSColin Finck }
1177c2c66affSColin Finck 
SAXContentHandler_Release(ISAXContentHandler * iface)1178c2c66affSColin Finck static ULONG WINAPI SAXContentHandler_Release(ISAXContentHandler *iface)
1179c2c66affSColin Finck {
1180c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1181c2c66affSColin Finck     return IMXWriter_Release(&This->IMXWriter_iface);
1182c2c66affSColin Finck }
1183c2c66affSColin Finck 
SAXContentHandler_putDocumentLocator(ISAXContentHandler * iface,ISAXLocator * locator)1184c2c66affSColin Finck static HRESULT WINAPI SAXContentHandler_putDocumentLocator(
1185c2c66affSColin Finck     ISAXContentHandler *iface,
1186c2c66affSColin Finck     ISAXLocator *locator)
1187c2c66affSColin Finck {
1188c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1189c2c66affSColin Finck     FIXME("(%p)->(%p)\n", This, locator);
1190c2c66affSColin Finck     return E_NOTIMPL;
1191c2c66affSColin Finck }
1192c2c66affSColin Finck 
SAXContentHandler_startDocument(ISAXContentHandler * iface)1193c2c66affSColin Finck static HRESULT WINAPI SAXContentHandler_startDocument(ISAXContentHandler *iface)
1194c2c66affSColin Finck {
1195c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1196c2c66affSColin Finck 
1197c2c66affSColin Finck     TRACE("(%p)\n", This);
1198c2c66affSColin Finck 
1199c2c66affSColin Finck     /* If properties have been changed since the last "endDocument" call
1200c2c66affSColin Finck      * we need to reset the output buffer. If we don't the output buffer
1201c2c66affSColin Finck      * could end up with multiple XML documents in it, plus this seems to
1202c2c66affSColin Finck      * be how Windows works.
1203c2c66affSColin Finck      */
1204c2c66affSColin Finck     if (This->prop_changed) {
1205c2c66affSColin Finck         reset_output_buffer(This);
1206c2c66affSColin Finck         This->prop_changed = FALSE;
1207c2c66affSColin Finck     }
1208c2c66affSColin Finck 
1209c2c66affSColin Finck     if (This->props[MXWriter_OmitXmlDecl] == VARIANT_TRUE) return S_OK;
1210c2c66affSColin Finck 
1211c2c66affSColin Finck     write_prolog_buffer(This);
1212c2c66affSColin Finck 
1213c2c66affSColin Finck     if (This->dest && This->xml_enc == XmlEncoding_UTF16) {
1214c2c66affSColin Finck         static const char utf16BOM[] = {0xff,0xfe};
1215c2c66affSColin Finck 
1216c2c66affSColin Finck         if (This->props[MXWriter_BOM] == VARIANT_TRUE)
1217c2c66affSColin Finck             /* Windows passes a NULL pointer as the pcbWritten parameter and
1218c2c66affSColin Finck              * ignores any error codes returned from this Write call.
1219c2c66affSColin Finck              */
1220c2c66affSColin Finck             IStream_Write(This->dest, utf16BOM, sizeof(utf16BOM), NULL);
1221c2c66affSColin Finck     }
1222c2c66affSColin Finck 
1223c2c66affSColin Finck     return S_OK;
1224c2c66affSColin Finck }
1225c2c66affSColin Finck 
SAXContentHandler_endDocument(ISAXContentHandler * iface)1226c2c66affSColin Finck static HRESULT WINAPI SAXContentHandler_endDocument(ISAXContentHandler *iface)
1227c2c66affSColin Finck {
1228c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1229c2c66affSColin Finck     TRACE("(%p)\n", This);
1230c2c66affSColin Finck     This->prop_changed = FALSE;
1231c2c66affSColin Finck     return flush_output_buffer(This);
1232c2c66affSColin Finck }
1233c2c66affSColin Finck 
SAXContentHandler_startPrefixMapping(ISAXContentHandler * iface,const WCHAR * prefix,int nprefix,const WCHAR * uri,int nuri)1234c2c66affSColin Finck static HRESULT WINAPI SAXContentHandler_startPrefixMapping(
1235c2c66affSColin Finck     ISAXContentHandler *iface,
1236c2c66affSColin Finck     const WCHAR *prefix,
1237c2c66affSColin Finck     int nprefix,
1238c2c66affSColin Finck     const WCHAR *uri,
1239c2c66affSColin Finck     int nuri)
1240c2c66affSColin Finck {
1241c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1242c2c66affSColin Finck     TRACE("(%p)->(%s %s)\n", This, debugstr_wn(prefix, nprefix), debugstr_wn(uri, nuri));
1243c2c66affSColin Finck     return S_OK;
1244c2c66affSColin Finck }
1245c2c66affSColin Finck 
SAXContentHandler_endPrefixMapping(ISAXContentHandler * iface,const WCHAR * prefix,int nprefix)1246c2c66affSColin Finck static HRESULT WINAPI SAXContentHandler_endPrefixMapping(
1247c2c66affSColin Finck     ISAXContentHandler *iface,
1248c2c66affSColin Finck     const WCHAR *prefix,
1249c2c66affSColin Finck     int nprefix)
1250c2c66affSColin Finck {
1251c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1252c2c66affSColin Finck     TRACE("(%p)->(%s)\n", This, debugstr_wn(prefix, nprefix));
1253c2c66affSColin Finck     return S_OK;
1254c2c66affSColin Finck }
1255c2c66affSColin Finck 
mxwriter_write_attribute(mxwriter * writer,const WCHAR * qname,int qname_len,const WCHAR * value,int value_len,BOOL escape)1256c2c66affSColin Finck static void mxwriter_write_attribute(mxwriter *writer, const WCHAR *qname, int qname_len,
1257c2c66affSColin Finck     const WCHAR *value, int value_len, BOOL escape)
1258c2c66affSColin Finck {
1259c2c66affSColin Finck     static const WCHAR eqW[] = {'='};
1260c2c66affSColin Finck 
1261c2c66affSColin Finck     /* space separator in front of every attribute */
1262c2c66affSColin Finck     write_output_buffer(writer, spaceW, 1);
1263c2c66affSColin Finck     write_output_buffer(writer, qname, qname_len);
1264c2c66affSColin Finck     write_output_buffer(writer, eqW, 1);
1265c2c66affSColin Finck 
1266c2c66affSColin Finck     if (escape)
1267c2c66affSColin Finck     {
1268c2c66affSColin Finck         WCHAR *escaped = get_escaped_string(value, EscapeValue, &value_len);
1269c2c66affSColin Finck         write_output_buffer_quoted(writer, escaped, value_len);
1270c2c66affSColin Finck         heap_free(escaped);
1271c2c66affSColin Finck     }
1272c2c66affSColin Finck     else
1273c2c66affSColin Finck         write_output_buffer_quoted(writer, value, value_len);
1274c2c66affSColin Finck }
1275c2c66affSColin Finck 
mxwriter_write_starttag(mxwriter * writer,const WCHAR * qname,int len)1276c2c66affSColin Finck static void mxwriter_write_starttag(mxwriter *writer, const WCHAR *qname, int len)
1277c2c66affSColin Finck {
1278c2c66affSColin Finck     static const WCHAR ltW[] = {'<'};
1279c2c66affSColin Finck 
1280c2c66affSColin Finck     close_element_starttag(writer);
1281c2c66affSColin Finck     set_element_name(writer, qname ? qname : emptyW, qname ? len : 0);
1282c2c66affSColin Finck 
1283c2c66affSColin Finck     write_node_indent(writer);
1284c2c66affSColin Finck 
1285c2c66affSColin Finck     write_output_buffer(writer, ltW, 1);
1286c2c66affSColin Finck     write_output_buffer(writer, qname ? qname : emptyW, qname ? len : 0);
1287c2c66affSColin Finck     writer_inc_indent(writer);
1288c2c66affSColin Finck }
1289c2c66affSColin Finck 
SAXContentHandler_startElement(ISAXContentHandler * iface,const WCHAR * namespaceUri,int nnamespaceUri,const WCHAR * local_name,int nlocal_name,const WCHAR * QName,int nQName,ISAXAttributes * attr)1290c2c66affSColin Finck static HRESULT WINAPI SAXContentHandler_startElement(
1291c2c66affSColin Finck     ISAXContentHandler *iface,
1292c2c66affSColin Finck     const WCHAR *namespaceUri,
1293c2c66affSColin Finck     int nnamespaceUri,
1294c2c66affSColin Finck     const WCHAR *local_name,
1295c2c66affSColin Finck     int nlocal_name,
1296c2c66affSColin Finck     const WCHAR *QName,
1297c2c66affSColin Finck     int nQName,
1298c2c66affSColin Finck     ISAXAttributes *attr)
1299c2c66affSColin Finck {
1300c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1301c2c66affSColin Finck 
1302c2c66affSColin Finck     TRACE("(%p)->(%s %s %s %p)\n", This, debugstr_wn(namespaceUri, nnamespaceUri),
1303c2c66affSColin Finck         debugstr_wn(local_name, nlocal_name), debugstr_wn(QName, nQName), attr);
1304c2c66affSColin Finck 
1305c2c66affSColin Finck     if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1306c2c66affSColin Finck         (nQName == -1 && This->class_version == MSXML6))
1307c2c66affSColin Finck         return E_INVALIDARG;
1308c2c66affSColin Finck 
1309c2c66affSColin Finck     mxwriter_write_starttag(This, QName, nQName);
1310c2c66affSColin Finck 
1311c2c66affSColin Finck     if (attr)
1312c2c66affSColin Finck     {
1313c2c66affSColin Finck         int length, i, escape;
1314c2c66affSColin Finck         HRESULT hr;
1315c2c66affSColin Finck 
1316c2c66affSColin Finck         hr = ISAXAttributes_getLength(attr, &length);
1317c2c66affSColin Finck         if (FAILED(hr)) return hr;
1318c2c66affSColin Finck 
1319c2c66affSColin Finck         escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
1320c2c66affSColin Finck             (This->class_version == MSXML4 || This->class_version == MSXML6);
1321c2c66affSColin Finck 
1322c2c66affSColin Finck         for (i = 0; i < length; i++)
1323c2c66affSColin Finck         {
1324c2c66affSColin Finck             int qname_len = 0, value_len = 0;
1325c2c66affSColin Finck             const WCHAR *qname, *value;
1326c2c66affSColin Finck 
1327c2c66affSColin Finck             hr = ISAXAttributes_getQName(attr, i, &qname, &qname_len);
1328c2c66affSColin Finck             if (FAILED(hr)) return hr;
1329c2c66affSColin Finck 
1330c2c66affSColin Finck             hr = ISAXAttributes_getValue(attr, i, &value, &value_len);
1331c2c66affSColin Finck             if (FAILED(hr)) return hr;
1332c2c66affSColin Finck 
1333c2c66affSColin Finck             mxwriter_write_attribute(This, qname, qname_len, value, value_len, escape);
1334c2c66affSColin Finck         }
1335c2c66affSColin Finck     }
1336c2c66affSColin Finck 
1337c2c66affSColin Finck     return S_OK;
1338c2c66affSColin Finck }
1339c2c66affSColin Finck 
SAXContentHandler_endElement(ISAXContentHandler * iface,const WCHAR * namespaceUri,int nnamespaceUri,const WCHAR * local_name,int nlocal_name,const WCHAR * QName,int nQName)1340c2c66affSColin Finck static HRESULT WINAPI SAXContentHandler_endElement(
1341c2c66affSColin Finck     ISAXContentHandler *iface,
1342c2c66affSColin Finck     const WCHAR *namespaceUri,
1343c2c66affSColin Finck     int nnamespaceUri,
1344c2c66affSColin Finck     const WCHAR * local_name,
1345c2c66affSColin Finck     int nlocal_name,
1346c2c66affSColin Finck     const WCHAR *QName,
1347c2c66affSColin Finck     int nQName)
1348c2c66affSColin Finck {
1349c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1350c2c66affSColin Finck 
1351c2c66affSColin Finck     TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(namespaceUri, nnamespaceUri), nnamespaceUri,
1352c2c66affSColin Finck         debugstr_wn(local_name, nlocal_name), nlocal_name, debugstr_wn(QName, nQName), nQName);
1353c2c66affSColin Finck 
1354c2c66affSColin Finck     if (((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6) ||
1355c2c66affSColin Finck          (nQName == -1 && This->class_version == MSXML6))
1356c2c66affSColin Finck         return E_INVALIDARG;
1357c2c66affSColin Finck 
1358c2c66affSColin Finck     writer_dec_indent(This);
1359c2c66affSColin Finck 
1360c2c66affSColin Finck     if (This->element)
1361c2c66affSColin Finck     {
1362c2c66affSColin Finck         static const WCHAR closeW[] = {'/','>'};
1363c2c66affSColin Finck         write_output_buffer(This, closeW, 2);
1364c2c66affSColin Finck     }
1365c2c66affSColin Finck     else
1366c2c66affSColin Finck     {
1367c2c66affSColin Finck         static const WCHAR closetagW[] = {'<','/'};
1368c2c66affSColin Finck         static const WCHAR gtW[] = {'>'};
1369c2c66affSColin Finck 
1370c2c66affSColin Finck         write_node_indent(This);
1371c2c66affSColin Finck         write_output_buffer(This, closetagW, 2);
1372c2c66affSColin Finck         write_output_buffer(This, QName, nQName);
1373c2c66affSColin Finck         write_output_buffer(This, gtW, 1);
1374c2c66affSColin Finck     }
1375c2c66affSColin Finck 
1376c2c66affSColin Finck     set_element_name(This, NULL, 0);
1377c2c66affSColin Finck 
1378c2c66affSColin Finck     return S_OK;
1379c2c66affSColin Finck }
1380c2c66affSColin Finck 
SAXContentHandler_characters(ISAXContentHandler * iface,const WCHAR * chars,int nchars)1381c2c66affSColin Finck static HRESULT WINAPI SAXContentHandler_characters(
1382c2c66affSColin Finck     ISAXContentHandler *iface,
1383c2c66affSColin Finck     const WCHAR *chars,
1384c2c66affSColin Finck     int nchars)
1385c2c66affSColin Finck {
1386c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1387c2c66affSColin Finck 
1388c2c66affSColin Finck     TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1389c2c66affSColin Finck 
1390c2c66affSColin Finck     if (!chars) return E_INVALIDARG;
1391c2c66affSColin Finck 
1392c2c66affSColin Finck     close_element_starttag(This);
1393c2c66affSColin Finck     set_element_name(This, NULL, 0);
1394c2c66affSColin Finck 
1395c2c66affSColin Finck     if (!This->cdata)
1396c2c66affSColin Finck         This->text = TRUE;
1397c2c66affSColin Finck 
1398c2c66affSColin Finck     if (nchars)
1399c2c66affSColin Finck     {
1400c2c66affSColin Finck         if (This->cdata || This->props[MXWriter_DisableEscaping] == VARIANT_TRUE)
1401c2c66affSColin Finck             write_output_buffer(This, chars, nchars);
1402c2c66affSColin Finck         else
1403c2c66affSColin Finck         {
1404c2c66affSColin Finck             int len = nchars;
1405c2c66affSColin Finck             WCHAR *escaped;
1406c2c66affSColin Finck 
1407c2c66affSColin Finck             escaped = get_escaped_string(chars, EscapeText, &len);
1408c2c66affSColin Finck             write_output_buffer(This, escaped, len);
1409c2c66affSColin Finck             heap_free(escaped);
1410c2c66affSColin Finck         }
1411c2c66affSColin Finck     }
1412c2c66affSColin Finck 
1413c2c66affSColin Finck     return S_OK;
1414c2c66affSColin Finck }
1415c2c66affSColin Finck 
SAXContentHandler_ignorableWhitespace(ISAXContentHandler * iface,const WCHAR * chars,int nchars)1416c2c66affSColin Finck static HRESULT WINAPI SAXContentHandler_ignorableWhitespace(
1417c2c66affSColin Finck     ISAXContentHandler *iface,
1418c2c66affSColin Finck     const WCHAR *chars,
1419c2c66affSColin Finck     int nchars)
1420c2c66affSColin Finck {
1421c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1422c2c66affSColin Finck 
1423c2c66affSColin Finck     TRACE("(%p)->(%s)\n", This, debugstr_wn(chars, nchars));
1424c2c66affSColin Finck 
1425c2c66affSColin Finck     if (!chars) return E_INVALIDARG;
1426c2c66affSColin Finck 
1427c2c66affSColin Finck     write_output_buffer(This, chars, nchars);
1428c2c66affSColin Finck 
1429c2c66affSColin Finck     return S_OK;
1430c2c66affSColin Finck }
1431c2c66affSColin Finck 
SAXContentHandler_processingInstruction(ISAXContentHandler * iface,const WCHAR * target,int ntarget,const WCHAR * data,int ndata)1432c2c66affSColin Finck static HRESULT WINAPI SAXContentHandler_processingInstruction(
1433c2c66affSColin Finck     ISAXContentHandler *iface,
1434c2c66affSColin Finck     const WCHAR *target,
1435c2c66affSColin Finck     int ntarget,
1436c2c66affSColin Finck     const WCHAR *data,
1437c2c66affSColin Finck     int ndata)
1438c2c66affSColin Finck {
1439c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1440c2c66affSColin Finck     static const WCHAR openpiW[] = {'<','?'};
1441c2c66affSColin Finck     static const WCHAR closepiW[] = {'?','>','\r','\n'};
1442c2c66affSColin Finck 
1443c2c66affSColin Finck     TRACE("(%p)->(%s %s)\n", This, debugstr_wn(target, ntarget), debugstr_wn(data, ndata));
1444c2c66affSColin Finck 
1445c2c66affSColin Finck     if (!target) return E_INVALIDARG;
1446c2c66affSColin Finck 
1447c2c66affSColin Finck     write_node_indent(This);
1448bab6b90fSAmine Khaldi     write_output_buffer(This, openpiW, ARRAY_SIZE(openpiW));
1449c2c66affSColin Finck 
1450c2c66affSColin Finck     if (*target)
1451c2c66affSColin Finck         write_output_buffer(This, target, ntarget);
1452c2c66affSColin Finck 
1453c2c66affSColin Finck     if (data && *data && ndata)
1454c2c66affSColin Finck     {
1455c2c66affSColin Finck         write_output_buffer(This, spaceW, 1);
1456c2c66affSColin Finck         write_output_buffer(This, data, ndata);
1457c2c66affSColin Finck     }
1458c2c66affSColin Finck 
1459bab6b90fSAmine Khaldi     write_output_buffer(This, closepiW, ARRAY_SIZE(closepiW));
1460c2c66affSColin Finck     This->newline = TRUE;
1461c2c66affSColin Finck 
1462c2c66affSColin Finck     return S_OK;
1463c2c66affSColin Finck }
1464c2c66affSColin Finck 
SAXContentHandler_skippedEntity(ISAXContentHandler * iface,const WCHAR * name,int nname)1465c2c66affSColin Finck static HRESULT WINAPI SAXContentHandler_skippedEntity(
1466c2c66affSColin Finck     ISAXContentHandler *iface,
1467c2c66affSColin Finck     const WCHAR *name,
1468c2c66affSColin Finck     int nname)
1469c2c66affSColin Finck {
1470c2c66affSColin Finck     mxwriter *This = impl_from_ISAXContentHandler( iface );
1471c2c66affSColin Finck     FIXME("(%p)->(%s)\n", This, debugstr_wn(name, nname));
1472c2c66affSColin Finck     return E_NOTIMPL;
1473c2c66affSColin Finck }
1474c2c66affSColin Finck 
1475c2c66affSColin Finck static const struct ISAXContentHandlerVtbl SAXContentHandlerVtbl =
1476c2c66affSColin Finck {
1477c2c66affSColin Finck     SAXContentHandler_QueryInterface,
1478c2c66affSColin Finck     SAXContentHandler_AddRef,
1479c2c66affSColin Finck     SAXContentHandler_Release,
1480c2c66affSColin Finck     SAXContentHandler_putDocumentLocator,
1481c2c66affSColin Finck     SAXContentHandler_startDocument,
1482c2c66affSColin Finck     SAXContentHandler_endDocument,
1483c2c66affSColin Finck     SAXContentHandler_startPrefixMapping,
1484c2c66affSColin Finck     SAXContentHandler_endPrefixMapping,
1485c2c66affSColin Finck     SAXContentHandler_startElement,
1486c2c66affSColin Finck     SAXContentHandler_endElement,
1487c2c66affSColin Finck     SAXContentHandler_characters,
1488c2c66affSColin Finck     SAXContentHandler_ignorableWhitespace,
1489c2c66affSColin Finck     SAXContentHandler_processingInstruction,
1490c2c66affSColin Finck     SAXContentHandler_skippedEntity
1491c2c66affSColin Finck };
1492c2c66affSColin Finck 
1493c2c66affSColin Finck /*** ISAXLexicalHandler ***/
SAXLexicalHandler_QueryInterface(ISAXLexicalHandler * iface,REFIID riid,void ** obj)1494c2c66affSColin Finck static HRESULT WINAPI SAXLexicalHandler_QueryInterface(ISAXLexicalHandler *iface,
1495c2c66affSColin Finck     REFIID riid, void **obj)
1496c2c66affSColin Finck {
1497c2c66affSColin Finck     mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1498c2c66affSColin Finck     return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1499c2c66affSColin Finck }
1500c2c66affSColin Finck 
SAXLexicalHandler_AddRef(ISAXLexicalHandler * iface)1501c2c66affSColin Finck static ULONG WINAPI SAXLexicalHandler_AddRef(ISAXLexicalHandler *iface)
1502c2c66affSColin Finck {
1503c2c66affSColin Finck     mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1504c2c66affSColin Finck     return IMXWriter_AddRef(&This->IMXWriter_iface);
1505c2c66affSColin Finck }
1506c2c66affSColin Finck 
SAXLexicalHandler_Release(ISAXLexicalHandler * iface)1507c2c66affSColin Finck static ULONG WINAPI SAXLexicalHandler_Release(ISAXLexicalHandler *iface)
1508c2c66affSColin Finck {
1509c2c66affSColin Finck     mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1510c2c66affSColin Finck     return IMXWriter_Release(&This->IMXWriter_iface);
1511c2c66affSColin Finck }
1512c2c66affSColin Finck 
SAXLexicalHandler_startDTD(ISAXLexicalHandler * iface,const WCHAR * name,int name_len,const WCHAR * publicId,int publicId_len,const WCHAR * systemId,int systemId_len)1513c2c66affSColin Finck static HRESULT WINAPI SAXLexicalHandler_startDTD(ISAXLexicalHandler *iface,
1514c2c66affSColin Finck     const WCHAR *name, int name_len, const WCHAR *publicId, int publicId_len,
1515c2c66affSColin Finck     const WCHAR *systemId, int systemId_len)
1516c2c66affSColin Finck {
1517c2c66affSColin Finck     static const WCHAR doctypeW[] = {'<','!','D','O','C','T','Y','P','E',' '};
1518c2c66affSColin Finck     static const WCHAR openintW[] = {'[','\r','\n'};
1519c2c66affSColin Finck 
1520c2c66affSColin Finck     mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1521c2c66affSColin Finck 
1522c2c66affSColin Finck     TRACE("(%p)->(%s %s %s)\n", This, debugstr_wn(name, name_len), debugstr_wn(publicId, publicId_len),
1523c2c66affSColin Finck         debugstr_wn(systemId, systemId_len));
1524c2c66affSColin Finck 
1525c2c66affSColin Finck     if (!name) return E_INVALIDARG;
1526c2c66affSColin Finck 
1527bab6b90fSAmine Khaldi     write_output_buffer(This, doctypeW, ARRAY_SIZE(doctypeW));
1528c2c66affSColin Finck 
1529c2c66affSColin Finck     if (*name)
1530c2c66affSColin Finck     {
1531c2c66affSColin Finck         write_output_buffer(This, name, name_len);
1532c2c66affSColin Finck         write_output_buffer(This, spaceW, 1);
1533c2c66affSColin Finck     }
1534c2c66affSColin Finck 
1535c2c66affSColin Finck     if (publicId)
1536c2c66affSColin Finck     {
1537bab6b90fSAmine Khaldi         write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
1538c2c66affSColin Finck         write_output_buffer_quoted(This, publicId, publicId_len);
1539c2c66affSColin Finck 
1540c2c66affSColin Finck         if (!systemId) return E_INVALIDARG;
1541c2c66affSColin Finck 
1542c2c66affSColin Finck         if (*publicId)
1543c2c66affSColin Finck             write_output_buffer(This, spaceW, 1);
1544c2c66affSColin Finck 
1545c2c66affSColin Finck         write_output_buffer_quoted(This, systemId, systemId_len);
1546c2c66affSColin Finck 
1547c2c66affSColin Finck         if (*systemId)
1548c2c66affSColin Finck             write_output_buffer(This, spaceW, 1);
1549c2c66affSColin Finck     }
1550c2c66affSColin Finck     else if (systemId)
1551c2c66affSColin Finck     {
1552bab6b90fSAmine Khaldi         write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
1553c2c66affSColin Finck         write_output_buffer_quoted(This, systemId, systemId_len);
1554c2c66affSColin Finck         if (*systemId)
1555c2c66affSColin Finck             write_output_buffer(This, spaceW, 1);
1556c2c66affSColin Finck     }
1557c2c66affSColin Finck 
1558bab6b90fSAmine Khaldi     write_output_buffer(This, openintW, ARRAY_SIZE(openintW));
1559c2c66affSColin Finck 
1560c2c66affSColin Finck     return S_OK;
1561c2c66affSColin Finck }
1562c2c66affSColin Finck 
SAXLexicalHandler_endDTD(ISAXLexicalHandler * iface)1563c2c66affSColin Finck static HRESULT WINAPI SAXLexicalHandler_endDTD(ISAXLexicalHandler *iface)
1564c2c66affSColin Finck {
1565c2c66affSColin Finck     mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1566c2c66affSColin Finck     static const WCHAR closedtdW[] = {']','>','\r','\n'};
1567c2c66affSColin Finck 
1568c2c66affSColin Finck     TRACE("(%p)\n", This);
1569c2c66affSColin Finck 
1570bab6b90fSAmine Khaldi     write_output_buffer(This, closedtdW, ARRAY_SIZE(closedtdW));
1571c2c66affSColin Finck 
1572c2c66affSColin Finck     return S_OK;
1573c2c66affSColin Finck }
1574c2c66affSColin Finck 
SAXLexicalHandler_startEntity(ISAXLexicalHandler * iface,const WCHAR * name,int len)1575c2c66affSColin Finck static HRESULT WINAPI SAXLexicalHandler_startEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1576c2c66affSColin Finck {
1577c2c66affSColin Finck     mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1578c2c66affSColin Finck     FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1579c2c66affSColin Finck     return E_NOTIMPL;
1580c2c66affSColin Finck }
1581c2c66affSColin Finck 
SAXLexicalHandler_endEntity(ISAXLexicalHandler * iface,const WCHAR * name,int len)1582c2c66affSColin Finck static HRESULT WINAPI SAXLexicalHandler_endEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
1583c2c66affSColin Finck {
1584c2c66affSColin Finck     mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1585c2c66affSColin Finck     FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
1586c2c66affSColin Finck     return E_NOTIMPL;
1587c2c66affSColin Finck }
1588c2c66affSColin Finck 
SAXLexicalHandler_startCDATA(ISAXLexicalHandler * iface)1589c2c66affSColin Finck static HRESULT WINAPI SAXLexicalHandler_startCDATA(ISAXLexicalHandler *iface)
1590c2c66affSColin Finck {
1591c2c66affSColin Finck     static const WCHAR scdataW[] = {'<','!','[','C','D','A','T','A','['};
1592c2c66affSColin Finck     mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1593c2c66affSColin Finck 
1594c2c66affSColin Finck     TRACE("(%p)\n", This);
1595c2c66affSColin Finck 
1596c2c66affSColin Finck     write_node_indent(This);
1597bab6b90fSAmine Khaldi     write_output_buffer(This, scdataW, ARRAY_SIZE(scdataW));
1598c2c66affSColin Finck     This->cdata = TRUE;
1599c2c66affSColin Finck 
1600c2c66affSColin Finck     return S_OK;
1601c2c66affSColin Finck }
1602c2c66affSColin Finck 
SAXLexicalHandler_endCDATA(ISAXLexicalHandler * iface)1603c2c66affSColin Finck static HRESULT WINAPI SAXLexicalHandler_endCDATA(ISAXLexicalHandler *iface)
1604c2c66affSColin Finck {
1605c2c66affSColin Finck     mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1606c2c66affSColin Finck     static const WCHAR ecdataW[] = {']',']','>'};
1607c2c66affSColin Finck 
1608c2c66affSColin Finck     TRACE("(%p)\n", This);
1609c2c66affSColin Finck 
1610bab6b90fSAmine Khaldi     write_output_buffer(This, ecdataW, ARRAY_SIZE(ecdataW));
1611c2c66affSColin Finck     This->cdata = FALSE;
1612c2c66affSColin Finck 
1613c2c66affSColin Finck     return S_OK;
1614c2c66affSColin Finck }
1615c2c66affSColin Finck 
SAXLexicalHandler_comment(ISAXLexicalHandler * iface,const WCHAR * chars,int nchars)1616c2c66affSColin Finck static HRESULT WINAPI SAXLexicalHandler_comment(ISAXLexicalHandler *iface, const WCHAR *chars, int nchars)
1617c2c66affSColin Finck {
1618c2c66affSColin Finck     mxwriter *This = impl_from_ISAXLexicalHandler( iface );
1619c2c66affSColin Finck     static const WCHAR copenW[] = {'<','!','-','-'};
1620c2c66affSColin Finck     static const WCHAR ccloseW[] = {'-','-','>','\r','\n'};
1621c2c66affSColin Finck 
1622c2c66affSColin Finck     TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);
1623c2c66affSColin Finck 
1624c2c66affSColin Finck     if (!chars) return E_INVALIDARG;
1625c2c66affSColin Finck 
1626c2c66affSColin Finck     close_element_starttag(This);
1627c2c66affSColin Finck     write_node_indent(This);
1628c2c66affSColin Finck 
1629bab6b90fSAmine Khaldi     write_output_buffer(This, copenW, ARRAY_SIZE(copenW));
1630c2c66affSColin Finck     if (nchars)
1631c2c66affSColin Finck         write_output_buffer(This, chars, nchars);
1632bab6b90fSAmine Khaldi     write_output_buffer(This, ccloseW, ARRAY_SIZE(ccloseW));
1633c2c66affSColin Finck 
1634c2c66affSColin Finck     return S_OK;
1635c2c66affSColin Finck }
1636c2c66affSColin Finck 
1637c2c66affSColin Finck static const struct ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl =
1638c2c66affSColin Finck {
1639c2c66affSColin Finck     SAXLexicalHandler_QueryInterface,
1640c2c66affSColin Finck     SAXLexicalHandler_AddRef,
1641c2c66affSColin Finck     SAXLexicalHandler_Release,
1642c2c66affSColin Finck     SAXLexicalHandler_startDTD,
1643c2c66affSColin Finck     SAXLexicalHandler_endDTD,
1644c2c66affSColin Finck     SAXLexicalHandler_startEntity,
1645c2c66affSColin Finck     SAXLexicalHandler_endEntity,
1646c2c66affSColin Finck     SAXLexicalHandler_startCDATA,
1647c2c66affSColin Finck     SAXLexicalHandler_endCDATA,
1648c2c66affSColin Finck     SAXLexicalHandler_comment
1649c2c66affSColin Finck };
1650c2c66affSColin Finck 
1651c2c66affSColin Finck /*** ISAXDeclHandler ***/
SAXDeclHandler_QueryInterface(ISAXDeclHandler * iface,REFIID riid,void ** obj)1652c2c66affSColin Finck static HRESULT WINAPI SAXDeclHandler_QueryInterface(ISAXDeclHandler *iface,
1653c2c66affSColin Finck     REFIID riid, void **obj)
1654c2c66affSColin Finck {
1655c2c66affSColin Finck     mxwriter *This = impl_from_ISAXDeclHandler( iface );
1656c2c66affSColin Finck     return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1657c2c66affSColin Finck }
1658c2c66affSColin Finck 
SAXDeclHandler_AddRef(ISAXDeclHandler * iface)1659c2c66affSColin Finck static ULONG WINAPI SAXDeclHandler_AddRef(ISAXDeclHandler *iface)
1660c2c66affSColin Finck {
1661c2c66affSColin Finck     mxwriter *This = impl_from_ISAXDeclHandler( iface );
1662c2c66affSColin Finck     return IMXWriter_AddRef(&This->IMXWriter_iface);
1663c2c66affSColin Finck }
1664c2c66affSColin Finck 
SAXDeclHandler_Release(ISAXDeclHandler * iface)1665c2c66affSColin Finck static ULONG WINAPI SAXDeclHandler_Release(ISAXDeclHandler *iface)
1666c2c66affSColin Finck {
1667c2c66affSColin Finck     mxwriter *This = impl_from_ISAXDeclHandler( iface );
1668c2c66affSColin Finck     return IMXWriter_Release(&This->IMXWriter_iface);
1669c2c66affSColin Finck }
1670c2c66affSColin Finck 
SAXDeclHandler_elementDecl(ISAXDeclHandler * iface,const WCHAR * name,int n_name,const WCHAR * model,int n_model)1671c2c66affSColin Finck static HRESULT WINAPI SAXDeclHandler_elementDecl(ISAXDeclHandler *iface,
1672c2c66affSColin Finck     const WCHAR *name, int n_name, const WCHAR *model, int n_model)
1673c2c66affSColin Finck {
1674c2c66affSColin Finck     static const WCHAR elementW[] = {'<','!','E','L','E','M','E','N','T',' '};
1675c2c66affSColin Finck     mxwriter *This = impl_from_ISAXDeclHandler( iface );
1676c2c66affSColin Finck 
1677c2c66affSColin Finck     TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1678c2c66affSColin Finck         debugstr_wn(model, n_model), n_model);
1679c2c66affSColin Finck 
1680c2c66affSColin Finck     if (!name || !model) return E_INVALIDARG;
1681c2c66affSColin Finck 
1682bab6b90fSAmine Khaldi     write_output_buffer(This, elementW, ARRAY_SIZE(elementW));
1683c2c66affSColin Finck     if (n_name) {
1684c2c66affSColin Finck         write_output_buffer(This, name, n_name);
1685bab6b90fSAmine Khaldi         write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1686c2c66affSColin Finck     }
1687c2c66affSColin Finck     if (n_model)
1688c2c66affSColin Finck         write_output_buffer(This, model, n_model);
1689bab6b90fSAmine Khaldi     write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1690c2c66affSColin Finck 
1691c2c66affSColin Finck     return S_OK;
1692c2c66affSColin Finck }
1693c2c66affSColin Finck 
SAXDeclHandler_attributeDecl(ISAXDeclHandler * iface,const WCHAR * element,int n_element,const WCHAR * attr,int n_attr,const WCHAR * type,int n_type,const WCHAR * Default,int n_default,const WCHAR * value,int n_value)1694c2c66affSColin Finck static HRESULT WINAPI SAXDeclHandler_attributeDecl(ISAXDeclHandler *iface,
1695c2c66affSColin Finck     const WCHAR *element, int n_element, const WCHAR *attr, int n_attr,
1696c2c66affSColin Finck     const WCHAR *type, int n_type, const WCHAR *Default, int n_default,
1697c2c66affSColin Finck     const WCHAR *value, int n_value)
1698c2c66affSColin Finck {
1699c2c66affSColin Finck     mxwriter *This = impl_from_ISAXDeclHandler( iface );
1700c2c66affSColin Finck     static const WCHAR attlistW[] = {'<','!','A','T','T','L','I','S','T',' '};
1701c2c66affSColin Finck     static const WCHAR closetagW[] = {'>','\r','\n'};
1702c2c66affSColin Finck 
1703c2c66affSColin Finck     TRACE("(%p)->(%s:%d %s:%d %s:%d %s:%d %s:%d)\n", This, debugstr_wn(element, n_element), n_element,
1704c2c66affSColin Finck         debugstr_wn(attr, n_attr), n_attr, debugstr_wn(type, n_type), n_type, debugstr_wn(Default, n_default), n_default,
1705c2c66affSColin Finck         debugstr_wn(value, n_value), n_value);
1706c2c66affSColin Finck 
1707bab6b90fSAmine Khaldi     write_output_buffer(This, attlistW, ARRAY_SIZE(attlistW));
1708c2c66affSColin Finck     if (n_element) {
1709c2c66affSColin Finck         write_output_buffer(This, element, n_element);
1710bab6b90fSAmine Khaldi         write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1711c2c66affSColin Finck     }
1712c2c66affSColin Finck 
1713c2c66affSColin Finck     if (n_attr) {
1714c2c66affSColin Finck         write_output_buffer(This, attr, n_attr);
1715bab6b90fSAmine Khaldi         write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1716c2c66affSColin Finck     }
1717c2c66affSColin Finck 
1718c2c66affSColin Finck     if (n_type) {
1719c2c66affSColin Finck         write_output_buffer(This, type, n_type);
1720bab6b90fSAmine Khaldi         write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1721c2c66affSColin Finck     }
1722c2c66affSColin Finck 
1723c2c66affSColin Finck     if (n_default) {
1724c2c66affSColin Finck         write_output_buffer(This, Default, n_default);
1725bab6b90fSAmine Khaldi         write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1726c2c66affSColin Finck     }
1727c2c66affSColin Finck 
1728c2c66affSColin Finck     if (n_value)
1729c2c66affSColin Finck         write_output_buffer_quoted(This, value, n_value);
1730c2c66affSColin Finck 
1731bab6b90fSAmine Khaldi     write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1732c2c66affSColin Finck 
1733c2c66affSColin Finck     return S_OK;
1734c2c66affSColin Finck }
1735c2c66affSColin Finck 
SAXDeclHandler_internalEntityDecl(ISAXDeclHandler * iface,const WCHAR * name,int n_name,const WCHAR * value,int n_value)1736c2c66affSColin Finck static HRESULT WINAPI SAXDeclHandler_internalEntityDecl(ISAXDeclHandler *iface,
1737c2c66affSColin Finck     const WCHAR *name, int n_name, const WCHAR *value, int n_value)
1738c2c66affSColin Finck {
1739c2c66affSColin Finck     mxwriter *This = impl_from_ISAXDeclHandler( iface );
1740c2c66affSColin Finck 
1741c2c66affSColin Finck     TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1742c2c66affSColin Finck         debugstr_wn(value, n_value), n_value);
1743c2c66affSColin Finck 
1744c2c66affSColin Finck     if (!name || !value) return E_INVALIDARG;
1745c2c66affSColin Finck 
1746bab6b90fSAmine Khaldi     write_output_buffer(This, entityW, ARRAY_SIZE(entityW));
1747c2c66affSColin Finck     if (n_name) {
1748c2c66affSColin Finck         write_output_buffer(This, name, n_name);
1749bab6b90fSAmine Khaldi         write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1750c2c66affSColin Finck     }
1751c2c66affSColin Finck 
1752c2c66affSColin Finck     if (n_value)
1753c2c66affSColin Finck         write_output_buffer_quoted(This, value, n_value);
1754c2c66affSColin Finck 
1755bab6b90fSAmine Khaldi     write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1756c2c66affSColin Finck 
1757c2c66affSColin Finck     return S_OK;
1758c2c66affSColin Finck }
1759c2c66affSColin Finck 
SAXDeclHandler_externalEntityDecl(ISAXDeclHandler * iface,const WCHAR * name,int n_name,const WCHAR * publicId,int n_publicId,const WCHAR * systemId,int n_systemId)1760c2c66affSColin Finck static HRESULT WINAPI SAXDeclHandler_externalEntityDecl(ISAXDeclHandler *iface,
1761c2c66affSColin Finck     const WCHAR *name, int n_name, const WCHAR *publicId, int n_publicId,
1762c2c66affSColin Finck     const WCHAR *systemId, int n_systemId)
1763c2c66affSColin Finck {
1764c2c66affSColin Finck     mxwriter *This = impl_from_ISAXDeclHandler( iface );
1765c2c66affSColin Finck 
1766c2c66affSColin Finck     TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
1767c2c66affSColin Finck         debugstr_wn(publicId, n_publicId), n_publicId, debugstr_wn(systemId, n_systemId), n_systemId);
1768c2c66affSColin Finck 
1769c2c66affSColin Finck     if (!name || !systemId) return E_INVALIDARG;
1770c2c66affSColin Finck 
1771bab6b90fSAmine Khaldi     write_output_buffer(This, entityW, ARRAY_SIZE(entityW));
1772c2c66affSColin Finck     if (n_name) {
1773c2c66affSColin Finck         write_output_buffer(This, name, n_name);
1774bab6b90fSAmine Khaldi         write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1775c2c66affSColin Finck     }
1776c2c66affSColin Finck 
1777c2c66affSColin Finck     if (publicId)
1778c2c66affSColin Finck     {
1779bab6b90fSAmine Khaldi         write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
1780c2c66affSColin Finck         write_output_buffer_quoted(This, publicId, n_publicId);
1781bab6b90fSAmine Khaldi         write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
1782c2c66affSColin Finck         write_output_buffer_quoted(This, systemId, n_systemId);
1783c2c66affSColin Finck     }
1784c2c66affSColin Finck     else
1785c2c66affSColin Finck     {
1786bab6b90fSAmine Khaldi         write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
1787c2c66affSColin Finck         write_output_buffer_quoted(This, systemId, n_systemId);
1788c2c66affSColin Finck     }
1789c2c66affSColin Finck 
1790bab6b90fSAmine Khaldi     write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
1791c2c66affSColin Finck 
1792c2c66affSColin Finck     return S_OK;
1793c2c66affSColin Finck }
1794c2c66affSColin Finck 
1795c2c66affSColin Finck static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl = {
1796c2c66affSColin Finck     SAXDeclHandler_QueryInterface,
1797c2c66affSColin Finck     SAXDeclHandler_AddRef,
1798c2c66affSColin Finck     SAXDeclHandler_Release,
1799c2c66affSColin Finck     SAXDeclHandler_elementDecl,
1800c2c66affSColin Finck     SAXDeclHandler_attributeDecl,
1801c2c66affSColin Finck     SAXDeclHandler_internalEntityDecl,
1802c2c66affSColin Finck     SAXDeclHandler_externalEntityDecl
1803c2c66affSColin Finck };
1804c2c66affSColin Finck 
1805c2c66affSColin Finck /*** IVBSAXDeclHandler ***/
VBSAXDeclHandler_QueryInterface(IVBSAXDeclHandler * iface,REFIID riid,void ** obj)1806c2c66affSColin Finck static HRESULT WINAPI VBSAXDeclHandler_QueryInterface(IVBSAXDeclHandler *iface,
1807c2c66affSColin Finck     REFIID riid, void **obj)
1808c2c66affSColin Finck {
1809c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1810c2c66affSColin Finck     return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1811c2c66affSColin Finck }
1812c2c66affSColin Finck 
VBSAXDeclHandler_AddRef(IVBSAXDeclHandler * iface)1813c2c66affSColin Finck static ULONG WINAPI VBSAXDeclHandler_AddRef(IVBSAXDeclHandler *iface)
1814c2c66affSColin Finck {
1815c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1816c2c66affSColin Finck     return IMXWriter_AddRef(&This->IMXWriter_iface);
1817c2c66affSColin Finck }
1818c2c66affSColin Finck 
VBSAXDeclHandler_Release(IVBSAXDeclHandler * iface)1819c2c66affSColin Finck static ULONG WINAPI VBSAXDeclHandler_Release(IVBSAXDeclHandler *iface)
1820c2c66affSColin Finck {
1821c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1822c2c66affSColin Finck     return IMXWriter_Release(&This->IMXWriter_iface);
1823c2c66affSColin Finck }
1824c2c66affSColin Finck 
VBSAXDeclHandler_GetTypeInfoCount(IVBSAXDeclHandler * iface,UINT * pctinfo)1825c2c66affSColin Finck static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfoCount(IVBSAXDeclHandler *iface, UINT* pctinfo)
1826c2c66affSColin Finck {
1827c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1828c2c66affSColin Finck     return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1829c2c66affSColin Finck }
1830c2c66affSColin Finck 
VBSAXDeclHandler_GetTypeInfo(IVBSAXDeclHandler * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)1831c2c66affSColin Finck static HRESULT WINAPI VBSAXDeclHandler_GetTypeInfo(IVBSAXDeclHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1832c2c66affSColin Finck {
1833c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1834c2c66affSColin Finck     return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1835c2c66affSColin Finck }
1836c2c66affSColin Finck 
VBSAXDeclHandler_GetIDsOfNames(IVBSAXDeclHandler * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)1837c2c66affSColin Finck static HRESULT WINAPI VBSAXDeclHandler_GetIDsOfNames(IVBSAXDeclHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1838c2c66affSColin Finck     UINT cNames, LCID lcid, DISPID* rgDispId )
1839c2c66affSColin Finck {
1840c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1841c2c66affSColin Finck     return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1842c2c66affSColin Finck }
1843c2c66affSColin Finck 
VBSAXDeclHandler_Invoke(IVBSAXDeclHandler * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)1844c2c66affSColin Finck static HRESULT WINAPI VBSAXDeclHandler_Invoke(IVBSAXDeclHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1845c2c66affSColin Finck     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1846c2c66affSColin Finck {
1847c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1848c2c66affSColin Finck     return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1849c2c66affSColin Finck         pExcepInfo, puArgErr);
1850c2c66affSColin Finck }
1851c2c66affSColin Finck 
VBSAXDeclHandler_elementDecl(IVBSAXDeclHandler * iface,BSTR * name,BSTR * model)1852c2c66affSColin Finck static HRESULT WINAPI VBSAXDeclHandler_elementDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *model)
1853c2c66affSColin Finck {
1854c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1855c2c66affSColin Finck 
1856c2c66affSColin Finck     TRACE("(%p)->(%p %p)\n", This, name, model);
1857c2c66affSColin Finck 
1858c2c66affSColin Finck     if (!name || !model)
1859c2c66affSColin Finck         return E_POINTER;
1860c2c66affSColin Finck 
1861c2c66affSColin Finck     return ISAXDeclHandler_elementDecl(&This->ISAXDeclHandler_iface, *name, -1, *model, -1);
1862c2c66affSColin Finck }
1863c2c66affSColin Finck 
VBSAXDeclHandler_attributeDecl(IVBSAXDeclHandler * iface,BSTR * element,BSTR * attr,BSTR * type,BSTR * default_value,BSTR * value)1864c2c66affSColin Finck static HRESULT WINAPI VBSAXDeclHandler_attributeDecl(IVBSAXDeclHandler *iface,
1865c2c66affSColin Finck     BSTR *element, BSTR *attr, BSTR *type, BSTR *default_value, BSTR *value)
1866c2c66affSColin Finck {
1867c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1868c2c66affSColin Finck 
1869c2c66affSColin Finck     TRACE("(%p)->(%p %p %p %p %p)\n", This, element, attr, type, default_value, value);
1870c2c66affSColin Finck 
1871c2c66affSColin Finck     if (!element || !attr || !type || !default_value || !value)
1872c2c66affSColin Finck         return E_POINTER;
1873c2c66affSColin Finck 
1874c2c66affSColin Finck     return ISAXDeclHandler_attributeDecl(&This->ISAXDeclHandler_iface, *element, -1, *attr, -1, *type, -1,
1875c2c66affSColin Finck         *default_value, -1, *value, -1);
1876c2c66affSColin Finck }
1877c2c66affSColin Finck 
VBSAXDeclHandler_internalEntityDecl(IVBSAXDeclHandler * iface,BSTR * name,BSTR * value)1878c2c66affSColin Finck static HRESULT WINAPI VBSAXDeclHandler_internalEntityDecl(IVBSAXDeclHandler *iface, BSTR *name, BSTR *value)
1879c2c66affSColin Finck {
1880c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1881c2c66affSColin Finck 
1882c2c66affSColin Finck     TRACE("(%p)->(%p %p)\n", This, name, value);
1883c2c66affSColin Finck 
1884c2c66affSColin Finck     if (!name || !value)
1885c2c66affSColin Finck         return E_POINTER;
1886c2c66affSColin Finck 
1887c2c66affSColin Finck     return ISAXDeclHandler_internalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *value, -1);
1888c2c66affSColin Finck }
1889c2c66affSColin Finck 
VBSAXDeclHandler_externalEntityDecl(IVBSAXDeclHandler * iface,BSTR * name,BSTR * publicid,BSTR * systemid)1890c2c66affSColin Finck static HRESULT WINAPI VBSAXDeclHandler_externalEntityDecl(IVBSAXDeclHandler *iface,
1891c2c66affSColin Finck     BSTR *name, BSTR *publicid, BSTR *systemid)
1892c2c66affSColin Finck {
1893c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDeclHandler( iface );
1894c2c66affSColin Finck 
1895c2c66affSColin Finck     TRACE("(%p)->(%p %p %p)\n", This, name, publicid, systemid);
1896c2c66affSColin Finck 
1897c2c66affSColin Finck     if (!name || !publicid || !systemid)
1898c2c66affSColin Finck         return E_POINTER;
1899c2c66affSColin Finck 
1900c2c66affSColin Finck     return ISAXDeclHandler_externalEntityDecl(&This->ISAXDeclHandler_iface, *name, -1, *publicid, -1, *systemid, -1);
1901c2c66affSColin Finck }
1902c2c66affSColin Finck 
1903c2c66affSColin Finck static const IVBSAXDeclHandlerVtbl VBSAXDeclHandlerVtbl = {
1904c2c66affSColin Finck     VBSAXDeclHandler_QueryInterface,
1905c2c66affSColin Finck     VBSAXDeclHandler_AddRef,
1906c2c66affSColin Finck     VBSAXDeclHandler_Release,
1907c2c66affSColin Finck     VBSAXDeclHandler_GetTypeInfoCount,
1908c2c66affSColin Finck     VBSAXDeclHandler_GetTypeInfo,
1909c2c66affSColin Finck     VBSAXDeclHandler_GetIDsOfNames,
1910c2c66affSColin Finck     VBSAXDeclHandler_Invoke,
1911c2c66affSColin Finck     VBSAXDeclHandler_elementDecl,
1912c2c66affSColin Finck     VBSAXDeclHandler_attributeDecl,
1913c2c66affSColin Finck     VBSAXDeclHandler_internalEntityDecl,
1914c2c66affSColin Finck     VBSAXDeclHandler_externalEntityDecl
1915c2c66affSColin Finck };
1916c2c66affSColin Finck 
1917c2c66affSColin Finck /*** IVBSAXLexicalHandler ***/
VBSAXLexicalHandler_QueryInterface(IVBSAXLexicalHandler * iface,REFIID riid,void ** obj)1918c2c66affSColin Finck static HRESULT WINAPI VBSAXLexicalHandler_QueryInterface(IVBSAXLexicalHandler *iface,
1919c2c66affSColin Finck     REFIID riid, void **obj)
1920c2c66affSColin Finck {
1921c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1922c2c66affSColin Finck     return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
1923c2c66affSColin Finck }
1924c2c66affSColin Finck 
VBSAXLexicalHandler_AddRef(IVBSAXLexicalHandler * iface)1925c2c66affSColin Finck static ULONG WINAPI VBSAXLexicalHandler_AddRef(IVBSAXLexicalHandler *iface)
1926c2c66affSColin Finck {
1927c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1928c2c66affSColin Finck     return IMXWriter_AddRef(&This->IMXWriter_iface);
1929c2c66affSColin Finck }
1930c2c66affSColin Finck 
VBSAXLexicalHandler_Release(IVBSAXLexicalHandler * iface)1931c2c66affSColin Finck static ULONG WINAPI VBSAXLexicalHandler_Release(IVBSAXLexicalHandler *iface)
1932c2c66affSColin Finck {
1933c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1934c2c66affSColin Finck     return IMXWriter_Release(&This->IMXWriter_iface);
1935c2c66affSColin Finck }
1936c2c66affSColin Finck 
VBSAXLexicalHandler_GetTypeInfoCount(IVBSAXLexicalHandler * iface,UINT * pctinfo)1937c2c66affSColin Finck static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfoCount(IVBSAXLexicalHandler *iface, UINT* pctinfo)
1938c2c66affSColin Finck {
1939c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1940c2c66affSColin Finck     return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
1941c2c66affSColin Finck }
1942c2c66affSColin Finck 
VBSAXLexicalHandler_GetTypeInfo(IVBSAXLexicalHandler * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)1943c2c66affSColin Finck static HRESULT WINAPI VBSAXLexicalHandler_GetTypeInfo(IVBSAXLexicalHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
1944c2c66affSColin Finck {
1945c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1946c2c66affSColin Finck     return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
1947c2c66affSColin Finck }
1948c2c66affSColin Finck 
VBSAXLexicalHandler_GetIDsOfNames(IVBSAXLexicalHandler * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)1949c2c66affSColin Finck static HRESULT WINAPI VBSAXLexicalHandler_GetIDsOfNames(IVBSAXLexicalHandler *iface, REFIID riid, LPOLESTR* rgszNames,
1950c2c66affSColin Finck     UINT cNames, LCID lcid, DISPID* rgDispId )
1951c2c66affSColin Finck {
1952c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1953c2c66affSColin Finck     return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
1954c2c66affSColin Finck }
1955c2c66affSColin Finck 
VBSAXLexicalHandler_Invoke(IVBSAXLexicalHandler * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)1956c2c66affSColin Finck static HRESULT WINAPI VBSAXLexicalHandler_Invoke(IVBSAXLexicalHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1957c2c66affSColin Finck     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
1958c2c66affSColin Finck {
1959c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1960c2c66affSColin Finck     return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
1961c2c66affSColin Finck         pExcepInfo, puArgErr);
1962c2c66affSColin Finck }
1963c2c66affSColin Finck 
VBSAXLexicalHandler_startDTD(IVBSAXLexicalHandler * iface,BSTR * name,BSTR * publicId,BSTR * systemId)1964c2c66affSColin Finck static HRESULT WINAPI VBSAXLexicalHandler_startDTD(IVBSAXLexicalHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
1965c2c66affSColin Finck {
1966c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1967c2c66affSColin Finck 
1968c2c66affSColin Finck     TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
1969c2c66affSColin Finck 
1970c2c66affSColin Finck     if (!name || !publicId || !systemId)
1971c2c66affSColin Finck         return E_POINTER;
1972c2c66affSColin Finck 
1973c2c66affSColin Finck     return ISAXLexicalHandler_startDTD(&This->ISAXLexicalHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
1974c2c66affSColin Finck }
1975c2c66affSColin Finck 
VBSAXLexicalHandler_endDTD(IVBSAXLexicalHandler * iface)1976c2c66affSColin Finck static HRESULT WINAPI VBSAXLexicalHandler_endDTD(IVBSAXLexicalHandler *iface)
1977c2c66affSColin Finck {
1978c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1979c2c66affSColin Finck     return ISAXLexicalHandler_endDTD(&This->ISAXLexicalHandler_iface);
1980c2c66affSColin Finck }
1981c2c66affSColin Finck 
VBSAXLexicalHandler_startEntity(IVBSAXLexicalHandler * iface,BSTR * name)1982c2c66affSColin Finck static HRESULT WINAPI VBSAXLexicalHandler_startEntity(IVBSAXLexicalHandler *iface, BSTR *name)
1983c2c66affSColin Finck {
1984c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1985c2c66affSColin Finck 
1986c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, name);
1987c2c66affSColin Finck 
1988c2c66affSColin Finck     if (!name)
1989c2c66affSColin Finck         return E_POINTER;
1990c2c66affSColin Finck 
1991c2c66affSColin Finck     return ISAXLexicalHandler_startEntity(&This->ISAXLexicalHandler_iface, *name, -1);
1992c2c66affSColin Finck }
1993c2c66affSColin Finck 
VBSAXLexicalHandler_endEntity(IVBSAXLexicalHandler * iface,BSTR * name)1994c2c66affSColin Finck static HRESULT WINAPI VBSAXLexicalHandler_endEntity(IVBSAXLexicalHandler *iface, BSTR *name)
1995c2c66affSColin Finck {
1996c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
1997c2c66affSColin Finck 
1998c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, name);
1999c2c66affSColin Finck 
2000c2c66affSColin Finck     if (!name)
2001c2c66affSColin Finck         return E_POINTER;
2002c2c66affSColin Finck 
2003c2c66affSColin Finck     return ISAXLexicalHandler_endEntity(&This->ISAXLexicalHandler_iface, *name, -1);
2004c2c66affSColin Finck }
2005c2c66affSColin Finck 
VBSAXLexicalHandler_startCDATA(IVBSAXLexicalHandler * iface)2006c2c66affSColin Finck static HRESULT WINAPI VBSAXLexicalHandler_startCDATA(IVBSAXLexicalHandler *iface)
2007c2c66affSColin Finck {
2008c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2009c2c66affSColin Finck     return ISAXLexicalHandler_startCDATA(&This->ISAXLexicalHandler_iface);
2010c2c66affSColin Finck }
2011c2c66affSColin Finck 
VBSAXLexicalHandler_endCDATA(IVBSAXLexicalHandler * iface)2012c2c66affSColin Finck static HRESULT WINAPI VBSAXLexicalHandler_endCDATA(IVBSAXLexicalHandler *iface)
2013c2c66affSColin Finck {
2014c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2015c2c66affSColin Finck     return ISAXLexicalHandler_endCDATA(&This->ISAXLexicalHandler_iface);
2016c2c66affSColin Finck }
2017c2c66affSColin Finck 
VBSAXLexicalHandler_comment(IVBSAXLexicalHandler * iface,BSTR * chars)2018c2c66affSColin Finck static HRESULT WINAPI VBSAXLexicalHandler_comment(IVBSAXLexicalHandler *iface, BSTR *chars)
2019c2c66affSColin Finck {
2020c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXLexicalHandler( iface );
2021c2c66affSColin Finck 
2022c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, chars);
2023c2c66affSColin Finck 
2024c2c66affSColin Finck     if (!chars)
2025c2c66affSColin Finck         return E_POINTER;
2026c2c66affSColin Finck 
2027c2c66affSColin Finck     return ISAXLexicalHandler_comment(&This->ISAXLexicalHandler_iface, *chars, -1);
2028c2c66affSColin Finck }
2029c2c66affSColin Finck 
2030c2c66affSColin Finck static const IVBSAXLexicalHandlerVtbl VBSAXLexicalHandlerVtbl = {
2031c2c66affSColin Finck     VBSAXLexicalHandler_QueryInterface,
2032c2c66affSColin Finck     VBSAXLexicalHandler_AddRef,
2033c2c66affSColin Finck     VBSAXLexicalHandler_Release,
2034c2c66affSColin Finck     VBSAXLexicalHandler_GetTypeInfoCount,
2035c2c66affSColin Finck     VBSAXLexicalHandler_GetTypeInfo,
2036c2c66affSColin Finck     VBSAXLexicalHandler_GetIDsOfNames,
2037c2c66affSColin Finck     VBSAXLexicalHandler_Invoke,
2038c2c66affSColin Finck     VBSAXLexicalHandler_startDTD,
2039c2c66affSColin Finck     VBSAXLexicalHandler_endDTD,
2040c2c66affSColin Finck     VBSAXLexicalHandler_startEntity,
2041c2c66affSColin Finck     VBSAXLexicalHandler_endEntity,
2042c2c66affSColin Finck     VBSAXLexicalHandler_startCDATA,
2043c2c66affSColin Finck     VBSAXLexicalHandler_endCDATA,
2044c2c66affSColin Finck     VBSAXLexicalHandler_comment
2045c2c66affSColin Finck };
2046c2c66affSColin Finck 
2047c2c66affSColin Finck /*** IVBSAXContentHandler ***/
VBSAXContentHandler_QueryInterface(IVBSAXContentHandler * iface,REFIID riid,void ** obj)2048c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_QueryInterface(IVBSAXContentHandler *iface, REFIID riid, void **obj)
2049c2c66affSColin Finck {
2050c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2051c2c66affSColin Finck     return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2052c2c66affSColin Finck }
2053c2c66affSColin Finck 
VBSAXContentHandler_AddRef(IVBSAXContentHandler * iface)2054c2c66affSColin Finck static ULONG WINAPI VBSAXContentHandler_AddRef(IVBSAXContentHandler *iface)
2055c2c66affSColin Finck {
2056c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2057c2c66affSColin Finck     return IMXWriter_AddRef(&This->IMXWriter_iface);
2058c2c66affSColin Finck }
2059c2c66affSColin Finck 
VBSAXContentHandler_Release(IVBSAXContentHandler * iface)2060c2c66affSColin Finck static ULONG WINAPI VBSAXContentHandler_Release(IVBSAXContentHandler *iface)
2061c2c66affSColin Finck {
2062c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2063c2c66affSColin Finck     return IMXWriter_Release(&This->IMXWriter_iface);
2064c2c66affSColin Finck }
2065c2c66affSColin Finck 
VBSAXContentHandler_GetTypeInfoCount(IVBSAXContentHandler * iface,UINT * pctinfo)2066c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_GetTypeInfoCount(IVBSAXContentHandler *iface, UINT* pctinfo)
2067c2c66affSColin Finck {
2068c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2069c2c66affSColin Finck     return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2070c2c66affSColin Finck }
2071c2c66affSColin Finck 
VBSAXContentHandler_GetTypeInfo(IVBSAXContentHandler * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)2072c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_GetTypeInfo(IVBSAXContentHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2073c2c66affSColin Finck {
2074c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2075c2c66affSColin Finck     return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2076c2c66affSColin Finck }
2077c2c66affSColin Finck 
VBSAXContentHandler_GetIDsOfNames(IVBSAXContentHandler * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)2078c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_GetIDsOfNames(IVBSAXContentHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2079c2c66affSColin Finck     UINT cNames, LCID lcid, DISPID* rgDispId )
2080c2c66affSColin Finck {
2081c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2082c2c66affSColin Finck     return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2083c2c66affSColin Finck }
2084c2c66affSColin Finck 
VBSAXContentHandler_Invoke(IVBSAXContentHandler * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)2085c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_Invoke(IVBSAXContentHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2086c2c66affSColin Finck     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2087c2c66affSColin Finck {
2088c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2089c2c66affSColin Finck     return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2090c2c66affSColin Finck         pExcepInfo, puArgErr);
2091c2c66affSColin Finck }
2092c2c66affSColin Finck 
VBSAXContentHandler_putref_documentLocator(IVBSAXContentHandler * iface,IVBSAXLocator * locator)2093c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_putref_documentLocator(IVBSAXContentHandler *iface, IVBSAXLocator *locator)
2094c2c66affSColin Finck {
2095c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2096c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, locator);
2097c2c66affSColin Finck     return S_OK;
2098c2c66affSColin Finck }
2099c2c66affSColin Finck 
VBSAXContentHandler_startDocument(IVBSAXContentHandler * iface)2100c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_startDocument(IVBSAXContentHandler *iface)
2101c2c66affSColin Finck {
2102c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2103c2c66affSColin Finck     return ISAXContentHandler_startDocument(&This->ISAXContentHandler_iface);
2104c2c66affSColin Finck }
2105c2c66affSColin Finck 
VBSAXContentHandler_endDocument(IVBSAXContentHandler * iface)2106c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_endDocument(IVBSAXContentHandler *iface)
2107c2c66affSColin Finck {
2108c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2109c2c66affSColin Finck     return ISAXContentHandler_endDocument(&This->ISAXContentHandler_iface);
2110c2c66affSColin Finck }
2111c2c66affSColin Finck 
VBSAXContentHandler_startPrefixMapping(IVBSAXContentHandler * iface,BSTR * prefix,BSTR * uri)2112c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_startPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix, BSTR *uri)
2113c2c66affSColin Finck {
2114c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2115c2c66affSColin Finck 
2116c2c66affSColin Finck     TRACE("(%p)->(%p %p)\n", This, prefix, uri);
2117c2c66affSColin Finck 
2118c2c66affSColin Finck     if (!prefix || !uri)
2119c2c66affSColin Finck         return E_POINTER;
2120c2c66affSColin Finck 
2121c2c66affSColin Finck     return ISAXContentHandler_startPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1, *uri, -1);
2122c2c66affSColin Finck }
2123c2c66affSColin Finck 
VBSAXContentHandler_endPrefixMapping(IVBSAXContentHandler * iface,BSTR * prefix)2124c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_endPrefixMapping(IVBSAXContentHandler *iface, BSTR *prefix)
2125c2c66affSColin Finck {
2126c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2127c2c66affSColin Finck 
2128c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, prefix);
2129c2c66affSColin Finck 
2130c2c66affSColin Finck     if (!prefix)
2131c2c66affSColin Finck         return E_POINTER;
2132c2c66affSColin Finck 
2133c2c66affSColin Finck     return ISAXContentHandler_endPrefixMapping(&This->ISAXContentHandler_iface, *prefix, -1);
2134c2c66affSColin Finck }
2135c2c66affSColin Finck 
VBSAXContentHandler_startElement(IVBSAXContentHandler * iface,BSTR * namespaceURI,BSTR * localName,BSTR * QName,IVBSAXAttributes * attrs)2136c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_startElement(IVBSAXContentHandler *iface,
2137c2c66affSColin Finck     BSTR *namespaceURI, BSTR *localName, BSTR *QName, IVBSAXAttributes *attrs)
2138c2c66affSColin Finck {
2139c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2140c2c66affSColin Finck 
2141c2c66affSColin Finck     TRACE("(%p)->(%p %p %p %p)\n", This, namespaceURI, localName, QName, attrs);
2142c2c66affSColin Finck 
2143c2c66affSColin Finck     if (!namespaceURI || !localName || !QName)
2144c2c66affSColin Finck         return E_POINTER;
2145c2c66affSColin Finck 
2146c2c66affSColin Finck     TRACE("(%s %s %s)\n", debugstr_w(*namespaceURI), debugstr_w(*localName), debugstr_w(*QName));
2147c2c66affSColin Finck 
2148c2c66affSColin Finck     mxwriter_write_starttag(This, *QName, SysStringLen(*QName));
2149c2c66affSColin Finck 
2150c2c66affSColin Finck     if (attrs)
2151c2c66affSColin Finck     {
2152c2c66affSColin Finck         int length, i, escape;
2153c2c66affSColin Finck         HRESULT hr;
2154c2c66affSColin Finck 
2155c2c66affSColin Finck         hr = IVBSAXAttributes_get_length(attrs, &length);
2156c2c66affSColin Finck         if (FAILED(hr)) return hr;
2157c2c66affSColin Finck 
2158c2c66affSColin Finck         escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
2159c2c66affSColin Finck             (This->class_version == MSXML4 || This->class_version == MSXML6);
2160c2c66affSColin Finck 
2161c2c66affSColin Finck         for (i = 0; i < length; i++)
2162c2c66affSColin Finck         {
2163c2c66affSColin Finck             BSTR qname, value;
2164c2c66affSColin Finck 
2165c2c66affSColin Finck             hr = IVBSAXAttributes_getQName(attrs, i, &qname);
2166c2c66affSColin Finck             if (FAILED(hr)) return hr;
2167c2c66affSColin Finck 
2168c2c66affSColin Finck             hr = IVBSAXAttributes_getValue(attrs, i, &value);
2169c2c66affSColin Finck             if (FAILED(hr))
2170c2c66affSColin Finck             {
2171c2c66affSColin Finck                 SysFreeString(qname);
2172c2c66affSColin Finck                 return hr;
2173c2c66affSColin Finck             }
2174c2c66affSColin Finck 
2175c2c66affSColin Finck             mxwriter_write_attribute(This, qname, SysStringLen(qname), value, SysStringLen(value), escape);
2176c2c66affSColin Finck             SysFreeString(qname);
2177c2c66affSColin Finck             SysFreeString(value);
2178c2c66affSColin Finck         }
2179c2c66affSColin Finck     }
2180c2c66affSColin Finck 
2181c2c66affSColin Finck     return S_OK;
2182c2c66affSColin Finck }
2183c2c66affSColin Finck 
VBSAXContentHandler_endElement(IVBSAXContentHandler * iface,BSTR * namespaceURI,BSTR * localName,BSTR * QName)2184c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_endElement(IVBSAXContentHandler *iface, BSTR *namespaceURI,
2185c2c66affSColin Finck     BSTR *localName, BSTR *QName)
2186c2c66affSColin Finck {
2187c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2188c2c66affSColin Finck 
2189c2c66affSColin Finck     TRACE("(%p)->(%p %p %p)\n", This, namespaceURI, localName, QName);
2190c2c66affSColin Finck 
2191c2c66affSColin Finck     if (!namespaceURI || !localName || !QName)
2192c2c66affSColin Finck         return E_POINTER;
2193c2c66affSColin Finck 
2194c2c66affSColin Finck     return ISAXContentHandler_endElement(&This->ISAXContentHandler_iface,
2195c2c66affSColin Finck         *namespaceURI, SysStringLen(*namespaceURI),
2196c2c66affSColin Finck         *localName, SysStringLen(*localName),
2197c2c66affSColin Finck         *QName, SysStringLen(*QName));
2198c2c66affSColin Finck }
2199c2c66affSColin Finck 
VBSAXContentHandler_characters(IVBSAXContentHandler * iface,BSTR * chars)2200c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_characters(IVBSAXContentHandler *iface, BSTR *chars)
2201c2c66affSColin Finck {
2202c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2203c2c66affSColin Finck 
2204c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, chars);
2205c2c66affSColin Finck 
2206c2c66affSColin Finck     if (!chars)
2207c2c66affSColin Finck         return E_POINTER;
2208c2c66affSColin Finck 
2209*eb44c20cSAmine Khaldi     return ISAXContentHandler_characters(&This->ISAXContentHandler_iface, *chars, SysStringLen(*chars));
2210c2c66affSColin Finck }
2211c2c66affSColin Finck 
VBSAXContentHandler_ignorableWhitespace(IVBSAXContentHandler * iface,BSTR * chars)2212c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_ignorableWhitespace(IVBSAXContentHandler *iface, BSTR *chars)
2213c2c66affSColin Finck {
2214c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2215c2c66affSColin Finck 
2216c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, chars);
2217c2c66affSColin Finck 
2218c2c66affSColin Finck     if (!chars)
2219c2c66affSColin Finck         return E_POINTER;
2220c2c66affSColin Finck 
2221c2c66affSColin Finck     return ISAXContentHandler_ignorableWhitespace(&This->ISAXContentHandler_iface, *chars, -1);
2222c2c66affSColin Finck }
2223c2c66affSColin Finck 
VBSAXContentHandler_processingInstruction(IVBSAXContentHandler * iface,BSTR * target,BSTR * data)2224c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_processingInstruction(IVBSAXContentHandler *iface,
2225c2c66affSColin Finck     BSTR *target, BSTR *data)
2226c2c66affSColin Finck {
2227c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2228c2c66affSColin Finck 
2229c2c66affSColin Finck     TRACE("(%p)->(%p %p)\n", This, target, data);
2230c2c66affSColin Finck 
2231c2c66affSColin Finck     if (!target || !data)
2232c2c66affSColin Finck         return E_POINTER;
2233c2c66affSColin Finck 
2234c2c66affSColin Finck     return ISAXContentHandler_processingInstruction(&This->ISAXContentHandler_iface, *target, -1, *data, -1);
2235c2c66affSColin Finck }
2236c2c66affSColin Finck 
VBSAXContentHandler_skippedEntity(IVBSAXContentHandler * iface,BSTR * name)2237c2c66affSColin Finck static HRESULT WINAPI VBSAXContentHandler_skippedEntity(IVBSAXContentHandler *iface, BSTR *name)
2238c2c66affSColin Finck {
2239c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
2240c2c66affSColin Finck 
2241c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, name);
2242c2c66affSColin Finck 
2243c2c66affSColin Finck     if (!name)
2244c2c66affSColin Finck         return E_POINTER;
2245c2c66affSColin Finck 
2246c2c66affSColin Finck     return ISAXContentHandler_skippedEntity(&This->ISAXContentHandler_iface, *name, -1);
2247c2c66affSColin Finck }
2248c2c66affSColin Finck 
2249c2c66affSColin Finck static const IVBSAXContentHandlerVtbl VBSAXContentHandlerVtbl = {
2250c2c66affSColin Finck     VBSAXContentHandler_QueryInterface,
2251c2c66affSColin Finck     VBSAXContentHandler_AddRef,
2252c2c66affSColin Finck     VBSAXContentHandler_Release,
2253c2c66affSColin Finck     VBSAXContentHandler_GetTypeInfoCount,
2254c2c66affSColin Finck     VBSAXContentHandler_GetTypeInfo,
2255c2c66affSColin Finck     VBSAXContentHandler_GetIDsOfNames,
2256c2c66affSColin Finck     VBSAXContentHandler_Invoke,
2257c2c66affSColin Finck     VBSAXContentHandler_putref_documentLocator,
2258c2c66affSColin Finck     VBSAXContentHandler_startDocument,
2259c2c66affSColin Finck     VBSAXContentHandler_endDocument,
2260c2c66affSColin Finck     VBSAXContentHandler_startPrefixMapping,
2261c2c66affSColin Finck     VBSAXContentHandler_endPrefixMapping,
2262c2c66affSColin Finck     VBSAXContentHandler_startElement,
2263c2c66affSColin Finck     VBSAXContentHandler_endElement,
2264c2c66affSColin Finck     VBSAXContentHandler_characters,
2265c2c66affSColin Finck     VBSAXContentHandler_ignorableWhitespace,
2266c2c66affSColin Finck     VBSAXContentHandler_processingInstruction,
2267c2c66affSColin Finck     VBSAXContentHandler_skippedEntity
2268c2c66affSColin Finck };
2269c2c66affSColin Finck 
SAXDTDHandler_QueryInterface(ISAXDTDHandler * iface,REFIID riid,void ** obj)2270c2c66affSColin Finck static HRESULT WINAPI SAXDTDHandler_QueryInterface(ISAXDTDHandler *iface, REFIID riid, void **obj)
2271c2c66affSColin Finck {
2272c2c66affSColin Finck     mxwriter *This = impl_from_ISAXDTDHandler( iface );
2273c2c66affSColin Finck     return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2274c2c66affSColin Finck }
2275c2c66affSColin Finck 
SAXDTDHandler_AddRef(ISAXDTDHandler * iface)2276c2c66affSColin Finck static ULONG WINAPI SAXDTDHandler_AddRef(ISAXDTDHandler *iface)
2277c2c66affSColin Finck {
2278c2c66affSColin Finck     mxwriter *This = impl_from_ISAXDTDHandler( iface );
2279c2c66affSColin Finck     return IMXWriter_AddRef(&This->IMXWriter_iface);
2280c2c66affSColin Finck }
2281c2c66affSColin Finck 
SAXDTDHandler_Release(ISAXDTDHandler * iface)2282c2c66affSColin Finck static ULONG WINAPI SAXDTDHandler_Release(ISAXDTDHandler *iface)
2283c2c66affSColin Finck {
2284c2c66affSColin Finck     mxwriter *This = impl_from_ISAXDTDHandler( iface );
2285c2c66affSColin Finck     return IMXWriter_Release(&This->IMXWriter_iface);
2286c2c66affSColin Finck }
2287c2c66affSColin Finck 
SAXDTDHandler_notationDecl(ISAXDTDHandler * iface,const WCHAR * name,INT n_name,const WCHAR * publicid,INT n_publicid,const WCHAR * systemid,INT n_systemid)2288c2c66affSColin Finck static HRESULT WINAPI SAXDTDHandler_notationDecl(ISAXDTDHandler *iface,
2289c2c66affSColin Finck     const WCHAR *name, INT n_name,
2290c2c66affSColin Finck     const WCHAR *publicid, INT n_publicid,
2291c2c66affSColin Finck     const WCHAR *systemid, INT n_systemid)
2292c2c66affSColin Finck {
2293c2c66affSColin Finck     static const WCHAR notationW[] = {'<','!','N','O','T','A','T','I','O','N',' '};
2294c2c66affSColin Finck     mxwriter *This = impl_from_ISAXDTDHandler( iface );
2295c2c66affSColin Finck 
2296c2c66affSColin Finck     TRACE("(%p)->(%s:%d, %s:%d, %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
2297c2c66affSColin Finck         debugstr_wn(publicid, n_publicid), n_publicid, debugstr_wn(systemid, n_systemid), n_systemid);
2298c2c66affSColin Finck 
2299c2c66affSColin Finck     if (!name || !n_name)
2300c2c66affSColin Finck         return E_INVALIDARG;
2301c2c66affSColin Finck 
2302bab6b90fSAmine Khaldi     write_output_buffer(This, notationW, ARRAY_SIZE(notationW));
2303c2c66affSColin Finck     write_output_buffer(This, name, n_name);
2304c2c66affSColin Finck 
2305c2c66affSColin Finck     if (!publicid && !systemid)
2306c2c66affSColin Finck         return E_INVALIDARG;
2307c2c66affSColin Finck 
2308bab6b90fSAmine Khaldi     write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
2309c2c66affSColin Finck     if (publicid)
2310c2c66affSColin Finck     {
2311bab6b90fSAmine Khaldi         write_output_buffer(This, publicW, ARRAY_SIZE(publicW));
2312c2c66affSColin Finck         write_output_buffer_quoted(This, publicid, n_publicid);
2313c2c66affSColin Finck         if (systemid)
2314c2c66affSColin Finck         {
2315bab6b90fSAmine Khaldi             write_output_buffer(This, spaceW, ARRAY_SIZE(spaceW));
2316c2c66affSColin Finck             write_output_buffer_quoted(This, systemid, n_systemid);
2317c2c66affSColin Finck         }
2318c2c66affSColin Finck     }
2319c2c66affSColin Finck     else
2320c2c66affSColin Finck     {
2321bab6b90fSAmine Khaldi         write_output_buffer(This, systemW, ARRAY_SIZE(systemW));
2322c2c66affSColin Finck         write_output_buffer_quoted(This, systemid, n_systemid);
2323c2c66affSColin Finck     }
2324c2c66affSColin Finck 
2325bab6b90fSAmine Khaldi     write_output_buffer(This, closetagW, ARRAY_SIZE(closetagW));
2326c2c66affSColin Finck 
2327c2c66affSColin Finck     return S_OK;
2328c2c66affSColin Finck }
2329c2c66affSColin Finck 
SAXDTDHandler_unparsedEntityDecl(ISAXDTDHandler * iface,const WCHAR * name,INT nname,const WCHAR * publicid,INT npublicid,const WCHAR * systemid,INT nsystemid,const WCHAR * notation,INT nnotation)2330c2c66affSColin Finck static HRESULT WINAPI SAXDTDHandler_unparsedEntityDecl(ISAXDTDHandler *iface,
2331c2c66affSColin Finck     const WCHAR *name, INT nname,
2332c2c66affSColin Finck     const WCHAR *publicid, INT npublicid,
2333c2c66affSColin Finck     const WCHAR *systemid, INT nsystemid,
2334c2c66affSColin Finck     const WCHAR *notation, INT nnotation)
2335c2c66affSColin Finck {
2336c2c66affSColin Finck     mxwriter *This = impl_from_ISAXDTDHandler( iface );
2337c2c66affSColin Finck     FIXME("(%p)->(%s:%d, %s:%d, %s:%d, %s:%d): stub\n", This, debugstr_wn(name, nname), nname,
2338c2c66affSColin Finck         debugstr_wn(publicid, npublicid), npublicid, debugstr_wn(systemid, nsystemid), nsystemid,
2339c2c66affSColin Finck         debugstr_wn(notation, nnotation), nnotation);
2340c2c66affSColin Finck     return E_NOTIMPL;
2341c2c66affSColin Finck }
2342c2c66affSColin Finck 
2343c2c66affSColin Finck static const ISAXDTDHandlerVtbl SAXDTDHandlerVtbl = {
2344c2c66affSColin Finck     SAXDTDHandler_QueryInterface,
2345c2c66affSColin Finck     SAXDTDHandler_AddRef,
2346c2c66affSColin Finck     SAXDTDHandler_Release,
2347c2c66affSColin Finck     SAXDTDHandler_notationDecl,
2348c2c66affSColin Finck     SAXDTDHandler_unparsedEntityDecl
2349c2c66affSColin Finck };
2350c2c66affSColin Finck 
2351c2c66affSColin Finck /*** IVBSAXDTDHandler ***/
VBSAXDTDHandler_QueryInterface(IVBSAXDTDHandler * iface,REFIID riid,void ** obj)2352c2c66affSColin Finck static HRESULT WINAPI VBSAXDTDHandler_QueryInterface(IVBSAXDTDHandler *iface, REFIID riid, void **obj)
2353c2c66affSColin Finck {
2354c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2355c2c66affSColin Finck     return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2356c2c66affSColin Finck }
2357c2c66affSColin Finck 
VBSAXDTDHandler_AddRef(IVBSAXDTDHandler * iface)2358c2c66affSColin Finck static ULONG WINAPI VBSAXDTDHandler_AddRef(IVBSAXDTDHandler *iface)
2359c2c66affSColin Finck {
2360c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2361c2c66affSColin Finck     return IMXWriter_AddRef(&This->IMXWriter_iface);
2362c2c66affSColin Finck }
2363c2c66affSColin Finck 
VBSAXDTDHandler_Release(IVBSAXDTDHandler * iface)2364c2c66affSColin Finck static ULONG WINAPI VBSAXDTDHandler_Release(IVBSAXDTDHandler *iface)
2365c2c66affSColin Finck {
2366c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2367c2c66affSColin Finck     return IMXWriter_Release(&This->IMXWriter_iface);
2368c2c66affSColin Finck }
2369c2c66affSColin Finck 
VBSAXDTDHandler_GetTypeInfoCount(IVBSAXDTDHandler * iface,UINT * pctinfo)2370c2c66affSColin Finck static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfoCount(IVBSAXDTDHandler *iface, UINT* pctinfo)
2371c2c66affSColin Finck {
2372c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2373c2c66affSColin Finck     return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2374c2c66affSColin Finck }
2375c2c66affSColin Finck 
VBSAXDTDHandler_GetTypeInfo(IVBSAXDTDHandler * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)2376c2c66affSColin Finck static HRESULT WINAPI VBSAXDTDHandler_GetTypeInfo(IVBSAXDTDHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2377c2c66affSColin Finck {
2378c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2379c2c66affSColin Finck     return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2380c2c66affSColin Finck }
2381c2c66affSColin Finck 
VBSAXDTDHandler_GetIDsOfNames(IVBSAXDTDHandler * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)2382c2c66affSColin Finck static HRESULT WINAPI VBSAXDTDHandler_GetIDsOfNames(IVBSAXDTDHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2383c2c66affSColin Finck     UINT cNames, LCID lcid, DISPID* rgDispId )
2384c2c66affSColin Finck {
2385c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2386c2c66affSColin Finck     return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2387c2c66affSColin Finck }
2388c2c66affSColin Finck 
VBSAXDTDHandler_Invoke(IVBSAXDTDHandler * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)2389c2c66affSColin Finck static HRESULT WINAPI VBSAXDTDHandler_Invoke(IVBSAXDTDHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2390c2c66affSColin Finck     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2391c2c66affSColin Finck {
2392c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2393c2c66affSColin Finck     return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2394c2c66affSColin Finck         pExcepInfo, puArgErr);
2395c2c66affSColin Finck }
2396c2c66affSColin Finck 
VBSAXDTDHandler_notationDecl(IVBSAXDTDHandler * iface,BSTR * name,BSTR * publicId,BSTR * systemId)2397c2c66affSColin Finck static HRESULT WINAPI VBSAXDTDHandler_notationDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId, BSTR *systemId)
2398c2c66affSColin Finck {
2399c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2400c2c66affSColin Finck 
2401c2c66affSColin Finck     TRACE("(%p)->(%p %p %p)\n", This, name, publicId, systemId);
2402c2c66affSColin Finck 
2403c2c66affSColin Finck     if (!name || !publicId || !systemId)
2404c2c66affSColin Finck         return E_POINTER;
2405c2c66affSColin Finck 
2406c2c66affSColin Finck     return ISAXDTDHandler_notationDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1, *systemId, -1);
2407c2c66affSColin Finck }
2408c2c66affSColin Finck 
VBSAXDTDHandler_unparsedEntityDecl(IVBSAXDTDHandler * iface,BSTR * name,BSTR * publicId,BSTR * systemId,BSTR * notation)2409c2c66affSColin Finck static HRESULT WINAPI VBSAXDTDHandler_unparsedEntityDecl(IVBSAXDTDHandler *iface, BSTR *name, BSTR *publicId,
2410c2c66affSColin Finck     BSTR *systemId, BSTR *notation)
2411c2c66affSColin Finck {
2412c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXDTDHandler( iface );
2413c2c66affSColin Finck 
2414c2c66affSColin Finck     TRACE("(%p)->(%p %p %p %p)\n", This, name, publicId, systemId, notation);
2415c2c66affSColin Finck 
2416c2c66affSColin Finck     if (!name || !publicId || !systemId || !notation)
2417c2c66affSColin Finck         return E_POINTER;
2418c2c66affSColin Finck 
2419c2c66affSColin Finck     return ISAXDTDHandler_unparsedEntityDecl(&This->ISAXDTDHandler_iface, *name, -1, *publicId, -1,
2420c2c66affSColin Finck         *systemId, -1, *notation, -1);
2421c2c66affSColin Finck }
2422c2c66affSColin Finck 
2423c2c66affSColin Finck static const IVBSAXDTDHandlerVtbl VBSAXDTDHandlerVtbl = {
2424c2c66affSColin Finck     VBSAXDTDHandler_QueryInterface,
2425c2c66affSColin Finck     VBSAXDTDHandler_AddRef,
2426c2c66affSColin Finck     VBSAXDTDHandler_Release,
2427c2c66affSColin Finck     VBSAXDTDHandler_GetTypeInfoCount,
2428c2c66affSColin Finck     VBSAXDTDHandler_GetTypeInfo,
2429c2c66affSColin Finck     VBSAXDTDHandler_GetIDsOfNames,
2430c2c66affSColin Finck     VBSAXDTDHandler_Invoke,
2431c2c66affSColin Finck     VBSAXDTDHandler_notationDecl,
2432c2c66affSColin Finck     VBSAXDTDHandler_unparsedEntityDecl
2433c2c66affSColin Finck };
2434c2c66affSColin Finck 
2435c2c66affSColin Finck /* ISAXErrorHandler */
SAXErrorHandler_QueryInterface(ISAXErrorHandler * iface,REFIID riid,void ** obj)2436c2c66affSColin Finck static HRESULT WINAPI SAXErrorHandler_QueryInterface(ISAXErrorHandler *iface, REFIID riid, void **obj)
2437c2c66affSColin Finck {
2438c2c66affSColin Finck     mxwriter *This = impl_from_ISAXErrorHandler( iface );
2439c2c66affSColin Finck     return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2440c2c66affSColin Finck }
2441c2c66affSColin Finck 
SAXErrorHandler_AddRef(ISAXErrorHandler * iface)2442c2c66affSColin Finck static ULONG WINAPI SAXErrorHandler_AddRef(ISAXErrorHandler *iface)
2443c2c66affSColin Finck {
2444c2c66affSColin Finck     mxwriter *This = impl_from_ISAXErrorHandler( iface );
2445c2c66affSColin Finck     return IMXWriter_AddRef(&This->IMXWriter_iface);
2446c2c66affSColin Finck }
2447c2c66affSColin Finck 
SAXErrorHandler_Release(ISAXErrorHandler * iface)2448c2c66affSColin Finck static ULONG WINAPI SAXErrorHandler_Release(ISAXErrorHandler *iface)
2449c2c66affSColin Finck {
2450c2c66affSColin Finck     mxwriter *This = impl_from_ISAXErrorHandler( iface );
2451c2c66affSColin Finck     return IMXWriter_Release(&This->IMXWriter_iface);
2452c2c66affSColin Finck }
2453c2c66affSColin Finck 
SAXErrorHandler_error(ISAXErrorHandler * iface,ISAXLocator * locator,const WCHAR * message,HRESULT hr)2454c2c66affSColin Finck static HRESULT WINAPI SAXErrorHandler_error(ISAXErrorHandler *iface,
2455c2c66affSColin Finck     ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2456c2c66affSColin Finck {
2457c2c66affSColin Finck     mxwriter *This = impl_from_ISAXErrorHandler( iface );
2458c2c66affSColin Finck 
2459c2c66affSColin Finck     FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2460c2c66affSColin Finck 
2461c2c66affSColin Finck     return E_NOTIMPL;
2462c2c66affSColin Finck }
2463c2c66affSColin Finck 
SAXErrorHandler_fatalError(ISAXErrorHandler * iface,ISAXLocator * locator,const WCHAR * message,HRESULT hr)2464c2c66affSColin Finck static HRESULT WINAPI SAXErrorHandler_fatalError(ISAXErrorHandler *iface,
2465c2c66affSColin Finck     ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2466c2c66affSColin Finck {
2467c2c66affSColin Finck     mxwriter *This = impl_from_ISAXErrorHandler( iface );
2468c2c66affSColin Finck 
2469c2c66affSColin Finck     FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2470c2c66affSColin Finck 
2471c2c66affSColin Finck     return E_NOTIMPL;
2472c2c66affSColin Finck }
2473c2c66affSColin Finck 
SAXErrorHandler_ignorableWarning(ISAXErrorHandler * iface,ISAXLocator * locator,const WCHAR * message,HRESULT hr)2474c2c66affSColin Finck static HRESULT WINAPI SAXErrorHandler_ignorableWarning(ISAXErrorHandler *iface,
2475c2c66affSColin Finck     ISAXLocator *locator, const WCHAR *message, HRESULT hr)
2476c2c66affSColin Finck {
2477c2c66affSColin Finck     mxwriter *This = impl_from_ISAXErrorHandler( iface );
2478c2c66affSColin Finck 
2479c2c66affSColin Finck     FIXME("(%p)->(%p %s 0x%08x)\n", This, locator, debugstr_w(message), hr);
2480c2c66affSColin Finck 
2481c2c66affSColin Finck     return E_NOTIMPL;
2482c2c66affSColin Finck }
2483c2c66affSColin Finck 
2484c2c66affSColin Finck static const ISAXErrorHandlerVtbl SAXErrorHandlerVtbl = {
2485c2c66affSColin Finck     SAXErrorHandler_QueryInterface,
2486c2c66affSColin Finck     SAXErrorHandler_AddRef,
2487c2c66affSColin Finck     SAXErrorHandler_Release,
2488c2c66affSColin Finck     SAXErrorHandler_error,
2489c2c66affSColin Finck     SAXErrorHandler_fatalError,
2490c2c66affSColin Finck     SAXErrorHandler_ignorableWarning
2491c2c66affSColin Finck };
2492c2c66affSColin Finck 
2493c2c66affSColin Finck /*** IVBSAXErrorHandler ***/
VBSAXErrorHandler_QueryInterface(IVBSAXErrorHandler * iface,REFIID riid,void ** obj)2494c2c66affSColin Finck static HRESULT WINAPI VBSAXErrorHandler_QueryInterface(IVBSAXErrorHandler *iface, REFIID riid, void **obj)
2495c2c66affSColin Finck {
2496c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2497c2c66affSColin Finck     return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
2498c2c66affSColin Finck }
2499c2c66affSColin Finck 
VBSAXErrorHandler_AddRef(IVBSAXErrorHandler * iface)2500c2c66affSColin Finck static ULONG WINAPI VBSAXErrorHandler_AddRef(IVBSAXErrorHandler *iface)
2501c2c66affSColin Finck {
2502c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2503c2c66affSColin Finck     return IMXWriter_AddRef(&This->IMXWriter_iface);
2504c2c66affSColin Finck }
2505c2c66affSColin Finck 
VBSAXErrorHandler_Release(IVBSAXErrorHandler * iface)2506c2c66affSColin Finck static ULONG WINAPI VBSAXErrorHandler_Release(IVBSAXErrorHandler *iface)
2507c2c66affSColin Finck {
2508c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2509c2c66affSColin Finck     return IMXWriter_Release(&This->IMXWriter_iface);
2510c2c66affSColin Finck }
2511c2c66affSColin Finck 
VBSAXErrorHandler_GetTypeInfoCount(IVBSAXErrorHandler * iface,UINT * pctinfo)2512c2c66affSColin Finck static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfoCount(IVBSAXErrorHandler *iface, UINT* pctinfo)
2513c2c66affSColin Finck {
2514c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2515c2c66affSColin Finck     return IMXWriter_GetTypeInfoCount(&This->IMXWriter_iface, pctinfo);
2516c2c66affSColin Finck }
2517c2c66affSColin Finck 
VBSAXErrorHandler_GetTypeInfo(IVBSAXErrorHandler * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)2518c2c66affSColin Finck static HRESULT WINAPI VBSAXErrorHandler_GetTypeInfo(IVBSAXErrorHandler *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2519c2c66affSColin Finck {
2520c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2521c2c66affSColin Finck     return IMXWriter_GetTypeInfo(&This->IMXWriter_iface, iTInfo, lcid, ppTInfo);
2522c2c66affSColin Finck }
2523c2c66affSColin Finck 
VBSAXErrorHandler_GetIDsOfNames(IVBSAXErrorHandler * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)2524c2c66affSColin Finck static HRESULT WINAPI VBSAXErrorHandler_GetIDsOfNames(IVBSAXErrorHandler *iface, REFIID riid, LPOLESTR* rgszNames,
2525c2c66affSColin Finck     UINT cNames, LCID lcid, DISPID* rgDispId )
2526c2c66affSColin Finck {
2527c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2528c2c66affSColin Finck     return IMXWriter_GetIDsOfNames(&This->IMXWriter_iface, riid, rgszNames, cNames, lcid, rgDispId);
2529c2c66affSColin Finck }
2530c2c66affSColin Finck 
VBSAXErrorHandler_Invoke(IVBSAXErrorHandler * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)2531c2c66affSColin Finck static HRESULT WINAPI VBSAXErrorHandler_Invoke(IVBSAXErrorHandler *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
2532c2c66affSColin Finck     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr )
2533c2c66affSColin Finck {
2534c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2535c2c66affSColin Finck     return IMXWriter_Invoke(&This->IMXWriter_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult,
2536c2c66affSColin Finck         pExcepInfo, puArgErr);
2537c2c66affSColin Finck }
2538c2c66affSColin Finck 
VBSAXErrorHandler_error(IVBSAXErrorHandler * iface,IVBSAXLocator * locator,BSTR * message,LONG code)2539c2c66affSColin Finck static HRESULT WINAPI VBSAXErrorHandler_error(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2540c2c66affSColin Finck {
2541c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2542c2c66affSColin Finck     FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2543c2c66affSColin Finck     return E_NOTIMPL;
2544c2c66affSColin Finck }
2545c2c66affSColin Finck 
VBSAXErrorHandler_fatalError(IVBSAXErrorHandler * iface,IVBSAXLocator * locator,BSTR * message,LONG code)2546c2c66affSColin Finck static HRESULT WINAPI VBSAXErrorHandler_fatalError(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2547c2c66affSColin Finck {
2548c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2549c2c66affSColin Finck     FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2550c2c66affSColin Finck     return E_NOTIMPL;
2551c2c66affSColin Finck }
2552c2c66affSColin Finck 
VBSAXErrorHandler_ignorableWarning(IVBSAXErrorHandler * iface,IVBSAXLocator * locator,BSTR * message,LONG code)2553c2c66affSColin Finck static HRESULT WINAPI VBSAXErrorHandler_ignorableWarning(IVBSAXErrorHandler *iface, IVBSAXLocator *locator, BSTR *message, LONG code)
2554c2c66affSColin Finck {
2555c2c66affSColin Finck     mxwriter *This = impl_from_IVBSAXErrorHandler( iface );
2556c2c66affSColin Finck     FIXME("(%p)->(%p %p %x): stub\n", This, locator, message, code);
2557c2c66affSColin Finck     return E_NOTIMPL;
2558c2c66affSColin Finck }
2559c2c66affSColin Finck 
2560c2c66affSColin Finck static const IVBSAXErrorHandlerVtbl VBSAXErrorHandlerVtbl = {
2561c2c66affSColin Finck     VBSAXErrorHandler_QueryInterface,
2562c2c66affSColin Finck     VBSAXErrorHandler_AddRef,
2563c2c66affSColin Finck     VBSAXErrorHandler_Release,
2564c2c66affSColin Finck     VBSAXErrorHandler_GetTypeInfoCount,
2565c2c66affSColin Finck     VBSAXErrorHandler_GetTypeInfo,
2566c2c66affSColin Finck     VBSAXErrorHandler_GetIDsOfNames,
2567c2c66affSColin Finck     VBSAXErrorHandler_Invoke,
2568c2c66affSColin Finck     VBSAXErrorHandler_error,
2569c2c66affSColin Finck     VBSAXErrorHandler_fatalError,
2570c2c66affSColin Finck     VBSAXErrorHandler_ignorableWarning
2571c2c66affSColin Finck };
2572c2c66affSColin Finck 
2573c2c66affSColin Finck static const tid_t mxwriter_iface_tids[] = {
2574c2c66affSColin Finck     IMXWriter_tid,
2575c2c66affSColin Finck     0
2576c2c66affSColin Finck };
2577c2c66affSColin Finck 
2578c2c66affSColin Finck static dispex_static_data_t mxwriter_dispex = {
2579c2c66affSColin Finck     NULL,
2580c2c66affSColin Finck     IMXWriter_tid,
2581c2c66affSColin Finck     NULL,
2582c2c66affSColin Finck     mxwriter_iface_tids
2583c2c66affSColin Finck };
2584c2c66affSColin Finck 
MXWriter_create(MSXML_VERSION version,void ** ppObj)2585c2c66affSColin Finck HRESULT MXWriter_create(MSXML_VERSION version, void **ppObj)
2586c2c66affSColin Finck {
2587c2c66affSColin Finck     static const WCHAR version10W[] = {'1','.','0',0};
2588c2c66affSColin Finck     mxwriter *This;
2589c2c66affSColin Finck     HRESULT hr;
2590c2c66affSColin Finck 
2591c2c66affSColin Finck     TRACE("(%p)\n", ppObj);
2592c2c66affSColin Finck 
2593c2c66affSColin Finck     This = heap_alloc( sizeof (*This) );
2594c2c66affSColin Finck     if(!This)
2595c2c66affSColin Finck         return E_OUTOFMEMORY;
2596c2c66affSColin Finck 
2597c2c66affSColin Finck     This->IMXWriter_iface.lpVtbl = &MXWriterVtbl;
2598c2c66affSColin Finck     This->ISAXContentHandler_iface.lpVtbl = &SAXContentHandlerVtbl;
2599c2c66affSColin Finck     This->ISAXLexicalHandler_iface.lpVtbl = &SAXLexicalHandlerVtbl;
2600c2c66affSColin Finck     This->ISAXDeclHandler_iface.lpVtbl = &SAXDeclHandlerVtbl;
2601c2c66affSColin Finck     This->ISAXDTDHandler_iface.lpVtbl = &SAXDTDHandlerVtbl;
2602c2c66affSColin Finck     This->ISAXErrorHandler_iface.lpVtbl = &SAXErrorHandlerVtbl;
2603c2c66affSColin Finck     This->IVBSAXDeclHandler_iface.lpVtbl = &VBSAXDeclHandlerVtbl;
2604c2c66affSColin Finck     This->IVBSAXLexicalHandler_iface.lpVtbl = &VBSAXLexicalHandlerVtbl;
2605c2c66affSColin Finck     This->IVBSAXContentHandler_iface.lpVtbl = &VBSAXContentHandlerVtbl;
2606c2c66affSColin Finck     This->IVBSAXDTDHandler_iface.lpVtbl = &VBSAXDTDHandlerVtbl;
2607c2c66affSColin Finck     This->IVBSAXErrorHandler_iface.lpVtbl = &VBSAXErrorHandlerVtbl;
2608c2c66affSColin Finck     This->ref = 1;
2609c2c66affSColin Finck     This->class_version = version;
2610c2c66affSColin Finck 
2611c2c66affSColin Finck     This->props[MXWriter_BOM] = VARIANT_TRUE;
2612c2c66affSColin Finck     This->props[MXWriter_DisableEscaping] = VARIANT_FALSE;
2613c2c66affSColin Finck     This->props[MXWriter_Indent] = VARIANT_FALSE;
2614c2c66affSColin Finck     This->props[MXWriter_OmitXmlDecl] = VARIANT_FALSE;
2615c2c66affSColin Finck     This->props[MXWriter_Standalone] = VARIANT_FALSE;
2616c2c66affSColin Finck     This->prop_changed = FALSE;
2617c2c66affSColin Finck     This->encoding = SysAllocString(utf16W);
2618c2c66affSColin Finck     This->version  = SysAllocString(version10W);
2619c2c66affSColin Finck     This->xml_enc  = XmlEncoding_UTF16;
2620c2c66affSColin Finck 
2621c2c66affSColin Finck     This->element = NULL;
2622c2c66affSColin Finck     This->cdata = FALSE;
2623c2c66affSColin Finck     This->indent = 0;
2624c2c66affSColin Finck     This->text = FALSE;
2625c2c66affSColin Finck     This->newline = FALSE;
2626c2c66affSColin Finck 
2627c2c66affSColin Finck     This->dest = NULL;
2628c2c66affSColin Finck 
2629c2c66affSColin Finck     hr = init_output_buffer(This->xml_enc, &This->buffer);
2630c2c66affSColin Finck     if (hr != S_OK) {
2631c2c66affSColin Finck         SysFreeString(This->encoding);
2632c2c66affSColin Finck         SysFreeString(This->version);
2633c2c66affSColin Finck         heap_free(This);
2634c2c66affSColin Finck         return hr;
2635c2c66affSColin Finck     }
2636c2c66affSColin Finck 
2637c2c66affSColin Finck     init_dispex(&This->dispex, (IUnknown*)&This->IMXWriter_iface, &mxwriter_dispex);
2638c2c66affSColin Finck 
2639c2c66affSColin Finck     *ppObj = &This->IMXWriter_iface;
2640c2c66affSColin Finck 
2641c2c66affSColin Finck     TRACE("returning iface %p\n", *ppObj);
2642c2c66affSColin Finck 
2643c2c66affSColin Finck     return S_OK;
2644c2c66affSColin Finck }
2645c2c66affSColin Finck 
MXAttributes_QueryInterface(IMXAttributes * iface,REFIID riid,void ** ppObj)2646c2c66affSColin Finck static HRESULT WINAPI MXAttributes_QueryInterface(IMXAttributes *iface, REFIID riid, void **ppObj)
2647c2c66affSColin Finck {
2648c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2649c2c66affSColin Finck 
2650c2c66affSColin Finck     TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppObj);
2651c2c66affSColin Finck 
2652c2c66affSColin Finck     *ppObj = NULL;
2653c2c66affSColin Finck 
2654c2c66affSColin Finck     if ( IsEqualGUID( riid, &IID_IUnknown )  ||
2655c2c66affSColin Finck          IsEqualGUID( riid, &IID_IDispatch ) ||
2656c2c66affSColin Finck          IsEqualGUID( riid, &IID_IMXAttributes ))
2657c2c66affSColin Finck     {
2658c2c66affSColin Finck         *ppObj = iface;
2659c2c66affSColin Finck     }
2660c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
2661c2c66affSColin Finck     {
2662c2c66affSColin Finck         *ppObj = &This->ISAXAttributes_iface;
2663c2c66affSColin Finck     }
2664c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
2665c2c66affSColin Finck     {
2666c2c66affSColin Finck         *ppObj = &This->IVBSAXAttributes_iface;
2667c2c66affSColin Finck     }
2668c2c66affSColin Finck     else if (dispex_query_interface(&This->dispex, riid, ppObj))
2669c2c66affSColin Finck     {
2670c2c66affSColin Finck         return *ppObj ? S_OK : E_NOINTERFACE;
2671c2c66affSColin Finck     }
2672c2c66affSColin Finck     else
2673c2c66affSColin Finck     {
2674c2c66affSColin Finck         FIXME("interface %s not implemented\n", debugstr_guid(riid));
2675c2c66affSColin Finck         return E_NOINTERFACE;
2676c2c66affSColin Finck     }
2677c2c66affSColin Finck 
2678c2c66affSColin Finck     IMXAttributes_AddRef( iface );
2679c2c66affSColin Finck 
2680c2c66affSColin Finck     return S_OK;
2681c2c66affSColin Finck }
2682c2c66affSColin Finck 
MXAttributes_AddRef(IMXAttributes * iface)2683c2c66affSColin Finck static ULONG WINAPI MXAttributes_AddRef(IMXAttributes *iface)
2684c2c66affSColin Finck {
2685c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2686c2c66affSColin Finck     ULONG ref = InterlockedIncrement( &This->ref );
2687c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, ref );
2688c2c66affSColin Finck     return ref;
2689c2c66affSColin Finck }
2690c2c66affSColin Finck 
MXAttributes_Release(IMXAttributes * iface)2691c2c66affSColin Finck static ULONG WINAPI MXAttributes_Release(IMXAttributes *iface)
2692c2c66affSColin Finck {
2693c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2694c2c66affSColin Finck     LONG ref = InterlockedDecrement( &This->ref );
2695c2c66affSColin Finck 
2696c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, ref);
2697c2c66affSColin Finck 
2698c2c66affSColin Finck     if (ref == 0)
2699c2c66affSColin Finck     {
2700c2c66affSColin Finck         int i;
2701c2c66affSColin Finck 
2702c2c66affSColin Finck         for (i = 0; i < This->length; i++)
2703c2c66affSColin Finck         {
2704c2c66affSColin Finck             SysFreeString(This->attr[i].qname);
2705c2c66affSColin Finck             SysFreeString(This->attr[i].local);
2706c2c66affSColin Finck             SysFreeString(This->attr[i].uri);
2707c2c66affSColin Finck             SysFreeString(This->attr[i].type);
2708c2c66affSColin Finck             SysFreeString(This->attr[i].value);
2709c2c66affSColin Finck         }
2710c2c66affSColin Finck 
2711c2c66affSColin Finck         heap_free(This->attr);
2712c2c66affSColin Finck         heap_free(This);
2713c2c66affSColin Finck     }
2714c2c66affSColin Finck 
2715c2c66affSColin Finck     return ref;
2716c2c66affSColin Finck }
2717c2c66affSColin Finck 
MXAttributes_GetTypeInfoCount(IMXAttributes * iface,UINT * pctinfo)2718c2c66affSColin Finck static HRESULT WINAPI MXAttributes_GetTypeInfoCount(IMXAttributes *iface, UINT* pctinfo)
2719c2c66affSColin Finck {
2720c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2721c2c66affSColin Finck     return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2722c2c66affSColin Finck }
2723c2c66affSColin Finck 
MXAttributes_GetTypeInfo(IMXAttributes * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)2724c2c66affSColin Finck static HRESULT WINAPI MXAttributes_GetTypeInfo(IMXAttributes *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
2725c2c66affSColin Finck {
2726c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2727c2c66affSColin Finck     return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2728c2c66affSColin Finck }
2729c2c66affSColin Finck 
MXAttributes_GetIDsOfNames(IMXAttributes * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)2730c2c66affSColin Finck static HRESULT WINAPI MXAttributes_GetIDsOfNames(
2731c2c66affSColin Finck     IMXAttributes *iface,
2732c2c66affSColin Finck     REFIID riid,
2733c2c66affSColin Finck     LPOLESTR* rgszNames,
2734c2c66affSColin Finck     UINT cNames,
2735c2c66affSColin Finck     LCID lcid,
2736c2c66affSColin Finck     DISPID* rgDispId)
2737c2c66affSColin Finck {
2738c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2739c2c66affSColin Finck     return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2740c2c66affSColin Finck         riid, rgszNames, cNames, lcid, rgDispId);
2741c2c66affSColin Finck }
2742c2c66affSColin Finck 
MXAttributes_Invoke(IMXAttributes * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)2743c2c66affSColin Finck static HRESULT WINAPI MXAttributes_Invoke(
2744c2c66affSColin Finck     IMXAttributes *iface,
2745c2c66affSColin Finck     DISPID dispIdMember,
2746c2c66affSColin Finck     REFIID riid,
2747c2c66affSColin Finck     LCID lcid,
2748c2c66affSColin Finck     WORD wFlags,
2749c2c66affSColin Finck     DISPPARAMS* pDispParams,
2750c2c66affSColin Finck     VARIANT* pVarResult,
2751c2c66affSColin Finck     EXCEPINFO* pExcepInfo,
2752c2c66affSColin Finck     UINT* puArgErr)
2753c2c66affSColin Finck {
2754c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2755c2c66affSColin Finck     return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
2756c2c66affSColin Finck         dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2757c2c66affSColin Finck }
2758c2c66affSColin Finck 
MXAttributes_addAttribute(IMXAttributes * iface,BSTR uri,BSTR localName,BSTR QName,BSTR type,BSTR value)2759c2c66affSColin Finck static HRESULT WINAPI MXAttributes_addAttribute(IMXAttributes *iface,
2760c2c66affSColin Finck     BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2761c2c66affSColin Finck {
2762c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2763c2c66affSColin Finck     mxattribute *attr;
2764c2c66affSColin Finck     HRESULT hr;
2765c2c66affSColin Finck 
2766c2c66affSColin Finck     TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(uri), debugstr_w(localName),
2767c2c66affSColin Finck         debugstr_w(QName), debugstr_w(type), debugstr_w(value));
2768c2c66affSColin Finck 
2769c2c66affSColin Finck     if ((!uri || !localName || !QName || !type || !value) && This->class_version != MSXML6)
2770c2c66affSColin Finck         return E_INVALIDARG;
2771c2c66affSColin Finck 
2772c2c66affSColin Finck     /* ensure array is large enough */
2773c2c66affSColin Finck     hr = mxattributes_grow(This);
2774c2c66affSColin Finck     if (hr != S_OK) return hr;
2775c2c66affSColin Finck 
2776c2c66affSColin Finck     attr = &This->attr[This->length];
2777c2c66affSColin Finck 
2778c2c66affSColin Finck     attr->qname = SysAllocString(QName);
2779c2c66affSColin Finck     attr->local = SysAllocString(localName);
2780c2c66affSColin Finck     attr->uri   = SysAllocString(uri);
2781c2c66affSColin Finck     attr->type  = SysAllocString(type ? type : emptyW);
2782c2c66affSColin Finck     attr->value = SysAllocString(value);
2783c2c66affSColin Finck     This->length++;
2784c2c66affSColin Finck 
2785c2c66affSColin Finck     return S_OK;
2786c2c66affSColin Finck }
2787c2c66affSColin Finck 
MXAttributes_addAttributeFromIndex(IMXAttributes * iface,VARIANT atts,int index)2788c2c66affSColin Finck static HRESULT WINAPI MXAttributes_addAttributeFromIndex(IMXAttributes *iface,
2789c2c66affSColin Finck     VARIANT atts, int index)
2790c2c66affSColin Finck {
2791c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2792c2c66affSColin Finck     FIXME("(%p)->(%s %d): stub\n", This, debugstr_variant(&atts), index);
2793c2c66affSColin Finck     return E_NOTIMPL;
2794c2c66affSColin Finck }
2795c2c66affSColin Finck 
MXAttributes_clear(IMXAttributes * iface)2796c2c66affSColin Finck static HRESULT WINAPI MXAttributes_clear(IMXAttributes *iface)
2797c2c66affSColin Finck {
2798c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2799c2c66affSColin Finck     int i;
2800c2c66affSColin Finck 
2801c2c66affSColin Finck     TRACE("(%p)\n", This);
2802c2c66affSColin Finck 
2803c2c66affSColin Finck     for (i = 0; i < This->length; i++)
2804c2c66affSColin Finck     {
2805c2c66affSColin Finck         SysFreeString(This->attr[i].qname);
2806c2c66affSColin Finck         SysFreeString(This->attr[i].local);
2807c2c66affSColin Finck         SysFreeString(This->attr[i].uri);
2808c2c66affSColin Finck         SysFreeString(This->attr[i].type);
2809c2c66affSColin Finck         SysFreeString(This->attr[i].value);
2810c2c66affSColin Finck         memset(&This->attr[i], 0, sizeof(mxattribute));
2811c2c66affSColin Finck     }
2812c2c66affSColin Finck 
2813c2c66affSColin Finck     This->length = 0;
2814c2c66affSColin Finck 
2815c2c66affSColin Finck     return S_OK;
2816c2c66affSColin Finck }
2817c2c66affSColin Finck 
get_attribute_byindex(mxattributes * attrs,int index)2818c2c66affSColin Finck static mxattribute *get_attribute_byindex(mxattributes *attrs, int index)
2819c2c66affSColin Finck {
2820c2c66affSColin Finck     if (index < 0 || index >= attrs->length) return NULL;
2821c2c66affSColin Finck     return &attrs->attr[index];
2822c2c66affSColin Finck }
2823c2c66affSColin Finck 
MXAttributes_removeAttribute(IMXAttributes * iface,int index)2824c2c66affSColin Finck static HRESULT WINAPI MXAttributes_removeAttribute(IMXAttributes *iface, int index)
2825c2c66affSColin Finck {
2826c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2827c2c66affSColin Finck     mxattribute *dst;
2828c2c66affSColin Finck 
2829c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, index);
2830c2c66affSColin Finck 
2831c2c66affSColin Finck     if (!(dst = get_attribute_byindex(This, index))) return E_INVALIDARG;
2832c2c66affSColin Finck 
2833c2c66affSColin Finck     /* no need to remove last attribute, just make it inaccessible */
2834c2c66affSColin Finck     if (index + 1 == This->length)
2835c2c66affSColin Finck     {
2836c2c66affSColin Finck         This->length--;
2837c2c66affSColin Finck         return S_OK;
2838c2c66affSColin Finck     }
2839c2c66affSColin Finck 
2840c2c66affSColin Finck     memmove(dst, dst + 1, (This->length-index-1)*sizeof(*dst));
2841c2c66affSColin Finck     This->length--;
2842c2c66affSColin Finck 
2843c2c66affSColin Finck     return S_OK;
2844c2c66affSColin Finck }
2845c2c66affSColin Finck 
MXAttributes_setAttribute(IMXAttributes * iface,int index,BSTR uri,BSTR localName,BSTR QName,BSTR type,BSTR value)2846c2c66affSColin Finck static HRESULT WINAPI MXAttributes_setAttribute(IMXAttributes *iface, int index,
2847c2c66affSColin Finck     BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
2848c2c66affSColin Finck {
2849c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2850c2c66affSColin Finck     FIXME("(%p)->(%d %s %s %s %s %s): stub\n", This, index, debugstr_w(uri),
2851c2c66affSColin Finck         debugstr_w(localName), debugstr_w(QName), debugstr_w(type), debugstr_w(value));
2852c2c66affSColin Finck     return E_NOTIMPL;
2853c2c66affSColin Finck }
2854c2c66affSColin Finck 
MXAttributes_setAttributes(IMXAttributes * iface,VARIANT atts)2855c2c66affSColin Finck static HRESULT WINAPI MXAttributes_setAttributes(IMXAttributes *iface, VARIANT atts)
2856c2c66affSColin Finck {
2857c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2858c2c66affSColin Finck     FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&atts));
2859c2c66affSColin Finck     return E_NOTIMPL;
2860c2c66affSColin Finck }
2861c2c66affSColin Finck 
MXAttributes_setLocalName(IMXAttributes * iface,int index,BSTR localName)2862c2c66affSColin Finck static HRESULT WINAPI MXAttributes_setLocalName(IMXAttributes *iface, int index,
2863c2c66affSColin Finck     BSTR localName)
2864c2c66affSColin Finck {
2865c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2866c2c66affSColin Finck     mxattribute *attr;
2867c2c66affSColin Finck 
2868c2c66affSColin Finck     TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(localName));
2869c2c66affSColin Finck 
2870c2c66affSColin Finck     if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2871c2c66affSColin Finck 
2872c2c66affSColin Finck     SysFreeString(attr->local);
2873c2c66affSColin Finck     attr->local = SysAllocString(localName);
2874c2c66affSColin Finck 
2875c2c66affSColin Finck     return S_OK;
2876c2c66affSColin Finck }
2877c2c66affSColin Finck 
MXAttributes_setQName(IMXAttributes * iface,int index,BSTR QName)2878c2c66affSColin Finck static HRESULT WINAPI MXAttributes_setQName(IMXAttributes *iface, int index, BSTR QName)
2879c2c66affSColin Finck {
2880c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2881c2c66affSColin Finck     mxattribute *attr;
2882c2c66affSColin Finck 
2883c2c66affSColin Finck     TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(QName));
2884c2c66affSColin Finck 
2885c2c66affSColin Finck     if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2886c2c66affSColin Finck 
2887c2c66affSColin Finck     SysFreeString(attr->qname);
2888c2c66affSColin Finck     attr->qname = SysAllocString(QName);
2889c2c66affSColin Finck 
2890c2c66affSColin Finck     return S_OK;
2891c2c66affSColin Finck }
2892c2c66affSColin Finck 
MXAttributes_setURI(IMXAttributes * iface,int index,BSTR uri)2893c2c66affSColin Finck static HRESULT WINAPI MXAttributes_setURI(IMXAttributes *iface, int index, BSTR uri)
2894c2c66affSColin Finck {
2895c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2896c2c66affSColin Finck     mxattribute *attr;
2897c2c66affSColin Finck 
2898c2c66affSColin Finck     TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(uri));
2899c2c66affSColin Finck 
2900c2c66affSColin Finck     if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2901c2c66affSColin Finck 
2902c2c66affSColin Finck     SysFreeString(attr->uri);
2903c2c66affSColin Finck     attr->uri = SysAllocString(uri);
2904c2c66affSColin Finck 
2905c2c66affSColin Finck     return S_OK;
2906c2c66affSColin Finck }
2907c2c66affSColin Finck 
MXAttributes_setValue(IMXAttributes * iface,int index,BSTR value)2908c2c66affSColin Finck static HRESULT WINAPI MXAttributes_setValue(IMXAttributes *iface, int index, BSTR value)
2909c2c66affSColin Finck {
2910c2c66affSColin Finck     mxattributes *This = impl_from_IMXAttributes( iface );
2911c2c66affSColin Finck     mxattribute *attr;
2912c2c66affSColin Finck 
2913c2c66affSColin Finck     TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(value));
2914c2c66affSColin Finck 
2915c2c66affSColin Finck     if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
2916c2c66affSColin Finck 
2917c2c66affSColin Finck     SysFreeString(attr->value);
2918c2c66affSColin Finck     attr->value = SysAllocString(value);
2919c2c66affSColin Finck 
2920c2c66affSColin Finck     return S_OK;
2921c2c66affSColin Finck }
2922c2c66affSColin Finck 
2923c2c66affSColin Finck static const IMXAttributesVtbl MXAttributesVtbl = {
2924c2c66affSColin Finck     MXAttributes_QueryInterface,
2925c2c66affSColin Finck     MXAttributes_AddRef,
2926c2c66affSColin Finck     MXAttributes_Release,
2927c2c66affSColin Finck     MXAttributes_GetTypeInfoCount,
2928c2c66affSColin Finck     MXAttributes_GetTypeInfo,
2929c2c66affSColin Finck     MXAttributes_GetIDsOfNames,
2930c2c66affSColin Finck     MXAttributes_Invoke,
2931c2c66affSColin Finck     MXAttributes_addAttribute,
2932c2c66affSColin Finck     MXAttributes_addAttributeFromIndex,
2933c2c66affSColin Finck     MXAttributes_clear,
2934c2c66affSColin Finck     MXAttributes_removeAttribute,
2935c2c66affSColin Finck     MXAttributes_setAttribute,
2936c2c66affSColin Finck     MXAttributes_setAttributes,
2937c2c66affSColin Finck     MXAttributes_setLocalName,
2938c2c66affSColin Finck     MXAttributes_setQName,
2939c2c66affSColin Finck     MXAttributes_setURI,
2940c2c66affSColin Finck     MXAttributes_setValue
2941c2c66affSColin Finck };
2942c2c66affSColin Finck 
SAXAttributes_QueryInterface(ISAXAttributes * iface,REFIID riid,void ** ppObj)2943c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_QueryInterface(ISAXAttributes *iface, REFIID riid, void **ppObj)
2944c2c66affSColin Finck {
2945c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
2946c2c66affSColin Finck     return IMXAttributes_QueryInterface(&This->IMXAttributes_iface, riid, ppObj);
2947c2c66affSColin Finck }
2948c2c66affSColin Finck 
SAXAttributes_AddRef(ISAXAttributes * iface)2949c2c66affSColin Finck static ULONG WINAPI SAXAttributes_AddRef(ISAXAttributes *iface)
2950c2c66affSColin Finck {
2951c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
2952c2c66affSColin Finck     return IMXAttributes_AddRef(&This->IMXAttributes_iface);
2953c2c66affSColin Finck }
2954c2c66affSColin Finck 
SAXAttributes_Release(ISAXAttributes * iface)2955c2c66affSColin Finck static ULONG WINAPI SAXAttributes_Release(ISAXAttributes *iface)
2956c2c66affSColin Finck {
2957c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
2958c2c66affSColin Finck     return IMXAttributes_Release(&This->IMXAttributes_iface);
2959c2c66affSColin Finck }
2960c2c66affSColin Finck 
SAXAttributes_getLength(ISAXAttributes * iface,int * length)2961c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getLength(ISAXAttributes *iface, int *length)
2962c2c66affSColin Finck {
2963c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
2964c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, length);
2965c2c66affSColin Finck 
2966c2c66affSColin Finck     if (!length && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
2967c2c66affSColin Finck        return E_POINTER;
2968c2c66affSColin Finck 
2969c2c66affSColin Finck     *length = This->length;
2970c2c66affSColin Finck 
2971c2c66affSColin Finck     return S_OK;
2972c2c66affSColin Finck }
2973c2c66affSColin Finck 
SAXAttributes_getURI(ISAXAttributes * iface,int index,const WCHAR ** uri,int * len)2974c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getURI(ISAXAttributes *iface, int index, const WCHAR **uri,
2975c2c66affSColin Finck     int *len)
2976c2c66affSColin Finck {
2977c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
2978c2c66affSColin Finck 
2979c2c66affSColin Finck     TRACE("(%p)->(%d %p %p)\n", This, index, uri, len);
2980c2c66affSColin Finck 
2981c2c66affSColin Finck     if (index >= This->length || index < 0) return E_INVALIDARG;
2982c2c66affSColin Finck     if (!uri || !len) return E_POINTER;
2983c2c66affSColin Finck 
2984c2c66affSColin Finck     *len = SysStringLen(This->attr[index].uri);
2985c2c66affSColin Finck     *uri = This->attr[index].uri;
2986c2c66affSColin Finck 
2987c2c66affSColin Finck     return S_OK;
2988c2c66affSColin Finck }
2989c2c66affSColin Finck 
SAXAttributes_getLocalName(ISAXAttributes * iface,int index,const WCHAR ** name,int * len)2990c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getLocalName(ISAXAttributes *iface, int index, const WCHAR **name,
2991c2c66affSColin Finck     int *len)
2992c2c66affSColin Finck {
2993c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
2994c2c66affSColin Finck 
2995c2c66affSColin Finck     TRACE("(%p)->(%d %p %p)\n", This, index, name, len);
2996c2c66affSColin Finck 
2997c2c66affSColin Finck     if (index >= This->length || index < 0) return E_INVALIDARG;
2998c2c66affSColin Finck     if (!name || !len) return E_POINTER;
2999c2c66affSColin Finck 
3000c2c66affSColin Finck     *len = SysStringLen(This->attr[index].local);
3001c2c66affSColin Finck     *name = This->attr[index].local;
3002c2c66affSColin Finck 
3003c2c66affSColin Finck     return S_OK;
3004c2c66affSColin Finck }
3005c2c66affSColin Finck 
SAXAttributes_getQName(ISAXAttributes * iface,int index,const WCHAR ** qname,int * length)3006c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getQName(ISAXAttributes *iface, int index, const WCHAR **qname, int *length)
3007c2c66affSColin Finck {
3008c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
3009c2c66affSColin Finck 
3010c2c66affSColin Finck     TRACE("(%p)->(%d %p %p)\n", This, index, qname, length);
3011c2c66affSColin Finck 
3012c2c66affSColin Finck     if (index >= This->length) return E_INVALIDARG;
3013c2c66affSColin Finck     if (!qname || !length) return E_POINTER;
3014c2c66affSColin Finck 
3015c2c66affSColin Finck     *qname = This->attr[index].qname;
3016c2c66affSColin Finck     *length = SysStringLen(This->attr[index].qname);
3017c2c66affSColin Finck 
3018c2c66affSColin Finck     return S_OK;
3019c2c66affSColin Finck }
3020c2c66affSColin Finck 
SAXAttributes_getName(ISAXAttributes * iface,int index,const WCHAR ** uri,int * uri_len,const WCHAR ** local,int * local_len,const WCHAR ** qname,int * qname_len)3021c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getName(ISAXAttributes *iface, int index, const WCHAR **uri, int *uri_len,
3022c2c66affSColin Finck     const WCHAR **local, int *local_len, const WCHAR **qname, int *qname_len)
3023c2c66affSColin Finck {
3024c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
3025c2c66affSColin Finck 
3026c2c66affSColin Finck     TRACE("(%p)->(%d %p %p %p %p %p %p)\n", This, index, uri, uri_len, local, local_len, qname, qname_len);
3027c2c66affSColin Finck 
3028c2c66affSColin Finck     if (index >= This->length || index < 0)
3029c2c66affSColin Finck         return E_INVALIDARG;
3030c2c66affSColin Finck 
3031c2c66affSColin Finck     if (!uri || !uri_len || !local || !local_len || !qname || !qname_len)
3032c2c66affSColin Finck         return E_POINTER;
3033c2c66affSColin Finck 
3034c2c66affSColin Finck     *uri_len = SysStringLen(This->attr[index].uri);
3035c2c66affSColin Finck     *uri = This->attr[index].uri;
3036c2c66affSColin Finck 
3037c2c66affSColin Finck     *local_len = SysStringLen(This->attr[index].local);
3038c2c66affSColin Finck     *local = This->attr[index].local;
3039c2c66affSColin Finck 
3040c2c66affSColin Finck     *qname_len = SysStringLen(This->attr[index].qname);
3041c2c66affSColin Finck     *qname = This->attr[index].qname;
3042c2c66affSColin Finck 
3043c2c66affSColin Finck     TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*local), debugstr_w(*qname));
3044c2c66affSColin Finck 
3045c2c66affSColin Finck     return S_OK;
3046c2c66affSColin Finck }
3047c2c66affSColin Finck 
SAXAttributes_getIndexFromName(ISAXAttributes * iface,const WCHAR * uri,int uri_len,const WCHAR * name,int len,int * index)3048c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getIndexFromName(ISAXAttributes *iface, const WCHAR *uri, int uri_len,
3049c2c66affSColin Finck     const WCHAR *name, int len, int *index)
3050c2c66affSColin Finck {
3051c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
3052c2c66affSColin Finck     int i;
3053c2c66affSColin Finck 
3054c2c66affSColin Finck     TRACE("(%p)->(%s:%d %s:%d %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
3055c2c66affSColin Finck         debugstr_wn(name, len), len, index);
3056c2c66affSColin Finck 
3057c2c66affSColin Finck     if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3058c2c66affSColin Finck         return E_POINTER;
3059c2c66affSColin Finck 
3060c2c66affSColin Finck     if (!uri || !name || !index) return E_INVALIDARG;
3061c2c66affSColin Finck 
3062c2c66affSColin Finck     for (i = 0; i < This->length; i++)
3063c2c66affSColin Finck     {
3064c2c66affSColin Finck         if (uri_len != SysStringLen(This->attr[i].uri)) continue;
3065c2c66affSColin Finck         if (strncmpW(uri, This->attr[i].uri, uri_len)) continue;
3066c2c66affSColin Finck 
3067c2c66affSColin Finck         if (len != SysStringLen(This->attr[i].local)) continue;
3068c2c66affSColin Finck         if (strncmpW(name, This->attr[i].local, len)) continue;
3069c2c66affSColin Finck 
3070c2c66affSColin Finck         *index = i;
3071c2c66affSColin Finck         return S_OK;
3072c2c66affSColin Finck     }
3073c2c66affSColin Finck 
3074c2c66affSColin Finck     return E_INVALIDARG;
3075c2c66affSColin Finck }
3076c2c66affSColin Finck 
SAXAttributes_getIndexFromQName(ISAXAttributes * iface,const WCHAR * qname,int len,int * index)3077c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getIndexFromQName(ISAXAttributes *iface, const WCHAR *qname,
3078c2c66affSColin Finck     int len, int *index)
3079c2c66affSColin Finck {
3080c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
3081c2c66affSColin Finck     int i;
3082c2c66affSColin Finck 
3083c2c66affSColin Finck     TRACE("(%p)->(%s:%d %p)\n", This, debugstr_wn(qname, len), len, index);
3084c2c66affSColin Finck 
3085c2c66affSColin Finck     if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3086c2c66affSColin Finck         return E_POINTER;
3087c2c66affSColin Finck 
3088c2c66affSColin Finck     if (!qname || !index || !len) return E_INVALIDARG;
3089c2c66affSColin Finck 
3090c2c66affSColin Finck     for (i = 0; i < This->length; i++)
3091c2c66affSColin Finck     {
3092c2c66affSColin Finck         if (len != SysStringLen(This->attr[i].qname)) continue;
3093c2c66affSColin Finck         if (strncmpW(qname, This->attr[i].qname, len)) continue;
3094c2c66affSColin Finck 
3095c2c66affSColin Finck         *index = i;
3096c2c66affSColin Finck         return S_OK;
3097c2c66affSColin Finck     }
3098c2c66affSColin Finck 
3099c2c66affSColin Finck     return E_INVALIDARG;
3100c2c66affSColin Finck }
3101c2c66affSColin Finck 
SAXAttributes_getType(ISAXAttributes * iface,int index,const WCHAR ** type,int * len)3102c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getType(ISAXAttributes *iface, int index, const WCHAR **type,
3103c2c66affSColin Finck     int *len)
3104c2c66affSColin Finck {
3105c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
3106c2c66affSColin Finck 
3107c2c66affSColin Finck     TRACE("(%p)->(%d %p %p)\n", This, index, type, len);
3108c2c66affSColin Finck 
3109c2c66affSColin Finck     if (index >= This->length) return E_INVALIDARG;
3110c2c66affSColin Finck 
3111c2c66affSColin Finck     if ((!type || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3112c2c66affSColin Finck        return E_POINTER;
3113c2c66affSColin Finck 
3114c2c66affSColin Finck     *type = This->attr[index].type;
3115c2c66affSColin Finck     *len = SysStringLen(This->attr[index].type);
3116c2c66affSColin Finck 
3117c2c66affSColin Finck     return S_OK;
3118c2c66affSColin Finck }
3119c2c66affSColin Finck 
SAXAttributes_getTypeFromName(ISAXAttributes * iface,const WCHAR * pUri,int nUri,const WCHAR * pLocalName,int nLocalName,const WCHAR ** pType,int * nType)3120c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getTypeFromName(ISAXAttributes *iface, const WCHAR * pUri, int nUri,
3121c2c66affSColin Finck     const WCHAR * pLocalName, int nLocalName, const WCHAR ** pType, int * nType)
3122c2c66affSColin Finck {
3123c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
3124c2c66affSColin Finck     FIXME("(%p)->(%s:%d %s:%d %p %p): stub\n", This, debugstr_wn(pUri, nUri), nUri,
3125c2c66affSColin Finck         debugstr_wn(pLocalName, nLocalName), nLocalName, pType, nType);
3126c2c66affSColin Finck     return E_NOTIMPL;
3127c2c66affSColin Finck }
3128c2c66affSColin Finck 
SAXAttributes_getTypeFromQName(ISAXAttributes * iface,const WCHAR * pQName,int nQName,const WCHAR ** pType,int * nType)3129c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getTypeFromQName(ISAXAttributes *iface, const WCHAR * pQName,
3130c2c66affSColin Finck     int nQName, const WCHAR ** pType, int * nType)
3131c2c66affSColin Finck {
3132c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
3133c2c66affSColin Finck     FIXME("(%p)->(%s:%d %p %p): stub\n", This, debugstr_wn(pQName, nQName), nQName, pType, nType);
3134c2c66affSColin Finck     return E_NOTIMPL;
3135c2c66affSColin Finck }
3136c2c66affSColin Finck 
SAXAttributes_getValue(ISAXAttributes * iface,int index,const WCHAR ** value,int * len)3137c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getValue(ISAXAttributes *iface, int index, const WCHAR **value,
3138c2c66affSColin Finck     int *len)
3139c2c66affSColin Finck {
3140c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
3141c2c66affSColin Finck 
3142c2c66affSColin Finck     TRACE("(%p)->(%d %p %p)\n", This, index, value, len);
3143c2c66affSColin Finck 
3144c2c66affSColin Finck     if (index >= This->length) return E_INVALIDARG;
3145c2c66affSColin Finck 
3146c2c66affSColin Finck     if ((!value || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
3147c2c66affSColin Finck        return E_POINTER;
3148c2c66affSColin Finck 
3149c2c66affSColin Finck     *value = This->attr[index].value;
3150c2c66affSColin Finck     *len = SysStringLen(This->attr[index].value);
3151c2c66affSColin Finck 
3152c2c66affSColin Finck     return S_OK;
3153c2c66affSColin Finck }
3154c2c66affSColin Finck 
SAXAttributes_getValueFromName(ISAXAttributes * iface,const WCHAR * uri,int uri_len,const WCHAR * name,int name_len,const WCHAR ** value,int * value_len)3155c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getValueFromName(ISAXAttributes *iface, const WCHAR *uri,
3156c2c66affSColin Finck     int uri_len, const WCHAR *name, int name_len, const WCHAR **value, int *value_len)
3157c2c66affSColin Finck {
3158c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
3159c2c66affSColin Finck     HRESULT hr;
3160c2c66affSColin Finck     int index;
3161c2c66affSColin Finck 
3162c2c66affSColin Finck     TRACE("(%p)->(%s:%d %s:%d %p %p)\n", This, debugstr_wn(uri, uri_len), uri_len,
3163c2c66affSColin Finck         debugstr_wn(name, name_len), name_len, value, value_len);
3164c2c66affSColin Finck 
3165c2c66affSColin Finck     if (!uri || !name || !value || !value_len)
3166c2c66affSColin Finck         return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3167c2c66affSColin Finck 
3168c2c66affSColin Finck     hr = ISAXAttributes_getIndexFromName(iface, uri, uri_len, name, name_len, &index);
3169c2c66affSColin Finck     if (hr == S_OK)
3170c2c66affSColin Finck         hr = ISAXAttributes_getValue(iface, index, value, value_len);
3171c2c66affSColin Finck 
3172c2c66affSColin Finck     return hr;
3173c2c66affSColin Finck }
3174c2c66affSColin Finck 
SAXAttributes_getValueFromQName(ISAXAttributes * iface,const WCHAR * qname,int qname_len,const WCHAR ** value,int * value_len)3175c2c66affSColin Finck static HRESULT WINAPI SAXAttributes_getValueFromQName(ISAXAttributes *iface, const WCHAR *qname,
3176c2c66affSColin Finck     int qname_len, const WCHAR **value, int *value_len)
3177c2c66affSColin Finck {
3178c2c66affSColin Finck     mxattributes *This = impl_from_ISAXAttributes( iface );
3179c2c66affSColin Finck     HRESULT hr;
3180c2c66affSColin Finck     int index;
3181c2c66affSColin Finck 
3182c2c66affSColin Finck     TRACE("(%p)->(%s:%d %p %p)\n", This, debugstr_wn(qname, qname_len), qname_len, value, value_len);
3183c2c66affSColin Finck 
3184c2c66affSColin Finck     if (!qname || !value || !value_len)
3185c2c66affSColin Finck         return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;
3186c2c66affSColin Finck 
3187c2c66affSColin Finck     hr = ISAXAttributes_getIndexFromQName(iface, qname, qname_len, &index);
3188c2c66affSColin Finck     if (hr == S_OK)
3189c2c66affSColin Finck         hr = ISAXAttributes_getValue(iface, index, value, value_len);
3190c2c66affSColin Finck 
3191c2c66affSColin Finck     return hr;
3192c2c66affSColin Finck }
3193c2c66affSColin Finck 
3194c2c66affSColin Finck static const ISAXAttributesVtbl SAXAttributesVtbl = {
3195c2c66affSColin Finck     SAXAttributes_QueryInterface,
3196c2c66affSColin Finck     SAXAttributes_AddRef,
3197c2c66affSColin Finck     SAXAttributes_Release,
3198c2c66affSColin Finck     SAXAttributes_getLength,
3199c2c66affSColin Finck     SAXAttributes_getURI,
3200c2c66affSColin Finck     SAXAttributes_getLocalName,
3201c2c66affSColin Finck     SAXAttributes_getQName,
3202c2c66affSColin Finck     SAXAttributes_getName,
3203c2c66affSColin Finck     SAXAttributes_getIndexFromName,
3204c2c66affSColin Finck     SAXAttributes_getIndexFromQName,
3205c2c66affSColin Finck     SAXAttributes_getType,
3206c2c66affSColin Finck     SAXAttributes_getTypeFromName,
3207c2c66affSColin Finck     SAXAttributes_getTypeFromQName,
3208c2c66affSColin Finck     SAXAttributes_getValue,
3209c2c66affSColin Finck     SAXAttributes_getValueFromName,
3210c2c66affSColin Finck     SAXAttributes_getValueFromQName
3211c2c66affSColin Finck };
3212c2c66affSColin Finck 
VBSAXAttributes_QueryInterface(IVBSAXAttributes * iface,REFIID riid,void ** ppvObject)3213c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_QueryInterface(
3214c2c66affSColin Finck         IVBSAXAttributes* iface,
3215c2c66affSColin Finck         REFIID riid,
3216c2c66affSColin Finck         void **ppvObject)
3217c2c66affSColin Finck {
3218c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3219c2c66affSColin Finck     TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
3220c2c66affSColin Finck     return ISAXAttributes_QueryInterface(&This->ISAXAttributes_iface, riid, ppvObject);
3221c2c66affSColin Finck }
3222c2c66affSColin Finck 
VBSAXAttributes_AddRef(IVBSAXAttributes * iface)3223c2c66affSColin Finck static ULONG WINAPI VBSAXAttributes_AddRef(IVBSAXAttributes* iface)
3224c2c66affSColin Finck {
3225c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3226c2c66affSColin Finck     return ISAXAttributes_AddRef(&This->ISAXAttributes_iface);
3227c2c66affSColin Finck }
3228c2c66affSColin Finck 
VBSAXAttributes_Release(IVBSAXAttributes * iface)3229c2c66affSColin Finck static ULONG WINAPI VBSAXAttributes_Release(IVBSAXAttributes* iface)
3230c2c66affSColin Finck {
3231c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3232c2c66affSColin Finck     return ISAXAttributes_Release(&This->ISAXAttributes_iface);
3233c2c66affSColin Finck }
3234c2c66affSColin Finck 
VBSAXAttributes_GetTypeInfoCount(IVBSAXAttributes * iface,UINT * pctinfo)3235c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
3236c2c66affSColin Finck {
3237c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3238c2c66affSColin Finck 
3239c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, pctinfo);
3240c2c66affSColin Finck 
3241c2c66affSColin Finck     *pctinfo = 1;
3242c2c66affSColin Finck 
3243c2c66affSColin Finck     return S_OK;
3244c2c66affSColin Finck }
3245c2c66affSColin Finck 
VBSAXAttributes_GetTypeInfo(IVBSAXAttributes * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)3246c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_GetTypeInfo(
3247c2c66affSColin Finck     IVBSAXAttributes *iface,
3248c2c66affSColin Finck     UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
3249c2c66affSColin Finck {
3250c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3251c2c66affSColin Finck     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
3252c2c66affSColin Finck     return get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
3253c2c66affSColin Finck }
3254c2c66affSColin Finck 
VBSAXAttributes_GetIDsOfNames(IVBSAXAttributes * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)3255c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_GetIDsOfNames(
3256c2c66affSColin Finck     IVBSAXAttributes *iface,
3257c2c66affSColin Finck     REFIID riid,
3258c2c66affSColin Finck     LPOLESTR* rgszNames,
3259c2c66affSColin Finck     UINT cNames,
3260c2c66affSColin Finck     LCID lcid,
3261c2c66affSColin Finck     DISPID* rgDispId)
3262c2c66affSColin Finck {
3263c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3264c2c66affSColin Finck     ITypeInfo *typeinfo;
3265c2c66affSColin Finck     HRESULT hr;
3266c2c66affSColin Finck 
3267c2c66affSColin Finck     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
3268c2c66affSColin Finck           lcid, rgDispId);
3269c2c66affSColin Finck 
3270c2c66affSColin Finck     if(!rgszNames || cNames == 0 || !rgDispId)
3271c2c66affSColin Finck         return E_INVALIDARG;
3272c2c66affSColin Finck 
3273c2c66affSColin Finck     hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
3274c2c66affSColin Finck     if(SUCCEEDED(hr))
3275c2c66affSColin Finck     {
3276c2c66affSColin Finck         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
3277c2c66affSColin Finck         ITypeInfo_Release(typeinfo);
3278c2c66affSColin Finck     }
3279c2c66affSColin Finck 
3280c2c66affSColin Finck     return hr;
3281c2c66affSColin Finck }
3282c2c66affSColin Finck 
VBSAXAttributes_Invoke(IVBSAXAttributes * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)3283c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_Invoke(
3284c2c66affSColin Finck     IVBSAXAttributes *iface,
3285c2c66affSColin Finck     DISPID dispIdMember,
3286c2c66affSColin Finck     REFIID riid,
3287c2c66affSColin Finck     LCID lcid,
3288c2c66affSColin Finck     WORD wFlags,
3289c2c66affSColin Finck     DISPPARAMS* pDispParams,
3290c2c66affSColin Finck     VARIANT* pVarResult,
3291c2c66affSColin Finck     EXCEPINFO* pExcepInfo,
3292c2c66affSColin Finck     UINT* puArgErr)
3293c2c66affSColin Finck {
3294c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3295c2c66affSColin Finck     ITypeInfo *typeinfo;
3296c2c66affSColin Finck     HRESULT hr;
3297c2c66affSColin Finck 
3298c2c66affSColin Finck     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
3299c2c66affSColin Finck           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3300c2c66affSColin Finck 
3301c2c66affSColin Finck     hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
3302c2c66affSColin Finck     if(SUCCEEDED(hr))
3303c2c66affSColin Finck     {
3304c2c66affSColin Finck         hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
3305c2c66affSColin Finck                 pDispParams, pVarResult, pExcepInfo, puArgErr);
3306c2c66affSColin Finck         ITypeInfo_Release(typeinfo);
3307c2c66affSColin Finck     }
3308c2c66affSColin Finck 
3309c2c66affSColin Finck     return hr;
3310c2c66affSColin Finck }
3311c2c66affSColin Finck 
VBSAXAttributes_get_length(IVBSAXAttributes * iface,int * len)3312c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_get_length(IVBSAXAttributes* iface, int *len)
3313c2c66affSColin Finck {
3314c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3315c2c66affSColin Finck     return ISAXAttributes_getLength(&This->ISAXAttributes_iface, len);
3316c2c66affSColin Finck }
3317c2c66affSColin Finck 
VBSAXAttributes_getURI(IVBSAXAttributes * iface,int index,BSTR * uri)3318c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_getURI(IVBSAXAttributes* iface, int index, BSTR *uri)
3319c2c66affSColin Finck {
3320c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3321c2c66affSColin Finck     const WCHAR *uriW;
3322c2c66affSColin Finck     HRESULT hr;
3323c2c66affSColin Finck     int len;
3324c2c66affSColin Finck 
3325c2c66affSColin Finck     TRACE("(%p)->(%d %p)\n", This, index, uri);
3326c2c66affSColin Finck 
3327c2c66affSColin Finck     if (!uri)
3328c2c66affSColin Finck         return E_POINTER;
3329c2c66affSColin Finck 
3330c2c66affSColin Finck     *uri = NULL;
3331c2c66affSColin Finck     hr = ISAXAttributes_getURI(&This->ISAXAttributes_iface, index, &uriW, &len);
3332c2c66affSColin Finck     if (FAILED(hr))
3333c2c66affSColin Finck         return hr;
3334c2c66affSColin Finck 
3335c2c66affSColin Finck     return return_bstrn(uriW, len, uri);
3336c2c66affSColin Finck }
3337c2c66affSColin Finck 
VBSAXAttributes_getLocalName(IVBSAXAttributes * iface,int index,BSTR * name)3338c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_getLocalName(IVBSAXAttributes* iface, int index, BSTR *name)
3339c2c66affSColin Finck {
3340c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3341c2c66affSColin Finck     const WCHAR *nameW;
3342c2c66affSColin Finck     HRESULT hr;
3343c2c66affSColin Finck     int len;
3344c2c66affSColin Finck 
3345c2c66affSColin Finck     TRACE("(%p)->(%d %p)\n", This, index, name);
3346c2c66affSColin Finck 
3347c2c66affSColin Finck     if (!name)
3348c2c66affSColin Finck         return E_POINTER;
3349c2c66affSColin Finck 
3350c2c66affSColin Finck     *name = NULL;
3351c2c66affSColin Finck     hr = ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, index, &nameW, &len);
3352c2c66affSColin Finck     if (FAILED(hr))
3353c2c66affSColin Finck         return hr;
3354c2c66affSColin Finck 
3355c2c66affSColin Finck     return return_bstrn(nameW, len, name);
3356c2c66affSColin Finck }
3357c2c66affSColin Finck 
VBSAXAttributes_getQName(IVBSAXAttributes * iface,int index,BSTR * qname)3358c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_getQName(IVBSAXAttributes* iface, int index, BSTR *qname)
3359c2c66affSColin Finck {
3360c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3361c2c66affSColin Finck     const WCHAR *qnameW;
3362c2c66affSColin Finck     HRESULT hr;
3363c2c66affSColin Finck     int len;
3364c2c66affSColin Finck 
3365c2c66affSColin Finck     TRACE("(%p)->(%d %p)\n", This, index, qname);
3366c2c66affSColin Finck 
3367c2c66affSColin Finck     if (!qname)
3368c2c66affSColin Finck         return E_POINTER;
3369c2c66affSColin Finck 
3370c2c66affSColin Finck     *qname = NULL;
3371c2c66affSColin Finck     hr = ISAXAttributes_getQName(&This->ISAXAttributes_iface, index, &qnameW, &len);
3372c2c66affSColin Finck     if (FAILED(hr))
3373c2c66affSColin Finck         return hr;
3374c2c66affSColin Finck 
3375c2c66affSColin Finck     return return_bstrn(qnameW, len, qname);
3376c2c66affSColin Finck }
3377c2c66affSColin Finck 
VBSAXAttributes_getIndexFromName(IVBSAXAttributes * iface,BSTR uri,BSTR name,int * index)3378c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_getIndexFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name, int *index)
3379c2c66affSColin Finck {
3380c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3381c2c66affSColin Finck     return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3382c2c66affSColin Finck             name, SysStringLen(name), index);
3383c2c66affSColin Finck }
3384c2c66affSColin Finck 
VBSAXAttributes_getIndexFromQName(IVBSAXAttributes * iface,BSTR qname,int * index)3385c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_getIndexFromQName(IVBSAXAttributes* iface, BSTR qname, int *index)
3386c2c66affSColin Finck {
3387c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3388c2c66affSColin Finck     return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, qname,
3389c2c66affSColin Finck             SysStringLen(qname), index);
3390c2c66affSColin Finck }
3391c2c66affSColin Finck 
VBSAXAttributes_getType(IVBSAXAttributes * iface,int index,BSTR * type)3392c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_getType(IVBSAXAttributes* iface, int index, BSTR *type)
3393c2c66affSColin Finck {
3394c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3395c2c66affSColin Finck     const WCHAR *typeW;
3396c2c66affSColin Finck     HRESULT hr;
3397c2c66affSColin Finck     int len;
3398c2c66affSColin Finck 
3399c2c66affSColin Finck     TRACE("(%p)->(%d %p)\n", This, index, type);
3400c2c66affSColin Finck 
3401c2c66affSColin Finck     if (!type)
3402c2c66affSColin Finck         return E_POINTER;
3403c2c66affSColin Finck 
3404c2c66affSColin Finck     *type = NULL;
3405c2c66affSColin Finck     hr = ISAXAttributes_getType(&This->ISAXAttributes_iface, index, &typeW, &len);
3406c2c66affSColin Finck     if (FAILED(hr))
3407c2c66affSColin Finck         return hr;
3408c2c66affSColin Finck 
3409c2c66affSColin Finck     return return_bstrn(typeW, len, type);
3410c2c66affSColin Finck }
3411c2c66affSColin Finck 
VBSAXAttributes_getTypeFromName(IVBSAXAttributes * iface,BSTR uri,BSTR name,BSTR * type)3412c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_getTypeFromName(IVBSAXAttributes* iface, BSTR uri,
3413c2c66affSColin Finck     BSTR name, BSTR *type)
3414c2c66affSColin Finck {
3415c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3416c2c66affSColin Finck     const WCHAR *typeW;
3417c2c66affSColin Finck     HRESULT hr;
3418c2c66affSColin Finck     int len;
3419c2c66affSColin Finck 
3420c2c66affSColin Finck     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), type);
3421c2c66affSColin Finck 
3422c2c66affSColin Finck     if (!type)
3423c2c66affSColin Finck         return E_POINTER;
3424c2c66affSColin Finck 
3425c2c66affSColin Finck     *type = NULL;
3426c2c66affSColin Finck     hr = ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3427c2c66affSColin Finck             name, SysStringLen(name), &typeW, &len);
3428c2c66affSColin Finck     if (FAILED(hr))
3429c2c66affSColin Finck         return hr;
3430c2c66affSColin Finck 
3431c2c66affSColin Finck     return return_bstrn(typeW, len, type);
3432c2c66affSColin Finck }
3433c2c66affSColin Finck 
VBSAXAttributes_getTypeFromQName(IVBSAXAttributes * iface,BSTR qname,BSTR * type)3434c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_getTypeFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *type)
3435c2c66affSColin Finck {
3436c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3437c2c66affSColin Finck     const WCHAR *typeW;
3438c2c66affSColin Finck     HRESULT hr;
3439c2c66affSColin Finck     int len;
3440c2c66affSColin Finck 
3441c2c66affSColin Finck     TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), type);
3442c2c66affSColin Finck 
3443c2c66affSColin Finck     if (!type)
3444c2c66affSColin Finck         return E_POINTER;
3445c2c66affSColin Finck 
3446c2c66affSColin Finck     *type = NULL;
3447c2c66affSColin Finck     hr = ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3448c2c66affSColin Finck             &typeW, &len);
3449c2c66affSColin Finck     if (FAILED(hr))
3450c2c66affSColin Finck         return hr;
3451c2c66affSColin Finck 
3452c2c66affSColin Finck     return return_bstrn(typeW, len, type);
3453c2c66affSColin Finck }
3454c2c66affSColin Finck 
VBSAXAttributes_getValue(IVBSAXAttributes * iface,int index,BSTR * value)3455c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_getValue(IVBSAXAttributes* iface, int index, BSTR *value)
3456c2c66affSColin Finck {
3457c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3458c2c66affSColin Finck     const WCHAR *valueW;
3459c2c66affSColin Finck     HRESULT hr;
3460c2c66affSColin Finck     int len;
3461c2c66affSColin Finck 
3462c2c66affSColin Finck     TRACE("(%p)->(%d %p)\n", This, index, value);
3463c2c66affSColin Finck 
3464c2c66affSColin Finck     if (!value)
3465c2c66affSColin Finck         return E_POINTER;
3466c2c66affSColin Finck 
3467c2c66affSColin Finck     *value = NULL;
3468c2c66affSColin Finck     hr = ISAXAttributes_getValue(&This->ISAXAttributes_iface, index, &valueW, &len);
3469c2c66affSColin Finck     if (FAILED(hr))
3470c2c66affSColin Finck         return hr;
3471c2c66affSColin Finck 
3472c2c66affSColin Finck     return return_bstrn(valueW, len, value);
3473c2c66affSColin Finck }
3474c2c66affSColin Finck 
VBSAXAttributes_getValueFromName(IVBSAXAttributes * iface,BSTR uri,BSTR name,BSTR * value)3475c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_getValueFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name,
3476c2c66affSColin Finck     BSTR *value)
3477c2c66affSColin Finck {
3478c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3479c2c66affSColin Finck     const WCHAR *valueW;
3480c2c66affSColin Finck     HRESULT hr;
3481c2c66affSColin Finck     int len;
3482c2c66affSColin Finck 
3483c2c66affSColin Finck     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(name), value);
3484c2c66affSColin Finck 
3485c2c66affSColin Finck     if (!value)
3486c2c66affSColin Finck         return E_POINTER;
3487c2c66affSColin Finck 
3488c2c66affSColin Finck     *value = NULL;
3489c2c66affSColin Finck     hr = ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
3490c2c66affSColin Finck             name, SysStringLen(name), &valueW, &len);
3491c2c66affSColin Finck     if (FAILED(hr))
3492c2c66affSColin Finck         return hr;
3493c2c66affSColin Finck 
3494c2c66affSColin Finck     return return_bstrn(valueW, len, value);
3495c2c66affSColin Finck }
3496c2c66affSColin Finck 
VBSAXAttributes_getValueFromQName(IVBSAXAttributes * iface,BSTR qname,BSTR * value)3497c2c66affSColin Finck static HRESULT WINAPI VBSAXAttributes_getValueFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *value)
3498c2c66affSColin Finck {
3499c2c66affSColin Finck     mxattributes *This = impl_from_IVBSAXAttributes( iface );
3500c2c66affSColin Finck     const WCHAR *valueW;
3501c2c66affSColin Finck     HRESULT hr;
3502c2c66affSColin Finck     int len;
3503c2c66affSColin Finck 
3504c2c66affSColin Finck     TRACE("(%p)->(%s %p)\n", This, debugstr_w(qname), value);
3505c2c66affSColin Finck 
3506c2c66affSColin Finck     if (!value)
3507c2c66affSColin Finck         return E_POINTER;
3508c2c66affSColin Finck 
3509c2c66affSColin Finck     *value = NULL;
3510c2c66affSColin Finck     hr = ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
3511c2c66affSColin Finck         &valueW, &len);
3512c2c66affSColin Finck     if (FAILED(hr))
3513c2c66affSColin Finck         return hr;
3514c2c66affSColin Finck 
3515c2c66affSColin Finck     return return_bstrn(valueW, len, value);
3516c2c66affSColin Finck }
3517c2c66affSColin Finck 
3518c2c66affSColin Finck static const struct IVBSAXAttributesVtbl VBSAXAttributesVtbl =
3519c2c66affSColin Finck {
3520c2c66affSColin Finck     VBSAXAttributes_QueryInterface,
3521c2c66affSColin Finck     VBSAXAttributes_AddRef,
3522c2c66affSColin Finck     VBSAXAttributes_Release,
3523c2c66affSColin Finck     VBSAXAttributes_GetTypeInfoCount,
3524c2c66affSColin Finck     VBSAXAttributes_GetTypeInfo,
3525c2c66affSColin Finck     VBSAXAttributes_GetIDsOfNames,
3526c2c66affSColin Finck     VBSAXAttributes_Invoke,
3527c2c66affSColin Finck     VBSAXAttributes_get_length,
3528c2c66affSColin Finck     VBSAXAttributes_getURI,
3529c2c66affSColin Finck     VBSAXAttributes_getLocalName,
3530c2c66affSColin Finck     VBSAXAttributes_getQName,
3531c2c66affSColin Finck     VBSAXAttributes_getIndexFromName,
3532c2c66affSColin Finck     VBSAXAttributes_getIndexFromQName,
3533c2c66affSColin Finck     VBSAXAttributes_getType,
3534c2c66affSColin Finck     VBSAXAttributes_getTypeFromName,
3535c2c66affSColin Finck     VBSAXAttributes_getTypeFromQName,
3536c2c66affSColin Finck     VBSAXAttributes_getValue,
3537c2c66affSColin Finck     VBSAXAttributes_getValueFromName,
3538c2c66affSColin Finck     VBSAXAttributes_getValueFromQName
3539c2c66affSColin Finck };
3540c2c66affSColin Finck 
3541c2c66affSColin Finck static const tid_t mxattrs_iface_tids[] = {
3542c2c66affSColin Finck     IMXAttributes_tid,
3543c2c66affSColin Finck     0
3544c2c66affSColin Finck };
3545c2c66affSColin Finck 
3546c2c66affSColin Finck static dispex_static_data_t mxattrs_dispex = {
3547c2c66affSColin Finck     NULL,
3548c2c66affSColin Finck     IMXAttributes_tid,
3549c2c66affSColin Finck     NULL,
3550c2c66affSColin Finck     mxattrs_iface_tids
3551c2c66affSColin Finck };
3552c2c66affSColin Finck 
SAXAttributes_create(MSXML_VERSION version,void ** ppObj)3553c2c66affSColin Finck HRESULT SAXAttributes_create(MSXML_VERSION version, void **ppObj)
3554c2c66affSColin Finck {
3555c2c66affSColin Finck     static const int default_count = 10;
3556c2c66affSColin Finck     mxattributes *This;
3557c2c66affSColin Finck 
3558c2c66affSColin Finck     TRACE("(%p)\n", ppObj);
3559c2c66affSColin Finck 
3560c2c66affSColin Finck     This = heap_alloc( sizeof (*This) );
3561c2c66affSColin Finck     if( !This )
3562c2c66affSColin Finck         return E_OUTOFMEMORY;
3563c2c66affSColin Finck 
3564c2c66affSColin Finck     This->IMXAttributes_iface.lpVtbl = &MXAttributesVtbl;
3565c2c66affSColin Finck     This->ISAXAttributes_iface.lpVtbl = &SAXAttributesVtbl;
3566c2c66affSColin Finck     This->IVBSAXAttributes_iface.lpVtbl = &VBSAXAttributesVtbl;
3567c2c66affSColin Finck     This->ref = 1;
3568c2c66affSColin Finck 
3569c2c66affSColin Finck     This->class_version = version;
3570c2c66affSColin Finck 
3571c2c66affSColin Finck     This->attr = heap_alloc(default_count*sizeof(mxattribute));
3572c2c66affSColin Finck     This->length = 0;
3573c2c66affSColin Finck     This->allocated = default_count;
3574c2c66affSColin Finck 
3575c2c66affSColin Finck     *ppObj = &This->IMXAttributes_iface;
3576c2c66affSColin Finck 
3577c2c66affSColin Finck     init_dispex(&This->dispex, (IUnknown*)&This->IMXAttributes_iface, &mxattrs_dispex);
3578c2c66affSColin Finck 
3579c2c66affSColin Finck     TRACE("returning iface %p\n", *ppObj);
3580c2c66affSColin Finck 
3581c2c66affSColin Finck     return S_OK;
3582c2c66affSColin Finck }
3583