mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-05 08:28:02 +00:00
webservices: Add support for optional and nillable fields 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
e87c64f69c
commit
81d978902d
|
@ -2111,6 +2111,90 @@ static void test_double(void)
|
||||||
WsFreeWriter( writer );
|
WsFreeWriter( writer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_field_flags(void)
|
||||||
|
{
|
||||||
|
static const char expected[] =
|
||||||
|
"<t><bool a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/><int32>-1</int32>"
|
||||||
|
"<xmlstr a:nil=\"true\" xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\"/></t>";
|
||||||
|
HRESULT hr;
|
||||||
|
WS_XML_WRITER *writer;
|
||||||
|
WS_STRUCT_DESCRIPTION s;
|
||||||
|
WS_FIELD_DESCRIPTION f, f2, f3, f4, *fields[4];
|
||||||
|
WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL}, str_guid = {4, (BYTE *)"guid"};
|
||||||
|
WS_XML_STRING str_int32 = {5, (BYTE *)"int32"}, str_bool = {4, (BYTE *)"bool"};
|
||||||
|
WS_XML_STRING str_xmlstr = {6, (BYTE *)"xmlstr"};
|
||||||
|
INT32 val = -1;
|
||||||
|
struct test
|
||||||
|
{
|
||||||
|
GUID guid;
|
||||||
|
BOOL *bool_ptr;
|
||||||
|
INT32 *int32_ptr;
|
||||||
|
WS_XML_STRING xmlstr;
|
||||||
|
} test;
|
||||||
|
|
||||||
|
hr = WsCreateWriter( NULL, 0, &writer, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
hr = set_output( writer );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
memset( &f, 0, sizeof(f) );
|
||||||
|
f.mapping = WS_ELEMENT_FIELD_MAPPING;
|
||||||
|
f.localName = &str_guid;
|
||||||
|
f.ns = &ns;
|
||||||
|
f.type = WS_GUID_TYPE;
|
||||||
|
f.options = WS_FIELD_OPTIONAL;
|
||||||
|
fields[0] = &f;
|
||||||
|
|
||||||
|
memset( &f2, 0, sizeof(f2) );
|
||||||
|
f2.mapping = WS_ELEMENT_FIELD_MAPPING;
|
||||||
|
f2.localName = &str_bool;
|
||||||
|
f2.offset = FIELD_OFFSET(struct test, bool_ptr);
|
||||||
|
f2.ns = &ns;
|
||||||
|
f2.type = WS_BOOL_TYPE;
|
||||||
|
f2.options = WS_FIELD_POINTER|WS_FIELD_NILLABLE;
|
||||||
|
fields[1] = &f2;
|
||||||
|
|
||||||
|
memset( &f3, 0, sizeof(f3) );
|
||||||
|
f3.mapping = WS_ELEMENT_FIELD_MAPPING;
|
||||||
|
f3.localName = &str_int32;
|
||||||
|
f3.offset = FIELD_OFFSET(struct test, int32_ptr);
|
||||||
|
f3.ns = &ns;
|
||||||
|
f3.type = WS_INT32_TYPE;
|
||||||
|
f3.options = WS_FIELD_POINTER|WS_FIELD_NILLABLE;
|
||||||
|
fields[2] = &f3;
|
||||||
|
|
||||||
|
memset( &f4, 0, sizeof(f4) );
|
||||||
|
f4.mapping = WS_ELEMENT_FIELD_MAPPING;
|
||||||
|
f4.localName = &str_xmlstr;
|
||||||
|
f4.offset = FIELD_OFFSET(struct test, xmlstr);
|
||||||
|
f4.ns = &ns;
|
||||||
|
f4.type = WS_XML_STRING_TYPE;
|
||||||
|
f4.options = WS_FIELD_NILLABLE;
|
||||||
|
fields[3] = &f4;
|
||||||
|
|
||||||
|
memset( &s, 0, sizeof(s) );
|
||||||
|
s.size = sizeof(struct test);
|
||||||
|
s.alignment = TYPE_ALIGNMENT(struct test);
|
||||||
|
s.fields = fields;
|
||||||
|
s.fieldCount = 4;
|
||||||
|
|
||||||
|
memset( &test, 0, sizeof(test) );
|
||||||
|
test.int32_ptr = &val;
|
||||||
|
hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, WS_WRITE_REQUIRED_VALUE,
|
||||||
|
&test, sizeof(test), NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
hr = WsWriteEndElement( writer, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
check_output( writer, expected, __LINE__ );
|
||||||
|
|
||||||
|
WsFreeWriter( writer );
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(writer)
|
START_TEST(writer)
|
||||||
{
|
{
|
||||||
test_WsCreateWriter();
|
test_WsCreateWriter();
|
||||||
|
@ -2137,4 +2221,5 @@ START_TEST(writer)
|
||||||
test_WsCopyNode();
|
test_WsCopyNode();
|
||||||
test_text_types();
|
test_text_types();
|
||||||
test_double();
|
test_double();
|
||||||
|
test_field_flags();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1564,6 +1564,26 @@ static HRESULT write_type_xml_string( struct writer *writer, WS_TYPE_MAPPING map
|
||||||
return write_type_text( writer, mapping, &utf8.text );
|
return write_type_text( writer, mapping, &utf8.text );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline BOOL is_nil_value( const char *value, ULONG size )
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
for (i = 0; i < size; i++) if (value[i]) return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT write_add_nil_attribute( struct writer *writer )
|
||||||
|
{
|
||||||
|
static const WS_XML_STRING prefix = {1, (BYTE *)"a"};
|
||||||
|
static const WS_XML_STRING localname = {3, (BYTE *)"nil"};
|
||||||
|
static const WS_XML_STRING ns = {41, (BYTE *)"http://www.w3.org/2001/XMLSchema-instance"};
|
||||||
|
static const WS_XML_UTF8_TEXT value = {{WS_XML_TEXT_TYPE_UTF8}, {4, (BYTE *)"true"}};
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if ((hr = write_add_attribute( writer, &prefix, &localname, &ns, FALSE )) != S_OK) return hr;
|
||||||
|
if ((hr = write_set_attribute_value( writer, &value.text )) != S_OK) return hr;
|
||||||
|
return write_add_namespace_attribute( writer, &prefix, &ns, FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT write_type( struct writer *, WS_TYPE_MAPPING, WS_TYPE, const void *, WS_WRITE_OPTION,
|
static HRESULT write_type( struct writer *, WS_TYPE_MAPPING, WS_TYPE, const void *, WS_WRITE_OPTION,
|
||||||
const void *, ULONG );
|
const void *, ULONG );
|
||||||
|
|
||||||
|
@ -1574,14 +1594,33 @@ static HRESULT write_type_struct_field( struct writer *writer, const WS_FIELD_DE
|
||||||
WS_TYPE_MAPPING mapping;
|
WS_TYPE_MAPPING mapping;
|
||||||
WS_WRITE_OPTION option;
|
WS_WRITE_OPTION option;
|
||||||
|
|
||||||
if (!desc->options || desc->options == WS_FIELD_OPTIONAL) option = 0;
|
if (desc->options & ~(WS_FIELD_POINTER|WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE))
|
||||||
else if (desc->options == WS_FIELD_POINTER) option = WS_WRITE_REQUIRED_POINTER;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
FIXME( "options 0x%x not supported\n", desc->options );
|
FIXME( "options 0x%x not supported\n", desc->options );
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_nil_value( value, size ))
|
||||||
|
{
|
||||||
|
if (desc->options & WS_FIELD_NILLABLE)
|
||||||
|
{
|
||||||
|
if (desc->options & WS_FIELD_POINTER)
|
||||||
|
option = WS_WRITE_NILLABLE_POINTER;
|
||||||
|
else
|
||||||
|
option = WS_WRITE_NILLABLE_VALUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (desc->options & WS_FIELD_OPTIONAL) return S_OK;
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (desc->options & WS_FIELD_POINTER) option = WS_WRITE_REQUIRED_POINTER;
|
||||||
|
else option = 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch (desc->mapping)
|
switch (desc->mapping)
|
||||||
{
|
{
|
||||||
case WS_ATTRIBUTE_FIELD_MAPPING:
|
case WS_ATTRIBUTE_FIELD_MAPPING:
|
||||||
|
@ -1595,6 +1634,10 @@ static HRESULT write_type_struct_field( struct writer *writer, const WS_FIELD_DE
|
||||||
|
|
||||||
case WS_ELEMENT_FIELD_MAPPING:
|
case WS_ELEMENT_FIELD_MAPPING:
|
||||||
if ((hr = write_element_node( writer, NULL, desc->localName, desc->ns )) != S_OK) return hr;
|
if ((hr = write_element_node( writer, NULL, desc->localName, desc->ns )) != S_OK) return hr;
|
||||||
|
if (option == WS_WRITE_NILLABLE_VALUE || option == WS_WRITE_NILLABLE_POINTER)
|
||||||
|
{
|
||||||
|
if ((hr = write_add_nil_attribute( writer )) != S_OK) return hr;
|
||||||
|
}
|
||||||
mapping = WS_ELEMENT_TYPE_MAPPING;
|
mapping = WS_ELEMENT_TYPE_MAPPING;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1620,8 +1663,11 @@ static HRESULT write_type_struct_field( struct writer *writer, const WS_FIELD_DE
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hr = write_type( writer, mapping, desc->type, desc->typeDescription, option, value, size )) != S_OK)
|
if (option != WS_WRITE_NILLABLE_VALUE && option != WS_WRITE_NILLABLE_POINTER)
|
||||||
return hr;
|
{
|
||||||
|
if ((hr = write_type( writer, mapping, desc->type, desc->typeDescription, option, value, size )) != S_OK)
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
switch (mapping)
|
switch (mapping)
|
||||||
{
|
{
|
||||||
|
@ -1670,11 +1716,13 @@ static HRESULT get_value_ptr( WS_WRITE_OPTION option, const void *value, ULONG s
|
||||||
switch (option)
|
switch (option)
|
||||||
{
|
{
|
||||||
case WS_WRITE_REQUIRED_VALUE:
|
case WS_WRITE_REQUIRED_VALUE:
|
||||||
|
case WS_WRITE_NILLABLE_VALUE:
|
||||||
if (!value || !size) return E_INVALIDARG;
|
if (!value || !size) return E_INVALIDARG;
|
||||||
*ptr = value;
|
*ptr = value;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
case WS_WRITE_REQUIRED_POINTER:
|
case WS_WRITE_REQUIRED_POINTER:
|
||||||
|
case WS_WRITE_NILLABLE_POINTER:
|
||||||
if (size != sizeof(const void *) || !(*ptr = *(const void **)value)) return E_INVALIDARG;
|
if (size != sizeof(const void *) || !(*ptr = *(const void **)value)) return E_INVALIDARG;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue