webservices: Add support for structure types in WsWriteType.
authorHans Leidekker <hans@codeweavers.com>
Fri, 29 Jan 2016 12:27:25 +0000 (13:27 +0100)
committerAlexandre Julliard <julliard@winehq.org>
Fri, 29 Jan 2016 12:30:54 +0000 (21:30 +0900)
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
dlls/webservices/tests/writer.c
dlls/webservices/writer.c

index 8394f7abb4a9a84d475157ba862d7fccc7896e32..fdddceb2dd61b91bcf03d20c066a03c9ef0a391c 100644 (file)
@@ -636,6 +636,91 @@ static void test_basic_type(void)
     WsFreeWriter( writer );
 }
 
+static void test_simple_struct_type(void)
+{
+    static const WCHAR valueW[] = {'v','a','l','u','e',0};
+    HRESULT hr;
+    WS_XML_WRITER *writer;
+    WS_STRUCT_DESCRIPTION s;
+    WS_FIELD_DESCRIPTION f, *fields[1];
+    WS_XML_STRING localname = {6, (BYTE *)"struct"}, ns = {0, NULL};
+    struct test
+    {
+        const WCHAR *field;
+    } *test;
+
+    hr = WsCreateWriter( NULL, 0, &writer, NULL ) ;
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = set_output( writer );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    memset( &f, 0, sizeof(f) );
+    f.mapping   = WS_TEXT_FIELD_MAPPING;
+    f.type      = WS_WSZ_TYPE;
+    fields[0] = &f;
+
+    memset( &s, 0, sizeof(s) );
+    s.size          = sizeof(struct test);
+    s.alignment     = TYPE_ALIGNMENT(struct test);
+    s.fields        = fields;
+    s.fieldCount    = 1;
+
+    test = HeapAlloc( GetProcessHeap(), 0, sizeof(*test) );
+    test->field  = valueW;
+    hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL,
+                      WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
+                      WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsWriteEndElement( writer, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    check_output( writer, "<struct>value</struct>", __LINE__ );
+
+    hr = set_output( writer );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
+                      WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsWriteEndElement( writer, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    check_output( writer, "<struct>value</struct>", __LINE__ );
+
+    hr = set_output( writer );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsWriteStartAttribute( writer, NULL, &localname, &ns, FALSE, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsWriteType( writer, WS_ATTRIBUTE_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
+                      WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsWriteEndAttribute( writer, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsWriteEndElement( writer, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    check_output( writer, "<struct struct=\"value\"/>", __LINE__ );
+
+    HeapFree( GetProcessHeap(), 0, test );
+    WsFreeWriter( writer );
+}
+
 START_TEST(writer)
 {
     test_WsCreateWriter();
@@ -646,4 +731,5 @@ START_TEST(writer)
     test_WsWriteStartAttribute();
     test_WsWriteType();
     test_basic_type();
+    test_simple_struct_type();
 }
index 00fd310c90500cf300e72a5e76fcb85f0a34f854..5efd62e689cf3b095e1a6e39a380e5c41e0a0756 100644 (file)
@@ -1113,12 +1113,138 @@ static HRESULT write_type_wsz( struct writer *writer, WS_TYPE_MAPPING mapping,
     return hr;
 }
 
+static HRESULT write_type_struct( struct writer *, WS_TYPE_MAPPING, const WS_STRUCT_DESCRIPTION *,
+                                  const void * );
+
+static HRESULT write_type_struct_field( struct writer *writer, WS_TYPE_MAPPING mapping,
+                                        const WS_FIELD_DESCRIPTION *desc, const void *value )
+{
+    HRESULT hr;
+
+    if (desc->options && desc->options != WS_FIELD_POINTER &&
+        desc->options != WS_FIELD_OPTIONAL &&
+        desc->options != (WS_FIELD_POINTER | WS_FIELD_OPTIONAL))
+    {
+        FIXME( "options 0x%x not supported\n", desc->options );
+        return E_NOTIMPL;
+    }
+
+    switch (desc->type)
+    {
+    case WS_STRUCT_TYPE:
+    {
+        const void * const *ptr = value;
+        if ((hr = write_type_struct( writer, mapping, desc->typeDescription, *ptr )) != S_OK) return hr;
+        break;
+    }
+    case WS_BOOL_TYPE:
+    {
+        const BOOL *ptr = value;
+        if ((hr = write_type_bool( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
+        break;
+    }
+    case WS_INT8_TYPE:
+    {
+        const INT8 *ptr = value;
+        if ((hr = write_type_int8( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
+        break;
+    }
+    case WS_INT16_TYPE:
+    {
+        const INT16 *ptr = value;
+        if ((hr = write_type_int16( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
+        break;
+    }
+    case WS_INT32_TYPE:
+    {
+        const INT32 *ptr = value;
+        if ((hr = write_type_int32( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
+        break;
+    }
+    case WS_INT64_TYPE:
+    {
+        const INT64 *ptr = value;
+        if ((hr = write_type_int64( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
+        break;
+    }
+    case WS_UINT8_TYPE:
+    {
+        const UINT8 *ptr = value;
+        if ((hr = write_type_uint8( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
+        break;
+    }
+    case WS_UINT16_TYPE:
+    {
+        const UINT16 *ptr = value;
+        if ((hr = write_type_uint16( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
+        break;
+    }
+    case WS_UINT32_TYPE:
+    {
+        const UINT32 *ptr = value;
+        if ((hr = write_type_uint32( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
+        break;
+    }
+    case WS_UINT64_TYPE:
+    {
+        const UINT64 *ptr = value;
+        if ((hr = write_type_uint64( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
+        break;
+    }
+    case WS_WSZ_TYPE:
+    {
+        const WCHAR * const *ptr = value;
+        if ((hr = write_type_wsz( writer, mapping, desc->typeDescription, *ptr )) != S_OK) return hr;
+        break;
+    }
+    default:
+        FIXME( "type %u not implemented\n", desc->type );
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
+
+static HRESULT write_type_struct( struct writer *writer, WS_TYPE_MAPPING mapping,
+                                  const WS_STRUCT_DESCRIPTION *desc, const void *value )
+{
+    ULONG i;
+    HRESULT hr;
+    const char *ptr;
+
+    if (!desc) return E_INVALIDARG;
+
+    if (desc->structOptions)
+    {
+        FIXME( "struct options 0x%x not supported\n", desc->structOptions );
+        return E_NOTIMPL;
+    }
+
+    for (i = 0; i < desc->fieldCount; i++)
+    {
+        ptr = (const char *)value + desc->fields[i]->offset;
+        if ((hr = write_type_struct_field( writer, mapping, desc->fields[i], ptr )) != S_OK)
+            return hr;
+    }
+
+    return S_OK;
+}
+
 static HRESULT write_type( struct writer *writer, WS_TYPE_MAPPING mapping, WS_TYPE type,
                            const void *desc, WS_WRITE_OPTION option, const void *value,
                            ULONG size )
 {
     switch (type)
     {
+    case WS_STRUCT_TYPE:
+    {
+        const void * const *ptr = value;
+
+        if (!desc || option != WS_WRITE_REQUIRED_POINTER || size != sizeof(*ptr))
+            return E_INVALIDARG;
+
+        return write_type_struct( writer, mapping, desc, *ptr );
+    }
     case WS_BOOL_TYPE:
     {
         const BOOL *ptr = value;