[6/6] webservices: Implement WsGetNamespaceFromPrefix.

Hans Leidekker hans at codeweavers.com
Tue Feb 23 06:11:55 CST 2016


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

diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 92a8184..f224720 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -607,6 +607,67 @@ HRESULT WINAPI WsGetHeapProperty( WS_HEAP *handle, WS_HEAP_PROPERTY_ID id, void
 }
 
 /**************************************************************************
+ *          WsGetNamespaceFromPrefix		[webservices.@]
+ */
+HRESULT WINAPI WsGetNamespaceFromPrefix( WS_XML_READER *handle, const WS_XML_STRING *prefix,
+                                         BOOL required, const WS_XML_STRING **ns, WS_ERROR *error )
+{
+    static const WS_XML_STRING xml = {3, (BYTE *)"xml"};
+    static const WS_XML_STRING xmlns = {5, (BYTE *)"xmlns"};
+    static const WS_XML_STRING empty_ns = {0, NULL};
+    static const WS_XML_STRING xml_ns = {36, (BYTE *)"http://www.w3.org/XML/1998/namespace"};
+    static const WS_XML_STRING xmlns_ns = {29, (BYTE *)"http://www.w3.org/2000/xmlns/"};
+    struct reader *reader = (struct reader *)handle;
+    BOOL found = FALSE;
+
+    TRACE( "%p %s %d %p %p\n", handle, debugstr_xmlstr(prefix), required, ns, error );
+    if (error) FIXME( "ignoring error parameter\n" );
+
+    if (!reader || !prefix || !ns) return E_INVALIDARG;
+    if (reader->state != READER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;
+
+    if (!prefix->length)
+    {
+        *ns = &empty_ns;
+        found = TRUE;
+    }
+    else if (WsXmlStringEquals( prefix, &xml, NULL ) == S_OK)
+    {
+        *ns = &xml_ns;
+        found = TRUE;
+    }
+    else if (WsXmlStringEquals( prefix, &xmlns, NULL ) == S_OK)
+    {
+        *ns = &xmlns_ns;
+        found = TRUE;
+    }
+    else
+    {
+        WS_XML_ELEMENT_NODE *elem = &reader->current->hdr;
+        ULONG i;
+
+        for (i = 0; i < elem->attributeCount; i++)
+        {
+            if (!elem->attributes[i]->isXmlNs) continue;
+            if (WsXmlStringEquals( prefix, elem->attributes[i]->prefix, NULL ) == S_OK)
+            {
+                *ns = elem->attributes[i]->ns;
+                found = TRUE;
+                break;
+            }
+        }
+    }
+
+    if (!found)
+    {
+        if (required) return WS_E_INVALID_FORMAT;
+        *ns = NULL;
+        return S_FALSE;
+    }
+    return S_OK;
+}
+
+/**************************************************************************
  *          WsGetReaderNode		[webservices.@]
  */
 HRESULT WINAPI WsGetReaderNode( WS_XML_READER *handle, const WS_XML_NODE **node,
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index 4416a84..1ee5de8 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -2016,6 +2016,184 @@ static void test_WsFindAttribute(void)
     WsFreeReader( reader );
 }
 
+static void prepare_namespace_test( WS_XML_READER *reader, const char *data )
+{
+    HRESULT hr;
+    ULONG size = strlen( data );
+
+    hr = set_input( reader, data, size );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+}
+
+static void test_WsGetNamespaceFromPrefix(void)
+{
+    WS_XML_STRING prefix = {0, NULL};
+    const WS_XML_STRING *ns;
+    const WS_XML_NODE *node;
+    WS_XML_READER *reader;
+    HRESULT hr;
+
+    hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, NULL, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, &ns, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = WsGetNamespaceFromPrefix( NULL, &prefix, FALSE, &ns, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    ns = (const WS_XML_STRING *)0xdeadbeef;
+    hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
+    ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+    ok( ns == (const WS_XML_STRING *)0xdeadbeef, "ns set\n" );
+
+    hr = set_input( reader, "<prefix:t xmlns:prefix2='ns'/>", sizeof("<prefix:t xmlns:prefix2='ns'/>") - 1 );
+    ok( hr == S_OK, "got %08x\n", hr );
+    hr = WsReadStartElement( reader, NULL );
+    todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
+
+    prepare_namespace_test( reader, "<t></t>" );
+    ns = NULL;
+    hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( ns != NULL, "ns not set\n" );
+    if (ns) ok( !ns->length, "got %u\n", ns->length );
+
+    prepare_namespace_test( reader, "<t xmls='ns'></t>" );
+    ns = NULL;
+    hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( ns != NULL, "ns not set\n" );
+    if (ns) ok( !ns->length, "got %u\n", ns->length );
+
+    prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
+    ns = NULL;
+    hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( ns != NULL, "ns not set\n" );
+    if (ns) ok( !ns->length, "got %u\n", ns->length );
+
+    prepare_namespace_test( reader, "<prefix:t xmlns:prefix='ns'></t>" );
+    prefix.bytes = (BYTE *)"prefix";
+    prefix.length = 6;
+    ns = NULL;
+    hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( ns != NULL, "ns not set\n" );
+    if (ns)
+    {
+        ok( ns->length == 2, "got %u\n", ns->length );
+        ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
+    }
+
+    prepare_namespace_test( reader, "<t xmlns:prefix='ns'>>/t>" );
+    ns = NULL;
+    hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( ns != NULL, "ns not set\n" );
+    if (ns)
+    {
+        ok( ns->length == 2, "got %u\n", ns->length );
+        ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" );
+    }
+
+    hr = set_input( reader, "<t xmlns:prefix='ns'></t>", sizeof("<t xmlns:prefix='ns'></t>") - 1 );
+    ok( hr == S_OK, "got %08x\n", hr );
+    hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    hr = WsGetReaderNode( reader, &node, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    if (node)
+    {
+        WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
+        WS_XML_ATTRIBUTE *attr;
+        WS_XML_UTF8_TEXT *text;
+
+        ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType );
+        ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
+        ok( elem->attributes != NULL, "attributes not set\n" );
+
+        attr = elem->attributes[0];
+        ok( attr->singleQuote, "singleQuote not set\n" );
+        ok( attr->isXmlNs, "isXmlNs not set\n" );
+        ok( attr->prefix != NULL, "prefix not set\n" );
+        ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length );
+        ok( attr->prefix->bytes != NULL, "bytes not set\n" );
+        ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" );
+        ok( attr->localName != NULL, "localName not set\n" );
+        ok( attr->localName->length == 6, "got %u\n", attr->localName->length );
+        ok( !memcmp( attr->localName->bytes, "prefix", 6 ), "wrong data\n" );
+        ok( attr->ns != NULL, "ns not set\n" );
+        ok( attr->ns->length == 2, "got %u\n", attr->ns->length );
+        ok( attr->ns->bytes != NULL, "bytes set\n" );
+        ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" );
+        ok( attr->value != NULL, "value not set\n" );
+
+        text = (WS_XML_UTF8_TEXT *)attr->value;
+        ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType );
+        ok( !text->value.length, "got %u\n", text->value.length );
+        ok( text->value.bytes == NULL, "bytes set\n" );
+    }
+
+    prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
+    hr = WsReadStartElement( reader, NULL );
+    todo_wine ok( hr == S_OK, "got %08x\n", hr );
+    hr = WsReadEndElement( reader, NULL );
+    todo_wine ok( hr == S_OK, "got %08x\n", hr );
+    hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
+    todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
+
+    prepare_namespace_test( reader, "<t></t>" );
+    ns = NULL;
+    prefix.bytes = (BYTE *)"xml";
+    prefix.length = 3;
+    hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( ns != NULL, "ns not set\n" );
+    if (ns)
+    {
+        ok( ns->length == 36, "got %u\n", ns->length );
+        ok( !memcmp( ns->bytes, "http://www.w3.org/XML/1998/namespace", 36 ), "wrong data\n" );
+    }
+
+    prepare_namespace_test( reader, "<t></t>" );
+    ns = NULL;
+    prefix.bytes = (BYTE *)"xmlns";
+    prefix.length = 5;
+    hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( ns != NULL, "ns not set\n" );
+    if (ns)
+    {
+        ok( ns->length == 29, "got %u\n", ns->length );
+        ok( !memcmp( ns->bytes, "http://www.w3.org/2000/xmlns/", 29 ), "wrong data\n" );
+    }
+
+    prepare_namespace_test( reader, "<t></t>" );
+    ns = (WS_XML_STRING *)0xdeadbeef;
+    prefix.bytes = (BYTE *)"prefix2";
+    prefix.length = 7;
+    hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
+    ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
+    ok( ns == (WS_XML_STRING *)0xdeadbeef, "ns set\n" );
+
+    prepare_namespace_test( reader, "<t></t>" );
+    ns = (WS_XML_STRING *)0xdeadbeef;
+    prefix.bytes = (BYTE *)"prefix2";
+    prefix.length = 7;
+    hr = WsGetNamespaceFromPrefix( reader, &prefix, FALSE, &ns, NULL );
+    ok( hr == S_FALSE, "got %08x\n", hr );
+    ok( ns == NULL, "ns not set\n" );
+
+    WsFreeReader( reader );
+}
+
 START_TEST(reader)
 {
     test_WsCreateError();
@@ -2036,4 +2214,5 @@ START_TEST(reader)
     test_simple_struct_type();
     test_cdata();
     test_WsFindAttribute();
+    test_WsGetNamespaceFromPrefix();
 }
diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec
index f0a843a..9c0b3c7 100644
--- a/dlls/webservices/webservices.spec
+++ b/dlls/webservices/webservices.spec
@@ -75,7 +75,7 @@
 @ stub WsGetMetadataEndpoints
 @ stub WsGetMetadataProperty
 @ stub WsGetMissingMetadataDocumentAddress
-@ stub WsGetNamespaceFromPrefix
+@ stdcall WsGetNamespaceFromPrefix(ptr ptr long ptr ptr)
 @ stub WsGetOperationContextProperty
 @ stub WsGetPolicyAlternativeCount
 @ stub WsGetPolicyProperty
diff --git a/include/webservices.h b/include/webservices.h
index cd82cb7..1b13fce 100644
--- a/include/webservices.h
+++ b/include/webservices.h
@@ -556,6 +556,8 @@ void WINAPI WsFreeWriter(WS_XML_WRITER*);
 HRESULT WINAPI WsGetErrorProperty(WS_ERROR*, WS_ERROR_PROPERTY_ID, void*, ULONG);
 HRESULT WINAPI WsGetErrorString(WS_ERROR*, ULONG, WS_STRING*);
 HRESULT WINAPI WsGetHeapProperty(WS_HEAP*, WS_HEAP_PROPERTY_ID, void*, ULONG, WS_ERROR*);
+HRESULT WINAPI WsGetNamespaceFromPrefix(WS_XML_READER*, const WS_XML_STRING*, BOOL,
+                                        const WS_XML_STRING**, WS_ERROR*);
 HRESULT WINAPI WsGetPrefixFromNamespace(WS_XML_WRITER*, const WS_XML_STRING*, BOOL,
                                         const WS_XML_STRING**, WS_ERROR*);
 HRESULT WINAPI WsGetReaderNode(WS_XML_READER*, const WS_XML_NODE**, WS_ERROR*);
-- 
2.7.0




More information about the wine-patches mailing list