Commit 7018ccd4 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

webservices: Add support for 16-bit length text records in the writer.

parent f1f510d9
......@@ -3505,19 +3505,6 @@ static HRESULT str_to_bool( const unsigned char *str, ULONG len, BOOL *ret )
return S_OK;
}
#define MAX_INT8 0x7f
#define MIN_INT8 (-MAX_INT8 - 1)
#define MAX_INT16 0x7fff
#define MIN_INT16 (-MAX_INT16 - 1)
#define MAX_INT32 0x7fffffff
#define MIN_INT32 (-MAX_INT32 - 1)
#define MAX_INT64 (((INT64)0x7fffffff << 32) | 0xffffffff)
#define MIN_INT64 (-MAX_INT64 - 1)
#define MAX_UINT8 0xff
#define MAX_UINT16 0xffff
#define MAX_UINT32 0xffffffff
#define MAX_UINT64 (((UINT64)0xffffffff << 32) | 0xffffffff)
static HRESULT str_to_int64( const unsigned char *str, ULONG len, INT64 min, INT64 max, INT64 *ret )
{
BOOL negative = FALSE;
......
......@@ -338,6 +338,19 @@ enum record_type
/* 0xbe ... 0xff reserved */
};
#define MAX_INT8 0x7f
#define MIN_INT8 (-MAX_INT8 - 1)
#define MAX_INT16 0x7fff
#define MIN_INT16 (-MAX_INT16 - 1)
#define MAX_INT32 0x7fffffff
#define MIN_INT32 (-MAX_INT32 - 1)
#define MAX_INT64 (((INT64)0x7fffffff << 32) | 0xffffffff)
#define MIN_INT64 (-MAX_INT64 - 1)
#define MAX_UINT8 0xff
#define MAX_UINT16 0xffff
#define MAX_UINT32 0xffffffff
#define MAX_UINT64 (((UINT64)0xffffffff << 32) | 0xffffffff)
#define TICKS_PER_SEC 10000000
#define TICKS_PER_MIN (60 * (ULONGLONG)TICKS_PER_SEC)
#define TICKS_PER_HOUR (3600 * (ULONGLONG)TICKS_PER_SEC)
......
......@@ -649,17 +649,27 @@ static HRESULT write_dict_string( struct writer *writer, ULONG id )
return S_OK;
}
static enum record_type get_text_record_type( const WS_XML_TEXT *text, BOOL attr )
static enum record_type get_attr_text_record_type( const WS_XML_TEXT *text )
{
const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text;
if (!utf8 || utf8->value.length <= 0xff) return attr ? RECORD_CHARS8_TEXT : RECORD_CHARS8_TEXT_WITH_ENDELEMENT;
return 0;
};
if (!text) return RECORD_CHARS8_TEXT;
switch (text->textType)
{
case WS_XML_TEXT_TYPE_UTF8:
{
const WS_XML_UTF8_TEXT *text_utf8 = (const WS_XML_UTF8_TEXT *)text;
if (text_utf8->value.length <= MAX_UINT8) return RECORD_CHARS8_TEXT;
if (text_utf8->value.length <= MAX_UINT16) return RECORD_CHARS16_TEXT;
return RECORD_CHARS32_TEXT;
}
default:
FIXME( "unhandled text type %u\n", text->textType );
return 0;
}
}
static HRESULT write_attribute_value_bin( struct writer *writer, const WS_XML_TEXT *text )
{
WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text;
enum record_type type = get_text_record_type( text, TRUE );
enum record_type type = get_attr_text_record_type( text );
HRESULT hr;
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
......@@ -668,19 +678,31 @@ static HRESULT write_attribute_value_bin( struct writer *writer, const WS_XML_TE
switch (type)
{
case RECORD_CHARS8_TEXT:
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
if (!utf8 || !utf8->value.length) write_char( writer, 0 );
else
{
WS_XML_UTF8_TEXT *text_utf8 = (WS_XML_UTF8_TEXT *)text;
if (!text_utf8)
{
write_char( writer, utf8->value.length );
if ((hr = write_grow_buffer( writer, utf8->value.length )) != S_OK) return hr;
write_bytes( writer, utf8->value.bytes, utf8->value.length );
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
write_char( writer, 0 );
return S_OK;
}
if ((hr = write_grow_buffer( writer, 1 + text_utf8->value.length )) != S_OK) return hr;
write_char( writer, text_utf8->value.length );
write_bytes( writer, text_utf8->value.bytes, text_utf8->value.length );
return S_OK;
}
case RECORD_CHARS16_TEXT:
{
WS_XML_UTF8_TEXT *text_utf8 = (WS_XML_UTF8_TEXT *)text;
UINT16 len = text_utf8->value.length;
if ((hr = write_grow_buffer( writer, sizeof(len) + len )) != S_OK) return hr;
write_bytes( writer, (const BYTE *)&len, sizeof(len) );
write_bytes( writer, text_utf8->value.bytes, len );
return S_OK;
}
default:
ERR( "unhandled record type %02x\n", type );
return WS_E_NOT_SUPPORTED;
return E_NOTIMPL;
}
}
......@@ -2040,15 +2062,16 @@ static HRESULT text_to_text( const WS_XML_TEXT *text, const WS_XML_TEXT *old, UL
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 );
const WS_XML_UTF8_TEXT *utf8_old = (const WS_XML_UTF8_TEXT *)old;
WS_XML_UTF8_TEXT *new;
const WCHAR *str = (const WCHAR *)utf16->bytes;
ULONG len = utf16->byteCount / sizeof(WCHAR), len_utf8, len_old = utf8_old ? utf8_old->value.length : 0;
if (utf16->byteCount % sizeof(WCHAR)) return E_INVALIDARG;
len_utf8 = WideCharToMultiByte( CP_UTF8, 0, str, len, NULL, 0, NULL, NULL );
if (!(new = alloc_utf8_text( NULL, len_old + len_utf8 ))) return E_OUTOFMEMORY;
if (old) memcpy( new->value.bytes, utf8_old->value.bytes, len_old );
WideCharToMultiByte( CP_UTF8, 0, str, len, (char *)new->value.bytes + len_old, len_utf8, NULL, NULL );
if (offset) *offset = len_old;
*ret = &new->text;
return S_OK;
......@@ -2266,35 +2289,61 @@ static HRESULT write_text_text( struct writer *writer, const WS_XML_TEXT *text,
return WS_E_INVALID_FORMAT;
}
static enum record_type get_text_record_type( const WS_XML_TEXT *text )
{
switch (text->textType)
{
case WS_XML_TEXT_TYPE_UTF8:
{
const WS_XML_UTF8_TEXT *text_utf8 = (const WS_XML_UTF8_TEXT *)text;
if (text_utf8->value.length <= MAX_UINT8) return RECORD_CHARS8_TEXT_WITH_ENDELEMENT;
if (text_utf8->value.length <= MAX_UINT16) return RECORD_CHARS16_TEXT_WITH_ENDELEMENT;
return RECORD_CHARS32_TEXT_WITH_ENDELEMENT;
}
default:
FIXME( "unhandled text type %u\n", text->textType );
return 0;
}
}
static HRESULT write_text_bin( struct writer *writer, const WS_XML_TEXT *text, ULONG offset )
{
const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text;
enum record_type type = get_text_record_type( text, FALSE );
enum record_type type = get_text_record_type( text );
HRESULT hr;
if (offset)
{
FIXME( "no support for appending text in binary mode\n" );
return WS_E_NOT_SUPPORTED;
return E_NOTIMPL;
}
switch (type)
{
case RECORD_CHARS8_TEXT_WITH_ENDELEMENT:
if ((hr = write_grow_buffer( writer, 2 )) != S_OK) return hr;
{
const WS_XML_UTF8_TEXT *text_utf8 = (const WS_XML_UTF8_TEXT *)text;
UINT8 len = text_utf8->value.length;
if ((hr = write_grow_buffer( writer, 1 + sizeof(len) + len )) != S_OK) return hr;
write_char( writer, type );
if (!utf8 || !utf8->value.length) write_char( writer, 0 );
else
{
write_char( writer, utf8->value.length );
if ((hr = write_grow_buffer( writer, utf8->value.length )) != S_OK) return hr;
write_bytes( writer, utf8->value.bytes, utf8->value.length );
}
write_char( writer, len );
write_bytes( writer, text_utf8->value.bytes, len );
return S_OK;
}
case RECORD_CHARS16_TEXT_WITH_ENDELEMENT:
{
const WS_XML_UTF8_TEXT *text_utf8 = (const WS_XML_UTF8_TEXT *)text;
UINT16 len = text_utf8->value.length;
if ((hr = write_grow_buffer( writer, 1 + sizeof(len) + len )) != S_OK) return hr;
write_char( writer, type );
write_bytes( writer, (const BYTE *)&len, sizeof(len) );
write_bytes( writer, text_utf8->value.bytes, len );
return S_OK;
}
default:
FIXME( "unhandled record type %02x\n", type );
return WS_E_NOT_SUPPORTED;
return E_NOTIMPL;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment