From 164024eaa9692c0e9718318d6929581bbd2ef067 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Wed, 21 Jun 2017 09:37:40 +0200 Subject: [PATCH] webservices: Add support for reading WS_UNIQUE_ID values. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/webservices/reader.c | 70 +++++++++++++++++++++++++++++++++ dlls/webservices/tests/reader.c | 36 ++++++++++++----- 2 files changed, 97 insertions(+), 9 deletions(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 7a0064ed736..4b2706b5879 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -3578,6 +3578,19 @@ static HRESULT str_to_string( const unsigned char *str, ULONG len, WS_HEAP *heap return S_OK; } +static HRESULT str_to_unique_id( const unsigned char *str, ULONG len, WS_HEAP *heap, WS_UNIQUE_ID *ret ) +{ + if (len == 45 && !memcmp( str, "urn:uuid:", 9 )) + { + ret->uri.length = 0; + ret->uri.chars = NULL; + return str_to_guid( str + 9, len - 9, &ret->guid ); + } + + memset( &ret->guid, 0, sizeof(ret->guid) ); + return str_to_string( str, len, heap, &ret->uri ); +} + static inline unsigned char decode_char( unsigned char c ) { if (c >= 'A' && c <= 'Z') return c - 'A'; @@ -4714,6 +4727,57 @@ static HRESULT read_type_guid( struct reader *reader, WS_TYPE_MAPPING mapping, return S_OK; } +static HRESULT read_type_unique_id( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_XML_STRING *localname, const WS_XML_STRING *ns, + const WS_UNIQUE_ID_DESCRIPTION *desc, WS_READ_OPTION option, + WS_HEAP *heap, void *ret, ULONG size ) +{ + WS_XML_UTF8_TEXT *utf8; + WS_UNIQUE_ID val = {{0}}; + HRESULT hr; + BOOL found; + + if (desc) FIXME( "ignoring description\n" ); + + if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; + if (found && (hr = str_to_unique_id( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK) return hr; + + switch (option) + { + case WS_READ_REQUIRED_VALUE: + if (!found) return WS_E_INVALID_FORMAT; + /* fall through */ + + case WS_READ_NILLABLE_VALUE: + if (size != sizeof(val)) return E_INVALIDARG; + *(WS_UNIQUE_ID *)ret = val; + break; + + case WS_READ_REQUIRED_POINTER: + if (!found) return WS_E_INVALID_FORMAT; + /* fall through */ + + case WS_READ_OPTIONAL_POINTER: + case WS_READ_NILLABLE_POINTER: + { + WS_UNIQUE_ID *heap_val = NULL; + if (size != sizeof(heap_val)) return E_INVALIDARG; + if (found) + { + if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED; + *heap_val = val; + } + *(WS_UNIQUE_ID **)ret = heap_val; + break; + } + default: + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + + return S_OK; +} + static HRESULT read_type_string( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_XML_STRING *localname, const WS_XML_STRING *ns, const WS_STRING_DESCRIPTION *desc, WS_READ_OPTION option, @@ -4976,6 +5040,7 @@ static WS_READ_OPTION get_field_read_option( WS_TYPE type, ULONG options ) case WS_DOUBLE_TYPE: case WS_DATETIME_TYPE: case WS_GUID_TYPE: + case WS_UNIQUE_ID_TYPE: case WS_STRING_TYPE: case WS_BYTES_TYPE: case WS_XML_STRING_TYPE: @@ -5383,6 +5448,11 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP return hr; break; + case WS_UNIQUE_ID_TYPE: + if ((hr = read_type_unique_id( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) + return hr; + break; + case WS_STRING_TYPE: if ((hr = read_type_string( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) return hr; diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index c5809db9b64..bbb899e9005 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -22,6 +22,8 @@ #include "webservices.h" #include "wine/test.h" +static const GUID guid_null; + static const char data1[] = ""; @@ -1360,9 +1362,6 @@ static void prepare_type_test( WS_XML_READER *reader, const char *data, ULONG si hr = set_input( reader, data, size ); ok( hr == S_OK, "got %08x\n", hr ); - hr = WsFillReader( reader, size, NULL, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); ok( hr == S_OK, "got %08x\n", hr ); @@ -1373,8 +1372,7 @@ static void prepare_type_test( WS_XML_READER *reader, const char *data, ULONG si static void test_WsReadType(void) { static const WCHAR testW[] = {'t','e','s','t',0}, test2W[] = {' ','t','e','s','t',' '}; - static const GUID guid1 = {0,0,0,{0,0,0,0,0,0,0,0}}; - static const GUID guid2 = {0,0,0,{0,0,0,0,0,0,0,0xa1}}; + static const GUID guid = {0,0,0,{0,0,0,0,0,0,0,0xa1}}; static const char utf8[] = {'<','t','>',0xe2,0x80,0x99,'<','/','t','>'}; static const WCHAR utf8W[] = {0x2019,0}; HRESULT hr; @@ -1399,6 +1397,7 @@ static void test_WsReadType(void) GUID val_guid; WS_BYTES val_bytes; WS_STRING val_string; + WS_UNIQUE_ID val_id; hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL ); ok( hr == S_OK, "got %08x\n", hr ); @@ -1650,7 +1649,7 @@ static void test_WsReadType(void) hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL, WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL ); ok( hr == S_OK, "got %08x\n", hr ); - ok( IsEqualGUID( &val_guid, &guid1 ), "wrong guid\n" ); + ok( IsEqualGUID( &val_guid, &guid_null ), "wrong guid\n" ); memset( &val_guid, 0, sizeof(val_guid) ); prepare_type_test( reader, "00000000-0000-0000-0000-0000000000a1", @@ -1658,7 +1657,7 @@ static void test_WsReadType(void) hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL, WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL ); ok( hr == S_OK, "got %08x\n", hr ); - ok( IsEqualGUID( &val_guid, &guid2 ), "wrong guid\n" ); + ok( IsEqualGUID( &val_guid, &guid ), "wrong guid\n" ); memset( &val_guid, 0, sizeof(val_guid) ); prepare_type_test( reader, "00000000-0000-0000-0000-0000000000A1", @@ -1666,7 +1665,7 @@ static void test_WsReadType(void) hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL, WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL ); ok( hr == S_OK, "got %08x\n", hr ); - ok( IsEqualGUID( &val_guid, &guid2 ), "wrong guid\n" ); + ok( IsEqualGUID( &val_guid, &guid ), "wrong guid\n" ); memset( &val_bytes, 0, sizeof(val_bytes) ); prepare_type_test( reader, "dGVzdA==", sizeof("dGVzdA==") - 1 ); @@ -1705,6 +1704,26 @@ static void test_WsReadType(void) ok( val_string.length == 6, "got %u\n", val_string.length ); ok( !memcmp( val_string.chars, test2W, sizeof(test2W) ), "wrong data\n" ); + memset( &val_id, 0, sizeof(val_id) ); + val_id.guid.Data1 = 0xdeadbeef; + prepare_type_test( reader, " test ", sizeof(" test ") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_id, sizeof(val_id), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_id.uri.length == 6, "got %u\n", val_string.length ); + ok( !memcmp( val_id.uri.chars, test2W, sizeof(test2W) ), "wrong data\n" ); + ok( IsEqualGUID( &val_id.guid, &guid_null ), "wrong guid\n" ); + + memset( &val_id, 0, sizeof(val_id) ); + prepare_type_test( reader, "urn:uuid:00000000-0000-0000-0000-0000000000a1", + sizeof("urn:uuid:00000000-0000-0000-0000-0000000000a1") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UNIQUE_ID_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_id, sizeof(val_id), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !val_id.uri.length, "got %u\n", val_string.length ); + ok( val_id.uri.chars == NULL, "chars set %s\n", wine_dbgstr_wn(val_id.uri.chars, val_id.uri.length) ); + ok( IsEqualGUID( &val_id.guid, &guid ), "wrong guid\n" ); + WsFreeReader( reader ); WsFreeHeap( heap ); } @@ -3842,7 +3861,6 @@ static void test_field_options(void) static const char xml[] = "" ""; - static const GUID guid_null = {0}; HRESULT hr; WS_HEAP *heap; WS_XML_READER *reader;