Module: wine Branch: master Commit: 92668f1d30ade1bc9082d90572d096ac9b6c980f URL: http://source.winehq.org/git/wine.git/?a=commit;h=92668f1d30ade1bc9082d90572...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Sun May 1 12:04:59 2011 +0400
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 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(); }