mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 11:26:10 +00:00
webservices: Add support for element and text field mappings 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
0fd7bb5389
commit
bf74c6a5dd
2 changed files with 152 additions and 86 deletions
|
@ -1306,6 +1306,101 @@ static void test_WsGetPrefixFromNamespace(void)
|
|||
WsFreeWriter( writer );
|
||||
}
|
||||
|
||||
static void test_complex_struct_type(void)
|
||||
{
|
||||
static const char expected[] =
|
||||
"<o:OfficeConfig xmlns:o=\"urn:schemas-microsoft-com:office:office\">"
|
||||
"<o:services o:GenerationTime=\"2015-09-03T18:47:54\"/>"
|
||||
"</o:OfficeConfig>";
|
||||
static const WCHAR timestampW[] =
|
||||
{'2','0','1','5','-','0','9','-','0','3','T','1','8',':','4','7',':','5','4',0};
|
||||
WS_XML_STRING str_officeconfig = {12, (BYTE *)"OfficeConfig"};
|
||||
WS_XML_STRING str_services = {8, (BYTE *)"services"};
|
||||
WS_XML_STRING str_generationtime = {14, (BYTE *)"GenerationTime"};
|
||||
WS_XML_STRING ns = {39, (BYTE *)"urn:schemas-microsoft-com:office:office"};
|
||||
WS_XML_STRING prefix = {1, (BYTE *)"o"};
|
||||
DWORD size;
|
||||
HRESULT hr;
|
||||
WS_HEAP *heap;
|
||||
WS_XML_BUFFER *buffer;
|
||||
WS_XML_WRITER *writer;
|
||||
WS_STRUCT_DESCRIPTION s, s2;
|
||||
WS_FIELD_DESCRIPTION f, f2, *fields[1], *fields2[1];
|
||||
struct services
|
||||
{
|
||||
const WCHAR *generationtime;
|
||||
};
|
||||
struct officeconfig
|
||||
{
|
||||
struct services *services;
|
||||
} *test;
|
||||
|
||||
hr = WsCreateWriter( NULL, 0, &writer, NULL ) ;
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = WsWriteStartElement( writer, &prefix, &str_officeconfig, &ns, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
memset( &f2, 0, sizeof(f2) );
|
||||
f2.mapping = WS_ATTRIBUTE_FIELD_MAPPING;
|
||||
f2.localName = &str_generationtime;
|
||||
f2.ns = &ns;
|
||||
f2.type = WS_WSZ_TYPE;
|
||||
f2.options = WS_FIELD_OPTIONAL;
|
||||
fields2[0] = &f2;
|
||||
|
||||
memset( &s2, 0, sizeof(s2) );
|
||||
s2.size = sizeof(*test->services);
|
||||
s2.alignment = 4;
|
||||
s2.fields = fields2;
|
||||
s2.fieldCount = 1;
|
||||
s2.typeLocalName = &str_services;
|
||||
s2.typeNs = &ns;
|
||||
|
||||
memset( &f, 0, sizeof(f) );
|
||||
f.mapping = WS_ELEMENT_FIELD_MAPPING;
|
||||
f.localName = &str_services;
|
||||
f.ns = &ns;
|
||||
f.type = WS_STRUCT_TYPE;
|
||||
f.typeDescription = &s2;
|
||||
f.options = WS_FIELD_POINTER;
|
||||
fields[0] = &f;
|
||||
|
||||
memset( &s, 0, sizeof(s) );
|
||||
s.size = sizeof(*test);
|
||||
s.alignment = 4;
|
||||
s.fields = fields;
|
||||
s.fieldCount = 1;
|
||||
s.typeLocalName = &str_officeconfig;
|
||||
s.typeNs = &ns;
|
||||
|
||||
size = sizeof(struct officeconfig) + sizeof(struct services);
|
||||
test = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
|
||||
test->services = (struct services *)(test + 1);
|
||||
test->services->generationtime = timestampW;
|
||||
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_buffer( buffer, expected, __LINE__ );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, test );
|
||||
WsFreeWriter( writer );
|
||||
WsFreeHeap( heap );
|
||||
}
|
||||
|
||||
|
||||
START_TEST(writer)
|
||||
{
|
||||
test_WsCreateWriter();
|
||||
|
@ -1323,4 +1418,5 @@ START_TEST(writer)
|
|||
test_WsWriteStartCData();
|
||||
test_WsWriteXmlnsAttribute();
|
||||
test_WsGetPrefixFromNamespace();
|
||||
test_complex_struct_type();
|
||||
}
|
||||
|
|
|
@ -714,7 +714,6 @@ HRESULT WINAPI WsWriteEndAttribute( WS_XML_WRITER *handle, WS_ERROR *error )
|
|||
if (error) FIXME( "ignoring error parameter\n" );
|
||||
|
||||
if (!writer) return E_INVALIDARG;
|
||||
if (writer->state != WRITER_STATE_STARTATTRIBUTE) return WS_E_INVALID_OPERATION;
|
||||
|
||||
writer->state = WRITER_STATE_STARTELEMENT;
|
||||
return S_OK;
|
||||
|
@ -1115,7 +1114,6 @@ static HRESULT write_type_text( struct writer *writer, WS_TYPE_MAPPING mapping,
|
|||
{
|
||||
case WRITER_STATE_STARTATTRIBUTE:
|
||||
write_set_attribute_value( writer, text );
|
||||
writer->state = WRITER_STATE_STARTELEMENT;
|
||||
return S_OK;
|
||||
|
||||
case WRITER_STATE_STARTELEMENT:
|
||||
|
@ -1304,17 +1302,19 @@ 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 writer *, WS_TYPE_MAPPING, WS_TYPE, const void *, WS_WRITE_OPTION,
|
||||
const void *, ULONG );
|
||||
|
||||
static HRESULT write_type_struct_field( struct writer *writer, WS_TYPE_MAPPING mapping,
|
||||
const WS_FIELD_DESCRIPTION *desc, const void *value )
|
||||
static HRESULT write_type_struct_field( struct writer *writer, const WS_FIELD_DESCRIPTION *desc,
|
||||
const void *value, ULONG size )
|
||||
{
|
||||
HRESULT hr;
|
||||
WS_TYPE_MAPPING mapping;
|
||||
WS_WRITE_OPTION option;
|
||||
|
||||
if (desc->options && desc->options != WS_FIELD_POINTER &&
|
||||
desc->options != WS_FIELD_OPTIONAL &&
|
||||
desc->options != (WS_FIELD_POINTER | WS_FIELD_OPTIONAL))
|
||||
if (!desc->options || desc->options == WS_FIELD_OPTIONAL) option = 0;
|
||||
else if (desc->options == WS_FIELD_POINTER) option = WS_WRITE_REQUIRED_POINTER;
|
||||
else
|
||||
{
|
||||
FIXME( "options 0x%x not supported\n", desc->options );
|
||||
return E_NOTIMPL;
|
||||
|
@ -1326,9 +1326,32 @@ static HRESULT write_type_struct_field( struct writer *writer, WS_TYPE_MAPPING m
|
|||
if (!desc->localName || !desc->ns) return E_INVALIDARG;
|
||||
if ((hr = write_add_attribute( writer, NULL, desc->localName, desc->ns, FALSE )) != S_OK)
|
||||
return hr;
|
||||
|
||||
mapping = WS_ATTRIBUTE_TYPE_MAPPING;
|
||||
break;
|
||||
|
||||
case WS_ELEMENT_FIELD_MAPPING:
|
||||
if ((hr = write_add_element_node( writer, NULL, desc->localName, desc->ns )) != S_OK)
|
||||
return hr;
|
||||
|
||||
mapping = WS_ELEMENT_TYPE_MAPPING;
|
||||
break;
|
||||
|
||||
case WS_TEXT_FIELD_MAPPING:
|
||||
switch (writer->state)
|
||||
{
|
||||
case WRITER_STATE_STARTELEMENT:
|
||||
mapping = WS_ELEMENT_CONTENT_TYPE_MAPPING;
|
||||
break;
|
||||
|
||||
case WRITER_STATE_STARTATTRIBUTE:
|
||||
mapping = WS_ATTRIBUTE_TYPE_MAPPING;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME( "unhandled writer state %u\n", writer->state );
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1336,86 +1359,35 @@ static HRESULT write_type_struct_field( struct writer *writer, WS_TYPE_MAPPING m
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
switch (desc->type)
|
||||
if ((hr = write_type( writer, mapping, desc->type, desc->typeDescription, option, value, size )) != S_OK)
|
||||
return hr;
|
||||
|
||||
switch (mapping)
|
||||
{
|
||||
case WS_STRUCT_TYPE:
|
||||
{
|
||||
const void * const *ptr = value;
|
||||
if ((hr = write_type_struct( writer, mapping, desc->typeDescription, *ptr )) != S_OK) return hr;
|
||||
case WS_ATTRIBUTE_TYPE_MAPPING:
|
||||
writer->state = WRITER_STATE_STARTELEMENT;
|
||||
break;
|
||||
}
|
||||
case WS_BOOL_TYPE:
|
||||
{
|
||||
const BOOL *ptr = value;
|
||||
if ((hr = write_type_bool( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr;
|
||||
|
||||
case WS_ELEMENT_TYPE_MAPPING:
|
||||
if ((hr = write_close_element( writer )) != 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;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG get_field_size( const WS_STRUCT_DESCRIPTION *desc, ULONG index )
|
||||
{
|
||||
if (index < desc->fieldCount - 1) return desc->fields[index + 1]->offset - desc->fields[index]->offset;
|
||||
return desc->size - desc->fields[index]->offset;
|
||||
}
|
||||
|
||||
static HRESULT write_type_struct( struct writer *writer, WS_TYPE_MAPPING mapping,
|
||||
const WS_STRUCT_DESCRIPTION *desc, const void *value )
|
||||
{
|
||||
ULONG i;
|
||||
ULONG i, size;
|
||||
HRESULT hr;
|
||||
const char *ptr;
|
||||
|
||||
|
@ -1430,7 +1402,8 @@ static HRESULT write_type_struct( struct writer *writer, WS_TYPE_MAPPING mapping
|
|||
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)
|
||||
size = get_field_size( desc, i );
|
||||
if ((hr = write_type_struct_field( writer, desc->fields[i], ptr, size )) != S_OK)
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -1447,7 +1420,7 @@ static HRESULT write_type( struct writer *writer, WS_TYPE_MAPPING mapping, WS_TY
|
|||
{
|
||||
const void * const *ptr = value;
|
||||
|
||||
if (!desc || option != WS_WRITE_REQUIRED_POINTER || size != sizeof(*ptr))
|
||||
if (!desc || (option && option != WS_WRITE_REQUIRED_POINTER) || size != sizeof(*ptr))
|
||||
return E_INVALIDARG;
|
||||
|
||||
return write_type_struct( writer, mapping, desc, *ptr );
|
||||
|
@ -1509,7 +1482,7 @@ static HRESULT write_type( struct writer *writer, WS_TYPE_MAPPING mapping, WS_TY
|
|||
case WS_WSZ_TYPE:
|
||||
{
|
||||
const WCHAR * const *ptr = value;
|
||||
if (option != WS_WRITE_REQUIRED_POINTER || size != sizeof(*ptr)) return E_INVALIDARG;
|
||||
if ((option && option != WS_WRITE_REQUIRED_POINTER) || size != sizeof(*ptr)) return E_INVALIDARG;
|
||||
return write_type_wsz( writer, mapping, desc, *ptr );
|
||||
}
|
||||
default:
|
||||
|
@ -1539,11 +1512,8 @@ HRESULT WINAPI WsWriteAttribute( WS_XML_WRITER *handle, const WS_ATTRIBUTE_DESCR
|
|||
if ((hr = write_add_attribute( writer, NULL, desc->attributeLocalName, desc->attributeNs,
|
||||
FALSE )) != S_OK) return hr;
|
||||
|
||||
if ((hr = write_type( writer, WS_ATTRIBUTE_TYPE_MAPPING, desc->type, desc->typeDescription,
|
||||
option, value, size )) != S_OK) return hr;
|
||||
|
||||
writer->state = WRITER_STATE_STARTELEMENT;
|
||||
return S_OK;
|
||||
return write_type( writer, WS_ATTRIBUTE_TYPE_MAPPING, desc->type, desc->typeDescription,
|
||||
option, value, size );
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
|
Loading…
Reference in a new issue