From 0e942e5021f3411598ee4e813bd3e9cb59fc6c0d Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 30 May 2017 10:09:06 +0200 Subject: [PATCH] webservices: Add support for dictionary strings in the reader. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/webservices/reader.c | 88 ++++++++- dlls/webservices/tests/reader.c | 314 ++++++++++++++++++++++++++++++-- 2 files changed, 389 insertions(+), 13 deletions(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 6dd6de45db5..8485ad65c17 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -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; diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index 8f31ea5db75..7eab4b8215f 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -18,6 +18,7 @@ #include #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(); }