[2/6] webservices: Implement WsWriteQualifiedName.

Hans Leidekker hans at codeweavers.com
Fri Apr 28 05:12:47 CDT 2017


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/webservices/tests/writer.c   | 79 ++++++++++++++++++++++++++++++++++++
 dlls/webservices/webservices.spec |  2 +-
 dlls/webservices/writer.c         | 84 +++++++++++++++++++++++++++++++++++++++
 include/webservices.h             |  2 +
 4 files changed, 166 insertions(+), 1 deletion(-)

diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c
index 8cd9762fa2..3d0124544a 100644
--- a/dlls/webservices/tests/writer.c
+++ b/dlls/webservices/tests/writer.c
@@ -3036,6 +3036,84 @@ static void test_repeating_element(void)
     WsFreeWriter( writer );
 }
 
+static const WS_XML_STRING *init_xmlstring( const char *src, WS_XML_STRING *str )
+{
+    if (!src) return NULL;
+    str->length = strlen( src );
+    str->bytes  = (BYTE *)src;
+    return str;
+}
+
+static void test_WsWriteQualifiedName(void)
+{
+    WS_XML_STRING prefix = {1, (BYTE *)"p"}, localname = {1, (BYTE *)"t"}, ns = {2, (BYTE *)"ns"};
+    WS_XML_WRITER *writer;
+    HRESULT hr;
+    ULONG i;
+    static const struct
+    {
+        const char *prefix;
+        const char *localname;
+        const char *ns;
+        HRESULT     hr;
+        const char *result;
+    } tests[] =
+    {
+        { NULL, NULL, NULL, E_INVALIDARG, NULL },
+        { NULL, "t2", NULL, E_INVALIDARG, NULL },
+        { "p2", "t2", NULL, S_OK, "<p:t xmlns:p=\"ns\">p2:t2" },
+        { NULL, "t2", "ns2", WS_E_INVALID_FORMAT, NULL },
+        { NULL, "t2", "ns", S_OK, "<p:t xmlns:p=\"ns\">p:t2" },
+        { "p2", "t2", "ns2", S_OK, "<p:t xmlns:p=\"ns\">p2:t2" },
+        { "p2", "t2", "ns", S_OK, "<p:t xmlns:p=\"ns\">p2:t2" },
+        { "p", "t", NULL, S_OK, "<p:t xmlns:p=\"ns\">p:t" },
+        { NULL, "t", "ns", S_OK, "<p:t xmlns:p=\"ns\">p:t" },
+        { "p2", "", "", S_OK, "<p:t xmlns:p=\"ns\">p2:" },
+        { "p2", "", "ns2", S_OK, "<p:t xmlns:p=\"ns\">p2:" },
+        { "p2", "t2", "", S_OK, "<p:t xmlns:p=\"ns\">p2:t2" },
+        { "", "t2", "", S_OK, "<p:t xmlns:p=\"ns\">t2" },
+        { "", "", "ns2", S_OK, "<p:t xmlns:p=\"ns\">" },
+        { "", "", "", S_OK, "<p:t xmlns:p=\"ns\">" },
+    };
+
+    hr = WsWriteQualifiedName( NULL, NULL, NULL, NULL, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = WsCreateWriter( NULL, 0, &writer, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsWriteQualifiedName( writer, NULL, NULL, NULL, NULL );
+    ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
+    hr = set_output( writer );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsWriteQualifiedName( writer, NULL, NULL, NULL, NULL );
+    ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
+
+    for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
+    {
+        WS_XML_STRING prefix2, localname2, ns2;
+        const WS_XML_STRING *prefix_ptr, *localname_ptr, *ns_ptr;
+
+        hr = set_output( writer );
+        ok( hr == S_OK, "%u: got %08x\n", i, hr );
+
+        hr = WsWriteStartElement( writer, &prefix, &localname, &ns, NULL );
+        ok( hr == S_OK, "%u: got %08x\n", i, hr );
+
+        prefix_ptr = init_xmlstring( tests[i].prefix, &prefix2 );
+        localname_ptr = init_xmlstring( tests[i].localname, &localname2 );
+        ns_ptr = init_xmlstring( tests[i].ns, &ns2 );
+
+        hr = WsWriteQualifiedName( writer, prefix_ptr, localname_ptr, ns_ptr, NULL );
+        ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
+        if (tests[i].hr == S_OK && hr == S_OK) check_output( writer, tests[i].result, __LINE__ );
+    }
+
+    WsFreeWriter( writer );
+}
+
 START_TEST(writer)
 {
     test_WsCreateWriter();
@@ -3069,4 +3147,5 @@ START_TEST(writer)
     test_write_option();
     test_datetime();
     test_repeating_element();
+    test_WsWriteQualifiedName();
 }
diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec
index aa9b58f8a0..e63b805659 100644
--- a/dlls/webservices/webservices.spec
+++ b/dlls/webservices/webservices.spec
@@ -180,7 +180,7 @@
 @ stdcall WsWriteMessageEnd(ptr ptr ptr ptr)
 @ stdcall WsWriteMessageStart(ptr ptr ptr ptr)
 @ stdcall WsWriteNode(ptr ptr ptr)
-@ stub WsWriteQualifiedName
+@ stdcall WsWriteQualifiedName(ptr ptr ptr ptr ptr)
 @ stdcall WsWriteStartAttribute(ptr ptr ptr ptr long ptr)
 @ stdcall WsWriteStartCData(ptr ptr)
 @ stdcall WsWriteStartElement(ptr ptr ptr ptr ptr)
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index 4c9f1a91d1..4fd112642f 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -2800,6 +2800,90 @@ HRESULT WINAPI WsWriteXmlnsAttribute( WS_XML_WRITER *handle, const WS_XML_STRING
     return hr;
 }
 
+static HRESULT find_prefix( struct writer *writer, const WS_XML_STRING *ns, const WS_XML_STRING **prefix )
+{
+    const struct node *node;
+    for (node = writer->current; node_type( node ) == WS_XML_NODE_TYPE_ELEMENT; node = node->parent)
+    {
+        const WS_XML_ELEMENT_NODE *elem = &node->hdr;
+        ULONG i;
+        for (i = 0; i < elem->attributeCount; i++)
+        {
+            if (!elem->attributes[i]->isXmlNs) continue;
+            if (WsXmlStringEquals( elem->attributes[i]->ns, ns, NULL ) != S_OK) continue;
+            *prefix = elem->attributes[i]->prefix;
+            return S_OK;
+        }
+    }
+    return WS_E_INVALID_FORMAT;
+}
+
+static HRESULT write_qualified_name( struct writer *writer, const WS_XML_STRING *prefix,
+                                     const WS_XML_STRING *localname )
+{
+    HRESULT hr;
+    if (prefix->length)
+    {
+        if ((hr = write_grow_buffer( writer, prefix->length + localname->length + 1 )) != S_OK) return hr;
+        write_bytes( writer, prefix->bytes, prefix->length );
+        write_char( writer, ':' );
+    }
+    else if ((hr = write_grow_buffer( writer, localname->length )) != S_OK) return hr;
+    write_bytes( writer, localname->bytes, localname->length );
+    return S_OK;
+}
+
+/**************************************************************************
+ *          WsWriteQualifiedName		[webservices.@]
+ */
+HRESULT WINAPI WsWriteQualifiedName( WS_XML_WRITER *handle, const WS_XML_STRING *prefix,
+                                     const WS_XML_STRING *localname, const WS_XML_STRING *ns,
+                                     WS_ERROR *error )
+{
+    struct writer *writer = (struct writer *)handle;
+    HRESULT hr;
+
+    TRACE( "%p %s %s %s %p\n", handle, debugstr_xmlstr(prefix), debugstr_xmlstr(localname),
+           debugstr_xmlstr(ns), error );
+    if (error) FIXME( "ignoring error parameter\n" );
+
+    if (!writer) return E_INVALIDARG;
+
+    EnterCriticalSection( &writer->cs );
+
+    if (writer->magic != WRITER_MAGIC)
+    {
+        LeaveCriticalSection( &writer->cs );
+        return E_INVALIDARG;
+    }
+
+    if (!writer->output_type)
+    {
+        LeaveCriticalSection( &writer->cs );
+        return WS_E_INVALID_OPERATION;
+    }
+
+    if (writer->state != WRITER_STATE_STARTELEMENT)
+    {
+        LeaveCriticalSection( &writer->cs );
+        return WS_E_INVALID_FORMAT;
+    }
+
+    if (!localname || (!prefix && !ns))
+    {
+        LeaveCriticalSection( &writer->cs );
+        return E_INVALIDARG;
+    }
+
+    if ((hr = write_flush( writer )) != S_OK) goto done;
+    if (!prefix && ((hr = find_prefix( writer, ns, &prefix )) != S_OK)) goto done;
+    hr = write_qualified_name( writer, prefix, localname );
+
+done:
+    LeaveCriticalSection( &writer->cs );
+    return hr;
+}
+
 static HRESULT write_move_to( struct writer *writer, WS_MOVE_TO move, BOOL *found )
 {
     BOOL success = FALSE;
diff --git a/include/webservices.h b/include/webservices.h
index 783a6ae77b..a0857f6bc8 100644
--- a/include/webservices.h
+++ b/include/webservices.h
@@ -1675,6 +1675,8 @@ HRESULT WINAPI WsWriteEnvelopeStart(WS_MESSAGE*, WS_XML_WRITER*, WS_MESSAGE_DONE
 HRESULT WINAPI WsWriteMessageStart(WS_CHANNEL*, WS_MESSAGE*, const WS_ASYNC_CONTEXT*, WS_ERROR*);
 HRESULT WINAPI WsWriteMessageEnd(WS_CHANNEL*, WS_MESSAGE*, const WS_ASYNC_CONTEXT*, WS_ERROR*);
 HRESULT WINAPI WsWriteNode(WS_XML_WRITER*, const WS_XML_NODE*, WS_ERROR*);
+HRESULT WINAPI WsWriteQualifiedName(WS_XML_WRITER*, const WS_XML_STRING*, const WS_XML_STRING*,
+                                    const WS_XML_STRING*, WS_ERROR*);
 HRESULT WINAPI WsWriteStartAttribute(WS_XML_WRITER*, const WS_XML_STRING*, const WS_XML_STRING*,
                                      const WS_XML_STRING*, BOOL, WS_ERROR*);
 HRESULT WINAPI WsWriteStartCData(WS_XML_WRITER*, WS_ERROR*);
-- 
2.11.0




More information about the wine-patches mailing list