diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 2dad976d5aa..7a0064ed736 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -3565,6 +3565,19 @@ static HRESULT str_to_guid( const unsigned char *str, ULONG len, GUID *ret ) return S_OK; } +static HRESULT str_to_string( const unsigned char *str, ULONG len, WS_HEAP *heap, WS_STRING *ret ) +{ + const unsigned char *p = str; + int len_utf16; + + len_utf16 = MultiByteToWideChar( CP_UTF8, 0, (const char *)p, len, NULL, 0 ); + if (!(ret->chars = ws_alloc( heap, len_utf16 * sizeof(WCHAR) ))) return WS_E_QUOTA_EXCEEDED; + MultiByteToWideChar( CP_UTF8, 0, (const char *)p, len, ret->chars, len_utf16 ); + ret->length = len_utf16; + + return S_OK; +} + static inline unsigned char decode_char( unsigned char c ) { if (c >= 'A' && c <= 'Z') return c - 'A'; @@ -3976,7 +3989,7 @@ static HRESULT read_type_bool( struct reader *reader, WS_TYPE_MAPPING mapping, /* fall through */ case WS_READ_NILLABLE_VALUE: - if (size != sizeof(BOOL)) return E_INVALIDARG; + if (size != sizeof(val)) return E_INVALIDARG; *(BOOL *)ret = val; break; @@ -4196,7 +4209,7 @@ static HRESULT read_type_int64( struct reader *reader, WS_TYPE_MAPPING mapping, /* fall through */ case WS_READ_NILLABLE_VALUE: - if (size != sizeof(INT64)) return E_INVALIDARG; + if (size != sizeof(val)) return E_INVALIDARG; *(INT64 *)ret = val; break; @@ -4416,7 +4429,7 @@ static HRESULT read_type_uint64( struct reader *reader, WS_TYPE_MAPPING mapping, /* fall through */ case WS_READ_NILLABLE_VALUE: - if (size != sizeof(UINT64)) return E_INVALIDARG; + if (size != sizeof(val)) return E_INVALIDARG; *(UINT64 *)ret = val; break; @@ -4467,7 +4480,7 @@ static HRESULT read_type_double( struct reader *reader, WS_TYPE_MAPPING mapping, /* fall through */ case WS_READ_NILLABLE_VALUE: - if (size != sizeof(double)) return E_INVALIDARG; + if (size != sizeof(val)) return E_INVALIDARG; *(double *)ret = val; break; @@ -4570,7 +4583,7 @@ static HRESULT read_type_enum( struct reader *reader, WS_TYPE_MAPPING mapping, /* fall through */ case WS_READ_NILLABLE_VALUE: - if (size != sizeof(int)) return E_INVALIDARG; + if (size != sizeof(val)) return E_INVALIDARG; *(int *)ret = val; break; @@ -4621,7 +4634,7 @@ static HRESULT read_type_datetime( struct reader *reader, WS_TYPE_MAPPING mappin /* fall through */ case WS_READ_NILLABLE_VALUE: - if (size != sizeof(WS_DATETIME)) return E_INVALIDARG; + if (size != sizeof(val)) return E_INVALIDARG; *(WS_DATETIME *)ret = val; break; @@ -4672,7 +4685,7 @@ static HRESULT read_type_guid( struct reader *reader, WS_TYPE_MAPPING mapping, /* fall through */ case WS_READ_NILLABLE_VALUE: - if (size != sizeof(GUID)) return E_INVALIDARG; + if (size != sizeof(val)) return E_INVALIDARG; *(GUID *)ret = val; break; @@ -4701,6 +4714,58 @@ static HRESULT read_type_guid( struct reader *reader, WS_TYPE_MAPPING mapping, 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, + WS_HEAP *heap, void *ret, ULONG size ) +{ + WS_XML_UTF8_TEXT *utf8; + WS_STRING 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_string( 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_STRING *)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_STRING *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_STRING **)ret = heap_val; + break; + } + default: + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + + return S_OK; +} + static HRESULT read_type_bytes( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_XML_STRING *localname, const WS_XML_STRING *ns, const WS_BYTES_DESCRIPTION *desc, WS_READ_OPTION option, @@ -4724,7 +4789,7 @@ static HRESULT read_type_bytes( struct reader *reader, WS_TYPE_MAPPING mapping, /* fall through */ case WS_READ_NILLABLE_VALUE: - if (size != sizeof(WS_BYTES)) return E_INVALIDARG; + if (size != sizeof(val)) return E_INVALIDARG; *(WS_BYTES *)ret = val; break; @@ -5318,6 +5383,11 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP 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; + break; + case WS_WSZ_TYPE: if ((hr = read_type_wsz( 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 466ba78b293..c5809db9b64 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -1372,7 +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}; + 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 char utf8[] = {'<','t','>',0xe2,0x80,0x99,'<','/','t','>'}; @@ -1398,6 +1398,7 @@ static void test_WsReadType(void) UINT64 val_uint64; GUID val_guid; WS_BYTES val_bytes; + WS_STRING val_string; hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL ); ok( hr == S_OK, "got %08x\n", hr ); @@ -1696,6 +1697,14 @@ static void test_WsReadType(void) ok( val_str != NULL, "pointer not set\n" ); if (val_str) ok( !lstrcmpW( val_str, utf8W ), "wrong data %s\n", wine_dbgstr_w(val_str) ); + memset( &val_string, 0, sizeof(val_string) ); + prepare_type_test( reader, " test ", sizeof(" test ") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRING_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_string, sizeof(val_string), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_string.length == 6, "got %u\n", val_string.length ); + ok( !memcmp( val_string.chars, test2W, sizeof(test2W) ), "wrong data\n" ); + WsFreeReader( reader ); WsFreeHeap( heap ); }