From 92668f1d30ade1bc9082d90572d096ac9b6c980f Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sun, 1 May 2011 12:04:59 +0400 Subject: [PATCH] msxml3: Store stream reference as destination. --- 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 fed2fda7494..14fccb8c7ce 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 784b37a6245..1f7aac7656f 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(); }