webservices: Implement WsReadNode.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
45ded33bc9
commit
ef3e05ee5b
|
@ -273,6 +273,16 @@ static struct node *alloc_node( WS_XML_NODE_TYPE type )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void free_attribute( WS_XML_ATTRIBUTE *attr )
|
||||
{
|
||||
if (!attr) return;
|
||||
heap_free( attr->prefix );
|
||||
heap_free( attr->localName );
|
||||
heap_free( attr->ns );
|
||||
heap_free( attr->value );
|
||||
heap_free( attr );
|
||||
}
|
||||
|
||||
static void free_node( struct node *node )
|
||||
{
|
||||
if (!node) return;
|
||||
|
@ -281,6 +291,10 @@ static void free_node( struct node *node )
|
|||
case WS_XML_NODE_TYPE_ELEMENT:
|
||||
{
|
||||
WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node;
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < elem->attributeCount; i++) free_attribute( elem->attributes[i] );
|
||||
heap_free( elem->attributes );
|
||||
heap_free( elem->prefix );
|
||||
heap_free( elem->localName );
|
||||
heap_free( elem->ns );
|
||||
|
@ -705,12 +719,89 @@ static HRESULT read_xmldecl( struct reader *reader )
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT append_attribute( WS_XML_ELEMENT_NODE *elem, WS_XML_ATTRIBUTE *attr )
|
||||
{
|
||||
if (elem->attributeCount)
|
||||
{
|
||||
WS_XML_ATTRIBUTE **tmp;
|
||||
if (!(tmp = heap_realloc( elem->attributes, (elem->attributeCount + 1) * sizeof(attr) )))
|
||||
return E_OUTOFMEMORY;
|
||||
elem->attributes = tmp;
|
||||
}
|
||||
else if (!(elem->attributes = heap_alloc( sizeof(attr) ))) return E_OUTOFMEMORY;
|
||||
elem->attributes[elem->attributeCount++] = attr;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT read_attribute( struct reader *reader, WS_XML_ATTRIBUTE **ret )
|
||||
{
|
||||
WS_XML_ATTRIBUTE *attr;
|
||||
WS_XML_UTF8_TEXT *text;
|
||||
unsigned int len = 0, ch, skip;
|
||||
const char *start;
|
||||
HRESULT hr = WS_E_INVALID_FORMAT;
|
||||
|
||||
if (!(attr = heap_alloc_zero( sizeof(*attr) ))) return E_OUTOFMEMORY;
|
||||
|
||||
start = read_current_ptr( reader );
|
||||
for (;;)
|
||||
{
|
||||
if (!(ch = read_utf8_char( reader, &skip ))) goto error;
|
||||
if (!read_isnamechar( ch )) break;
|
||||
read_skip( reader, skip );
|
||||
len += skip;
|
||||
}
|
||||
if (!len) goto error;
|
||||
|
||||
hr = E_OUTOFMEMORY;
|
||||
if (!(attr->localName = alloc_xml_string( start, len ))) goto error;
|
||||
if (!(attr->prefix = alloc_xml_string( NULL, 0 ))) goto error;
|
||||
attr->prefix->bytes = NULL;
|
||||
if (!(attr->ns = alloc_xml_string( NULL, 0 ))) goto error;
|
||||
attr->ns->bytes = NULL;
|
||||
|
||||
hr = WS_E_INVALID_FORMAT;
|
||||
read_skip_whitespace( reader );
|
||||
if (read_cmp( reader, "=", 1 )) goto error;
|
||||
read_skip( reader, 1 );
|
||||
|
||||
read_skip_whitespace( reader );
|
||||
if (read_cmp( reader, "\"", 1 )) goto error;
|
||||
read_skip( reader, 1 );
|
||||
|
||||
len = 0;
|
||||
start = read_current_ptr( reader );
|
||||
for (;;)
|
||||
{
|
||||
if (!(ch = read_utf8_char( reader, &skip ))) goto error;
|
||||
if (ch == '"') break;
|
||||
read_skip( reader, skip );
|
||||
len += skip;
|
||||
}
|
||||
read_skip( reader, 1 );
|
||||
|
||||
if (!(text = alloc_utf8_text( start, len )))
|
||||
{
|
||||
free_attribute( attr );
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
attr->value = (WS_XML_TEXT *)text;
|
||||
|
||||
*ret = attr;
|
||||
return S_OK;
|
||||
|
||||
error:
|
||||
free_attribute( attr );
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT read_element( struct reader *reader )
|
||||
{
|
||||
unsigned int len = 0, ch, skip;
|
||||
const char *start;
|
||||
struct node *node;
|
||||
WS_XML_ELEMENT_NODE *elem;
|
||||
WS_XML_ATTRIBUTE *attr;
|
||||
HRESULT hr = WS_E_INVALID_FORMAT;
|
||||
|
||||
if (read_end_of_data( reader ))
|
||||
|
@ -742,10 +833,19 @@ static HRESULT read_element( struct reader *reader )
|
|||
elem->prefix->bytes = NULL;
|
||||
if (!(elem->ns = alloc_xml_string( NULL, 0 ))) goto error;
|
||||
|
||||
/* FIXME: parse attributes */
|
||||
while (reader->read_pos < reader->read_size && reader->read_bufptr[reader->read_pos] != '>')
|
||||
reader->read_pos++;
|
||||
for (;;)
|
||||
{
|
||||
read_skip_whitespace( reader );
|
||||
if (!read_cmp( reader, ">", 1 )) break;
|
||||
if ((hr = read_attribute( reader, &attr )) != S_OK) goto error;
|
||||
if ((hr = append_attribute( elem, attr )) != S_OK)
|
||||
{
|
||||
free_attribute( attr );
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
read_skip_whitespace( reader );
|
||||
if (read_cmp( reader, ">", 1 ))
|
||||
{
|
||||
hr = WS_E_INVALID_FORMAT;
|
||||
|
@ -862,6 +962,29 @@ static HRESULT read_endelement( struct reader *reader )
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT read_node( struct reader *reader )
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (read_end_of_data( reader ))
|
||||
{
|
||||
reader->current = LIST_ENTRY( list_tail( &reader->nodes ), struct node, entry );
|
||||
reader->state = READER_STATE_EOF;
|
||||
return S_OK;
|
||||
}
|
||||
if (!read_cmp( reader, "<?", 2 ))
|
||||
{
|
||||
hr = read_xmldecl( reader );
|
||||
if (FAILED( hr )) return hr;
|
||||
}
|
||||
else if (!read_cmp( reader, "</", 2 )) return read_endelement( reader );
|
||||
else if (!read_cmp( reader, "<", 1 )) return read_startelement( reader );
|
||||
else return read_text( reader );
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* WsReadEndElement [webservices.@]
|
||||
*/
|
||||
|
@ -876,6 +999,20 @@ HRESULT WINAPI WsReadEndElement( WS_XML_READER *handle, WS_ERROR *error )
|
|||
return read_endelement( reader );
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* WsReadNode [webservices.@]
|
||||
*/
|
||||
HRESULT WINAPI WsReadNode( WS_XML_READER *handle, WS_ERROR *error )
|
||||
{
|
||||
struct reader *reader = (struct reader *)handle;
|
||||
|
||||
TRACE( "%p %p\n", handle, error );
|
||||
if (error) FIXME( "ignoring error parameter\n" );
|
||||
|
||||
if (!reader) return E_INVALIDARG;
|
||||
return read_node( reader );
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* WsReadStartElement [webservices.@]
|
||||
*/
|
||||
|
|
|
@ -45,6 +45,13 @@ static const char data4[] =
|
|||
"</o:services>\r\n"
|
||||
"</o:OfficeConfig>\r\n";
|
||||
|
||||
static const char data5[] =
|
||||
"</text>";
|
||||
|
||||
static const char data6[] =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
||||
"<text attr= \"value\" >test</text>";
|
||||
|
||||
static const char data8[] =
|
||||
"<node1><node2>test</node2></node1>";
|
||||
|
||||
|
@ -694,6 +701,204 @@ static void test_WsReadStartElement(void)
|
|||
WsFreeReader( reader );
|
||||
}
|
||||
|
||||
static void test_WsReadEndElement(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
WS_XML_READER *reader;
|
||||
const WS_XML_NODE *node;
|
||||
|
||||
hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = set_input( reader, data2, sizeof(data2) - 1 );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsReadEndElement( reader, NULL );
|
||||
ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
|
||||
|
||||
hr = set_input( reader, data2, sizeof(data2) - 1 );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsReadNode( reader, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsGetReaderNode( reader, &node, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
|
||||
|
||||
hr = WsReadNode( reader, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsGetReaderNode( reader, &node, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
|
||||
|
||||
hr = WsReadNode( reader, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsGetReaderNode( reader, &node, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
|
||||
|
||||
hr = WsReadNode( reader, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsGetReaderNode( reader, &node, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
|
||||
|
||||
hr = set_input( reader, data5, sizeof(data5) - 1 );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsFillReader( reader, sizeof(data5) - 1, NULL, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsReadEndElement( reader, NULL );
|
||||
ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
|
||||
WsFreeReader( reader );
|
||||
}
|
||||
|
||||
static void test_WsReadNode(void)
|
||||
{
|
||||
static const char str1[] = "<a>";
|
||||
static const char str2[] = "< a>";
|
||||
static const char str3[] = "<a >";
|
||||
static const char str4[] = "<<a>>";
|
||||
static const char str5[] = "<>";
|
||||
static const char str6[] = "</a>";
|
||||
static const char str7[] = " <a>";
|
||||
static const char str8[] = "<?xml>";
|
||||
static const char str9[] = "<?xml?>";
|
||||
static const char str10[] = "<?xml ?>";
|
||||
static const char str11[] = "<?xml version=\"1.0\"?>";
|
||||
static const char str12[] = "<text>test</text>";
|
||||
static const char str13[] = "<?xml version=\"1.0\"?><text>test</text>";
|
||||
static const char str14[] = "";
|
||||
HRESULT hr;
|
||||
WS_XML_READER *reader;
|
||||
const WS_XML_NODE *node;
|
||||
unsigned int i;
|
||||
int found;
|
||||
static const struct
|
||||
{
|
||||
const char *text;
|
||||
HRESULT hr;
|
||||
WS_XML_NODE_TYPE type;
|
||||
int todo;
|
||||
}
|
||||
tests[] =
|
||||
{
|
||||
{ str1, S_OK, WS_XML_NODE_TYPE_ELEMENT },
|
||||
{ str2, WS_E_INVALID_FORMAT, 0 },
|
||||
{ str3, S_OK, WS_XML_NODE_TYPE_ELEMENT },
|
||||
{ str4, WS_E_INVALID_FORMAT, 0 },
|
||||
{ str5, WS_E_INVALID_FORMAT, 0 },
|
||||
{ str6, WS_E_INVALID_FORMAT, 0 },
|
||||
{ str7, S_OK, WS_XML_NODE_TYPE_TEXT },
|
||||
{ str8, WS_E_INVALID_FORMAT, 0 },
|
||||
{ str9, WS_E_INVALID_FORMAT, 0 },
|
||||
{ str10, WS_E_INVALID_FORMAT, 0, 1 },
|
||||
{ str11, S_OK, WS_XML_NODE_TYPE_EOF },
|
||||
{ str12, S_OK, WS_XML_NODE_TYPE_ELEMENT },
|
||||
{ str13, S_OK, WS_XML_NODE_TYPE_ELEMENT },
|
||||
{ str14, WS_E_INVALID_FORMAT, 0, 1 },
|
||||
};
|
||||
|
||||
hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
|
||||
{
|
||||
hr = set_input( reader, tests[i].text, strlen(tests[i].text) );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsFillReader( reader, strlen(tests[i].text), NULL, NULL );
|
||||
ok( hr == S_OK, "%u: got %08x\n", i, hr );
|
||||
|
||||
hr = WsReadNode( reader, NULL );
|
||||
if (tests[i].todo)
|
||||
todo_wine ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
|
||||
else
|
||||
ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
|
||||
if (hr == S_OK)
|
||||
{
|
||||
node = NULL;
|
||||
hr = WsGetReaderNode( reader, &node, NULL );
|
||||
ok( hr == S_OK, "%u: got %08x\n", i, hr );
|
||||
ok( node != NULL, "%u: node not set\n", i );
|
||||
if (node)
|
||||
{
|
||||
if (tests[i].todo)
|
||||
todo_wine
|
||||
ok( node->nodeType == tests[i].type, "%u: got %u\n", i, node->nodeType );
|
||||
else
|
||||
ok( node->nodeType == tests[i].type, "%u: got %u\n", i, node->nodeType );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hr = set_input( reader, data6, sizeof(data6) - 1 );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsFillReader( reader, sizeof(data6) - 1, NULL, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
found = -1;
|
||||
hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
ok( found == TRUE, "got %d\n", found );
|
||||
|
||||
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->prefix != NULL, "prefix not set\n" );
|
||||
ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
|
||||
ok( elem->prefix->bytes == NULL, "bytes set\n" );
|
||||
ok( elem->localName != NULL, "localName not set\n" );
|
||||
ok( elem->localName->length == 4, "got %u\n", elem->localName->length );
|
||||
ok( !memcmp( elem->localName->bytes, "text", 4 ), "wrong data\n" );
|
||||
ok( elem->ns != NULL, "ns not set\n" );
|
||||
ok( !elem->ns->length, "got %u\n", elem->ns->length );
|
||||
ok( elem->ns->bytes != NULL, "bytes not set\n" );
|
||||
ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount );
|
||||
ok( elem->attributes != NULL, "attributes not set\n" );
|
||||
ok( !elem->isEmpty, "isEmpty not zero\n" );
|
||||
|
||||
attr = elem->attributes[0];
|
||||
ok( !attr->singleQuote, "got %u\n", attr->singleQuote );
|
||||
ok( !attr->isXmlNs, "got %u\n", attr->isXmlNs );
|
||||
ok( attr->prefix != NULL, "prefix not set\n" );
|
||||
ok( !attr->prefix->length, "got %u\n", attr->prefix->length );
|
||||
ok( attr->prefix->bytes == NULL, "bytes set\n" );
|
||||
ok( attr->localName != NULL, "localName not set\n" );
|
||||
ok( attr->localName->length == 4, "got %u\n", attr->localName->length );
|
||||
ok( !memcmp( attr->localName->bytes, "attr", 4 ), "wrong data\n" );
|
||||
ok( attr->ns != NULL, "ns not set\n" );
|
||||
ok( !attr->ns->length, "got %u\n", attr->ns->length );
|
||||
ok( attr->ns->bytes == NULL, "bytes set\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 == 5, "got %u\n", text->value.length );
|
||||
ok( !memcmp( text->value.bytes, "value", 5 ), "wrong data\n" );
|
||||
}
|
||||
|
||||
WsFreeReader( reader );
|
||||
}
|
||||
|
||||
START_TEST(reader)
|
||||
{
|
||||
test_WsCreateError();
|
||||
|
@ -703,4 +908,6 @@ START_TEST(reader)
|
|||
test_WsFillReader();
|
||||
test_WsReadToStartElement();
|
||||
test_WsReadStartElement();
|
||||
test_WsReadEndElement();
|
||||
test_WsReadNode();
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@
|
|||
@ stub WsReadMessageEnd
|
||||
@ stub WsReadMessageStart
|
||||
@ stub WsReadMetadata
|
||||
@ stub WsReadNode
|
||||
@ stdcall WsReadNode(ptr ptr)
|
||||
@ stub WsReadQualifiedName
|
||||
@ stub WsReadStartAttribute
|
||||
@ stdcall WsReadStartElement(ptr ptr)
|
||||
|
|
Loading…
Reference in New Issue