Module: wine Branch: master Commit: 9c988e7b0e4c4cd63846f050dfa91990474629ff URL: http://source.winehq.org/git/wine.git/?a=commit;h=9c988e7b0e4c4cd63846f050df...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Fri Mar 3 14:14:34 2017 +0300
xmllite/writer: Implement WriteString().
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/xmllite/tests/writer.c | 86 ++++++++++++++++++++++++++++++++++++++++++--- dlls/xmllite/writer.c | 40 +++++++++++++++++++-- 2 files changed, 119 insertions(+), 7 deletions(-)
diff --git a/dlls/xmllite/tests/writer.c b/dlls/xmllite/tests/writer.c index 661b837..2a97a75 100644 --- a/dlls/xmllite/tests/writer.c +++ b/dlls/xmllite/tests/writer.c @@ -33,10 +33,10 @@ DEFINE_GUID(IID_IXmlWriterOutput, 0xc1131708, 0x0f59, 0x477f, 0x93, 0x59, 0x7d,
static void check_output(IStream *stream, const char *expected, BOOL todo, int line) { - HGLOBAL hglobal; int len = strlen(expected), size; - char *ptr; + HGLOBAL hglobal; HRESULT hr; + char *ptr;
hr = GetHGlobalFromStream(stream, &hglobal); ok_(__FILE__, line)(hr == S_OK, "got 0x%08x\n", hr); @@ -48,10 +48,10 @@ static void check_output(IStream *stream, const char *expected, BOOL todo, int l if (size != len) { ok_(__FILE__, line)(0, "data size mismatch, expected %u, got %u\n", len, size); - ok_(__FILE__, line)(0, "got %s, expected %s\n", ptr, expected); + ok_(__FILE__, line)(0, "got |%s|, expected |%s|\n", ptr, expected); } else - ok_(__FILE__, line)(!strncmp(ptr, expected, len), "got %s, expected %s\n", ptr, expected); + ok_(__FILE__, line)(!strncmp(ptr, expected, len), "got |%s|, expected |%s|\n", ptr, expected); } GlobalUnlock(hglobal); } @@ -1258,6 +1258,83 @@ static void test_WriteCharEntity(void) IStream_Release(stream); }
+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; + + hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + + hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, TRUE); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteString(writer, aW); + ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteString(writer, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteString(writer, emptyW); + ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr); + + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteString(writer, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteString(writer, emptyW); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteString(writer, aW); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* WriteString automatically escapes markup characters */ + hr = IXmlWriter_WriteString(writer, markupW); + 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, + "<b>a<&">="); + IStream_Release(stream); + + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteString(writer, NULL); + 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, + "<b"); + + hr = IXmlWriter_WriteString(writer, emptyW); + 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, + "<b>"); + + IXmlWriter_Release(writer); + IStream_Release(stream); +} + START_TEST(writer) { test_writer_create(); @@ -1277,4 +1354,5 @@ START_TEST(writer) test_WriteAttributeString(); test_WriteFullEndElement(); test_WriteCharEntity(); + test_WriteString(); } diff --git a/dlls/xmllite/writer.c b/dlls/xmllite/writer.c index f7f2604..55a53a6 100644 --- a/dlls/xmllite/writer.c +++ b/dlls/xmllite/writer.c @@ -1203,16 +1203,49 @@ static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR pre return S_OK; }
-static HRESULT WINAPI xmlwriter_WriteString(IXmlWriter *iface, LPCWSTR pwszText) +static void write_escaped_string(xmlwriter *writer, const WCHAR *string) +{ + static const WCHAR ampW[] = {'&','a','m','p',';'}; + static const WCHAR ltW[] = {'&','l','t',';'}; + static const WCHAR gtW[] = {'&','g','t',';'}; + + while (*string) + { + switch (*string) + { + case '<': + write_output_buffer(writer->output, ltW, ARRAY_SIZE(ltW)); + break; + case '&': + write_output_buffer(writer->output, ampW, ARRAY_SIZE(ampW)); + break; + case '>': + write_output_buffer(writer->output, gtW, ARRAY_SIZE(gtW)); + break; + default: + write_output_buffer(writer->output, string, 1); + } + + string++; + } +} + +static HRESULT WINAPI xmlwriter_WriteString(IXmlWriter *iface, const WCHAR *string) { xmlwriter *This = impl_from_IXmlWriter(iface);
- FIXME("%p %s\n", This, wine_dbgstr_w(pwszText)); + TRACE("%p %s\n", This, debugstr_w(string)); + + if (!string) + return S_OK;
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; @@ -1221,7 +1254,8 @@ static HRESULT WINAPI xmlwriter_WriteString(IXmlWriter *iface, LPCWSTR pwszText) ; }
- return E_NOTIMPL; + write_escaped_string(This, string); + return S_OK; }
static HRESULT WINAPI xmlwriter_WriteSurrogateCharEntity(IXmlWriter *iface, WCHAR wchLow, WCHAR wchHigh)