[1/6] webservices: Avoid writing redundant namespace attributes.

Hans Leidekker hans at codeweavers.com
Wed Jun 15 02:21:20 CDT 2016


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 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 );
 }
-- 
2.1.4




More information about the wine-patches mailing list