webservices: Implement WS_REPEATING_ELEMENT_CHOICE_FIELD_MAPPING in the writer.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bb586c7e73
commit
ca0b46a10c
|
@ -4544,6 +4544,111 @@ static void test_text_types_binary(void)
|
|||
WsFreeWriter( writer );
|
||||
}
|
||||
|
||||
static void test_repeating_element_choice(void)
|
||||
{
|
||||
static const WCHAR testW[] = {'t','e','s','t',0};
|
||||
static WS_XML_STRING str_ns = {0, NULL}, str_a = {1, (BYTE *)"a"}, str_b = {1, (BYTE *)"b"};
|
||||
static WS_XML_STRING str_s = {1, (BYTE *)"s"}, str_t = {1, (BYTE *)"t"};
|
||||
HRESULT hr;
|
||||
WS_XML_WRITER *writer;
|
||||
WS_UNION_DESCRIPTION u;
|
||||
WS_UNION_FIELD_DESCRIPTION f, f2, *fields[2];
|
||||
WS_FIELD_DESCRIPTION f_items, *fields_items[1];
|
||||
WS_STRUCT_DESCRIPTION s;
|
||||
enum choice {CHOICE_A, CHOICE_B, CHOICE_NONE};
|
||||
struct item
|
||||
{
|
||||
enum choice choice;
|
||||
union
|
||||
{
|
||||
const WCHAR *a;
|
||||
UINT32 b;
|
||||
} value;
|
||||
} items[2];
|
||||
struct test
|
||||
{
|
||||
struct item *items;
|
||||
ULONG count;
|
||||
} test;
|
||||
|
||||
hr = WsCreateWriter( NULL, 0, &writer, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
memset( &f, 0, sizeof(f) );
|
||||
f.value = CHOICE_A;
|
||||
f.field.mapping = WS_ELEMENT_FIELD_MAPPING;
|
||||
f.field.localName = &str_a;
|
||||
f.field.ns = &str_ns;
|
||||
f.field.type = WS_WSZ_TYPE;
|
||||
f.field.offset = FIELD_OFFSET(struct item, value.a);
|
||||
fields[0] = &f;
|
||||
|
||||
memset( &f2, 0, sizeof(f2) );
|
||||
f2.value = CHOICE_B;
|
||||
f2.field.mapping = WS_ELEMENT_FIELD_MAPPING;
|
||||
f2.field.localName = &str_b;
|
||||
f2.field.ns = &str_ns;
|
||||
f2.field.type = WS_UINT32_TYPE;
|
||||
f2.field.offset = FIELD_OFFSET(struct item, value.b);
|
||||
fields[1] = &f2;
|
||||
|
||||
memset( &u, 0, sizeof(u) );
|
||||
u.size = sizeof(struct item);
|
||||
u.alignment = TYPE_ALIGNMENT(struct item);
|
||||
u.fields = fields;
|
||||
u.fieldCount = 2;
|
||||
u.enumOffset = FIELD_OFFSET(struct item, choice);
|
||||
u.noneEnumValue = CHOICE_NONE;
|
||||
|
||||
memset( &f_items, 0, sizeof(f_items) );
|
||||
f_items.mapping = WS_REPEATING_ELEMENT_CHOICE_FIELD_MAPPING;
|
||||
f_items.localName = &str_t;
|
||||
f_items.ns = &str_ns;
|
||||
f_items.type = WS_UNION_TYPE;
|
||||
f_items.typeDescription = &u;
|
||||
f_items.countOffset = FIELD_OFFSET(struct test, count);
|
||||
fields_items[0] = &f_items;
|
||||
|
||||
memset( &s, 0, sizeof(s) );
|
||||
s.size = sizeof(struct test);
|
||||
s.alignment = TYPE_ALIGNMENT(struct test);
|
||||
s.fields = fields_items;
|
||||
s.fieldCount = 1;
|
||||
s.typeLocalName = &str_s;
|
||||
s.typeNs = &str_ns;
|
||||
|
||||
items[0].choice = CHOICE_A;
|
||||
items[0].value.a = testW;
|
||||
items[1].choice = CHOICE_B;
|
||||
items[1].value.b = 1;
|
||||
test.items = items;
|
||||
test.count = 2;
|
||||
|
||||
hr = set_output( writer );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
|
||||
WS_WRITE_REQUIRED_VALUE, &test, sizeof(test), NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
check_output( writer, "<t><a>test</a><b>1</b></t>", __LINE__ );
|
||||
|
||||
items[0].choice = CHOICE_NONE;
|
||||
hr = set_output( writer );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
|
||||
WS_WRITE_REQUIRED_VALUE, &test, sizeof(test), NULL );
|
||||
ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
|
||||
|
||||
test.count = 0;
|
||||
hr = set_output( writer );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
|
||||
WS_WRITE_REQUIRED_VALUE, &test, sizeof(test), NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
check_output( writer, "<t/>", __LINE__ );
|
||||
|
||||
WsFreeWriter( writer );
|
||||
}
|
||||
|
||||
START_TEST(writer)
|
||||
{
|
||||
test_WsCreateWriter();
|
||||
|
@ -4586,4 +4691,5 @@ START_TEST(writer)
|
|||
test_dictionary();
|
||||
test_union_type();
|
||||
test_text_types_binary();
|
||||
test_repeating_element_choice();
|
||||
}
|
||||
|
|
|
@ -3492,6 +3492,7 @@ static WS_WRITE_OPTION get_field_write_option( WS_TYPE type, ULONG options )
|
|||
case WS_XML_QNAME_TYPE:
|
||||
case WS_STRUCT_TYPE:
|
||||
case WS_ENUM_TYPE:
|
||||
case WS_UNION_TYPE:
|
||||
if (options & (WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE)) return WS_WRITE_NILLABLE_VALUE;
|
||||
return WS_WRITE_REQUIRED_VALUE;
|
||||
|
||||
|
@ -3506,42 +3507,11 @@ static WS_WRITE_OPTION get_field_write_option( WS_TYPE type, ULONG options )
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT write_type_field( struct writer *, const WS_FIELD_DESCRIPTION *, const char *, ULONG );
|
||||
|
||||
static HRESULT write_type( struct writer *, WS_TYPE_MAPPING, WS_TYPE, const void *, WS_WRITE_OPTION,
|
||||
const void *, ULONG );
|
||||
|
||||
static HRESULT write_type_repeating_element( struct writer *writer, const WS_FIELD_DESCRIPTION *desc,
|
||||
const char *buf, ULONG count )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
ULONG i, size, offset = 0;
|
||||
WS_WRITE_OPTION option;
|
||||
|
||||
if (!(option = get_field_write_option( desc->type, desc->options ))) return E_INVALIDARG;
|
||||
|
||||
/* wrapper element */
|
||||
if (desc->localName && ((hr = write_element_node( writer, NULL, desc->localName, desc->ns )) != S_OK))
|
||||
return hr;
|
||||
|
||||
if (option == WS_WRITE_REQUIRED_VALUE || option == WS_WRITE_NILLABLE_VALUE)
|
||||
size = get_type_size( desc->type, desc->typeDescription );
|
||||
else
|
||||
size = sizeof(const void *);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if ((hr = write_element_node( writer, NULL, desc->itemLocalName, desc->itemNs )) != S_OK) return hr;
|
||||
if ((hr = write_type( writer, WS_ELEMENT_TYPE_MAPPING, desc->type, desc->typeDescription, option,
|
||||
buf + offset, size )) != S_OK) return hr;
|
||||
if ((hr = write_endelement_node( writer )) != S_OK) return hr;
|
||||
offset += size;
|
||||
}
|
||||
|
||||
if (desc->localName) hr = write_endelement_node( writer );
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT write_type_field( struct writer *, const WS_FIELD_DESCRIPTION *, const char *, ULONG );
|
||||
|
||||
static HRESULT write_type_union( struct writer *writer, const WS_UNION_DESCRIPTION *desc, WS_WRITE_OPTION option,
|
||||
const void *value, ULONG size )
|
||||
{
|
||||
|
@ -3581,6 +3551,45 @@ static HRESULT write_type_union( struct writer *writer, const WS_UNION_DESCRIPTI
|
|||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
static HRESULT write_type_array( struct writer *writer, const WS_FIELD_DESCRIPTION *desc, const char *buf,
|
||||
ULONG count )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
ULONG i, size, offset = 0;
|
||||
WS_WRITE_OPTION option;
|
||||
|
||||
if (!(option = get_field_write_option( desc->type, desc->options ))) return E_INVALIDARG;
|
||||
|
||||
/* wrapper element */
|
||||
if (desc->localName && ((hr = write_element_node( writer, NULL, desc->localName, desc->ns )) != S_OK))
|
||||
return hr;
|
||||
|
||||
if (option == WS_WRITE_REQUIRED_VALUE || option == WS_WRITE_NILLABLE_VALUE)
|
||||
size = get_type_size( desc->type, desc->typeDescription );
|
||||
else
|
||||
size = sizeof(const void *);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (desc->type == WS_UNION_TYPE)
|
||||
{
|
||||
if ((hr = write_type_union( writer, desc->typeDescription, option, buf + offset, size )) != S_OK)
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((hr = write_element_node( writer, NULL, desc->itemLocalName, desc->itemNs )) != S_OK) return hr;
|
||||
if ((hr = write_type( writer, WS_ELEMENT_TYPE_MAPPING, desc->type, desc->typeDescription, option,
|
||||
buf + offset, size )) != S_OK) return hr;
|
||||
if ((hr = write_endelement_node( writer )) != S_OK) return hr;
|
||||
}
|
||||
offset += size;
|
||||
}
|
||||
|
||||
if (desc->localName) hr = write_endelement_node( writer );
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT write_type_field( struct writer *writer, const WS_FIELD_DESCRIPTION *desc, const char *buf,
|
||||
ULONG offset )
|
||||
{
|
||||
|
@ -3646,8 +3655,9 @@ static HRESULT write_type_field( struct writer *writer, const WS_FIELD_DESCRIPTI
|
|||
return write_type_union( writer, desc->typeDescription, option, ptr, size );
|
||||
|
||||
case WS_REPEATING_ELEMENT_FIELD_MAPPING:
|
||||
case WS_REPEATING_ELEMENT_CHOICE_FIELD_MAPPING:
|
||||
count = *(const ULONG *)(buf + desc->countOffset);
|
||||
return write_type_repeating_element( writer, desc, *(const char **)ptr, count );
|
||||
return write_type_array( writer, desc, *(const char **)ptr, count );
|
||||
|
||||
case WS_TEXT_FIELD_MAPPING:
|
||||
switch (writer->state)
|
||||
|
@ -4713,7 +4723,7 @@ static ULONG get_array_len( const WS_PARAMETER_DESCRIPTION *params, ULONG count,
|
|||
static HRESULT write_param_array( struct writer *writer, const WS_FIELD_DESCRIPTION *desc, const void *value,
|
||||
ULONG len )
|
||||
{
|
||||
return write_type_repeating_element( writer, desc, value, len );
|
||||
return write_type_array( writer, desc, value, len );
|
||||
}
|
||||
|
||||
HRESULT write_input_params( WS_XML_WRITER *handle, const WS_ELEMENT_DESCRIPTION *desc,
|
||||
|
|
Loading…
Reference in New Issue