From 1ba18219491aa5a03aceee1d8c2bfecaa7f5f4da Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Wed, 14 Jun 2017 11:07:31 +0200 Subject: [PATCH] webservices: Store buffer encoding and character set. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/webservices/heap.c | 9 +++- dlls/webservices/reader.c | 59 +++++++++++--------------- dlls/webservices/webservices_private.h | 10 +++-- dlls/webservices/writer.c | 42 ++++++++++++------ 4 files changed, 66 insertions(+), 54 deletions(-) diff --git a/dlls/webservices/heap.c b/dlls/webservices/heap.c index 7a4b3b41d7e..a135cffed65 100644 --- a/dlls/webservices/heap.c +++ b/dlls/webservices/heap.c @@ -315,7 +315,7 @@ HRESULT WINAPI WsGetHeapProperty( WS_HEAP *handle, WS_HEAP_PROPERTY_ID id, void } #define XML_BUFFER_INITIAL_ALLOCATED_SIZE 256 -struct xmlbuf *alloc_xmlbuf( WS_HEAP *heap ) +struct xmlbuf *alloc_xmlbuf( WS_HEAP *heap, WS_XML_WRITER_ENCODING_TYPE encoding, WS_CHARSET charset ) { struct xmlbuf *ret; @@ -328,6 +328,8 @@ struct xmlbuf *alloc_xmlbuf( WS_HEAP *heap ) ret->heap = heap; ret->size = XML_BUFFER_INITIAL_ALLOCATED_SIZE; ret->bytes.length = 0; + ret->encoding = encoding; + ret->charset = charset; return ret; } @@ -349,7 +351,10 @@ HRESULT WINAPI WsCreateXmlBuffer( WS_HEAP *heap, const WS_XML_BUFFER_PROPERTY *p if (!heap || !handle) return E_INVALIDARG; if (count) FIXME( "properties not implemented\n" ); - if (!(xmlbuf = alloc_xmlbuf( heap ))) return WS_E_QUOTA_EXCEEDED; + if (!(xmlbuf = alloc_xmlbuf( heap, WS_XML_WRITER_ENCODING_TYPE_TEXT, WS_CHARSET_UTF8 ))) + { + return WS_E_QUOTA_EXCEEDED; + } *handle = (WS_XML_BUFFER *)xmlbuf; return S_OK; diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 4a427cc47be..2dad976d5aa 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -365,6 +365,7 @@ struct reader ULONG nb_prefixes; ULONG nb_prefixes_allocated; WS_XML_READER_ENCODING_TYPE input_enc; + WS_CHARSET input_charset; WS_XML_READER_INPUT_TYPE input_type; struct xmlbuf *input_buf; const unsigned char *input_data; @@ -510,9 +511,10 @@ static HRESULT init_reader( struct reader *reader ) 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; - reader->dict_static = NULL; - reader->dict = NULL; + reader->input_enc = WS_XML_READER_ENCODING_TYPE_TEXT; + reader->input_charset = WS_CHARSET_UTF8; + reader->dict_static = NULL; + reader->dict = NULL; return S_OK; } @@ -524,7 +526,6 @@ HRESULT WINAPI WsCreateReader( const WS_XML_READER_PROPERTY *properties, ULONG c { struct reader *reader; ULONG i, max_depth = 32, max_attrs = 128, max_ns = 32; - WS_CHARSET charset = WS_CHARSET_UTF8; BOOL read_decl = TRUE; HRESULT hr; @@ -537,7 +538,6 @@ HRESULT WINAPI WsCreateReader( const WS_XML_READER_PROPERTY *properties, ULONG c prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_MAX_DEPTH, &max_depth, sizeof(max_depth) ); prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES, &max_attrs, sizeof(max_attrs) ); prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_READ_DECLARATION, &read_decl, sizeof(read_decl) ); - prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET, &charset, sizeof(charset) ); prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_MAX_NAMESPACES, &max_ns, sizeof(max_ns) ); for (i = 0; i < count; i++) @@ -719,6 +719,14 @@ HRESULT WINAPI WsGetReaderNode( WS_XML_READER *handle, const WS_XML_NODE **node, return S_OK; } +static HRESULT get_charset( struct reader *reader, void *buf, ULONG size ) +{ + if (!buf || size != sizeof(reader->input_charset)) return E_INVALIDARG; + if (!reader->input_charset) return WS_E_INVALID_FORMAT; + *(WS_CHARSET *)buf = reader->input_charset; + return S_OK; +} + /************************************************************************** * WsGetReaderProperty [webservices.@] */ @@ -747,21 +755,9 @@ HRESULT WINAPI WsGetReaderProperty( WS_XML_READER *handle, WS_XML_READER_PROPERT return WS_E_INVALID_OPERATION; } - if (id == WS_XML_READER_PROPERTY_CHARSET) - { - WS_CHARSET charset; - if ((hr = prop_get( reader->prop, reader->prop_count, id, &charset, size )) != S_OK) goto done; - if (!charset) - { - hr = WS_E_INVALID_FORMAT; - goto done; - } - *(WS_CHARSET *)buf = charset; - hr = S_OK; - } + if (id == WS_XML_READER_PROPERTY_CHARSET) hr = get_charset( reader, buf, size ); else hr = prop_get( reader->prop, reader->prop_count, id, buf, size ); -done: LeaveCriticalSection( &reader->cs ); return hr; } @@ -5604,7 +5600,6 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING * { 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 (input->inputType != WS_XML_READER_INPUT_TYPE_BUFFER) { @@ -5613,12 +5608,8 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING * goto done; } - if (charset == WS_CHARSET_AUTO) - charset = detect_charset( buf->encodedData, buf->encodedDataSize, &offset ); - - hr = prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET, - &charset, sizeof(charset) ); - if (hr != S_OK) goto done; + if (text->charSet != WS_CHARSET_AUTO) reader->input_charset = text->charSet; + else reader->input_charset = detect_charset( buf->encodedData, buf->encodedDataSize, &offset ); reader->input_enc = WS_XML_READER_ENCODING_TYPE_TEXT; break; @@ -5626,9 +5617,10 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING * case WS_XML_READER_ENCODING_TYPE_BINARY: { WS_XML_READER_BINARY_ENCODING *bin = (WS_XML_READER_BINARY_ENCODING *)encoding; - reader->input_enc = WS_XML_READER_ENCODING_TYPE_BINARY; - reader->dict_static = bin->staticDictionary ? bin->staticDictionary : &dict_builtin_static; - reader->dict = bin->dynamicDictionary ? bin->dynamicDictionary : &dict_builtin; + reader->input_enc = WS_XML_READER_ENCODING_TYPE_BINARY; + reader->input_charset = 0; + reader->dict_static = bin->staticDictionary ? bin->staticDictionary : &dict_builtin_static; + reader->dict = bin->dynamicDictionary ? bin->dynamicDictionary : &dict_builtin; break; } default: @@ -5669,10 +5661,9 @@ HRESULT WINAPI WsSetInputToBuffer( WS_XML_READER *handle, WS_XML_BUFFER *buffer, { struct reader *reader = (struct reader *)handle; struct xmlbuf *xmlbuf = (struct xmlbuf *)buffer; - WS_CHARSET charset; struct node *node; - ULONG i, offset = 0; HRESULT hr; + ULONG i; TRACE( "%p %p %p %u %p\n", handle, buffer, properties, count, error ); if (error) FIXME( "ignoring error parameter\n" ); @@ -5696,12 +5687,10 @@ HRESULT WINAPI WsSetInputToBuffer( WS_XML_READER *handle, WS_XML_BUFFER *buffer, if ((hr = init_reader( reader )) != S_OK) goto done; - charset = detect_charset( xmlbuf->bytes.bytes, xmlbuf->bytes.length, &offset ); - 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 = xmlbuf->encoding; + reader->input_charset = xmlbuf->charset; + set_input_buffer( reader, xmlbuf, xmlbuf->bytes.bytes, xmlbuf->bytes.length ); - set_input_buffer( reader, xmlbuf, xmlbuf->bytes.bytes + offset, xmlbuf->bytes.length - offset ); if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY; else read_insert_bof( reader, node ); diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index 7dc299478d3..28bc6fb023b 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -20,9 +20,11 @@ struct xmlbuf { - WS_HEAP *heap; - WS_BYTES bytes; - SIZE_T size; + WS_HEAP *heap; + WS_BYTES bytes; + SIZE_T size; + WS_XML_WRITER_ENCODING_TYPE encoding; + WS_CHARSET charset; }; void *ws_alloc( WS_HEAP *, SIZE_T ) DECLSPEC_HIDDEN; @@ -30,7 +32,7 @@ void *ws_alloc_zero( WS_HEAP *, SIZE_T ) DECLSPEC_HIDDEN; void *ws_realloc( WS_HEAP *, void *, SIZE_T, SIZE_T ) DECLSPEC_HIDDEN; void *ws_realloc_zero( WS_HEAP *, void *, SIZE_T, SIZE_T ) DECLSPEC_HIDDEN; void ws_free( WS_HEAP *, void *, SIZE_T ) DECLSPEC_HIDDEN; -struct xmlbuf *alloc_xmlbuf( WS_HEAP * ) DECLSPEC_HIDDEN; +struct xmlbuf *alloc_xmlbuf( WS_HEAP *, WS_XML_WRITER_ENCODING_TYPE, WS_CHARSET ) DECLSPEC_HIDDEN; void free_xmlbuf( struct xmlbuf * ) DECLSPEC_HIDDEN; WS_XML_DICTIONARY dict_builtin DECLSPEC_HIDDEN; diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 4de60de2ece..2f2cd5d955e 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -80,6 +80,7 @@ struct writer struct node *current; WS_XML_STRING *current_ns; WS_XML_WRITER_ENCODING_TYPE output_enc; + WS_CHARSET output_charset; WS_XML_WRITER_OUTPUT_TYPE output_type; struct xmlbuf *output_buf; WS_HEAP *output_heap; @@ -154,18 +155,19 @@ static HRESULT init_writer( struct writer *writer ) { struct node *node; - writer->write_pos = 0; - writer->write_bufptr = NULL; + writer->write_pos = 0; + writer->write_bufptr = NULL; destroy_nodes( writer->root ); - writer->root = writer->current = NULL; + writer->root = writer->current = NULL; free_xml_string( writer->current_ns ); - writer->current_ns = NULL; + writer->current_ns = NULL; if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY; write_insert_eof( writer, node ); - writer->state = WRITER_STATE_INITIAL; - writer->output_enc = WS_XML_WRITER_ENCODING_TYPE_TEXT; - writer->dict = NULL; + writer->state = WRITER_STATE_INITIAL; + writer->output_enc = WS_XML_WRITER_ENCODING_TYPE_TEXT; + writer->output_charset = WS_CHARSET_UTF8; + writer->dict = NULL; return S_OK; } @@ -376,14 +378,16 @@ HRESULT WINAPI WsSetOutput( WS_XML_WRITER *handle, const WS_XML_WRITER_ENCODING hr = E_NOTIMPL; goto done; } - writer->output_enc = WS_XML_WRITER_ENCODING_TYPE_TEXT; + writer->output_enc = WS_XML_WRITER_ENCODING_TYPE_TEXT; + writer->output_charset = WS_CHARSET_UTF8; break; } case WS_XML_WRITER_ENCODING_TYPE_BINARY: { WS_XML_WRITER_BINARY_ENCODING *bin = (WS_XML_WRITER_BINARY_ENCODING *)encoding; - writer->output_enc = WS_XML_WRITER_ENCODING_TYPE_BINARY; - writer->dict = bin->staticDictionary; + writer->output_enc = WS_XML_WRITER_ENCODING_TYPE_BINARY; + writer->output_charset = 0; + writer->dict = bin->staticDictionary; break; } default: @@ -397,9 +401,12 @@ HRESULT WINAPI WsSetOutput( WS_XML_WRITER *handle, const WS_XML_WRITER_ENCODING case WS_XML_WRITER_OUTPUT_TYPE_BUFFER: { struct xmlbuf *xmlbuf; - - if (!(xmlbuf = alloc_xmlbuf( writer->output_heap ))) hr = WS_E_QUOTA_EXCEEDED; - else set_output_buffer( writer, xmlbuf ); + if (!(xmlbuf = alloc_xmlbuf( writer->output_heap, writer->output_enc, writer->output_charset ))) + { + hr = WS_E_QUOTA_EXCEEDED; + goto done; + } + set_output_buffer( writer, xmlbuf ); break; } default: @@ -450,6 +457,8 @@ HRESULT WINAPI WsSetOutputToBuffer( WS_XML_WRITER *handle, WS_XML_BUFFER *buffer } if ((hr = init_writer( writer )) != S_OK) goto done; + writer->output_enc = xmlbuf->encoding; + writer->output_charset = xmlbuf->charset; set_output_buffer( writer, xmlbuf ); if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY; @@ -3247,6 +3256,13 @@ HRESULT WINAPI WsWriteXmlBuffer( WS_XML_WRITER *handle, WS_XML_BUFFER *buffer, W return E_INVALIDARG; } + if (xmlbuf->encoding != writer->output_enc || xmlbuf->charset != writer->output_charset) + { + FIXME( "no support for different encoding and/or charset\n" ); + hr = E_NOTIMPL; + goto done; + } + if ((hr = write_flush( writer )) != S_OK) goto done; if ((hr = write_grow_buffer( writer, xmlbuf->bytes.length )) != S_OK) goto done; write_bytes( writer, xmlbuf->bytes.bytes, xmlbuf->bytes.length );