Module: wine Branch: master Commit: 7018ccd4bcfcd2221cbf75e78d7c500a2756ee5a URL: http://source.winehq.org/git/wine.git/?a=commit;h=7018ccd4bcfcd2221cbf75e78d...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Jul 12 15:34:30 2017 +0200
webservices: Add support for 16-bit length text records in the writer.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/webservices/reader.c | 13 ---- dlls/webservices/webservices_private.h | 13 ++++ dlls/webservices/writer.c | 121 +++++++++++++++++++++++---------- 3 files changed, 98 insertions(+), 49 deletions(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 88ad498..4aacaf7 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -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; diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index 38d5786..ddaf59e 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -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) diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 8ce59a1..5f16623 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -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; } }