Hans Leidekker : webservices: Implement WsReadBytes.

Alexandre Julliard julliard at winehq.org
Tue Oct 25 14:58:22 CDT 2016


Module: wine
Branch: master
Commit: 4951f5468c2e4abab94a5492742fb1d5fcc83fae
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4951f5468c2e4abab94a5492742fb1d5fcc83fae

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Tue Oct 25 13:03:18 2016 +0200

webservices: Implement WsReadBytes.

Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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*);




More information about the wine-cvs mailing list