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 );
}