From: Hans Leidekker Date: Thu, 21 Jan 2016 14:27:59 +0000 (+0100) Subject: webservices: Implement WsWriteType for a number of basic types. X-Git-Url: http://git.etersoft.ru/projects/?a=commitdiff_plain;h=2563356bd64f98bbc0f5933d40550df932e60ea3;p=wine%2Feterwine.git webservices: Implement WsWriteType for a number of basic types. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- diff --git a/dlls/webservices/Makefile.in b/dlls/webservices/Makefile.in index c3fea8526d..d48e3c6ddc 100644 --- a/dlls/webservices/Makefile.in +++ b/dlls/webservices/Makefile.in @@ -1,5 +1,6 @@ MODULE = webservices.dll IMPORTLIB = webservices +IMPORTS = user32 C_SRCS = \ main.c \ diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index fe9eb6c473..e846251470 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -185,7 +185,7 @@ @ stub WsWriteStartCData @ stdcall WsWriteStartElement(ptr ptr ptr ptr ptr) @ stdcall WsWriteText(ptr ptr ptr) -@ stub WsWriteType +@ stdcall WsWriteType(ptr long long ptr long ptr long ptr) @ stub WsWriteValue @ stdcall WsWriteXmlBuffer(ptr ptr ptr) @ stdcall WsWriteXmlBufferToBytes(ptr ptr ptr ptr long ptr ptr ptr ptr) diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 62e78be382..00fd310c90 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -20,10 +20,12 @@ #include "windef.h" #include "winbase.h" +#include "winuser.h" #include "webservices.h" #include "wine/debug.h" #include "wine/list.h" +#include "wine/unicode.h" #include "webservices_private.h" WINE_DEFAULT_DEBUG_CHANNEL(webservices); @@ -63,6 +65,7 @@ enum writer_state WRITER_STATE_STARTENDELEMENT, WRITER_STATE_STARTATTRIBUTE, WRITER_STATE_ENDSTARTELEMENT, + WRITER_STATE_TEXT, WRITER_STATE_ENDELEMENT }; @@ -571,6 +574,15 @@ static HRESULT write_endelement( struct writer *writer ) return S_OK; } +static HRESULT write_endstartelement( struct writer *writer ) +{ + HRESULT hr; + if ((hr = write_startelement( writer )) != S_OK) return hr; + if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr; + write_char( writer, '>' ); + return S_OK; +} + /************************************************************************** * WsWriteEndAttribute [webservices.@] */ @@ -588,19 +600,10 @@ HRESULT WINAPI WsWriteEndAttribute( WS_XML_WRITER *handle, WS_ERROR *error ) return S_OK; } -/************************************************************************** - * WsWriteEndElement [webservices.@] - */ -HRESULT WINAPI WsWriteEndElement( WS_XML_WRITER *handle, WS_ERROR *error ) +static HRESULT write_close_element( struct writer *writer ) { - struct writer *writer = (struct writer *)handle; HRESULT hr; - TRACE( "%p %p\n", handle, error ); - if (error) FIXME( "ignoring error parameter\n" ); - - if (!writer) return E_INVALIDARG; - if (writer->state == WRITER_STATE_STARTELEMENT) { /* '/>' */ @@ -633,6 +636,21 @@ HRESULT WINAPI WsWriteEndElement( WS_XML_WRITER *handle, WS_ERROR *error ) return WS_E_INVALID_OPERATION; } +/************************************************************************** + * WsWriteEndElement [webservices.@] + */ +HRESULT WINAPI WsWriteEndElement( WS_XML_WRITER *handle, WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + + TRACE( "%p %p\n", handle, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!writer) return E_INVALIDARG; + + return write_close_element( writer ); +} + /************************************************************************** * WsWriteEndStartElement [webservices.@] */ @@ -647,10 +665,7 @@ HRESULT WINAPI WsWriteEndStartElement( WS_XML_WRITER *handle, WS_ERROR *error ) if (!writer) return E_INVALIDARG; if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION; - if ((hr = write_startelement( writer )) != S_OK) return hr; - if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr; - write_char( writer, '>' ); - + if ((hr = write_endstartelement( writer )) != S_OK) return hr; writer->state = WRITER_STATE_ENDSTARTELEMENT; return S_OK; } @@ -745,13 +760,18 @@ error: return hr; } +static inline void write_set_attribute_value( struct writer *writer, WS_XML_TEXT *text ) +{ + WS_XML_ELEMENT_NODE *elem = &writer->current->hdr; + elem->attributes[elem->attributeCount - 1]->value = text; +} + /************************************************************************** * WsWriteText [webservices.@] */ HRESULT WINAPI WsWriteText( WS_XML_WRITER *handle, const WS_XML_TEXT *text, WS_ERROR *error ) { struct writer *writer = (struct writer *)handle; - WS_XML_ELEMENT_NODE *elem; WS_XML_UTF8_TEXT *src, *dst; TRACE( "%p %p %p\n", handle, text, error ); @@ -772,11 +792,440 @@ HRESULT WINAPI WsWriteText( WS_XML_WRITER *handle, const WS_XML_TEXT *text, WS_E if (!(dst = alloc_utf8_text( src->value.bytes, src->value.length ))) return E_OUTOFMEMORY; - elem = (WS_XML_ELEMENT_NODE *)writer->current; - elem->attributes[elem->attributeCount - 1]->value = (WS_XML_TEXT *)dst; + write_set_attribute_value( writer, &dst->text ); + return S_OK; +} + +static WS_XML_TEXT *widechar_to_xmltext( const WCHAR *src, WS_XML_TEXT_TYPE type ) +{ + switch (type) + { + case WS_XML_TEXT_TYPE_UTF8: + { + WS_XML_UTF8_TEXT *text; + int len = WideCharToMultiByte( CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL ) - 1; + if (!(text = alloc_utf8_text( NULL, len ))) return NULL; + WideCharToMultiByte( CP_UTF8, 0, src, -1, (char *)text->value.bytes, text->value.length, NULL, NULL ); + return &text->text; + } + default: + FIXME( "unhandled type %u\n", type ); + return NULL; + } +} + +static WS_XML_UTF8_TEXT *format_bool( const BOOL *ptr ) +{ + static const unsigned char bool_true[] = {'t','r','u','e'}, bool_false[] = {'f','a','l','s','e'}; + if (*ptr) return alloc_utf8_text( bool_true, sizeof(bool_true) ); + else return alloc_utf8_text( bool_false, sizeof(bool_false) ); +} + +static WS_XML_UTF8_TEXT *format_int8( const INT8 *ptr ) +{ + char buf[5]; /* "-128" */ + int len = wsprintfA( buf, "%d", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_int16( const INT16 *ptr ) +{ + char buf[7]; /* "-32768" */ + int len = wsprintfA( buf, "%d", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_int32( const INT32 *ptr ) +{ + char buf[12]; /* "-2147483648" */ + int len = wsprintfA( buf, "%d", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_int64( const INT64 *ptr ) +{ + char buf[21]; /* "-9223372036854775808" */ + int len = wsprintfA( buf, "%I64d", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_uint8( const UINT8 *ptr ) +{ + char buf[4]; /* "255" */ + int len = wsprintfA( buf, "%u", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_uint16( const UINT16 *ptr ) +{ + char buf[6]; /* "65535" */ + int len = wsprintfA( buf, "%u", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_uint32( const UINT32 *ptr ) +{ + char buf[11]; /* "4294967295" */ + int len = wsprintfA( buf, "%u", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_uint64( const UINT64 *ptr ) +{ + char buf[21]; /* "18446744073709551615" */ + int len = wsprintfA( buf, "%I64u", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static HRESULT write_add_text_node( struct writer *writer, WS_XML_TEXT *value ) +{ + struct node *node; + WS_XML_TEXT_NODE *text; + + if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return E_OUTOFMEMORY; + text = (WS_XML_TEXT_NODE *)node; + text->text = value; + + write_insert_node( writer, node ); + writer->state = WRITER_STATE_TEXT; return S_OK; } +static HRESULT write_text_node( struct writer *writer ) +{ + HRESULT hr; + WS_XML_TEXT_NODE *node = (WS_XML_TEXT_NODE *)writer->current; + WS_XML_UTF8_TEXT *text = (WS_XML_UTF8_TEXT *)node->text; + + if ((hr = write_grow_buffer( writer, text->value.length )) != S_OK) return hr; + write_bytes( writer, text->value.bytes, text->value.length ); + return S_OK; +} + +static HRESULT write_type_text( struct writer *writer, WS_TYPE_MAPPING mapping, + WS_XML_TEXT *text ) +{ + HRESULT hr; + + switch (mapping) + { + case WS_ELEMENT_TYPE_MAPPING: + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = write_endstartelement( writer )) != S_OK) return hr; + if ((hr = write_add_text_node( writer, text )) != S_OK) return hr; + return write_text_node( writer ); + + case WS_ATTRIBUTE_TYPE_MAPPING: + write_set_attribute_value( writer, text ); + return S_OK; + + case WS_ANY_ELEMENT_TYPE_MAPPING: + switch (writer->state) + { + case WRITER_STATE_STARTATTRIBUTE: + write_set_attribute_value( writer, text ); + writer->state = WRITER_STATE_STARTELEMENT; + return S_OK; + + case WRITER_STATE_STARTELEMENT: + if ((hr = write_endstartelement( writer )) != S_OK) return hr; + if ((hr = write_add_text_node( writer, text )) != S_OK) return hr; + return write_text_node( writer ); + + default: + FIXME( "writer state %u not handled\n", writer->state ); + return E_NOTIMPL; + } + + default: + FIXME( "mapping %u not implemented\n", mapping ); + return E_NOTIMPL; + } +} + +static HRESULT write_type_bool( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_BOOL_DESCRIPTION *desc, const BOOL *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_bool( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_int8( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_INT8_DESCRIPTION *desc, const INT8 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_int8( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_int16( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_INT16_DESCRIPTION *desc, const INT16 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_int16( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_int32( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_INT32_DESCRIPTION *desc, const INT32 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_int32( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_int64( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_INT64_DESCRIPTION *desc, const INT64 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_int64( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_uint8( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_UINT8_DESCRIPTION *desc, const UINT8 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_uint8( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_uint16( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_UINT16_DESCRIPTION *desc, const UINT16 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_uint16( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_uint32( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_UINT32_DESCRIPTION *desc, const UINT32 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_uint32( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_uint64( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_UINT64_DESCRIPTION *desc, const UINT64 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_uint64( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_wsz( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_WSZ_DESCRIPTION *desc, const WCHAR *value ) +{ + WS_XML_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = widechar_to_xmltext( value, WS_XML_TEXT_TYPE_UTF8 ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type( struct writer *writer, WS_TYPE_MAPPING mapping, WS_TYPE type, + const void *desc, WS_WRITE_OPTION option, const void *value, + ULONG size ) +{ + switch (type) + { + case WS_BOOL_TYPE: + { + const BOOL *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_bool( writer, mapping, desc, ptr ); + } + case WS_INT8_TYPE: + { + const INT8 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_int8( writer, mapping, desc, ptr ); + } + case WS_INT16_TYPE: + { + const INT16 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_int16( writer, mapping, desc, ptr ); + } + case WS_INT32_TYPE: + { + const INT32 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_int32( writer, mapping, desc, ptr ); + } + case WS_INT64_TYPE: + { + const INT64 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_int64( writer, mapping, desc, ptr ); + } + case WS_UINT8_TYPE: + { + const UINT8 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_uint8( writer, mapping, desc, ptr ); + } + case WS_UINT16_TYPE: + { + const UINT16 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_uint16( writer, mapping, desc, ptr ); + } + case WS_UINT32_TYPE: + { + const UINT32 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_uint32( writer, mapping, desc, ptr ); + } + case WS_UINT64_TYPE: + { + const UINT64 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_uint64( writer, mapping, desc, ptr ); + } + case WS_WSZ_TYPE: + { + const WCHAR * const *ptr = value; + if (option != WS_WRITE_REQUIRED_POINTER || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_wsz( writer, mapping, desc, *ptr ); + } + default: + FIXME( "type %u not supported\n", type ); + return E_NOTIMPL; + } +} + +/************************************************************************** + * WsWriteType [webservices.@] + */ +HRESULT WINAPI WsWriteType( WS_XML_WRITER *handle, WS_TYPE_MAPPING mapping, WS_TYPE type, + const void *desc, WS_WRITE_OPTION option, const void *value, + ULONG size, WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + HRESULT hr; + + TRACE( "%p %u %u %p %u %p %u %p\n", handle, mapping, type, desc, option, value, + size, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!writer || !value) return E_INVALIDARG; + + switch (mapping) + { + case WS_ATTRIBUTE_TYPE_MAPPING: + if (writer->state != WRITER_STATE_STARTATTRIBUTE) return WS_E_INVALID_FORMAT; + hr = write_type( writer, mapping, type, desc, option, value, size ); + break; + + case WS_ELEMENT_TYPE_MAPPING: + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_FORMAT; + hr = write_type( writer, mapping, type, desc, option, value, size ); + break; + + case WS_ANY_ELEMENT_TYPE_MAPPING: + hr = write_type( writer, mapping, type, desc, option, value, size ); + break; + + default: + FIXME( "mapping %u not implemented\n", mapping ); + return E_NOTIMPL; + } + + return hr; +} + /************************************************************************** * WsWriteXmlBuffer [webservices.@] */