Commit 24d39bc3 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

webservices: Add initial support for binary XML in the writer.

parent da030566
......@@ -3420,6 +3420,51 @@ static void test_WsWriteCharsUtf8(void)
WsFreeWriter( writer );
}
static void test_binary_encoding(void)
{
static const char res[] = {0x40,0x01,'t',0x01,0};
WS_XML_WRITER_BINARY_ENCODING bin = {{WS_XML_WRITER_ENCODING_TYPE_BINARY}};
WS_XML_WRITER_BUFFER_OUTPUT buf = {{WS_XML_WRITER_OUTPUT_TYPE_BUFFER}};
static const char localname[] = "t", empty[] = "";
const WS_XML_STRING *prefix_ptr, *localname_ptr, *ns_ptr;
WS_XML_STRING str, str2, str3;
WS_XML_WRITER *writer;
HRESULT hr;
ULONG i;
static const struct
{
const char *prefix;
const char *localname;
const char *ns;
const char *result;
}
elem_tests[] =
{
{ NULL, localname, empty, res }, /* short element */
};
hr = WsCreateWriter( NULL, 0, &writer, NULL );
ok( hr == S_OK, "got %08x\n", hr );
for (i = 0; i < sizeof(elem_tests)/sizeof(elem_tests[0]); i++)
{
hr = WsSetOutput( writer, &bin.encoding, &buf.output, NULL, 0, NULL );
ok( hr == S_OK, "%u: got %08x\n", i, hr );
prefix_ptr = init_xmlstring( elem_tests[i].prefix, &str );
localname_ptr = init_xmlstring( elem_tests[i].localname, &str2 );
ns_ptr = init_xmlstring( elem_tests[i].ns, &str3 );
hr = WsWriteStartElement( writer, prefix_ptr, localname_ptr, ns_ptr, NULL );
ok( hr == S_OK, "%u: got %08x\n", i, hr );
hr = WsWriteEndElement( writer, NULL );
ok( hr == S_OK, "%u: got %08x\n", i, hr );
if (hr == S_OK) check_output( writer, elem_tests[i].result, __LINE__ );
}
WsFreeWriter( writer );
}
START_TEST(writer)
{
test_WsCreateWriter();
......@@ -3457,4 +3502,5 @@ START_TEST(writer)
test_WsWriteBytes();
test_WsWriteChars();
test_WsWriteCharsUtf8();
test_binary_encoding();
}
......@@ -79,6 +79,7 @@ struct writer
struct node *root;
struct node *current;
WS_XML_STRING *current_ns;
WS_XML_WRITER_ENCODING_TYPE output_enc;
WS_XML_WRITER_OUTPUT_TYPE output_type;
struct xmlbuf *output_buf;
WS_HEAP *output_heap;
......@@ -162,6 +163,7 @@ static HRESULT init_writer( struct writer *writer )
if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
write_insert_eof( writer, node );
writer->state = WRITER_STATE_INITIAL;
writer->output_enc = WS_XML_WRITER_ENCODING_TYPE_TEXT;
return S_OK;
}
......@@ -372,6 +374,12 @@ HRESULT WINAPI WsSetOutput( WS_XML_WRITER *handle, const WS_XML_WRITER_ENCODING
hr = E_NOTIMPL;
goto done;
}
writer->output_enc = WS_XML_WRITER_ENCODING_TYPE_TEXT;
break;
}
case WS_XML_WRITER_ENCODING_TYPE_BINARY:
{
writer->output_enc = WS_XML_WRITER_ENCODING_TYPE_BINARY;
break;
}
default:
......@@ -737,9 +745,9 @@ HRESULT WINAPI WsWriteEndAttribute( WS_XML_WRITER *handle, WS_ERROR *error )
return S_OK;
}
static HRESULT write_startelement( struct writer *writer )
static HRESULT write_startelement_text( struct writer *writer )
{
WS_XML_ELEMENT_NODE *elem = &writer->current->hdr;
const WS_XML_ELEMENT_NODE *elem = &writer->current->hdr;
ULONG size, i;
HRESULT hr;
......@@ -774,6 +782,114 @@ static HRESULT write_startelement( struct writer *writer )
return S_OK;
}
static enum record_type get_elem_record_type( const WS_XML_ELEMENT_NODE *elem )
{
if (!elem->prefix || !elem->prefix->length) return RECORD_SHORT_ELEMENT;
if (elem->prefix->length == 1 && elem->prefix->bytes[0] >= 'a' && elem->prefix->bytes[0] <= 'z')
{
return RECORD_PREFIX_ELEMENT_A + elem->prefix->bytes[0] - 'a';
}
return RECORD_ELEMENT;
};
static HRESULT write_int31( struct writer *writer, ULONG len )
{
HRESULT hr;
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
if (len < 0x80)
{
write_char( writer, len );
return S_OK;
}
write_char( writer, (len & 0x7f) | 0x80 );
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
if ((len >>= 7) < 0x80)
{
write_char( writer, len );
return S_OK;
}
write_char( writer, (len & 0x7f) | 0x80 );
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
if ((len >>= 7) < 0x80)
{
write_char( writer, len );
return S_OK;
}
write_char( writer, (len & 0x7f) | 0x80 );
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
if ((len >>= 7) < 0x80)
{
write_char( writer, len );
return S_OK;
}
write_char( writer, (len & 0x7f) | 0x80 );
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
if ((len >>= 7) < 0x08)
{
write_char( writer, len );
return S_OK;
}
return WS_E_INVALID_FORMAT;
}
static HRESULT write_string( struct writer *writer, const BYTE *bytes, ULONG len )
{
HRESULT hr;
if ((hr = write_int31( writer, len )) != S_OK) return hr;
if ((hr = write_grow_buffer( writer, len )) != S_OK) return hr;
write_bytes( writer, bytes, len );
return S_OK;
}
static HRESULT write_startelement_bin( struct writer *writer )
{
const WS_XML_ELEMENT_NODE *elem = &writer->current->hdr;
enum record_type type = get_elem_record_type( elem );
HRESULT hr;
if (type >= RECORD_PREFIX_ELEMENT_A && type <= RECORD_PREFIX_ELEMENT_Z)
{
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
write_char( writer, type );
return write_string( writer, elem->localName->bytes, elem->localName->length );
}
switch (type)
{
case RECORD_SHORT_ELEMENT:
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
write_char( writer, type );
return write_string( writer, elem->localName->bytes, elem->localName->length );
case RECORD_ELEMENT:
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
write_char( writer, type );
if ((hr = write_string( writer, elem->prefix->bytes, elem->prefix->length )) != S_OK) return hr;
return write_string( writer, elem->localName->bytes, elem->localName->length );
default:
FIXME( "unhandled record type %u\n", type );
return WS_E_NOT_SUPPORTED;
}
}
static HRESULT write_startelement( struct writer *writer )
{
switch (writer->output_enc)
{
case WS_XML_WRITER_ENCODING_TYPE_TEXT: return write_startelement_text( writer );
case WS_XML_WRITER_ENCODING_TYPE_BINARY: return write_startelement_bin( writer );
default:
ERR( "unhandled encoding %u\n", writer->output_enc );
return WS_E_NOT_SUPPORTED;
}
}
static struct node *write_find_startelement( struct writer *writer )
{
struct node *node;
......@@ -790,7 +906,7 @@ static inline BOOL is_empty_element( const struct node *node )
return node_type( head ) == WS_XML_NODE_TYPE_END_ELEMENT;
}
static HRESULT write_endelement( struct writer *writer, const WS_XML_ELEMENT_NODE *elem )
static HRESULT write_endelement_text( struct writer *writer, const WS_XML_ELEMENT_NODE *elem )
{
ULONG size;
HRESULT hr;
......@@ -823,6 +939,26 @@ static HRESULT write_endelement( struct writer *writer, const WS_XML_ELEMENT_NOD
return S_OK;
}
static HRESULT write_endelement_bin( struct writer *writer )
{
HRESULT hr;
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
write_char( writer, RECORD_ENDELEMENT );
return S_OK;
}
static HRESULT write_endelement( struct writer *writer, const WS_XML_ELEMENT_NODE *elem )
{
switch (writer->output_enc)
{
case WS_XML_WRITER_ENCODING_TYPE_TEXT: return write_endelement_text( writer, elem );
case WS_XML_WRITER_ENCODING_TYPE_BINARY: return write_endelement_bin( writer );
default:
ERR( "unhandled encoding %u\n", writer->output_enc );
return WS_E_NOT_SUPPORTED;
}
}
static HRESULT write_close_element( struct writer *writer, struct node *node )
{
WS_XML_ELEMENT_NODE *elem = &node->hdr;
......@@ -874,7 +1010,7 @@ HRESULT WINAPI WsWriteEndElement( WS_XML_WRITER *handle, WS_ERROR *error )
return hr;
}
static HRESULT write_endstartelement( struct writer *writer )
static HRESULT write_endstartelement_text( struct writer *writer )
{
HRESULT hr;
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
......@@ -882,6 +1018,18 @@ static HRESULT write_endstartelement( struct writer *writer )
return S_OK;
}
static HRESULT write_endstartelement( struct writer *writer )
{
switch (writer->output_enc)
{
case WS_XML_WRITER_ENCODING_TYPE_TEXT: return write_endstartelement_text( writer );
case WS_XML_WRITER_ENCODING_TYPE_BINARY: return S_OK;
default:
ERR( "unhandled encoding %u\n", writer->output_enc );
return WS_E_NOT_SUPPORTED;
}
}
/**************************************************************************
* WsWriteEndStartElement [webservices.@]
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment