webservices: Implement WsWriteType for a number of basic types.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2016-01-21 15:27:59 +01:00 committed by Alexandre Julliard
parent 6086ad0fe3
commit 2563356bd6
3 changed files with 468 additions and 18 deletions

View File

@ -1,5 +1,6 @@
MODULE = webservices.dll
IMPORTLIB = webservices
IMPORTS = user32
C_SRCS = \
main.c \

View File

@ -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)

View File

@ -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.@]
*/