xmllite/writer: Initial support for indented output.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
fc1563591f
commit
c52fa73a43
|
@ -1006,6 +1006,54 @@ static void test_writer_state(void)
|
||||||
IXmlWriter_Release(writer);
|
IXmlWriter_Release(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_indentation(void)
|
||||||
|
{
|
||||||
|
static const WCHAR commentW[] = {'c','o','m','m','e','n','t',0};
|
||||||
|
static const WCHAR aW[] = {'a',0};
|
||||||
|
static const WCHAR bW[] = {'b',0};
|
||||||
|
IXmlWriter *writer;
|
||||||
|
IStream *stream;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
|
||||||
|
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
|
||||||
|
|
||||||
|
stream = writer_set_output(writer);
|
||||||
|
|
||||||
|
hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, TRUE);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_Indent, TRUE);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IXmlWriter_WriteComment(writer, commentW);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IXmlWriter_WriteEndDocument(writer);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IXmlWriter_Flush(writer);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
CHECK_OUTPUT(stream,
|
||||||
|
"<a>\r\n"
|
||||||
|
" <!--comment-->\r\n"
|
||||||
|
" <b />\r\n"
|
||||||
|
"</a>");
|
||||||
|
|
||||||
|
IXmlWriter_Release(writer);
|
||||||
|
IStream_Release(stream);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(writer)
|
START_TEST(writer)
|
||||||
{
|
{
|
||||||
test_writer_create();
|
test_writer_create();
|
||||||
|
@ -1021,4 +1069,5 @@ START_TEST(writer)
|
||||||
test_WriteComment();
|
test_WriteComment();
|
||||||
test_WriteCData();
|
test_WriteCData();
|
||||||
test_WriteRaw();
|
test_WriteRaw();
|
||||||
|
test_indentation();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* IXmlWriter implementation
|
* IXmlWriter implementation
|
||||||
*
|
*
|
||||||
* Copyright 2011 Alistair Leslie-Hughes
|
* Copyright 2011 Alistair Leslie-Hughes
|
||||||
* Copyright 2014 Nikolay Sivov for CodeWeavers
|
* Copyright 2014, 2016 Nikolay Sivov for CodeWeavers
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -90,6 +90,7 @@ typedef struct _xmlwriter
|
||||||
LONG ref;
|
LONG ref;
|
||||||
IMalloc *imalloc;
|
IMalloc *imalloc;
|
||||||
xmlwriteroutput *output;
|
xmlwriteroutput *output;
|
||||||
|
unsigned int indent_level;
|
||||||
BOOL indent;
|
BOOL indent;
|
||||||
BOOL bom;
|
BOOL bom;
|
||||||
BOOL omitxmldecl;
|
BOOL omitxmldecl;
|
||||||
|
@ -417,6 +418,32 @@ static HRESULT writer_close_starttag(xmlwriter *writer)
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void writer_inc_indent(xmlwriter *writer)
|
||||||
|
{
|
||||||
|
writer->indent_level++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writer_dec_indent(xmlwriter *writer)
|
||||||
|
{
|
||||||
|
if (writer->indent_level)
|
||||||
|
writer->indent_level--;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_node_indent(xmlwriter *writer)
|
||||||
|
{
|
||||||
|
static const WCHAR dblspaceW[] = {' ',' '};
|
||||||
|
static const WCHAR crlfW[] = {'\r','\n'};
|
||||||
|
unsigned int indent_level = writer->indent_level;
|
||||||
|
|
||||||
|
if (!writer->indent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (writer->output->buffer.written)
|
||||||
|
write_output_buffer(writer->output, crlfW, ARRAY_SIZE(crlfW));
|
||||||
|
while (indent_level--)
|
||||||
|
write_output_buffer(writer->output, dblspaceW, ARRAY_SIZE(dblspaceW));
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI xmlwriter_QueryInterface(IXmlWriter *iface, REFIID riid, void **ppvObject)
|
static HRESULT WINAPI xmlwriter_QueryInterface(IXmlWriter *iface, REFIID riid, void **ppvObject)
|
||||||
{
|
{
|
||||||
xmlwriter *This = impl_from_IXmlWriter(iface);
|
xmlwriter *This = impl_from_IXmlWriter(iface);
|
||||||
|
@ -483,6 +510,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 = FALSE;
|
This->bomwritten = FALSE;
|
||||||
|
This->indent_level = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* just reset current output */
|
/* just reset current output */
|
||||||
|
@ -554,6 +582,9 @@ static HRESULT WINAPI xmlwriter_SetProperty(IXmlWriter *iface, UINT property, LO
|
||||||
|
|
||||||
switch (property)
|
switch (property)
|
||||||
{
|
{
|
||||||
|
case XmlWriterProperty_Indent:
|
||||||
|
This->indent = !!value;
|
||||||
|
break;
|
||||||
case XmlWriterProperty_ByteOrderMark:
|
case XmlWriterProperty_ByteOrderMark:
|
||||||
This->bom = !!value;
|
This->bom = !!value;
|
||||||
break;
|
break;
|
||||||
|
@ -636,6 +667,7 @@ static HRESULT WINAPI xmlwriter_WriteCData(IXmlWriter *iface, LPCWSTR data)
|
||||||
|
|
||||||
len = data ? strlenW(data) : 0;
|
len = data ? strlenW(data) : 0;
|
||||||
|
|
||||||
|
write_node_indent(This);
|
||||||
if (!len)
|
if (!len)
|
||||||
write_cdata_section(This->output, NULL, 0);
|
write_cdata_section(This->output, NULL, 0);
|
||||||
else {
|
else {
|
||||||
|
@ -696,6 +728,7 @@ static HRESULT WINAPI xmlwriter_WriteChars(IXmlWriter *iface, const WCHAR *pwch,
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static HRESULT WINAPI xmlwriter_WriteComment(IXmlWriter *iface, LPCWSTR comment)
|
static HRESULT WINAPI xmlwriter_WriteComment(IXmlWriter *iface, LPCWSTR comment)
|
||||||
{
|
{
|
||||||
static const WCHAR copenW[] = {'<','!','-','-'};
|
static const WCHAR copenW[] = {'<','!','-','-'};
|
||||||
|
@ -717,6 +750,7 @@ static HRESULT WINAPI xmlwriter_WriteComment(IXmlWriter *iface, LPCWSTR comment)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write_node_indent(This);
|
||||||
write_output_buffer(This->output, copenW, ARRAY_SIZE(copenW));
|
write_output_buffer(This->output, copenW, ARRAY_SIZE(copenW));
|
||||||
if (comment) {
|
if (comment) {
|
||||||
int len = strlenW(comment), i;
|
int len = strlenW(comment), i;
|
||||||
|
@ -841,6 +875,8 @@ static HRESULT WINAPI xmlwriter_WriteEndElement(IXmlWriter *iface)
|
||||||
if (!element)
|
if (!element)
|
||||||
return WR_E_INVALIDACTION;
|
return WR_E_INVALIDACTION;
|
||||||
|
|
||||||
|
writer_dec_indent(This);
|
||||||
|
|
||||||
if (This->starttagopen) {
|
if (This->starttagopen) {
|
||||||
static WCHAR closetagW[] = {' ','/','>'};
|
static WCHAR closetagW[] = {' ','/','>'};
|
||||||
write_output_buffer(This->output, closetagW, ARRAY_SIZE(closetagW));
|
write_output_buffer(This->output, closetagW, ARRAY_SIZE(closetagW));
|
||||||
|
@ -848,6 +884,7 @@ static HRESULT WINAPI xmlwriter_WriteEndElement(IXmlWriter *iface)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* write full end tag */
|
/* write full end tag */
|
||||||
|
write_node_indent(This);
|
||||||
write_output_buffer(This->output, closeelementW, ARRAY_SIZE(closeelementW));
|
write_output_buffer(This->output, closeelementW, ARRAY_SIZE(closeelementW));
|
||||||
write_output_buffer(This->output, element->qname, element->len);
|
write_output_buffer(This->output, element->qname, element->len);
|
||||||
write_output_buffer(This->output, gtW, ARRAY_SIZE(gtW));
|
write_output_buffer(This->output, gtW, ARRAY_SIZE(gtW));
|
||||||
|
@ -994,6 +1031,7 @@ static HRESULT WINAPI xmlwriter_WriteProcessingInstruction(IXmlWriter *iface, LP
|
||||||
}
|
}
|
||||||
|
|
||||||
write_encoding_bom(This);
|
write_encoding_bom(This);
|
||||||
|
write_node_indent(This);
|
||||||
write_output_buffer(This->output, openpiW, ARRAY_SIZE(openpiW));
|
write_output_buffer(This->output, openpiW, ARRAY_SIZE(openpiW));
|
||||||
write_output_buffer(This->output, name, -1);
|
write_output_buffer(This->output, name, -1);
|
||||||
write_output_buffer(This->output, spaceW, ARRAY_SIZE(spaceW));
|
write_output_buffer(This->output, spaceW, ARRAY_SIZE(spaceW));
|
||||||
|
@ -1130,8 +1168,10 @@ static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR pre
|
||||||
|
|
||||||
push_element(This, element);
|
push_element(This, element);
|
||||||
|
|
||||||
|
write_node_indent(This);
|
||||||
write_output_buffer(This->output, ltW, ARRAY_SIZE(ltW));
|
write_output_buffer(This->output, ltW, ARRAY_SIZE(ltW));
|
||||||
write_output_qname(This->output, prefix, local_name);
|
write_output_qname(This->output, prefix, local_name);
|
||||||
|
writer_inc_indent(This);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -1302,6 +1342,7 @@ HRESULT WINAPI CreateXmlWriter(REFIID riid, void **obj, IMalloc *imalloc)
|
||||||
writer->imalloc = imalloc;
|
writer->imalloc = imalloc;
|
||||||
if (imalloc) IMalloc_AddRef(imalloc);
|
if (imalloc) IMalloc_AddRef(imalloc);
|
||||||
writer->output = NULL;
|
writer->output = NULL;
|
||||||
|
writer->indent_level = 0;
|
||||||
writer->indent = FALSE;
|
writer->indent = FALSE;
|
||||||
writer->bom = TRUE;
|
writer->bom = TRUE;
|
||||||
writer->omitxmldecl = FALSE;
|
writer->omitxmldecl = FALSE;
|
||||||
|
|
Loading…
Reference in New Issue