[4/7] webservices: Add support for appending byte records in the reader.

Hans Leidekker hans at codeweavers.com
Mon Jul 10 04:02:31 CDT 2017


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/webservices/reader.c       | 428 +++++++++++++++++++++++++++-------------
 dlls/webservices/tests/reader.c |  75 ++++---
 2 files changed, 322 insertions(+), 181 deletions(-)

diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index c51fb4a..bf05352 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -17,6 +17,7 @@
  */
 
 #include <stdarg.h>
+#include <assert.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -1974,6 +1975,93 @@ static struct node *alloc_base64_text_node( const BYTE *data, ULONG len, WS_XML_
     return node;
 }
 
+static HRESULT append_text_bytes( struct reader *reader, WS_XML_TEXT_NODE *node, ULONG len )
+{
+    WS_XML_BASE64_TEXT *new, *old = (WS_XML_BASE64_TEXT *)node->text;
+    HRESULT hr;
+
+    if (!(new = alloc_base64_text( NULL, old->length + len ))) return E_OUTOFMEMORY;
+    memcpy( new->bytes, old->bytes, old->length );
+    if ((hr = read_bytes( reader, new->bytes + old->length, len )) != S_OK) return hr;
+    heap_free( old );
+    node->text = &new->text;
+    return S_OK;
+}
+
+static HRESULT read_text_bytes( struct reader *reader, unsigned char type )
+{
+    struct node *node = NULL, *parent;
+    WS_XML_BASE64_TEXT *base64;
+    HRESULT hr;
+    ULONG len;
+
+    if (!(parent = find_parent( reader ))) return WS_E_INVALID_FORMAT;
+    for (;;)
+    {
+        switch (type)
+        {
+        case RECORD_BYTES8_TEXT:
+        case RECORD_BYTES8_TEXT_WITH_ENDELEMENT:
+        {
+            UINT8 len_uint8;
+            if ((hr = read_byte( reader, (unsigned char *)&len_uint8 )) != S_OK) goto error;
+            len = len_uint8;
+            break;
+        }
+        case RECORD_BYTES16_TEXT:
+        case RECORD_BYTES16_TEXT_WITH_ENDELEMENT:
+        {
+            UINT16 len_uint16;
+            if ((hr = read_bytes( reader, (unsigned char *)&len_uint16, sizeof(len_uint16) )) != S_OK) goto error;
+            len = len_uint16;
+            break;
+        }
+        case RECORD_BYTES32_TEXT:
+        case RECORD_BYTES32_TEXT_WITH_ENDELEMENT:
+        {
+            INT32 len_int32;
+            if ((hr = read_bytes( reader, (unsigned char *)&len_int32, sizeof(len_int32) )) != S_OK) goto error;
+            if (len_int32 < 0)
+            {
+                hr = WS_E_INVALID_FORMAT;
+                goto error;
+            }
+            len = len_int32;
+            break;
+        }
+        default:
+            ERR( "unexpected type %u\n", type );
+            hr = E_INVALIDARG;
+            goto error;
+        }
+
+        if (!node)
+        {
+            if (!(node = alloc_base64_text_node( NULL, len, &base64 ))) return E_OUTOFMEMORY;
+            if ((hr = read_bytes( reader, base64->bytes, len )) != S_OK) goto error;
+        }
+        else if ((hr = append_text_bytes( reader, (WS_XML_TEXT_NODE *)node, len )) != S_OK) goto error;
+
+        if (type & 1)
+        {
+            node->flags |= NODE_FLAG_TEXT_WITH_IMPLICIT_END_ELEMENT;
+            break;
+        }
+        if ((hr = read_peek( reader, &type )) != S_OK) goto error;
+        if (type < RECORD_BYTES8_TEXT || type > RECORD_BYTES32_TEXT_WITH_ENDELEMENT) break;
+        read_skip( reader, 1 );
+    }
+
+    read_insert_node( reader, parent, node );
+    reader->state = READER_STATE_TEXT;
+    reader->text_conv_offset = 0;
+    return S_OK;
+
+error:
+    free_node( node );
+    return hr;
+}
+
 static HRESULT read_text_bin( struct reader *reader )
 {
     static const unsigned char zero[] = {'0'}, one[] = {'1'};
@@ -1981,7 +2069,6 @@ static HRESULT read_text_bin( struct reader *reader )
     unsigned char type, buf[46];
     struct node *node = NULL, *parent;
     WS_XML_UTF8_TEXT *utf8;
-    WS_XML_BASE64_TEXT *base64;
     const WS_XML_STRING *str;
     BOOL val_bool;
     INT8 val_int8;
@@ -2085,37 +2172,11 @@ static HRESULT read_text_bin( struct reader *reader )
 
     case RECORD_BYTES8_TEXT:
     case RECORD_BYTES8_TEXT_WITH_ENDELEMENT:
-        if ((hr = read_byte( reader, (unsigned char *)&val_uint8 )) != S_OK) return hr;
-        if (!(node = alloc_base64_text_node( NULL, val_uint8, &base64 ))) return E_OUTOFMEMORY;
-        if ((hr = read_bytes( reader, base64->bytes, val_uint8 )) != S_OK)
-        {
-            free_node( node );
-            return hr;
-        }
-        break;
-
     case RECORD_BYTES16_TEXT:
     case RECORD_BYTES16_TEXT_WITH_ENDELEMENT:
-        if ((hr = read_bytes( reader, (unsigned char *)&val_uint16, sizeof(val_uint16) )) != S_OK) return hr;
-        if (!(node = alloc_base64_text_node( NULL, val_uint16, &base64 ))) return E_OUTOFMEMORY;
-        if ((hr = read_bytes( reader, base64->bytes, val_uint16 )) != S_OK)
-        {
-            free_node( node );
-            return hr;
-        }
-        break;
-
     case RECORD_BYTES32_TEXT:
     case RECORD_BYTES32_TEXT_WITH_ENDELEMENT:
-        if ((hr = read_bytes( reader, (unsigned char *)&val_int32, sizeof(val_int32) )) != S_OK) return hr;
-        if (val_int32 < 0) return WS_E_INVALID_FORMAT;
-        if (!(node = alloc_base64_text_node( NULL, val_int32, &base64 ))) return E_OUTOFMEMORY;
-        if ((hr = read_bytes( reader, base64->bytes, val_int32 )) != S_OK)
-        {
-            free_node( node );
-            return hr;
-        }
-        break;
+        return read_text_bytes( reader, type );
 
     case RECORD_EMPTY_TEXT:
     case RECORD_EMPTY_TEXT_WITH_ENDELEMENT:
@@ -3822,36 +3883,6 @@ HRESULT WINAPI WsFileTimeToDateTime( const FILETIME *ft, WS_DATETIME *dt, WS_ERR
     return S_OK;
 }
 
-static HRESULT read_get_node_text( struct reader *reader, WS_XML_UTF8_TEXT **ret )
-{
-    WS_XML_TEXT_NODE *node = (WS_XML_TEXT_NODE *)&reader->current->hdr.node;
-    if (node->text->textType != WS_XML_TEXT_TYPE_UTF8)
-    {
-        FIXME( "text type %u not supported\n", node->text->textType );
-        return E_NOTIMPL;
-    }
-    *ret = (WS_XML_UTF8_TEXT *)node->text;
-    return S_OK;
-}
-
-static HRESULT read_get_attribute_text( struct reader *reader, ULONG index, WS_XML_UTF8_TEXT **ret )
-{
-    WS_XML_ELEMENT_NODE *elem = &reader->current->hdr;
-    WS_XML_ATTRIBUTE *attr;
-
-    if (node_type( reader->current ) != WS_XML_NODE_TYPE_ELEMENT)
-        return WS_E_INVALID_FORMAT;
-
-    attr = elem->attributes[index];
-    if (attr->value->textType != WS_XML_TEXT_TYPE_UTF8)
-    {
-        FIXME( "text type %u not supported\n", attr->value->textType );
-        return E_NOTIMPL;
-    }
-    *ret = (WS_XML_UTF8_TEXT *)attr->value;
-    return S_OK;
-}
-
 static BOOL find_attribute( struct reader *reader, const WS_XML_STRING *localname,
                             const WS_XML_STRING *ns, ULONG *index )
 {
@@ -3922,6 +3953,20 @@ HRESULT WINAPI WsFindAttribute( WS_XML_READER *handle, const WS_XML_STRING *loca
     return hr;
 }
 
+static HRESULT get_node_text( struct reader *reader, const WS_XML_TEXT **ret )
+{
+    WS_XML_TEXT_NODE *node = (WS_XML_TEXT_NODE *)&reader->current->hdr.node;
+    *ret = node->text;
+    return S_OK;
+}
+
+static HRESULT get_attribute_text( struct reader *reader, ULONG index, const WS_XML_TEXT **ret )
+{
+    WS_XML_ELEMENT_NODE *elem = &reader->current->hdr;
+    *ret = elem->attributes[index]->value;
+    return S_OK;
+}
+
 static BOOL match_element( const struct node *node, const WS_XML_STRING *localname, const WS_XML_STRING *ns )
 {
     const WS_XML_ELEMENT_NODE *elem = (const WS_XML_ELEMENT_NODE *)node;
@@ -3940,9 +3985,8 @@ static HRESULT read_next_node( struct reader *reader )
     return WS_E_INVALID_FORMAT;
 }
 
-static HRESULT read_get_text( struct reader *reader, WS_TYPE_MAPPING mapping,
-                              const WS_XML_STRING *localname, const WS_XML_STRING *ns,
-                              WS_XML_UTF8_TEXT **ret, BOOL *found )
+static HRESULT get_text( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_XML_STRING *localname,
+                         const WS_XML_STRING *ns, const WS_XML_TEXT **ret, BOOL *found )
 {
     switch (mapping)
     {
@@ -3950,7 +3994,7 @@ static HRESULT read_get_text( struct reader *reader, WS_TYPE_MAPPING mapping,
     {
         ULONG index;
         if (!(*found = find_attribute( reader, localname, ns, &index ))) return S_OK;
-        return read_get_attribute_text( reader, index, ret );
+        return get_attribute_text( reader, index, ret );
     }
     case WS_ELEMENT_TYPE_MAPPING:
     case WS_ELEMENT_CONTENT_TYPE_MAPPING:
@@ -3978,7 +4022,7 @@ static HRESULT read_get_text( struct reader *reader, WS_TYPE_MAPPING mapping,
             *found = FALSE;
             return S_OK;
         }
-        return read_get_node_text( reader, ret );
+        return get_node_text( reader, ret );
     }
     default:
         FIXME( "mapping %u not supported\n", mapping );
@@ -3986,12 +4030,24 @@ static HRESULT read_get_text( struct reader *reader, WS_TYPE_MAPPING mapping,
     }
 }
 
+static const WS_XML_UTF8_TEXT *text_to_utf8( const WS_XML_TEXT *text )
+{
+    assert( text->textType == WS_XML_TEXT_TYPE_UTF8 );
+    return (const WS_XML_UTF8_TEXT *)text;
+}
+
+static const WS_XML_BASE64_TEXT *text_to_base64( const WS_XML_TEXT *text )
+{
+    assert( text->textType == WS_XML_TEXT_TYPE_BASE64 );
+    return (const WS_XML_BASE64_TEXT *)text;
+}
+
 static HRESULT read_type_bool( struct reader *reader, WS_TYPE_MAPPING mapping,
                                const WS_XML_STRING *localname, const WS_XML_STRING *ns,
                                const WS_BOOL_DESCRIPTION *desc, WS_READ_OPTION option,
                                WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     BOOL found, val = FALSE;
 
@@ -4000,9 +4056,10 @@ static HRESULT read_type_bool( struct reader *reader, WS_TYPE_MAPPING mapping,
         FIXME( "description not supported\n" );
         return E_NOTIMPL;
     }
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
     if (found)
     {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
         ULONG len = utf8->value.length;
         if (len == 4 && !memcmp( utf8->value.bytes, "true", 4 )) val = TRUE;
         else if (len == 1 && !memcmp( utf8->value.bytes, "1", 1 )) val = TRUE;
@@ -4052,7 +4109,7 @@ static HRESULT read_type_int8( struct reader *reader, WS_TYPE_MAPPING mapping,
                                const WS_INT8_DESCRIPTION *desc, WS_READ_OPTION option,
                                WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     INT64 val = 0;
     BOOL found;
@@ -4062,9 +4119,13 @@ static HRESULT read_type_int8( struct reader *reader, WS_TYPE_MAPPING mapping,
         FIXME( "description not supported\n" );
         return E_NOTIMPL;
     }
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT8, MAX_INT8, &val )) != S_OK)
-        return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT8, MAX_INT8, &val )) != S_OK)
+            return hr;
+    }
 
     switch (option)
     {
@@ -4107,7 +4168,7 @@ static HRESULT read_type_int16( struct reader *reader, WS_TYPE_MAPPING mapping,
                                 const WS_INT16_DESCRIPTION *desc, WS_READ_OPTION option,
                                 WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     INT64 val = 0;
     BOOL found;
@@ -4117,9 +4178,13 @@ static HRESULT read_type_int16( struct reader *reader, WS_TYPE_MAPPING mapping,
         FIXME( "description not supported\n" );
         return E_NOTIMPL;
     }
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT16, MAX_INT16, &val )) != S_OK)
-        return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT16, MAX_INT16, &val )) != S_OK)
+            return hr;
+    }
 
     switch (option)
     {
@@ -4162,7 +4227,7 @@ static HRESULT read_type_int32( struct reader *reader, WS_TYPE_MAPPING mapping,
                                 const WS_INT32_DESCRIPTION *desc, WS_READ_OPTION option,
                                 WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     INT64 val = 0;
     BOOL found;
@@ -4172,9 +4237,13 @@ static HRESULT read_type_int32( struct reader *reader, WS_TYPE_MAPPING mapping,
         FIXME( "description not supported\n" );
         return E_NOTIMPL;
     }
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT32, MAX_INT32, &val )) != S_OK)
-        return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT32, MAX_INT32, &val )) != S_OK)
+            return hr;
+    }
 
     switch (option)
     {
@@ -4217,7 +4286,7 @@ static HRESULT read_type_int64( struct reader *reader, WS_TYPE_MAPPING mapping,
                                 const WS_INT64_DESCRIPTION *desc, WS_READ_OPTION option,
                                 WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     INT64 val = 0;
     BOOL found;
@@ -4227,9 +4296,13 @@ static HRESULT read_type_int64( struct reader *reader, WS_TYPE_MAPPING mapping,
         FIXME( "description not supported\n" );
         return E_NOTIMPL;
     }
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT64, MAX_INT64, &val )) != S_OK)
-        return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT64, MAX_INT64, &val )) != S_OK)
+            return hr;
+    }
 
     switch (option)
     {
@@ -4272,7 +4345,7 @@ static HRESULT read_type_uint8( struct reader *reader, WS_TYPE_MAPPING mapping,
                                 const WS_UINT8_DESCRIPTION *desc, WS_READ_OPTION option,
                                 WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     UINT64 val = 0;
     BOOL found;
@@ -4282,9 +4355,13 @@ static HRESULT read_type_uint8( struct reader *reader, WS_TYPE_MAPPING mapping,
         FIXME( "description not supported\n" );
         return E_NOTIMPL;
     }
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT8, &val )) != S_OK)
-        return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT8, &val )) != S_OK)
+            return hr;
+    }
 
     switch (option)
     {
@@ -4327,7 +4404,7 @@ static HRESULT read_type_uint16( struct reader *reader, WS_TYPE_MAPPING mapping,
                                  const WS_UINT16_DESCRIPTION *desc, WS_READ_OPTION option,
                                  WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     UINT64 val = 0;
     BOOL found;
@@ -4337,9 +4414,13 @@ static HRESULT read_type_uint16( struct reader *reader, WS_TYPE_MAPPING mapping,
         FIXME( "description not supported\n" );
         return E_NOTIMPL;
     }
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT16, &val )) != S_OK)
-        return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT16, &val )) != S_OK)
+            return hr;
+    }
 
     switch (option)
     {
@@ -4382,7 +4463,7 @@ static HRESULT read_type_uint32( struct reader *reader, WS_TYPE_MAPPING mapping,
                                  const WS_UINT32_DESCRIPTION *desc, WS_READ_OPTION option,
                                  WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     UINT64 val = 0;
     BOOL found;
@@ -4392,9 +4473,13 @@ static HRESULT read_type_uint32( struct reader *reader, WS_TYPE_MAPPING mapping,
         FIXME( "description not supported\n" );
         return E_NOTIMPL;
     }
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT32, &val )) != S_OK)
-        return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT32, &val )) != S_OK)
+            return hr;
+    }
 
     switch (option)
     {
@@ -4437,7 +4522,7 @@ static HRESULT read_type_uint64( struct reader *reader, WS_TYPE_MAPPING mapping,
                                  const WS_UINT64_DESCRIPTION *desc, WS_READ_OPTION option,
                                  WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     UINT64 val = 0;
     BOOL found;
@@ -4447,9 +4532,13 @@ static HRESULT read_type_uint64( struct reader *reader, WS_TYPE_MAPPING mapping,
         FIXME( "description not supported\n" );
         return E_NOTIMPL;
     }
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT64, &val )) != S_OK)
-        return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT64, &val )) != S_OK)
+            return hr;
+    }
 
     switch (option)
     {
@@ -4492,15 +4581,19 @@ static HRESULT read_type_double( struct reader *reader, WS_TYPE_MAPPING mapping,
                                  const WS_DOUBLE_DESCRIPTION *desc, WS_READ_OPTION option,
                                  WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     double val = 0.0;
     BOOL found;
 
     if (desc) FIXME( "ignoring description\n" );
 
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_double( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_double( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr;
+    }
 
     switch (option)
     {
@@ -4543,7 +4636,7 @@ static HRESULT read_type_wsz( struct reader *reader, WS_TYPE_MAPPING mapping,
                               const WS_WSZ_DESCRIPTION *desc, WS_READ_OPTION option,
                               WS_HEAP *heap, WCHAR **ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     WCHAR *str = NULL;
     BOOL found;
@@ -4553,13 +4646,13 @@ static HRESULT read_type_wsz( struct reader *reader, WS_TYPE_MAPPING mapping,
         FIXME( "description not supported\n" );
         return E_NOTIMPL;
     }
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && !(str = xmltext_to_widechar( heap, &utf8->text ))) return WS_E_QUOTA_EXCEEDED;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found && !(str = xmltext_to_widechar( heap, text ))) return WS_E_QUOTA_EXCEEDED;
 
     switch (option)
     {
     case WS_READ_REQUIRED_POINTER:
-        if (!found && !(str = ws_alloc_zero( heap, 1 ))) return WS_E_QUOTA_EXCEEDED;
+        if (!str && !(str = ws_alloc_zero( heap, sizeof(*str) ))) return WS_E_QUOTA_EXCEEDED;
         /* fall through */
 
     case WS_READ_OPTIONAL_POINTER:
@@ -4595,15 +4688,19 @@ static HRESULT read_type_enum( struct reader *reader, WS_TYPE_MAPPING mapping,
                                const WS_ENUM_DESCRIPTION *desc, WS_READ_OPTION option,
                                WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     int val = 0;
     BOOL found;
 
     if (!desc) return E_INVALIDARG;
 
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = get_enum_value( utf8, desc, &val )) != S_OK) return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = get_enum_value( utf8, desc, &val )) != S_OK) return hr;
+    }
 
     switch (option)
     {
@@ -4646,15 +4743,19 @@ static HRESULT read_type_datetime( struct reader *reader, WS_TYPE_MAPPING mappin
                                    const WS_DATETIME_DESCRIPTION *desc, WS_READ_OPTION option,
                                    WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     HRESULT hr;
     WS_DATETIME val = {0, WS_DATETIME_FORMAT_UTC};
     BOOL found;
 
     if (desc) FIXME( "ignoring description\n" );
 
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_datetime( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_datetime( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr;
+    }
 
     switch (option)
     {
@@ -4697,15 +4798,19 @@ static HRESULT read_type_guid( struct reader *reader, WS_TYPE_MAPPING mapping,
                                const WS_GUID_DESCRIPTION *desc, WS_READ_OPTION option,
                                WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     GUID val = {0};
     HRESULT hr;
     BOOL found;
 
     if (desc) FIXME( "ignoring description\n" );
 
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_guid( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_guid( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr;
+    }
 
     switch (option)
     {
@@ -4748,15 +4853,19 @@ static HRESULT read_type_unique_id( struct reader *reader, WS_TYPE_MAPPING mappi
                                     const WS_UNIQUE_ID_DESCRIPTION *desc, WS_READ_OPTION option,
                                     WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     WS_UNIQUE_ID val = {{0}};
     HRESULT hr;
     BOOL found;
 
     if (desc) FIXME( "ignoring description\n" );
 
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_unique_id( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK) return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_unique_id( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK) return hr;
+    }
 
     switch (option)
     {
@@ -4799,16 +4908,20 @@ static HRESULT read_type_string( struct reader *reader, WS_TYPE_MAPPING mapping,
                                  const WS_STRING_DESCRIPTION *desc, WS_READ_OPTION option,
                                  WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     WS_STRING val = {0};
     HRESULT hr;
     BOOL found;
 
     if (desc) FIXME( "ignoring description\n" );
 
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_string( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK)
-        return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_string( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK)
+            return hr;
+    }
 
     switch (option)
     {
@@ -4853,16 +4966,38 @@ static HRESULT read_type_bytes( struct reader *reader, WS_TYPE_MAPPING mapping,
                                 const WS_BYTES_DESCRIPTION *desc, WS_READ_OPTION option,
                                 WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     WS_BYTES val = {0};
     HRESULT hr;
     BOOL found;
 
     if (desc) FIXME( "ignoring description\n" );
 
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_bytes( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK)
-        return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        switch (reader->input_enc)
+        {
+        case WS_XML_READER_ENCODING_TYPE_TEXT:
+        {
+            const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+            if ((hr = str_to_bytes( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK)
+                return hr;
+            break;
+        }
+        case WS_XML_READER_ENCODING_TYPE_BINARY:
+        {
+            const WS_XML_BASE64_TEXT *base64 = text_to_base64( text );
+            if (!(val.bytes = ws_alloc( heap, base64->length ))) return WS_E_QUOTA_EXCEEDED;
+            memcpy( val.bytes, base64->bytes, base64->length );
+            val.length = base64->length;
+            break;
+        }
+        default:
+            FIXME( "unhandled input encoding %u\n", reader->input_enc );
+            return WS_E_NOT_SUPPORTED;
+        }
+    }
 
     switch (option)
     {
@@ -4907,16 +5042,20 @@ static HRESULT read_type_xml_string( struct reader *reader, WS_TYPE_MAPPING mapp
                                      const WS_XML_STRING_DESCRIPTION *desc, WS_READ_OPTION option,
                                      WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     WS_XML_STRING val = {0};
     HRESULT hr;
     BOOL found;
 
     if (desc) FIXME( "ignoring description\n" );
 
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_xml_string( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK)
-        return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_xml_string( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK)
+            return hr;
+    }
 
     switch (option)
     {
@@ -4961,7 +5100,7 @@ static HRESULT read_type_qname( struct reader *reader, WS_TYPE_MAPPING mapping,
                                 const WS_XML_QNAME_DESCRIPTION *desc, WS_READ_OPTION option,
                                 WS_HEAP *heap, void *ret, ULONG size )
 {
-    WS_XML_UTF8_TEXT *utf8;
+    const WS_XML_TEXT *text;
     WS_XML_QNAME val = {{0}};
     HRESULT hr;
     BOOL found;
@@ -4972,9 +5111,13 @@ static HRESULT read_type_qname( struct reader *reader, WS_TYPE_MAPPING mapping,
     if ((hr = read_startelement( reader )) != S_OK) return hr;
     if (node_type( reader->current ) != WS_XML_NODE_TYPE_TEXT) return WS_E_INVALID_FORMAT;
 
-    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
-    if (found && (hr = str_to_qname( reader, utf8->value.bytes, utf8->value.length, heap,
-                                     NULL, &val.localName, &val.ns )) != S_OK) return hr;
+    if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
+    if (found)
+    {
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text );
+        if ((hr = str_to_qname( reader, utf8->value.bytes, utf8->value.length, heap, NULL,
+                                &val.localName, &val.ns )) != S_OK) return hr;
+    }
 
     switch (option)
     {
@@ -5015,18 +5158,26 @@ static HRESULT read_type_qname( struct reader *reader, WS_TYPE_MAPPING mapping,
 static BOOL is_empty_text_node( const struct node *node )
 {
     const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)node;
-    const WS_XML_UTF8_TEXT *utf8;
-    ULONG i;
 
     if (node_type( node ) != WS_XML_NODE_TYPE_TEXT) return FALSE;
-    if (text->text->textType != WS_XML_TEXT_TYPE_UTF8)
+    switch (text->text->textType)
+    {
+    case WS_XML_TEXT_TYPE_UTF8:
+    {
+        ULONG i;
+        const WS_XML_UTF8_TEXT *utf8 = text_to_utf8( text->text );
+        for (i = 0; i < utf8->value.length; i++) if (!read_isspace( utf8->value.bytes[i] )) return FALSE;
+        return TRUE;
+    }
+    case WS_XML_TEXT_TYPE_BASE64:
     {
+        const WS_XML_BASE64_TEXT *base64 = text_to_base64( text->text );
+        return !base64->length;
+    }
+    default:
         ERR( "unhandled text type %u\n", text->text->textType );
         return FALSE;
     }
-    utf8 = (const WS_XML_UTF8_TEXT *)text->text;
-    for (i = 0; i < utf8->value.length; i++) if (!read_isspace( utf8->value.bytes[i] )) return FALSE;
-    return TRUE;
 }
 
 /* skips comment and empty text nodes */
@@ -5316,7 +5467,6 @@ static HRESULT read_type_union( struct reader *reader, const WS_UNION_DESCRIPTIO
     return S_OK;
 }
 
-
 static HRESULT read_type_field( struct reader *reader, const WS_FIELD_DESCRIPTION *desc, WS_HEAP *heap, char *buf,
                                 ULONG offset )
 {
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index ce8590a..3d90ca0 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -4804,6 +4804,7 @@ static HRESULT set_input_bin( WS_XML_READER *reader, const char *data, ULONG siz
 
 static void test_binary_encoding(void)
 {
+    static WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
     static const char test[] =
         {0x40,0x01,'t',0x01};
     static const char test2[] =
@@ -4813,9 +4814,9 @@ static void test_binary_encoding(void)
     static const char test4[] =
         {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x99,0x04,'t','e','s','t'};
     static const char test5[] =
-        {0x40,0x01,'t',0xa0,0x01,0x00,'a',0x9f,0x01,'b'};
+        {0x40,0x01,'t',0x9f,0x01,'a'};
     static const char test6[] =
-        {0x40,0x01,'t',0x9e,0x01,'a',0x9f,0x01,'b'};
+        {0x40,0x01,'t',0xa0,0x01,0x00,'a',0x9f,0x01,'b'};
     static const char test100[] =
         {0x40,0x01,'t',0x04,0x01,'t',0x98,0x00,0x01};
     static const char test101[] =
@@ -4826,7 +4827,7 @@ static void test_binary_encoding(void)
         {0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x04,'t','e','s','t',0x09,0x02,'p','2',0x02,'n','s',0x01};
     static const char test200[] =
         {0x02,0x07,'c','o','m','m','e','n','t'};
-    const WS_XML_NODE *node, *node2;
+    const WS_XML_NODE *node;
     const WS_XML_ELEMENT_NODE *elem;
     const WS_XML_ATTRIBUTE *attr;
     const WS_XML_TEXT_NODE *text;
@@ -4834,8 +4835,15 @@ static void test_binary_encoding(void)
     const WS_XML_BASE64_TEXT *base64;
     const WS_XML_COMMENT_NODE *comment;
     WS_XML_READER *reader;
+    WS_HEAP *heap;
     BOOL found;
     HRESULT hr;
+    WS_STRUCT_DESCRIPTION s;
+    WS_FIELD_DESCRIPTION f, *fields[1];
+    struct typetest
+    {
+        WS_BYTES data;
+    } *typetest;
 
     hr = WsCreateReader( NULL, 0, &reader, NULL );
     ok( hr == S_OK, "got %08x\n", hr );
@@ -5176,7 +5184,7 @@ static void test_binary_encoding(void)
     hr = WsReadEndElement( reader, NULL );
     ok( hr == S_OK, "got %08x\n", hr );
 
-    /* element with different byte record types */
+    /* element with byte record text */
     hr = set_input_bin( reader, test5, sizeof(test5), NULL );
     ok( hr == S_OK, "got %08x\n", hr );
 
@@ -5193,51 +5201,34 @@ static void test_binary_encoding(void)
     ok( base64->length == 1, "got %u\n", base64->length );
     ok( base64->bytes[0] == 'a', "wrong data %02x\n", base64->bytes[0] );
 
-    hr = WsReadNode( reader, NULL );
-    ok( hr == S_OK, "got %08x\n", hr );
-    hr = WsGetReaderNode( reader, &node2, NULL );
-    ok( hr == S_OK, "got %08x\n", hr );
-    todo_wine ok( node2 == node, "different node\n" );
-    ok( node2->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node2->nodeType );
-    text = (const WS_XML_TEXT_NODE *)node2;
-    ok( text->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text->text->textType );
-    base64 = (const WS_XML_BASE64_TEXT *)text->text;
-    ok( base64->length == 1, "got %u\n", base64->length );
-    ok( base64->bytes[0] == 'b', "wrong data %02x\n", base64->bytes[0] );
-    hr = WsReadNode( reader, NULL );
-    ok( hr == S_OK, "got %08x\n", hr );
-
-    /* element with equal byte record types */
+    /* element with mixed byte record text */
     hr = set_input_bin( reader, test6, sizeof(test6), NULL );
     ok( hr == S_OK, "got %08x\n", hr );
 
-    hr = WsReadNode( reader, NULL );
-    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 );
+    hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, 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_BASE64, "got %u\n", text->text->textType );
-    base64 = (const WS_XML_BASE64_TEXT *)text->text;
-    ok( base64->length == 1, "got %u\n", base64->length );
-    ok( base64->bytes[0] == 'a', "wrong data %02x\n", base64->bytes[0] );
 
-    hr = WsReadNode( reader, NULL );
-    ok( hr == S_OK, "got %08x\n", hr );
-    hr = WsGetReaderNode( reader, &node2, NULL );
-    ok( hr == S_OK, "got %08x\n", hr );
-    todo_wine ok( node2 == node, "different node\n" );
-    ok( node2->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node2->nodeType );
-    text = (const WS_XML_TEXT_NODE *)node2;
-    ok( text->text->textType == WS_XML_TEXT_TYPE_BASE64, "got %u\n", text->text->textType );
-    base64 = (const WS_XML_BASE64_TEXT *)text->text;
-    ok( base64->length == 1, "got %u\n", base64->length );
-    ok( base64->bytes[0] == 'b', "wrong data %02x\n", base64->bytes[0] );
-    hr = WsReadNode( reader, NULL );
+    memset( &f, 0, sizeof(f) );
+    f.mapping      = WS_ELEMENT_FIELD_MAPPING;
+    f.localName    = &localname;
+    f.ns           = &ns;
+    f.type         = WS_BYTES_TYPE;
+    f.offset       = FIELD_OFFSET(struct typetest, data);
+    fields[0] = &f;
+
+    memset( &s, 0, sizeof(s) );
+    s.size       = sizeof(struct typetest);
+    s.alignment  = TYPE_ALIGNMENT(struct typetest);
+    s.fields     = fields;
+    s.fieldCount = 1;
+
+    hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
+                     WS_READ_REQUIRED_POINTER, heap, &typetest, sizeof(typetest), NULL );
     ok( hr == S_OK, "got %08x\n", hr );
+    ok( typetest->data.length == 2, "got %u\n", typetest->data.length );
+    ok( !memcmp( typetest->data.bytes, "ab", 2 ), "wrong data\n" );
 
+    WsFreeHeap( heap );
     WsFreeReader( reader );
 }
 
-- 
2.1.4




More information about the wine-patches mailing list