diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 1024c8575a7..9d75f94b8ef 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -772,7 +772,7 @@ HRESULT WINAPI WsGetXmlAttribute( WS_XML_READER *handle, const WS_XML_STRING *at return E_NOTIMPL; } -WS_XML_UTF8_TEXT *alloc_utf8_text( const unsigned char *data, ULONG len ) +WS_XML_UTF8_TEXT *alloc_utf8_text( const BYTE *data, ULONG len ) { WS_XML_UTF8_TEXT *ret; @@ -786,6 +786,18 @@ WS_XML_UTF8_TEXT *alloc_utf8_text( const unsigned char *data, ULONG len ) return ret; } +static WS_XML_BASE64_TEXT *alloc_base64_text( const BYTE *data, ULONG len ) +{ + WS_XML_BASE64_TEXT *ret; + + if (!(ret = heap_alloc( sizeof(*ret) + len ))) return NULL; + ret->text.textType = WS_XML_TEXT_TYPE_BASE64; + ret->length = len; + ret->bytes = len ? (BYTE *)(ret + 1) : NULL; + if (data) memcpy( ret->bytes, data, len ); + return ret; +} + static inline BOOL read_end_of_data( struct reader *reader ) { return reader->read_pos >= reader->read_size; @@ -1277,43 +1289,6 @@ static HRESULT read_datetime( struct reader *reader, WS_DATETIME *ret ) return S_OK; } -static HRESULT read_encode_base64( struct reader *reader, ULONG len, unsigned char *buf, ULONG *ret_len ) -{ - static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - unsigned char byte; - ULONG i = 0, x; - HRESULT hr; - - while (len > 0) - { - if ((hr = read_byte( reader, &byte )) != S_OK) return hr; - buf[i++] = base64[(byte & 0xfc) >> 2]; - x = (byte & 3) << 4; - if (len == 1) - { - buf[i++] = base64[x]; - buf[i++] = '='; - buf[i++] = '='; - break; - } - if ((hr = read_byte( reader, &byte )) != S_OK) return hr; - buf[i++] = base64[x | ((byte & 0xf0) >> 4)]; - x = (byte & 0x0f) << 2; - if (len == 2) - { - buf[i++] = base64[x]; - buf[i++] = '='; - break; - } - if ((hr = read_byte( reader, &byte )) != S_OK) return hr; - buf[i++] = base64[x | ((byte & 0xc0) >> 6)]; - buf[i++] = base64[byte & 0x3f]; - len -= 3; - } - *ret_len = i; - return S_OK; -} - static HRESULT lookup_string( struct reader *reader, ULONG id, const WS_XML_STRING **ret ) { const WS_XML_DICTIONARY *dict = (id & 1) ? reader->dict : reader->dict_static; @@ -1327,6 +1302,7 @@ static HRESULT read_attribute_value_bin( struct reader *reader, WS_XML_ATTRIBUTE static const unsigned char zero[] = {'0'}, one[] = {'1'}; static const unsigned char false[] = {'f','a','l','s','e'}, true[] = {'t','r','u','e'}; WS_XML_UTF8_TEXT *utf8 = NULL; + WS_XML_BASE64_TEXT *base64; const WS_XML_STRING *str; unsigned char type, buf[46]; BOOL val_bool; @@ -1418,20 +1394,20 @@ static HRESULT read_attribute_value_bin( struct reader *reader, WS_XML_ATTRIBUTE case RECORD_BYTES8_TEXT: if ((hr = read_byte( reader, (unsigned char *)&val_uint8 )) != S_OK) return hr; - if (!(utf8 = alloc_utf8_text( NULL, ((4 * val_uint8 / 3) + 3) & ~3 ))) return E_OUTOFMEMORY; - if ((hr = read_encode_base64( reader, val_uint8, utf8->value.bytes, &utf8->value.length )) != S_OK) + if (!(base64 = alloc_base64_text( NULL, val_uint8 ))) return E_OUTOFMEMORY; + if ((hr = read_bytes( reader, base64->bytes, val_uint8 )) != S_OK) { - heap_free( utf8 ); + heap_free( base64 ); return hr; } break; case RECORD_BYTES16_TEXT: if ((hr = read_bytes( reader, (unsigned char *)&val_uint16, sizeof(val_uint16) )) != S_OK) return hr; - if (!(utf8 = alloc_utf8_text( NULL, ((4 * val_uint16 / 3) + 3) & ~3 ))) return E_OUTOFMEMORY; - if ((hr = read_encode_base64( reader, val_uint16, utf8->value.bytes, &utf8->value.length )) != S_OK) + if (!(base64 = alloc_base64_text( NULL, val_uint16 ))) return E_OUTOFMEMORY; + if ((hr = read_bytes( reader, base64->bytes, val_uint16 )) != S_OK) { - heap_free( utf8 ); + heap_free( base64 ); return hr; } break; @@ -1439,10 +1415,10 @@ static HRESULT read_attribute_value_bin( struct reader *reader, WS_XML_ATTRIBUTE case RECORD_BYTES32_TEXT: 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 (!(utf8 = alloc_utf8_text( NULL, ((4 * val_int32 / 3) + 3) & ~3 ))) return E_OUTOFMEMORY; - if ((hr = read_encode_base64( reader, val_int32, utf8->value.bytes, &utf8->value.length )) != S_OK) + if (!(base64 = alloc_base64_text( NULL, val_int32 ))) return E_OUTOFMEMORY; + if ((hr = read_bytes( reader, base64->bytes, val_int32 )) != S_OK) { - heap_free( utf8 ); + heap_free( base64 ); return hr; } break; @@ -1486,6 +1462,12 @@ static HRESULT read_attribute_value_bin( struct reader *reader, WS_XML_ATTRIBUTE return WS_E_NOT_SUPPORTED; } + if (type >= RECORD_BYTES8_TEXT && type <= RECORD_BYTES32_TEXT) + { + attr->value = &base64->text; + return S_OK; + } + if (!utf8) { if (!(utf8 = alloc_utf8_text( NULL, len ))) return E_OUTOFMEMORY; @@ -1956,7 +1938,7 @@ static HRESULT read_text_text( struct reader *reader ) return S_OK; } -static struct node *alloc_text_node( const unsigned char *data, ULONG len, WS_XML_UTF8_TEXT **ret ) +static struct node *alloc_utf8_text_node( const BYTE *data, ULONG len, WS_XML_UTF8_TEXT **ret ) { struct node *node; WS_XML_UTF8_TEXT *utf8; @@ -1974,6 +1956,24 @@ static struct node *alloc_text_node( const unsigned char *data, ULONG len, WS_XM return node; } +static struct node *alloc_base64_text_node( const BYTE *data, ULONG len, WS_XML_BASE64_TEXT **ret ) +{ + struct node *node; + WS_XML_BASE64_TEXT *base64; + WS_XML_TEXT_NODE *text; + + if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return NULL; + if (!(base64 = alloc_base64_text( data, len ))) + { + heap_free( node ); + return NULL; + } + text = (WS_XML_TEXT_NODE *)node; + text->text = &base64->text; + if (ret) *ret = base64; + return node; +} + static HRESULT read_text_bin( struct reader *reader ) { static const unsigned char zero[] = {'0'}, one[] = {'1'}; @@ -1981,6 +1981,7 @@ 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; @@ -2003,64 +2004,64 @@ static HRESULT read_text_bin( struct reader *reader ) { case RECORD_ZERO_TEXT: case RECORD_ZERO_TEXT_WITH_ENDELEMENT: - if (!(node = alloc_text_node( zero, sizeof(zero), NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( zero, sizeof(zero), NULL ))) return E_OUTOFMEMORY; break; case RECORD_ONE_TEXT: case RECORD_ONE_TEXT_WITH_ENDELEMENT: - if (!(node = alloc_text_node( one, sizeof(one), NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( one, sizeof(one), NULL ))) return E_OUTOFMEMORY; break; case RECORD_FALSE_TEXT: case RECORD_FALSE_TEXT_WITH_ENDELEMENT: - if (!(node = alloc_text_node( false, sizeof(false), NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( false, sizeof(false), NULL ))) return E_OUTOFMEMORY; break; case RECORD_TRUE_TEXT: case RECORD_TRUE_TEXT_WITH_ENDELEMENT: - if (!(node = alloc_text_node( true, sizeof(true), NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( true, sizeof(true), NULL ))) return E_OUTOFMEMORY; break; case RECORD_INT8_TEXT: case RECORD_INT8_TEXT_WITH_ENDELEMENT: if ((hr = read_byte( reader, (unsigned char *)&val_int8 )) != S_OK) return hr; len = format_int8( &val_int8, buf ); - if (!(node = alloc_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; break; case RECORD_INT16_TEXT: case RECORD_INT16_TEXT_WITH_ENDELEMENT: if ((hr = read_bytes( reader, (unsigned char *)&val_int16, sizeof(val_int16) )) != S_OK) return hr; len = format_int16( &val_int16, buf ); - if (!(node = alloc_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; break; case RECORD_INT32_TEXT: case RECORD_INT32_TEXT_WITH_ENDELEMENT: if ((hr = read_bytes( reader, (unsigned char *)&val_int32, sizeof(val_int32) )) != S_OK) return hr; len = format_int32( &val_int32, buf ); - if (!(node = alloc_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; break; case RECORD_INT64_TEXT: case RECORD_INT64_TEXT_WITH_ENDELEMENT: if ((hr = read_bytes( reader, (unsigned char *)&val_int64, sizeof(val_int64) )) != S_OK) return hr; len = format_int64( &val_int64, buf ); - if (!(node = alloc_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; break; case RECORD_DOUBLE_TEXT: case RECORD_DOUBLE_TEXT_WITH_ENDELEMENT: if ((hr = read_bytes( reader, (unsigned char *)&val_double, sizeof(val_double) )) != S_OK) return hr; len = format_double( &val_double, buf ); - if (!(node = alloc_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; break; case RECORD_DATETIME_TEXT: case RECORD_DATETIME_TEXT_WITH_ENDELEMENT: if ((hr = read_datetime( reader, &datetime )) != S_OK) return hr; len = format_datetime( &datetime, buf ); - if (!(node = alloc_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; break; case RECORD_CHARS8_TEXT: @@ -2085,8 +2086,8 @@ 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_text_node( NULL, ((4 * val_uint8 / 3) + 3) & ~3, &utf8 ))) return E_OUTOFMEMORY; - if ((hr = read_encode_base64( reader, val_uint8, utf8->value.bytes, &utf8->value.length )) != S_OK) + 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; @@ -2096,8 +2097,8 @@ static HRESULT read_text_bin( struct reader *reader ) 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_text_node( NULL, ((4 * val_uint16 / 3) + 3) & ~3, &utf8 ))) return E_OUTOFMEMORY; - if ((hr = read_encode_base64( reader, val_uint16, utf8->value.bytes, &utf8->value.length )) != S_OK) + 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; @@ -2108,8 +2109,8 @@ static HRESULT read_text_bin( struct reader *reader ) 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_text_node( NULL, ((4 * val_int32 / 3) + 3) & ~3, &utf8 ))) return E_OUTOFMEMORY; - if ((hr = read_encode_base64( reader, val_int32, utf8->value.bytes, &utf8->value.length )) != S_OK) + 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; @@ -2125,35 +2126,35 @@ static HRESULT read_text_bin( struct reader *reader ) case RECORD_DICTIONARY_TEXT_WITH_ENDELEMENT: if ((hr = read_int31( reader, &id )) != S_OK) return hr; if ((hr = lookup_string( reader, id, &str )) != S_OK) return hr; - if (!(node = alloc_text_node( str->bytes, str->length, NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( str->bytes, str->length, NULL ))) return E_OUTOFMEMORY; break; case RECORD_UNIQUEID_TEXT: case RECORD_UNIQUEID_TEXT_WITH_ENDELEMENT: if ((hr = read_bytes( reader, (unsigned char *)&uuid, sizeof(uuid) )) != S_OK) return hr; len = format_urn( &uuid, buf ); - if (!(node = alloc_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; break; case RECORD_UUID_TEXT: case RECORD_UUID_TEXT_WITH_ENDELEMENT: if ((hr = read_bytes( reader, (unsigned char *)&uuid, sizeof(uuid) )) != S_OK) return hr; len = format_guid( &uuid, buf ); - if (!(node = alloc_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; break; case RECORD_UINT64_TEXT: case RECORD_UINT64_TEXT_WITH_ENDELEMENT: if ((hr = read_bytes( reader, (unsigned char *)&val_uint64, sizeof(val_uint64) )) != S_OK) return hr; len = format_uint64( &val_uint64, buf ); - if (!(node = alloc_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; break; case RECORD_BOOL_TEXT: case RECORD_BOOL_TEXT_WITH_ENDELEMENT: if ((hr = read_bytes( reader, (unsigned char *)&val_bool, sizeof(val_bool) )) != S_OK) return hr; len = format_bool( &val_bool, buf ); - if (!(node = alloc_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY; break; default: @@ -2163,7 +2164,7 @@ static HRESULT read_text_bin( struct reader *reader ) if (!node) { - if (!(node = alloc_text_node( NULL, len, &utf8 ))) return E_OUTOFMEMORY; + if (!(node = alloc_utf8_text_node( NULL, len, &utf8 ))) return E_OUTOFMEMORY; if ((hr = read_bytes( reader, utf8->value.bytes, len )) != S_OK) { free_node( node ); diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index 66151ffab8f..5ce37e8a2ce 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -4807,29 +4807,34 @@ static HRESULT set_input_bin( WS_XML_READER *reader, const char *data, ULONG siz static void test_binary_encoding(void) { - static const char res[] = + static const char test[] = {0x40,0x01,'t',0x01}; - static const char res2[] = + static const char test2[] = {0x6d,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01}; - static const char res3[] = + static const char test3[] = {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x01}; - static const char res4[] = + 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 res100[] = + static const char test5[] = + {0x40,0x01,'t',0xa0,0x01,0x00,'a',0x9f,0x01,'b'}; + static const char test6[] = + {0x40,0x01,'t',0x9e,0x01,'a',0x9f,0x01,'b'}; + static const char test100[] = {0x40,0x01,'t',0x04,0x01,'t',0x98,0x00,0x01}; - static const char res101[] = + static const char test101[] = {0x40,0x01,'t',0x35,0x01,'t',0x98,0x00,0x09,0x01,'p',0x02,'n','s',0x01}; - static const char res102[] = + static const char test102[] = {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x00,0x09,0x02,'p','2',0x02,'n','s',0x01}; - static const char res103[] = + static const char test103[] = {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 res200[] = + static const char test200[] = {0x02,0x07,'c','o','m','m','e','n','t'}; - const WS_XML_NODE *node; + const WS_XML_NODE *node, *node2; const WS_XML_ELEMENT_NODE *elem; const WS_XML_ATTRIBUTE *attr; const WS_XML_TEXT_NODE *text; const WS_XML_UTF8_TEXT *utf8; + const WS_XML_BASE64_TEXT *base64; const WS_XML_COMMENT_NODE *comment; WS_XML_READER *reader; BOOL found; @@ -4839,7 +4844,7 @@ static void test_binary_encoding(void) ok( hr == S_OK, "got %08x\n", hr ); /* short element */ - hr = set_input_bin( reader, res, sizeof(res), NULL ); + hr = set_input_bin( reader, test, sizeof(test), NULL ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsReadNode( reader, NULL ); @@ -4865,7 +4870,7 @@ static void test_binary_encoding(void) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType ); /* single character prefix element */ - hr = set_input_bin( reader, res2, sizeof(res2), NULL ); + hr = set_input_bin( reader, test2, sizeof(test2), NULL ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsReadNode( reader, NULL ); @@ -4897,7 +4902,7 @@ static void test_binary_encoding(void) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType ); /* element */ - hr = set_input_bin( reader, res3, sizeof(res3), NULL ); + hr = set_input_bin( reader, test3, sizeof(test3), NULL ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsReadNode( reader, NULL ); @@ -4929,7 +4934,7 @@ static void test_binary_encoding(void) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType ); /* element with text */ - hr = set_input_bin( reader, res4, sizeof(res4), NULL ); + hr = set_input_bin( reader, test4, sizeof(test4), NULL ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsReadNode( reader, NULL ); @@ -4972,7 +4977,7 @@ static void test_binary_encoding(void) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType ); /* short attribute */ - hr = set_input_bin( reader, res100, sizeof(res100), NULL ); + hr = set_input_bin( reader, test100, sizeof(test100), NULL ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsReadNode( reader, NULL ); @@ -5009,7 +5014,7 @@ static void test_binary_encoding(void) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType ); /* single character prefix attribute */ - hr = set_input_bin( reader, res101, sizeof(res101), NULL ); + hr = set_input_bin( reader, test101, sizeof(test101), NULL ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsReadNode( reader, NULL ); @@ -5054,7 +5059,7 @@ static void test_binary_encoding(void) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType ); /* attribute */ - hr = set_input_bin( reader, res102, sizeof(res102), NULL ); + hr = set_input_bin( reader, test102, sizeof(test102), NULL ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsReadNode( reader, NULL ); @@ -5099,7 +5104,7 @@ static void test_binary_encoding(void) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType ); /* attribute with value */ - hr = set_input_bin( reader, res103, sizeof(res103), NULL ); + hr = set_input_bin( reader, test103, sizeof(test103), NULL ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsReadNode( reader, NULL ); @@ -5150,7 +5155,7 @@ static void test_binary_encoding(void) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType ); /* comment */ - hr = set_input_bin( reader, res200, sizeof(res200), NULL ); + hr = set_input_bin( reader, test200, sizeof(test200), NULL ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsReadNode( reader, NULL ); @@ -5162,7 +5167,7 @@ static void test_binary_encoding(void) ok( comment->value.length == 7, "got %u\n", comment->value.length ); ok( !memcmp( comment->value.bytes, "comment", 7 ), "wrong data\n" ); - hr = set_input_bin( reader, res, sizeof(res), NULL ); + hr = set_input_bin( reader, test, sizeof(test), NULL ); ok( hr == S_OK, "got %08x\n", hr ); found = -1; @@ -5174,6 +5179,68 @@ static void test_binary_encoding(void) hr = WsReadEndElement( reader, NULL ); ok( hr == S_OK, "got %08x\n", hr ); + /* element with different byte record types */ + hr = set_input_bin( reader, test5, sizeof(test5), 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 ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* element with equal byte record types */ + 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 ); + ok( hr == S_OK, "got %08x\n", hr ); + WsFreeReader( reader ); }