webservices: Implement WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
829b225546
commit
459b7caeb2
|
@ -4000,7 +4000,11 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping,
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
if (!desc) return E_INVALIDARG;
|
if (!desc) return E_INVALIDARG;
|
||||||
if (desc->structOptions) FIXME( "struct options %08x not supported\n", desc->structOptions );
|
if (desc->structOptions & ~WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT)
|
||||||
|
{
|
||||||
|
FIXME( "struct options %08x not supported\n",
|
||||||
|
desc->structOptions & ~WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT );
|
||||||
|
}
|
||||||
|
|
||||||
switch (option)
|
switch (option)
|
||||||
{
|
{
|
||||||
|
@ -4037,7 +4041,7 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping,
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
*(char **)ret = buf;
|
*(char **)ret = buf;
|
||||||
return S_OK;
|
break;
|
||||||
|
|
||||||
case WS_READ_OPTIONAL_POINTER:
|
case WS_READ_OPTIONAL_POINTER:
|
||||||
case WS_READ_NILLABLE_POINTER:
|
case WS_READ_NILLABLE_POINTER:
|
||||||
|
@ -4047,16 +4051,77 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping,
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
}
|
}
|
||||||
*(char **)ret = buf;
|
*(char **)ret = buf;
|
||||||
return S_OK;
|
break;
|
||||||
|
|
||||||
case WS_READ_REQUIRED_VALUE:
|
case WS_READ_REQUIRED_VALUE:
|
||||||
case WS_READ_NILLABLE_VALUE:
|
case WS_READ_NILLABLE_VALUE:
|
||||||
return hr;
|
if (hr != S_OK) return hr;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ERR( "unhandled read option %u\n", option );
|
ERR( "unhandled read option %u\n", option );
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (desc->structOptions & WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT)
|
||||||
|
{
|
||||||
|
struct node *parent = find_parent( reader );
|
||||||
|
parent->flags |= NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT start_mapping( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_XML_STRING *localname,
|
||||||
|
const WS_XML_STRING *ns )
|
||||||
|
{
|
||||||
|
switch (mapping)
|
||||||
|
{
|
||||||
|
case WS_ELEMENT_TYPE_MAPPING:
|
||||||
|
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
|
||||||
|
return read_type_next_element_node( reader, localname, ns );
|
||||||
|
|
||||||
|
case WS_ANY_ELEMENT_TYPE_MAPPING:
|
||||||
|
case WS_ATTRIBUTE_TYPE_MAPPING:
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FIXME( "unhandled mapping %u\n", mapping );
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT read_type_endelement_node( struct reader *reader )
|
||||||
|
{
|
||||||
|
const struct node *parent = find_parent( reader );
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if ((hr = read_type_next_node( reader )) != S_OK) return hr;
|
||||||
|
if (node_type( reader->current ) == WS_XML_NODE_TYPE_END_ELEMENT && reader->current->parent == parent)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
if (read_end_of_data( reader ) || !(parent->flags & NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WS_E_INVALID_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT end_mapping( struct reader *reader, WS_TYPE_MAPPING mapping )
|
||||||
|
{
|
||||||
|
switch (mapping)
|
||||||
|
{
|
||||||
|
case WS_ELEMENT_TYPE_MAPPING:
|
||||||
|
return read_type_endelement_node( reader );
|
||||||
|
|
||||||
|
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
|
||||||
|
return read_type_next_node( reader );
|
||||||
|
|
||||||
|
case WS_ATTRIBUTE_TYPE_MAPPING:
|
||||||
|
default:
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT is_nil_element( const WS_XML_ELEMENT_NODE *elem )
|
static HRESULT is_nil_element( const WS_XML_ELEMENT_NODE *elem )
|
||||||
|
@ -4078,28 +4143,17 @@ static HRESULT is_nil_element( const WS_XML_ELEMENT_NODE *elem )
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYPE type,
|
static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYPE type,
|
||||||
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
|
const WS_XML_STRING *localname, const WS_XML_STRING *ns, const void *desc,
|
||||||
const void *desc, WS_READ_OPTION option, WS_HEAP *heap,
|
WS_READ_OPTION option, WS_HEAP *heap, void *value, ULONG size )
|
||||||
void *value, ULONG size )
|
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
switch (mapping)
|
if ((hr = start_mapping( reader, mapping, localname, ns )) != S_OK) return hr;
|
||||||
|
|
||||||
|
if (mapping == WS_ELEMENT_TYPE_MAPPING && is_nil_element( &reader->current->hdr ))
|
||||||
{
|
{
|
||||||
case WS_ELEMENT_TYPE_MAPPING:
|
if (option != WS_READ_NILLABLE_POINTER && option != WS_READ_NILLABLE_VALUE) return WS_E_INVALID_FORMAT;
|
||||||
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
|
return end_mapping( reader, mapping );
|
||||||
if ((hr = read_type_next_element_node( reader, localname, ns )) != S_OK) return hr;
|
|
||||||
if ((option == WS_READ_NILLABLE_POINTER || option == WS_READ_NILLABLE_VALUE) &&
|
|
||||||
is_nil_element( &reader->current->hdr )) return read_type_next_node( reader );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WS_ANY_ELEMENT_TYPE_MAPPING:
|
|
||||||
case WS_ATTRIBUTE_TYPE_MAPPING:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
FIXME( "unhandled mapping %u\n", mapping );
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -4189,16 +4243,7 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mapping)
|
return end_mapping( reader, mapping );
|
||||||
{
|
|
||||||
case WS_ELEMENT_TYPE_MAPPING:
|
|
||||||
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
|
|
||||||
return read_type_next_node( reader );
|
|
||||||
|
|
||||||
case WS_ATTRIBUTE_TYPE_MAPPING:
|
|
||||||
default:
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
|
|
@ -71,6 +71,12 @@ static const char data11[] =
|
||||||
"</o:services>"
|
"</o:services>"
|
||||||
"</o:OfficeConfig>";
|
"</o:OfficeConfig>";
|
||||||
|
|
||||||
|
static const char data11b[] =
|
||||||
|
"<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
|
||||||
|
"<o:services o:GenerationTime=\"2015-09-03T18:47:54\"></o:services>"
|
||||||
|
"<trailing>content</trailing>"
|
||||||
|
"</o:OfficeConfig>";
|
||||||
|
|
||||||
static const char data12[] =
|
static const char data12[] =
|
||||||
"<services>"
|
"<services>"
|
||||||
"<service><id>1</id></service>"
|
"<service><id>1</id></service>"
|
||||||
|
@ -2069,12 +2075,23 @@ static void test_simple_struct_type(void)
|
||||||
s.typeLocalName = &localname2;
|
s.typeLocalName = &localname2;
|
||||||
s.typeNs = &ns;
|
s.typeNs = &ns;
|
||||||
|
|
||||||
test = NULL;
|
|
||||||
prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
|
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,
|
hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
|
||||||
WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
|
WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
|
||||||
ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
|
ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
|
||||||
|
|
||||||
|
prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
|
||||||
|
hr = WsReadType( reader, WS_ELEMENT_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 );
|
||||||
|
|
||||||
|
s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
|
||||||
|
prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str><str>test2</str>" );
|
||||||
|
hr = WsReadType( reader, WS_ELEMENT_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 );
|
||||||
|
s.structOptions = 0;
|
||||||
|
|
||||||
test = NULL;
|
test = NULL;
|
||||||
prepare_struct_type_test( reader, "<?xml version=\"1.0\" encoding=\"utf-8\"?><str>test</str>" );
|
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,
|
hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
|
||||||
|
@ -2815,6 +2832,29 @@ static void test_complex_struct_type(void)
|
||||||
ok( hr == S_OK, "got %08x\n", hr );
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
|
ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
|
||||||
|
|
||||||
|
/* trailing content */
|
||||||
|
prepare_struct_type_test( reader, data11b );
|
||||||
|
hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT;
|
||||||
|
hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
|
||||||
|
WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
|
prepare_struct_type_test( reader, data11b );
|
||||||
|
hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
s.structOptions = 0;
|
||||||
|
hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
|
||||||
|
WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error );
|
||||||
|
ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
|
||||||
|
|
||||||
WsFreeReader( reader );
|
WsFreeReader( reader );
|
||||||
WsFreeHeap( heap );
|
WsFreeHeap( heap );
|
||||||
WsFreeError( error );
|
WsFreeError( error );
|
||||||
|
|
|
@ -41,12 +41,18 @@ HRESULT set_output( WS_XML_WRITER * ) DECLSPEC_HIDDEN;
|
||||||
HRESULT set_input( WS_XML_READER *, char *, ULONG ) DECLSPEC_HIDDEN;
|
HRESULT set_input( WS_XML_READER *, char *, ULONG ) DECLSPEC_HIDDEN;
|
||||||
ULONG get_type_size( WS_TYPE, const WS_STRUCT_DESCRIPTION * ) DECLSPEC_HIDDEN;
|
ULONG get_type_size( WS_TYPE, const WS_STRUCT_DESCRIPTION * ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
enum node_flag
|
||||||
|
{
|
||||||
|
NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT = 0x1,
|
||||||
|
};
|
||||||
|
|
||||||
struct node
|
struct node
|
||||||
{
|
{
|
||||||
WS_XML_ELEMENT_NODE hdr;
|
WS_XML_ELEMENT_NODE hdr;
|
||||||
struct list entry;
|
struct list entry;
|
||||||
struct node *parent;
|
struct node *parent;
|
||||||
struct list children;
|
struct list children;
|
||||||
|
ULONG flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct node *alloc_node( WS_XML_NODE_TYPE ) DECLSPEC_HIDDEN;
|
struct node *alloc_node( WS_XML_NODE_TYPE ) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue