webservices: Add support for reading GUID values.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
acf64c4e68
commit
dbbcd290fd
|
@ -2108,6 +2108,52 @@ done:
|
|||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT str_to_guid( const unsigned char *str, ULONG len, GUID *ret )
|
||||
{
|
||||
static const unsigned char hex[] =
|
||||
{
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x00 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x10 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x20 */
|
||||
0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, /* 0x30 */
|
||||
0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0, /* 0x40 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x50 */
|
||||
0,10,11,12,13,14,15 /* 0x60 */
|
||||
};
|
||||
const unsigned char *p = str;
|
||||
ULONG i;
|
||||
|
||||
while (len && read_isspace( *p )) { p++; len--; }
|
||||
while (len && read_isspace( p[len - 1] )) { len--; }
|
||||
if (len != 36) return WS_E_INVALID_FORMAT;
|
||||
|
||||
if (p[8] != '-' || p[13] != '-' || p[18] != '-' || p[23] != '-')
|
||||
return WS_E_INVALID_FORMAT;
|
||||
|
||||
for (i = 0; i < 36; i++)
|
||||
{
|
||||
if (i == 8 || i == 13 || i == 18 || i == 23) continue;
|
||||
if (p[i] > 'f' || (!hex[p[i]] && p[i] != '0')) return WS_E_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
ret->Data1 = hex[p[0]] << 28 | hex[p[1]] << 24 | hex[p[2]] << 20 | hex[p[3]] << 16 |
|
||||
hex[p[4]] << 12 | hex[p[5]] << 8 | hex[p[6]] << 4 | hex[p[7]];
|
||||
|
||||
ret->Data2 = hex[p[9]] << 12 | hex[p[10]] << 8 | hex[p[11]] << 4 | hex[p[12]];
|
||||
ret->Data3 = hex[p[14]] << 12 | hex[p[15]] << 8 | hex[p[16]] << 4 | hex[p[17]];
|
||||
|
||||
ret->Data4[0] = hex[p[19]] << 4 | hex[p[20]];
|
||||
ret->Data4[1] = hex[p[21]] << 4 | hex[p[22]];
|
||||
ret->Data4[2] = hex[p[24]] << 4 | hex[p[25]];
|
||||
ret->Data4[3] = hex[p[26]] << 4 | hex[p[27]];
|
||||
ret->Data4[4] = hex[p[28]] << 4 | hex[p[29]];
|
||||
ret->Data4[5] = hex[p[30]] << 4 | hex[p[31]];
|
||||
ret->Data4[6] = hex[p[32]] << 4 | hex[p[33]];
|
||||
ret->Data4[7] = hex[p[34]] << 4 | hex[p[35]];
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#define TICKS_PER_SEC 10000000
|
||||
#define TICKS_PER_MIN (60 * (ULONGLONG)TICKS_PER_SEC)
|
||||
#define TICKS_PER_HOUR (3600 * (ULONGLONG)TICKS_PER_SEC)
|
||||
|
@ -3074,6 +3120,53 @@ static HRESULT read_type_datetime( struct reader *reader, WS_TYPE_MAPPING mappin
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT read_type_guid( struct reader *reader, WS_TYPE_MAPPING mapping,
|
||||
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
|
||||
const WS_GUID_DESCRIPTION *desc, WS_READ_OPTION option,
|
||||
WS_HEAP *heap, void *ret, ULONG size )
|
||||
{
|
||||
WS_XML_UTF8_TEXT *utf8;
|
||||
GUID val;
|
||||
HRESULT hr;
|
||||
BOOL found;
|
||||
|
||||
if (desc) FIXME( "ignoring description\n" );
|
||||
|
||||
if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
|
||||
if (found && (hr = str_to_guid( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr;
|
||||
|
||||
switch (option)
|
||||
{
|
||||
case WS_READ_REQUIRED_VALUE:
|
||||
if (!found) return WS_E_INVALID_FORMAT;
|
||||
if (size != sizeof(GUID)) return E_INVALIDARG;
|
||||
*(GUID *)ret = val;
|
||||
break;
|
||||
|
||||
case WS_READ_REQUIRED_POINTER:
|
||||
if (!found) return WS_E_INVALID_FORMAT;
|
||||
/* fall through */
|
||||
|
||||
case WS_READ_OPTIONAL_POINTER:
|
||||
{
|
||||
GUID *heap_val = NULL;
|
||||
if (size != sizeof(heap_val)) return E_INVALIDARG;
|
||||
if (found)
|
||||
{
|
||||
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
|
||||
*heap_val = val;
|
||||
}
|
||||
*(GUID **)ret = heap_val;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME( "read option %u not supported\n", option );
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static BOOL is_empty_text_node( const struct node *node )
|
||||
{
|
||||
const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)node;
|
||||
|
@ -3182,6 +3275,9 @@ static ULONG get_type_size( WS_TYPE type, const WS_STRUCT_DESCRIPTION *desc )
|
|||
case WS_DATETIME_TYPE:
|
||||
return sizeof(WS_DATETIME);
|
||||
|
||||
case WS_GUID_TYPE:
|
||||
return sizeof(GUID);
|
||||
|
||||
case WS_WSZ_TYPE:
|
||||
return sizeof(WCHAR *);
|
||||
|
||||
|
@ -3211,6 +3307,7 @@ static WS_READ_OPTION get_array_read_option( WS_TYPE type )
|
|||
case WS_ENUM_TYPE:
|
||||
case WS_STRUCT_TYPE:
|
||||
case WS_DATETIME_TYPE:
|
||||
case WS_GUID_TYPE:
|
||||
return WS_READ_REQUIRED_VALUE;
|
||||
|
||||
case WS_WSZ_TYPE:
|
||||
|
@ -3315,6 +3412,7 @@ static WS_READ_OPTION get_field_read_option( WS_TYPE type )
|
|||
case WS_DOUBLE_TYPE:
|
||||
case WS_ENUM_TYPE:
|
||||
case WS_DATETIME_TYPE:
|
||||
case WS_GUID_TYPE:
|
||||
return WS_READ_REQUIRED_VALUE;
|
||||
|
||||
case WS_WSZ_TYPE:
|
||||
|
@ -3564,6 +3662,11 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP
|
|||
return hr;
|
||||
break;
|
||||
|
||||
case WS_GUID_TYPE:
|
||||
if ((hr = read_type_guid( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
|
||||
return hr;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME( "type %u not supported\n", type );
|
||||
return E_NOTIMPL;
|
||||
|
|
|
@ -1321,6 +1321,8 @@ static void prepare_type_test( WS_XML_READER *reader, const char *data, ULONG si
|
|||
static void test_WsReadType(void)
|
||||
{
|
||||
static const WCHAR testW[] = {'t','e','s','t',0};
|
||||
static const GUID guid1 = {0,0,0,{0,0,0,0,0,0,0,0}};
|
||||
static const GUID guid2 = {0,0,0,{0,0,0,0,0,0,0,0xa1}};
|
||||
HRESULT hr;
|
||||
WS_XML_READER *reader;
|
||||
WS_HEAP *heap;
|
||||
|
@ -1340,6 +1342,7 @@ static void test_WsReadType(void)
|
|||
UINT16 val_uint16;
|
||||
UINT32 val_uint32;
|
||||
UINT64 val_uint64;
|
||||
GUID val_guid;
|
||||
|
||||
hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
@ -1579,6 +1582,36 @@ static void test_WsReadType(void)
|
|||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
ok( val_enum == 1, "got %d\n", val_enum );
|
||||
|
||||
prepare_type_test( reader, "<t>{00000000-0000-0000-0000-000000000000}</t>",
|
||||
sizeof("<t>{00000000-0000-0000-0000-000000000000}</t>") - 1 );
|
||||
hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
|
||||
WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
|
||||
ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
|
||||
|
||||
memset( &val_guid, 0xff, sizeof(val_guid) );
|
||||
prepare_type_test( reader, "<t> 00000000-0000-0000-0000-000000000000 </t>",
|
||||
sizeof("<t> 00000000-0000-0000-0000-000000000000 </t>") - 1 );
|
||||
hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
|
||||
WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
ok( !memcmp( &val_guid, &guid1, sizeof(val_guid) ), "wrong guid\n" );
|
||||
|
||||
memset( &val_guid, 0, sizeof(val_guid) );
|
||||
prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000a1</t>",
|
||||
sizeof("<t>00000000-0000-0000-0000-0000000000a1</t>") - 1 );
|
||||
hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
|
||||
WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
ok( !memcmp( &val_guid, &guid2, sizeof(val_guid) ), "wrong guid\n" );
|
||||
|
||||
memset( &val_guid, 0, sizeof(val_guid) );
|
||||
prepare_type_test( reader, "<t>00000000-0000-0000-0000-0000000000A1</t>",
|
||||
sizeof("<t>00000000-0000-0000-0000-0000000000A1</t>") - 1 );
|
||||
hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_GUID_TYPE, NULL,
|
||||
WS_READ_REQUIRED_VALUE, heap, &val_guid, sizeof(val_guid), NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
ok( !memcmp( &val_guid, &guid2, sizeof(val_guid) ), "wrong guid\n" );
|
||||
|
||||
WsFreeReader( reader );
|
||||
WsFreeHeap( heap );
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ typedef struct _WS_CALL_PROPERTY WS_CALL_PROPERTY;
|
|||
typedef struct _WS_DOUBLE_DESCRIPTION WS_DOUBLE_DESCRIPTION;
|
||||
typedef struct _WS_DATETIME WS_DATETIME;
|
||||
typedef struct _WS_DATETIME_DESCRIPTION WS_DATETIME_DESCRIPTION;
|
||||
typedef struct _WS_GUID_DESCRIPTION WS_GUID_DESCRIPTION;
|
||||
typedef struct _WS_URL WS_URL;
|
||||
typedef struct _WS_HTTP_URL WS_HTTP_URL;
|
||||
typedef struct _WS_HTTPS_URL WS_HTTPS_URL;
|
||||
|
|
Loading…
Reference in New Issue