diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 4b2706b5879..dbe993b70fc 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -3663,6 +3663,18 @@ static HRESULT str_to_bytes( const unsigned char *str, ULONG len, WS_HEAP *heap, return S_OK; } +static HRESULT str_to_xml_string( const unsigned char *str, ULONG len, WS_HEAP *heap, WS_XML_STRING *ret ) +{ + const unsigned char *p = str; + + if (!(ret->bytes = ws_alloc( heap, len ))) return WS_E_QUOTA_EXCEEDED; + memcpy( ret->bytes, p, len ); + ret->length = len; + ret->dictionary = NULL; + ret->id = 0; + return S_OK; +} + static const int month_offsets[2][12] = { {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, @@ -4882,6 +4894,58 @@ static HRESULT read_type_bytes( struct reader *reader, WS_TYPE_MAPPING mapping, return S_OK; } +static HRESULT read_type_xml_string( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_XML_STRING *localname, const WS_XML_STRING *ns, + const WS_XML_STRING_DESCRIPTION *desc, WS_READ_OPTION option, + WS_HEAP *heap, void *ret, ULONG size ) +{ + WS_XML_UTF8_TEXT *utf8; + WS_XML_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_xml_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_XML_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_XML_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_XML_STRING **)ret = heap_val; + break; + } + default: + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + + return S_OK; +} + static BOOL is_empty_text_node( const struct node *node ) { const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)node; @@ -5468,6 +5532,11 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP return hr; break; + case WS_XML_STRING_TYPE: + if ((hr = read_type_xml_string( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) + return hr; + break; + case WS_STRUCT_TYPE: if ((hr = read_type_struct( 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 bbb899e9005..d528ecadb75 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -1379,8 +1379,7 @@ static void test_WsReadType(void) WS_XML_READER *reader; WS_HEAP *heap; enum { ONE = 1, TWO = 2 }; - WS_XML_STRING one = { 3, (BYTE *)"ONE" }; - WS_XML_STRING two = { 3, (BYTE *)"TWO" }; + WS_XML_STRING one = { 3, (BYTE *)"ONE" }, two = { 3, (BYTE *)"TWO" }, val_xmlstr; WS_ENUM_VALUE enum_values[] = { { ONE, &one }, { TWO, &two } }; WS_ENUM_DESCRIPTION enum_desc; int val_enum; @@ -1696,6 +1695,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_xmlstr, 0, sizeof(val_xmlstr) ); + prepare_type_test( reader, " test ", sizeof(" test ") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_XML_STRING_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_xmlstr, sizeof(val_xmlstr), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_xmlstr.length == 6, "got %u\n", val_xmlstr.length ); + ok( !memcmp( val_xmlstr.bytes, " test ", 6 ), "wrong data\n" ); + 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,