webservices: Avoid writing redundant namespace attributes.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2015-11-11 11:02:03 +01:00 committed by Alexandre Julliard
parent c08fb1a211
commit e9435db25f
1 changed files with 23 additions and 2 deletions

View File

@ -73,6 +73,7 @@ struct writer
enum writer_state state; enum writer_state state;
struct node *root; struct node *root;
struct node *current; struct node *current;
WS_XML_STRING *current_ns;
WS_XML_WRITER_OUTPUT_TYPE output_type; WS_XML_WRITER_OUTPUT_TYPE output_type;
struct xmlbuf *output_buf; struct xmlbuf *output_buf;
WS_HEAP *output_heap; WS_HEAP *output_heap;
@ -123,6 +124,7 @@ static HRESULT get_writer_prop( struct writer *writer, WS_XML_WRITER_PROPERTY_ID
static void free_writer( struct writer *writer ) static void free_writer( struct writer *writer )
{ {
destroy_nodes( writer->root ); destroy_nodes( writer->root );
heap_free( writer->current_ns );
WsFreeHeap( writer->output_heap ); WsFreeHeap( writer->output_heap );
heap_free( writer ); heap_free( writer );
} }
@ -161,8 +163,11 @@ static HRESULT write_init_state( struct writer *writer )
{ {
struct node *node; struct node *node;
heap_free( writer->current_ns );
writer->current_ns = NULL;
destroy_nodes( writer->root ); destroy_nodes( writer->root );
writer->root = NULL; writer->root = NULL;
if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY; if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
write_insert_eof( writer, node ); write_insert_eof( writer, node );
writer->state = WRITER_STATE_INITIAL; writer->state = WRITER_STATE_INITIAL;
@ -476,6 +481,20 @@ static HRESULT write_attribute( struct writer *writer, WS_XML_ATTRIBUTE *attr )
return S_OK; return S_OK;
} }
static inline BOOL is_current_namespace( struct writer *writer, const WS_XML_STRING *ns )
{
return (WsXmlStringEquals( writer->current_ns, ns, NULL ) == S_OK);
}
static HRESULT set_current_namespace( struct writer *writer, const WS_XML_STRING *ns )
{
WS_XML_STRING *str;
if (!(str = alloc_xml_string( (const char *)ns->bytes, ns->length ))) return E_OUTOFMEMORY;
heap_free( writer->current_ns );
writer->current_ns = str;
return S_OK;
}
static HRESULT write_startelement( struct writer *writer ) static HRESULT write_startelement( struct writer *writer )
{ {
WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)writer->current; WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)writer->current;
@ -486,7 +505,7 @@ static HRESULT write_startelement( struct writer *writer )
size = elem->localName->length + 1 /* '<' */; size = elem->localName->length + 1 /* '<' */;
if (elem->prefix) size += elem->prefix->length + 1 /* ':' */; if (elem->prefix) size += elem->prefix->length + 1 /* ':' */;
if (elem->ns->length) if (elem->ns->length && !is_current_namespace( writer, elem->ns ))
{ {
size += strlen(" xmlns") + elem->ns->length + 3 /* '=""' */; size += strlen(" xmlns") + elem->ns->length + 3 /* '=""' */;
if (elem->prefix) size += elem->prefix->length + 1 /* ':' */; if (elem->prefix) size += elem->prefix->length + 1 /* ':' */;
@ -504,8 +523,10 @@ static HRESULT write_startelement( struct writer *writer )
{ {
if ((hr = write_attribute( writer, elem->attributes[i] )) != S_OK) return hr; if ((hr = write_attribute( writer, elem->attributes[i] )) != S_OK) return hr;
} }
if (elem->ns->length) if (elem->ns->length && !is_current_namespace( writer, elem->ns ))
{ {
if ((hr = set_current_namespace( writer, elem->ns )) != S_OK) return hr;
write_bytes( writer, (const BYTE *)" xmlns", 6 ); write_bytes( writer, (const BYTE *)" xmlns", 6 );
if (elem->prefix) if (elem->prefix)
{ {