webservices: Add support for structure types in WsReadType.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2016-01-29 13:27:30 +01:00 committed by Alexandre Julliard
parent bd4361cb0f
commit 9fb780ec08
2 changed files with 722 additions and 115 deletions

View File

@ -164,6 +164,12 @@ void *ws_alloc( WS_HEAP *handle, SIZE_T size )
return HeapAlloc( heap->handle, 0, size );
}
static void *ws_alloc_zero( WS_HEAP *handle, SIZE_T size )
{
struct heap *heap = (struct heap *)handle;
return HeapAlloc( heap->handle, HEAP_ZERO_MEMORY, size );
}
void *ws_realloc( WS_HEAP *handle, void *ptr, SIZE_T size )
{
struct heap *heap = (struct heap *)handle;
@ -1463,177 +1469,679 @@ static HRESULT str_to_uint64( const unsigned char *str, ULONG len, UINT64 max, U
return S_OK;
}
/**************************************************************************
* WsReadType [webservices.@]
*/
HRESULT WINAPI WsReadType( WS_XML_READER *handle, WS_TYPE_MAPPING mapping, WS_TYPE type,
const void *desc, WS_READ_OPTION option, WS_HEAP *heap, void *value,
ULONG value_size, WS_ERROR *error )
static HRESULT read_get_node_text( struct reader *reader, WS_XML_UTF8_TEXT **ret )
{
struct reader *reader = (struct reader *)handle;
WS_XML_TEXT_NODE *text;
TRACE( "%p %u %u %p %u %p %p %u %p\n", handle, mapping, type, desc, option, heap, value,
value_size, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !value) return E_INVALIDARG;
if (reader->current->hdr.node.nodeType != WS_XML_NODE_TYPE_TEXT)
{
FIXME( "only text nodes are supported\n" );
return E_NOTIMPL;
}
return WS_E_INVALID_FORMAT;
text = (WS_XML_TEXT_NODE *)&reader->current->hdr.node;
if (text->text->textType != WS_XML_TEXT_TYPE_UTF8)
{
FIXME( "text type %u not supported\n", text->text->textType );
return E_NOTIMPL;
}
*ret = (WS_XML_UTF8_TEXT *)text->text;
return S_OK;
}
static HRESULT read_get_attribute_text( struct reader *reader, WS_XML_UTF8_TEXT **ret )
{
WS_XML_ELEMENT_NODE *elem = &reader->current->hdr;
WS_XML_ATTRIBUTE *attr;
if (reader->current->hdr.node.nodeType != WS_XML_NODE_TYPE_ELEMENT ||
reader->current_attr >= elem->attributeCount) return WS_E_INVALID_FORMAT;
attr = elem->attributes[reader->current_attr];
if (attr->value->textType != WS_XML_TEXT_TYPE_UTF8)
{
FIXME( "text type %u not supported\n", attr->value->textType );
return E_NOTIMPL;
}
*ret = (WS_XML_UTF8_TEXT *)attr->value;
reader->current_attr++;
return S_OK;
}
static HRESULT read_type_bool( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_BOOL_DESCRIPTION *desc, BOOL *ret )
{
WS_XML_UTF8_TEXT *utf8;
HRESULT hr;
ULONG len;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
switch (mapping)
{
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
case WS_ATTRIBUTE_TYPE_MAPPING:
if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr;
len = utf8->value.length;
break;
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr;
len = utf8->value.length;
break;
default:
FIXME( "mapping %u not supported\n", mapping );
return E_NOTIMPL;
}
if (len == 4 && !memcmp( utf8->value.bytes, "true", 4 )) *ret = TRUE;
else if (len == 1 && !memcmp( utf8->value.bytes, "1", 1 )) *ret = TRUE;
else if (len == 5 && !memcmp( utf8->value.bytes, "false", 5 )) *ret = FALSE;
else if (len == 1 && !memcmp( utf8->value.bytes, "0", 1 )) *ret = FALSE;
else return WS_E_INVALID_FORMAT;
return S_OK;
}
static HRESULT read_type_int8( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_INT8_DESCRIPTION *desc, INT8 *ret )
{
WS_XML_UTF8_TEXT *utf8;
HRESULT hr;
INT64 val;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
switch (mapping)
{
case WS_ATTRIBUTE_TYPE_MAPPING:
if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr;
break;
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr;
break;
default:
FIXME( "mapping %u not supported\n", mapping );
return E_NOTIMPL;
}
if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT8, MAX_INT8, &val )) != S_OK)
return hr;
*ret = val;
return S_OK;
}
static HRESULT read_type_int16( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_INT16_DESCRIPTION *desc, INT16 *ret )
{
WS_XML_UTF8_TEXT *utf8;
HRESULT hr;
INT64 val;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
switch (mapping)
{
case WS_ATTRIBUTE_TYPE_MAPPING:
if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr;
break;
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr;
break;
default:
FIXME( "mapping %u not supported\n", mapping );
return E_NOTIMPL;
}
if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT16, MAX_INT16, &val )) != S_OK)
return hr;
*ret = val;
return S_OK;
}
static HRESULT read_type_int32( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_INT32_DESCRIPTION *desc, INT32 *ret )
{
WS_XML_UTF8_TEXT *utf8;
HRESULT hr;
INT64 val;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
switch (mapping)
{
case WS_ATTRIBUTE_TYPE_MAPPING:
if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr;
break;
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr;
break;
default:
FIXME( "mapping %u not supported\n", mapping );
return E_NOTIMPL;
}
if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT32, MAX_INT32, &val )) != S_OK)
return hr;
*ret = val;
return S_OK;
}
static HRESULT read_type_int64( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_INT64_DESCRIPTION *desc, INT64 *ret )
{
WS_XML_UTF8_TEXT *utf8;
HRESULT hr;
INT64 val;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
switch (mapping)
{
case WS_ATTRIBUTE_TYPE_MAPPING:
if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr;
break;
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr;
break;
default:
FIXME( "mapping %u not supported\n", mapping );
return E_NOTIMPL;
}
if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT64, MAX_INT64, &val )) != S_OK)
return hr;
*ret = val;
return S_OK;
}
static HRESULT read_type_uint8( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_UINT8_DESCRIPTION *desc, UINT8 *ret )
{
WS_XML_UTF8_TEXT *utf8;
HRESULT hr;
UINT64 val;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
switch (mapping)
{
case WS_ATTRIBUTE_TYPE_MAPPING:
if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr;
break;
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr;
break;
default:
FIXME( "mapping %u not supported\n", mapping );
return E_NOTIMPL;
}
if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT8, &val )) != S_OK)
return hr;
*ret = val;
return S_OK;
}
static HRESULT read_type_uint16( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_UINT16_DESCRIPTION *desc, UINT16 *ret )
{
WS_XML_UTF8_TEXT *utf8;
HRESULT hr;
UINT64 val;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
switch (mapping)
{
case WS_ATTRIBUTE_TYPE_MAPPING:
if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr;
break;
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr;
break;
default:
FIXME( "mapping %u not supported\n", mapping );
return E_NOTIMPL;
}
if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT16, &val )) != S_OK)
return hr;
*ret = val;
return S_OK;
}
static HRESULT read_type_uint32( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_UINT32_DESCRIPTION *desc, UINT32 *ret )
{
WS_XML_UTF8_TEXT *utf8;
HRESULT hr;
UINT64 val;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
switch (mapping)
{
case WS_ATTRIBUTE_TYPE_MAPPING:
if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr;
break;
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr;
break;
default:
FIXME( "mapping %u not supported\n", mapping );
return E_NOTIMPL;
}
if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT32, &val )) != S_OK)
return hr;
*ret = val;
return S_OK;
}
static HRESULT read_type_uint64( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_UINT64_DESCRIPTION *desc, UINT64 *ret )
{
WS_XML_UTF8_TEXT *utf8;
HRESULT hr;
UINT64 val;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
switch (mapping)
{
case WS_ATTRIBUTE_TYPE_MAPPING:
if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr;
break;
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr;
break;
default:
FIXME( "mapping %u not supported\n", mapping );
return E_NOTIMPL;
}
if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT64, &val )) != S_OK)
return hr;
*ret = val;
return S_OK;
}
static HRESULT read_type_wsz( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_WSZ_DESCRIPTION *desc, WS_HEAP *heap, WCHAR **ret )
{
WS_XML_UTF8_TEXT *utf8;
HRESULT hr;
WCHAR *str;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
switch (mapping)
{
case WS_ATTRIBUTE_TYPE_MAPPING:
if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr;
break;
case WS_ELEMENT_TYPE_MAPPING:
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr;
break;
default:
FIXME( "mapping %u not supported\n", mapping );
return E_NOTIMPL;
}
if (!(str = xmltext_to_widechar( heap, &utf8->text ))) return WS_E_QUOTA_EXCEEDED;
*ret = str;
return S_OK;
}
static HRESULT read_type_struct( struct reader *, WS_TYPE_MAPPING, const WS_STRUCT_DESCRIPTION *,
WS_HEAP *, void ** );
static HRESULT read_type_struct_field( struct reader *reader, const WS_FIELD_DESCRIPTION *desc,
WS_HEAP *heap, char *buf )
{
char *ptr = buf + desc->offset;
WS_TYPE_MAPPING mapping;
HRESULT hr;
if (desc->options && desc->options != WS_FIELD_POINTER &&
desc->options != WS_FIELD_OPTIONAL &&
desc->options != (WS_FIELD_POINTER | WS_FIELD_OPTIONAL))
{
FIXME( "options 0x%x not supported\n", desc->options );
return E_NOTIMPL;
}
switch (desc->mapping)
{
case WS_ATTRIBUTE_FIELD_MAPPING:
mapping = WS_ATTRIBUTE_TYPE_MAPPING;
break;
case WS_ELEMENT_FIELD_MAPPING:
mapping = WS_ELEMENT_TYPE_MAPPING;
break;
default:
FIXME( "unhandled field mapping %u\n", desc->mapping );
return E_NOTIMPL;
}
switch (desc->type)
{
case WS_STRUCT_TYPE:
hr = read_type_struct( reader, mapping, desc->typeDescription, heap, (void **)ptr );
break;
case WS_BOOL_TYPE:
hr = read_type_bool( reader, mapping, desc->typeDescription, (BOOL *)ptr );
break;
case WS_INT8_TYPE:
hr = read_type_int8( reader, mapping, desc->typeDescription, (INT8 *)ptr );
break;
case WS_INT16_TYPE:
hr = read_type_int16( reader, mapping, desc->typeDescription, (INT16 *)ptr );
break;
case WS_INT32_TYPE:
hr = read_type_int32( reader, mapping, desc->typeDescription, (INT32 *)ptr );
break;
case WS_INT64_TYPE:
hr = read_type_int64( reader, mapping, desc->typeDescription, (INT64 *)ptr );
break;
case WS_UINT8_TYPE:
hr = read_type_uint8( reader, mapping, desc->typeDescription, (UINT8 *)ptr );
break;
case WS_UINT16_TYPE:
hr = read_type_uint16( reader, mapping, desc->typeDescription, (UINT16 *)ptr );
break;
case WS_UINT32_TYPE:
hr = read_type_uint32( reader, mapping, desc->typeDescription, (UINT32 *)ptr );
break;
case WS_UINT64_TYPE:
hr = read_type_uint64( reader, mapping, desc->typeDescription, (UINT64 *)ptr );
break;
case WS_WSZ_TYPE:
hr = read_type_wsz( reader, mapping, desc->typeDescription, heap, (WCHAR **)ptr );
break;
default:
FIXME( "type %u not implemented\n", desc->type );
return E_NOTIMPL;
}
return hr;
}
static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_STRUCT_DESCRIPTION *desc, WS_HEAP *heap, void **ret )
{
ULONG i;
HRESULT hr;
char *buf;
if (!desc) return E_INVALIDARG;
if (desc->structOptions)
{
FIXME( "struct options 0x%x not supported\n", desc->structOptions );
return E_NOTIMPL;
}
switch (mapping)
{
case WS_ELEMENT_TYPE_MAPPING:
if ((hr = read_to_startelement( reader, NULL )) != S_OK) return hr;
break;
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
if ((hr = read_to_startelement( reader, NULL )) != S_OK) return hr;
if ((hr = read_startelement( reader )) != S_OK) return hr;
break;
default:
FIXME( "unhandled mapping %u\n", mapping );
return E_NOTIMPL;
}
if (!(buf = ws_alloc_zero( heap, desc->size ))) return WS_E_QUOTA_EXCEEDED;
for (i = 0; i < desc->fieldCount; i++)
{
if ((hr = read_type_struct_field( reader, desc->fields[i], heap, buf )) != S_OK)
{
ws_free( heap, buf );
return hr;
}
}
switch (mapping)
{
case WS_ELEMENT_TYPE_MAPPING:
if ((hr = read_endelement( reader )) != S_OK) return hr;
break;
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
if ((hr = read_endelement( reader )) != S_OK) return hr;
if ((hr = read_node( reader )) != S_OK) return hr;
if (reader->state != READER_STATE_EOF) return WS_E_INVALID_FORMAT;
break;
default: break;
}
*ret = buf;
return S_OK;
}
static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYPE type,
const void *desc, WS_READ_OPTION option, WS_HEAP *heap,
void *value, ULONG size )
{
switch (type)
{
case WS_STRUCT_TYPE:
{
void **ptr = value;
if (option != WS_READ_REQUIRED_POINTER || size != sizeof(*ptr))
return E_INVALIDARG;
return read_type_struct( reader, mapping, desc, heap, ptr );
}
case WS_BOOL_TYPE:
{
WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
ULONG len = utf8->value.length;
BOOL *ret = value;
if (value_size != sizeof(BOOL)) return E_INVALIDARG;
if (len == 4 && !memcmp( utf8->value.bytes, "true", 4 )) *ret = TRUE;
else if (len == 1 && !memcmp( utf8->value.bytes, "1", 1 )) *ret = TRUE;
else if (len == 5 && !memcmp( utf8->value.bytes, "false", 5 )) *ret = FALSE;
else if (len == 1 && !memcmp( utf8->value.bytes, "0", 1 )) *ret = FALSE;
else return WS_E_INVALID_FORMAT;
break;
BOOL *ptr = value;
if (option != WS_READ_REQUIRED_VALUE)
{
FIXME( "read option %u not supported\n", option );
return E_NOTIMPL;
}
if (size != sizeof(*ptr)) return E_INVALIDARG;
return read_type_bool( reader, mapping, desc, ptr );
}
case WS_INT8_TYPE:
{
WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
INT8 *ret = value;
HRESULT hr;
INT64 val;
if (value_size != sizeof(INT8)) return E_INVALIDARG;
hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT8, MAX_INT8, &val );
if (hr != S_OK) return hr;
*ret = val;
break;
INT8 *ptr = value;
if (option != WS_READ_REQUIRED_VALUE)
{
FIXME( "read option %u not supported\n", option );
return E_NOTIMPL;
}
if (size != sizeof(*ptr)) return E_INVALIDARG;
return read_type_int8( reader, mapping, desc, ptr );
}
case WS_INT16_TYPE:
{
WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
INT16 *ret = value;
HRESULT hr;
INT64 val;
if (value_size != sizeof(INT16)) return E_INVALIDARG;
hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT16, MAX_INT16, &val );
if (hr != S_OK) return hr;
*ret = val;
break;
INT16 *ptr = value;
if (option != WS_READ_REQUIRED_VALUE)
{
FIXME( "read option %u not supported\n", option );
return E_NOTIMPL;
}
if (size != sizeof(*ptr)) return E_INVALIDARG;
return read_type_int16( reader, mapping, desc, ptr );
}
case WS_INT32_TYPE:
{
WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
INT32 *ret = value;
HRESULT hr;
INT64 val;
if (value_size != sizeof(INT32)) return E_INVALIDARG;
hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT32, MAX_INT32, &val );
if (hr != S_OK) return hr;
*ret = val;
break;
INT32 *ptr = value;
if (option != WS_READ_REQUIRED_VALUE)
{
FIXME( "read option %u not supported\n", option );
return E_NOTIMPL;
}
if (size != sizeof(*ptr)) return E_INVALIDARG;
return read_type_int32( reader, mapping, desc, ptr );
}
case WS_INT64_TYPE:
{
WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
INT64 val, *ret = value;
HRESULT hr;
if (value_size != sizeof(INT64)) return E_INVALIDARG;
hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT64, MAX_INT64, &val );
if (hr != S_OK) return hr;
*ret = val;
break;
INT64 *ptr = value;
if (option != WS_READ_REQUIRED_VALUE)
{
FIXME( "read option %u not supported\n", option );
return E_NOTIMPL;
}
if (size != sizeof(*ptr)) return E_INVALIDARG;
return read_type_int64( reader, mapping, desc, ptr );
}
case WS_UINT8_TYPE:
{
WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
UINT8 *ret = value;
HRESULT hr;
UINT64 val;
if (value_size != sizeof(UINT8)) return E_INVALIDARG;
hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT8, &val );
if (hr != S_OK) return hr;
*ret = val;
break;
UINT8 *ptr = value;
if (option != WS_READ_REQUIRED_VALUE)
{
FIXME( "read option %u not supported\n", option );
return E_NOTIMPL;
}
if (size != sizeof(*ptr)) return E_INVALIDARG;
return read_type_uint8( reader, mapping, desc, ptr );
}
case WS_UINT16_TYPE:
{
WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
UINT16 *ret = value;
HRESULT hr;
UINT64 val;
if (value_size != sizeof(UINT16)) return E_INVALIDARG;
hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT16, &val );
if (hr != S_OK) return hr;
*ret = val;
break;
UINT16 *ptr = value;
if (option != WS_READ_REQUIRED_VALUE)
{
FIXME( "read option %u not supported\n", option );
return E_NOTIMPL;
}
if (size != sizeof(*ptr)) return E_INVALIDARG;
return read_type_uint16( reader, mapping, desc, ptr );
}
case WS_UINT32_TYPE:
{
WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
UINT32 *ret = value;
HRESULT hr;
UINT64 val;
if (value_size != sizeof(UINT32)) return E_INVALIDARG;
hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT32, &val );
if (hr != S_OK) return hr;
*ret = val;
break;
UINT32 *ptr = value;
if (option != WS_READ_REQUIRED_VALUE)
{
FIXME( "read option %u not supported\n", option );
return E_NOTIMPL;
}
if (size != sizeof(*ptr)) return E_INVALIDARG;
return read_type_uint32( reader, mapping, desc, ptr );
}
case WS_UINT64_TYPE:
{
WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
UINT64 val, *ret = value;
HRESULT hr;
if (value_size != sizeof(UINT64)) return E_INVALIDARG;
hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT64, &val );
if (hr != S_OK) return hr;
*ret = val;
break;
UINT64 *ptr = value;
if (option != WS_READ_REQUIRED_VALUE)
{
FIXME( "read option %u not supported\n", option );
return E_NOTIMPL;
}
if (size != sizeof(*ptr)) return E_INVALIDARG;
return read_type_uint64( reader, mapping, desc, ptr );
}
case WS_WSZ_TYPE:
{
WCHAR *str, **ret = value;
if (value_size != sizeof(WCHAR *)) return E_INVALIDARG;
if (!(str = xmltext_to_widechar( heap, text->text ))) return E_OUTOFMEMORY;
*ret = str;
break;
WCHAR **ptr = value;
if (option != WS_READ_REQUIRED_POINTER)
{
FIXME( "read option %u not supported\n", option );
return E_NOTIMPL;
}
if (size != sizeof(*ptr)) return E_INVALIDARG;
return read_type_wsz( reader, mapping, desc, heap, ptr );
}
default:
FIXME( "type %u not supported\n", type );
return E_NOTIMPL;
}
}
return S_OK;
/**************************************************************************
* WsReadType [webservices.@]
*/
HRESULT WINAPI WsReadType( WS_XML_READER *handle, WS_TYPE_MAPPING mapping, WS_TYPE type,
const void *desc, WS_READ_OPTION option, WS_HEAP *heap, void *value,
ULONG size, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
TRACE( "%p %u %u %p %u %p %p %u %p\n", handle, mapping, type, desc, option, heap, value,
size, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !value) return E_INVALIDARG;
return read_type( reader, mapping, type, desc, option, heap, value, size );
}
/**************************************************************************

View File

@ -1707,6 +1707,104 @@ static void test_WsMoveReader(void)
WsFreeHeap( heap );
}
static void prepare_struct_type_test( WS_XML_READER *reader, const char *data )
{
HRESULT hr;
ULONG size = strlen( data );
hr = set_input( reader, data, size );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsFillReader( reader, size, NULL, NULL );
ok( hr == S_OK, "got %08x\n", hr );
}
static void test_simple_struct_type(void)
{
static const WCHAR testW[] = {'t','e','s','t',0};
HRESULT hr;
WS_XML_READER *reader;
WS_HEAP *heap;
WS_STRUCT_DESCRIPTION s;
WS_FIELD_DESCRIPTION f, *fields[1];
WS_XML_STRING ns = {0, NULL}, localname = {3, (BYTE *)"str"};
WS_XML_STRING localname2 = {4, (BYTE *)"test"};
const WS_XML_NODE *node;
struct test { WCHAR *str; } *test;
hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
ok( hr == S_OK, "got %08x\n", hr );
prepare_struct_type_test( reader, "<str>test</str>" );
hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL,
WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
ok( hr == E_INVALIDARG, "got %08x\n", hr );
hr = WsGetReaderNode( reader, &node, NULL );
ok( hr == S_OK, "got %08x\n", hr );
ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
/* element field mapping */
memset( &f, 0, sizeof(f) );
f.mapping = WS_ELEMENT_FIELD_MAPPING;
f.localName = &localname;
f.ns = &ns;
f.type = WS_WSZ_TYPE;
fields[0] = &f;
memset( &s, 0, sizeof(s) );
s.size = sizeof(struct test);
s.alignment = TYPE_ALIGNMENT(struct test);
s.fields = fields;
s.fieldCount = 1;
s.typeLocalName = &localname2;
s.typeNs = &ns;
test = NULL;
prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
test = NULL;
prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str>" );
hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
ok( hr == S_OK, "got %08x\n", hr );
ok( test != NULL, "test not set\n" );
if (test)
{
ok( test->str != NULL, "str not set\n" );
if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
}
hr = WsGetReaderNode( reader, &node, NULL );
ok( hr == S_OK, "got %08x\n", hr );
ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
test = NULL;
prepare_struct_type_test( reader, "<str>test</str>" );
hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
ok( hr == S_OK, "got %08x\n", hr );
ok( test != NULL, "test not set\n" );
if (test)
{
ok( test->str != NULL, "str not set\n" );
if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" );
}
hr = WsGetReaderNode( reader, &node, NULL );
ok( hr == S_OK, "got %08x\n", hr );
ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
WsFreeReader( reader );
WsFreeHeap( heap );
}
START_TEST(reader)
{
test_WsCreateError();
@ -1724,4 +1822,5 @@ START_TEST(reader)
test_WsXmlStringEquals();
test_WsAlloc();
test_WsMoveReader();
test_simple_struct_type();
}