[3/6] webservices: Add initial support for binary XML in the writer.
Hans Leidekker
hans at codeweavers.com
Tue May 23 05:03:51 CDT 2017
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
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 aa33b7633a..014266c5a5 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 75dfdb9fea..b1b2caa0eb 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 2b5affc461..6b1994e059 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.0
More information about the wine-patches
mailing list