From 24d39bc3c4b511c398b5b8b2c047ded299d12c23 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 23 May 2017 12:03:51 +0200 Subject: [PATCH] webservices: Add initial support for binary XML in the writer. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/webservices/tests/writer.c | 46 ++++++++ dlls/webservices/webservices_private.h | 188 +++++++++++++++++++++++++++++++++ dlls/webservices/writer.c | 182 ++++++++++++++++++++++++++++--- 3 files changed, 399 insertions(+), 17 deletions(-) diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index aa33b7633a7..014266c5a5f 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -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(); } diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index 75dfdb9feae..b1b2caa0eb4 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -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; +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_MIN (60 * (ULONGLONG)TICKS_PER_SEC) #define TICKS_PER_HOUR (3600 * (ULONGLONG)TICKS_PER_SEC) diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 2b5affc4615..6b1994e0598 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -71,19 +71,20 @@ enum writer_state struct writer { - ULONG magic; - CRITICAL_SECTION cs; - ULONG write_pos; - unsigned char *write_bufptr; - enum writer_state state; - struct node *root; - struct node *current; - WS_XML_STRING *current_ns; - WS_XML_WRITER_OUTPUT_TYPE output_type; - struct xmlbuf *output_buf; - WS_HEAP *output_heap; - ULONG prop_count; - struct prop prop[sizeof(writer_props)/sizeof(writer_props[0])]; + ULONG magic; + CRITICAL_SECTION cs; + ULONG write_pos; + unsigned char *write_bufptr; + enum writer_state state; + 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; + ULONG prop_count; + struct prop prop[sizeof(writer_props)/sizeof(writer_props[0])]; }; #define WRITER_MAGIC (('W' << 24) | ('R' << 16) | ('I' << 8) | 'T') @@ -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.@] */ -- 2.11.4.GIT