Module: wine Branch: master Commit: cbc5193e0e8df012176d30e886844e67febd1b88 URL: http://source.winehq.org/git/wine.git/?a=commit;h=cbc5193e0e8df012176d30e886...
Author: Hans Leidekker hans@codeweavers.com Date: Tue Oct 25 13:03:20 2016 +0200
webservices: Implement WsReadChars.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/webservices/reader.c | 45 ++++++++++++++ dlls/webservices/tests/reader.c | 121 ++++++++++++++++++++++++++++++++++++++ dlls/webservices/webservices.spec | 2 +- 3 files changed, 167 insertions(+), 1 deletion(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 44f8402..7996cbe 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -4583,6 +4583,51 @@ HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count, return S_OK; }
+static HRESULT utf8_to_utf16( const WS_XML_UTF8_TEXT *utf8, WS_XML_UTF16_TEXT *utf16 ) +{ + int len = MultiByteToWideChar( CP_UTF8, 0, (char *)utf8->value.bytes, utf8->value.length, NULL, 0 ); + if (!(utf16->bytes = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + MultiByteToWideChar( CP_UTF8, 0, (char *)utf8->value.bytes, utf8->value.length, (WCHAR *)utf16->bytes, len ); + utf16->byteCount = len * sizeof(WCHAR); + return S_OK; +} + +/************************************************************************** + * WsReadChars [webservices.@] + */ +HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count, ULONG *count, WS_ERROR *error ) +{ + struct reader *reader = (struct reader *)handle; + + TRACE( "%p %p %u %p %p\n", handle, chars, 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 && chars) + { + const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current; + WS_XML_UTF16_TEXT utf16; + HRESULT hr; + + if ((hr = utf8_to_utf16( (const WS_XML_UTF8_TEXT *)text->text, &utf16 )) != S_OK) return hr; + if (reader->text_conv_offset == utf16.byteCount / sizeof(WCHAR)) + { + heap_free( utf16.bytes ); + return read_node( reader ); + } + *count = min( utf16.byteCount / sizeof(WCHAR) - reader->text_conv_offset, max_count ); + memcpy( chars, utf16.bytes + reader->text_conv_offset * sizeof(WCHAR), *count * sizeof(WCHAR) ); + reader->text_conv_offset += *count; + heap_free( utf16.bytes ); + } + + return S_OK; +} + /************************************************************************** * WsReadCharsUtf8 [webservices.@] */ diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index 330eb00..23c3f10 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -3978,6 +3978,126 @@ static void test_WsReadBytes(void) WsFreeReader( reader ); }
+static void test_WsReadChars(void) +{ + static const WCHAR textW[] = {'t','e','x','t'}; + HRESULT hr; + WS_XML_READER *reader; + const WS_XML_NODE *node; + const WS_XML_TEXT_NODE *text; + const WS_XML_UTF8_TEXT *utf8; + unsigned char buf[4]; + WCHAR bufW[4]; + ULONG count; + + hr = WsCreateReader( NULL, 0, &reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadChars( NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsReadChars( reader, NULL, 0, NULL, NULL ); + ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr ); + + hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadChars( reader, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadChars( reader, bufW, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = set_input( reader, "<t>text</t>", sizeof("<t>text</t>") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = WsReadChars( reader, NULL, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + count = 0xdeadbeef; + hr = WsReadChars( 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 = WsReadChars( reader, bufW, 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 = WsReadChars( reader, bufW, 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 = WsReadChars( reader, bufW, 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 = WsReadChars( 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 = WsReadChars( reader, bufW, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + ok( !memcmp( bufW, textW, 2 * sizeof(WCHAR) ), "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 == 4, "got %u\n", utf8->value.length ); + ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" ); + + /* continue reading in a different encoding */ + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadCharsUtf8( 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 = WsReadCharsUtf8( 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 ); +} + static void test_WsReadCharsUtf8(void) { HRESULT hr; @@ -4132,5 +4252,6 @@ START_TEST(reader) test_entities(); test_field_options(); test_WsReadBytes(); + test_WsReadChars(); test_WsReadCharsUtf8(); } diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index e785497..074f612 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -105,7 +105,7 @@ @ stub WsReadAttribute @ stdcall WsReadBody(ptr ptr long ptr ptr long ptr) @ stdcall WsReadBytes(ptr ptr long ptr ptr) -@ stub WsReadChars +@ stdcall WsReadChars(ptr ptr long ptr ptr) @ stdcall WsReadCharsUtf8(ptr ptr long ptr ptr) @ stdcall WsReadElement(ptr ptr long ptr ptr long ptr) @ stdcall WsReadEndAttribute(ptr ptr)