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

Alexandre Julliard julliard at winehq.org
Tue Mar 28 15:38:41 CDT 2017


Module: wine
Branch: master
Commit: cebed397c335490c57389245b6e365b651a2f796
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=cebed397c335490c57389245b6e365b651a2f796

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Tue Mar 28 00:04:33 2017 +0300

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

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 74a9180..4c4f60e 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 3713490..4bac5a1 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);




More information about the wine-cvs mailing list