Module: wine Branch: master Commit: 4951f5468c2e4abab94a5492742fb1d5fcc83fae URL: http://source.winehq.org/git/wine.git/?a=commit;h=4951f5468c2e4abab94a549274...
Author: Hans Leidekker hans@codeweavers.com Date: Tue Oct 25 13:03:18 2016 +0200
webservices: Implement WsReadBytes.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/webservices/reader.c | 46 +++++++++++++++ dlls/webservices/tests/reader.c | 118 ++++++++++++++++++++++++++++++++++++++ dlls/webservices/webservices.spec | 2 +- include/webservices.h | 3 + 4 files changed, 168 insertions(+), 1 deletion(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 9ba4dfc..9a3c7d7 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -590,6 +590,7 @@ struct reader struct xmlbuf *input_buf; const unsigned char *input_data; ULONG input_size; + ULONG text_conv_offset; ULONG prop_count; struct prop prop[sizeof(reader_props)/sizeof(reader_props[0])]; }; @@ -1540,6 +1541,7 @@ static HRESULT read_text( struct reader *reader )
read_insert_node( reader, parent, node ); reader->state = READER_STATE_TEXT; + reader->text_conv_offset = 0; return S_OK; }
@@ -4536,3 +4538,47 @@ HRESULT WINAPI WsSetReaderPosition( WS_XML_READER *handle, const WS_XML_NODE_POS reader->current = pos->node; return S_OK; } + +static HRESULT utf8_to_base64( const WS_XML_UTF8_TEXT *utf8, WS_XML_BASE64_TEXT *base64 ) +{ + if (utf8->value.length % 4) return WS_E_INVALID_FORMAT; + if (!(base64->bytes = heap_alloc( utf8->value.length * 3 / 4 ))) return E_OUTOFMEMORY; + base64->length = decode_base64( utf8->value.bytes, utf8->value.length, base64->bytes ); + return S_OK; +} + +/************************************************************************** + * WsReadBytes [webservices.@] + */ +HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count, ULONG *count, WS_ERROR *error ) +{ + struct reader *reader = (struct reader *)handle; + HRESULT hr; + + TRACE( "%p %p %u %p %p\n", handle, bytes, max_count, count, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!reader) return E_INVALIDARG; + if (!reader->input_type) return WS_E_INVALID_OPERATION; + if (!count) return E_INVALIDARG; + + *count = 0; + if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && bytes) + { + const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current; + WS_XML_BASE64_TEXT base64; + + if ((hr = utf8_to_base64( (const WS_XML_UTF8_TEXT *)text->text, &base64 )) != S_OK) return hr; + if (reader->text_conv_offset == base64.length) + { + heap_free( base64.bytes ); + return read_node( reader ); + } + *count = min( base64.length - reader->text_conv_offset, max_count ); + memcpy( bytes, base64.bytes + reader->text_conv_offset, *count ); + reader->text_conv_offset += *count; + heap_free( base64.bytes ); + } + + return S_OK; +} diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index 62ed499..c804105 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -3861,6 +3861,123 @@ static void test_field_options(void) WsFreeHeap( heap ); }
+static void test_WsReadBytes(void) +{ + HRESULT hr; + WS_XML_READER *reader; + const WS_XML_NODE *node; + const WS_XML_TEXT_NODE *text; + const WS_XML_UTF8_TEXT *utf8; + BYTE buf[4]; + ULONG count; + + hr = WsCreateReader( NULL, 0, &reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadBytes( NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsReadBytes( reader, NULL, 0, NULL, NULL ); + ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr ); + + hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadBytes( reader, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadBytes( reader, buf, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = set_input( reader, "<t>dGV4dA==</t>", sizeof("<t>dGV4dA==</t>") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = WsReadBytes( reader, NULL, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + count = 0xdeadbeef; + hr = WsReadBytes( reader, NULL, 1, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadBytes( reader, buf, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + ok( !buf[0], "wrong data\n" ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadBytes( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + ok( !buf[0], "wrong data\n" ); + + hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadBytes( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + ok( !buf[0], "wrong data\n" ); + + hr = WsReadStartElement( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = WsReadBytes( reader, NULL, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadBytes( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + ok( !memcmp( buf, "te", 2 ), "wrong data\n" ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType ); + utf8 = (const WS_XML_UTF8_TEXT *)text->text; + ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType ); + ok( utf8->value.length == 8, "got %u\n", utf8->value.length ); + ok( !memcmp( utf8->value.bytes, "dGV4dA==", 8 ), "wrong data\n" ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadBytes( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + ok( !memcmp( buf, "xt", 2 ), "wrong data\n" ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType ); + + count = 0xdeadbeef; + hr = WsReadBytes( reader, buf, 1, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType ); + + WsFreeReader( reader ); +} + START_TEST(reader) { test_WsCreateError(); @@ -3897,4 +4014,5 @@ START_TEST(reader) test_WsSetReaderPosition(); test_entities(); test_field_options(); + test_WsReadBytes(); } diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index a03b7bd..26db0b2 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -104,7 +104,7 @@ @ stub WsReadArray @ stub WsReadAttribute @ stdcall WsReadBody(ptr ptr long ptr ptr long ptr) -@ stub WsReadBytes +@ stdcall WsReadBytes(ptr ptr long ptr ptr) @ stub WsReadChars @ stub WsReadCharsUtf8 @ stdcall WsReadElement(ptr ptr long ptr ptr long ptr) diff --git a/include/webservices.h b/include/webservices.h index f1d34c4..3274082 100644 --- a/include/webservices.h +++ b/include/webservices.h @@ -1461,6 +1461,9 @@ HRESULT WINAPI WsReadAttribute(WS_XML_READER*, const WS_ATTRIBUTE_DESCRIPTION*, WS_HEAP*, void*, ULONG, WS_ERROR*); HRESULT WINAPI WsReadBody(WS_MESSAGE*, const WS_ELEMENT_DESCRIPTION*, WS_READ_OPTION, WS_HEAP*, void*, ULONG, WS_ERROR*); +HRESULT WINAPI WsReadBytes(WS_XML_READER*, void*, ULONG, ULONG*, WS_ERROR*); +HRESULT WINAPI WsReadChars(WS_XML_READER*, WCHAR*, ULONG, ULONG*, WS_ERROR*); +HRESULT WINAPI WsReadCharsUtf8(WS_XML_READER*, BYTE*, ULONG, ULONG*, WS_ERROR*); HRESULT WINAPI WsReadElement(WS_XML_READER*, const WS_ELEMENT_DESCRIPTION*, WS_READ_OPTION, WS_HEAP*, void*, ULONG, WS_ERROR*); HRESULT WINAPI WsReadEndAttribute(WS_XML_READER*, WS_ERROR*);