webservices: Add support for structure types in WsWriteType.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
93988c5039
commit
98d19212e7
|
@ -636,6 +636,91 @@ static void test_basic_type(void)
|
|||
WsFreeWriter( writer );
|
||||
}
|
||||
|
||||
static void test_simple_struct_type(void)
|
||||
{
|
||||
static const WCHAR valueW[] = {'v','a','l','u','e',0};
|
||||
HRESULT hr;
|
||||
WS_XML_WRITER *writer;
|
||||
WS_STRUCT_DESCRIPTION s;
|
||||
WS_FIELD_DESCRIPTION f, *fields[1];
|
||||
WS_XML_STRING localname = {6, (BYTE *)"struct"}, ns = {0, NULL};
|
||||
struct test
|
||||
{
|
||||
const WCHAR *field;
|
||||
} *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_TEXT_FIELD_MAPPING;
|
||||
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;
|
||||
|
||||
test = HeapAlloc( GetProcessHeap(), 0, sizeof(*test) );
|
||||
test->field = valueW;
|
||||
hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL,
|
||||
WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL );
|
||||
ok( hr == E_INVALIDARG, "got %08x\n", hr );
|
||||
|
||||
hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
|
||||
WS_WRITE_REQUIRED_POINTER, &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, "<struct>value</struct>", __LINE__ );
|
||||
|
||||
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 );
|
||||
|
||||
hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
|
||||
WS_WRITE_REQUIRED_POINTER, &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, "<struct>value</struct>", __LINE__ );
|
||||
|
||||
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 );
|
||||
|
||||
hr = WsWriteStartAttribute( writer, NULL, &localname, &ns, FALSE, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsWriteType( writer, WS_ATTRIBUTE_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
|
||||
WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsWriteEndAttribute( writer, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsWriteEndElement( writer, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
check_output( writer, "<struct struct=\"value\"/>", __LINE__ );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, test );
|
||||
WsFreeWriter( writer );
|
||||
}
|
||||
|
||||
START_TEST(writer)
|
||||
{
|
||||
test_WsCreateWriter();
|
||||
|
@ -646,4 +731,5 @@ START_TEST(writer)
|
|||
test_WsWriteStartAttribute();
|
||||
test_WsWriteType();
|
||||
test_basic_type();
|
||||
test_simple_struct_type();
|
||||
}
|
||||
|
|
|
@ -1113,12 +1113,138 @@ static HRESULT write_type_wsz( struct writer *writer, WS_TYPE_MAPPING mapping,
|
|||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT write_type_struct( struct writer *, WS_TYPE_MAPPING, const WS_STRUCT_DESCRIPTION *,
|
||||
const void * );
|
||||
|
||||
static HRESULT write_type_struct_field( struct writer *writer, WS_TYPE_MAPPING mapping,
|
||||
const WS_FIELD_DESCRIPTION *desc, const void *value )
|
||||
{
|
||||
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->type)
|
||||
{
|
||||
case WS_STRUCT_TYPE:
|
||||
{
|
||||
const void * const *ptr = value;
|
||||
if ((hr = write_type_struct( writer, mapping, desc->typeDescription, *ptr )) != S_OK) return hr;
|
||||
break;
|
||||
}
|
||||
case WS_BOOL_TYPE:
|
||||
{
|
||||
const BOOL *ptr = value;
|
||||
if ((hr = write_type_bool( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
|
||||
break;
|
||||
}
|
||||
case WS_INT8_TYPE:
|
||||
{
|
||||
const INT8 *ptr = value;
|
||||
if ((hr = write_type_int8( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
|
||||
break;
|
||||
}
|
||||
case WS_INT16_TYPE:
|
||||
{
|
||||
const INT16 *ptr = value;
|
||||
if ((hr = write_type_int16( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
|
||||
break;
|
||||
}
|
||||
case WS_INT32_TYPE:
|
||||
{
|
||||
const INT32 *ptr = value;
|
||||
if ((hr = write_type_int32( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
|
||||
break;
|
||||
}
|
||||
case WS_INT64_TYPE:
|
||||
{
|
||||
const INT64 *ptr = value;
|
||||
if ((hr = write_type_int64( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
|
||||
break;
|
||||
}
|
||||
case WS_UINT8_TYPE:
|
||||
{
|
||||
const UINT8 *ptr = value;
|
||||
if ((hr = write_type_uint8( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
|
||||
break;
|
||||
}
|
||||
case WS_UINT16_TYPE:
|
||||
{
|
||||
const UINT16 *ptr = value;
|
||||
if ((hr = write_type_uint16( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
|
||||
break;
|
||||
}
|
||||
case WS_UINT32_TYPE:
|
||||
{
|
||||
const UINT32 *ptr = value;
|
||||
if ((hr = write_type_uint32( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
|
||||
break;
|
||||
}
|
||||
case WS_UINT64_TYPE:
|
||||
{
|
||||
const UINT64 *ptr = value;
|
||||
if ((hr = write_type_uint64( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
|
||||
break;
|
||||
}
|
||||
case WS_WSZ_TYPE:
|
||||
{
|
||||
const WCHAR * const *ptr = value;
|
||||
if ((hr = write_type_wsz( writer, mapping, desc->typeDescription, *ptr )) != S_OK) return hr;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME( "type %u not implemented\n", desc->type );
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT write_type_struct( struct writer *writer, WS_TYPE_MAPPING mapping,
|
||||
const WS_STRUCT_DESCRIPTION *desc, const void *value )
|
||||
{
|
||||
ULONG i;
|
||||
HRESULT hr;
|
||||
const char *ptr;
|
||||
|
||||
if (!desc) return E_INVALIDARG;
|
||||
|
||||
if (desc->structOptions)
|
||||
{
|
||||
FIXME( "struct options 0x%x not supported\n", desc->structOptions );
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
for (i = 0; i < desc->fieldCount; i++)
|
||||
{
|
||||
ptr = (const char *)value + desc->fields[i]->offset;
|
||||
if ((hr = write_type_struct_field( writer, mapping, desc->fields[i], ptr )) != S_OK)
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT write_type( struct writer *writer, WS_TYPE_MAPPING mapping, WS_TYPE type,
|
||||
const void *desc, WS_WRITE_OPTION option, const void *value,
|
||||
ULONG size )
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case WS_STRUCT_TYPE:
|
||||
{
|
||||
const void * const *ptr = value;
|
||||
|
||||
if (!desc || option != WS_WRITE_REQUIRED_POINTER || size != sizeof(*ptr))
|
||||
return E_INVALIDARG;
|
||||
|
||||
return write_type_struct( writer, mapping, desc, *ptr );
|
||||
}
|
||||
case WS_BOOL_TYPE:
|
||||
{
|
||||
const BOOL *ptr = value;
|
||||
|
|
Loading…
Reference in New Issue