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:
parent
bd4361cb0f
commit
9fb780ec08
|
@ -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 );
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue