From 9784ef163379295579e5b3b679e63996e9435c4e Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 14 Sep 2018 13:06:46 +0300 Subject: [PATCH] xmllite/writer: Fix formatted output for closing tags. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/xmllite/tests/writer.c | 88 ++++++++++++++++++++++++++++++------- dlls/xmllite/writer.c | 21 +++++---- 2 files changed, 85 insertions(+), 24 deletions(-) diff --git a/dlls/xmllite/tests/writer.c b/dlls/xmllite/tests/writer.c index 1710462deb9..42b534f2693 100644 --- a/dlls/xmllite/tests/writer.c +++ b/dlls/xmllite/tests/writer.c @@ -881,6 +881,20 @@ static HRESULT write_element_string(IXmlWriter *writer, const char *prefix, cons return hr; } +static HRESULT write_string(IXmlWriter *writer, const char *str) +{ + WCHAR *strW; + HRESULT hr; + + strW = strdupAtoW(str); + + hr = IXmlWriter_WriteString(writer, strW); + + heap_free(strW); + + return hr; +} + static void test_WriteStartElement(void) { static const struct @@ -1853,10 +1867,6 @@ static void test_WriteCharEntity(void) static void test_WriteString(void) { - static const WCHAR markupW[] = {'<','&','"','>','=',0}; - static const WCHAR aW[] = {'a',0}; - static const WCHAR bW[] = {'b',0}; - static const WCHAR emptyW[] = {0}; IXmlWriter *writer; IStream *stream; HRESULT hr; @@ -1866,31 +1876,31 @@ static void test_WriteString(void) writer_set_property(writer, XmlWriterProperty_OmitXmlDeclaration); - hr = IXmlWriter_WriteString(writer, aW); + hr = write_string(writer, "a"); ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr); - hr = IXmlWriter_WriteString(writer, NULL); + hr = write_string(writer, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); - hr = IXmlWriter_WriteString(writer, emptyW); + hr = write_string(writer, ""); ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr); stream = writer_set_output(writer); - hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL); + hr = write_start_element(writer, NULL, "b", NULL); ok(hr == S_OK, "got 0x%08x\n", hr); - hr = IXmlWriter_WriteString(writer, NULL); + hr = write_string(writer, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); - hr = IXmlWriter_WriteString(writer, emptyW); + hr = write_string(writer, ""); ok(hr == S_OK, "got 0x%08x\n", hr); - hr = IXmlWriter_WriteString(writer, aW); + hr = write_string(writer, "a"); ok(hr == S_OK, "got 0x%08x\n", hr); /* WriteString automatically escapes markup characters */ - hr = IXmlWriter_WriteString(writer, markupW); + hr = write_string(writer, "<&\">="); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IXmlWriter_Flush(writer); @@ -1902,10 +1912,10 @@ static void test_WriteString(void) stream = writer_set_output(writer); - hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL); + hr = write_start_element(writer, NULL, "b", NULL); ok(hr == S_OK, "got 0x%08x\n", hr); - hr = IXmlWriter_WriteString(writer, NULL); + hr = write_string(writer, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IXmlWriter_Flush(writer); @@ -1914,7 +1924,7 @@ static void test_WriteString(void) CHECK_OUTPUT(stream, ""); + IStream_Release(stream); + IXmlWriter_Release(writer); + + /* With indentation */ + hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL); + ok(hr == S_OK, "Failed to create a writer, hr %#x.\n", hr); + + stream = writer_set_output(writer); + + writer_set_property(writer, XmlWriterProperty_Indent); + + 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 = 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, + "\r\n" + " text"); + + hr = IXmlWriter_WriteFullEndElement(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, + "\r\n" + " text"); + + hr = IXmlWriter_WriteFullEndElement(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, + "\r\n" + " text\r\n" + ""); + IXmlWriter_Release(writer); IStream_Release(stream); } diff --git a/dlls/xmllite/writer.c b/dlls/xmllite/writer.c index 92217b8a4d3..94e1f2f8a87 100644 --- a/dlls/xmllite/writer.c +++ b/dlls/xmllite/writer.c @@ -80,6 +80,7 @@ typedef struct xml_encoding encoding; WCHAR *encoding_name; /* exactly as specified on output creation */ struct output_buffer buffer; + DWORD written : 1; } xmlwriteroutput; static const struct IUnknownVtbl xmlwriteroutputvtbl; @@ -114,9 +115,9 @@ typedef struct _xmlwriter BOOL omitxmldecl; XmlConformanceLevel conformance; XmlWriterState state; - BOOL bomwritten; - BOOL starttagopen; struct list elements; + DWORD bomwritten : 1; + DWORD starttagopen : 1; } xmlwriter; static inline xmlwriter *impl_from_IXmlWriter(IXmlWriter *iface) @@ -438,6 +439,7 @@ static HRESULT write_output_buffer(xmlwriteroutput *output, const WCHAR *data, i length = WideCharToMultiByte(buffer->codepage, 0, data, len, ptr, length, NULL, NULL); buffer->written += len == -1 ? length-1 : length; } + output->written = length != 0; return S_OK; } @@ -603,7 +605,7 @@ static HRESULT writer_close_starttag(xmlwriter *writer) writer_output_ns(writer, LIST_ENTRY(list_head(&writer->elements), struct element, entry)); hr = write_output_buffer(writer->output, gtW, ARRAY_SIZE(gtW)); - writer->starttagopen = FALSE; + writer->starttagopen = 0; return hr; } @@ -629,7 +631,7 @@ static void write_node_indent(xmlwriter *writer) /* Do state check to prevent newline inserted after BOM. It is assumed that state does not change between writing BOM and inserting indentation. */ - if (writer->output->buffer.written && writer->state != XmlWriterState_Ready) + if (writer->output->written && writer->state != XmlWriterState_Ready) write_output_buffer(writer->output, crlfW, ARRAY_SIZE(crlfW)); while (indent_level--) write_output_buffer(writer->output, dblspaceW, ARRAY_SIZE(dblspaceW)); @@ -701,7 +703,7 @@ static HRESULT WINAPI xmlwriter_SetOutput(IXmlWriter *iface, IUnknown *output) writeroutput_release_stream(This->output); IUnknown_Release(&This->output->IXmlWriterOutput_iface); This->output = NULL; - This->bomwritten = FALSE; + This->bomwritten = 0; This->indent_level = 0; writer_free_element_stack(This); } @@ -1211,7 +1213,7 @@ static HRESULT WINAPI xmlwriter_WriteEndElement(IXmlWriter *iface) { writer_output_ns(This, element); write_output_buffer(This->output, closetagW, ARRAY_SIZE(closetagW)); - This->starttagopen = FALSE; + This->starttagopen = 0; } else { @@ -1551,7 +1553,7 @@ static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR pre write_node_indent(This); This->state = XmlWriterState_ElemStarted; - This->starttagopen = TRUE; + This->starttagopen = 1; writer_push_element(This, element); @@ -1772,8 +1774,8 @@ HRESULT WINAPI CreateXmlWriter(REFIID riid, void **obj, IMalloc *imalloc) writer->omitxmldecl = FALSE; writer->conformance = XmlConformanceLevel_Document; writer->state = XmlWriterState_Initial; - writer->bomwritten = FALSE; - writer->starttagopen = FALSE; + writer->bomwritten = 0; + writer->starttagopen = 0; list_init(&writer->elements); hr = IXmlWriter_QueryInterface(&writer->IXmlWriter_iface, riid, obj); @@ -1819,6 +1821,7 @@ static HRESULT create_writer_output(IUnknown *stream, IMalloc *imalloc, xml_enco } else writeroutput->encoding_name = NULL; + writeroutput->written = 0; IUnknown_QueryInterface(stream, &IID_IUnknown, (void**)&writeroutput->output);