[6/6] webservices: Add support for structure types in WsReadType.
Hans Leidekker
hans at codeweavers.com
Fri Jan 29 06:27:30 CST 2016
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/webservices/reader.c | 712 ++++++++++++++++++++++++++++++++++------
dlls/webservices/tests/reader.c | 99 ++++++
2 files changed, 709 insertions(+), 102 deletions(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 82a3a1a..a0c32a9 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -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->current->hdr.node.nodeType != WS_XML_NODE_TYPE_TEXT)
+ return WS_E_INVALID_FORMAT;
- if (!reader || !value) return E_INVALIDARG;
+ 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;
+}
- if (reader->current->hdr.node.nodeType != WS_XML_NODE_TYPE_TEXT)
+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( "only text nodes are supported\n" );
+ FIXME( "text type %u not supported\n", attr->value->textType );
return E_NOTIMPL;
}
- text = (WS_XML_TEXT_NODE *)&reader->current->hdr.node;
- if (text->text->textType != WS_XML_TEXT_TYPE_UTF8)
+ *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( "text type %u not supported\n", text->text->textType );
+ 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;
+ 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;
}
- switch (type)
+ 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)
{
- case WS_BOOL_TYPE:
+ FIXME( "description not supported\n" );
+ return E_NOTIMPL;
+ }
+ switch (mapping)
{
- WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
- ULONG len = utf8->value.length;
- BOOL *ret = value;
+ 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 (value_size != sizeof(BOOL)) return E_INVALIDARG;
+ 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;
- 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;
+ 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;
}
- case WS_INT8_TYPE:
+
+ 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)
{
- WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
- INT8 *ret = value;
- HRESULT hr;
- INT64 val;
+ 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;
- 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;
+ 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;
}
- case WS_INT16_TYPE:
+
+ 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)
{
- WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
- INT16 *ret = value;
- HRESULT hr;
- INT64 val;
+ 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;
- 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;
+ 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;
}
- case WS_INT32_TYPE:
+
+ 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)
{
- WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
- INT32 *ret = value;
- HRESULT hr;
- INT64 val;
+ 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;
- 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;
+ 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;
}
- case WS_INT64_TYPE:
+
+ 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)
{
- WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
- INT64 val, *ret = value;
- HRESULT hr;
+ 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;
- 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;
+ 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;
}
- case WS_UINT8_TYPE:
+
+ 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)
{
- WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
- UINT8 *ret = value;
- HRESULT hr;
- UINT64 val;
+ 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;
- 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;
+ 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;
}
- case WS_UINT16_TYPE:
+
+ 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)
{
- WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
- UINT16 *ret = value;
- HRESULT hr;
- UINT64 val;
+ 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;
- 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;
+ 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;
}
- case WS_UINT32_TYPE:
+
+ 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))
{
- WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
- UINT32 *ret = value;
- HRESULT hr;
- UINT64 val;
+ FIXME( "options 0x%x not supported\n", desc->options );
+ return E_NOTIMPL;
+ }
- 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;
+ 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)
{
- WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
- UINT64 val, *ret = value;
- HRESULT hr;
+ FIXME( "struct options 0x%x not supported\n", desc->structOptions );
+ return E_NOTIMPL;
+ }
- 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;
+ 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;
}
- case WS_WSZ_TYPE:
+
+ 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)
{
- WCHAR *str, **ret = value;
+ case WS_ELEMENT_TYPE_MAPPING:
+ if ((hr = read_endelement( reader )) != S_OK) return hr;
+ break;
- if (value_size != sizeof(WCHAR *)) return E_INVALIDARG;
- if (!(str = xmltext_to_widechar( heap, text->text ))) return E_OUTOFMEMORY;
- *ret = str;
+ 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:
+ {
+ 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:
+ {
+ 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:
+ {
+ 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:
+ {
+ 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:
+ {
+ 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:
+ {
+ 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:
+ {
+ 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:
+ {
+ 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:
+ {
+ 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 **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 );
}
/**************************************************************************
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index 58d1b2b..d2f2308 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -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();
}
--
2.7.0.rc3
More information about the wine-patches
mailing list