diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index bd99b855102..9055021f1f1 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -1815,6 +1815,62 @@ static void test_WsCopyNode(void) WsFreeHeap( heap ); } +static void test_text_types(void) +{ + static const WCHAR utf16W[] = {'u','t','f','1','6'}; + WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL}; + WS_XML_WRITER *writer; + static const WS_XML_UTF8_TEXT val_utf8 = { {WS_XML_TEXT_TYPE_UTF8}, {4, (BYTE *)"utf8"} }; + static WS_XML_UTF16_TEXT val_utf16 = { {WS_XML_TEXT_TYPE_UTF16} }; + static const WS_XML_GUID_TEXT val_guid = { {WS_XML_TEXT_TYPE_GUID} }; + static const WS_XML_UNIQUE_ID_TEXT val_urn = { {WS_XML_TEXT_TYPE_UNIQUE_ID} }; + static const WS_XML_BOOL_TEXT val_bool = { {WS_XML_TEXT_TYPE_BOOL}, TRUE }; + static const WS_XML_INT32_TEXT val_int32 = { {WS_XML_TEXT_TYPE_INT32}, -2147483647 - 1 }; + static const WS_XML_INT64_TEXT val_int64 = { {WS_XML_TEXT_TYPE_INT64}, -9223372036854775807 - 1 }; + static const WS_XML_UINT64_TEXT val_uint64 = { {WS_XML_TEXT_TYPE_UINT64}, ~0 }; + static const struct + { + const WS_XML_TEXT *text; + const char *result; + } + tests[] = + { + { &val_utf8.text, "utf8" }, + { &val_utf16.text, "utf16" }, + { &val_guid.text, "00000000-0000-0000-0000-000000000000" }, + { &val_urn.text, "urn:uuid:00000000-0000-0000-0000-000000000000" }, + { &val_bool.text, "true" }, + { &val_int32.text, "-2147483648" }, + { &val_int64.text, "-9223372036854775808" }, + { &val_uint64.text, "18446744073709551615" }, + }; + HRESULT hr; + ULONG i; + + val_utf16.bytes = (BYTE *)utf16W; + val_utf16.byteCount = sizeof(utf16W); + + hr = WsCreateWriter( NULL, 0, &writer, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "%u: got %08x\n", i, hr ); + + hr = WsWriteText( writer, tests[i].text, NULL ); + ok( hr == S_OK, "%u: got %08x\n", i, hr ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "%u: got %08x\n", i, hr ); + check_output( writer, tests[i].result, __LINE__ ); + } + + WsFreeWriter( writer ); +} + START_TEST(writer) { test_WsCreateWriter(); @@ -1839,4 +1895,5 @@ START_TEST(writer) test_WsWriteXmlBuffer(); test_WsWriteNode(); test_WsCopyNode(); + test_text_types(); } diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 86789c75a10..85a89737ed0 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -17,6 +17,7 @@ */ #include +#include #include "windef.h" #include "winbase.h" @@ -989,6 +990,74 @@ HRESULT WINAPI WsWriteStartElement( WS_XML_WRITER *handle, const WS_XML_STRING * return write_element_node( writer, prefix, localname, ns ); } +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) + { + memcpy( buf, bool_true, sizeof(bool_true) ); + return sizeof(bool_true); + } + memcpy( buf, bool_false, sizeof(bool_false) ); + return sizeof(bool_false); +} + +static ULONG format_int8( const INT8 *ptr, unsigned char *buf ) +{ + return wsprintfA( (char *)buf, "%d", *ptr ); +} + +static ULONG format_int16( const INT16 *ptr, unsigned char *buf ) +{ + return wsprintfA( (char *)buf, "%d", *ptr ); +} + +static ULONG format_int32( const INT32 *ptr, unsigned char *buf ) +{ + return wsprintfA( (char *)buf, "%d", *ptr ); +} + +static ULONG format_int64( const INT64 *ptr, unsigned char *buf ) +{ + return wsprintfA( (char *)buf, "%I64d", *ptr ); +} + +static ULONG format_uint8( const UINT8 *ptr, unsigned char *buf ) +{ + return wsprintfA( (char *)buf, "%u", *ptr ); +} + +static ULONG format_uint16( const UINT16 *ptr, unsigned char *buf ) +{ + return wsprintfA( (char *)buf, "%u", *ptr ); +} + +static ULONG format_uint32( const UINT32 *ptr, unsigned char *buf ) +{ + return wsprintfA( (char *)buf, "%u", *ptr ); +} + +static ULONG format_uint64( const UINT64 *ptr, unsigned char *buf ) +{ + return wsprintfA( (char *)buf, "%I64u", *ptr ); +} + +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, + ptr->Data4[0], ptr->Data4[1], ptr->Data4[2], ptr->Data4[3], + ptr->Data4[4], ptr->Data4[5], ptr->Data4[6], ptr->Data4[7] ); +} + +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, + ptr->Data4[0], ptr->Data4[1], ptr->Data4[2], ptr->Data4[3], + ptr->Data4[4], ptr->Data4[5], ptr->Data4[6], ptr->Data4[7] ); +} + static HRESULT text_to_utf8text( const WS_XML_TEXT *text, WS_XML_UTF8_TEXT **ret ) { switch (text->textType) @@ -1011,6 +1080,51 @@ static HRESULT text_to_utf8text( const WS_XML_TEXT *text, WS_XML_UTF8_TEXT **ret WideCharToMultiByte( CP_UTF8, 0, str, len, (char *)(*ret)->value.bytes, (*ret)->value.length, NULL, NULL ); return S_OK; } + case WS_XML_TEXT_TYPE_BOOL: + { + const WS_XML_BOOL_TEXT *bool_text = (const WS_XML_BOOL_TEXT *)text; + if (!(*ret = alloc_utf8_text( NULL, 5 ))) return E_OUTOFMEMORY; + (*ret)->value.length = format_bool( &bool_text->value, (*ret)->value.bytes ); + return S_OK; + } + case WS_XML_TEXT_TYPE_INT32: + { + const WS_XML_INT32_TEXT *int32_text = (const WS_XML_INT32_TEXT *)text; + unsigned char buf[12]; /* "-2147483648" */ + ULONG len = format_int32( &int32_text->value, buf ); + if (!(*ret = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY; + return S_OK; + } + case WS_XML_TEXT_TYPE_INT64: + { + const WS_XML_INT64_TEXT *int64_text = (const WS_XML_INT64_TEXT *)text; + unsigned char buf[21]; /* "-9223372036854775808" */ + ULONG len = format_int64( &int64_text->value, buf ); + if (!(*ret = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY; + return S_OK; + } + case WS_XML_TEXT_TYPE_UINT64: + { + const WS_XML_UINT64_TEXT *uint64_text = (const WS_XML_UINT64_TEXT *)text; + unsigned char buf[21]; /* "18446744073709551615" */ + ULONG len = format_uint64( &uint64_text->value, buf ); + if (!(*ret = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY; + return S_OK; + } + case WS_XML_TEXT_TYPE_GUID: + { + const WS_XML_GUID_TEXT *id = (const WS_XML_GUID_TEXT *)text; + if (!(*ret = alloc_utf8_text( NULL, 37 ))) return E_OUTOFMEMORY; + (*ret)->value.length = format_guid( &id->value, (*ret)->value.bytes ); + return S_OK; + } + case WS_XML_TEXT_TYPE_UNIQUE_ID: + { + const WS_XML_UNIQUE_ID_TEXT *id = (const WS_XML_UNIQUE_ID_TEXT *)text; + if (!(*ret = alloc_utf8_text( NULL, 46 ))) return E_OUTOFMEMORY; + (*ret)->value.length = format_urn( &id->value, (*ret)->value.bytes ); + return S_OK; + } default: FIXME( "unhandled text type %u\n", text->textType ); return E_NOTIMPL; @@ -1088,58 +1202,6 @@ HRESULT WINAPI WsWriteText( WS_XML_WRITER *handle, const WS_XML_TEXT *text, WS_E return write_text_node( writer, text ); } -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) - { - memcpy( buf, bool_true, sizeof(bool_true) ); - return sizeof(bool_true); - } - memcpy( buf, bool_false, sizeof(bool_false) ); - return sizeof(bool_false); -} - -static ULONG format_int8( const INT8 *ptr, unsigned char *buf ) -{ - return wsprintfA( (char *)buf, "%d", *ptr ); -} - -static ULONG format_int16( const INT16 *ptr, unsigned char *buf ) -{ - return wsprintfA( (char *)buf, "%d", *ptr ); -} - -static ULONG format_int32( const INT32 *ptr, unsigned char *buf ) -{ - return wsprintfA( (char *)buf, "%d", *ptr ); -} - -static ULONG format_int64( const INT64 *ptr, unsigned char *buf ) -{ - return wsprintfA( (char *)buf, "%I64d", *ptr ); -} - -static ULONG format_uint8( const UINT8 *ptr, unsigned char *buf ) -{ - return wsprintfA( (char *)buf, "%u", *ptr ); -} - -static ULONG format_uint16( const UINT16 *ptr, unsigned char *buf ) -{ - return wsprintfA( (char *)buf, "%u", *ptr ); -} - -static ULONG format_uint32( const UINT32 *ptr, unsigned char *buf ) -{ - return wsprintfA( (char *)buf, "%u", *ptr ); -} - -static ULONG format_uint64( const UINT64 *ptr, unsigned char *buf ) -{ - return wsprintfA( (char *)buf, "%I64u", *ptr ); -} - static HRESULT write_type_text( struct writer *writer, WS_TYPE_MAPPING mapping, const WS_XML_TEXT *text ) { switch (mapping) diff --git a/include/webservices.h b/include/webservices.h index fad070be9bd..c9c2ade9093 100644 --- a/include/webservices.h +++ b/include/webservices.h @@ -557,6 +557,36 @@ typedef struct _WS_XML_UTF16_TEXT { ULONG byteCount; } WS_XML_UTF16_TEXT; +typedef struct _WS_XML_BOOL_TEXT { + WS_XML_TEXT text; + BOOL value; +} WS_XML_BOOL_TEXT; + +typedef struct _WS_XML_INT32_TEXT { + WS_XML_TEXT text; + __int32 value; +} WS_XML_INT32_TEXT; + +typedef struct _WS_XML_INT64_TEXT { + WS_XML_TEXT text; + __int64 value; +} WS_XML_INT64_TEXT; + +typedef struct _WS_XML_UINT64_TEXT { + WS_XML_TEXT text; + unsigned __int64 value; +} WS_XML_UINT64_TEXT; + +typedef struct _WS_XML_GUID_TEXT { + WS_XML_TEXT text; + GUID value; +} WS_XML_GUID_TEXT; + +typedef struct _WS_XML_UNIQUE_ID_TEXT { + WS_XML_TEXT text; + GUID value; +} WS_XML_UNIQUE_ID_TEXT; + typedef enum { WS_BOOL_VALUE_TYPE, WS_INT8_VALUE_TYPE,