Module: wine Branch: master Commit: acf64c4e68510915c79dc482bbf926b65bd09389 URL: http://source.winehq.org/git/wine.git/?a=commit;h=acf64c4e68510915c79dc482bb...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Jun 15 09:21:20 2016 +0200
webservices: Avoid writing redundant namespace attributes.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/webservices/tests/writer.c | 15 +++++++++++++++ dlls/webservices/writer.c | 29 ++++++++++++++++++----------- 2 files changed, 33 insertions(+), 11 deletions(-)
diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index 4f6b1b1..4e22887 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -1072,6 +1072,7 @@ static void test_WsWriteXmlnsAttribute(void) WS_XML_STRING ns = {2, (BYTE *)"ns"}, ns2 = {3, (BYTE *)"ns2"}; WS_XML_STRING prefix = {6, (BYTE *)"prefix"}, prefix2 = {7, (BYTE *)"prefix2"}; WS_XML_STRING xmlns = {6, (BYTE *)"xmlns"}, attr = {4, (BYTE *)"attr"}; + WS_XML_STRING localname = {1, (BYTE *)"u"}; WS_HEAP *heap; WS_XML_BUFFER *buffer; WS_XML_WRITER *writer; @@ -1211,6 +1212,20 @@ static void test_WsWriteXmlnsAttribute(void) check_output_buffer( buffer, "<prefix:t prefix:attr='' xmlns:prefix='ns' xmlns:prefix2='ns2'/>", __LINE__ ); WsFreeHeap( heap );
+ /* scope */ + prepare_xmlns_test( writer, &heap, &buffer ); + hr = WsWriteXmlnsAttribute( writer, &prefix2, &ns2, TRUE, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteStartElement( writer, &prefix2, &localname, &ns2, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output_buffer( buffer, "<prefix:t xmlns:prefix2='ns2' xmlns:prefix="ns">prefix2:u/</prefix:t>", + __LINE__ ); + WsFreeHeap( heap ); + WsFreeWriter( writer ); }
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 20e17d0..ecbba37 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -633,21 +633,28 @@ static HRESULT write_add_namespace_attribute( struct writer *writer, const WS_XM return S_OK; }
-static const WS_XML_ATTRIBUTE *find_namespace_attribute( const WS_XML_ELEMENT_NODE *elem, - const WS_XML_STRING *prefix, - const WS_XML_STRING *ns ) +static BOOL namespace_in_scope( const WS_XML_ELEMENT_NODE *elem, const WS_XML_STRING *prefix, + const WS_XML_STRING *ns ) { ULONG i; - for (i = 0; i < elem->attributeCount; i++) + const struct node *node; + + for (node = (const struct node *)elem; node; node = node->parent) { - if (!elem->attributes[i]->isXmlNs) continue; - if (WsXmlStringEquals( elem->attributes[i]->prefix, prefix, NULL ) == S_OK && - WsXmlStringEquals( elem->attributes[i]->ns, ns, NULL ) == S_OK) + if (node_type( node ) != WS_XML_NODE_TYPE_ELEMENT) break; + + elem = &node->hdr; + for (i = 0; i < elem->attributeCount; i++) { - return elem->attributes[i]; + if (!elem->attributes[i]->isXmlNs) continue; + if (WsXmlStringEquals( elem->attributes[i]->prefix, prefix, NULL ) == S_OK && + WsXmlStringEquals( elem->attributes[i]->ns, ns, NULL ) == S_OK) + { + return TRUE; + } } } - return NULL; + return FALSE; }
static HRESULT write_set_element_namespace( struct writer *writer ) @@ -656,7 +663,7 @@ static HRESULT write_set_element_namespace( struct writer *writer ) HRESULT hr;
if (!elem->ns->length || is_current_namespace( writer, elem->ns ) || - find_namespace_attribute( elem, elem->prefix, elem->ns )) return S_OK; + namespace_in_scope( elem, elem->prefix, elem->ns )) return S_OK;
if ((hr = write_add_namespace_attribute( writer, elem->prefix, elem->ns, FALSE )) != S_OK) return hr; @@ -1689,6 +1696,6 @@ HRESULT WINAPI WsWriteXmlnsAttribute( WS_XML_WRITER *handle, const WS_XML_STRING if (!writer || !ns) return E_INVALIDARG; if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;
- if (find_namespace_attribute( &writer->current->hdr, prefix, ns )) return S_OK; + if (namespace_in_scope( &writer->current->hdr, prefix, ns )) return S_OK; return write_add_namespace_attribute( writer, prefix, ns, single ); }