From 506e981d08788f165606013ac3c4fe229574e513 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Thu, 22 Oct 2015 11:30:13 +0200 Subject: [PATCH] webservices: Implement WsSetInputToBuffer. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- 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 870e7de392d..aeba36cc781 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 03dd569a081..3f23d90cdbf 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 4a8b88e18ee..6e0f4f26202 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)