[PATCH 2/2] msxml3: Added support for setting IResponse as xsl processor output
Nikolay Sivov
nsivov at codeweavers.com
Mon Mar 27 16:04:33 CDT 2017
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/msxml3/stylesheet.c | 72 ++++++++++++++++++++++++++++++++++++++++------
dlls/msxml3/tests/domdoc.c | 22 ++++++++++++--
2 files changed, 84 insertions(+), 10 deletions(-)
diff --git a/dlls/msxml3/stylesheet.c b/dlls/msxml3/stylesheet.c
index 74a91808f8..4c4f60ee0f 100644
--- a/dlls/msxml3/stylesheet.c
+++ b/dlls/msxml3/stylesheet.c
@@ -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)
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 371349011f..4bac5a1ccf 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -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);
--
2.11.0
More information about the wine-patches
mailing list