Commit ef7b911a authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

xmllite/writer: Fix formatted output with interleaving text nodes.

parent 9784ef16
...@@ -1981,6 +1981,93 @@ static void test_WriteString(void) ...@@ -1981,6 +1981,93 @@ static void test_WriteString(void)
" <b>text</b>\r\n" " <b>text</b>\r\n"
"</a>"); "</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); IXmlWriter_Release(writer);
IStream_Release(stream); IStream_Release(stream);
} }
......
...@@ -118,6 +118,7 @@ typedef struct _xmlwriter ...@@ -118,6 +118,7 @@ typedef struct _xmlwriter
struct list elements; struct list elements;
DWORD bomwritten : 1; DWORD bomwritten : 1;
DWORD starttagopen : 1; DWORD starttagopen : 1;
DWORD textnode : 1;
} xmlwriter; } xmlwriter;
static inline xmlwriter *impl_from_IXmlWriter(IXmlWriter *iface) static inline xmlwriter *impl_from_IXmlWriter(IXmlWriter *iface)
...@@ -626,8 +627,11 @@ static void write_node_indent(xmlwriter *writer) ...@@ -626,8 +627,11 @@ static void write_node_indent(xmlwriter *writer)
static const WCHAR crlfW[] = {'\r','\n'}; static const WCHAR crlfW[] = {'\r','\n'};
unsigned int indent_level = writer->indent_level; unsigned int indent_level = writer->indent_level;
if (!writer->indent) if (!writer->indent || writer->textnode)
{
writer->textnode = 0;
return; return;
}
/* Do state check to prevent newline inserted after BOM. It is assumed that /* Do state check to prevent newline inserted after BOM. It is assumed that
state does not change between writing BOM and inserting indentation. */ state does not change between writing BOM and inserting indentation. */
...@@ -635,6 +639,8 @@ static void write_node_indent(xmlwriter *writer) ...@@ -635,6 +639,8 @@ static void write_node_indent(xmlwriter *writer)
write_output_buffer(writer->output, crlfW, ARRAY_SIZE(crlfW)); write_output_buffer(writer->output, crlfW, ARRAY_SIZE(crlfW));
while (indent_level--) while (indent_level--)
write_output_buffer(writer->output, dblspaceW, ARRAY_SIZE(dblspaceW)); write_output_buffer(writer->output, dblspaceW, ARRAY_SIZE(dblspaceW));
writer->textnode = 0;
} }
static HRESULT WINAPI xmlwriter_QueryInterface(IXmlWriter *iface, REFIID riid, void **ppvObject) static HRESULT WINAPI xmlwriter_QueryInterface(IXmlWriter *iface, REFIID riid, void **ppvObject)
...@@ -704,6 +710,7 @@ static HRESULT WINAPI xmlwriter_SetOutput(IXmlWriter *iface, IUnknown *output) ...@@ -704,6 +710,7 @@ static HRESULT WINAPI xmlwriter_SetOutput(IXmlWriter *iface, IUnknown *output)
IUnknown_Release(&This->output->IXmlWriterOutput_iface); IUnknown_Release(&This->output->IXmlWriterOutput_iface);
This->output = NULL; This->output = NULL;
This->bomwritten = 0; This->bomwritten = 0;
This->textnode = 0;
This->indent_level = 0; This->indent_level = 0;
writer_free_element_stack(This); writer_free_element_stack(This);
} }
...@@ -1281,7 +1288,10 @@ static HRESULT WINAPI xmlwriter_WriteFullEndElement(IXmlWriter *iface) ...@@ -1281,7 +1288,10 @@ static HRESULT WINAPI xmlwriter_WriteFullEndElement(IXmlWriter *iface)
/* don't force full end tag to the next line */ /* don't force full end tag to the next line */
if (This->state == XmlWriterState_ElemStarted) if (This->state == XmlWriterState_ElemStarted)
{
This->state = XmlWriterState_Content; This->state = XmlWriterState_Content;
This->textnode = 0;
}
else else
write_node_indent(This); write_node_indent(This);
...@@ -1623,6 +1633,7 @@ static HRESULT WINAPI xmlwriter_WriteString(IXmlWriter *iface, const WCHAR *stri ...@@ -1623,6 +1633,7 @@ static HRESULT WINAPI xmlwriter_WriteString(IXmlWriter *iface, const WCHAR *stri
; ;
} }
This->textnode = 1;
write_escaped_string(This, string); write_escaped_string(This, string);
return S_OK; return S_OK;
} }
...@@ -1761,21 +1772,18 @@ HRESULT WINAPI CreateXmlWriter(REFIID riid, void **obj, IMalloc *imalloc) ...@@ -1761,21 +1772,18 @@ HRESULT WINAPI CreateXmlWriter(REFIID riid, void **obj, IMalloc *imalloc)
writer = IMalloc_Alloc(imalloc, sizeof(*writer)); writer = IMalloc_Alloc(imalloc, sizeof(*writer));
else else
writer = heap_alloc(sizeof(*writer)); 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->IXmlWriter_iface.lpVtbl = &xmlwriter_vtbl;
writer->ref = 1; writer->ref = 1;
writer->imalloc = imalloc; writer->imalloc = imalloc;
if (imalloc) IMalloc_AddRef(imalloc); if (imalloc) IMalloc_AddRef(imalloc);
writer->output = NULL;
writer->indent_level = 0;
writer->indent = FALSE;
writer->bom = TRUE; writer->bom = TRUE;
writer->omitxmldecl = FALSE;
writer->conformance = XmlConformanceLevel_Document; writer->conformance = XmlConformanceLevel_Document;
writer->state = XmlWriterState_Initial; writer->state = XmlWriterState_Initial;
writer->bomwritten = 0;
writer->starttagopen = 0;
list_init(&writer->elements); list_init(&writer->elements);
hr = IXmlWriter_QueryInterface(&writer->IXmlWriter_iface, riid, obj); hr = IXmlWriter_QueryInterface(&writer->IXmlWriter_iface, riid, obj);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment