[PATCH] xmllite/writer: Implement WriteString()

Nikolay Sivov nsivov at codeweavers.com
Fri Mar 3 05:14:34 CST 2017


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 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 661b837990..2a97a75db9 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 f7f2604f3d..55a53a65e7 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)
-- 
2.11.0




More information about the wine-patches mailing list