[6/7] webservices: Store all text in native format in binary mode.
Hans Leidekker
hans at codeweavers.com
Mon Jul 10 04:02:33 CDT 2017
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/webservices/reader.c | 517 ++++++++++++++++++++++++---------
dlls/webservices/webservices_private.h | 24 +-
dlls/webservices/writer.c | 245 ++++++++++++++--
3 files changed, 614 insertions(+), 172 deletions(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index bf05352..5bc862e 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -787,7 +787,19 @@ WS_XML_UTF8_TEXT *alloc_utf8_text( const BYTE *data, ULONG len )
return ret;
}
-static WS_XML_BASE64_TEXT *alloc_base64_text( const BYTE *data, ULONG len )
+WS_XML_UTF16_TEXT *alloc_utf16_text( const BYTE *data, ULONG len )
+{
+ WS_XML_UTF16_TEXT *ret;
+
+ if (!(ret = heap_alloc( sizeof(*ret) + len ))) return NULL;
+ ret->text.textType = WS_XML_TEXT_TYPE_UTF16;
+ ret->byteCount = len;
+ ret->bytes = len ? (BYTE *)(ret + 1) : NULL;
+ if (data) memcpy( ret->bytes, data, len );
+ return ret;
+}
+
+WS_XML_BASE64_TEXT *alloc_base64_text( const BYTE *data, ULONG len )
{
WS_XML_BASE64_TEXT *ret;
@@ -799,6 +811,86 @@ static WS_XML_BASE64_TEXT *alloc_base64_text( const BYTE *data, ULONG len )
return ret;
}
+WS_XML_BOOL_TEXT *alloc_bool_text( BOOL value )
+{
+ WS_XML_BOOL_TEXT *ret;
+
+ if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+ ret->text.textType = WS_XML_TEXT_TYPE_BOOL;
+ ret->value = value;
+ return ret;
+}
+
+WS_XML_INT32_TEXT *alloc_int32_text( INT32 value )
+{
+ WS_XML_INT32_TEXT *ret;
+
+ if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+ ret->text.textType = WS_XML_TEXT_TYPE_INT32;
+ ret->value = value;
+ return ret;
+}
+
+WS_XML_INT64_TEXT *alloc_int64_text( INT64 value )
+{
+ WS_XML_INT64_TEXT *ret;
+
+ if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+ ret->text.textType = WS_XML_TEXT_TYPE_INT64;
+ ret->value = value;
+ return ret;
+}
+
+WS_XML_UINT64_TEXT *alloc_uint64_text( UINT64 value )
+{
+ WS_XML_UINT64_TEXT *ret;
+
+ if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+ ret->text.textType = WS_XML_TEXT_TYPE_UINT64;
+ ret->value = value;
+ return ret;
+}
+
+WS_XML_DOUBLE_TEXT *alloc_double_text( double value )
+{
+ WS_XML_DOUBLE_TEXT *ret;
+
+ if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+ ret->text.textType = WS_XML_TEXT_TYPE_DOUBLE;
+ ret->value = value;
+ return ret;
+}
+
+WS_XML_GUID_TEXT *alloc_guid_text( const GUID *value )
+{
+ WS_XML_GUID_TEXT *ret;
+
+ if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+ ret->text.textType = WS_XML_TEXT_TYPE_GUID;
+ ret->value = *value;
+ return ret;
+}
+
+WS_XML_UNIQUE_ID_TEXT *alloc_unique_id_text( const GUID *value )
+{
+ WS_XML_UNIQUE_ID_TEXT *ret;
+
+ if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+ ret->text.textType = WS_XML_TEXT_TYPE_UNIQUE_ID;
+ ret->value = *value;
+ return ret;
+}
+
+WS_XML_DATETIME_TEXT *alloc_datetime_text( const WS_DATETIME *value )
+{
+ WS_XML_DATETIME_TEXT *ret;
+
+ if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+ ret->text.textType = WS_XML_TEXT_TYPE_DATETIME;
+ ret->value = *value;
+ return ret;
+}
+
static inline BOOL read_end_of_data( struct reader *reader )
{
return reader->read_pos >= reader->read_size;
@@ -1300,24 +1392,18 @@ static HRESULT lookup_string( struct reader *reader, ULONG id, const WS_XML_STRI
static HRESULT read_attribute_value_bin( struct reader *reader, WS_XML_ATTRIBUTE *attr )
{
- static const unsigned char zero[] = {'0'}, one[] = {'1'};
- static const unsigned char false[] = {'f','a','l','s','e'}, true[] = {'t','r','u','e'};
- WS_XML_UTF8_TEXT *utf8 = NULL;
- WS_XML_BASE64_TEXT *base64;
+ WS_XML_UTF8_TEXT *text_utf8 = NULL;
+ WS_XML_BASE64_TEXT *text_base64 = NULL;
+ WS_XML_INT32_TEXT *text_int32;
+ WS_XML_INT64_TEXT *text_int64;
+ WS_XML_BOOL_TEXT *text_bool;
const WS_XML_STRING *str;
- unsigned char type, buf[46];
- BOOL val_bool;
- INT8 val_int8;
- INT16 val_int16;
- INT32 val_int32;
- INT64 val_int64;
- double val_double;
+ unsigned char type;
UINT8 val_uint8;
UINT16 val_uint16;
- UINT64 val_uint64;
- WS_DATETIME datetime;
- ULONG len, id;
- GUID uuid;
+ INT32 val_int32;
+ ULONG len = 0, id;
+ GUID guid;
HRESULT hr;
if ((hr = read_byte( reader, &type )) != S_OK) return hr;
@@ -1326,57 +1412,79 @@ static HRESULT read_attribute_value_bin( struct reader *reader, WS_XML_ATTRIBUTE
switch (type)
{
case RECORD_ZERO_TEXT:
- if (!(utf8 = alloc_utf8_text( zero, sizeof(zero) ))) return E_OUTOFMEMORY;
- break;
-
+ {
+ if (!(text_int32 = alloc_int32_text( 0 ))) return E_OUTOFMEMORY;
+ attr->value = &text_int32->text;
+ return S_OK;
+ }
case RECORD_ONE_TEXT:
- if (!(utf8 = alloc_utf8_text( one, sizeof(one) ))) return E_OUTOFMEMORY;
- break;
-
+ {
+ if (!(text_int32 = alloc_int32_text( 1 ))) return E_OUTOFMEMORY;
+ attr->value = &text_int32->text;
+ return S_OK;
+ }
case RECORD_FALSE_TEXT:
- if (!(utf8 = alloc_utf8_text( false, sizeof(false) ))) return E_OUTOFMEMORY;
- break;
-
+ {
+ if (!(text_bool = alloc_bool_text( FALSE ))) return E_OUTOFMEMORY;
+ attr->value = &text_bool->text;
+ return S_OK;
+ }
case RECORD_TRUE_TEXT:
- if (!(utf8 = alloc_utf8_text( true, sizeof(true) ))) return E_OUTOFMEMORY;
- break;
-
+ {
+ if (!(text_bool = alloc_bool_text( TRUE ))) return E_OUTOFMEMORY;
+ attr->value = &text_bool->text;
+ return S_OK;
+ }
case RECORD_INT8_TEXT:
+ {
+ INT8 val_int8;
if ((hr = read_byte( reader, (unsigned char *)&val_int8 )) != S_OK) return hr;
- len = format_int8( &val_int8, buf );
- if (!(utf8 = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
- break;
-
+ if (!(text_int64 = alloc_int64_text( val_int8 ))) return E_OUTOFMEMORY;
+ attr->value = &text_int64->text;
+ return S_OK;
+ }
case RECORD_INT16_TEXT:
+ {
+ INT16 val_int16;
if ((hr = read_bytes( reader, (unsigned char *)&val_int16, sizeof(val_int16) )) != S_OK) return hr;
- len = format_int16( &val_int16, buf );
- if (!(utf8 = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
- break;
-
+ if (!(text_int64 = alloc_int64_text( val_int16 ))) return E_OUTOFMEMORY;
+ attr->value = &text_int64->text;
+ return S_OK;
+ }
case RECORD_INT32_TEXT:
if ((hr = read_bytes( reader, (unsigned char *)&val_int32, sizeof(val_int32) )) != S_OK) return hr;
- len = format_int32( &val_int32, buf );
- if (!(utf8 = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
- break;
+ if (!(text_int64 = alloc_int64_text( val_int32 ))) return E_OUTOFMEMORY;
+ attr->value = &text_int64->text;
+ return S_OK;
case RECORD_INT64_TEXT:
+ {
+ INT64 val_int64;
if ((hr = read_bytes( reader, (unsigned char *)&val_int64, sizeof(val_int64) )) != S_OK) return hr;
- len = format_int64( &val_int64, buf );
- if (!(utf8 = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
- break;
-
+ if (!(text_int64 = alloc_int64_text( val_int64 ))) return E_OUTOFMEMORY;
+ attr->value = &text_int64->text;
+ return S_OK;
+ }
case RECORD_DOUBLE_TEXT:
- if ((hr = read_bytes( reader, (unsigned char *)&val_double, sizeof(val_double) )) != S_OK) return hr;
- len = format_double( &val_double, buf );
- if (!(utf8 = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
- break;
+ {
+ WS_XML_DOUBLE_TEXT *text_double;
+ double val_double;
+ if ((hr = read_bytes( reader, (unsigned char *)&val_double, sizeof(val_double) )) != S_OK) return hr;
+ if (!(text_double = alloc_double_text( val_double ))) return E_OUTOFMEMORY;
+ attr->value = &text_double->text;
+ return S_OK;
+ }
case RECORD_DATETIME_TEXT:
- if ((hr = read_datetime( reader, &datetime )) != S_OK) return hr;
- len = format_datetime( &datetime, buf );
- if (!(utf8 = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
- break;
+ {
+ WS_XML_DATETIME_TEXT *text_datetime;
+ WS_DATETIME datetime;
+ if ((hr = read_datetime( reader, &datetime )) != S_OK) return hr;
+ if (!(text_datetime = alloc_datetime_text( &datetime ))) return E_OUTOFMEMORY;
+ attr->value = &text_datetime->text;
+ return S_OK;
+ }
case RECORD_CHARS8_TEXT:
if ((hr = read_byte( reader, (unsigned char *)&val_uint8 )) != S_OK) return hr;
len = val_uint8;
@@ -1395,20 +1503,20 @@ static HRESULT read_attribute_value_bin( struct reader *reader, WS_XML_ATTRIBUTE
case RECORD_BYTES8_TEXT:
if ((hr = read_byte( reader, (unsigned char *)&val_uint8 )) != S_OK) return hr;
- if (!(base64 = alloc_base64_text( NULL, val_uint8 ))) return E_OUTOFMEMORY;
- if ((hr = read_bytes( reader, base64->bytes, val_uint8 )) != S_OK)
+ if (!(text_base64 = alloc_base64_text( NULL, val_uint8 ))) return E_OUTOFMEMORY;
+ if ((hr = read_bytes( reader, text_base64->bytes, val_uint8 )) != S_OK)
{
- heap_free( base64 );
+ heap_free( text_base64 );
return hr;
}
break;
case RECORD_BYTES16_TEXT:
if ((hr = read_bytes( reader, (unsigned char *)&val_uint16, sizeof(val_uint16) )) != S_OK) return hr;
- if (!(base64 = alloc_base64_text( NULL, val_uint16 ))) return E_OUTOFMEMORY;
- if ((hr = read_bytes( reader, base64->bytes, val_uint16 )) != S_OK)
+ if (!(text_base64 = alloc_base64_text( NULL, val_uint16 ))) return E_OUTOFMEMORY;
+ if ((hr = read_bytes( reader, text_base64->bytes, val_uint16 )) != S_OK)
{
- heap_free( base64 );
+ heap_free( text_base64 );
return hr;
}
break;
@@ -1416,71 +1524,87 @@ static HRESULT read_attribute_value_bin( struct reader *reader, WS_XML_ATTRIBUTE
case RECORD_BYTES32_TEXT:
if ((hr = read_bytes( reader, (unsigned char *)&val_int32, sizeof(val_int32) )) != S_OK) return hr;
if (val_int32 < 0) return WS_E_INVALID_FORMAT;
- if (!(base64 = alloc_base64_text( NULL, val_int32 ))) return E_OUTOFMEMORY;
- if ((hr = read_bytes( reader, base64->bytes, val_int32 )) != S_OK)
+ if (!(text_base64 = alloc_base64_text( NULL, val_int32 ))) return E_OUTOFMEMORY;
+ if ((hr = read_bytes( reader, text_base64->bytes, val_int32 )) != S_OK)
{
- heap_free( base64 );
+ heap_free( text_base64 );
return hr;
}
break;
case RECORD_EMPTY_TEXT:
- len = 0;
break;
case RECORD_DICTIONARY_TEXT:
if ((hr = read_int31( reader, &id )) != S_OK) return hr;
if ((hr = lookup_string( reader, id, &str )) != S_OK) return hr;
- if (!(utf8 = alloc_utf8_text( str->bytes, str->length ))) return E_OUTOFMEMORY;
+ if (!(text_utf8 = alloc_utf8_text( str->bytes, str->length ))) return E_OUTOFMEMORY;
break;
case RECORD_UNIQUEID_TEXT:
- if ((hr = read_bytes( reader, (unsigned char *)&uuid, sizeof(uuid) )) != S_OK) return hr;
- len = format_urn( &uuid, buf );
- if (!(utf8 = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
- break;
-
+ {
+ WS_XML_UNIQUE_ID_TEXT *text_unique_id;
+ if ((hr = read_bytes( reader, (unsigned char *)&guid, sizeof(guid) )) != S_OK) return hr;
+ if (!(text_unique_id = alloc_unique_id_text( &guid ))) return E_OUTOFMEMORY;
+ attr->value = &text_unique_id->text;
+ return S_OK;
+ }
case RECORD_UUID_TEXT:
- if ((hr = read_bytes( reader, (unsigned char *)&uuid, sizeof(uuid) )) != S_OK) return hr;
- len = format_guid( &uuid, buf );
- if (!(utf8 = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
- break;
-
+ {
+ WS_XML_GUID_TEXT *guid_text;
+ if ((hr = read_bytes( reader, (unsigned char *)&guid, sizeof(guid) )) != S_OK) return hr;
+ if (!(guid_text = alloc_guid_text( &guid ))) return E_OUTOFMEMORY;
+ attr->value = &guid_text->text;
+ return S_OK;
+ }
case RECORD_UINT64_TEXT:
- if ((hr = read_bytes( reader, (unsigned char *)&val_uint64, sizeof(val_uint64) )) != S_OK) return hr;
- len = format_uint64( &val_uint64, buf );
- if (!(utf8 = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
- break;
+ {
+ WS_XML_UINT64_TEXT *text_uint64;
+ UINT64 val_uint64;
+ if ((hr = read_bytes( reader, (unsigned char *)&val_uint64, sizeof(val_uint64) )) != S_OK) return hr;
+ if (!(text_uint64 = alloc_uint64_text( val_uint64 ))) return E_OUTOFMEMORY;
+ attr->value = &text_uint64->text;
+ return S_OK;
+ }
case RECORD_BOOL_TEXT:
- if ((hr = read_bytes( reader, (unsigned char *)&val_bool, sizeof(val_bool) )) != S_OK) return hr;
- len = format_bool( &val_bool, buf );
- if (!(utf8 = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
- break;
+ {
+ WS_XML_BOOL_TEXT *text_bool;
+ BOOL val_bool;
+ if ((hr = read_bytes( reader, (unsigned char *)&val_bool, sizeof(val_bool) )) != S_OK) return hr;
+ if (!(text_bool = alloc_bool_text( !!val_bool ))) return E_OUTOFMEMORY;
+ attr->value = &text_bool->text;
+ return S_OK;
+ }
default:
ERR( "unhandled record type %02x\n", type );
return WS_E_NOT_SUPPORTED;
}
+ if (type >= RECORD_INT8_TEXT && type <= RECORD_INT64_TEXT)
+ {
+ attr->value = &text_int64->text;
+ return S_OK;
+ }
if (type >= RECORD_BYTES8_TEXT && type <= RECORD_BYTES32_TEXT)
{
- attr->value = &base64->text;
+ attr->value = &text_base64->text;
return S_OK;
}
- if (!utf8)
+ if (!text_utf8)
{
- if (!(utf8 = alloc_utf8_text( NULL, len ))) return E_OUTOFMEMORY;
- if (!len) utf8->value.bytes = (BYTE *)(utf8 + 1); /* quirk */
- if ((hr = read_bytes( reader, utf8->value.bytes, len )) != S_OK)
+ if (!(text_utf8 = alloc_utf8_text( NULL, len ))) return E_OUTOFMEMORY;
+ if (!len) text_utf8->value.bytes = (BYTE *)(text_utf8 + 1); /* quirk */
+ if ((hr = read_bytes( reader, text_utf8->value.bytes, len )) != S_OK)
{
- heap_free( utf8 );
+ heap_free( text_utf8 );
return hr;
}
}
- attr->value = &utf8->text;
+ attr->value = &text_utf8->text;
return S_OK;
}
@@ -1975,6 +2099,142 @@ static struct node *alloc_base64_text_node( const BYTE *data, ULONG len, WS_XML_
return node;
}
+static struct node *alloc_bool_text_node( BOOL value )
+{
+ struct node *node;
+ WS_XML_BOOL_TEXT *text_bool;
+ WS_XML_TEXT_NODE *text;
+
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return NULL;
+ if (!(text_bool = alloc_bool_text( value )))
+ {
+ heap_free( node );
+ return NULL;
+ }
+ text = (WS_XML_TEXT_NODE *)node;
+ text->text = &text_bool->text;
+ return node;
+}
+
+static struct node *alloc_int32_text_node( INT32 value )
+{
+ struct node *node;
+ WS_XML_INT32_TEXT *text_int32;
+ WS_XML_TEXT_NODE *text;
+
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return NULL;
+ if (!(text_int32 = alloc_int32_text( value )))
+ {
+ heap_free( node );
+ return NULL;
+ }
+ text = (WS_XML_TEXT_NODE *)node;
+ text->text = &text_int32->text;
+ return node;
+}
+
+static struct node *alloc_int64_text_node( INT64 value )
+{
+ struct node *node;
+ WS_XML_INT64_TEXT *text_int64;
+ WS_XML_TEXT_NODE *text;
+
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return NULL;
+ if (!(text_int64 = alloc_int64_text( value )))
+ {
+ heap_free( node );
+ return NULL;
+ }
+ text = (WS_XML_TEXT_NODE *)node;
+ text->text = &text_int64->text;
+ return node;
+}
+
+static struct node *alloc_double_text_node( double value )
+{
+ struct node *node;
+ WS_XML_DOUBLE_TEXT *text_double;
+ WS_XML_TEXT_NODE *text;
+
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return NULL;
+ if (!(text_double = alloc_double_text( value )))
+ {
+ heap_free( node );
+ return NULL;
+ }
+ text = (WS_XML_TEXT_NODE *)node;
+ text->text = &text_double->text;
+ return node;
+}
+
+static struct node *alloc_datetime_text_node( const WS_DATETIME *value )
+{
+ struct node *node;
+ WS_XML_DATETIME_TEXT *text_datetime;
+ WS_XML_TEXT_NODE *text;
+
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return NULL;
+ if (!(text_datetime = alloc_datetime_text( value )))
+ {
+ heap_free( node );
+ return NULL;
+ }
+ text = (WS_XML_TEXT_NODE *)node;
+ text->text = &text_datetime->text;
+ return node;
+}
+
+static struct node *alloc_unique_id_text_node( const GUID *value )
+{
+ struct node *node;
+ WS_XML_UNIQUE_ID_TEXT *text_unique_id;
+ WS_XML_TEXT_NODE *text;
+
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return NULL;
+ if (!(text_unique_id = alloc_unique_id_text( value )))
+ {
+ heap_free( node );
+ return NULL;
+ }
+ text = (WS_XML_TEXT_NODE *)node;
+ text->text = &text_unique_id->text;
+ return node;
+}
+
+static struct node *alloc_guid_text_node( const GUID *value )
+{
+ struct node *node;
+ WS_XML_GUID_TEXT *text_guid;
+ WS_XML_TEXT_NODE *text;
+
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return NULL;
+ if (!(text_guid = alloc_guid_text( value )))
+ {
+ heap_free( node );
+ return NULL;
+ }
+ text = (WS_XML_TEXT_NODE *)node;
+ text->text = &text_guid->text;
+ return node;
+}
+
+static struct node *alloc_uint64_text_node( UINT64 value )
+{
+ struct node *node;
+ WS_XML_UINT64_TEXT *text_uint64;
+ WS_XML_TEXT_NODE *text;
+
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return NULL;
+ if (!(text_uint64 = alloc_uint64_text( value )))
+ {
+ heap_free( node );
+ return NULL;
+ }
+ text = (WS_XML_TEXT_NODE *)node;
+ text->text = &text_uint64->text;
+ return node;
+}
+
static HRESULT append_text_bytes( struct reader *reader, WS_XML_TEXT_NODE *node, ULONG len )
{
WS_XML_BASE64_TEXT *new, *old = (WS_XML_BASE64_TEXT *)node->text;
@@ -2064,22 +2324,12 @@ error:
static HRESULT read_text_bin( struct reader *reader )
{
- static const unsigned char zero[] = {'0'}, one[] = {'1'};
- static const unsigned char false[] = {'f','a','l','s','e'}, true[] = {'t','r','u','e'};
- unsigned char type, buf[46];
struct node *node = NULL, *parent;
+ unsigned char type;
WS_XML_UTF8_TEXT *utf8;
- const WS_XML_STRING *str;
- BOOL val_bool;
- INT8 val_int8;
- INT16 val_int16;
INT32 val_int32;
- INT64 val_int64;
- double val_double;
UINT8 val_uint8;
UINT16 val_uint16;
- UINT64 val_uint64;
- WS_DATETIME datetime;
ULONG len, id;
GUID uuid;
HRESULT hr;
@@ -2091,66 +2341,70 @@ static HRESULT read_text_bin( struct reader *reader )
{
case RECORD_ZERO_TEXT:
case RECORD_ZERO_TEXT_WITH_ENDELEMENT:
- if (!(node = alloc_utf8_text_node( zero, sizeof(zero), NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_int32_text_node( 0 ))) return E_OUTOFMEMORY;
break;
case RECORD_ONE_TEXT:
case RECORD_ONE_TEXT_WITH_ENDELEMENT:
- if (!(node = alloc_utf8_text_node( one, sizeof(one), NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_int32_text_node( 1 ))) return E_OUTOFMEMORY;
break;
case RECORD_FALSE_TEXT:
case RECORD_FALSE_TEXT_WITH_ENDELEMENT:
- if (!(node = alloc_utf8_text_node( false, sizeof(false), NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_bool_text_node( FALSE ))) return E_OUTOFMEMORY;
break;
case RECORD_TRUE_TEXT:
case RECORD_TRUE_TEXT_WITH_ENDELEMENT:
- if (!(node = alloc_utf8_text_node( true, sizeof(true), NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_bool_text_node( TRUE ))) return E_OUTOFMEMORY;
break;
case RECORD_INT8_TEXT:
case RECORD_INT8_TEXT_WITH_ENDELEMENT:
+ {
+ INT8 val_int8;
if ((hr = read_byte( reader, (unsigned char *)&val_int8 )) != S_OK) return hr;
- len = format_int8( &val_int8, buf );
- if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_int32_text_node( val_int8 ))) return E_OUTOFMEMORY;
break;
-
+ }
case RECORD_INT16_TEXT:
case RECORD_INT16_TEXT_WITH_ENDELEMENT:
+ {
+ INT16 val_int16;
if ((hr = read_bytes( reader, (unsigned char *)&val_int16, sizeof(val_int16) )) != S_OK) return hr;
- len = format_int16( &val_int16, buf );
- if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_int32_text_node( val_int16 ))) return E_OUTOFMEMORY;
break;
-
+ }
case RECORD_INT32_TEXT:
case RECORD_INT32_TEXT_WITH_ENDELEMENT:
if ((hr = read_bytes( reader, (unsigned char *)&val_int32, sizeof(val_int32) )) != S_OK) return hr;
- len = format_int32( &val_int32, buf );
- if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_int32_text_node( val_int32 ))) return E_OUTOFMEMORY;
break;
case RECORD_INT64_TEXT:
case RECORD_INT64_TEXT_WITH_ENDELEMENT:
+ {
+ INT64 val_int64;
if ((hr = read_bytes( reader, (unsigned char *)&val_int64, sizeof(val_int64) )) != S_OK) return hr;
- len = format_int64( &val_int64, buf );
- if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_int64_text_node( val_int64 ))) return E_OUTOFMEMORY;
break;
-
+ }
case RECORD_DOUBLE_TEXT:
case RECORD_DOUBLE_TEXT_WITH_ENDELEMENT:
+ {
+ double val_double;
if ((hr = read_bytes( reader, (unsigned char *)&val_double, sizeof(val_double) )) != S_OK) return hr;
- len = format_double( &val_double, buf );
- if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_double_text_node( val_double ))) return E_OUTOFMEMORY;
break;
-
+ }
case RECORD_DATETIME_TEXT:
case RECORD_DATETIME_TEXT_WITH_ENDELEMENT:
+ {
+ WS_DATETIME datetime;
if ((hr = read_datetime( reader, &datetime )) != S_OK) return hr;
- len = format_datetime( &datetime, buf );
- if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_datetime_text_node( &datetime ))) return E_OUTOFMEMORY;
break;
-
+ }
case RECORD_CHARS8_TEXT:
case RECORD_CHARS8_TEXT_WITH_ENDELEMENT:
if ((hr = read_byte( reader, (unsigned char *)&val_uint8 )) != S_OK) return hr;
@@ -2185,39 +2439,41 @@ static HRESULT read_text_bin( struct reader *reader )
case RECORD_DICTIONARY_TEXT:
case RECORD_DICTIONARY_TEXT_WITH_ENDELEMENT:
+ {
+ const WS_XML_STRING *str;
if ((hr = read_int31( reader, &id )) != S_OK) return hr;
if ((hr = lookup_string( reader, id, &str )) != S_OK) return hr;
if (!(node = alloc_utf8_text_node( str->bytes, str->length, NULL ))) return E_OUTOFMEMORY;
break;
-
+ }
case RECORD_UNIQUEID_TEXT:
case RECORD_UNIQUEID_TEXT_WITH_ENDELEMENT:
if ((hr = read_bytes( reader, (unsigned char *)&uuid, sizeof(uuid) )) != S_OK) return hr;
- len = format_urn( &uuid, buf );
- if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_unique_id_text_node( &uuid ))) return E_OUTOFMEMORY;
break;
case RECORD_UUID_TEXT:
case RECORD_UUID_TEXT_WITH_ENDELEMENT:
if ((hr = read_bytes( reader, (unsigned char *)&uuid, sizeof(uuid) )) != S_OK) return hr;
- len = format_guid( &uuid, buf );
- if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_guid_text_node( &uuid ))) return E_OUTOFMEMORY;
break;
case RECORD_UINT64_TEXT:
case RECORD_UINT64_TEXT_WITH_ENDELEMENT:
+ {
+ UINT64 val_uint64;
if ((hr = read_bytes( reader, (unsigned char *)&val_uint64, sizeof(val_uint64) )) != S_OK) return hr;
- len = format_uint64( &val_uint64, buf );
- if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_uint64_text_node( val_uint64 ))) return E_OUTOFMEMORY;
break;
-
+ }
case RECORD_BOOL_TEXT:
case RECORD_BOOL_TEXT_WITH_ENDELEMENT:
+ {
+ BOOL val_bool;
if ((hr = read_bytes( reader, (unsigned char *)&val_bool, sizeof(val_bool) )) != S_OK) return hr;
- len = format_bool( &val_bool, buf );
- if (!(node = alloc_utf8_text_node( buf, len, NULL ))) return E_OUTOFMEMORY;
+ if (!(node = alloc_bool_text_node( !!val_bool ))) return E_OUTOFMEMORY;
break;
-
+ }
default:
ERR( "unhandled record type %02x\n", type );
return WS_E_NOT_SUPPORTED;
@@ -2226,6 +2482,7 @@ static HRESULT read_text_bin( struct reader *reader )
if (!node)
{
if (!(node = alloc_utf8_text_node( NULL, len, &utf8 ))) return E_OUTOFMEMORY;
+ if (!len) utf8->value.bytes = (BYTE *)(utf8 + 1); /* quirk */
if ((hr = read_bytes( reader, utf8->value.bytes, len )) != S_OK)
{
free_node( node );
diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h
index 68837db..38d5786 100644
--- a/dlls/webservices/webservices_private.h
+++ b/dlls/webservices/webservices_private.h
@@ -44,23 +44,11 @@ struct dictionary
struct dictionary dict_builtin DECLSPEC_HIDDEN;
const struct dictionary dict_builtin_static DECLSPEC_HIDDEN;
-ULONG format_bool( const BOOL *, unsigned char * ) DECLSPEC_HIDDEN;
-ULONG format_int8( const INT8 *, unsigned char * ) DECLSPEC_HIDDEN;
-ULONG format_int16( const INT16 *, unsigned char * ) DECLSPEC_HIDDEN;
-ULONG format_int32( const INT32 *, unsigned char * ) DECLSPEC_HIDDEN;
-ULONG format_int64( const INT64 *, unsigned char * ) DECLSPEC_HIDDEN;
-ULONG format_uint64( const UINT64 *, unsigned char * ) DECLSPEC_HIDDEN;
-ULONG format_double( const double *, unsigned char * ) DECLSPEC_HIDDEN;
-ULONG format_datetime( const WS_DATETIME *, unsigned char * ) DECLSPEC_HIDDEN;
-ULONG format_guid( const GUID *, unsigned char * ) DECLSPEC_HIDDEN;
-ULONG format_urn( const GUID *, unsigned char * ) DECLSPEC_HIDDEN;
-
const char *debugstr_xmlstr( const WS_XML_STRING * ) DECLSPEC_HIDDEN;
WS_XML_STRING *alloc_xml_string( const unsigned char *, ULONG ) DECLSPEC_HIDDEN;
WS_XML_STRING *dup_xml_string( const WS_XML_STRING * ) DECLSPEC_HIDDEN;
HRESULT add_xml_string( WS_XML_STRING * ) DECLSPEC_HIDDEN;
void free_xml_string( WS_XML_STRING * ) DECLSPEC_HIDDEN;
-WS_XML_UTF8_TEXT *alloc_utf8_text( const unsigned char *, ULONG ) DECLSPEC_HIDDEN;
HRESULT append_attribute( WS_XML_ELEMENT_NODE *, WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN;
void free_attribute( WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN;
WS_TYPE map_value_type( WS_VALUE_TYPE ) DECLSPEC_HIDDEN;
@@ -71,6 +59,18 @@ ULONG get_type_size( WS_TYPE, const void * ) DECLSPEC_HIDDEN;
HRESULT read_header( WS_XML_READER *, const WS_XML_STRING *, const WS_XML_STRING *, WS_TYPE,
const void *, WS_READ_OPTION, WS_HEAP *, void *, ULONG ) DECLSPEC_HIDDEN;
+WS_XML_UTF8_TEXT *alloc_utf8_text( const BYTE *, ULONG ) DECLSPEC_HIDDEN;
+WS_XML_UTF16_TEXT *alloc_utf16_text( const BYTE *, ULONG ) DECLSPEC_HIDDEN;
+WS_XML_BASE64_TEXT *alloc_base64_text( const BYTE *, ULONG ) DECLSPEC_HIDDEN;
+WS_XML_BOOL_TEXT *alloc_bool_text( BOOL ) DECLSPEC_HIDDEN;
+WS_XML_INT32_TEXT *alloc_int32_text( INT32 ) DECLSPEC_HIDDEN;
+WS_XML_INT64_TEXT *alloc_int64_text( INT64 ) DECLSPEC_HIDDEN;
+WS_XML_UINT64_TEXT *alloc_uint64_text( UINT64 ) DECLSPEC_HIDDEN;
+WS_XML_DOUBLE_TEXT *alloc_double_text( double ) DECLSPEC_HIDDEN;
+WS_XML_GUID_TEXT *alloc_guid_text( const GUID * ) DECLSPEC_HIDDEN;
+WS_XML_UNIQUE_ID_TEXT *alloc_unique_id_text( const GUID * ) DECLSPEC_HIDDEN;
+WS_XML_DATETIME_TEXT *alloc_datetime_text( const WS_DATETIME * ) DECLSPEC_HIDDEN;
+
#define INVALID_PARAMETER_INDEX 0xffff
HRESULT get_param_desc( const WS_STRUCT_DESCRIPTION *, USHORT, const WS_FIELD_DESCRIPTION ** ) DECLSPEC_HIDDEN;
HRESULT write_input_params( WS_XML_WRITER *, const WS_ELEMENT_DESCRIPTION *,
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index b4793f9..8ce59a1 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -1609,7 +1609,7 @@ HRESULT WINAPI WsWriteStartElement( WS_XML_WRITER *handle, const WS_XML_STRING *
return hr;
}
-ULONG format_bool( const BOOL *ptr, unsigned char *buf )
+static ULONG format_bool( const BOOL *ptr, unsigned char *buf )
{
static const unsigned char bool_true[] = {'t','r','u','e'}, bool_false[] = {'f','a','l','s','e'};
if (*ptr)
@@ -1621,22 +1621,22 @@ ULONG format_bool( const BOOL *ptr, unsigned char *buf )
return sizeof(bool_false);
}
-ULONG format_int8( const INT8 *ptr, unsigned char *buf )
+static ULONG format_int8( const INT8 *ptr, unsigned char *buf )
{
return wsprintfA( (char *)buf, "%d", *ptr );
}
-ULONG format_int16( const INT16 *ptr, unsigned char *buf )
+static ULONG format_int16( const INT16 *ptr, unsigned char *buf )
{
return wsprintfA( (char *)buf, "%d", *ptr );
}
-ULONG format_int32( const INT32 *ptr, unsigned char *buf )
+static ULONG format_int32( const INT32 *ptr, unsigned char *buf )
{
return wsprintfA( (char *)buf, "%d", *ptr );
}
-ULONG format_int64( const INT64 *ptr, unsigned char *buf )
+static ULONG format_int64( const INT64 *ptr, unsigned char *buf )
{
return wsprintfA( (char *)buf, "%I64d", *ptr );
}
@@ -1656,12 +1656,12 @@ static ULONG format_uint32( const UINT32 *ptr, unsigned char *buf )
return wsprintfA( (char *)buf, "%u", *ptr );
}
-ULONG format_uint64( const UINT64 *ptr, unsigned char *buf )
+static ULONG format_uint64( const UINT64 *ptr, unsigned char *buf )
{
return wsprintfA( (char *)buf, "%I64u", *ptr );
}
-ULONG format_double( const double *ptr, unsigned char *buf )
+static ULONG format_double( const double *ptr, unsigned char *buf )
{
#ifdef HAVE_POWL
static const long double precision = 0.0000000000000001;
@@ -1758,7 +1758,7 @@ static inline int year_size( int year )
}
#define TZ_OFFSET 8
-ULONG format_datetime( const WS_DATETIME *ptr, unsigned char *buf )
+static ULONG format_datetime( const WS_DATETIME *ptr, unsigned char *buf )
{
static const char fmt[] = "%04u-%02u-%02uT%02u:%02u:%02u";
int day, hour, min, sec, sec_frac, month = 0, year = 1, tz_hour;
@@ -1814,7 +1814,7 @@ ULONG format_datetime( const WS_DATETIME *ptr, unsigned char *buf )
return len;
}
-ULONG format_guid( const GUID *ptr, unsigned char *buf )
+static ULONG format_guid( const GUID *ptr, unsigned char *buf )
{
static const char fmt[] = "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
return sprintf( (char *)buf, fmt, ptr->Data1, ptr->Data2, ptr->Data3,
@@ -1822,7 +1822,7 @@ ULONG format_guid( const GUID *ptr, unsigned char *buf )
ptr->Data4[4], ptr->Data4[5], ptr->Data4[6], ptr->Data4[7] );
}
-ULONG format_urn( const GUID *ptr, unsigned char *buf )
+static ULONG format_urn( const GUID *ptr, unsigned char *buf )
{
static const char fmt[] = "urn:uuid:%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
return sprintf( (char *)buf, fmt, ptr->Data1, ptr->Data2, ptr->Data3,
@@ -1875,9 +1875,11 @@ static ULONG encode_base64( const unsigned char *bin, ULONG len, unsigned char *
return i;
}
-static HRESULT text_to_utf8text( const WS_XML_TEXT *text, const WS_XML_UTF8_TEXT *old, WS_XML_UTF8_TEXT **ret )
+static HRESULT text_to_utf8text( const WS_XML_TEXT *text, const WS_XML_UTF8_TEXT *old, ULONG *offset,
+ WS_XML_UTF8_TEXT **ret )
{
ULONG len_old = old ? old->value.length : 0;
+ if (offset) *offset = len_old;
switch (text->textType)
{
@@ -2016,10 +2018,136 @@ static HRESULT text_to_utf8text( const WS_XML_TEXT *text, const WS_XML_UTF8_TEXT
}
}
+static HRESULT text_to_text( const WS_XML_TEXT *text, const WS_XML_TEXT *old, ULONG *offset, WS_XML_TEXT **ret )
+{
+ if (offset) *offset = 0;
+ switch (text->textType)
+ {
+ case WS_XML_TEXT_TYPE_UTF8:
+ {
+ const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text;
+ const WS_XML_UTF8_TEXT *utf8_old = (const WS_XML_UTF8_TEXT *)old;
+ WS_XML_UTF8_TEXT *new;
+ ULONG len = utf8->value.length, len_old = utf8_old ? utf8_old->value.length : 0;
+
+ if (!(new = alloc_utf8_text( NULL, len_old + len ))) return E_OUTOFMEMORY;
+ if (utf8_old) memcpy( new->value.bytes, utf8_old->value.bytes, len_old );
+ memcpy( new->value.bytes + len_old, utf8->value.bytes, len );
+ if (offset) *offset = len_old;
+ *ret = &new->text;
+ return S_OK;
+ }
+ case WS_XML_TEXT_TYPE_UTF16:
+ {
+ const WS_XML_UTF16_TEXT *utf16 = (const WS_XML_UTF16_TEXT *)text;
+ const WS_XML_UTF16_TEXT *utf16_old = (const WS_XML_UTF16_TEXT *)old;
+ WS_XML_UTF16_TEXT *new;
+ ULONG len = utf16->byteCount / sizeof(WCHAR);
+ ULONG len_old = utf16_old ? utf16_old->byteCount / sizeof(WCHAR) : 0;
+
+ if (len % sizeof(WCHAR)) return E_INVALIDARG;
+ if (!(new = alloc_utf16_text( NULL, len_old + len ))) return E_OUTOFMEMORY;
+ if (old) memcpy( new->bytes, utf16_old->bytes, len_old );
+ memcpy( new->bytes + len_old, utf16->bytes, len );
+ if (offset) *offset = len_old;
+ *ret = &new->text;
+ return S_OK;
+ }
+ case WS_XML_TEXT_TYPE_BASE64:
+ {
+ const WS_XML_BASE64_TEXT *base64 = (const WS_XML_BASE64_TEXT *)text;
+ const WS_XML_BASE64_TEXT *base64_old = (const WS_XML_BASE64_TEXT *)old;
+ WS_XML_BASE64_TEXT *new;
+ ULONG len = base64->length, len_old = base64_old ? base64_old->length : 0;
+
+ if (!(new = alloc_base64_text( NULL, len_old + len ))) return E_OUTOFMEMORY;
+ if (base64_old) memcpy( new->bytes, base64_old->bytes, len_old );
+ memcpy( new->bytes + len_old, base64->bytes, len );
+ if (offset) *offset = len_old;
+ *ret = &new->text;
+ return S_OK;
+ }
+ case WS_XML_TEXT_TYPE_BOOL:
+ {
+ const WS_XML_BOOL_TEXT *bool_text = (const WS_XML_BOOL_TEXT *)text;
+ WS_XML_BOOL_TEXT *new;
+
+ if (!(new = alloc_bool_text( bool_text->value ))) return E_OUTOFMEMORY;
+ *ret = &new->text;
+ return S_OK;
+ }
+ case WS_XML_TEXT_TYPE_INT32:
+ {
+ const WS_XML_INT32_TEXT *int32_text = (const WS_XML_INT32_TEXT *)text;
+ WS_XML_INT32_TEXT *new;
+
+ if (!(new = alloc_int32_text( int32_text->value ))) return E_OUTOFMEMORY;
+ *ret = &new->text;
+ return S_OK;
+ }
+ case WS_XML_TEXT_TYPE_INT64:
+ {
+ const WS_XML_INT64_TEXT *int64_text = (const WS_XML_INT64_TEXT *)text;
+ WS_XML_INT64_TEXT *new;
+
+ if (!(new = alloc_int64_text( int64_text->value ))) return E_OUTOFMEMORY;
+ *ret = &new->text;
+ return S_OK;
+ }
+ case WS_XML_TEXT_TYPE_UINT64:
+ {
+ const WS_XML_UINT64_TEXT *uint64_text = (const WS_XML_UINT64_TEXT *)text;
+ WS_XML_UINT64_TEXT *new;
+
+ if (!(new = alloc_uint64_text( uint64_text->value ))) return E_OUTOFMEMORY;
+ *ret = &new->text;
+ return S_OK;
+ }
+ case WS_XML_TEXT_TYPE_DOUBLE:
+ {
+ const WS_XML_DOUBLE_TEXT *double_text = (const WS_XML_DOUBLE_TEXT *)text;
+ WS_XML_DOUBLE_TEXT *new;
+
+ if (!(new = alloc_double_text( double_text->value ))) return E_OUTOFMEMORY;
+ *ret = &new->text;
+ return S_OK;
+ }
+ case WS_XML_TEXT_TYPE_GUID:
+ {
+ const WS_XML_GUID_TEXT *id = (const WS_XML_GUID_TEXT *)text;
+ WS_XML_GUID_TEXT *new;
+
+ if (!(new = alloc_guid_text( &id->value ))) return E_OUTOFMEMORY;
+ *ret = &new->text;
+ return S_OK;
+ }
+ case WS_XML_TEXT_TYPE_UNIQUE_ID:
+ {
+ const WS_XML_UNIQUE_ID_TEXT *id = (const WS_XML_UNIQUE_ID_TEXT *)text;
+ WS_XML_UNIQUE_ID_TEXT *new;
+
+ if (!(new = alloc_unique_id_text( &id->value ))) return E_OUTOFMEMORY;
+ *ret = &new->text;
+ return S_OK;
+ }
+ case WS_XML_TEXT_TYPE_DATETIME:
+ {
+ const WS_XML_DATETIME_TEXT *dt = (const WS_XML_DATETIME_TEXT *)text;
+ WS_XML_DATETIME_TEXT *new;
+
+ if (!(new = alloc_datetime_text( &dt->value ))) return E_OUTOFMEMORY;
+ *ret = &new->text;
+ return S_OK;
+ }
+ default:
+ FIXME( "unhandled text type %u\n", text->textType );
+ return E_NOTIMPL;
+ }
+}
+
static HRESULT write_set_attribute_value( struct writer *writer, const WS_XML_TEXT *value )
{
WS_XML_ELEMENT_NODE *elem = &writer->current->hdr;
- WS_XML_UTF8_TEXT *new, *old = (WS_XML_UTF8_TEXT *)elem->attributes[elem->attributeCount - 1]->value;
HRESULT hr;
switch (value->textType)
@@ -2037,7 +2165,7 @@ static HRESULT write_set_attribute_value( struct writer *writer, const WS_XML_TE
case WS_XML_TEXT_TYPE_GUID:
case WS_XML_TEXT_TYPE_UNIQUE_ID:
case WS_XML_TEXT_TYPE_DATETIME:
- if (old) return WS_E_INVALID_OPERATION;
+ if (elem->attributes[elem->attributeCount - 1]->value) return WS_E_INVALID_OPERATION;
break;
default:
@@ -2045,10 +2173,28 @@ static HRESULT write_set_attribute_value( struct writer *writer, const WS_XML_TE
return E_NOTIMPL;
}
- if ((hr = text_to_utf8text( value, old, &new )) != S_OK) return hr;
-
- heap_free( old );
- elem->attributes[elem->attributeCount - 1]->value = &new->text;
+ switch (writer->output_enc)
+ {
+ case WS_XML_WRITER_ENCODING_TYPE_TEXT:
+ {
+ WS_XML_UTF8_TEXT *new, *old = (WS_XML_UTF8_TEXT *)elem->attributes[elem->attributeCount - 1]->value;
+ if ((hr = text_to_utf8text( value, old, NULL, &new )) != S_OK) return hr;
+ heap_free( old );
+ elem->attributes[elem->attributeCount - 1]->value = &new->text;
+ break;
+ }
+ case WS_XML_WRITER_ENCODING_TYPE_BINARY:
+ {
+ WS_XML_TEXT *new, *old = elem->attributes[elem->attributeCount - 1]->value;
+ if ((hr = text_to_text( value, old, NULL, &new )) != S_OK) return hr;
+ heap_free( old );
+ elem->attributes[elem->attributeCount - 1]->value = new;
+ break;
+ }
+ default:
+ FIXME( "unhandled output encoding %u\n", writer->output_enc );
+ return E_NOTIMPL;
+ }
return S_OK;
}
@@ -2057,7 +2203,6 @@ static HRESULT write_add_text_node( struct writer *writer, const WS_XML_TEXT *va
{
struct node *node;
WS_XML_TEXT_NODE *text;
- WS_XML_UTF8_TEXT *utf8;
HRESULT hr;
if (node_type( writer->current ) != WS_XML_NODE_TYPE_ELEMENT &&
@@ -2065,13 +2210,37 @@ static HRESULT write_add_text_node( struct writer *writer, const WS_XML_TEXT *va
node_type( writer->current ) != WS_XML_NODE_TYPE_CDATA) return WS_E_INVALID_FORMAT;
if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return E_OUTOFMEMORY;
- if ((hr = text_to_utf8text( value, NULL, &utf8 )) != S_OK)
+ text = (WS_XML_TEXT_NODE *)node;
+
+ switch (writer->output_enc)
{
+ case WS_XML_WRITER_ENCODING_TYPE_TEXT:
+ {
+ WS_XML_UTF8_TEXT *new;
+ if ((hr = text_to_utf8text( value, NULL, NULL, &new )) != S_OK)
+ {
+ heap_free( node );
+ return hr;
+ }
+ text->text = &new->text;
+ break;
+ }
+ case WS_XML_WRITER_ENCODING_TYPE_BINARY:
+ {
+ WS_XML_TEXT *new;
+ if ((hr = text_to_text( value, NULL, NULL, &new )) != S_OK)
+ {
+ heap_free( node );
+ return hr;
+ }
+ text->text = new;
+ break;
+ }
+ default:
+ FIXME( "unhandled output encoding %u\n", writer->output_enc );
heap_free( node );
- return hr;
+ return E_NOTIMPL;
}
- text = (WS_XML_TEXT_NODE *)node;
- text->text = &utf8->text;
write_insert_node( writer, writer->current, node );
return S_OK;
@@ -2146,24 +2315,40 @@ static HRESULT write_text( struct writer *writer, const WS_XML_TEXT *text, ULONG
static HRESULT write_text_node( struct writer *writer, const WS_XML_TEXT *text )
{
WS_XML_TEXT_NODE *node = (WS_XML_TEXT_NODE *)writer->current;
- ULONG offset;
+ ULONG offset = 0;
HRESULT hr;
if ((hr = write_flush( writer )) != S_OK) return hr;
if (node_type( writer->current ) != WS_XML_NODE_TYPE_TEXT)
{
- offset = 0;
if ((hr = write_add_text_node( writer, text )) != S_OK) return hr;
node = (WS_XML_TEXT_NODE *)writer->current;
}
else
{
- WS_XML_UTF8_TEXT *new, *old = (WS_XML_UTF8_TEXT *)node->text;
-
- offset = old->value.length;
- if ((hr = text_to_utf8text( text, old, &new )) != S_OK) return hr;
- heap_free( old );
- node->text = &new->text;
+ switch (writer->output_enc)
+ {
+ case WS_XML_WRITER_ENCODING_TYPE_TEXT:
+ {
+ WS_XML_UTF8_TEXT *new, *old = (WS_XML_UTF8_TEXT *)node->text;
+ offset = old->value.length;
+ if ((hr = text_to_utf8text( text, old, &offset, &new )) != S_OK) return hr;
+ heap_free( old );
+ node->text = &new->text;
+ break;
+ }
+ case WS_XML_WRITER_ENCODING_TYPE_BINARY:
+ {
+ WS_XML_TEXT *new, *old = node->text;
+ if ((hr = text_to_text( text, old, &offset, &new )) != S_OK) return hr;
+ heap_free( old );
+ node->text = new;
+ break;
+ }
+ default:
+ FIXME( "unhandled output encoding %u\n", writer->output_enc );
+ return E_NOTIMPL;
+ }
}
if ((hr = write_text( writer, node->text, offset )) != S_OK) return hr;
--
2.1.4
More information about the wine-patches
mailing list