[3/7] webservices: Add initial support for binary XML in the reader.
Hans Leidekker
hans at codeweavers.com
Thu May 25 05:54:40 CDT 2017
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/webservices/reader.c | 451 +++++++++++++++++++++++++++++++---------
dlls/webservices/tests/reader.c | 52 +++++
2 files changed, 399 insertions(+), 104 deletions(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index befe8db794..4895603694 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -357,26 +357,27 @@ struct prefix
struct reader
{
- ULONG magic;
- CRITICAL_SECTION cs;
- ULONG read_size;
- ULONG read_pos;
- const unsigned char *read_bufptr;
- enum reader_state state;
- struct node *root;
- struct node *current;
- ULONG current_attr;
- struct node *last;
- struct prefix *prefixes;
- ULONG nb_prefixes;
- ULONG nb_prefixes_allocated;
- WS_XML_READER_INPUT_TYPE input_type;
- struct xmlbuf *input_buf;
- const unsigned char *input_data;
- ULONG input_size;
- ULONG text_conv_offset;
- ULONG prop_count;
- struct prop prop[sizeof(reader_props)/sizeof(reader_props[0])];
+ ULONG magic;
+ CRITICAL_SECTION cs;
+ ULONG read_size;
+ ULONG read_pos;
+ const unsigned char *read_bufptr;
+ enum reader_state state;
+ struct node *root;
+ struct node *current;
+ ULONG current_attr;
+ struct node *last;
+ struct prefix *prefixes;
+ ULONG nb_prefixes;
+ ULONG nb_prefixes_allocated;
+ WS_XML_READER_ENCODING_TYPE input_enc;
+ WS_XML_READER_INPUT_TYPE input_type;
+ struct xmlbuf *input_buf;
+ const unsigned char *input_data;
+ ULONG input_size;
+ ULONG text_conv_offset;
+ ULONG prop_count;
+ struct prop prop[sizeof(reader_props)/sizeof(reader_props[0])];
};
#define READER_MAGIC (('R' << 24) | ('E' << 16) | ('A' << 8) | 'D')
@@ -519,6 +520,7 @@ static HRESULT init_reader( struct reader *reader )
reader->nb_prefixes = 1;
if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
read_insert_eof( reader, node );
+ reader->input_enc = WS_XML_READER_ENCODING_TYPE_TEXT;
return S_OK;
}
@@ -819,6 +821,28 @@ static inline const unsigned char *read_current_ptr( struct reader *reader )
return &reader->read_bufptr[reader->read_pos];
}
+static inline HRESULT read_peek( struct reader *reader, unsigned char *byte )
+{
+ if (reader->read_pos >= reader->read_size) return WS_E_INVALID_FORMAT;
+ *byte = reader->read_bufptr[reader->read_pos];
+ return S_OK;
+}
+
+static inline HRESULT read_byte( struct reader *reader, unsigned char *byte )
+{
+ if (reader->read_pos >= reader->read_size) return WS_E_INVALID_FORMAT;
+ *byte = reader->read_bufptr[reader->read_pos++];
+ return S_OK;
+}
+
+static inline HRESULT read_bytes( struct reader *reader, unsigned char *bytes, unsigned int len )
+{
+ if (reader->read_pos + len > reader->read_size) return WS_E_INVALID_FORMAT;
+ memcpy( bytes, reader->read_bufptr + reader->read_pos, len );
+ reader->read_pos += len;
+ return S_OK;
+}
+
/* UTF-8 support based on libs/wine/utf8.c */
/* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */
@@ -1145,12 +1169,100 @@ static HRESULT decode_text( const unsigned char *str, ULONG len, unsigned char *
return S_OK;
}
-static HRESULT read_attribute( struct reader *reader, WS_XML_ATTRIBUTE **ret )
+static HRESULT read_attribute_value_text( struct reader *reader, WS_XML_ATTRIBUTE *attr )
+{
+ WS_XML_UTF8_TEXT *utf8 = NULL;
+ unsigned int len, ch, skip, quote;
+ const unsigned char *start;
+ HRESULT hr = E_OUTOFMEMORY;
+
+ read_skip_whitespace( reader );
+ if (read_cmp( reader, "=", 1 )) return WS_E_INVALID_FORMAT;
+ read_skip( reader, 1 );
+
+ read_skip_whitespace( reader );
+ if (read_cmp( reader, "\"", 1 ) && read_cmp( reader, "'", 1 )) return WS_E_INVALID_FORMAT;
+ quote = read_utf8_char( reader, &skip );
+ read_skip( reader, 1 );
+
+ len = 0;
+ start = read_current_ptr( reader );
+ for (;;)
+ {
+ if (!(ch = read_utf8_char( reader, &skip ))) return WS_E_INVALID_FORMAT;
+ if (ch == quote) break;
+ read_skip( reader, skip );
+ len += skip;
+ }
+ read_skip( reader, 1 );
+
+ if (attr->isXmlNs)
+ {
+ if (!(attr->ns = alloc_xml_string( start, len ))) goto error;
+ if ((hr = bind_prefix( reader, attr->prefix, attr->ns )) != S_OK) goto error;
+ if (!(utf8 = alloc_utf8_text( NULL, 0 )))
+ {
+ hr = E_OUTOFMEMORY;
+ goto error;
+ }
+ }
+ else
+ {
+ if (!(utf8 = alloc_utf8_text( NULL, len ))) goto error;
+ if ((hr = decode_text( start, len, utf8->value.bytes, &utf8->value.length )) != S_OK) goto error;
+ }
+
+ attr->value = &utf8->text;
+ attr->singleQuote = (quote == '\'');
+ return S_OK;
+
+error:
+ heap_free( utf8 );
+ return hr;
+}
+
+static HRESULT read_int31( struct reader *reader, ULONG *len )
+{
+ unsigned char byte;
+ HRESULT hr;
+
+ if ((hr = read_byte( reader, &byte )) != S_OK) return hr;
+ *len = byte & 0x7f;
+ if (!(byte & 0x80)) return S_OK;
+
+ if ((hr = read_byte( reader, &byte )) != S_OK) return hr;
+ *len += (byte & 0x7f) << 7;
+ if (!(byte & 0x80)) return S_OK;
+
+ if ((hr = read_byte( reader, &byte )) != S_OK) return hr;
+ *len += (byte & 0x7f) << 14;
+ if (!(byte & 0x80)) return S_OK;
+
+ if ((hr = read_byte( reader, &byte )) != S_OK) return hr;
+ *len += (byte & 0x7f) << 21;
+ if (!(byte & 0x80)) return S_OK;
+
+ if ((hr = read_byte( reader, &byte )) != S_OK) return hr;
+ *len += (byte & 0x07) << 28;
+ return S_OK;
+}
+
+static HRESULT read_string( struct reader *reader, WS_XML_STRING **str )
+{
+ ULONG len;
+ HRESULT hr;
+ if ((hr = read_int31( reader, &len )) != S_OK) return hr;
+ if (!(*str = alloc_xml_string( NULL, len ))) return E_OUTOFMEMORY;
+ if ((hr = read_bytes( reader, (*str)->bytes, len )) == S_OK) return S_OK;
+ heap_free( *str );
+ return hr;
+}
+
+static HRESULT read_attribute_text( struct reader *reader, WS_XML_ATTRIBUTE **ret )
{
static const WS_XML_STRING xmlns = {5, (BYTE *)"xmlns"};
WS_XML_ATTRIBUTE *attr;
- WS_XML_UTF8_TEXT *text = NULL;
- unsigned int len = 0, ch, skip, quote;
+ unsigned int len = 0, ch, skip;
const unsigned char *start;
WS_XML_STRING *prefix, *localname;
HRESULT hr = WS_E_INVALID_FORMAT;
@@ -1168,7 +1280,6 @@ static HRESULT read_attribute( struct reader *reader, WS_XML_ATTRIBUTE **ret )
if (!len) goto error;
if ((hr = parse_name( start, len, &prefix, &localname )) != S_OK) goto error;
- hr = E_OUTOFMEMORY;
if (WsXmlStringEquals( prefix, &xmlns, NULL ) == S_OK)
{
heap_free( prefix );
@@ -1176,6 +1287,7 @@ static HRESULT read_attribute( struct reader *reader, WS_XML_ATTRIBUTE **ret )
if (!(attr->prefix = alloc_xml_string( localname->bytes, localname->length )))
{
heap_free( localname );
+ hr = E_OUTOFMEMORY;
goto error;
}
attr->localName = localname;
@@ -1192,61 +1304,25 @@ static HRESULT read_attribute( struct reader *reader, WS_XML_ATTRIBUTE **ret )
attr->localName = localname;
}
- 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 ) && read_cmp( reader, "'", 1 )) goto error;
- quote = read_utf8_char( reader, &skip );
- read_skip( reader, 1 );
-
- len = 0;
- start = read_current_ptr( reader );
- for (;;)
- {
- if (!(ch = read_utf8_char( reader, &skip ))) goto error;
- if (ch == quote) break;
- read_skip( reader, skip );
- len += skip;
- }
- read_skip( reader, 1 );
-
- hr = E_OUTOFMEMORY;
- if (attr->isXmlNs)
- {
- if (!(attr->ns = alloc_xml_string( start, len ))) goto error;
- if ((hr = bind_prefix( reader, attr->prefix, attr->ns )) != S_OK) goto error;
- if (!(text = alloc_utf8_text( NULL, 0 ))) goto error;
- }
- else
- {
- if (!(text = alloc_utf8_text( NULL, len ))) goto error;
- if ((hr = decode_text( start, len, text->value.bytes, &text->value.length )) != S_OK) goto error;
- }
-
- attr->value = &text->text;
- attr->singleQuote = (quote == '\'');
+ if ((hr = read_attribute_value_text( reader, attr )) != S_OK) goto error;
*ret = attr;
return S_OK;
error:
- heap_free( text );
free_attribute( attr );
return hr;
}
-static struct node *find_parent( struct reader *reader )
+static inline struct node *find_parent( struct reader *reader )
{
if (node_type( reader->current ) == WS_XML_NODE_TYPE_END_ELEMENT)
{
if (is_valid_parent( reader->current->parent->parent )) return reader->current->parent->parent;
return NULL;
}
- else if (is_valid_parent( reader->current )) return reader->current;
- else if (is_valid_parent( reader->current->parent )) return reader->current->parent;
+ if (is_valid_parent( reader->current )) return reader->current;
+ if (is_valid_parent( reader->current->parent )) return reader->current->parent;
return NULL;
}
@@ -1270,13 +1346,47 @@ static HRESULT set_namespaces( struct reader *reader, WS_XML_ELEMENT_NODE *elem
return S_OK;
}
-static HRESULT read_element( struct reader *reader )
+static WS_XML_ELEMENT_NODE *alloc_element_pair(void)
+{
+ struct node *node, *end;
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_ELEMENT ))) return NULL;
+ if (!(end = alloc_node( WS_XML_NODE_TYPE_END_ELEMENT )))
+ {
+ free_node( node );
+ return NULL;
+ }
+ list_add_tail( &node->children, &end->entry );
+ end->parent = node;
+ return &node->hdr;
+}
+
+static HRESULT read_attributes_text( struct reader *reader, WS_XML_ELEMENT_NODE *elem )
+{
+ WS_XML_ATTRIBUTE *attr;
+ HRESULT hr;
+
+ reader->current_attr = 0;
+ for (;;)
+ {
+ read_skip_whitespace( reader );
+ if (!read_cmp( reader, ">", 1 ) || !read_cmp( reader, "/>", 2 )) break;
+ if ((hr = read_attribute_text( reader, &attr )) != S_OK) return hr;
+ if ((hr = append_attribute( elem, attr )) != S_OK)
+ {
+ free_attribute( attr );
+ return hr;
+ }
+ reader->current_attr++;
+ }
+ return S_OK;
+}
+
+static HRESULT read_element_text( struct reader *reader )
{
unsigned int len = 0, ch, skip;
const unsigned char *start;
- struct node *node = NULL, *endnode, *parent;
+ struct node *node = NULL, *parent;
WS_XML_ELEMENT_NODE *elem;
- WS_XML_ATTRIBUTE *attr = NULL;
HRESULT hr = WS_E_INVALID_FORMAT;
if (read_end_of_data( reader ))
@@ -1287,14 +1397,17 @@ static HRESULT read_element( struct reader *reader )
return S_OK;
}
- if (read_cmp( reader, "<", 1 )) goto error;
+ if (read_cmp( reader, "<", 1 )) return WS_E_INVALID_FORMAT;
read_skip( reader, 1 );
if (!read_isnamechar( read_utf8_char( reader, &skip )))
{
read_rewind( reader, 1 );
- goto error;
+ return WS_E_INVALID_FORMAT;;
}
+ if (!(elem = alloc_element_pair())) return E_OUTOFMEMORY;
+ node = (struct node *)elem;
+
start = read_current_ptr( reader );
for (;;)
{
@@ -1306,29 +1419,78 @@ static HRESULT read_element( struct reader *reader )
if (!len) goto error;
if (!(parent = find_parent( reader ))) goto error;
+ if ((hr = parse_name( start, len, &elem->prefix, &elem->localName )) != S_OK) goto error;
- hr = E_OUTOFMEMORY;
- if (!(node = alloc_node( WS_XML_NODE_TYPE_ELEMENT ))) goto error;
- if (!(endnode = alloc_node( WS_XML_NODE_TYPE_END_ELEMENT ))) goto error;
- list_add_tail( &node->children, &endnode->entry );
- endnode->parent = node;
+ if ((hr = read_attributes_text( reader, elem )) != S_OK) goto error;
+ if ((hr = set_namespaces( reader, elem )) != S_OK) goto error;
- elem = (WS_XML_ELEMENT_NODE *)node;
- if ((hr = parse_name( start, len, &elem->prefix, &elem->localName )) != S_OK) goto error;
+ read_insert_node( reader, parent, node );
+ reader->state = READER_STATE_STARTELEMENT;
+ return S_OK;
- reader->current_attr = 0;
- for (;;)
+error:
+ destroy_nodes( node );
+ return hr;
+}
+
+static inline BOOL is_element_type( unsigned char type )
+{
+ return (type >= RECORD_SHORT_ELEMENT && type <= RECORD_PREFIX_ELEMENT_Z);
+}
+
+static HRESULT read_element_bin( struct reader *reader )
+{
+ struct node *node = NULL, *parent;
+ WS_XML_ELEMENT_NODE *elem;
+ unsigned char type;
+ HRESULT hr;
+
+ if ((hr = read_byte( reader, &type )) != S_OK) return hr;
+ if (!is_element_type( type )) return WS_E_INVALID_FORMAT;
+
+ if (!(elem = alloc_element_pair())) return E_OUTOFMEMORY;
+ node = (struct node *)elem;
+
+ if (type >= RECORD_PREFIX_ELEMENT_A && type <= RECORD_PREFIX_ELEMENT_Z)
{
- read_skip_whitespace( reader );
- if (!read_cmp( reader, ">", 1 ) || !read_cmp( reader, "/>", 2 )) break;
- if ((hr = read_attribute( reader, &attr )) != S_OK) goto error;
- if ((hr = append_attribute( elem, attr )) != S_OK)
+ unsigned char ch = type - RECORD_PREFIX_ELEMENT_A + 'a';
+ if (!(elem->prefix = alloc_xml_string( &ch, 1 )))
{
- free_attribute( attr );
+ hr = E_OUTOFMEMORY;
goto error;
}
- reader->current_attr++;
+ if ((hr = read_string( reader, &elem->localName )) != S_OK) goto error;
}
+ else
+ {
+ switch (type)
+ {
+ case RECORD_SHORT_ELEMENT:
+ if (!(elem->prefix = alloc_xml_string( NULL, 0 )))
+ {
+ hr = E_OUTOFMEMORY;
+ goto error;
+ }
+ if ((hr = read_string( reader, &elem->localName )) != S_OK) goto error;
+ break;
+
+ case RECORD_ELEMENT:
+ if ((hr = read_string( reader, &elem->prefix )) != S_OK) goto error;
+ if ((hr = read_string( reader, &elem->localName )) != S_OK) goto error;
+ break;
+
+ default:
+ ERR( "unhandled record type %02x\n", type );
+ return WS_E_NOT_SUPPORTED;
+ }
+ }
+
+ if (!(parent = find_parent( reader )))
+ {
+ hr = WS_E_INVALID_FORMAT;
+ goto error;
+ }
+
if ((hr = set_namespaces( reader, elem )) != S_OK) goto error;
read_insert_node( reader, parent, node );
@@ -1382,7 +1544,7 @@ static HRESULT read_text( struct reader *reader )
return S_OK;
}
-static HRESULT read_node( struct reader * );
+static HRESULT read_node_text( struct reader * );
static HRESULT read_startelement( struct reader *reader )
{
@@ -1398,7 +1560,7 @@ static HRESULT read_startelement( struct reader *reader )
else if (!read_cmp( reader, ">", 1 ))
{
read_skip( reader, 1 );
- return read_node( reader );
+ return read_node_text( reader );
}
return WS_E_INVALID_FORMAT;
}
@@ -1422,7 +1584,7 @@ static HRESULT read_to_startelement( struct reader *reader, BOOL *found )
}
read_skip_whitespace( reader );
- if ((hr = read_element( reader )) == S_OK && found)
+ if ((hr = read_element_text( reader )) == S_OK && found)
{
if (reader->state == READER_STATE_STARTELEMENT)
*found = TRUE;
@@ -1441,8 +1603,8 @@ static int cmp_name( const unsigned char *name1, ULONG len1, const unsigned char
return 0;
}
-static struct node *read_find_startelement( struct reader *reader, const WS_XML_STRING *prefix,
- const WS_XML_STRING *localname )
+static struct node *find_startelement( struct reader *reader, const WS_XML_STRING *prefix,
+ const WS_XML_STRING *localname )
{
struct node *parent;
const WS_XML_STRING *str;
@@ -1461,7 +1623,7 @@ static struct node *read_find_startelement( struct reader *reader, const WS_XML_
return NULL;
}
-static HRESULT read_endelement( struct reader *reader )
+static HRESULT read_endelement_text( struct reader *reader )
{
struct node *parent;
unsigned int len = 0, ch, skip;
@@ -1469,16 +1631,6 @@ static HRESULT read_endelement( struct reader *reader )
WS_XML_STRING *prefix, *localname;
HRESULT hr;
- if (reader->state == READER_STATE_EOF) return WS_E_INVALID_FORMAT;
-
- if (read_end_of_data( reader ))
- {
- reader->current = LIST_ENTRY( list_tail( &reader->root->children ), struct node, entry );
- reader->last = reader->current;
- reader->state = READER_STATE_EOF;
- return S_OK;
- }
-
if (read_cmp( reader, "</", 2 )) return WS_E_INVALID_FORMAT;
read_skip( reader, 2 );
@@ -1497,7 +1649,7 @@ static HRESULT read_endelement( struct reader *reader )
}
if ((hr = parse_name( start, len, &prefix, &localname )) != S_OK) return hr;
- parent = read_find_startelement( reader, prefix, localname );
+ parent = find_startelement( reader, prefix, localname );
heap_free( prefix );
heap_free( localname );
if (!parent) return WS_E_INVALID_FORMAT;
@@ -1508,6 +1660,45 @@ static HRESULT read_endelement( struct reader *reader )
return S_OK;
}
+static HRESULT read_endelement_bin( struct reader *reader )
+{
+ struct node *parent;
+ unsigned char type;
+ HRESULT hr;
+
+ if ((hr = read_byte( reader, &type )) != S_OK) return hr;
+ if (type != RECORD_ENDELEMENT) return WS_E_INVALID_FORMAT;
+
+ if (!(parent = find_parent( reader ))) return WS_E_INVALID_FORMAT;
+
+ reader->current = LIST_ENTRY( list_tail( &parent->children ), struct node, entry );
+ reader->last = reader->current;
+ reader->state = READER_STATE_ENDELEMENT;
+ return S_OK;
+}
+
+static HRESULT read_endelement( struct reader *reader )
+{
+ if (reader->state == READER_STATE_EOF) return WS_E_INVALID_FORMAT;
+
+ if (read_end_of_data( reader ))
+ {
+ reader->current = LIST_ENTRY( list_tail( &reader->root->children ), struct node, entry );
+ reader->last = reader->current;
+ reader->state = READER_STATE_EOF;
+ return S_OK;
+ }
+
+ switch (reader->input_enc)
+ {
+ case WS_XML_READER_ENCODING_TYPE_TEXT: return read_endelement_text( reader );
+ case WS_XML_READER_ENCODING_TYPE_BINARY: return read_endelement_bin( reader );
+ default:
+ ERR( "unhandled encoding %u\n", reader->input_enc );
+ return WS_E_NOT_SUPPORTED;
+ }
+}
+
static HRESULT read_comment( struct reader *reader )
{
unsigned int len = 0, ch, skip;
@@ -1618,7 +1809,7 @@ static HRESULT read_endcdata( struct reader *reader )
return S_OK;
}
-static HRESULT read_node( struct reader *reader )
+static HRESULT read_node_text( struct reader *reader )
{
HRESULT hr;
@@ -1638,15 +1829,61 @@ static HRESULT read_node( struct reader *reader )
hr = read_xmldecl( reader );
if (FAILED( hr )) return hr;
}
- else if (!read_cmp( reader, "</", 2 )) return read_endelement( reader );
+ else if (!read_cmp( reader, "</", 2 )) return read_endelement_text( reader );
else if (!read_cmp( reader, "<![CDATA[", 9 )) return read_startcdata( reader );
else if (!read_cmp( reader, "<!--", 4 )) return read_comment( reader );
- else if (!read_cmp( reader, "<", 1 )) return read_element( reader );
+ else if (!read_cmp( reader, "<", 1 )) return read_element_text( reader );
else if (!read_cmp( reader, "/>", 2 ) || !read_cmp( reader, ">", 1 )) return read_startelement( reader );
else return read_text( reader );
}
}
+static HRESULT read_node_bin( struct reader *reader )
+{
+ unsigned char type;
+ HRESULT hr;
+
+ if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT)
+ {
+ reader->current = LIST_ENTRY( list_tail( &reader->current->parent->children ), struct node, entry );
+ reader->last = reader->current;
+ reader->state = READER_STATE_ENDELEMENT;
+ return S_OK;
+ }
+ if (read_end_of_data( reader ))
+ {
+ reader->current = LIST_ENTRY( list_tail( &reader->root->children ), struct node, entry );
+ reader->last = reader->current;
+ reader->state = READER_STATE_EOF;
+ return S_OK;
+ }
+
+ if ((hr = read_peek( reader, &type )) != S_OK) return hr;
+ if (type == RECORD_ENDELEMENT)
+ {
+ return read_endelement_bin( reader );
+ }
+ else if (type >= RECORD_SHORT_ELEMENT && type <= RECORD_PREFIX_ELEMENT_Z)
+ {
+ return read_element_bin( reader );
+ }
+
+ FIXME( "unhandled record type %02x\n", type );
+ return WS_E_NOT_SUPPORTED;
+}
+
+static HRESULT read_node( struct reader *reader )
+{
+ switch (reader->input_enc)
+ {
+ case WS_XML_READER_ENCODING_TYPE_TEXT: return read_node_text( reader );
+ case WS_XML_READER_ENCODING_TYPE_BINARY: return read_node_bin( reader );
+ default:
+ ERR( "unhandled encoding %u\n", reader->input_enc );
+ return WS_E_NOT_SUPPORTED;
+ }
+}
+
HRESULT copy_node( WS_XML_READER *handle, struct node **node )
{
struct reader *reader = (struct reader *)handle;
@@ -4641,8 +4878,14 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
hr = prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET,
&charset, sizeof(charset) );
if (hr != S_OK) goto done;
+
+ reader->input_enc = WS_XML_READER_ENCODING_TYPE_TEXT;
break;
}
+ case WS_XML_READER_ENCODING_TYPE_BINARY:
+ reader->input_enc = WS_XML_READER_ENCODING_TYPE_BINARY;
+ break;
+
default:
FIXME( "encoding type %u not supported\n", encoding->encodingType );
hr = E_NOTIMPL;
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index b7c3c75567..34fe2da564 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -4495,6 +4495,57 @@ static void test_WsSkipNode(void)
WsFreeReader( reader );
}
+static HRESULT set_input_bin( WS_XML_READER *reader, const char *data, ULONG size )
+{
+ WS_XML_READER_BINARY_ENCODING bin = {{WS_XML_READER_ENCODING_TYPE_BINARY}};
+ WS_XML_READER_BUFFER_INPUT buf;
+
+ buf.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER;
+ buf.encodedData = (void *)data;
+ buf.encodedDataSize = size;
+ return WsSetInput( reader, &bin.encoding, &buf.input, NULL, 0, NULL );
+}
+
+static void test_binary_encoding(void)
+{
+ static const char res[] =
+ {0x40,0x01,'t',0x01};
+ const WS_XML_NODE *node;
+ const WS_XML_ELEMENT_NODE *elem;
+ WS_XML_READER *reader;
+ HRESULT hr;
+
+ hr = WsCreateReader( NULL, 0, &reader, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ /* short element */
+ hr = set_input_bin( reader, res, sizeof(res) );
+ 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 );
+ ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
+ elem = (const WS_XML_ELEMENT_NODE *)node;
+ ok( !elem->prefix->length, "got %u\n", elem->prefix->length );
+ ok( elem->prefix->bytes == NULL, "bytes set\n" );
+ ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
+ ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
+ ok( !elem->ns->length, "got %u\n", elem->ns->length );
+ ok( elem->ns->bytes != NULL, "bytes not set\n" );
+ ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
+ ok( !elem->isEmpty, "empty\n" );
+
+ 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 );
+ ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
+
+ WsFreeReader( reader );
+}
+
START_TEST(reader)
{
test_WsCreateError();
@@ -4537,4 +4588,5 @@ START_TEST(reader)
test_WsReadQualifiedName();
test_WsReadAttribute();
test_WsSkipNode();
+ test_binary_encoding();
}
--
2.11.0
More information about the wine-patches
mailing list