Nikolay Sivov : xmllite/writer: Implement WriteEndDocument().

Alexandre Julliard julliard at wine.codeweavers.com
Wed May 20 10:04:11 CDT 2015


Module: wine
Branch: master
Commit: aadd9ff1599c3addcf81c63e676a12a65b37ceec
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=aadd9ff1599c3addcf81c63e676a12a65b37ceec

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Tue May 19 21:59:59 2015 +0300

xmllite/writer: Implement WriteEndDocument().

---

 dlls/xmllite/tests/writer.c | 67 +++++++++++++++++++++++++++++++++++++++++++++
 dlls/xmllite/writer.c       | 44 ++++++++++++++++++++++++++---
 2 files changed, 107 insertions(+), 4 deletions(-)

diff --git a/dlls/xmllite/tests/writer.c b/dlls/xmllite/tests/writer.c
index 984a34d..d81a934 100644
--- a/dlls/xmllite/tests/writer.c
+++ b/dlls/xmllite/tests/writer.c
@@ -670,6 +670,72 @@ static void test_writeendelement(void)
     IStream_Release(stream);
 }
 
+static void test_writeenddocument(void)
+{
+    static const WCHAR aW[] = {'a',0};
+    static const WCHAR bW[] = {'b',0};
+    IXmlWriter *writer;
+    IStream *stream;
+    HGLOBAL hglobal;
+    HRESULT hr;
+    char *ptr;
+
+    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = pCreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+
+    hr = IXmlWriter_WriteEndDocument(writer);
+    ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
+
+    hr = IXmlWriter_SetOutput(writer, (IUnknown*)stream);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    /* WriteEndDocument resets it to initial state */
+    hr = IXmlWriter_WriteEndDocument(writer);
+    ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
+
+    hr = IXmlWriter_WriteEndDocument(writer);
+    ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
+
+    hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
+    ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
+
+    hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
+    ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
+
+    hr = IXmlWriter_SetOutput(writer, (IUnknown*)stream);
+    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_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 = GetHGlobalFromStream(stream, &hglobal);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    ptr = GlobalLock(hglobal);
+    ok(ptr == NULL, "got %p\n", ptr);
+
+    /* we still need to flush manually, WriteEndDocument doesn't do that */
+    hr = IXmlWriter_Flush(writer);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    ptr = GlobalLock(hglobal);
+    ok(ptr != NULL, "got %p\n", ptr);
+    ok(!strncmp(ptr, "<a><b /></a>", 12), "got %s\n", ptr);
+    GlobalUnlock(hglobal);
+
+    IXmlWriter_Release(writer);
+    IStream_Release(stream);
+}
+
 START_TEST(writer)
 {
     if (!init_pointers())
@@ -683,4 +749,5 @@ START_TEST(writer)
     test_flush();
     test_omitxmldeclaration();
     test_bom();
+    test_writeenddocument();
 }
diff --git a/dlls/xmllite/writer.c b/dlls/xmllite/writer.c
index abbe07d..8387935 100644
--- a/dlls/xmllite/writer.c
+++ b/dlls/xmllite/writer.c
@@ -59,7 +59,8 @@ typedef enum
     XmlWriterState_PIDocStarted, /* document was started with manually added 'xml' PI */
     XmlWriterState_DocStarted,   /* document was started with WriteStartDocument() */
     XmlWriterState_ElemStarted,  /* writing element */
-    XmlWriterState_Content       /* content is accepted at this point */
+    XmlWriterState_Content,      /* content is accepted at this point */
+    XmlWriterState_DocClosed     /* WriteEndDocument was called */
 } XmlWriterState;
 
 typedef struct
@@ -608,6 +609,8 @@ static HRESULT WINAPI xmlwriter_WriteElementString(IXmlWriter *iface, LPCWSTR pr
     case XmlWriterState_ElemStarted:
         writer_close_starttag(This);
         break;
+    case XmlWriterState_DocClosed:
+        return WR_E_INVALIDACTION;
     default:
         ;
     }
@@ -631,10 +634,34 @@ static HRESULT WINAPI xmlwriter_WriteElementString(IXmlWriter *iface, LPCWSTR pr
 static HRESULT WINAPI xmlwriter_WriteEndDocument(IXmlWriter *iface)
 {
     xmlwriter *This = impl_from_IXmlWriter(iface);
+    HRESULT hr = S_OK;
 
-    FIXME("%p\n", This);
+    TRACE("%p\n", This);
 
-    return E_NOTIMPL;
+    switch (This->state)
+    {
+    case XmlWriterState_Initial:
+        hr = E_UNEXPECTED;
+        break;
+    case XmlWriterState_Ready:
+    case XmlWriterState_DocClosed:
+        hr = WR_E_INVALIDACTION;
+        break;
+    default:
+        ;
+    }
+
+    if (FAILED(hr)) {
+        This->state = XmlWriterState_DocClosed;
+        return hr;
+    }
+
+    /* empty element stack */
+    while (IXmlWriter_WriteEndElement(iface) == S_OK)
+        ;
+
+    This->state = XmlWriterState_DocClosed;
+    return S_OK;
 }
 
 static HRESULT WINAPI xmlwriter_WriteEndElement(IXmlWriter *iface)
@@ -749,6 +776,7 @@ static HRESULT WINAPI xmlwriter_WriteProcessingInstruction(IXmlWriter *iface, LP
             return WR_E_INVALIDACTION;
         break;
     case XmlWriterState_ElemStarted:
+    case XmlWriterState_DocClosed:
         return WR_E_INVALIDACTION;
     default:
         ;
@@ -812,6 +840,7 @@ static HRESULT WINAPI xmlwriter_WriteStartDocument(IXmlWriter *iface, XmlStandal
         return S_OK;
     case XmlWriterState_DocStarted:
     case XmlWriterState_ElemStarted:
+    case XmlWriterState_DocClosed:
         return WR_E_INVALIDACTION;
     default:
         ;
@@ -853,8 +882,15 @@ static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR pre
 
     TRACE("(%p)->(%s %s %s)\n", This, wine_dbgstr_w(prefix), wine_dbgstr_w(local_name), wine_dbgstr_w(uri));
 
-    if (This->state == XmlWriterState_Initial)
+    switch (This->state)
+    {
+    case XmlWriterState_Initial:
         return E_UNEXPECTED;
+    case XmlWriterState_DocClosed:
+        return WR_E_INVALIDACTION;
+    default:
+        ;
+    }
 
     if (!local_name)
         return E_INVALIDARG;




More information about the wine-cvs mailing list