webservices: Take the output encoding into account in WsCopyNode.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2018-01-24 14:29:58 +01:00 committed by Alexandre Julliard
parent 008efda737
commit a3f80e3ab5
3 changed files with 65 additions and 43 deletions

View File

@ -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 );

View File

@ -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 )
{

View File

@ -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 );