Module: wine Branch: master Commit: 98d19212e7a8c0ed4625941f415a42cc34a62cee URL: http://source.winehq.org/git/wine.git/?a=commit;h=98d19212e7a8c0ed4625941f41...
Author: Hans Leidekker hans@codeweavers.com Date: Fri Jan 29 13:27:25 2016 +0100
webservices: Add support for structure types in WsWriteType.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/webservices/tests/writer.c | 86 +++++++++++++++++++++++++++ dlls/webservices/writer.c | 126 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+)
diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index 8394f7a..fdddceb 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -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(); } diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 00fd310..5efd62e 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -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;