2 * IXmlWriter implementation
4 * Copyright 2011 Alistair Leslie-Hughes
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "xmllite_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(xmllite
);
34 /* not defined in public headers */
35 DEFINE_GUID(IID_IXmlWriterOutput
, 0xc1131708, 0x0f59, 0x477f, 0x93, 0x59, 0x7d, 0x33, 0x24, 0x51, 0xbc, 0x1a);
39 IXmlWriterOutput IXmlWriterOutput_iface
;
43 xml_encoding encoding
;
46 typedef struct _xmlwriter
48 IXmlWriter IXmlWriter_iface
;
53 static inline xmlwriter
*impl_from_IXmlWriter(IXmlWriter
*iface
)
55 return CONTAINING_RECORD(iface
, xmlwriter
, IXmlWriter_iface
);
58 static inline xmlwriteroutput
*impl_from_IXmlWriterOutput(IXmlWriterOutput
*iface
)
60 return CONTAINING_RECORD(iface
, xmlwriteroutput
, IXmlWriterOutput_iface
);
63 /* writer output memory allocation functions */
64 static inline void *writeroutput_alloc(xmlwriteroutput
*output
, size_t len
)
66 return m_alloc(output
->imalloc
, len
);
69 static inline void writeroutput_free(xmlwriteroutput
*output
, void *mem
)
71 m_free(output
->imalloc
, mem
);
74 /* writer memory allocation functions */
75 static inline void *writer_alloc(xmlwriter
*writer
, size_t len
)
77 return m_alloc(writer
->imalloc
, len
);
80 static inline void writer_free(xmlwriter
*writer
, void *mem
)
82 m_free(writer
->imalloc
, mem
);
85 static HRESULT WINAPI
xmlwriter_QueryInterface(IXmlWriter
*iface
, REFIID riid
, void **ppvObject
)
87 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
89 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
91 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
92 IsEqualGUID(riid
, &IID_IXmlWriter
))
97 IXmlWriter_AddRef(iface
);
102 static ULONG WINAPI
xmlwriter_AddRef(IXmlWriter
*iface
)
104 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
106 return InterlockedIncrement(&This
->ref
);
109 static ULONG WINAPI
xmlwriter_Release(IXmlWriter
*iface
)
111 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
116 ref
= InterlockedDecrement(&This
->ref
);
118 IMalloc
*imalloc
= This
->imalloc
;
119 writer_free(This
, This
);
120 if (imalloc
) IMalloc_Release(imalloc
);
126 /*** IXmlWriter methods ***/
127 static HRESULT WINAPI
xmlwriter_SetOutput(IXmlWriter
*iface
, IUnknown
*pOutput
)
129 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
131 FIXME("%p %p\n", This
, pOutput
);
136 static HRESULT WINAPI
xmlwriter_GetProperty(IXmlWriter
*iface
, UINT nProperty
, LONG_PTR
*ppValue
)
138 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
140 FIXME("%p %u %p\n", This
, nProperty
, ppValue
);
145 static HRESULT WINAPI
xmlwriter_SetProperty(IXmlWriter
*iface
, UINT nProperty
, LONG_PTR pValue
)
147 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
149 FIXME("%p %u %lu\n", This
, nProperty
, pValue
);
154 static HRESULT WINAPI
xmlwriter_WriteAttributes(IXmlWriter
*iface
, IXmlReader
*pReader
,
155 BOOL fWriteDefaultAttributes
)
157 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
159 FIXME("%p %p %d\n", This
, pReader
, fWriteDefaultAttributes
);
164 static HRESULT WINAPI
xmlwriter_WriteAttributeString(IXmlWriter
*iface
, LPCWSTR pwszPrefix
,
165 LPCWSTR pwszLocalName
, LPCWSTR pwszNamespaceUri
,
168 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
170 FIXME("%p %s %s %s %s\n", This
, wine_dbgstr_w(pwszPrefix
), wine_dbgstr_w(pwszLocalName
),
171 wine_dbgstr_w(pwszNamespaceUri
), wine_dbgstr_w(pwszValue
));
176 static HRESULT WINAPI
xmlwriter_WriteCData(IXmlWriter
*iface
, LPCWSTR pwszText
)
178 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
180 FIXME("%p %s\n", This
, wine_dbgstr_w(pwszText
));
185 static HRESULT WINAPI
xmlwriter_WriteCharEntity(IXmlWriter
*iface
, WCHAR wch
)
190 static HRESULT WINAPI
xmlwriter_WriteChars(IXmlWriter
*iface
, const WCHAR
*pwch
, UINT cwch
)
192 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
194 FIXME("%p %s %d\n", This
, wine_dbgstr_w(pwch
), cwch
);
199 static HRESULT WINAPI
xmlwriter_WriteComment(IXmlWriter
*iface
, LPCWSTR pwszComment
)
204 static HRESULT WINAPI
xmlwriter_WriteDocType(IXmlWriter
*iface
, LPCWSTR pwszName
, LPCWSTR pwszPublicId
,
205 LPCWSTR pwszSystemId
, LPCWSTR pwszSubset
)
207 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
209 FIXME("%p %s %s %s %s\n", This
, wine_dbgstr_w(pwszName
), wine_dbgstr_w(pwszPublicId
),
210 wine_dbgstr_w(pwszSystemId
), wine_dbgstr_w(pwszSubset
));
215 static HRESULT WINAPI
xmlwriter_WriteElementString(IXmlWriter
*iface
, LPCWSTR pwszPrefix
,
216 LPCWSTR pwszLocalName
, LPCWSTR pwszNamespaceUri
,
219 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
221 FIXME("%p %s %s %s %s\n", This
, wine_dbgstr_w(pwszPrefix
), wine_dbgstr_w(pwszLocalName
),
222 wine_dbgstr_w(pwszNamespaceUri
), wine_dbgstr_w(pwszValue
));
227 static HRESULT WINAPI
xmlwriter_WriteEndDocument(IXmlWriter
*iface
)
229 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
236 static HRESULT WINAPI
xmlwriter_WriteEndElement(IXmlWriter
*iface
)
238 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
245 static HRESULT WINAPI
xmlwriter_WriteEntityRef(IXmlWriter
*iface
, LPCWSTR pwszName
)
247 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
249 FIXME("%p %s\n", This
, wine_dbgstr_w(pwszName
));
254 static HRESULT WINAPI
xmlwriter_WriteFullEndElement(IXmlWriter
*iface
)
256 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
263 static HRESULT WINAPI
xmlwriter_WriteName(IXmlWriter
*iface
, LPCWSTR pwszName
)
265 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
267 FIXME("%p %s\n", This
, wine_dbgstr_w(pwszName
));
272 static HRESULT WINAPI
xmlwriter_WriteNmToken(IXmlWriter
*iface
, LPCWSTR pwszNmToken
)
274 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
276 FIXME("%p %s\n", This
, wine_dbgstr_w(pwszNmToken
));
281 static HRESULT WINAPI
xmlwriter_WriteNode(IXmlWriter
*iface
, IXmlReader
*pReader
,
282 BOOL fWriteDefaultAttributes
)
284 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
286 FIXME("%p %p %d\n", This
, pReader
, fWriteDefaultAttributes
);
291 static HRESULT WINAPI
xmlwriter_WriteNodeShallow(IXmlWriter
*iface
, IXmlReader
*pReader
,
292 BOOL fWriteDefaultAttributes
)
294 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
296 FIXME("%p %p %d\n", This
, pReader
, fWriteDefaultAttributes
);
301 static HRESULT WINAPI
xmlwriter_WriteProcessingInstruction(IXmlWriter
*iface
, LPCWSTR pwszName
,
304 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
306 FIXME("%p %s %s\n", This
, wine_dbgstr_w(pwszName
), wine_dbgstr_w(pwszText
));
311 static HRESULT WINAPI
xmlwriter_WriteQualifiedName(IXmlWriter
*iface
, LPCWSTR pwszLocalName
,
312 LPCWSTR pwszNamespaceUri
)
314 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
316 FIXME("%p %s %s\n", This
, wine_dbgstr_w(pwszLocalName
), wine_dbgstr_w(pwszNamespaceUri
));
321 static HRESULT WINAPI
xmlwriter_WriteRaw(IXmlWriter
*iface
, LPCWSTR pwszData
)
323 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
325 FIXME("%p %s\n", This
, wine_dbgstr_w(pwszData
));
330 static HRESULT WINAPI
xmlwriter_WriteRawChars(IXmlWriter
*iface
, const WCHAR
*pwch
, UINT cwch
)
332 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
334 FIXME("%p %s %d\n", This
, wine_dbgstr_w(pwch
), cwch
);
339 static HRESULT WINAPI
xmlwriter_WriteStartDocument(IXmlWriter
*iface
, XmlStandalone standalone
)
341 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
348 static HRESULT WINAPI
xmlwriter_WriteStartElement(IXmlWriter
*iface
, LPCWSTR pwszPrefix
,
349 LPCWSTR pwszLocalName
, LPCWSTR pwszNamespaceUri
)
351 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
353 FIXME("%p %s %s %s\n", This
, wine_dbgstr_w(pwszPrefix
), wine_dbgstr_w(pwszLocalName
),
354 wine_dbgstr_w(pwszNamespaceUri
));
359 static HRESULT WINAPI
xmlwriter_WriteString(IXmlWriter
*iface
, LPCWSTR pwszText
)
361 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
363 FIXME("%p %s\n", This
, wine_dbgstr_w(pwszText
));
368 static HRESULT WINAPI
xmlwriter_WriteSurrogateCharEntity(IXmlWriter
*iface
, WCHAR wchLow
, WCHAR wchHigh
)
370 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
372 FIXME("%p %d %d\n", This
, wchLow
, wchHigh
);
377 static HRESULT WINAPI
xmlwriter_WriteWhitespace(IXmlWriter
*iface
, LPCWSTR pwszWhitespace
)
379 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
381 FIXME("%p %s\n", This
, wine_dbgstr_w(pwszWhitespace
));
386 static HRESULT WINAPI
xmlwriter_Flush(IXmlWriter
*iface
)
388 xmlwriter
*This
= impl_from_IXmlWriter(iface
);
395 static const struct IXmlWriterVtbl xmlwriter_vtbl
=
397 xmlwriter_QueryInterface
,
401 xmlwriter_GetProperty
,
402 xmlwriter_SetProperty
,
403 xmlwriter_WriteAttributes
,
404 xmlwriter_WriteAttributeString
,
405 xmlwriter_WriteCData
,
406 xmlwriter_WriteCharEntity
,
407 xmlwriter_WriteChars
,
408 xmlwriter_WriteComment
,
409 xmlwriter_WriteDocType
,
410 xmlwriter_WriteElementString
,
411 xmlwriter_WriteEndDocument
,
412 xmlwriter_WriteEndElement
,
413 xmlwriter_WriteEntityRef
,
414 xmlwriter_WriteFullEndElement
,
416 xmlwriter_WriteNmToken
,
418 xmlwriter_WriteNodeShallow
,
419 xmlwriter_WriteProcessingInstruction
,
420 xmlwriter_WriteQualifiedName
,
422 xmlwriter_WriteRawChars
,
423 xmlwriter_WriteStartDocument
,
424 xmlwriter_WriteStartElement
,
425 xmlwriter_WriteString
,
426 xmlwriter_WriteSurrogateCharEntity
,
427 xmlwriter_WriteWhitespace
,
431 /** IXmlWriterOutput **/
432 static HRESULT WINAPI
xmlwriteroutput_QueryInterface(IXmlWriterOutput
*iface
, REFIID riid
, void** ppvObject
)
434 xmlwriteroutput
*This
= impl_from_IXmlWriterOutput(iface
);
436 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
438 if (IsEqualGUID(riid
, &IID_IXmlWriterOutput
) ||
439 IsEqualGUID(riid
, &IID_IUnknown
))
445 WARN("interface %s not implemented\n", debugstr_guid(riid
));
447 return E_NOINTERFACE
;
450 IUnknown_AddRef(iface
);
455 static ULONG WINAPI
xmlwriteroutput_AddRef(IXmlWriterOutput
*iface
)
457 xmlwriteroutput
*This
= impl_from_IXmlWriterOutput(iface
);
458 ULONG ref
= InterlockedIncrement(&This
->ref
);
459 TRACE("(%p)->(%d)\n", This
, ref
);
463 static ULONG WINAPI
xmlwriteroutput_Release(IXmlWriterOutput
*iface
)
465 xmlwriteroutput
*This
= impl_from_IXmlWriterOutput(iface
);
466 LONG ref
= InterlockedDecrement(&This
->ref
);
468 TRACE("(%p)->(%d)\n", This
, ref
);
472 IMalloc
*imalloc
= This
->imalloc
;
473 if (This
->output
) IUnknown_Release(This
->output
);
474 writeroutput_free(This
, This
);
475 if (imalloc
) IMalloc_Release(imalloc
);
481 static const struct IUnknownVtbl xmlwriteroutputvtbl
=
483 xmlwriteroutput_QueryInterface
,
484 xmlwriteroutput_AddRef
,
485 xmlwriteroutput_Release
488 HRESULT WINAPI
CreateXmlWriter(REFIID riid
, void **obj
, IMalloc
*imalloc
)
492 TRACE("(%s, %p, %p)\n", wine_dbgstr_guid(riid
), obj
, imalloc
);
494 if (!IsEqualGUID(riid
, &IID_IXmlWriter
))
496 ERR("Unexpected IID requested -> (%s)\n", wine_dbgstr_guid(riid
));
501 writer
= IMalloc_Alloc(imalloc
, sizeof(*writer
));
503 writer
= heap_alloc(sizeof(*writer
));
504 if(!writer
) return E_OUTOFMEMORY
;
506 writer
->IXmlWriter_iface
.lpVtbl
= &xmlwriter_vtbl
;
508 writer
->imalloc
= imalloc
;
509 if (imalloc
) IMalloc_AddRef(imalloc
);
511 *obj
= &writer
->IXmlWriter_iface
;
513 TRACE("returning iface %p\n", *obj
);
518 HRESULT WINAPI
CreateXmlWriterOutputWithEncodingName(IUnknown
*stream
,
521 IXmlWriterOutput
**output
)
523 xmlwriteroutput
*writeroutput
;
525 TRACE("%p %p %s %p\n", stream
, imalloc
, debugstr_w(encoding
), output
);
527 if (!stream
|| !output
) return E_INVALIDARG
;
530 writeroutput
= IMalloc_Alloc(imalloc
, sizeof(*writeroutput
));
532 writeroutput
= heap_alloc(sizeof(*writeroutput
));
533 if(!writeroutput
) return E_OUTOFMEMORY
;
535 writeroutput
->IXmlWriterOutput_iface
.lpVtbl
= &xmlwriteroutputvtbl
;
536 writeroutput
->ref
= 1;
537 writeroutput
->imalloc
= imalloc
;
538 if (imalloc
) IMalloc_AddRef(imalloc
);
539 writeroutput
->encoding
= parse_encoding_name(encoding
, -1);
541 IUnknown_QueryInterface(stream
, &IID_IUnknown
, (void**)&writeroutput
->output
);
543 *output
= &writeroutput
->IXmlWriterOutput_iface
;
545 TRACE("returning iface %p\n", *output
);