[01/10] webservices: Implement WsFindAttribute.

Hans Leidekker hans at codeweavers.com
Wed Feb 10 08:01:59 CST 2016


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/webservices/reader.c         | 65 +++++++++++++++++++++++++---
 dlls/webservices/tests/reader.c   | 89 +++++++++++++++++++++++++++++++++++++++
 dlls/webservices/webservices.spec |  2 +-
 3 files changed, 149 insertions(+), 7 deletions(-)

diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 9391cf8..9164b4f 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -1068,12 +1068,12 @@ static HRESULT read_to_startelement( struct reader *reader, BOOL *found )
     return hr;
 }
 
-static BOOL cmp_localname( const unsigned char *name1, ULONG len1, const unsigned char *name2, ULONG len2 )
+static int cmp_name( const unsigned char *name1, ULONG len1, const unsigned char *name2, ULONG len2 )
 {
     ULONG i;
-    if (len1 != len2) return FALSE;
-    for (i = 0; i < len1; i++) { if (toupper( name1[i] ) != toupper( name2[i] )) return FALSE; }
-    return TRUE;
+    if (len1 != len2) return 1;
+    for (i = 0; i < len1; i++) { if (toupper( name1[i] ) != toupper( name2[i] )) return 1; }
+    return 0;
 }
 
 struct node *find_parent_element( struct node *node, const WS_XML_STRING *prefix,
@@ -1088,10 +1088,10 @@ struct node *find_parent_element( struct node *node, const WS_XML_STRING *prefix
         if (!localname) return parent;
 
         str = parent->hdr.prefix;
-        if (!cmp_localname( str->bytes, str->length, prefix->bytes, prefix->length )) continue;
+        if (cmp_name( str->bytes, str->length, prefix->bytes, prefix->length )) continue;
 
         str = parent->hdr.localName;
-        if (!cmp_localname( str->bytes, str->length, localname->bytes, localname->length )) continue;
+        if (cmp_name( str->bytes, str->length, localname->bytes, localname->length )) continue;
 
         return parent;
     }
@@ -1579,6 +1579,59 @@ static HRESULT read_get_attribute_text( struct reader *reader, WS_XML_UTF8_TEXT
     return S_OK;
 }
 
+static BOOL find_attribute( struct reader *reader, const WS_XML_STRING *localname,
+                            const WS_XML_STRING *ns, ULONG *index )
+{
+    ULONG i;
+    WS_XML_ELEMENT_NODE *elem = &reader->current->hdr;
+
+    if (!localname)
+    {
+        *index = reader->current_attr;
+        return TRUE;
+    }
+    for (i = 0; i < elem->attributeCount; i++)
+    {
+        const WS_XML_STRING *localname2 = elem->attributes[i]->localName;
+        const WS_XML_STRING *ns2 = elem->attributes[i]->ns;
+
+        if (!cmp_name( localname->bytes, localname->length, localname2->bytes, localname2->length ) &&
+            !cmp_name( ns->bytes, ns->length, ns2->bytes, ns2->length ))
+        {
+            *index = i;
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+/**************************************************************************
+ *          WsFindAttribute		[webservices.@]
+ */
+HRESULT WINAPI WsFindAttribute( WS_XML_READER *handle, const WS_XML_STRING *localname,
+                                const WS_XML_STRING *ns, BOOL required, ULONG *index,
+                                WS_ERROR *error )
+{
+    struct reader *reader = (struct reader *)handle;
+
+    TRACE( "%p %s %s %d %p %p\n", handle, debugstr_xmlstr(localname), debugstr_xmlstr(ns),
+           required, index, error );
+    if (error) FIXME( "ignoring error parameter\n" );
+
+    if (!reader || !localname || !ns || !index) return E_INVALIDARG;
+
+    if (reader->current->hdr.node.nodeType != WS_XML_NODE_TYPE_ELEMENT)
+        return WS_E_INVALID_OPERATION;
+
+    if (!find_attribute( reader, localname, ns, index ))
+    {
+        if (required) return WS_E_INVALID_FORMAT;
+        *index = ~0u;
+        return S_FALSE;
+    }
+    return S_OK;
+}
+
 static HRESULT read_type_bool( struct reader *reader, WS_TYPE_MAPPING mapping,
                                const WS_BOOL_DESCRIPTION *desc, BOOL *ret )
 {
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index f9b2ea9..555226d 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -1871,6 +1871,94 @@ static void test_cdata(void)
     WsFreeReader( reader );
 }
 
+static void test_WsFindAttribute(void)
+{
+    static const char test[] = "<t attr='value' attr2='value2'></t>";
+    WS_XML_STRING ns = {0, NULL}, localname = {4, (BYTE *)"attr"};
+    WS_XML_STRING localname2 = {5, (BYTE *)"attr2"}, localname3 = {5, (BYTE *)"attr3"};
+    WS_XML_READER *reader;
+    ULONG index;
+    HRESULT hr;
+
+    hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = set_input( reader, test, sizeof(test) - 1 );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsReadNode( reader, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsFindAttribute( reader, &localname, &ns, TRUE, NULL, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = set_input( reader, test, sizeof(test) - 1 );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsReadNode( reader, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsFindAttribute( reader, &localname, NULL, TRUE, &index, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = set_input( reader, test, sizeof(test) - 1 );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsReadNode( reader, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsFindAttribute( reader, NULL, &ns, TRUE, &index, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = set_input( reader, test, sizeof(test) - 1 );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsReadNode( reader, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    index = 0xdeadbeef;
+    hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( !index, "got %u\n", index );
+
+    index = 0xdeadbeef;
+    hr = WsFindAttribute( reader, &localname2, &ns, TRUE, &index, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( index == 1, "got %u\n", index );
+
+    hr = WsReadNode( reader, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    index = 0xdeadbeef;
+    hr = WsFindAttribute( reader, &localname, &ns, TRUE, &index, NULL );
+    ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+    ok( index == 0xdeadbeef, "got %u\n", index );
+
+    hr = set_input( reader, test, sizeof(test) - 1 );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsReadNode( reader, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    index = 0xdeadbeef;
+    hr = WsFindAttribute( reader, &localname3, &ns, TRUE, &index, NULL );
+    ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
+    ok( index == 0xdeadbeef, "got %u\n", index );
+
+    hr = set_input( reader, test, sizeof(test) - 1 );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsReadNode( reader, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    index = 0xdeadbeef;
+    hr = WsFindAttribute( reader, &localname3, &ns, FALSE, &index, NULL );
+    ok( hr == S_FALSE, "got %08x\n", hr );
+    ok( index == ~0u, "got %u\n", index );
+
+    WsFreeReader( reader );
+}
+
 START_TEST(reader)
 {
     test_WsCreateError();
@@ -1890,4 +1978,5 @@ START_TEST(reader)
     test_WsMoveReader();
     test_simple_struct_type();
     test_cdata();
+    test_WsFindAttribute();
 }
diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec
index ffe8bca..5500424 100644
--- a/dlls/webservices/webservices.spec
+++ b/dlls/webservices/webservices.spec
@@ -45,7 +45,7 @@
 @ stub WsFileTimeToDateTime
 @ stub WsFillBody
 @ stdcall WsFillReader(ptr long ptr ptr)
-@ stub WsFindAttribute
+@ stdcall WsFindAttribute(ptr ptr ptr long ptr ptr)
 @ stub WsFlushBody
 @ stub WsFlushWriter
 @ stub WsFreeChannel
-- 
2.7.0




More information about the wine-patches mailing list