Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/xmllite/tests/writer.c | 87 +++++++++++++++++++++++++++++++++++++ dlls/xmllite/writer.c | 24 ++++++---- 2 files changed, 103 insertions(+), 8 deletions(-)
diff --git a/dlls/xmllite/tests/writer.c b/dlls/xmllite/tests/writer.c index 42b534f269..7f731be211 100644 --- a/dlls/xmllite/tests/writer.c +++ b/dlls/xmllite/tests/writer.c @@ -1981,6 +1981,93 @@ static void test_WriteString(void) " <b>text</b>\r\n" "</a>");
+ IStream_Release(stream); + + stream = writer_set_output(writer); + + hr = write_start_element(writer, NULL, "a", NULL); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_start_element(writer, NULL, "b", NULL); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = IXmlWriter_WriteEndElement(writer); + ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b />"); + + hr = write_start_element(writer, NULL, "c", NULL); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_attribute_string(writer, NULL, "attr", NULL, "value"); + ok(hr == S_OK, "Failed to write attribute string, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b />\r\n" + " <c attr="value""); + + hr = write_string(writer, "text"); + ok(hr == S_OK, "Failed to write a string, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b />\r\n" + " <c attr="value">text"); + + hr = IXmlWriter_WriteEndElement(writer); + ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b />\r\n" + " <c attr="value">text</c>"); + + hr = write_start_element(writer, NULL, "d", NULL); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_string(writer, ""); + ok(hr == S_OK, "Failed to write a string, hr %#x.\n", hr); + + hr = IXmlWriter_WriteEndElement(writer); + ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b />\r\n" + " <c attr="value">text</c>\r\n" + " <d></d>"); + + hr = IXmlWriter_WriteEndElement(writer); + ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b />\r\n" + " <c attr="value">text</c>\r\n" + " <d></d>\r\n" + "</a>"); + IXmlWriter_Release(writer); IStream_Release(stream); } diff --git a/dlls/xmllite/writer.c b/dlls/xmllite/writer.c index 94e1f2f8a8..f0eac777ca 100644 --- a/dlls/xmllite/writer.c +++ b/dlls/xmllite/writer.c @@ -118,6 +118,7 @@ typedef struct _xmlwriter struct list elements; DWORD bomwritten : 1; DWORD starttagopen : 1; + DWORD textnode : 1; } xmlwriter;
static inline xmlwriter *impl_from_IXmlWriter(IXmlWriter *iface) @@ -626,8 +627,11 @@ static void write_node_indent(xmlwriter *writer) static const WCHAR crlfW[] = {'\r','\n'}; unsigned int indent_level = writer->indent_level;
- if (!writer->indent) + if (!writer->indent || writer->textnode) + { + writer->textnode = 0; return; + }
/* Do state check to prevent newline inserted after BOM. It is assumed that state does not change between writing BOM and inserting indentation. */ @@ -635,6 +639,8 @@ static void write_node_indent(xmlwriter *writer) write_output_buffer(writer->output, crlfW, ARRAY_SIZE(crlfW)); while (indent_level--) write_output_buffer(writer->output, dblspaceW, ARRAY_SIZE(dblspaceW)); + + writer->textnode = 0; }
static HRESULT WINAPI xmlwriter_QueryInterface(IXmlWriter *iface, REFIID riid, void **ppvObject) @@ -704,6 +710,7 @@ static HRESULT WINAPI xmlwriter_SetOutput(IXmlWriter *iface, IUnknown *output) IUnknown_Release(&This->output->IXmlWriterOutput_iface); This->output = NULL; This->bomwritten = 0; + This->textnode = 0; This->indent_level = 0; writer_free_element_stack(This); } @@ -1281,7 +1288,10 @@ static HRESULT WINAPI xmlwriter_WriteFullEndElement(IXmlWriter *iface)
/* don't force full end tag to the next line */ if (This->state == XmlWriterState_ElemStarted) + { This->state = XmlWriterState_Content; + This->textnode = 0; + } else write_node_indent(This);
@@ -1623,6 +1633,7 @@ static HRESULT WINAPI xmlwriter_WriteString(IXmlWriter *iface, const WCHAR *stri ; }
+ This->textnode = 1; write_escaped_string(This, string); return S_OK; } @@ -1761,21 +1772,18 @@ HRESULT WINAPI CreateXmlWriter(REFIID riid, void **obj, IMalloc *imalloc) writer = IMalloc_Alloc(imalloc, sizeof(*writer)); else writer = heap_alloc(sizeof(*writer)); - if(!writer) return E_OUTOFMEMORY; + if (!writer) + return E_OUTOFMEMORY; + + memset(writer, 0, sizeof(*writer));
writer->IXmlWriter_iface.lpVtbl = &xmlwriter_vtbl; writer->ref = 1; writer->imalloc = imalloc; if (imalloc) IMalloc_AddRef(imalloc); - writer->output = NULL; - writer->indent_level = 0; - writer->indent = FALSE; writer->bom = TRUE; - writer->omitxmldecl = FALSE; writer->conformance = XmlConformanceLevel_Document; writer->state = XmlWriterState_Initial; - writer->bomwritten = 0; - writer->starttagopen = 0; list_init(&writer->elements);
hr = IXmlWriter_QueryInterface(&writer->IXmlWriter_iface, riid, obj);