diff --git a/dlls/msxml3/stylesheet.c b/dlls/msxml3/stylesheet.c index 00ba3cade52..cf24a9b0a09 100644 --- a/dlls/msxml3/stylesheet.c +++ b/dlls/msxml3/stylesheet.c @@ -57,7 +57,9 @@ typedef struct _xslprocessor xsltemplate *stylesheet; IXMLDOMNode *input; + IStream *output; + BSTR outstr; } xslprocessor; static HRESULT XSLProcessor_create(xsltemplate*, IXSLProcessor**); @@ -292,6 +294,7 @@ static HRESULT WINAPI xslprocessor_QueryInterface( else { FIXME("Unsupported interface %s\n", debugstr_guid(riid)); + *ppvObject = NULL; return E_NOINTERFACE; } @@ -315,6 +318,7 @@ static ULONG WINAPI xslprocessor_Release( IXSLProcessor *iface ) { if (This->input) IXMLDOMNode_Release(This->input); if (This->output) IStream_Release(This->output); + SysFreeString(This->outstr); IXSLTemplate_Release(&This->stylesheet->IXSLTemplate_iface); heap_free( This ); } @@ -518,8 +522,25 @@ static HRESULT WINAPI xslprocessor_get_output( { xslprocessor *This = impl_from_IXSLProcessor( iface ); - FIXME("(%p)->(%p): stub\n", This, output); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, output); + + if (!output) return E_INVALIDARG; + + if (This->output) + { + V_VT(output) = VT_UNKNOWN; + V_UNKNOWN(output) = (IUnknown*)This->output; + IStream_AddRef(This->output); + } + else if (This->outstr) + { + V_VT(output) = VT_BSTR; + V_BSTR(output) = SysAllocString(This->outstr); + } + else + V_VT(output) = VT_EMPTY; + + return S_OK; } static HRESULT WINAPI xslprocessor_transform( @@ -528,21 +549,23 @@ static HRESULT WINAPI xslprocessor_transform( { xslprocessor *This = impl_from_IXSLProcessor( iface ); HRESULT hr; - BSTR p; TRACE("(%p)->(%p)\n", This, ret); if (!ret) return E_INVALIDARG; - hr = IXMLDOMNode_transformNode(This->input, This->stylesheet->node, &p); + SysFreeString(This->outstr); + hr = IXMLDOMNode_transformNode(This->input, This->stylesheet->node, &This->outstr); if (hr == S_OK) { - ULONG len = 0; + if (This->output) + { + ULONG len = 0; - /* output to stream */ - hr = IStream_Write(This->output, p, SysStringByteLen(p), &len); - *ret = len == SysStringByteLen(p) ? VARIANT_TRUE : VARIANT_FALSE; - SysFreeString(p); + /* output to stream */ + hr = IStream_Write(This->output, This->outstr, SysStringByteLen(This->outstr), &len); + *ret = len == SysStringByteLen(This->outstr) ? VARIANT_TRUE : VARIANT_FALSE; + } } else *ret = VARIANT_FALSE; @@ -642,6 +665,7 @@ HRESULT XSLProcessor_create(xsltemplate *template, IXSLProcessor **ppObj) This->ref = 1; This->input = NULL; This->output = NULL; + This->outstr = NULL; This->stylesheet = template; IXSLTemplate_AddRef(&template->IXSLTemplate_iface); diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 552e52b570f..c8529330771 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -7865,7 +7865,7 @@ static void test_xsltemplate(void) { IXSLTemplate *template; IXSLProcessor *processor; - IXMLDOMDocument *doc; + IXMLDOMDocument *doc, *doc2; IStream *stream; VARIANT_BOOL b; HRESULT hr; @@ -7947,6 +7947,9 @@ todo_wine { ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v)); } + hr = IXSLProcessor_get_output(processor, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + /* reset before it was set */ V_VT(&v) = VT_EMPTY; hr = IXSLProcessor_put_output(processor, v); @@ -7967,6 +7970,17 @@ todo_wine { IStream_Release(stream); todo_wine ok(ref == 4, "got %d\n", ref); + V_VT(&v) = VT_EMPTY; + hr = IXSLProcessor_get_output(processor, &v); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v)); + ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v)); + + ref = IStream_AddRef(stream); + IStream_Release(stream); + todo_wine ok(ref == 5, "got %d\n", ref); + VariantClear(&v); + hr = IXSLProcessor_transform(processor, NULL); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); @@ -7980,6 +7994,31 @@ todo_wine { ok(ref == 2, "got %d\n", ref); IStream_Release(stream); + + /* no output interface set, check output */ + doc2 = create_document(&IID_IXMLDOMDocument); + + b = VARIANT_TRUE; + hr = IXMLDOMDocument_loadXML( doc2, _bstr_("test"), &b ); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok( b == VARIANT_TRUE, "got %d\n", b); + + V_VT(&v) = VT_UNKNOWN; + V_UNKNOWN(&v) = (IUnknown*)doc2; + hr = IXSLProcessor_put_input(processor, v); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXSLProcessor_transform(processor, &b); + ok(hr == S_OK, "got 0x%08x\n", hr); + + V_VT(&v) = VT_EMPTY; + hr = IXSLProcessor_get_output(processor, &v); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v)); + /* we currently output one '\n' instead of empty string */ + todo_wine ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v))); + IXMLDOMDocument_Release(doc2); + IXSLProcessor_Release(processor); /* drop reference */ @@ -7991,6 +8030,7 @@ todo_wine { IXMLDOMDocument_Release(doc); IXSLTemplate_Release(template); + free_bstrs(); } START_TEST(domdoc)