webservices: Implement WsFindAttribute.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2016-02-10 15:01:59 +01:00 committed by Alexandre Julliard
parent acf0c92943
commit 46393a3f86
3 changed files with 149 additions and 7 deletions

View File

@ -1068,12 +1068,12 @@ static HRESULT read_to_startelement( struct reader *reader, BOOL *found )
return hr; 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; ULONG i;
if (len1 != len2) return FALSE; if (len1 != len2) return 1;
for (i = 0; i < len1; i++) { if (toupper( name1[i] ) != toupper( name2[i] )) return FALSE; } for (i = 0; i < len1; i++) { if (toupper( name1[i] ) != toupper( name2[i] )) return 1; }
return TRUE; return 0;
} }
struct node *find_parent_element( struct node *node, const WS_XML_STRING *prefix, 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; if (!localname) return parent;
str = parent->hdr.prefix; 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; 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; return parent;
} }
@ -1579,6 +1579,59 @@ static HRESULT read_get_attribute_text( struct reader *reader, WS_XML_UTF8_TEXT
return S_OK; 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, static HRESULT read_type_bool( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_BOOL_DESCRIPTION *desc, BOOL *ret ) const WS_BOOL_DESCRIPTION *desc, BOOL *ret )
{ {

View File

@ -1871,6 +1871,94 @@ static void test_cdata(void)
WsFreeReader( reader ); 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) START_TEST(reader)
{ {
test_WsCreateError(); test_WsCreateError();
@ -1890,4 +1978,5 @@ START_TEST(reader)
test_WsMoveReader(); test_WsMoveReader();
test_simple_struct_type(); test_simple_struct_type();
test_cdata(); test_cdata();
test_WsFindAttribute();
} }

View File

@ -45,7 +45,7 @@
@ stub WsFileTimeToDateTime @ stub WsFileTimeToDateTime
@ stub WsFillBody @ stub WsFillBody
@ stdcall WsFillReader(ptr long ptr ptr) @ stdcall WsFillReader(ptr long ptr ptr)
@ stub WsFindAttribute @ stdcall WsFindAttribute(ptr ptr ptr long ptr ptr)
@ stub WsFlushBody @ stub WsFlushBody
@ stub WsFlushWriter @ stub WsFlushWriter
@ stub WsFreeChannel @ stub WsFreeChannel