Module: wine Branch: master Commit: 459b7caeb2a58895bf5d8173dd847edfec3815df URL: http://source.winehq.org/git/wine.git/?a=commit;h=459b7caeb2a58895bf5d8173dd...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Oct 12 15:30:25 2016 +0200
webservices: Implement WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/webservices/reader.c | 109 +++++++++++++++++++++++---------- dlls/webservices/tests/reader.c | 42 ++++++++++++- dlls/webservices/webservices_private.h | 6 ++ 3 files changed, 124 insertions(+), 33 deletions(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 9a82bcd..9ba4dfc 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -4000,7 +4000,11 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping, char *buf;
if (!desc) return E_INVALIDARG; - if (desc->structOptions) FIXME( "struct options %08x not supported\n", desc->structOptions ); + if (desc->structOptions & ~WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT) + { + FIXME( "struct options %08x not supported\n", + desc->structOptions & ~WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT ); + }
switch (option) { @@ -4037,7 +4041,7 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping, return hr; } *(char **)ret = buf; - return S_OK; + break;
case WS_READ_OPTIONAL_POINTER: case WS_READ_NILLABLE_POINTER: @@ -4047,16 +4051,77 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping, buf = NULL; } *(char **)ret = buf; - return S_OK; + break;
case WS_READ_REQUIRED_VALUE: case WS_READ_NILLABLE_VALUE: - return hr; + if (hr != S_OK) return hr; + break;
default: ERR( "unhandled read option %u\n", option ); return E_NOTIMPL; } + + if (desc->structOptions & WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT) + { + struct node *parent = find_parent( reader ); + parent->flags |= NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT; + } + return S_OK; +} + +static HRESULT start_mapping( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_XML_STRING *localname, + const WS_XML_STRING *ns ) +{ + switch (mapping) + { + case WS_ELEMENT_TYPE_MAPPING: + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + return read_type_next_element_node( reader, localname, ns ); + + case WS_ANY_ELEMENT_TYPE_MAPPING: + case WS_ATTRIBUTE_TYPE_MAPPING: + return S_OK; + + default: + FIXME( "unhandled mapping %u\n", mapping ); + return E_NOTIMPL; + } +} + +static HRESULT read_type_endelement_node( struct reader *reader ) +{ + const struct node *parent = find_parent( reader ); + HRESULT hr; + + for (;;) + { + if ((hr = read_type_next_node( reader )) != S_OK) return hr; + if (node_type( reader->current ) == WS_XML_NODE_TYPE_END_ELEMENT && reader->current->parent == parent) + { + return S_OK; + } + if (read_end_of_data( reader ) || !(parent->flags & NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT)) break; + } + + return WS_E_INVALID_FORMAT; +} + +static HRESULT end_mapping( struct reader *reader, WS_TYPE_MAPPING mapping ) +{ + switch (mapping) + { + case WS_ELEMENT_TYPE_MAPPING: + return read_type_endelement_node( reader ); + + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + return read_type_next_node( reader ); + + case WS_ATTRIBUTE_TYPE_MAPPING: + default: + return S_OK; + } }
static HRESULT is_nil_element( const WS_XML_ELEMENT_NODE *elem ) @@ -4078,28 +4143,17 @@ static HRESULT is_nil_element( const WS_XML_ELEMENT_NODE *elem ) }
static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYPE type, - const WS_XML_STRING *localname, const WS_XML_STRING *ns, - const void *desc, WS_READ_OPTION option, WS_HEAP *heap, - void *value, ULONG size ) + const WS_XML_STRING *localname, const WS_XML_STRING *ns, const void *desc, + WS_READ_OPTION option, WS_HEAP *heap, void *value, ULONG size ) { HRESULT hr;
- switch (mapping) - { - case WS_ELEMENT_TYPE_MAPPING: - case WS_ELEMENT_CONTENT_TYPE_MAPPING: - if ((hr = read_type_next_element_node( reader, localname, ns )) != S_OK) return hr; - if ((option == WS_READ_NILLABLE_POINTER || option == WS_READ_NILLABLE_VALUE) && - is_nil_element( &reader->current->hdr )) return read_type_next_node( reader ); - break; - - case WS_ANY_ELEMENT_TYPE_MAPPING: - case WS_ATTRIBUTE_TYPE_MAPPING: - break; + if ((hr = start_mapping( reader, mapping, localname, ns )) != S_OK) return hr;
- default: - FIXME( "unhandled mapping %u\n", mapping ); - return E_NOTIMPL; + if (mapping == WS_ELEMENT_TYPE_MAPPING && is_nil_element( &reader->current->hdr )) + { + if (option != WS_READ_NILLABLE_POINTER && option != WS_READ_NILLABLE_VALUE) return WS_E_INVALID_FORMAT; + return end_mapping( reader, mapping ); }
switch (type) @@ -4189,16 +4243,7 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP return E_NOTIMPL; }
- switch (mapping) - { - case WS_ELEMENT_TYPE_MAPPING: - case WS_ELEMENT_CONTENT_TYPE_MAPPING: - return read_type_next_node( reader ); - - case WS_ATTRIBUTE_TYPE_MAPPING: - default: - return S_OK; - } + return end_mapping( reader, mapping ); }
/************************************************************************** diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index a020c01..62ed499 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -71,6 +71,12 @@ static const char data11[] = "</o:services>" "</o:OfficeConfig>";
+static const char data11b[] = + "<o:OfficeConfig xmlns:o="urn:schemas-microsoft-com:office:office">" + "<o:services o:GenerationTime="2015-09-03T18:47:54"></o:services>" + "<trailing>content</trailing>" + "</o:OfficeConfig>"; + static const char data12[] = "<services>" "<service><id>1</id></service>" @@ -2069,12 +2075,23 @@ static void test_simple_struct_type(void) s.typeLocalName = &localname2; s.typeNs = &ns;
- test = NULL; prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" ); hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL ); ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
+ prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" ); + hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + + s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT; + prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" ); + hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + s.structOptions = 0; + test = NULL; prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str>" ); hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, @@ -2815,6 +2832,29 @@ static void test_complex_struct_type(void) ok( hr == S_OK, "got %08x\n", hr ); ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
+ /* trailing content */ + prepare_struct_type_test( reader, data11b ); + hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT; + hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error ); + 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_EOF, "got %u\n", node->nodeType ); + + prepare_struct_type_test( reader, data11b ); + hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + s.structOptions = 0; + hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + WsFreeReader( reader ); WsFreeHeap( heap ); WsFreeError( error ); diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index 12b7984..424f3fe 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -41,12 +41,18 @@ HRESULT set_output( WS_XML_WRITER * ) DECLSPEC_HIDDEN; HRESULT set_input( WS_XML_READER *, char *, ULONG ) DECLSPEC_HIDDEN; ULONG get_type_size( WS_TYPE, const WS_STRUCT_DESCRIPTION * ) DECLSPEC_HIDDEN;
+enum node_flag +{ + NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT = 0x1, +}; + struct node { WS_XML_ELEMENT_NODE hdr; struct list entry; struct node *parent; struct list children; + ULONG flags; };
struct node *alloc_node( WS_XML_NODE_TYPE ) DECLSPEC_HIDDEN;