Hans Leidekker : webservices: Add support for serializing array parameters in WsCall.

Alexandre Julliard julliard at winehq.org
Thu Nov 17 17:45:58 CST 2016


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

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Thu Nov 17 10:11:08 2016 -0600

webservices: Add support for serializing array parameters in WsCall.

Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/webservices/tests/proxy.c | 68 +++++++++++++++++++++++++++++-------------
 dlls/webservices/writer.c      | 23 +++++++++++++-
 2 files changed, 70 insertions(+), 21 deletions(-)

diff --git a/dlls/webservices/tests/proxy.c b/dlls/webservices/tests/proxy.c
index f1676cd..61dff79 100644
--- a/dlls/webservices/tests/proxy.c
+++ b/dlls/webservices/tests/proxy.c
@@ -289,7 +289,7 @@ static HRESULT create_proxy( int port, WS_SERVICE_PROXY **ret )
 
 static const char req_test2[] =
     "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body>"
-    "<req_test2 xmlns=\"ns\"><val>1</val></req_test2>"
+    "<req_test2 xmlns=\"ns\"><val>1</val><str>test</str><str>test2</str></req_test2>"
     "</s:Body></s:Envelope>";
 
 static const char resp_test2[] =
@@ -299,7 +299,7 @@ static const char resp_test2[] =
 
 static void test_WsCall( int port )
 {
-    static WCHAR testW[] = {'t','e','s','t',0};
+    static const WCHAR testW[] = {'t','e','s','t',0}, test2W[] = {'t','e','s','t','2',0};
     WS_XML_STRING str = {3, (BYTE *)"str"};
     WS_XML_STRING req = {3, (BYTE *)"req"};
     WS_XML_STRING resp = {4, (BYTE *)"resp"};
@@ -315,16 +315,19 @@ static void test_WsCall( int port )
     WS_MESSAGE_DESCRIPTION input_msg, output_msg;
     WS_ELEMENT_DESCRIPTION input_elem, output_elem;
     WS_STRUCT_DESCRIPTION input_struct, output_struct;
-    WS_FIELD_DESCRIPTION f, f2, f3, *fields[2], *fields2[2];
-    WS_PARAMETER_DESCRIPTION param[4];
-    const void *args[4];
+    WS_FIELD_DESCRIPTION f, f2, f3, f4, *fields[2], *fields2[2];
+    WS_PARAMETER_DESCRIPTION param[6];
+    const void *args[6];
     WS_HEAP *heap;
     INT32 **val_ptr;
     WCHAR **str_ptr;
     ULONG *count_ptr;
+    const WCHAR *str_array[2];
     struct input
     {
-        INT32   val;
+        INT32         val;
+        ULONG         count;
+        const WCHAR **str;
     } in;
     struct output
     {
@@ -352,11 +355,20 @@ static void test_WsCall( int port )
     f.type      = WS_INT32_TYPE;
     fields[0] = &f;
 
+    memset( &f4, 0, sizeof(f4) );
+    f4.mapping       = WS_REPEATING_ELEMENT_FIELD_MAPPING;
+    f4.type          = WS_WSZ_TYPE;
+    f4.offset        = FIELD_OFFSET(struct input, str);
+    f4.countOffset   = FIELD_OFFSET(struct input, count);
+    f4.itemLocalName = &str;
+    f4.itemNs        = &ns;
+    fields[1] = &f4;
+
     memset( &input_struct, 0, sizeof(input_struct) );
     input_struct.size          = sizeof(struct input);
     input_struct.alignment     = TYPE_ALIGNMENT(struct input);
     input_struct.fields        = fields;
-    input_struct.fieldCount    = 1;
+    input_struct.fieldCount    = 2;
     input_struct.typeLocalName = &req;
     input_struct.typeNs        = &ns;
 
@@ -403,24 +415,32 @@ static void test_WsCall( int port )
     param[0].inputMessageIndex  = 0;
     param[0].outputMessageIndex = 0xffff;
 
-    param[1].parameterType      = WS_PARAMETER_TYPE_NORMAL;
-    param[1].inputMessageIndex  = 0xffff;
-    param[1].outputMessageIndex = 0;
+    param[1].parameterType      = WS_PARAMETER_TYPE_ARRAY;
+    param[1].inputMessageIndex  = 1;
+    param[1].outputMessageIndex = 0xffff;
 
-    param[2].parameterType      = WS_PARAMETER_TYPE_ARRAY;
-    param[2].inputMessageIndex  = 0xffff;
-    param[2].outputMessageIndex = 1;
+    param[2].parameterType      = WS_PARAMETER_TYPE_ARRAY_COUNT;
+    param[2].inputMessageIndex  = 1;
+    param[2].outputMessageIndex = 0xffff;
 
-    param[3].parameterType      = WS_PARAMETER_TYPE_ARRAY_COUNT;
+    param[3].parameterType      = WS_PARAMETER_TYPE_NORMAL;
     param[3].inputMessageIndex  = 0xffff;
-    param[3].outputMessageIndex = 1;
+    param[3].outputMessageIndex = 0;
+
+    param[4].parameterType      = WS_PARAMETER_TYPE_ARRAY;
+    param[4].inputMessageIndex  = 0xffff;
+    param[4].outputMessageIndex = 1;
+
+    param[5].parameterType      = WS_PARAMETER_TYPE_ARRAY_COUNT;
+    param[5].inputMessageIndex  = 0xffff;
+    param[5].outputMessageIndex = 1;
 
     op.versionInfo              = 1;
     op.inputMessageDescription  = &input_msg;
     op.outputMessageDescription = &output_msg;
     op.inputMessageOptions      = 0;
     op.outputMessageOptions     = 0;
-    op.parameterCount           = 4;
+    op.parameterCount           = 6;
     op.parameterDescription     = param;
     op.stubCallback             = NULL;
     op.style                    = 0;
@@ -428,17 +448,25 @@ static void test_WsCall( int port )
     ok( hr == E_INVALIDARG, "got %08x\n", hr );
 
     in.val   = 1;
+    str_array[0] = testW;
+    str_array[1] = test2W;
+    in.str   = str_array;
+    in.count = 2;
+
     args[0] = &in.val;
+    args[1] = &in.str;
+    args[2] = &in.count;
 
     out.str   = NULL;
     out.count = 0;
-    out.val   = 0;
+    out.val   = NULL;
     str_ptr   = &out.str;
     val_ptr   = &out.val;
     count_ptr = &out.count;
-    args[1] = &str_ptr;
-    args[2] = &val_ptr;
-    args[3] = &count_ptr;
+
+    args[3] = &str_ptr;
+    args[4] = &val_ptr;
+    args[5] = &count_ptr;
 
     hr = WsCall( proxy, &op, args, heap, NULL, 0, NULL, NULL );
     ok( hr == S_OK, "got %08x\n", hr );
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index d5c953c..c1f1b0c 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -2813,6 +2813,25 @@ static HRESULT write_param( struct writer *writer, const WS_FIELD_DESCRIPTION *d
     return write_type_struct_field( writer, desc, value, 0 );
 }
 
+static ULONG get_array_len( const WS_PARAMETER_DESCRIPTION *params, ULONG count, ULONG index, const void **args )
+{
+    ULONG i, ret = 0;
+    for (i = 0; i < count; i++)
+    {
+        if (params[i].inputMessageIndex != index || params[i].parameterType != WS_PARAMETER_TYPE_ARRAY_COUNT)
+            continue;
+        if (args[i]) ret = *(const ULONG *)args[i];
+        break;
+    }
+    return ret;
+}
+
+static HRESULT write_param_array( struct writer *writer, const WS_FIELD_DESCRIPTION *desc, const void *value,
+                                  ULONG len )
+{
+    return write_type_repeating_element( writer, desc, value, len );
+}
+
 HRESULT write_input_params( WS_XML_WRITER *handle, const WS_ELEMENT_DESCRIPTION *desc,
                             const WS_PARAMETER_DESCRIPTION *params, ULONG count, const void **args )
 {
@@ -2841,7 +2860,9 @@ HRESULT write_input_params( WS_XML_WRITER *handle, const WS_ELEMENT_DESCRIPTION
         }
         else if (params[i].parameterType == WS_PARAMETER_TYPE_ARRAY)
         {
-            FIXME( "no support for writing array parameters\n" );
+            const void *ptr = *(const void **)args[i];
+            ULONG len = get_array_len( params, count, params[i].inputMessageIndex, args );
+            if ((hr = write_param_array( writer, desc_field, ptr, len )) != S_OK) return hr;
         }
     }
 




More information about the wine-cvs mailing list