Hans Leidekker : webservices: Support WS_CHARSET_UTF16LE for buffer input.

Alexandre Julliard julliard at winehq.org
Fri Mar 27 16:14:39 CDT 2020


Module: wine
Branch: master
Commit: 18d32bfb55a85ddacb6ffe02f00969d451584fa3
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=18d32bfb55a85ddacb6ffe02f00969d451584fa3

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Fri Mar 27 15:47:41 2020 +0100

webservices: Support WS_CHARSET_UTF16LE for buffer input.

Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/webservices/reader.c       | 85 +++++++++++++++++++++++++++++------------
 dlls/webservices/tests/reader.c |  2 +-
 2 files changed, 61 insertions(+), 26 deletions(-)

diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 0d0e7d09f0..ffa789fb6e 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -395,7 +395,7 @@ struct reader
     WS_READ_CALLBACK             input_cb;
     void                        *input_cb_state;
     struct xmlbuf               *input_buf;
-    const unsigned char         *input_data;
+    unsigned char               *input_conv;
     ULONG                        input_size;
     ULONG                        text_conv_offset;
     unsigned char               *stream_buf;
@@ -519,6 +519,7 @@ static void free_reader( struct reader *reader )
     clear_prefixes( reader->prefixes, reader->nb_prefixes );
     heap_free( reader->prefixes );
     heap_free( reader->stream_buf );
+    heap_free( reader->input_conv );
 
     reader->cs.DebugInfo->Spare[0] = 0;
     DeleteCriticalSection( &reader->cs );
@@ -6893,18 +6894,40 @@ static WS_CHARSET detect_charset( const unsigned char *data, ULONG size, ULONG *
     return ret;
 }
 
-static void set_input_buffer( struct reader *reader, const unsigned char *data, ULONG size )
+static HRESULT utf16le_to_utf8( const unsigned char *data, ULONG size, unsigned char **buf, ULONG *buflen )
+{
+    if (size % sizeof(WCHAR)) return E_INVALIDARG;
+    *buflen = WideCharToMultiByte( CP_UTF8, 0, (const WCHAR *)data, size / sizeof(WCHAR), NULL, 0, NULL, NULL );
+    if (!(*buf = heap_alloc( *buflen ))) return E_OUTOFMEMORY;
+    WideCharToMultiByte( CP_UTF8, 0, (const WCHAR *)data, size / sizeof(WCHAR), (char *)*buf, *buflen, NULL, NULL );
+    return S_OK;
+}
+
+static HRESULT set_input_buffer( struct reader *reader, const unsigned char *data, ULONG size )
 {
     reader->input_type  = WS_XML_READER_INPUT_TYPE_BUFFER;
     reader->input_buf   = NULL;
-    reader->input_data  = data;
-    reader->input_size  = size;
 
-    reader->read_size   = reader->input_size;
-    reader->read_pos    = 0;
-    reader->read_bufptr = reader->input_data;
+    if (reader->input_enc == WS_XML_READER_ENCODING_TYPE_TEXT && reader->input_charset == WS_CHARSET_UTF16LE)
+    {
+        unsigned char *buf;
+        ULONG buflen;
+        HRESULT hr;
+
+        if ((hr = utf16le_to_utf8( data, size, &buf, &buflen )) != S_OK) return hr;
+        heap_free( reader->input_conv );
+        reader->read_bufptr = reader->input_conv = buf;
+        reader->read_size   = reader->input_size = buflen;
+    }
+    else
+    {
+        reader->read_bufptr = data;
+        reader->read_size   = reader->input_size = size;
+    }
 
+    reader->read_pos         = 0;
     reader->text_conv_offset = 0;
+    return S_OK;
 }
 
 static void set_input_stream( struct reader *reader, WS_READ_CALLBACK callback, void *state )
@@ -6913,7 +6936,6 @@ static void set_input_stream( struct reader *reader, WS_READ_CALLBACK callback,
     reader->input_cb       = callback;
     reader->input_cb_state = state;
     reader->input_buf      = NULL;
-    reader->input_data     = reader->stream_buf;
     reader->input_size     = STREAM_BUFSIZE;
 
     if (reader->read_pos >= reader->read_size) reader->read_size = 0;
@@ -6922,9 +6944,8 @@ static void set_input_stream( struct reader *reader, WS_READ_CALLBACK callback,
         memmove( reader->stream_buf, reader->stream_buf + reader->read_pos, reader->read_size - reader->read_pos );
         reader->read_size -= reader->read_pos;
     }
-    reader->read_pos    = 0;
-    reader->read_bufptr = reader->input_data;
-
+    reader->read_pos         = 0;
+    reader->read_bufptr      = reader->stream_buf;
     reader->text_conv_offset = 0;
 }
 
@@ -6997,7 +7018,8 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
     case WS_XML_READER_INPUT_TYPE_BUFFER:
     {
         const WS_XML_READER_BUFFER_INPUT *buf = (const WS_XML_READER_BUFFER_INPUT *)input;
-        set_input_buffer( reader, (const unsigned char *)buf->encodedData + offset, buf->encodedDataSize - offset );
+        hr = set_input_buffer( reader, (const unsigned char *)buf->encodedData + offset, buf->encodedDataSize - offset );
+        if (hr != S_OK) goto done;
         break;
     }
     case WS_XML_READER_INPUT_TYPE_STREAM:
@@ -7026,22 +7048,35 @@ done:
     return hr;
 }
 
-static void set_input_xml_buffer( struct reader *reader, struct xmlbuf *buf )
+static HRESULT set_input_xml_buffer( struct reader *reader, struct xmlbuf *xmlbuf )
 {
     reader->input_type    = WS_XML_READER_INPUT_TYPE_BUFFER;
-    reader->input_buf     = buf;
-    reader->input_enc     = buf->encoding;
-    reader->input_charset = buf->charset;
-    reader->input_data    = buf->bytes.bytes;
-    reader->input_size    = buf->bytes.length;
-    reader->dict_static   = buf->dict_static;
-    reader->dict          = buf->dict;
-
-    reader->read_size   = reader->input_size;
-    reader->read_pos    = 0;
-    reader->read_bufptr = reader->input_data;
+    reader->input_buf     = xmlbuf;
+    reader->input_enc     = xmlbuf->encoding;
+    reader->input_charset = xmlbuf->charset;
+    reader->dict_static   = xmlbuf->dict_static;
+    reader->dict          = xmlbuf->dict;
+
+    if (reader->input_enc == WS_XML_READER_ENCODING_TYPE_TEXT && reader->input_charset == WS_CHARSET_UTF16LE)
+    {
+        unsigned char *buf;
+        ULONG buflen;
+        HRESULT hr;
 
+        if ((hr = utf16le_to_utf8( xmlbuf->bytes.bytes, xmlbuf->bytes.length, &buf, &buflen )) != S_OK) return hr;
+        heap_free( reader->input_conv );
+        reader->read_bufptr = reader->input_conv = buf;
+        reader->read_size   = reader->input_size = buflen;
+    }
+    else
+    {
+        reader->read_bufptr = xmlbuf->bytes.bytes;
+        reader->read_size   = reader->input_size = xmlbuf->bytes.length;
+    }
+
+    reader->read_pos         = 0;
     reader->text_conv_offset = 0;
+    return S_OK;
 }
 
 /**************************************************************************
@@ -7078,7 +7113,7 @@ HRESULT WINAPI WsSetInputToBuffer( WS_XML_READER *handle, WS_XML_BUFFER *buffer,
     }
 
     if ((hr = init_reader( reader )) != S_OK) goto done;
-    set_input_xml_buffer( reader, xmlbuf );
+    if ((hr = set_input_xml_buffer( reader, xmlbuf )) != S_OK) goto done;
 
     if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY;
     else read_insert_bof( reader, node );
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index 4b9b589d8d..7d56ebccd5 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -524,7 +524,7 @@ static void test_WsSetInput(void)
 
     found = -1;
     hr = WsReadToStartElement( reader, NULL, NULL, &found, NULL );
-    todo_wine ok( hr == S_OK, "got %08x\n", hr );
+    ok( hr == S_OK, "got %08x\n", hr );
     if (hr == S_OK)
     {
         ok( found == TRUE, "got %d\n", found );




More information about the wine-cvs mailing list