Skip to content

Commit

Permalink
msxml3: Added support for setting IResponse as xsl processor output.
Browse files Browse the repository at this point in the history
Signed-off-by: Nikolay Sivov <[email protected]>
Signed-off-by: Alexandre Julliard <[email protected]>
  • Loading branch information
nsivov authored and julliard committed Mar 28, 2017
1 parent d1f1731 commit cebed39
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 10 deletions.
72 changes: 64 additions & 8 deletions dlls/msxml3/stylesheet.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@

#include "msxml_private.h"

#include "initguid.h"
#include "asptlb.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(msxml);
Expand All @@ -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
Expand All @@ -70,6 +74,7 @@ typedef struct
IUnknown *unk;
ISequentialStream *stream;
IPersistStream *persiststream;
IResponse *response;
} output;
enum output_type output_type;
BSTR outstr;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
22 changes: 20 additions & 2 deletions dlls/msxml3/tests/domdoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit cebed39

Please sign in to comment.