[8/8] webservices: Implement WsSetInputToBuffer.

Hans Leidekker hans at codeweavers.com
Thu Oct 22 04:30:13 CDT 2015


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/webservices/reader.c         | 137 ++++++++++++++++++++++++++------------
 dlls/webservices/tests/reader.c   |  74 ++++++++++++++++++--
 dlls/webservices/webservices.spec |   2 +-
 3 files changed, 164 insertions(+), 49 deletions(-)

diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 870e7de..aeba36c 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -365,16 +365,17 @@ enum reader_state
 
 struct reader
 {
-    ULONG                   read_size;
-    ULONG                   read_pos;
-    const char             *read_bufptr;
-    enum reader_state       state;
-    struct list             nodes;
-    struct node            *current;
-    const char             *input_data;
-    ULONG                   input_size;
-    ULONG                   prop_count;
-    WS_XML_READER_PROPERTY  prop[sizeof(reader_props)/sizeof(reader_props[0])];
+    ULONG                    read_size;
+    ULONG                    read_pos;
+    const char              *read_bufptr;
+    enum reader_state        state;
+    struct list              nodes;
+    struct node             *current;
+    WS_XML_READER_INPUT_TYPE input_type;
+    const char              *input_data;
+    ULONG                    input_size;
+    ULONG                    prop_count;
+    WS_XML_READER_PROPERTY   prop[sizeof(reader_props)/sizeof(reader_props[0])];
 };
 
 static struct reader *alloc_reader(void)
@@ -416,6 +417,21 @@ static HRESULT get_reader_prop( struct reader *reader, WS_XML_READER_PROPERTY_ID
     return S_OK;
 }
 
+static HRESULT read_init_state( struct reader *reader )
+{
+    struct node *node;
+
+    list_init( &reader->nodes );
+    if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
+    list_add_tail( &reader->nodes, &node->entry );
+    reader->current     = node;
+    reader->state       = READER_STATE_INITIAL;
+    reader->read_size   = 0;
+    reader->read_pos    = 0;
+    reader->read_bufptr = NULL;
+    return S_OK;
+}
+
 /**************************************************************************
  *          WsCreateReader		[webservices.@]
  */
@@ -423,7 +439,6 @@ HRESULT WINAPI WsCreateReader( const WS_XML_READER_PROPERTY *properties, ULONG c
                                WS_XML_READER **handle, WS_ERROR *error )
 {
     struct reader *reader;
-    struct node *node;
     ULONG i, max_depth = 32, max_attrs = 128, max_ns = 32;
     WS_CHARSET charset = WS_CHARSET_UTF8;
     BOOL read_decl = TRUE;
@@ -451,15 +466,11 @@ HRESULT WINAPI WsCreateReader( const WS_XML_READER_PROPERTY *properties, ULONG c
         }
     }
 
-    if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF )))
+    if ((hr = read_init_state( reader )) != S_OK)
     {
         heap_free( reader );
-        return E_OUTOFMEMORY;
+        return hr;
     }
-    list_init( &reader->nodes );
-    list_add_tail( &reader->nodes, &node->entry );
-    reader->current = node;
-    reader->state   = READER_STATE_INITIAL;
 
     *handle = (WS_XML_READER *)reader;
     return S_OK;
@@ -562,7 +573,7 @@ HRESULT WINAPI WsGetReaderProperty( WS_XML_READER *handle, WS_XML_READER_PROPERT
     TRACE( "%p %u %p %u %p\n", handle, id, buf, size, error );
     if (error) FIXME( "ignoring error parameter\n" );
 
-    if (!reader->input_data) return WS_E_INVALID_OPERATION;
+    if (!reader->input_type) return WS_E_INVALID_OPERATION;
 
     if (id == WS_XML_READER_PROPERTY_CHARSET)
     {
@@ -1418,34 +1429,22 @@ static inline BOOL is_utf16le( const unsigned char *data, ULONG size, ULONG *off
            (size >= 4 && p[0] == '<' && !p[1] && !(*offset = 0));
 }
 
-static HRESULT detect_charset( const WS_XML_READER_INPUT *input, WS_CHARSET *charset, ULONG *offset )
+static WS_CHARSET detect_charset( const unsigned char *data, ULONG size, ULONG *offset )
 {
-    const WS_XML_READER_BUFFER_INPUT *buf = (const WS_XML_READER_BUFFER_INPUT *)input;
-
-    if (input->inputType != WS_XML_READER_INPUT_TYPE_BUFFER)
-    {
-        FIXME( "charset detection on input type %u not supported\n", input->inputType );
-        return E_NOTIMPL;
-    }
+    WS_CHARSET ret = 0;
 
     /* FIXME: parse xml declaration */
 
-    if (is_utf16le( buf->encodedData, buf->encodedDataSize, offset ))
-    {
-        *charset = WS_CHARSET_UTF16LE;
-    }
-    else if (is_utf8( buf->encodedData, buf->encodedDataSize, offset ))
-    {
-        *charset = WS_CHARSET_UTF8;
-    }
+    if (is_utf16le( data, size, offset )) ret = WS_CHARSET_UTF16LE;
+    else if (is_utf8( data, size, offset )) ret = WS_CHARSET_UTF8;
     else
     {
         FIXME( "charset not recognized\n" );
-        *charset = 0;
+        return 0;
     }
 
-    TRACE( "detected charset %u\n", *charset );
-    return S_OK;
+    TRACE( "detected charset %u\n", ret );
+    return ret;
 }
 
 /**************************************************************************
@@ -1465,15 +1464,35 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
 
     if (!reader) return E_INVALIDARG;
 
+    for (i = 0; i < count; i++)
+    {
+        hr = set_reader_prop( reader, properties[i].id, properties[i].value, properties[i].valueSize );
+        if (hr != S_OK) return hr;
+    }
+
+    destroy_nodes( &reader->nodes );
+    if ((hr = read_init_state( reader )) != S_OK) return hr;
+
+    if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY;
+    list_add_head( &reader->nodes, &node->entry );
+    reader->current = node;
+
     switch (encoding->encodingType)
     {
         case WS_XML_READER_ENCODING_TYPE_TEXT:
         {
             WS_XML_READER_TEXT_ENCODING *text = (WS_XML_READER_TEXT_ENCODING *)encoding;
+            WS_XML_READER_BUFFER_INPUT *buf = (WS_XML_READER_BUFFER_INPUT *)input;
             WS_CHARSET charset = text->charSet;
 
-            if (charset == WS_CHARSET_AUTO && (hr = detect_charset( input, &charset, &offset )) != S_OK)
-                return hr;
+            if (input->inputType != WS_XML_READER_INPUT_TYPE_BUFFER)
+            {
+                FIXME( "charset detection on input type %u not supported\n", input->inputType );
+                return E_NOTIMPL;
+            }
+
+            if (charset == WS_CHARSET_AUTO)
+                charset = detect_charset( buf->encodedData, buf->encodedDataSize, &offset );
 
             hr = set_reader_prop( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, sizeof(charset) );
             if (hr != S_OK) return hr;
@@ -1488,8 +1507,10 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
         case WS_XML_READER_INPUT_TYPE_BUFFER:
         {
             WS_XML_READER_BUFFER_INPUT *buf = (WS_XML_READER_BUFFER_INPUT *)input;
-            reader->input_data = (const char *)buf->encodedData + offset;
-            reader->input_size = buf->encodedDataSize - offset;
+
+            reader->input_type  = WS_XML_READER_INPUT_TYPE_BUFFER;
+            reader->input_data  = (const char *)buf->encodedData + offset;
+            reader->input_size  = buf->encodedDataSize - offset;
             reader->read_bufptr = reader->input_data;
             break;
         }
@@ -1498,16 +1519,48 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
             return E_NOTIMPL;
     }
 
+    return S_OK;
+}
+
+/**************************************************************************
+ *          WsSetInputToBuffer		[webservices.@]
+ */
+HRESULT WINAPI WsSetInputToBuffer( WS_XML_READER *handle, WS_XML_BUFFER *buffer,
+                                   const WS_XML_READER_PROPERTY *properties, ULONG count,
+                                   WS_ERROR *error )
+{
+    struct reader *reader = (struct reader *)handle;
+    struct xmlbuf *xmlbuf = (struct xmlbuf *)buffer;
+    WS_CHARSET charset;
+    struct node *node;
+    HRESULT hr;
+    ULONG i, offset = 0;
+
+    TRACE( "%p %p %p %u %p\n", handle, buffer, properties, count, error );
+    if (error) FIXME( "ignoring error parameter\n" );
+
+    if (!reader || !xmlbuf) return E_INVALIDARG;
+
     for (i = 0; i < count; i++)
     {
         hr = set_reader_prop( reader, properties[i].id, properties[i].value, properties[i].valueSize );
         if (hr != S_OK) return hr;
     }
 
+    destroy_nodes( &reader->nodes );
+    if ((hr = read_init_state( reader )) != S_OK) return hr;
+
     if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY;
     list_add_head( &reader->nodes, &node->entry );
     reader->current = node;
-    reader->state   = READER_STATE_INITIAL;
 
+    charset = detect_charset( xmlbuf->ptr, xmlbuf->size, &offset );
+    hr = set_reader_prop( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, sizeof(charset) );
+    if (hr != S_OK) return hr;
+
+    reader->input_type  = WS_XML_READER_INPUT_TYPE_BUFFER;
+    reader->input_data  = (const char *)xmlbuf->ptr + offset;
+    reader->input_size  = xmlbuf->size - offset;
+    reader->read_bufptr = reader->input_data;
     return S_OK;
 }
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index 03dd569..3f23d90 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -235,8 +235,7 @@ static HRESULT set_input( WS_XML_READER *reader, const char *data, ULONG size )
     input.encodedData     = (void *)data;
     input.encodedDataSize = size;
 
-    return WsSetInput( reader, (WS_XML_READER_ENCODING *)&encoding,
-                       (WS_XML_READER_INPUT *)&input, NULL, 0, NULL );
+    return WsSetInput( reader, &encoding.encoding, &input.input, NULL, 0, NULL );
 }
 
 static void test_WsCreateReader(void)
@@ -457,7 +456,7 @@ static void test_WsSetInput(void)
     input.encodedData     = (void *)data1;
     input.encodedDataSize = sizeof(data1) - 1;
 
-    hr = WsSetInput( reader, (WS_XML_READER_ENCODING *)&enc, (WS_XML_READER_INPUT *)&input, NULL, 0, NULL );
+    hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
     ok( hr == S_OK, "got %08x\n", hr );
 
     node = NULL;
@@ -467,7 +466,7 @@ static void test_WsSetInput(void)
     if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
 
     /* multiple calls are allowed */
-    hr = WsSetInput( reader, (WS_XML_READER_ENCODING *)&enc, (WS_XML_READER_INPUT *)&input, NULL, 0, NULL );
+    hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
     ok( hr == S_OK, "got %08x\n", hr );
 
     /* charset is detected by WsSetInput */
@@ -478,7 +477,7 @@ static void test_WsSetInput(void)
     {
         input.encodedData     = tests[i].data;
         input.encodedDataSize = tests[i].size;
-        hr = WsSetInput( reader, (WS_XML_READER_ENCODING *)&enc, (WS_XML_READER_INPUT *)&input, NULL, 0, NULL );
+        hr = WsSetInput( reader, &enc.encoding, &input.input, NULL, 0, NULL );
         ok( hr == S_OK, "%u: got %08x\n", i, hr );
 
         charset = 0xdeadbeef;
@@ -506,7 +505,7 @@ static void test_WsSetInput(void)
     prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
     prop.value = &max_depth;
     prop.valueSize = sizeof(max_depth);
-    hr = WsSetInput( reader, (WS_XML_READER_ENCODING *)&enc, (WS_XML_READER_INPUT *)&input, &prop, 1, NULL );
+    hr = WsSetInput( reader, &enc.encoding, &input.input, &prop, 1, NULL );
     ok( hr == S_OK, "got %08x\n", hr );
 
     max_depth = 0xdeadbeef;
@@ -517,6 +516,68 @@ static void test_WsSetInput(void)
     WsFreeReader( reader );
 }
 
+static void test_WsSetInputToBuffer(void)
+{
+    HRESULT hr;
+    WS_HEAP *heap;
+    WS_XML_BUFFER *buffer;
+    WS_XML_READER *reader;
+    WS_XML_READER_PROPERTY prop;
+    const WS_XML_NODE *node;
+    ULONG size, max_depth;
+
+    hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsSetInputToBuffer( NULL, NULL, NULL, 0, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = WsSetInputToBuffer( reader, NULL, NULL, 0, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    node = NULL;
+    hr = WsGetReaderNode( reader, &node, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( node != NULL, "node not set\n" );
+    if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
+
+    hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    node = NULL;
+    hr = WsGetReaderNode( reader, &node, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( node != NULL, "node not set\n" );
+    if (node) ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
+
+    /* multiple calls are allowed */
+    hr = WsSetInputToBuffer( reader, buffer, NULL, 0, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    /* reader properties can be set with WsSetInputToBuffer */
+    max_depth = 16;
+    prop.id = WS_XML_READER_PROPERTY_MAX_DEPTH;
+    prop.value = &max_depth;
+    prop.valueSize = sizeof(max_depth);
+    hr = WsSetInputToBuffer( reader, buffer, &prop, 1, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    max_depth = 0xdeadbeef;
+    size = sizeof(max_depth);
+    hr = WsGetReaderProperty( reader, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, size, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( max_depth == 16, "got %u\n", max_depth );
+
+    WsFreeReader( reader );
+    WsFreeHeap( heap );
+}
+
 static void test_WsFillReader(void)
 {
     HRESULT hr;
@@ -1351,6 +1412,7 @@ START_TEST(reader)
     test_WsCreateHeap();
     test_WsCreateReader();
     test_WsSetInput();
+    test_WsSetInputToBuffer();
     test_WsFillReader();
     test_WsReadToStartElement();
     test_WsReadStartElement();
diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec
index 4a8b88e..6e0f4f2 100644
--- a/dlls/webservices/webservices.spec
+++ b/dlls/webservices/webservices.spec
@@ -151,7 +151,7 @@
 @ stub WsSetFaultErrorProperty
 @ stub WsSetHeader
 @ stdcall WsSetInput(ptr ptr ptr ptr long ptr)
-@ stub WsSetInputToBuffer
+@ stdcall WsSetInputToBuffer(ptr ptr ptr long ptr)
 @ stub WsSetListenerProperty
 @ stub WsSetMessageProperty
 @ stdcall WsSetOutput(ptr ptr ptr ptr long ptr)
-- 
2.6.1




More information about the wine-patches mailing list