Module: wine Branch: master Commit: b9953cef4e4dc4d9ce45654abbe692d995ab72c9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b9953cef4e4dc4d9ce45654abb...
Author: Hans Leidekker hans@codeweavers.com Date: Thu May 25 12:54:42 2017 +0200
webservices: Add support for reading text in binary mode.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/webservices/reader.c | 117 +++++++++++++++++++++++++++++++++++++--- dlls/webservices/tests/reader.c | 47 ++++++++++++++++ 2 files changed, 158 insertions(+), 6 deletions(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index a5e3efc..f0f96ea 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -1643,7 +1643,7 @@ error: return hr; }
-static HRESULT read_text( struct reader *reader ) +static HRESULT read_text_text( struct reader *reader ) { unsigned int len = 0, ch, skip; const unsigned char *start; @@ -1685,9 +1685,58 @@ static HRESULT read_text( struct reader *reader ) return S_OK; }
+static HRESULT read_text_bin( struct reader *reader ) +{ + unsigned char type; + struct node *node, *parent; + WS_XML_TEXT_NODE *text; + WS_XML_UTF8_TEXT *utf8; + ULONG len; + HRESULT hr; + + if ((hr = read_byte( reader, &type )) != S_OK) return hr; + if (!is_text_type( type )) return WS_E_INVALID_FORMAT; + + switch (type) + { + case RECORD_CHARS8_TEXT_WITH_ENDELEMENT: + { + unsigned char len8; + if ((hr = read_byte( reader, &len8 )) != S_OK) return hr; + len = len8; + break; + } + default: + ERR( "unhandled record type %02x\n", type ); + return WS_E_NOT_SUPPORTED; + } + + if (!(parent = find_parent( reader ))) return WS_E_INVALID_FORMAT; + + if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return E_OUTOFMEMORY; + text = (WS_XML_TEXT_NODE *)node; + if (!(utf8 = alloc_utf8_text( NULL, len ))) + { + heap_free( node ); + return E_OUTOFMEMORY; + } + if ((hr = read_bytes( reader, utf8->value.bytes, len )) != S_OK) + { + heap_free( utf8 ); + heap_free( node ); + return hr; + } + text->text = &utf8->text; + + read_insert_node( reader, parent, node ); + reader->state = READER_STATE_TEXT; + reader->text_conv_offset = 0; + return S_OK; +} + static HRESULT read_node_text( struct reader * );
-static HRESULT read_startelement( struct reader *reader ) +static HRESULT read_startelement_text( struct reader *reader ) { read_skip_whitespace( reader ); if (!read_cmp( reader, "/>", 2 )) @@ -1706,7 +1755,27 @@ static HRESULT read_startelement( struct reader *reader ) return WS_E_INVALID_FORMAT; }
-static HRESULT read_to_startelement( struct reader *reader, BOOL *found ) +static HRESULT read_node_bin( struct reader * ); + +static HRESULT read_startelement_bin( struct reader *reader ) +{ + if (node_type( reader->current ) != WS_XML_NODE_TYPE_ELEMENT) return WS_E_INVALID_FORMAT; + return read_node_bin( reader ); +} + +static HRESULT read_startelement( struct reader *reader ) +{ + switch (reader->input_enc) + { + case WS_XML_READER_ENCODING_TYPE_TEXT: return read_startelement_text( reader ); + case WS_XML_READER_ENCODING_TYPE_BINARY: return read_startelement_bin( reader ); + default: + ERR( "unhandled encoding %u\n", reader->input_enc ); + return WS_E_NOT_SUPPORTED; + } +} + +static HRESULT read_to_startelement_text( struct reader *reader, BOOL *found ) { HRESULT hr;
@@ -1736,6 +1805,39 @@ static HRESULT read_to_startelement( struct reader *reader, BOOL *found ) return hr; }
+static HRESULT read_to_startelement_bin( struct reader *reader, BOOL *found ) +{ + HRESULT hr; + + if (reader->state == READER_STATE_STARTELEMENT) + { + if (found) *found = TRUE; + return S_OK; + } + + if ((hr = read_element_bin( reader )) == S_OK && found) + { + if (reader->state == READER_STATE_STARTELEMENT) + *found = TRUE; + else + *found = FALSE; + } + + return hr; +} + +static HRESULT read_to_startelement( struct reader *reader, BOOL *found ) +{ + switch (reader->input_enc) + { + case WS_XML_READER_ENCODING_TYPE_TEXT: return read_to_startelement_text( reader, found ); + case WS_XML_READER_ENCODING_TYPE_BINARY: return read_to_startelement_bin( reader, found ); + default: + ERR( "unhandled encoding %u\n", reader->input_enc ); + return WS_E_NOT_SUPPORTED; + } +} + static int cmp_name( const unsigned char *name1, ULONG len1, const unsigned char *name2, ULONG len2 ) { ULONG i; @@ -1974,8 +2076,8 @@ static HRESULT read_node_text( struct reader *reader ) else if (!read_cmp( reader, "<![CDATA[", 9 )) return read_startcdata( reader ); else if (!read_cmp( reader, "<!--", 4 )) return read_comment( reader ); else if (!read_cmp( reader, "<", 1 )) return read_element_text( reader ); - else if (!read_cmp( reader, "/>", 2 ) || !read_cmp( reader, ">", 1 )) return read_startelement( reader ); - else return read_text( reader ); + else if (!read_cmp( reader, "/>", 2 ) || !read_cmp( reader, ">", 1 )) return read_startelement_text( reader ); + else return read_text_text( reader ); } }
@@ -2008,7 +2110,10 @@ static HRESULT read_node_bin( struct reader *reader ) { return read_element_bin( reader ); } - + else if (type >= RECORD_ZERO_TEXT && type <= RECORD_QNAME_DICTIONARY_TEXT_WITH_ENDELEMENT) + { + return read_text_bin( reader ); + } FIXME( "unhandled record type %02x\n", type ); return WS_E_NOT_SUPPORTED; } diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index 41cbadc..4af941b 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -4514,9 +4514,13 @@ static void test_binary_encoding(void) {0x6d,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01}; static const char res3[] = {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x01}; + static const char res4[] = + {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x99,0x04,'t','e','s','t'}; const WS_XML_NODE *node; const WS_XML_ELEMENT_NODE *elem; const WS_XML_ATTRIBUTE *attr; + const WS_XML_TEXT_NODE *text; + const WS_XML_UTF8_TEXT *utf8; WS_XML_READER *reader; HRESULT hr;
@@ -4612,6 +4616,49 @@ static void test_binary_encoding(void) ok( hr == S_OK, "got %08x\n", hr ); 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) ); + 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, "t", 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 == 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_TEXT, "got %u\n", node->nodeType ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType ); + utf8 = (const WS_XML_UTF8_TEXT *)text->text; + ok( utf8->value.length == 4, "got %u\n", utf8->value.length ); + ok( !memcmp( utf8->value.bytes, "test", 4 ), "wrong text\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 ); }