Hans Leidekker : webservices: Implement WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT.

Alexandre Julliard julliard at winehq.org
Wed Oct 12 16:06:16 CDT 2016


Module: wine
Branch: master
Commit: 459b7caeb2a58895bf5d8173dd847edfec3815df
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=459b7caeb2a58895bf5d8173dd847edfec3815df

Author: Hans Leidekker <hans at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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;




More information about the wine-cvs mailing list