webservices: Add support for dictionary strings in the reader.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2017-05-30 10:09:06 +02:00 committed by Alexandre Julliard
parent 51d934abbc
commit 0e942e5021
2 changed files with 389 additions and 13 deletions

View File

@ -376,6 +376,7 @@ struct reader
const unsigned char *input_data;
ULONG input_size;
ULONG text_conv_offset;
WS_XML_DICTIONARY *dict;
ULONG prop_count;
struct prop prop[sizeof(reader_props)/sizeof(reader_props[0])];
};
@ -521,6 +522,7 @@ static HRESULT init_reader( struct reader *reader )
if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
read_insert_eof( reader, node );
reader->input_enc = WS_XML_READER_ENCODING_TYPE_TEXT;
reader->dict = NULL;
return S_OK;
}
@ -1277,6 +1279,17 @@ static HRESULT read_string( struct reader *reader, WS_XML_STRING **str )
return hr;
}
static HRESULT read_dict_string( struct reader *reader, WS_XML_STRING **str )
{
ULONG id;
HRESULT hr;
if ((hr = read_int31( reader, &id )) != S_OK) return hr;
if (!reader->dict || (id >>= 1) >= reader->dict->stringCount) return WS_E_INVALID_FORMAT;
if (!(*str = alloc_xml_string( NULL, 0 ))) return E_OUTOFMEMORY;
*(*str) = reader->dict->strings[id];
return S_OK;
}
static HRESULT read_attribute_value_bin( struct reader *reader, WS_XML_ATTRIBUTE *attr )
{
WS_XML_UTF8_TEXT *utf8 = NULL;
@ -1395,6 +1408,17 @@ static HRESULT read_attribute_bin( struct reader *reader, WS_XML_ATTRIBUTE **ret
if ((hr = read_string( reader, &attr->localName )) != S_OK) goto error;
if ((hr = read_attribute_value_bin( reader, attr )) != S_OK) goto error;
}
else if (type >= RECORD_PREFIX_DICTIONARY_ATTRIBUTE_A && type <= RECORD_PREFIX_DICTIONARY_ATTRIBUTE_Z)
{
unsigned char ch = type - RECORD_PREFIX_DICTIONARY_ATTRIBUTE_A + 'a';
if (!(attr->prefix = alloc_xml_string( &ch, 1 )))
{
hr = E_OUTOFMEMORY;
goto error;
}
if ((hr = read_dict_string( reader, &attr->localName )) != S_OK) goto error;
if ((hr = read_attribute_value_bin( reader, attr )) != S_OK) goto error;
}
else
{
switch (type)
@ -1415,6 +1439,22 @@ static HRESULT read_attribute_bin( struct reader *reader, WS_XML_ATTRIBUTE **ret
if ((hr = read_attribute_value_bin( reader, attr )) != S_OK) goto error;
break;
case RECORD_SHORT_DICTIONARY_ATTRIBUTE:
if (!(attr->prefix = alloc_xml_string( NULL, 0 )))
{
hr = E_OUTOFMEMORY;
goto error;
}
if ((hr = read_dict_string( reader, &attr->localName )) != S_OK) goto error;
if ((hr = read_attribute_value_bin( reader, attr )) != S_OK) goto error;
break;
case RECORD_DICTIONARY_ATTRIBUTE:
if ((hr = read_string( reader, &attr->prefix )) != S_OK) goto error;
if ((hr = read_dict_string( reader, &attr->localName )) != S_OK) goto error;
if ((hr = read_attribute_value_bin( reader, attr )) != S_OK) goto error;
break;
case RECORD_SHORT_XMLNS_ATTRIBUTE:
if (!(attr->prefix = alloc_xml_string( NULL, 0 )))
{
@ -1422,6 +1462,7 @@ static HRESULT read_attribute_bin( struct reader *reader, WS_XML_ATTRIBUTE **ret
goto error;
}
if ((hr = read_string( reader, &attr->ns )) != S_OK) goto error;
if ((hr = bind_prefix( reader, attr->prefix, attr->ns )) != S_OK) goto error;
attr->isXmlNs = 1;
break;
@ -1432,6 +1473,24 @@ static HRESULT read_attribute_bin( struct reader *reader, WS_XML_ATTRIBUTE **ret
attr->isXmlNs = 1;
break;
case RECORD_SHORT_DICTIONARY_XMLNS_ATTRIBUTE:
if (!(attr->prefix = alloc_xml_string( NULL, 0 )))
{
hr = E_OUTOFMEMORY;
goto error;
}
if ((hr = read_dict_string( reader, &attr->ns )) != S_OK) goto error;
if ((hr = bind_prefix( reader, attr->prefix, attr->ns )) != S_OK) goto error;
attr->isXmlNs = 1;
break;
case RECORD_DICTIONARY_XMLNS_ATTRIBUTE:
if ((hr = read_string( reader, &attr->prefix )) != S_OK) goto error;
if ((hr = read_dict_string( reader, &attr->ns )) != S_OK) goto error;
if ((hr = bind_prefix( reader, attr->prefix, attr->ns )) != S_OK) goto error;
attr->isXmlNs = 1;
break;
default:
ERR( "unhandled record type %02x\n", type );
return WS_E_NOT_SUPPORTED;
@ -1615,6 +1674,16 @@ static HRESULT read_element_bin( struct reader *reader )
}
if ((hr = read_string( reader, &elem->localName )) != S_OK) goto error;
}
else if (type >= RECORD_PREFIX_DICTIONARY_ELEMENT_A && type <= RECORD_PREFIX_DICTIONARY_ELEMENT_Z)
{
unsigned char ch = type - RECORD_PREFIX_DICTIONARY_ELEMENT_A + 'a';
if (!(elem->prefix = alloc_xml_string( &ch, 1 )))
{
hr = E_OUTOFMEMORY;
goto error;
}
if ((hr = read_dict_string( reader, &elem->localName )) != S_OK) goto error;
}
else
{
switch (type)
@ -1633,6 +1702,20 @@ static HRESULT read_element_bin( struct reader *reader )
if ((hr = read_string( reader, &elem->localName )) != S_OK) goto error;
break;
case RECORD_SHORT_DICTIONARY_ELEMENT:
if (!(elem->prefix = alloc_xml_string( NULL, 0 )))
{
hr = E_OUTOFMEMORY;
goto error;
}
if ((hr = read_dict_string( reader, &elem->localName )) != S_OK) goto error;
break;
case RECORD_DICTIONARY_ELEMENT:
if ((hr = read_string( reader, &elem->prefix )) != S_OK) goto error;
if ((hr = read_dict_string( reader, &elem->localName )) != S_OK) goto error;
break;
default:
ERR( "unhandled record type %02x\n", type );
return WS_E_NOT_SUPPORTED;
@ -5180,9 +5263,12 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
break;
}
case WS_XML_READER_ENCODING_TYPE_BINARY:
{
WS_XML_READER_BINARY_ENCODING *bin = (WS_XML_READER_BINARY_ENCODING *)encoding;
reader->input_enc = WS_XML_READER_ENCODING_TYPE_BINARY;
reader->dict = bin->staticDictionary;
break;
}
default:
FIXME( "encoding type %u not supported\n", encoding->encodingType );
hr = E_NOTIMPL;

View File

@ -18,6 +18,7 @@
#include <stdio.h>
#include "windows.h"
#include "rpc.h"
#include "webservices.h"
#include "wine/test.h"
@ -4495,9 +4496,9 @@ static void test_WsSkipNode(void)
WsFreeReader( reader );
}
static HRESULT set_input_bin( WS_XML_READER *reader, const char *data, ULONG size )
static HRESULT set_input_bin( WS_XML_READER *reader, const char *data, ULONG size, WS_XML_DICTIONARY *dict )
{
WS_XML_READER_BINARY_ENCODING bin = {{WS_XML_READER_ENCODING_TYPE_BINARY}};
WS_XML_READER_BINARY_ENCODING bin = {{WS_XML_READER_ENCODING_TYPE_BINARY}, dict};
WS_XML_READER_BUFFER_INPUT buf;
buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
@ -4540,7 +4541,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) );
hr = set_input_bin( reader, res, sizeof(res), NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsReadNode( reader, NULL );
@ -4553,6 +4554,7 @@ static void test_binary_encoding(void)
ok( elem->prefix->bytes == NULL, "bytes set\n" );
ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
todo_wine ok( elem->localName->dictionary != NULL, "dictionary not set\n" );
ok( !elem->ns->length, "got %u\n", elem->ns->length );
ok( elem->ns->bytes != NULL, "bytes not set\n" );
ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
@ -4565,7 +4567,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) );
hr = set_input_bin( reader, res2, sizeof(res2), NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsReadNode( reader, NULL );
@ -4597,7 +4599,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) );
hr = set_input_bin( reader, res3, sizeof(res3), NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsReadNode( reader, NULL );
@ -4629,7 +4631,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) );
hr = set_input_bin( reader, res4, sizeof(res4), NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsReadNode( reader, NULL );
@ -4672,7 +4674,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) );
hr = set_input_bin( reader, res100, sizeof(res100), NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsReadNode( reader, NULL );
@ -4709,7 +4711,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) );
hr = set_input_bin( reader, res101, sizeof(res101), NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsReadNode( reader, NULL );
@ -4754,7 +4756,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) );
hr = set_input_bin( reader, res102, sizeof(res102), NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsReadNode( reader, NULL );
@ -4799,7 +4801,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) );
hr = set_input_bin( reader, res103, sizeof(res103), NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsReadNode( reader, NULL );
@ -4850,7 +4852,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) );
hr = set_input_bin( reader, res200, sizeof(res200), NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsReadNode( reader, NULL );
@ -4862,7 +4864,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) );
hr = set_input_bin( reader, res, sizeof(res), NULL );
ok( hr == S_OK, "got %08x\n", hr );
found = -1;
@ -4877,6 +4879,293 @@ static void test_binary_encoding(void)
WsFreeReader( reader );
}
static void test_dictionary(void)
{
static const char res[] =
{0x42,0x04,0x01};
static const char res2[] =
{0x53,0x06,0x0b,0x01,'p',0x0a,0x01};
static const char res3[] =
{0x43,0x02,'p','2',0x06,0x0b,0x02,'p','2',0x0a,0x01};
static const char res4[] =
{0x42,0x06,0x06,0x06,0x98,0x00,0x01};
static const char res5[] =
{0x42,0x06,0x1b,0x06,0x98,0x00,0x0b,0x01,'p',0x0a,0x01};
static const char res6[] =
{0x42,0x06,0x07,0x02,'p','2',0x06,0x98,0x00,0x0b,0x02,'p','2',0x0a,0x01};
const WS_XML_NODE *node;
const WS_XML_ELEMENT_NODE *elem;
const WS_XML_ATTRIBUTE *attr;
const WS_XML_UTF8_TEXT *utf8;
WS_XML_STRING strings[6];
WS_XML_DICTIONARY dict;
WS_XML_READER *reader;
HRESULT hr;
hr = WsCreateReader( NULL, 0, &reader, NULL );
ok( hr == S_OK, "got %08x\n", hr );
strings[0].length = 0;
strings[0].bytes = NULL;
strings[0].dictionary = &dict;
strings[0].id = 0;
strings[1].length = 1;
strings[1].bytes = (BYTE *)"p";
strings[1].dictionary = &dict;
strings[1].id = 1;
strings[2].length = 1;
strings[2].bytes = (BYTE *)"t";
strings[2].dictionary = &dict;
strings[2].id = ~0u;
strings[3].length = 1;
strings[3].bytes = (BYTE *)"u";
strings[3].dictionary = &dict;
strings[3].id = 3;
strings[4].length = 2;
strings[4].bytes = (BYTE *)"p2";
strings[4].dictionary = &dict;
strings[4].id = 4;
strings[5].length = 2;
strings[5].bytes = (BYTE *)"ns";
strings[5].dictionary = &dict;
strings[5].id = 5;
UuidCreate( &dict.guid );
dict.strings = strings;
dict.stringCount = sizeof(strings)/sizeof(strings[0]);
dict.isConst = TRUE;
/* short dictionary element */
hr = set_input_bin( reader, res, sizeof(res), &dict );
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_ELEMENT, "got %u\n", node->nodeType );
elem = (const WS_XML_ELEMENT_NODE *)node;
ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
ok( elem->prefix->bytes == NULL, "bytes set\n" );
ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
ok( elem->localName->dictionary == &dict, "unexpected dict\n" );
ok( elem->localName->id == ~0u, "unexpected id %08x\n", elem->localName->id );
ok( !elem->ns->length, "got %u\n", elem->ns->length );
ok( elem->ns->bytes != NULL, "bytes not set\n" );
ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
ok( !elem->isEmpty, "empty\n" );
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_END_ELEMENT, "got %u\n", node->nodeType );
/* single character prefix dictionary element */
hr = set_input_bin( reader, res2, sizeof(res2), &dict );
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_ELEMENT, "got %u\n", node->nodeType );
elem = (const WS_XML_ELEMENT_NODE *)node;
ok( elem->prefix->length == 1, "got %u\n", elem->prefix->length );
ok( !memcmp( elem->prefix->bytes, "p", 1 ), "wrong prefix\n" );
ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
ok( !elem->isEmpty, "empty\n" );
attr = elem->attributes[0];
ok( !attr->singleQuote, "single quote\n" );
ok( attr->isXmlNs, "not xmlns\n" );
ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
ok( attr->ns->dictionary == &dict, "unexpected dict\n" );
ok( attr->ns->id == 5, "unexpected id %08x\n", attr->ns->id );
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_END_ELEMENT, "got %u\n", node->nodeType );
/* dictionary element */
hr = set_input_bin( reader, res3, sizeof(res3), &dict );
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_ELEMENT, "got %u\n", node->nodeType );
elem = (const WS_XML_ELEMENT_NODE *)node;
ok( elem->prefix->length == 2, "got %u\n", elem->prefix->length );
ok( !memcmp( elem->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
ok( elem->localName->dictionary == &dict, "unexpected dict\n" );
ok( elem->localName->id == 3, "unexpected id %08x\n", elem->localName->id );
ok( elem->ns->length == 2, "got %u\n", elem->ns->length );
ok( !memcmp( elem->ns->bytes, "ns", 2 ), "wrong namespace\n" );
ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
ok( !elem->isEmpty, "empty\n" );
attr = elem->attributes[0];
ok( !attr->singleQuote, "single quote\n" );
ok( attr->isXmlNs, "not xmlns\n" );
ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
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_END_ELEMENT, "got %u\n", node->nodeType );
/* short dictionary attribute */
hr = set_input_bin( reader, res4, sizeof(res4), &dict );
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_ELEMENT, "got %u\n", node->nodeType );
elem = (const WS_XML_ELEMENT_NODE *)node;
ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
ok( !elem->ns->length, "got %u\n", elem->ns->length );
ok( elem->ns->bytes != NULL, "bytes not set\n" );
ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
ok( !elem->isEmpty, "empty\n" );
attr = elem->attributes[0];
ok( !attr->singleQuote, "single quote\n" );
ok( !attr->isXmlNs, "is xmlns\n" );
ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
ok( attr->localName->id == 3, "unexpected id %08x\n", attr->localName->id );
ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
ok( !attr->ns->length, "got %u\n", attr->ns->length );
ok( elem->ns->bytes != NULL, "bytes not set\n" );
ok( attr->value != NULL, "value not set\n" );
utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
ok( !utf8->value.length, "got %u\n", utf8->value.length );
ok( utf8->value.bytes != NULL, "bytes not set\n" );
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_END_ELEMENT, "got %u\n", node->nodeType );
/* single character prefix dictionary attribute */
hr = set_input_bin( reader, res5, sizeof(res5), &dict );
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_ELEMENT, "got %u\n", node->nodeType );
elem = (const WS_XML_ELEMENT_NODE *)node;
ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
ok( !elem->ns->length, "got %u\n", elem->ns->length );
ok( elem->ns->bytes != NULL, "ns not set\n" );
ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
ok( !elem->isEmpty, "empty\n" );
attr = elem->attributes[0];
ok( !attr->singleQuote, "single quote\n" );
ok( !attr->isXmlNs, "is xmlns\n" );
ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
ok( attr->localName->id == 3, "unexpected id %08x\n", attr->localName->id );
ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
ok( attr->value != NULL, "value not set\n" );
utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
ok( !utf8->value.length, "got %u\n", utf8->value.length );
ok( utf8->value.bytes != NULL, "bytes not set\n" );
attr = elem->attributes[1];
ok( !attr->singleQuote, "single quote\n" );
ok( attr->isXmlNs, "not xmlns\n" );
ok( attr->prefix->length == 1, "got %u\n", attr->prefix->length );
ok( !memcmp( attr->prefix->bytes, "p", 1 ), "wrong prefix\n" );
ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
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_END_ELEMENT, "got %u\n", node->nodeType );
/* dictionary attribute */
hr = set_input_bin( reader, res6, sizeof(res6), &dict );
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_ELEMENT, "got %u\n", node->nodeType );
elem = (const WS_XML_ELEMENT_NODE *)node;
ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
ok( !memcmp( elem->localName->bytes, "u", 1 ), "wrong name\n" );
ok( !elem->ns->length, "got %u\n", elem->ns->length );
ok( elem->ns->bytes != NULL, "ns not set\n" );
ok( elem->attributeCount == 2, "got %u\n", elem->attributeCount );
ok( !elem->isEmpty, "empty\n" );
attr = elem->attributes[0];
ok( !attr->singleQuote, "single quote\n" );
ok( !attr->isXmlNs, "is xmlns\n" );
ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
ok( attr->localName->length == 1, "got %u\n", attr->localName->length );
ok( !memcmp( attr->localName->bytes, "u", 1 ), "wrong name\n" );
ok( attr->localName->dictionary == &dict, "unexpected dict\n" );
ok( attr->localName->id == 3, "unexpected id %08x\n", attr->localName->id );
ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
ok( attr->value != NULL, "value not set\n" );
utf8 = (const WS_XML_UTF8_TEXT *)attr->value;
ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
ok( !utf8->value.length, "got %u\n", utf8->value.length );
ok( utf8->value.bytes != NULL, "bytes not set\n" );
attr = elem->attributes[1];
ok( !attr->singleQuote, "single quote\n" );
ok( attr->isXmlNs, "not xmlns\n" );
ok( attr->prefix->length == 2, "got %u\n", attr->prefix->length );
ok( !memcmp( attr->prefix->bytes, "p2", 2 ), "wrong prefix\n" );
ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong namespace\n" );
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_END_ELEMENT, "got %u\n", node->nodeType );
WsFreeReader( reader );
}
START_TEST(reader)
{
test_WsCreateError();
@ -4920,4 +5209,5 @@ START_TEST(reader)
test_WsReadAttribute();
test_WsSkipNode();
test_binary_encoding();
test_dictionary();
}