[5/6] webservices: Set namespace attributes for prefixes introduced by attributes.

Hans Leidekker hans at codeweavers.com
Tue May 23 05:03:53 CDT 2017


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/webservices/tests/writer.c | 27 ++++++++++++++++++++++
 dlls/webservices/writer.c       | 51 ++++++++++++++++++++++++-----------------
 2 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c
index 7fd2d4432b..7ee0325985 100644
--- a/dlls/webservices/tests/writer.c
+++ b/dlls/webservices/tests/writer.c
@@ -3470,6 +3470,32 @@ static void test_binary_encoding(void)
     WsFreeWriter( writer );
 }
 
+static void test_namespaces(void)
+{
+    WS_XML_STRING prefix = {1, (BYTE *)"p"}, prefix2 = {1, (BYTE *)"q"};
+    WS_XML_STRING localname = {1, (BYTE *)"t"}, localname2 = {1, (BYTE *)"a"};
+    WS_XML_STRING ns = {1, (BYTE *)"n"}, ns2 = {1, (BYTE *)"o"};
+    WS_XML_WRITER *writer;
+    HRESULT hr;
+
+    hr = WsCreateWriter( NULL, 0, &writer, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = set_output( writer );
+    ok( hr == S_OK, "got %08x\n", hr );
+    hr = WsWriteStartElement( writer, &prefix, &localname, &ns, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    hr = WsWriteStartAttribute( writer, &prefix2, &localname2, &ns2, FALSE, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    hr = WsWriteEndAttribute( writer, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    hr = WsWriteEndElement( writer, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    check_output( writer, "<p:t q:a=\"\" xmlns:p=\"n\" xmlns:q=\"o\"/>", __LINE__ );
+
+    WsFreeWriter( writer );
+}
+
 START_TEST(writer)
 {
     test_WsCreateWriter();
@@ -3508,4 +3534,5 @@ START_TEST(writer)
     test_WsWriteChars();
     test_WsWriteCharsUtf8();
     test_binary_encoding();
+    test_namespaces();
 }
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index a2b0763bb2..e1b8c9e4a3 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -615,15 +615,6 @@ HRESULT WINAPI WsGetPrefixFromNamespace( WS_XML_WRITER *handle, const WS_XML_STR
     return hr;
 }
 
-static HRESULT set_current_namespace( struct writer *writer, const WS_XML_STRING *ns )
-{
-    WS_XML_STRING *str;
-    if (!(str = alloc_xml_string( ns->bytes, ns->length ))) return E_OUTOFMEMORY;
-    heap_free( writer->current_ns );
-    writer->current_ns = str;
-    return S_OK;
-}
-
 static HRESULT write_namespace_attribute_text( struct writer *writer, const WS_XML_ATTRIBUTE *attr )
 {
     unsigned char quote = attr->singleQuote ? '\'' : '"';
@@ -747,8 +738,8 @@ static HRESULT write_namespace_attribute( struct writer *writer, const WS_XML_AT
     }
 }
 
-static HRESULT write_add_namespace_attribute( struct writer *writer, const WS_XML_STRING *prefix,
-                                              const WS_XML_STRING *ns, BOOL single )
+static HRESULT add_namespace_attribute( struct writer *writer, const WS_XML_STRING *prefix,
+                                        const WS_XML_STRING *ns, BOOL single )
 {
     WS_XML_ATTRIBUTE *attr;
     WS_XML_ELEMENT_NODE *elem = &writer->current->hdr;
@@ -803,17 +794,35 @@ static BOOL namespace_in_scope( const WS_XML_ELEMENT_NODE *elem, const WS_XML_ST
     return FALSE;
 }
 
-static HRESULT write_set_element_namespace( struct writer *writer )
+static HRESULT set_current_namespace( struct writer *writer, const WS_XML_STRING *ns )
+{
+    WS_XML_STRING *str;
+    if (!(str = alloc_xml_string( ns->bytes, ns->length ))) return E_OUTOFMEMORY;
+    heap_free( writer->current_ns );
+    writer->current_ns = str;
+    return S_OK;
+}
+
+static HRESULT set_namespaces( struct writer *writer )
 {
     WS_XML_ELEMENT_NODE *elem = &writer->current->hdr;
     HRESULT hr;
+    ULONG i;
 
-    if (!elem->ns->length || namespace_in_scope( elem, elem->prefix, elem->ns )) return S_OK;
+    if (elem->ns->length && !namespace_in_scope( elem, elem->prefix, elem->ns ))
+    {
+        if ((hr = add_namespace_attribute( writer, elem->prefix, elem->ns, FALSE )) != S_OK) return hr;
+        if ((hr = set_current_namespace( writer, elem->ns )) != S_OK) return hr;
+    }
 
-    if ((hr = write_add_namespace_attribute( writer, elem->prefix, elem->ns, FALSE )) != S_OK)
-        return hr;
+    for (i = 0; i < elem->attributeCount; i++)
+    {
+        const WS_XML_ATTRIBUTE *attr = elem->attributes[i];
+        if (!attr->ns->length || namespace_in_scope( elem, attr->prefix, attr->ns )) continue;
+        if ((hr = add_namespace_attribute( writer, attr->prefix, attr->ns, FALSE )) != S_OK) return hr;
+    }
 
-    return set_current_namespace( writer, elem->ns );
+    return S_OK;
 }
 
 /**************************************************************************
@@ -1026,7 +1035,7 @@ static HRESULT write_endelement_node( struct writer *writer )
     if (!(node = write_find_startelement( writer ))) return WS_E_INVALID_FORMAT;
     if (writer->state == WRITER_STATE_STARTELEMENT)
     {
-        if ((hr = write_set_element_namespace( writer )) != S_OK) return hr;
+        if ((hr = set_namespaces( writer )) != S_OK) return hr;
         if ((hr = write_startelement( writer )) != S_OK) return hr;
     }
     if ((hr = write_close_element( writer, node )) != S_OK) return hr;
@@ -1109,7 +1118,7 @@ HRESULT WINAPI WsWriteEndStartElement( WS_XML_WRITER *handle, WS_ERROR *error )
         return WS_E_INVALID_OPERATION;
     }
 
-    if ((hr = write_set_element_namespace( writer )) != S_OK) goto done;
+    if ((hr = set_namespaces( writer )) != S_OK) goto done;
     if ((hr = write_startelement( writer )) != S_OK) goto done;
     if ((hr = write_endstartelement( writer )) != S_OK) goto done;
     writer->state = WRITER_STATE_ENDSTARTELEMENT;
@@ -1198,7 +1207,7 @@ static HRESULT write_flush( struct writer *writer )
     if (writer->state == WRITER_STATE_STARTELEMENT)
     {
         HRESULT hr;
-        if ((hr = write_set_element_namespace( writer )) != S_OK) return hr;
+        if ((hr = set_namespaces( writer )) != S_OK) return hr;
         if ((hr = write_startelement( writer )) != S_OK) return hr;
         if ((hr = write_endstartelement( writer )) != S_OK) return hr;
         writer->state = WRITER_STATE_ENDSTARTELEMENT;
@@ -2086,7 +2095,7 @@ static HRESULT write_add_nil_attribute( struct writer *writer )
 
     if ((hr = write_add_attribute( writer, &prefix, &localname, &ns, FALSE )) != S_OK) return hr;
     if ((hr = write_set_attribute_value( writer, &value.text )) != S_OK) return hr;
-    return write_add_namespace_attribute( writer, &prefix, &ns, FALSE );
+    return add_namespace_attribute( writer, &prefix, &ns, FALSE );
 }
 
 static HRESULT get_value_ptr( WS_WRITE_OPTION option, const void *value, ULONG size, ULONG expected_size,
@@ -3124,7 +3133,7 @@ HRESULT WINAPI WsWriteXmlnsAttribute( WS_XML_WRITER *handle, const WS_XML_STRING
     }
 
     if (!namespace_in_scope( &writer->current->hdr, prefix, ns ))
-        hr = write_add_namespace_attribute( writer, prefix, ns, single );
+        hr = add_namespace_attribute( writer, prefix, ns, single );
 
     LeaveCriticalSection( &writer->cs );
     return hr;
-- 
2.11.0




More information about the wine-patches mailing list