static ULONG WINAPI xmlwriter_Release(IXmlWriter *iface) { xmlwriter *This = impl_from_IXmlWriter(iface); LONG ref; TRACE("%p\n", This); ref = InterlockedDecrement(&This->ref); if (ref == 0) { struct element *element, *element2; IMalloc *imalloc = This->imalloc; IXmlWriter_Flush(iface); if (This->output) IUnknown_Release(&This->output->IXmlWriterOutput_iface); /* element stack */ LIST_FOR_EACH_ENTRY_SAFE(element, element2, &This->elements, struct element, entry) { list_remove(&element->entry); free_element(This, element); } writer_free(This, This); if (imalloc) IMalloc_Release(imalloc); } return ref; }
static HRESULT WINAPI xmlwriter_WriteCharEntity(IXmlWriter *iface, WCHAR ch) { static const WCHAR fmtW[] = {'&','#','x','%','x',';',0}; xmlwriter *This = impl_from_IXmlWriter(iface); WCHAR bufW[16]; TRACE("%p %#x\n", This, ch); switch (This->state) { case XmlWriterState_Initial: return E_UNEXPECTED; case XmlWriterState_ElemStarted: writer_close_starttag(This); break; case XmlWriterState_DocClosed: return WR_E_INVALIDACTION; default: ; } sprintfW(bufW, fmtW, ch); write_output_buffer(This->output, bufW, -1); return S_OK; }
static HRESULT WINAPI xmlwriter_WriteEndDocument(IXmlWriter *iface) { xmlwriter *This = impl_from_IXmlWriter(iface); HRESULT hr = S_OK; TRACE("%p\n", This); switch (This->state) { case XmlWriterState_Initial: hr = E_UNEXPECTED; break; case XmlWriterState_Ready: case XmlWriterState_DocClosed: hr = WR_E_INVALIDACTION; break; default: ; } if (FAILED(hr)) { This->state = XmlWriterState_DocClosed; return hr; } /* empty element stack */ while (IXmlWriter_WriteEndElement(iface) == S_OK) ; This->state = XmlWriterState_DocClosed; return S_OK; }
static HRESULT WINAPI xmlwriter_WriteAttributeString(IXmlWriter *iface, LPCWSTR ns_prefix, LPCWSTR local_name, LPCWSTR ns_uri, LPCWSTR value) { static const WCHAR eqW[] = {'=','"'}; xmlwriter *This = impl_from_IXmlWriter(iface); TRACE("%p %s %s %s %s\n", This, debugstr_w(ns_prefix), debugstr_w(local_name), debugstr_w(ns_uri), debugstr_w(value)); switch (This->state) { case XmlWriterState_Initial: return E_UNEXPECTED; case XmlWriterState_Ready: case XmlWriterState_DocClosed: This->state = XmlWriterState_DocClosed; return WR_E_INVALIDACTION; default: ; } if (ns_prefix || ns_uri) { FIXME("namespaces are not supported.\n"); return E_NOTIMPL; } write_output_buffer(This->output, spaceW, ARRAY_SIZE(spaceW)); write_output_buffer(This->output, local_name, -1); write_output_buffer(This->output, eqW, ARRAY_SIZE(eqW)); write_output_buffer(This->output, value, -1); write_output_buffer(This->output, quoteW, ARRAY_SIZE(quoteW)); return S_OK; }
static HRESULT WINAPI xmlwriter_WriteEndElement(IXmlWriter *iface) { xmlwriter *This = impl_from_IXmlWriter(iface); struct element *element; TRACE("%p\n", This); element = pop_element(This); if (!element) return WR_E_INVALIDACTION; if (This->starttagopen) { static WCHAR closetagW[] = {' ','/','>'}; write_output_buffer(This->output, closetagW, ARRAY_SIZE(closetagW)); This->starttagopen = FALSE; } else { /* write full end tag */ write_output_buffer(This->output, closeelementW, ARRAY_SIZE(closeelementW)); write_output_buffer(This->output, element->qname, element->len); write_output_buffer(This->output, gtW, ARRAY_SIZE(gtW)); } return S_OK; }
static HRESULT WINAPI xmlwriter_WriteElementString(IXmlWriter *iface, LPCWSTR prefix, LPCWSTR local_name, LPCWSTR uri, LPCWSTR value) { xmlwriter *This = impl_from_IXmlWriter(iface); TRACE("(%p)->(%s %s %s %s)\n", This, wine_dbgstr_w(prefix), wine_dbgstr_w(local_name), wine_dbgstr_w(uri), wine_dbgstr_w(value)); switch (This->state) { case XmlWriterState_Initial: return E_UNEXPECTED; case XmlWriterState_ElemStarted: writer_close_starttag(This); break; default: ; } write_encoding_bom(This); write_output_buffer(This->output, ltW, ARRAY_SIZE(ltW)); write_output_qname(This->output, prefix, local_name); write_output_buffer(This->output, gtW, ARRAY_SIZE(gtW)); if (value) write_output_buffer(This->output, value, -1); write_output_buffer(This->output, closeelementW, ARRAY_SIZE(closeelementW)); write_output_qname(This->output, prefix, local_name); write_output_buffer(This->output, gtW, ARRAY_SIZE(gtW)); This->state = XmlWriterState_Content; return S_OK; }
static HRESULT WINAPI xmlwriter_WriteRaw(IXmlWriter *iface, LPCWSTR data) { xmlwriter *This = impl_from_IXmlWriter(iface); TRACE("%p %s\n", This, debugstr_w(data)); if (!data) return S_OK; switch (This->state) { case XmlWriterState_Initial: return E_UNEXPECTED; case XmlWriterState_Ready: write_xmldecl(This, XmlStandalone_Omit); /* fallthrough */ case XmlWriterState_DocStarted: case XmlWriterState_PIDocStarted: break; default: This->state = XmlWriterState_DocClosed; return WR_E_INVALIDACTION; } write_output_buffer(This->output, data, -1); return S_OK; }
static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR prefix, LPCWSTR local_name, LPCWSTR uri) { xmlwriter *This = impl_from_IXmlWriter(iface); struct element *element; TRACE("(%p)->(%s %s %s)\n", This, wine_dbgstr_w(prefix), wine_dbgstr_w(local_name), wine_dbgstr_w(uri)); if (This->state == XmlWriterState_Initial) return E_UNEXPECTED; if (!local_name) return E_INVALIDARG; /* close pending element */ if (This->starttagopen) write_output_buffer(This->output, gtW, ARRAY_SIZE(gtW)); element = alloc_element(This, prefix, local_name); if (!element) return E_OUTOFMEMORY; write_encoding_bom(This); This->state = XmlWriterState_ElemStarted; This->starttagopen = TRUE; push_element(This, element); write_output_buffer(This->output, ltW, ARRAY_SIZE(ltW)); write_output_qname(This->output, prefix, local_name); return S_OK; }
static HRESULT WINAPI xmlwriter_GetProperty(IXmlWriter *iface, UINT property, LONG_PTR *value) { xmlwriter *This = impl_from_IXmlWriter(iface); TRACE("(%p)->(%s %p)\n", This, debugstr_writer_prop(property), value); if (!value) return E_INVALIDARG; switch (property) { case XmlWriterProperty_Indent: *value = This->indent; break; case XmlWriterProperty_ByteOrderMark: *value = This->bom; break; case XmlWriterProperty_OmitXmlDeclaration: *value = This->omitxmldecl; break; case XmlWriterProperty_ConformanceLevel: *value = This->conformance; break; default: FIXME("Unimplemented property (%u)\n", property); return E_NOTIMPL; } return S_OK; }
static HRESULT WINAPI xmlwriter_WriteFullEndElement(IXmlWriter *iface) { xmlwriter *This = impl_from_IXmlWriter(iface); struct element *element; TRACE("%p\n", This); switch (This->state) { case XmlWriterState_Initial: return E_UNEXPECTED; case XmlWriterState_Ready: case XmlWriterState_DocClosed: This->state = XmlWriterState_DocClosed; return WR_E_INVALIDACTION; default: ; } element = pop_element(This); if (!element) return WR_E_INVALIDACTION; /* write full end tag */ write_output_buffer(This->output, closeelementW, ARRAY_SIZE(closeelementW)); write_output_buffer(This->output, element->qname, element->len); write_output_buffer(This->output, gtW, ARRAY_SIZE(gtW)); This->starttagopen = FALSE; return S_OK; }
static HRESULT WINAPI xmlwriter_GetProperty(IXmlWriter *iface, UINT nProperty, LONG_PTR *ppValue) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p %u %p\n", This, nProperty, ppValue); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_WriteSurrogateCharEntity(IXmlWriter *iface, WCHAR wchLow, WCHAR wchHigh) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p %d %d\n", This, wchLow, wchHigh); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_WriteRawChars(IXmlWriter *iface, const WCHAR *pwch, UINT cwch) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p %s %d\n", This, wine_dbgstr_w(pwch), cwch); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_WriteWhitespace(IXmlWriter *iface, LPCWSTR pwszWhitespace) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p %s\n", This, wine_dbgstr_w(pwszWhitespace)); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_WriteFullEndElement(IXmlWriter *iface) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p\n", This); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_Flush(IXmlWriter *iface) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p\n", This); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_Flush(IXmlWriter *iface) { xmlwriter *This = impl_from_IXmlWriter(iface); TRACE("%p\n", This); return writeroutput_flush_stream(This->output); }
/*** IXmlWriter methods ***/ static HRESULT WINAPI xmlwriter_SetOutput(IXmlWriter *iface, IUnknown *pOutput) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p %p\n", This, pOutput); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_WriteStartDocument(IXmlWriter *iface, XmlStandalone standalone) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p\n", This); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_WriteProcessingInstruction(IXmlWriter *iface, LPCWSTR pwszName, LPCWSTR pwszText) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p %s %s\n", This, wine_dbgstr_w(pwszName), wine_dbgstr_w(pwszText)); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_WriteNodeShallow(IXmlWriter *iface, IXmlReader *pReader, BOOL fWriteDefaultAttributes) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p %p %d\n", This, pReader, fWriteDefaultAttributes); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_WriteQualifiedName(IXmlWriter *iface, LPCWSTR pwszLocalName, LPCWSTR pwszNamespaceUri) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p %s %s\n", This, wine_dbgstr_w(pwszLocalName), wine_dbgstr_w(pwszNamespaceUri)); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_WriteDocType(IXmlWriter *iface, LPCWSTR pwszName, LPCWSTR pwszPublicId, LPCWSTR pwszSystemId, LPCWSTR pwszSubset) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p %s %s %s %s\n", This, wine_dbgstr_w(pwszName), wine_dbgstr_w(pwszPublicId), wine_dbgstr_w(pwszSystemId), wine_dbgstr_w(pwszSubset)); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_WriteElementString(IXmlWriter *iface, LPCWSTR pwszPrefix, LPCWSTR pwszLocalName, LPCWSTR pwszNamespaceUri, LPCWSTR pwszValue) { xmlwriter *This = impl_from_IXmlWriter(iface); FIXME("%p %s %s %s %s\n", This, wine_dbgstr_w(pwszPrefix), wine_dbgstr_w(pwszLocalName), wine_dbgstr_w(pwszNamespaceUri), wine_dbgstr_w(pwszValue)); return E_NOTIMPL; }
static HRESULT WINAPI xmlwriter_WriteStartDocument(IXmlWriter *iface, XmlStandalone standalone) { static const WCHAR versionW[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"'}; static const WCHAR encodingW[] = {' ','e','n','c','o','d','i','n','g','='}; xmlwriter *This = impl_from_IXmlWriter(iface); TRACE("(%p)->(%d)\n", This, standalone); switch (This->state) { case XmlWriterState_Initial: return E_UNEXPECTED; case XmlWriterState_PIDocStarted: This->state = XmlWriterState_DocStarted; return S_OK; case XmlWriterState_DocStarted: case XmlWriterState_ElemStarted: case XmlWriterState_DocClosed: return WR_E_INVALIDACTION; default: ; } write_encoding_bom(This); This->state = XmlWriterState_DocStarted; if (This->omitxmldecl) return S_OK; /* version */ write_output_buffer(This->output, versionW, ARRAY_SIZE(versionW)); /* encoding */ write_output_buffer(This->output, encodingW, ARRAY_SIZE(encodingW)); write_output_buffer_quoted(This->output, get_encoding_name(This->output->encoding), -1); /* standalone */ if (standalone == XmlStandalone_Omit) write_output_buffer(This->output, closepiW, ARRAY_SIZE(closepiW)); else { static const WCHAR standaloneW[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'}; static const WCHAR yesW[] = {'y','e','s','\"','?','>'}; static const WCHAR noW[] = {'n','o','\"','?','>'}; write_output_buffer(This->output, standaloneW, ARRAY_SIZE(standaloneW)); if (standalone == XmlStandalone_Yes) write_output_buffer(This->output, yesW, ARRAY_SIZE(yesW)); else write_output_buffer(This->output, noW, ARRAY_SIZE(noW)); } return S_OK; }
static ULONG WINAPI xmlwriter_Release(IXmlWriter *iface) { xmlwriter *This = impl_from_IXmlWriter(iface); LONG ref; TRACE("%p\n", This); ref = InterlockedDecrement(&This->ref); if (ref == 0) { HeapFree(GetProcessHeap(), 0, This); } return ref; }
static HRESULT WINAPI xmlwriter_QueryInterface(IXmlWriter *iface, REFIID riid, void **ppvObject) { xmlwriter *This = impl_from_IXmlWriter(iface); TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IXmlWriter)) { *ppvObject = iface; } IXmlWriter_AddRef(iface); return S_OK; }
/*** IXmlWriter methods ***/ static HRESULT WINAPI xmlwriter_SetOutput(IXmlWriter *iface, IUnknown *output) { xmlwriter *This = impl_from_IXmlWriter(iface); IXmlWriterOutput *writeroutput; HRESULT hr; TRACE("(%p)->(%p)\n", This, output); if (This->output) { writeroutput_release_stream(This->output); IUnknown_Release(&This->output->IXmlWriterOutput_iface); This->output = NULL; This->bomwritten = FALSE; This->indent_level = 0; } /* just reset current output */ if (!output) { This->state = XmlWriterState_Initial; return S_OK; } /* now try IXmlWriterOutput, ISequentialStream, IStream */ hr = IUnknown_QueryInterface(output, &IID_IXmlWriterOutput, (void**)&writeroutput); if (hr == S_OK) { if (writeroutput->lpVtbl == &xmlwriteroutputvtbl) This->output = impl_from_IXmlWriterOutput(writeroutput); else { ERR("got external IXmlWriterOutput implementation: %p, vtbl=%p\n", writeroutput, writeroutput->lpVtbl); IUnknown_Release(writeroutput); return E_FAIL; } } if (hr != S_OK || !writeroutput) { /* create IXmlWriterOutput basing on supplied interface */ hr = CreateXmlWriterOutputWithEncodingName(output, This->imalloc, NULL, &writeroutput); if (hr != S_OK) return hr; This->output = impl_from_IXmlWriterOutput(writeroutput); } This->state = XmlWriterState_Ready; return writeroutput_query_for_stream(This->output); }
static HRESULT WINAPI xmlwriter_WriteCData(IXmlWriter *iface, LPCWSTR data) { xmlwriter *This = impl_from_IXmlWriter(iface); int len; TRACE("%p %s\n", This, debugstr_w(data)); switch (This->state) { case XmlWriterState_Initial: return E_UNEXPECTED; case XmlWriterState_ElemStarted: writer_close_starttag(This); break; case XmlWriterState_Ready: case XmlWriterState_DocClosed: This->state = XmlWriterState_DocClosed; return WR_E_INVALIDACTION; default: ; } len = data ? strlenW(data) : 0; write_node_indent(This); if (!len) write_cdata_section(This->output, NULL, 0); else { static const WCHAR cdatacloseW[] = {']',']','>',0}; while (len) { const WCHAR *str = strstrW(data, cdatacloseW); if (str) { str += 2; write_cdata_section(This->output, data, str - data); len -= str - data; data = str; } else { write_cdata_section(This->output, data, len); break; } } } return S_OK; }
static HRESULT WINAPI xmlwriter_WriteComment(IXmlWriter *iface, LPCWSTR comment) { static const WCHAR copenW[] = {'<','!','-','-'}; static const WCHAR ccloseW[] = {'-','-','>'}; xmlwriter *This = impl_from_IXmlWriter(iface); TRACE("%p %s\n", This, debugstr_w(comment)); switch (This->state) { case XmlWriterState_Initial: return E_UNEXPECTED; case XmlWriterState_ElemStarted: writer_close_starttag(This); break; case XmlWriterState_DocClosed: return WR_E_INVALIDACTION; default: ; } write_node_indent(This); write_output_buffer(This->output, copenW, ARRAY_SIZE(copenW)); if (comment) { int len = strlenW(comment), i; /* Make sure there's no two hyphen sequences in a string, space is used as a separator to produce compliant comment string */ if (len > 1) { for (i = 0; i < len; i++) { write_output_buffer(This->output, comment + i, 1); if (comment[i] == '-' && (i + 1 < len) && comment[i+1] == '-') write_output_buffer(This->output, spaceW, ARRAY_SIZE(spaceW)); } } else write_output_buffer(This->output, comment, len); if (len && comment[len-1] == '-') write_output_buffer(This->output, spaceW, ARRAY_SIZE(spaceW)); } write_output_buffer(This->output, ccloseW, ARRAY_SIZE(ccloseW)); return S_OK; }