[3/6] webservices: Implement WsReadChars.

Hans Leidekker hans at codeweavers.com
Tue Oct 25 06:03:20 CDT 2016


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 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)
-- 
2.1.4




More information about the wine-patches mailing list