[PATCH 2/6] webservices: Take the output encoding into account in WsCopyNode.

Hans Leidekker hans at codeweavers.com
Wed Jan 24 07:29:58 CST 2018


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/webservices/reader.c              | 95 +++++++++++++++++++++-------------
 dlls/webservices/webservices_private.h |  5 +-
 dlls/webservices/writer.c              |  8 +--
 3 files changed, 65 insertions(+), 43 deletions(-)

diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 3e5434cf64..bdf950ec29 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -143,29 +143,36 @@ void destroy_nodes( struct node *node )
     free_node( node );
 }
 
-static WS_XML_ATTRIBUTE *dup_attribute( const WS_XML_ATTRIBUTE *src )
+static WS_XML_ATTRIBUTE *dup_attribute( const WS_XML_ATTRIBUTE *src, WS_XML_WRITER_ENCODING_TYPE enc )
 {
     WS_XML_ATTRIBUTE *dst;
-    const WS_XML_STRING *prefix = src->prefix;
-    const WS_XML_STRING *localname = src->localName;
-    const WS_XML_STRING *ns = src->localName;
-    const WS_XML_TEXT *text = src->value;
+    HRESULT hr;
 
-    if (!(dst = heap_alloc( sizeof(*dst) ))) return NULL;
+    if (!(dst = heap_alloc_zero( sizeof(*dst) ))) return NULL;
     dst->singleQuote = src->singleQuote;
     dst->isXmlNs     = src->isXmlNs;
 
-    if (!prefix) dst->prefix = NULL;
-    else if (!(dst->prefix = dup_xml_string( prefix, FALSE ))) goto error;
-    if (!(dst->localName = dup_xml_string( localname, FALSE ))) goto error;
-    if (!(dst->ns = dup_xml_string( ns, FALSE ))) goto error;
+    if (src->prefix && !(dst->prefix = dup_xml_string( src->prefix, FALSE ))) goto error;
+    if (src->localName && !(dst->localName = dup_xml_string( src->localName, FALSE ))) goto error;
+    if (src->ns && !(dst->ns = dup_xml_string( src->ns, FALSE ))) goto error;
 
-    if (text)
+    if (src->value)
     {
-        WS_XML_UTF8_TEXT *utf8;
-        const WS_XML_UTF8_TEXT *utf8_src = (const WS_XML_UTF8_TEXT *)text;
-        if (!(utf8 = alloc_utf8_text( utf8_src->value.bytes, utf8_src->value.length ))) goto error;
-        dst->value = &utf8->text;
+        switch (enc)
+        {
+        case WS_XML_WRITER_ENCODING_TYPE_BINARY:
+            if ((hr = text_to_text( src->value, NULL, NULL, &dst->value )) != S_OK) goto error;
+            break;
+
+        case WS_XML_WRITER_ENCODING_TYPE_TEXT:
+            if ((hr = text_to_utf8text( src->value, NULL, NULL, (WS_XML_UTF8_TEXT **)&dst->value )) != S_OK)
+                goto error;
+            break;
+
+        default:
+            ERR( "unhandled encoding %u\n", enc );
+            goto error;
+        }
     }
 
     return dst;
@@ -175,7 +182,8 @@ error:
     return NULL;
 }
 
-static WS_XML_ATTRIBUTE **dup_attributes( WS_XML_ATTRIBUTE * const *src, ULONG count )
+static WS_XML_ATTRIBUTE **dup_attributes( WS_XML_ATTRIBUTE * const *src, ULONG count,
+                                          WS_XML_WRITER_ENCODING_TYPE enc )
 {
     WS_XML_ATTRIBUTE **dst;
     ULONG i;
@@ -183,7 +191,7 @@ static WS_XML_ATTRIBUTE **dup_attributes( WS_XML_ATTRIBUTE * const *src, ULONG c
     if (!(dst = heap_alloc( sizeof(*dst) * count ))) return NULL;
     for (i = 0; i < count; i++)
     {
-        if (!(dst[i] = dup_attribute( src[i] )))
+        if (!(dst[i] = dup_attribute( src[i], enc )))
         {
             for (; i > 0; i--) free_attribute( dst[i - 1] );
             heap_free( dst );
@@ -193,7 +201,7 @@ static WS_XML_ATTRIBUTE **dup_attributes( WS_XML_ATTRIBUTE * const *src, ULONG c
     return dst;
 }
 
-static struct node *dup_element_node( const WS_XML_ELEMENT_NODE *src )
+static struct node *dup_element_node( const WS_XML_ELEMENT_NODE *src, WS_XML_WRITER_ENCODING_TYPE enc )
 {
     struct node *node;
     WS_XML_ELEMENT_NODE *dst;
@@ -206,7 +214,7 @@ static struct node *dup_element_node( const WS_XML_ELEMENT_NODE *src )
     if (!(node = alloc_node( WS_XML_NODE_TYPE_ELEMENT ))) return NULL;
     dst = &node->hdr;
 
-    if (count && !(dst->attributes = dup_attributes( attrs, count ))) goto error;
+    if (count && !(dst->attributes = dup_attributes( attrs, count, enc ))) goto error;
     dst->attributeCount = count;
 
     if (prefix && !(dst->prefix = dup_xml_string( prefix, FALSE ))) goto error;
@@ -219,25 +227,38 @@ error:
     return NULL;
 }
 
-static struct node *dup_text_node( const WS_XML_TEXT_NODE *src )
+static struct node *dup_text_node( const WS_XML_TEXT_NODE *src, WS_XML_WRITER_ENCODING_TYPE enc )
 {
     struct node *node;
     WS_XML_TEXT_NODE *dst;
+    HRESULT hr;
 
     if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return NULL;
     dst = (WS_XML_TEXT_NODE *)node;
+    if (!src->text) return node;
 
-    if (src->text)
+    switch (enc)
     {
-        WS_XML_UTF8_TEXT *utf8;
-        const WS_XML_UTF8_TEXT *utf8_src = (const WS_XML_UTF8_TEXT *)src->text;
-        if (!(utf8 = alloc_utf8_text( utf8_src->value.bytes, utf8_src->value.length )))
-        {
-            free_node( node );
-            return NULL;
-        }
-        dst->text = &utf8->text;
+    case WS_XML_WRITER_ENCODING_TYPE_BINARY:
+        hr = text_to_text( src->text, NULL, NULL, &dst->text );
+        break;
+
+    case WS_XML_WRITER_ENCODING_TYPE_TEXT:
+        hr = text_to_utf8text( src->text, NULL, NULL, (WS_XML_UTF8_TEXT **)&dst->text );
+        break;
+
+    default:
+        ERR( "unhandled encoding %u\n", enc );
+        free_node( node );
+        return NULL;
     }
+
+    if (hr != S_OK)
+    {
+        free_node( node );
+        return NULL;
+    }
+
     return node;
 }
 
@@ -259,15 +280,15 @@ static struct node *dup_comment_node( const WS_XML_COMMENT_NODE *src )
     return node;
 }
 
-static struct node *dup_node( const struct node *src )
+static struct node *dup_node( const struct node *src, WS_XML_WRITER_ENCODING_TYPE enc )
 {
     switch (node_type( src ))
     {
     case WS_XML_NODE_TYPE_ELEMENT:
-        return dup_element_node( &src->hdr );
+        return dup_element_node( &src->hdr, enc );
 
     case WS_XML_NODE_TYPE_TEXT:
-        return dup_text_node( (const WS_XML_TEXT_NODE *)src );
+        return dup_text_node( (const WS_XML_TEXT_NODE *)src, enc );
 
     case WS_XML_NODE_TYPE_COMMENT:
         return dup_comment_node( (const WS_XML_COMMENT_NODE *)src );
@@ -286,12 +307,12 @@ static struct node *dup_node( const struct node *src )
     return NULL;
 }
 
-static HRESULT dup_tree( struct node **dst, const struct node *src )
+static HRESULT dup_tree( const struct node *src, WS_XML_WRITER_ENCODING_TYPE enc, struct node **dst )
 {
     struct node *parent;
     const struct node *child;
 
-    if (!*dst && !(*dst = dup_node( src ))) return E_OUTOFMEMORY;
+    if (!*dst && !(*dst = dup_node( src, enc ))) return E_OUTOFMEMORY;
     parent = *dst;
 
     LIST_FOR_EACH_ENTRY( child, &src->children, struct node, entry )
@@ -299,7 +320,7 @@ static HRESULT dup_tree( struct node **dst, const struct node *src )
         HRESULT hr = E_OUTOFMEMORY;
         struct node *new_child;
 
-        if (!(new_child = dup_node( child )) || (hr = dup_tree( &new_child, child )) != S_OK)
+        if (!(new_child = dup_node( child, enc )) || (hr = dup_tree( child, enc, &new_child )) != S_OK)
         {
             destroy_nodes( *dst );
             return hr;
@@ -2970,7 +2991,7 @@ static HRESULT read_node( struct reader *reader )
     }
 }
 
-HRESULT copy_node( WS_XML_READER *handle, struct node **node )
+HRESULT copy_node( WS_XML_READER *handle, WS_XML_WRITER_ENCODING_TYPE enc, struct node **node )
 {
     struct reader *reader = (struct reader *)handle;
     const struct list *ptr;
@@ -3001,7 +3022,7 @@ HRESULT copy_node( WS_XML_READER *handle, struct node **node )
 
     start = LIST_ENTRY( ptr, struct node, entry );
     if (node_type( start ) == WS_XML_NODE_TYPE_EOF) hr = WS_E_INVALID_OPERATION;
-    else hr = dup_tree( node, start );
+    else hr = dup_tree( start, enc, node );
 
 done:
     LeaveCriticalSection( &reader->cs );
diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h
index e477e0fc3f..3f6d2f4492 100644
--- a/dlls/webservices/webservices_private.h
+++ b/dlls/webservices/webservices_private.h
@@ -66,7 +66,8 @@ ULONG get_type_size( WS_TYPE, const void * ) DECLSPEC_HIDDEN;
 HRESULT read_header( WS_XML_READER *, const WS_XML_STRING *, const WS_XML_STRING *, WS_TYPE,
                      const void *, WS_READ_OPTION, WS_HEAP *, void *, ULONG ) DECLSPEC_HIDDEN;
 HRESULT create_header_buffer( WS_XML_READER *, WS_HEAP *, WS_XML_BUFFER ** ) DECLSPEC_HIDDEN;
-
+HRESULT text_to_text( const WS_XML_TEXT *, const WS_XML_TEXT *, ULONG *, WS_XML_TEXT ** ) DECLSPEC_HIDDEN;
+HRESULT text_to_utf8text( const WS_XML_TEXT *, const WS_XML_UTF8_TEXT *, ULONG *, WS_XML_UTF8_TEXT ** ) DECLSPEC_HIDDEN;
 WS_XML_UTF8_TEXT *alloc_utf8_text( const BYTE *, ULONG ) DECLSPEC_HIDDEN;
 WS_XML_UTF16_TEXT *alloc_utf16_text( const BYTE *, ULONG ) DECLSPEC_HIDDEN;
 WS_XML_BASE64_TEXT *alloc_base64_text( const BYTE *, ULONG ) DECLSPEC_HIDDEN;
@@ -105,7 +106,7 @@ struct node
 struct node *alloc_node( WS_XML_NODE_TYPE ) DECLSPEC_HIDDEN;
 void free_node( struct node * ) DECLSPEC_HIDDEN;
 void destroy_nodes( struct node * ) DECLSPEC_HIDDEN;
-HRESULT copy_node( WS_XML_READER *, struct node ** ) DECLSPEC_HIDDEN;
+HRESULT copy_node( WS_XML_READER *, WS_XML_WRITER_ENCODING_TYPE, struct node ** ) DECLSPEC_HIDDEN;
 
 static inline WS_XML_NODE_TYPE node_type( const struct node *node )
 {
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index be2994af83..08b341034e 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -1034,8 +1034,8 @@ static ULONG encode_base64( const unsigned char *bin, ULONG len, unsigned char *
     return i;
 }
 
-static HRESULT text_to_utf8text( const WS_XML_TEXT *text, const WS_XML_UTF8_TEXT *old, ULONG *offset,
-                                 WS_XML_UTF8_TEXT **ret )
+HRESULT text_to_utf8text( const WS_XML_TEXT *text, const WS_XML_UTF8_TEXT *old, ULONG *offset,
+                          WS_XML_UTF8_TEXT **ret )
 {
     ULONG len_old = old ? old->value.length : 0;
     if (offset) *offset = len_old;
@@ -2254,7 +2254,7 @@ HRESULT WINAPI WsWriteStartElement( WS_XML_WRITER *handle, const WS_XML_STRING *
     return hr;
 }
 
-static HRESULT text_to_text( const WS_XML_TEXT *text, const WS_XML_TEXT *old, ULONG *offset, WS_XML_TEXT **ret )
+HRESULT text_to_text( const WS_XML_TEXT *text, const WS_XML_TEXT *old, ULONG *offset, WS_XML_TEXT **ret )
 {
     if (offset) *offset = 0;
     switch (text->textType)
@@ -4758,7 +4758,7 @@ HRESULT WINAPI WsCopyNode( WS_XML_WRITER *handle, WS_XML_READER *reader, WS_ERRO
         return WS_E_INVALID_FORMAT;
     }
 
-    if ((hr = copy_node( reader, &node )) != S_OK) goto done;
+    if ((hr = copy_node( reader, writer->output_enc, &node )) != S_OK) goto done;
     current = writer->current;
     write_insert_node( writer, parent, node );
 
-- 
2.11.0




More information about the wine-devel mailing list