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) ...@@ -3420,6 +3420,51 @@ static void test_WsWriteCharsUtf8(void)
WsFreeWriter( writer ); 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) START_TEST(writer)
{ {
test_WsCreateWriter(); test_WsCreateWriter();
...@@ -3457,4 +3502,5 @@ START_TEST(writer) ...@@ -3457,4 +3502,5 @@ START_TEST(writer)
test_WsWriteBytes(); test_WsWriteBytes();
test_WsWriteChars(); test_WsWriteChars();
test_WsWriteCharsUtf8(); test_WsWriteCharsUtf8();
test_binary_encoding();
} }
...@@ -122,6 +122,194 @@ HRESULT channel_get_reader( WS_CHANNEL *, WS_XML_READER ** ) DECLSPEC_HIDDEN; ...@@ -122,6 +122,194 @@ HRESULT channel_get_reader( WS_CHANNEL *, WS_XML_READER ** ) DECLSPEC_HIDDEN;
HRESULT parse_url( const WS_STRING *, WS_URL_SCHEME_TYPE *, WCHAR **, USHORT * ) DECLSPEC_HIDDEN; HRESULT parse_url( const WS_STRING *, WS_URL_SCHEME_TYPE *, WCHAR **, USHORT * ) DECLSPEC_HIDDEN;
enum record_type
{
/* 0x00 reserved */
RECORD_ENDELEMENT = 0x01,
RECORD_COMMENT = 0x02,
RECORD_ARRAY = 0x03,
RECORD_SHORT_ATTRIBUTE = 0x04,
RECORD_ATTRIBUTE = 0x05,
RECORD_SHORT_DICTIONARY_ATTRIBUTE = 0x06,
RECORD_DICTIONARY_ATTRIBUTE = 0x07,
RECORD_SHORT_XMLNS_ATTRIBUTE = 0x08,
RECORD_XMLNS_ATTRIBUTE = 0x09,
RECORD_SHORT_DICTIONARY_XMLNS_ATTRIBUTE = 0x0a,
RECORD_DICTIONARY_XMLNS_ATTRIBUTE = 0x0b,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_A = 0x0c,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_B = 0x0d,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_C = 0x0e,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_D = 0x0f,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_E = 0x10,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_F = 0x11,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_G = 0x12,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_H = 0x13,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_I = 0x14,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_J = 0x15,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_K = 0x16,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_L = 0x17,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_M = 0x18,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_N = 0x19,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_O = 0x1a,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_P = 0x1b,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_Q = 0x1c,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_R = 0x1d,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_S = 0x1e,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_T = 0x1f,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_U = 0x20,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_V = 0x21,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_W = 0x22,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_X = 0x23,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_Y = 0x24,
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_Z = 0x25,
RECORD_PREFIX_ATTRIBUTE_A = 0x26,
RECORD_PREFIX_ATTRIBUTE_B = 0x27,
RECORD_PREFIX_ATTRIBUTE_C = 0x28,
RECORD_PREFIX_ATTRIBUTE_D = 0x29,
RECORD_PREFIX_ATTRIBUTE_E = 0x2a,
RECORD_PREFIX_ATTRIBUTE_F = 0x2b,
RECORD_PREFIX_ATTRIBUTE_G = 0x2c,
RECORD_PREFIX_ATTRIBUTE_H = 0x2d,
RECORD_PREFIX_ATTRIBUTE_I = 0x2e,
RECORD_PREFIX_ATTRIBUTE_J = 0x2f,
RECORD_PREFIX_ATTRIBUTE_K = 0x30,
RECORD_PREFIX_ATTRIBUTE_L = 0x31,
RECORD_PREFIX_ATTRIBUTE_M = 0x32,
RECORD_PREFIX_ATTRIBUTE_N = 0x33,
RECORD_PREFIX_ATTRIBUTE_O = 0x34,
RECORD_PREFIX_ATTRIBUTE_P = 0x35,
RECORD_PREFIX_ATTRIBUTE_Q = 0x36,
RECORD_PREFIX_ATTRIBUTE_R = 0x37,
RECORD_PREFIX_ATTRIBUTE_S = 0x38,
RECORD_PREFIX_ATTRIBUTE_T = 0x39,
RECORD_PREFIX_ATTRIBUTE_U = 0x3a,
RECORD_PREFIX_ATTRIBUTE_V = 0x3b,
RECORD_PREFIX_ATTRIBUTE_W = 0x3c,
RECORD_PREFIX_ATTRIBUTE_X = 0x3d,
RECORD_PREFIX_ATTRIBUTE_Y = 0x3e,
RECORD_PREFIX_ATTRIBUTE_Z = 0x3f,
RECORD_SHORT_ELEMENT = 0x40,
RECORD_ELEMENT = 0x41,
RECORD_SHORT_DICTIONARY_ELEMENT = 0x42,
RECORD_DICTIONARY_ELEMENT = 0x43,
RECORD_PREFIX_DICTIONARY_ELEMENT_A = 0x44,
RECORD_PREFIX_DICTIONARY_ELEMENT_B = 0x45,
RECORD_PREFIX_DICTIONARY_ELEMENT_C = 0x46,
RECORD_PREFIX_DICTIONARY_ELEMENT_D = 0x47,
RECORD_PREFIX_DICTIONARY_ELEMENT_E = 0x48,
RECORD_PREFIX_DICTIONARY_ELEMENT_F = 0x49,
RECORD_PREFIX_DICTIONARY_ELEMENT_G = 0x4a,
RECORD_PREFIX_DICTIONARY_ELEMENT_H = 0x4b,
RECORD_PREFIX_DICTIONARY_ELEMENT_I = 0x4c,
RECORD_PREFIX_DICTIONARY_ELEMENT_J = 0x4d,
RECORD_PREFIX_DICTIONARY_ELEMENT_K = 0x4e,
RECORD_PREFIX_DICTIONARY_ELEMENT_L = 0x4f,
RECORD_PREFIX_DICTIONARY_ELEMENT_M = 0x50,
RECORD_PREFIX_DICTIONARY_ELEMENT_N = 0x51,
RECORD_PREFIX_DICTIONARY_ELEMENT_O = 0x52,
RECORD_PREFIX_DICTIONARY_ELEMENT_P = 0x53,
RECORD_PREFIX_DICTIONARY_ELEMENT_Q = 0x54,
RECORD_PREFIX_DICTIONARY_ELEMENT_R = 0x55,
RECORD_PREFIX_DICTIONARY_ELEMENT_S = 0x56,
RECORD_PREFIX_DICTIONARY_ELEMENT_T = 0x57,
RECORD_PREFIX_DICTIONARY_ELEMENT_U = 0x58,
RECORD_PREFIX_DICTIONARY_ELEMENT_V = 0x59,
RECORD_PREFIX_DICTIONARY_ELEMENT_W = 0x5a,
RECORD_PREFIX_DICTIONARY_ELEMENT_X = 0x5b,
RECORD_PREFIX_DICTIONARY_ELEMENT_Y = 0x5c,
RECORD_PREFIX_DICTIONARY_ELEMENT_Z = 0x5d,
RECORD_PREFIX_ELEMENT_A = 0x5e,
RECORD_PREFIX_ELEMENT_B = 0x5f,
RECORD_PREFIX_ELEMENT_C = 0x60,
RECORD_PREFIX_ELEMENT_D = 0x61,
RECORD_PREFIX_ELEMENT_E = 0x62,
RECORD_PREFIX_ELEMENT_F = 0x63,
RECORD_PREFIX_ELEMENT_G = 0x64,
RECORD_PREFIX_ELEMENT_H = 0x65,
RECORD_PREFIX_ELEMENT_I = 0x66,
RECORD_PREFIX_ELEMENT_J = 0x67,
RECORD_PREFIX_ELEMENT_K = 0x68,
RECORD_PREFIX_ELEMENT_L = 0x69,
RECORD_PREFIX_ELEMENT_M = 0x6a,
RECORD_PREFIX_ELEMENT_N = 0x6b,
RECORD_PREFIX_ELEMENT_O = 0x6c,
RECORD_PREFIX_ELEMENT_P = 0x6d,
RECORD_PREFIX_ELEMENT_Q = 0x6e,
RECORD_PREFIX_ELEMENT_R = 0x6f,
RECORD_PREFIX_ELEMENT_S = 0x70,
RECORD_PREFIX_ELEMENT_T = 0x71,
RECORD_PREFIX_ELEMENT_U = 0x72,
RECORD_PREFIX_ELEMENT_V = 0x73,
RECORD_PREFIX_ELEMENT_W = 0x74,
RECORD_PREFIX_ELEMENT_X = 0x75,
RECORD_PREFIX_ELEMENT_Y = 0x76,
RECORD_PREFIX_ELEMENT_Z = 0x77,
/* 0x78 ... 0x7f reserved */
RECORD_ZERO_TEXT = 0x80,
RECORD_ZERO_TEXT_WITH_ENDELEMENT = 0x81,
RECORD_ONE_TEXT = 0x82,
RECORD_ONE_TEXT_WITH_ENDELEMENT = 0x83,
RECORD_FALSE_TEXT = 0x84,
RECORD_FALSE_TEXT_WITH_ENDELEMENT = 0x85,
RECORD_TRUE_TEXT = 0x86,
RECORD_TRUE_TEXT_WITH_ENDELEMENT = 0x87,
RECORD_INT8_TEXT = 0x88,
RECORD_INT8_TEXT_WITH_ENDELEMENT = 0x89,
RECORD_INT16_TEXT = 0x8a,
RECORD_INT16_TEXT_WITH_ENDELEMENT = 0x8b,
RECORD_INT32_TEXT = 0x8c,
RECORD_INT32_TEXT_WITH_ENDELEMENT = 0x8d,
RECORD_INT64_TEXT = 0x8e,
RECORD_INT64_TEXT_WITH_ENDELEMENT = 0x8f,
RECORD_FLOAT_TEXT = 0x90,
RECORD_FLOAT_TEXT_WITH_ENDELEMENT = 0x91,
RECORD_DOUBLE_TEXT = 0x92,
RECORD_DOUBLE_TEXT_WITH_ENDELEMENT = 0x93,
RECORD_DECIMAL_TEXT = 0x94,
RECORD_DECIMAL_TEXT_WITH_ENDELEMENT = 0x95,
RECORD_DATETIME_TEXT = 0x96,
RECORD_DATETIME_TEXT_WITH_ENDELEMENT = 0x97,
RECORD_CHARS8_TEXT = 0x98,
RECORD_CHARS8_TEXT_WITH_ENDELEMENT = 0x99,
RECORD_CHARS16_TEXT = 0x9a,
RECORD_CHARS16_TEXT_WITH_ENDELEMENT = 0x9b,
RECORD_CHARS32_TEXT = 0x9c,
RECORD_CHARS32_TEXT_WITH_ENDELEMENT = 0x9d,
RECORD_BYTES8_TEXT = 0x9e,
RECORD_BYTES8_TEXT_WITH_ENDELEMENT = 0x9f,
RECORD_BYTES16_TEXT = 0xa0,
RECORD_BYTES16_TEXT_WITH_ENDELEMENT = 0xa1,
RECORD_BYTES32_TEXT = 0xa2,
RECORD_BYTES32_TEXT_WITH_ENDELEMENT = 0xa3,
RECORD_STARTLIST_TEXT = 0xa4,
/* 0xa5 reserved */
RECORD_ENDLIST_TEXT = 0xa6,
/* 0xa7 reserved */
RECORD_EMPTY_TEXT = 0xa8,
RECORD_EMPTY_TEXT_WITH_ENDELEMENT = 0xa9,
RECORD_DICTIONARY_TEXT = 0xaa,
RECORD_DICTIONARY_TEXT_WITH_ENDELEMENT = 0xab,
RECORD_UNIQUEID_TEXT = 0xac,
RECORD_UNIQUEID_TEXT_WITH_ENDELEMENT = 0xad,
RECORD_TIMESPAN_TEXT = 0xae,
RECORD_TIMESPAN_TEXT_WITH_ENDELEMENT = 0xaf,
RECORD_UUID_TEXT = 0xb0,
RECORD_UUID_TEXT_WITH_ENDELEMENT = 0xb1,
RECORD_UINT64_TEXT = 0xb2,
RECORD_UINT64_TEXT_WITH_ENDELEMENT = 0xb3,
RECORD_BOOL_TEXT = 0xb4,
RECORD_BOOL_TEXT_WITH_ENDELEMENT = 0xb5,
RECORD_UNICODE_CHARS8_TEXT = 0xb6,
RECORD_UNICODE_CHARS8_TEXT_WITH_ENDELEMENT = 0xb7,
RECORD_UNICODE_CHARS16_TEXT = 0xb8,
RECORD_UNICODE_CHARS16_TEXT_WITH_ENDELEMENT = 0xb9,
RECORD_UNICODE_CHARS32_TEXT = 0xba,
RECORD_UNICODE_CHARS32_TEXT_WITH_ENDELEMENT = 0xbb,
RECORD_QNAME_DICTIONARY_TEXT = 0xbc,
RECORD_QNAME_DICTIONARY_TEXT_WITH_ENDELEMENT = 0xbd,
/* 0xbe ... 0xff reserved */
};
#define TICKS_PER_SEC 10000000 #define TICKS_PER_SEC 10000000
#define TICKS_PER_MIN (60 * (ULONGLONG)TICKS_PER_SEC) #define TICKS_PER_MIN (60 * (ULONGLONG)TICKS_PER_SEC)
#define TICKS_PER_HOUR (3600 * (ULONGLONG)TICKS_PER_SEC) #define TICKS_PER_HOUR (3600 * (ULONGLONG)TICKS_PER_SEC)
......
...@@ -71,19 +71,20 @@ enum writer_state ...@@ -71,19 +71,20 @@ enum writer_state
struct writer struct writer
{ {
ULONG magic; ULONG magic;
CRITICAL_SECTION cs; CRITICAL_SECTION cs;
ULONG write_pos; ULONG write_pos;
unsigned char *write_bufptr; unsigned char *write_bufptr;
enum writer_state state; enum writer_state state;
struct node *root; struct node *root;
struct node *current; struct node *current;
WS_XML_STRING *current_ns; WS_XML_STRING *current_ns;
WS_XML_WRITER_OUTPUT_TYPE output_type; WS_XML_WRITER_ENCODING_TYPE output_enc;
struct xmlbuf *output_buf; WS_XML_WRITER_OUTPUT_TYPE output_type;
WS_HEAP *output_heap; struct xmlbuf *output_buf;
ULONG prop_count; WS_HEAP *output_heap;
struct prop prop[sizeof(writer_props)/sizeof(writer_props[0])]; ULONG prop_count;
struct prop prop[sizeof(writer_props)/sizeof(writer_props[0])];
}; };
#define WRITER_MAGIC (('W' << 24) | ('R' << 16) | ('I' << 8) | 'T') #define WRITER_MAGIC (('W' << 24) | ('R' << 16) | ('I' << 8) | 'T')
...@@ -162,6 +163,7 @@ static HRESULT init_writer( struct writer *writer ) ...@@ -162,6 +163,7 @@ static HRESULT init_writer( struct writer *writer )
if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY; if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
write_insert_eof( writer, node ); write_insert_eof( writer, node );
writer->state = WRITER_STATE_INITIAL; writer->state = WRITER_STATE_INITIAL;
writer->output_enc = WS_XML_WRITER_ENCODING_TYPE_TEXT;
return S_OK; return S_OK;
} }
...@@ -372,6 +374,12 @@ HRESULT WINAPI WsSetOutput( WS_XML_WRITER *handle, const WS_XML_WRITER_ENCODING ...@@ -372,6 +374,12 @@ HRESULT WINAPI WsSetOutput( WS_XML_WRITER *handle, const WS_XML_WRITER_ENCODING
hr = E_NOTIMPL; hr = E_NOTIMPL;
goto done; 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; break;
} }
default: default:
...@@ -737,9 +745,9 @@ HRESULT WINAPI WsWriteEndAttribute( WS_XML_WRITER *handle, WS_ERROR *error ) ...@@ -737,9 +745,9 @@ HRESULT WINAPI WsWriteEndAttribute( WS_XML_WRITER *handle, WS_ERROR *error )
return S_OK; 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; ULONG size, i;
HRESULT hr; HRESULT hr;
...@@ -774,6 +782,114 @@ static HRESULT write_startelement( struct writer *writer ) ...@@ -774,6 +782,114 @@ static HRESULT write_startelement( struct writer *writer )
return S_OK; 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 ) static struct node *write_find_startelement( struct writer *writer )
{ {
struct node *node; struct node *node;
...@@ -790,7 +906,7 @@ static inline BOOL is_empty_element( const 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; 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; ULONG size;
HRESULT hr; HRESULT hr;
...@@ -823,6 +939,26 @@ static HRESULT write_endelement( struct writer *writer, const WS_XML_ELEMENT_NOD ...@@ -823,6 +939,26 @@ static HRESULT write_endelement( struct writer *writer, const WS_XML_ELEMENT_NOD
return S_OK; 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 ) static HRESULT write_close_element( struct writer *writer, struct node *node )
{ {
WS_XML_ELEMENT_NODE *elem = &node->hdr; WS_XML_ELEMENT_NODE *elem = &node->hdr;
...@@ -874,7 +1010,7 @@ HRESULT WINAPI WsWriteEndElement( WS_XML_WRITER *handle, WS_ERROR *error ) ...@@ -874,7 +1010,7 @@ HRESULT WINAPI WsWriteEndElement( WS_XML_WRITER *handle, WS_ERROR *error )
return hr; return hr;
} }
static HRESULT write_endstartelement( struct writer *writer ) static HRESULT write_endstartelement_text( struct writer *writer )
{ {
HRESULT hr; HRESULT hr;
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr; if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
...@@ -882,6 +1018,18 @@ static HRESULT write_endstartelement( struct writer *writer ) ...@@ -882,6 +1018,18 @@ static HRESULT write_endstartelement( struct writer *writer )
return S_OK; 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.@] * 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