[PATCH 6/8] Store stream reference as destination

Nikolay Sivov nsivov at codeweavers.com
Sun May 1 03:04:59 CDT 2011


---
 dlls/msxml3/mxwriter.c        |   41 +++++++++++++++-
 dlls/msxml3/tests/saxreader.c |  108 ++++++++++++++++++++++++++++++++++++-----
 2 files changed, 135 insertions(+), 14 deletions(-)

diff --git a/dlls/msxml3/mxwriter.c b/dlls/msxml3/mxwriter.c
index fed2fda..14fccb8 100644
--- a/dlls/msxml3/mxwriter.c
+++ b/dlls/msxml3/mxwriter.c
@@ -46,6 +46,8 @@ typedef struct _mxwriter
     LONG ref;
 
     VARIANT_BOOL standalone;
+
+    IStream *dest;
 } mxwriter;
 
 static inline mxwriter *impl_from_IMXWriter(IMXWriter *iface)
@@ -103,7 +105,10 @@ static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
     TRACE("(%p)->(%d)\n", This, ref);
 
     if(!ref)
+    {
+        if (This->dest) IStream_Release(This->dest);
         heap_free(This);
+    }
 
     return ref;
 }
@@ -183,8 +188,39 @@ static HRESULT WINAPI mxwriter_Invoke(
 static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
 {
     mxwriter *This = impl_from_IMXWriter( iface );
-    FIXME("(%p)->(%s)\n", This, debugstr_variant(&dest));
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%s)\n", This, debugstr_variant(&dest));
+
+    switch (V_VT(&dest))
+    {
+    case VT_EMPTY:
+    {
+        if (This->dest) IStream_Release(This->dest);
+        This->dest = NULL;
+        break;
+    }
+    case VT_UNKNOWN:
+    {
+        IStream *stream;
+        HRESULT hr;
+
+        hr = IUnknown_QueryInterface(V_UNKNOWN(&dest), &IID_IStream, (void**)&stream);
+        if (hr == S_OK)
+        {
+            if (This->dest) IStream_Release(This->dest);
+            This->dest = stream;
+            break;
+        }
+
+        FIXME("unhandled interface type for VT_UNKNOWN destination\n");
+        return E_NOTIMPL;
+    }
+    default:
+        FIXME("unhandled destination type %s\n", debugstr_variant(&dest));
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
 }
 
 static HRESULT WINAPI mxwriter_get_output(IMXWriter *iface, VARIANT *dest)
@@ -511,6 +547,7 @@ HRESULT MXWriter_create(IUnknown *pUnkOuter, void **ppObj)
     This->ref = 1;
 
     This->standalone = VARIANT_FALSE;
+    This->dest = NULL;
 
     *ppObj = &This->IMXWriter_iface;
 
diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c
index 784b37a..1f7aac7 100644
--- a/dlls/msxml3/tests/saxreader.c
+++ b/dlls/msxml3/tests/saxreader.c
@@ -669,11 +669,6 @@ static void test_mxwriter_contenthandler(void)
 
     hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
             &IID_IMXWriter, (void**)&writer);
-    if (hr != S_OK)
-    {
-        win_skip("MXXMLWriter not supported\n");
-        return;
-    }
     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
 
     EXPECT_REF(writer, 1);
@@ -702,11 +697,6 @@ static void test_mxwriter_properties(void)
 
     hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
             &IID_IMXWriter, (void**)&writer);
-    if (hr != S_OK)
-    {
-        win_skip("MXXMLWriter not supported\n");
-        return;
-    }
     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
 
     hr = IMXWriter_get_standalone(writer, NULL);
@@ -729,9 +719,92 @@ static void test_mxwriter_properties(void)
     IMXWriter_Release(writer);
 }
 
+static void test_mxwriter_flush(void)
+{
+    ISAXContentHandler *content;
+    IMXWriter *writer;
+    LARGE_INTEGER pos;
+    ULARGE_INTEGER pos2;
+    IStream *stream;
+    VARIANT dest;
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IMXWriter, (void**)&writer);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+
+    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+    EXPECT_REF(stream, 1);
+
+    /* detach whe nothing was attached */
+    V_VT(&dest) = VT_EMPTY;
+    hr = IMXWriter_put_output(writer, dest);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+
+    /* attach stream */
+    V_VT(&dest) = VT_UNKNOWN;
+    V_UNKNOWN(&dest) = (IUnknown*)stream;
+    hr = IMXWriter_put_output(writer, dest);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+    todo_wine EXPECT_REF(stream, 3);
+
+    /* detach setting VT_EMPTY destination */
+    V_VT(&dest) = VT_EMPTY;
+    hr = IMXWriter_put_output(writer, dest);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+    EXPECT_REF(stream, 1);
+
+    V_VT(&dest) = VT_UNKNOWN;
+    V_UNKNOWN(&dest) = (IUnknown*)stream;
+    hr = IMXWriter_put_output(writer, dest);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+
+    /* flush() doesn't detach a stream */
+    hr = IMXWriter_flush(writer);
+todo_wine {
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+    EXPECT_REF(stream, 3);
+}
+
+    pos.QuadPart = 0;
+    hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+    ok(pos2.QuadPart == 0, "expected stream beginning\n");
+
+    hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    hr = ISAXContentHandler_startDocument(content);
+    todo_wine ok(hr == S_OK, "got %08x\n", hr);
+
+    pos.QuadPart = 0;
+    hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+    todo_wine ok(pos2.QuadPart != 0, "expected stream beginning\n");
+
+    /* already started */
+    hr = ISAXContentHandler_startDocument(content);
+    todo_wine ok(hr == S_OK, "got %08x\n", hr);
+
+    hr = ISAXContentHandler_endDocument(content);
+    todo_wine ok(hr == S_OK, "got %08x\n", hr);
+
+    /* flushed on endDocument() */
+    pos.QuadPart = 0;
+    hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+    todo_wine ok(pos2.QuadPart != 0, "expected stream position moved\n");
+
+    ISAXContentHandler_Release(content);
+    IStream_Release(stream);
+    IMXWriter_Release(writer);
+}
+
 START_TEST(saxreader)
 {
     ISAXXMLReader *reader;
+    IMXWriter *writer;
     HRESULT hr;
 
     hr = CoInitialize(NULL);
@@ -750,8 +823,19 @@ START_TEST(saxreader)
 
     test_saxreader();
     test_encoding();
-    test_mxwriter_contenthandler();
-    test_mxwriter_properties();
+
+    hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IMXWriter, (void**)&writer);
+    if (hr == S_OK)
+    {
+        IMXWriter_Release(writer);
+
+        test_mxwriter_contenthandler();
+        test_mxwriter_properties();
+        test_mxwriter_flush();
+    }
+    else
+        win_skip("MXXMLWriter not supported\n");
 
     CoUninitialize();
 }
-- 
1.5.6.5



--------------070608020907000806010706--



More information about the wine-patches mailing list