diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index c51fb4a63c6..bf05352d8c9 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -17,6 +17,7 @@ */ #include +#include #include "windef.h" #include "winbase.h" @@ -1974,6 +1975,93 @@ static struct node *alloc_base64_text_node( const BYTE *data, ULONG len, WS_XML_ return node; } +static HRESULT append_text_bytes( struct reader *reader, WS_XML_TEXT_NODE *node, ULONG len ) +{ + WS_XML_BASE64_TEXT *new, *old = (WS_XML_BASE64_TEXT *)node->text; + HRESULT hr; + + if (!(new = alloc_base64_text( NULL, old->length + len ))) return E_OUTOFMEMORY; + memcpy( new->bytes, old->bytes, old->length ); + if ((hr = read_bytes( reader, new->bytes + old->length, len )) != S_OK) return hr; + heap_free( old ); + node->text = &new->text; + return S_OK; +} + +static HRESULT read_text_bytes( struct reader *reader, unsigned char type ) +{ + struct node *node = NULL, *parent; + WS_XML_BASE64_TEXT *base64; + HRESULT hr; + ULONG len; + + if (!(parent = find_parent( reader ))) return WS_E_INVALID_FORMAT; + for (;;) + { + switch (type) + { + case RECORD_BYTES8_TEXT: + case RECORD_BYTES8_TEXT_WITH_ENDELEMENT: + { + UINT8 len_uint8; + if ((hr = read_byte( reader, (unsigned char *)&len_uint8 )) != S_OK) goto error; + len = len_uint8; + break; + } + case RECORD_BYTES16_TEXT: + case RECORD_BYTES16_TEXT_WITH_ENDELEMENT: + { + UINT16 len_uint16; + if ((hr = read_bytes( reader, (unsigned char *)&len_uint16, sizeof(len_uint16) )) != S_OK) goto error; + len = len_uint16; + break; + } + case RECORD_BYTES32_TEXT: + case RECORD_BYTES32_TEXT_WITH_ENDELEMENT: + { + INT32 len_int32; + if ((hr = read_bytes( reader, (unsigned char *)&len_int32, sizeof(len_int32) )) != S_OK) goto error; + if (len_int32 < 0) + { + hr = WS_E_INVALID_FORMAT; + goto error; + } + len = len_int32; + break; + } + default: + ERR( "unexpected type %u\n", type ); + hr = E_INVALIDARG; + goto error; + } + + if (!node) + { + if (!(node = alloc_base64_text_node( NULL, len, &base64 ))) return E_OUTOFMEMORY; + if ((hr = read_bytes( reader, base64->bytes, len )) != S_OK) goto error; + } + else if ((hr = append_text_bytes( reader, (WS_XML_TEXT_NODE *)node, len )) != S_OK) goto error; + + if (type & 1) + { + node->flags |= NODE_FLAG_TEXT_WITH_IMPLICIT_END_ELEMENT; + break; + } + if ((hr = read_peek( reader, &type )) != S_OK) goto error; + if (type < RECORD_BYTES8_TEXT || type > RECORD_BYTES32_TEXT_WITH_ENDELEMENT) break; + read_skip( reader, 1 ); + } + + read_insert_node( reader, parent, node ); + reader->state = READER_STATE_TEXT; + reader->text_conv_offset = 0; + return S_OK; + +error: + free_node( node ); + return hr; +} + static HRESULT read_text_bin( struct reader *reader ) { static const unsigned char zero[] = {'0'}, one[] = {'1'}; @@ -1981,7 +2069,6 @@ static HRESULT read_text_bin( struct reader *reader ) unsigned char type, buf[46]; struct node *node = NULL, *parent; WS_XML_UTF8_TEXT *utf8; - WS_XML_BASE64_TEXT *base64; const WS_XML_STRING *str; BOOL val_bool; INT8 val_int8; @@ -2085,37 +2172,11 @@ static HRESULT read_text_bin( struct reader *reader ) case RECORD_BYTES8_TEXT: case RECORD_BYTES8_TEXT_WITH_ENDELEMENT: - if ((hr = read_byte( reader, (unsigned char *)&val_uint8 )) != S_OK) return hr; - if (!(node = alloc_base64_text_node( NULL, val_uint8, &base64 ))) return E_OUTOFMEMORY; - if ((hr = read_bytes( reader, base64->bytes, val_uint8 )) != S_OK) - { - free_node( node ); - return hr; - } - break; - case RECORD_BYTES16_TEXT: case RECORD_BYTES16_TEXT_WITH_ENDELEMENT: - if ((hr = read_bytes( reader, (unsigned char *)&val_uint16, sizeof(val_uint16) )) != S_OK) return hr; - if (!(node = alloc_base64_text_node( NULL, val_uint16, &base64 ))) return E_OUTOFMEMORY; - if ((hr = read_bytes( reader, base64->bytes, val_uint16 )) != S_OK) - { - free_node( node ); - return hr; - } - break; - case RECORD_BYTES32_TEXT: case RECORD_BYTES32_TEXT_WITH_ENDELEMENT: - if ((hr = read_bytes( reader, (unsigned char *)&val_int32, sizeof(val_int32) )) != S_OK) return hr; - if (val_int32 < 0) return WS_E_INVALID_FORMAT; - if (!(node = alloc_base64_text_node( NULL, val_int32, &base64 ))) return E_OUTOFMEMORY; - if ((hr = read_bytes( reader, base64->bytes, val_int32 )) != S_OK) - { - free_node( node ); - return hr; - } - break; + return read_text_bytes( reader, type ); case RECORD_EMPTY_TEXT: case RECORD_EMPTY_TEXT_WITH_ENDELEMENT: @@ -3822,36 +3883,6 @@ HRESULT WINAPI WsFileTimeToDateTime( const FILETIME *ft, WS_DATETIME *dt, WS_ERR return S_OK; } -static HRESULT read_get_node_text( struct reader *reader, WS_XML_UTF8_TEXT **ret ) -{ - WS_XML_TEXT_NODE *node = (WS_XML_TEXT_NODE *)&reader->current->hdr.node; - if (node->text->textType != WS_XML_TEXT_TYPE_UTF8) - { - FIXME( "text type %u not supported\n", node->text->textType ); - return E_NOTIMPL; - } - *ret = (WS_XML_UTF8_TEXT *)node->text; - return S_OK; -} - -static HRESULT read_get_attribute_text( struct reader *reader, ULONG index, WS_XML_UTF8_TEXT **ret ) -{ - WS_XML_ELEMENT_NODE *elem = &reader->current->hdr; - WS_XML_ATTRIBUTE *attr; - - if (node_type( reader->current ) != WS_XML_NODE_TYPE_ELEMENT) - return WS_E_INVALID_FORMAT; - - attr = elem->attributes[index]; - if (attr->value->textType != WS_XML_TEXT_TYPE_UTF8) - { - FIXME( "text type %u not supported\n", attr->value->textType ); - return E_NOTIMPL; - } - *ret = (WS_XML_UTF8_TEXT *)attr->value; - return S_OK; -} - static BOOL find_attribute( struct reader *reader, const WS_XML_STRING *localname, const WS_XML_STRING *ns, ULONG *index ) { @@ -3922,6 +3953,20 @@ HRESULT WINAPI WsFindAttribute( WS_XML_READER *handle, const WS_XML_STRING *loca return hr; } +static HRESULT get_node_text( struct reader *reader, const WS_XML_TEXT **ret ) +{ + WS_XML_TEXT_NODE *node = (WS_XML_TEXT_NODE *)&reader->current->hdr.node; + *ret = node->text; + return S_OK; +} + +static HRESULT get_attribute_text( struct reader *reader, ULONG index, const WS_XML_TEXT **ret ) +{ + WS_XML_ELEMENT_NODE *elem = &reader->current->hdr; + *ret = elem->attributes[index]->value; + return S_OK; +} + static BOOL match_element( const struct node *node, const WS_XML_STRING *localname, const WS_XML_STRING *ns ) { const WS_XML_ELEMENT_NODE *elem = (const WS_XML_ELEMENT_NODE *)node; @@ -3940,9 +3985,8 @@ static HRESULT read_next_node( struct reader *reader ) return WS_E_INVALID_FORMAT; } -static HRESULT read_get_text( struct reader *reader, WS_TYPE_MAPPING mapping, - const WS_XML_STRING *localname, const WS_XML_STRING *ns, - WS_XML_UTF8_TEXT **ret, BOOL *found ) +static HRESULT get_text( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_XML_STRING *localname, + const WS_XML_STRING *ns, const WS_XML_TEXT **ret, BOOL *found ) { switch (mapping) { @@ -3950,7 +3994,7 @@ static HRESULT read_get_text( struct reader *reader, WS_TYPE_MAPPING mapping, { ULONG index; if (!(*found = find_attribute( reader, localname, ns, &index ))) return S_OK; - return read_get_attribute_text( reader, index, ret ); + return get_attribute_text( reader, index, ret ); } case WS_ELEMENT_TYPE_MAPPING: case WS_ELEMENT_CONTENT_TYPE_MAPPING: @@ -3978,7 +4022,7 @@ static HRESULT read_get_text( struct reader *reader, WS_TYPE_MAPPING mapping, *found = FALSE; return S_OK; } - return read_get_node_text( reader, ret ); + return get_node_text( reader, ret ); } default: FIXME( "mapping %u not supported\n", mapping ); @@ -3986,12 +4030,24 @@ static HRESULT read_get_text( struct reader *reader, WS_TYPE_MAPPING mapping, } } +static const WS_XML_UTF8_TEXT *text_to_utf8( const WS_XML_TEXT *text ) +{ + assert( text->textType == WS_XML_TEXT_TYPE_UTF8 ); + return (const WS_XML_UTF8_TEXT *)text; +} + +static const WS_XML_BASE64_TEXT *text_to_base64( const WS_XML_TEXT *text ) +{ + assert( text->textType == WS_XML_TEXT_TYPE_BASE64 ); + return (const WS_XML_BASE64_TEXT *)text; +} + static HRESULT read_type_bool( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_XML_STRING *localname, const WS_XML_STRING *ns, const WS_BOOL_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; BOOL found, val = FALSE; @@ -4000,9 +4056,10 @@ static HRESULT read_type_bool( struct reader *reader, WS_TYPE_MAPPING mapping, FIXME( "description not supported\n" ); return E_NOTIMPL; } - if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; if (found) { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); ULONG len = utf8->value.length; if (len == 4 && !memcmp( utf8->value.bytes, "true", 4 )) val = TRUE; else if (len == 1 && !memcmp( utf8->value.bytes, "1", 1 )) val = TRUE; @@ -4052,7 +4109,7 @@ static HRESULT read_type_int8( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_INT8_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; INT64 val = 0; BOOL found; @@ -4062,9 +4119,13 @@ static HRESULT read_type_int8( struct reader *reader, WS_TYPE_MAPPING mapping, FIXME( "description not supported\n" ); return E_NOTIMPL; } - if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; - if (found && (hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT8, MAX_INT8, &val )) != S_OK) - return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT8, MAX_INT8, &val )) != S_OK) + return hr; + } switch (option) { @@ -4107,7 +4168,7 @@ static HRESULT read_type_int16( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_INT16_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; INT64 val = 0; BOOL found; @@ -4117,9 +4178,13 @@ static HRESULT read_type_int16( struct reader *reader, WS_TYPE_MAPPING mapping, FIXME( "description not supported\n" ); return E_NOTIMPL; } - if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; - if (found && (hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT16, MAX_INT16, &val )) != S_OK) - return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT16, MAX_INT16, &val )) != S_OK) + return hr; + } switch (option) { @@ -4162,7 +4227,7 @@ static HRESULT read_type_int32( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_INT32_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; INT64 val = 0; BOOL found; @@ -4172,9 +4237,13 @@ static HRESULT read_type_int32( struct reader *reader, WS_TYPE_MAPPING mapping, FIXME( "description not supported\n" ); return E_NOTIMPL; } - if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; - if (found && (hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT32, MAX_INT32, &val )) != S_OK) - return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT32, MAX_INT32, &val )) != S_OK) + return hr; + } switch (option) { @@ -4217,7 +4286,7 @@ static HRESULT read_type_int64( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_INT64_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; INT64 val = 0; BOOL found; @@ -4227,9 +4296,13 @@ static HRESULT read_type_int64( struct reader *reader, WS_TYPE_MAPPING mapping, FIXME( "description not supported\n" ); return E_NOTIMPL; } - if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; - if (found && (hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT64, MAX_INT64, &val )) != S_OK) - return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT64, MAX_INT64, &val )) != S_OK) + return hr; + } switch (option) { @@ -4272,7 +4345,7 @@ static HRESULT read_type_uint8( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_UINT8_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; UINT64 val = 0; BOOL found; @@ -4282,9 +4355,13 @@ static HRESULT read_type_uint8( struct reader *reader, WS_TYPE_MAPPING mapping, FIXME( "description not supported\n" ); return E_NOTIMPL; } - if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; - if (found && (hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT8, &val )) != S_OK) - return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT8, &val )) != S_OK) + return hr; + } switch (option) { @@ -4327,7 +4404,7 @@ static HRESULT read_type_uint16( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_UINT16_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; UINT64 val = 0; BOOL found; @@ -4337,9 +4414,13 @@ static HRESULT read_type_uint16( struct reader *reader, WS_TYPE_MAPPING mapping, FIXME( "description not supported\n" ); return E_NOTIMPL; } - if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; - if (found && (hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT16, &val )) != S_OK) - return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT16, &val )) != S_OK) + return hr; + } switch (option) { @@ -4382,7 +4463,7 @@ static HRESULT read_type_uint32( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_UINT32_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; UINT64 val = 0; BOOL found; @@ -4392,9 +4473,13 @@ static HRESULT read_type_uint32( struct reader *reader, WS_TYPE_MAPPING mapping, FIXME( "description not supported\n" ); return E_NOTIMPL; } - if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; - if (found && (hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT32, &val )) != S_OK) - return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT32, &val )) != S_OK) + return hr; + } switch (option) { @@ -4437,7 +4522,7 @@ static HRESULT read_type_uint64( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_UINT64_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; UINT64 val = 0; BOOL found; @@ -4447,9 +4532,13 @@ static HRESULT read_type_uint64( struct reader *reader, WS_TYPE_MAPPING mapping, FIXME( "description not supported\n" ); return E_NOTIMPL; } - if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; - if (found && (hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT64, &val )) != S_OK) - return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT64, &val )) != S_OK) + return hr; + } switch (option) { @@ -4492,15 +4581,19 @@ static HRESULT read_type_double( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_DOUBLE_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; double val = 0.0; 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_double( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_double( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr; + } switch (option) { @@ -4543,7 +4636,7 @@ static HRESULT read_type_wsz( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_WSZ_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, WCHAR **ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; WCHAR *str = NULL; BOOL found; @@ -4553,13 +4646,13 @@ static HRESULT read_type_wsz( struct reader *reader, WS_TYPE_MAPPING mapping, FIXME( "description not supported\n" ); return E_NOTIMPL; } - if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; - if (found && !(str = xmltext_to_widechar( heap, &utf8->text ))) return WS_E_QUOTA_EXCEEDED; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found && !(str = xmltext_to_widechar( heap, text ))) return WS_E_QUOTA_EXCEEDED; switch (option) { case WS_READ_REQUIRED_POINTER: - if (!found && !(str = ws_alloc_zero( heap, 1 ))) return WS_E_QUOTA_EXCEEDED; + if (!str && !(str = ws_alloc_zero( heap, sizeof(*str) ))) return WS_E_QUOTA_EXCEEDED; /* fall through */ case WS_READ_OPTIONAL_POINTER: @@ -4595,15 +4688,19 @@ static HRESULT read_type_enum( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_ENUM_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; int val = 0; BOOL found; if (!desc) return E_INVALIDARG; - if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; - if (found && (hr = get_enum_value( utf8, desc, &val )) != S_OK) return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = get_enum_value( utf8, desc, &val )) != S_OK) return hr; + } switch (option) { @@ -4646,15 +4743,19 @@ static HRESULT read_type_datetime( struct reader *reader, WS_TYPE_MAPPING mappin const WS_DATETIME_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; HRESULT hr; WS_DATETIME val = {0, WS_DATETIME_FORMAT_UTC}; 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_datetime( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_datetime( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr; + } switch (option) { @@ -4697,15 +4798,19 @@ static HRESULT read_type_guid( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_GUID_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; GUID 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_guid( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_guid( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr; + } switch (option) { @@ -4748,15 +4853,19 @@ static HRESULT read_type_unique_id( struct reader *reader, WS_TYPE_MAPPING mappi const WS_UNIQUE_ID_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; 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; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_unique_id( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK) return hr; + } switch (option) { @@ -4799,16 +4908,20 @@ static HRESULT read_type_string( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_STRING_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; 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; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_string( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK) + return hr; + } switch (option) { @@ -4853,16 +4966,38 @@ static HRESULT read_type_bytes( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_BYTES_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; WS_BYTES 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_bytes( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK) - return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + switch (reader->input_enc) + { + case WS_XML_READER_ENCODING_TYPE_TEXT: + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_bytes( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK) + return hr; + break; + } + case WS_XML_READER_ENCODING_TYPE_BINARY: + { + const WS_XML_BASE64_TEXT *base64 = text_to_base64( text ); + if (!(val.bytes = ws_alloc( heap, base64->length ))) return WS_E_QUOTA_EXCEEDED; + memcpy( val.bytes, base64->bytes, base64->length ); + val.length = base64->length; + break; + } + default: + FIXME( "unhandled input encoding %u\n", reader->input_enc ); + return WS_E_NOT_SUPPORTED; + } + } switch (option) { @@ -4907,16 +5042,20 @@ static HRESULT read_type_xml_string( struct reader *reader, WS_TYPE_MAPPING mapp const WS_XML_STRING_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; 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; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_xml_string( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK) + return hr; + } switch (option) { @@ -4961,7 +5100,7 @@ static HRESULT read_type_qname( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_XML_QNAME_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - WS_XML_UTF8_TEXT *utf8; + const WS_XML_TEXT *text; WS_XML_QNAME val = {{0}}; HRESULT hr; BOOL found; @@ -4972,9 +5111,13 @@ static HRESULT read_type_qname( struct reader *reader, WS_TYPE_MAPPING mapping, if ((hr = read_startelement( reader )) != S_OK) return hr; if (node_type( reader->current ) != WS_XML_NODE_TYPE_TEXT) return WS_E_INVALID_FORMAT; - if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; - if (found && (hr = str_to_qname( reader, utf8->value.bytes, utf8->value.length, heap, - NULL, &val.localName, &val.ns )) != S_OK) return hr; + if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr; + if (found) + { + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text ); + if ((hr = str_to_qname( reader, utf8->value.bytes, utf8->value.length, heap, NULL, + &val.localName, &val.ns )) != S_OK) return hr; + } switch (option) { @@ -5015,18 +5158,26 @@ static HRESULT read_type_qname( struct reader *reader, WS_TYPE_MAPPING mapping, static BOOL is_empty_text_node( const struct node *node ) { const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)node; - const WS_XML_UTF8_TEXT *utf8; - ULONG i; if (node_type( node ) != WS_XML_NODE_TYPE_TEXT) return FALSE; - if (text->text->textType != WS_XML_TEXT_TYPE_UTF8) + switch (text->text->textType) { + case WS_XML_TEXT_TYPE_UTF8: + { + ULONG i; + const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text->text ); + for (i = 0; i < utf8->value.length; i++) if (!read_isspace( utf8->value.bytes[i] )) return FALSE; + return TRUE; + } + case WS_XML_TEXT_TYPE_BASE64: + { + const WS_XML_BASE64_TEXT *base64 = text_to_base64( text->text ); + return !base64->length; + } + default: ERR( "unhandled text type %u\n", text->text->textType ); return FALSE; } - utf8 = (const WS_XML_UTF8_TEXT *)text->text; - for (i = 0; i < utf8->value.length; i++) if (!read_isspace( utf8->value.bytes[i] )) return FALSE; - return TRUE; } /* skips comment and empty text nodes */ @@ -5316,7 +5467,6 @@ static HRESULT read_type_union( struct reader *reader, const WS_UNION_DESCRIPTIO return S_OK; } - static HRESULT read_type_field( struct reader *reader, const WS_FIELD_DESCRIPTION *desc, WS_HEAP *heap, char *buf, ULONG offset ) { diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index ce8590a6574..3d90ca0d2f7 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -4804,6 +4804,7 @@ static HRESULT set_input_bin( WS_XML_READER *reader, const char *data, ULONG siz static void test_binary_encoding(void) { + static WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL}; static const char test[] = {0x40,0x01,'t',0x01}; static const char test2[] = @@ -4813,9 +4814,9 @@ static void test_binary_encoding(void) static const char test4[] = {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x99,0x04,'t','e','s','t'}; static const char test5[] = - {0x40,0x01,'t',0xa0,0x01,0x00,'a',0x9f,0x01,'b'}; + {0x40,0x01,'t',0x9f,0x01,'a'}; static const char test6[] = - {0x40,0x01,'t',0x9e,0x01,'a',0x9f,0x01,'b'}; + {0x40,0x01,'t',0xa0,0x01,0x00,'a',0x9f,0x01,'b'}; static const char test100[] = {0x40,0x01,'t',0x04,0x01,'t',0x98,0x00,0x01}; static const char test101[] = @@ -4826,7 +4827,7 @@ static void test_binary_encoding(void) {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x04,'t','e','s','t',0x09,0x02,'p','2',0x02,'n','s',0x01}; static const char test200[] = {0x02,0x07,'c','o','m','m','e','n','t'}; - const WS_XML_NODE *node, *node2; + const WS_XML_NODE *node; const WS_XML_ELEMENT_NODE *elem; const WS_XML_ATTRIBUTE *attr; const WS_XML_TEXT_NODE *text; @@ -4834,8 +4835,15 @@ static void test_binary_encoding(void) const WS_XML_BASE64_TEXT *base64; const WS_XML_COMMENT_NODE *comment; WS_XML_READER *reader; + WS_HEAP *heap; BOOL found; HRESULT hr; + WS_STRUCT_DESCRIPTION s; + WS_FIELD_DESCRIPTION f, *fields[1]; + struct typetest + { + WS_BYTES data; + } *typetest; hr = WsCreateReader( NULL, 0, &reader, NULL ); ok( hr == S_OK, "got %08x\n", hr ); @@ -5176,7 +5184,7 @@ static void test_binary_encoding(void) hr = WsReadEndElement( reader, NULL ); ok( hr == S_OK, "got %08x\n", hr ); - /* element with different byte record types */ + /* element with byte record text */ hr = set_input_bin( reader, test5, sizeof(test5), NULL ); ok( hr == S_OK, "got %08x\n", hr ); @@ -5193,51 +5201,34 @@ static void test_binary_encoding(void) ok( base64->length == 1, "got %u\n", base64->length ); ok( base64->bytes[0] == 'a', "wrong data %02x\n", base64->bytes[0] ); - hr = WsReadNode( reader, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - hr = WsGetReaderNode( reader, &node2, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - todo_wine ok( node2 == node, "different node\n" ); - ok( node2->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node2->nodeType ); - text = (const WS_XML_TEXT_NODE *)node2; - ok( text->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text->text->textType ); - base64 = (const WS_XML_BASE64_TEXT *)text->text; - ok( base64->length == 1, "got %u\n", base64->length ); - ok( base64->bytes[0] == 'b', "wrong data %02x\n", base64->bytes[0] ); - hr = WsReadNode( reader, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - - /* element with equal byte record types */ + /* element with mixed byte record text */ hr = set_input_bin( reader, test6, sizeof(test6), NULL ); ok( hr == S_OK, "got %08x\n", hr ); - hr = WsReadNode( reader, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - hr = WsReadNode( reader, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - hr = WsGetReaderNode( reader, &node, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType ); - text = (const WS_XML_TEXT_NODE *)node; - ok( text->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text->text->textType ); - base64 = (const WS_XML_BASE64_TEXT *)text->text; - ok( base64->length == 1, "got %u\n", base64->length ); - ok( base64->bytes[0] == 'a', "wrong data %02x\n", base64->bytes[0] ); - - hr = WsReadNode( reader, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - hr = WsGetReaderNode( reader, &node2, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - todo_wine ok( node2 == node, "different node\n" ); - ok( node2->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node2->nodeType ); - text = (const WS_XML_TEXT_NODE *)node2; - ok( text->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text->text->textType ); - base64 = (const WS_XML_BASE64_TEXT *)text->text; - ok( base64->length == 1, "got %u\n", base64->length ); - ok( base64->bytes[0] == 'b', "wrong data %02x\n", base64->bytes[0] ); - hr = WsReadNode( reader, NULL ); + hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL ); ok( hr == S_OK, "got %08x\n", hr ); + memset( &f, 0, sizeof(f) ); + f.mapping = WS_ELEMENT_FIELD_MAPPING; + f.localName = &localname; + f.ns = &ns; + f.type = WS_BYTES_TYPE; + f.offset = FIELD_OFFSET(struct typetest, data); + fields[0] = &f; + + memset( &s, 0, sizeof(s) ); + s.size = sizeof(struct typetest); + s.alignment = TYPE_ALIGNMENT(struct typetest); + s.fields = fields; + s.fieldCount = 1; + + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_READ_REQUIRED_POINTER, heap, &typetest, sizeof(typetest), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( typetest->data.length == 2, "got %u\n", typetest->data.length ); + ok( !memcmp( typetest->data.bytes, "ab", 2 ), "wrong data\n" ); + + WsFreeHeap( heap ); WsFreeReader( reader ); }