msxml3: Added support for setting IResponse as xsl processor output.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2017-03-28 00:04:33 +03:00 committed by Alexandre Julliard
parent d1f1731960
commit cebed397c3
2 changed files with 84 additions and 10 deletions

View File

@ -36,6 +36,9 @@
#include "msxml_private.h"
#include "initguid.h"
#include "asptlb.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(msxml);
@ -54,6 +57,7 @@ enum output_type
PROCESSOR_OUTPUT_NOT_SET,
PROCESSOR_OUTPUT_STREAM, /* IStream or ISequentialStream */
PROCESSOR_OUTPUT_PERSISTSTREAM, /* IPersistStream or IPersistStreamInit */
PROCESSOR_OUTPUT_RESPONSE, /* IResponse */
};
typedef struct
@ -70,6 +74,7 @@ typedef struct
IUnknown *unk;
ISequentialStream *stream;
IPersistStream *persiststream;
IResponse *response;
} output;
enum output_type output_type;
BSTR outstr;
@ -493,7 +498,11 @@ static HRESULT WINAPI xslprocessor_put_output(
hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_IStream, (void **)&output);
if (FAILED(hr))
hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_ISequentialStream, (void **)&output);
/* FIXME: try IResponse */
if (FAILED(hr))
{
output_type = PROCESSOR_OUTPUT_RESPONSE;
hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_IResponse, (void **)&output);
}
if (FAILED(hr))
{
output_type = PROCESSOR_OUTPUT_PERSISTSTREAM;
@ -570,20 +579,67 @@ static HRESULT WINAPI xslprocessor_transform(
stream = This->output.stream;
ISequentialStream_AddRef(stream);
}
else if (This->output_type == PROCESSOR_OUTPUT_PERSISTSTREAM)
else if (This->output_type == PROCESSOR_OUTPUT_PERSISTSTREAM ||
This->output_type == PROCESSOR_OUTPUT_RESPONSE)
{
CreateStreamOnHGlobal(NULL, TRUE, (IStream **)&stream);
}
hr = node_transform_node_params(get_node_obj(This->input), This->stylesheet->node,
&This->outstr, stream, &This->params);
if (SUCCEEDED(hr) && This->output_type == PROCESSOR_OUTPUT_PERSISTSTREAM)
if (SUCCEEDED(hr))
{
IStream *src = (IStream *)stream;
LARGE_INTEGER zero;
/* for IPersistStream* output seekable stream is used */
zero.QuadPart = 0;
IStream_Seek(src, zero, STREAM_SEEK_SET, NULL);
hr = IPersistStream_Load(This->output.persiststream, src);
switch (This->output_type)
{
case PROCESSOR_OUTPUT_PERSISTSTREAM:
{
LARGE_INTEGER zero;
/* for IPersistStream* output seekable stream is used */
zero.QuadPart = 0;
IStream_Seek(src, zero, STREAM_SEEK_SET, NULL);
hr = IPersistStream_Load(This->output.persiststream, src);
break;
}
case PROCESSOR_OUTPUT_RESPONSE:
{
SAFEARRAYBOUND bound;
SAFEARRAY *array;
HGLOBAL hglobal;
VARIANT bin;
DWORD size;
void *dest;
GetHGlobalFromStream(src, &hglobal);
size = GlobalSize(hglobal);
bound.lLbound = 0;
bound.cElements = size;
if (!(array = SafeArrayCreate(VT_UI1, 1, &bound)))
break;
V_VT(&bin) = VT_ARRAY | VT_UI1;
V_ARRAY(&bin) = array;
hr = SafeArrayAccessData(array, &dest);
if (hr == S_OK)
{
void *data = GlobalLock(hglobal);
memcpy(dest, data, size);
GlobalUnlock(hglobal);
SafeArrayUnaccessData(array);
IResponse_BinaryWrite(This->output.response, bin);
}
VariantClear(&bin);
break;
}
default:
;
}
}
if (stream)

View File

@ -361,7 +361,6 @@ static HRESULT WINAPI response_QI(IResponse *iface, REFIID riid, void **obj)
}
if (!IsEqualIID(&IID_IStream, riid) && !IsEqualIID(&IID_ISequentialStream, riid))
todo_wine
ok(0, "unexpected call\n");
return E_NOINTERFACE;
}
@ -488,7 +487,25 @@ static HRESULT WINAPI response_AppendToLog(IResponse *iface, BSTR bstrLogEntry)
static HRESULT WINAPI response_BinaryWrite(IResponse *iface, VARIANT input)
{
HRESULT hr;
LONG bound;
UINT dim;
ok(V_VT(&input) == (VT_ARRAY | VT_UI1), "got wrong input type %x\n", V_VT(&input));
dim = SafeArrayGetDim(V_ARRAY(&input));
ok(dim == 1, "got wrong array dimensions %u\n", dim);
bound = 1;
hr = SafeArrayGetLBound(V_ARRAY(&input), 1, &bound);
ok(hr == S_OK, "got %#x\n", hr);
ok(bound == 0, "wrong array low bound %d\n", bound);
bound = 0;
hr = SafeArrayGetUBound(V_ARRAY(&input), 1, &bound);
ok(hr == S_OK, "got %#x\n", hr);
ok(bound > 0, "wrong array high bound %d\n", bound);
return E_NOTIMPL;
}
@ -8977,11 +8994,12 @@ todo_wine {
V_VT(&v) = VT_UNKNOWN;
V_UNKNOWN(&v) = (IUnknown *)&testresponse;
hr = IXSLProcessor_put_output(processor, v);
todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
b = VARIANT_FALSE;
hr = IXSLProcessor_transform(processor, &b);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(b == VARIANT_TRUE, "got %x\n", b);
IXSLProcessor_Release(processor);
IXMLDOMDocument_Release(doc2);