mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-02 20:18:28 +00:00
webservices: Add support for writing attributes and text in binary mode.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e091c1ec1a
commit
e6b9f9a634
2 changed files with 302 additions and 82 deletions
|
@ -3420,17 +3420,46 @@ static void test_WsWriteCharsUtf8(void)
|
|||
WsFreeWriter( writer );
|
||||
}
|
||||
|
||||
static void check_output_bin( WS_XML_WRITER *writer, const char *expected, int len, unsigned int line )
|
||||
{
|
||||
WS_BYTES bytes;
|
||||
ULONG size = sizeof(bytes);
|
||||
HRESULT hr;
|
||||
|
||||
memset( &bytes, 0, sizeof(bytes) );
|
||||
hr = WsGetWriterProperty( writer, WS_XML_WRITER_PROPERTY_BYTES, &bytes, size, NULL );
|
||||
ok( hr == S_OK, "%u: got %08x\n", line, hr );
|
||||
ok( bytes.length == len, "%u: got %u expected %u\n", line, bytes.length, len );
|
||||
if (bytes.length != len) return;
|
||||
ok( !memcmp( bytes.bytes, expected, bytes.length ), "%u: got %s expected %s\n", line,
|
||||
debugstr_bytes(bytes.bytes, bytes.length), debugstr_bytes((const BYTE *)expected, len) );
|
||||
}
|
||||
|
||||
static void test_binary_encoding(void)
|
||||
{
|
||||
static const char res[] = {0x40,0x01,'t',0x01,0};
|
||||
static const char res2[] = {0x6d,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01,0};
|
||||
static const char res3[] = {0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x01,0};
|
||||
static const char res[] =
|
||||
{0x40,0x01,'t',0x01};
|
||||
static const char res2[] =
|
||||
{0x6d,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01};
|
||||
static const char res3[] =
|
||||
{0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x01};
|
||||
static const char res4[] =
|
||||
{0x41,0x02,'p','2',0x01,'t',0x09,0x02,'p','2',0x02,'n','s',0x99,0x04,'t','e','s','t'};
|
||||
static const char res100[] =
|
||||
{0x40,0x01,'t',0x04,0x01,'t',0x98,0x00,0x01};
|
||||
static const char res101[] =
|
||||
{0x40,0x01,'t',0x35,0x01,'t',0x98,0x00,0x09,0x01,'p',0x02,'n','s',0x01};
|
||||
static const char res102[] =
|
||||
{0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x00,0x09,0x02,'p','2',0x02,'n','s',0x01};
|
||||
static const char res103[] =
|
||||
{0x40,0x01,'t',0x05,0x02,'p','2',0x01,'t',0x98,0x04,'t','e','s','t',0x09,0x02,'p','2',0x02,'n','s',0x01};
|
||||
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 prefix[] = "p", prefix2[] = "p2";
|
||||
static const char localname[] = "t", empty[] = "", ns[] = "ns";
|
||||
static const char localname[] = "t", ns[] = "ns";
|
||||
const WS_XML_STRING *prefix_ptr, *localname_ptr, *ns_ptr;
|
||||
WS_XML_STRING str, str2, str3;
|
||||
WS_XML_STRING str, str2, str3, localname2 = {1, (BYTE *)"t"}, empty = {0, NULL};
|
||||
WS_XML_UTF8_TEXT utf8 = {{WS_XML_TEXT_TYPE_UTF8}};
|
||||
WS_XML_WRITER *writer;
|
||||
HRESULT hr;
|
||||
ULONG i;
|
||||
|
@ -3439,13 +3468,32 @@ static void test_binary_encoding(void)
|
|||
const char *prefix;
|
||||
const char *localname;
|
||||
const char *ns;
|
||||
const char *text;
|
||||
const char *result;
|
||||
int len_result;
|
||||
}
|
||||
elem_tests[] =
|
||||
{
|
||||
{ NULL, localname, empty, res }, /* short element */
|
||||
{ prefix, localname, ns, res2 }, /* one character prefix element */
|
||||
{ prefix2, localname, ns, res3 }, /* element */
|
||||
{ NULL, localname, "", NULL, res, sizeof(res) }, /* short element */
|
||||
{ prefix, localname, ns, NULL, res2, sizeof(res2) }, /* one character prefix element */
|
||||
{ prefix2, localname, ns, NULL, res3, sizeof(res3) }, /* element */
|
||||
{ prefix2, localname, ns, "test", res4, sizeof(res4) }, /* element with text */
|
||||
};
|
||||
static const struct
|
||||
{
|
||||
const char *prefix;
|
||||
const char *localname;
|
||||
const char *ns;
|
||||
const char *value;
|
||||
const char *result;
|
||||
int len_result;
|
||||
}
|
||||
attr_tests[] =
|
||||
{
|
||||
{ NULL, localname, "", NULL, res100, sizeof(res100) }, /* short attribute */
|
||||
{ prefix, localname, ns, NULL, res101, sizeof(res101) }, /* one character prefix attribute */
|
||||
{ prefix2, localname, ns, NULL, res102, sizeof(res102) }, /* attribute */
|
||||
{ prefix2, localname, ns, "test", res103, sizeof(res103) }, /* attribute with value */
|
||||
};
|
||||
|
||||
hr = WsCreateWriter( NULL, 0, &writer, NULL );
|
||||
|
@ -3462,9 +3510,43 @@ static void test_binary_encoding(void)
|
|||
|
||||
hr = WsWriteStartElement( writer, prefix_ptr, localname_ptr, ns_ptr, NULL );
|
||||
ok( hr == S_OK, "%u: got %08x\n", i, hr );
|
||||
if (elem_tests[i].text)
|
||||
{
|
||||
utf8.value.length = strlen( elem_tests[i].text );
|
||||
utf8.value.bytes = (BYTE *)elem_tests[i].text;
|
||||
hr = WsWriteText( writer, &utf8.text, 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__ );
|
||||
if (hr == S_OK) check_output_bin( writer, elem_tests[i].result, elem_tests[i].len_result, __LINE__ );
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(attr_tests)/sizeof(attr_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( attr_tests[i].prefix, &str );
|
||||
localname_ptr = init_xmlstring( attr_tests[i].localname, &str2 );
|
||||
ns_ptr = init_xmlstring( elem_tests[i].ns, &str3 );
|
||||
|
||||
hr = WsWriteStartElement( writer, NULL, &localname2, &empty, NULL );
|
||||
ok( hr == S_OK, "%u: got %08x\n", i, hr );
|
||||
hr = WsWriteStartAttribute( writer, prefix_ptr, localname_ptr, ns_ptr, FALSE, NULL );
|
||||
ok( hr == S_OK, "%u: got %08x\n", i, hr );
|
||||
if (attr_tests[i].value)
|
||||
{
|
||||
utf8.value.length = strlen( attr_tests[i].value );
|
||||
utf8.value.bytes = (BYTE *)attr_tests[i].value;
|
||||
hr = WsWriteText( writer, &utf8.text, NULL );
|
||||
ok( hr == S_OK, "%u: got %08x\n", i, hr );
|
||||
}
|
||||
hr = WsWriteEndAttribute( writer, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
hr = WsWriteEndElement( writer, NULL );
|
||||
ok( hr == S_OK, "%u: got %08x\n", i, hr );
|
||||
if (hr == S_OK) check_output_bin( writer, attr_tests[i].result, attr_tests[i].len_result, __LINE__ );
|
||||
}
|
||||
|
||||
WsFreeWriter( writer );
|
||||
|
|
|
@ -525,9 +525,19 @@ static HRESULT write_bytes_escape( struct writer *writer, const BYTE *bytes, ULO
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT write_attribute( struct writer *writer, WS_XML_ATTRIBUTE *attr )
|
||||
static HRESULT write_attribute_value_text( struct writer *writer, const WS_XML_TEXT *text, BOOL single )
|
||||
{
|
||||
WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text;
|
||||
const struct escape *escapes[3];
|
||||
|
||||
escapes[0] = single ? &escape_apos : &escape_quot;
|
||||
escapes[1] = &escape_lt;
|
||||
escapes[2] = &escape_amp;
|
||||
return write_bytes_escape( writer, utf8->value.bytes, utf8->value.length, escapes, 3 );
|
||||
}
|
||||
|
||||
static HRESULT write_attribute_text( struct writer *writer, const WS_XML_ATTRIBUTE *attr )
|
||||
{
|
||||
WS_XML_UTF8_TEXT *text = (WS_XML_UTF8_TEXT *)attr->value;
|
||||
unsigned char quote = attr->singleQuote ? '\'' : '"';
|
||||
const WS_XML_STRING *prefix = NULL;
|
||||
ULONG size;
|
||||
|
@ -539,7 +549,6 @@ static HRESULT write_attribute( struct writer *writer, WS_XML_ATTRIBUTE *attr )
|
|||
|
||||
size = attr->localName->length + 4 /* ' =""' */;
|
||||
if (prefix && prefix->length) size += prefix->length + 1 /* ':' */;
|
||||
if (text) size += text->value.length;
|
||||
if ((hr = write_grow_buffer( writer, size )) != S_OK) return hr;
|
||||
|
||||
write_char( writer, ' ' );
|
||||
|
@ -551,19 +560,156 @@ static HRESULT write_attribute( struct writer *writer, WS_XML_ATTRIBUTE *attr )
|
|||
write_bytes( writer, attr->localName->bytes, attr->localName->length );
|
||||
write_char( writer, '=' );
|
||||
write_char( writer, quote );
|
||||
if (text)
|
||||
{
|
||||
const struct escape *escapes[3];
|
||||
escapes[0] = attr->singleQuote ? &escape_apos : &escape_quot;
|
||||
escapes[1] = &escape_lt;
|
||||
escapes[2] = &escape_amp;
|
||||
hr = write_bytes_escape( writer, text->value.bytes, text->value.length, escapes, 3 );
|
||||
}
|
||||
if (attr->value) hr = write_attribute_value_text( writer, attr->value, attr->singleQuote );
|
||||
write_char( writer, quote );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static enum record_type get_attr_record_type( const WS_XML_ATTRIBUTE *attr )
|
||||
{
|
||||
if (!attr->prefix || !attr->prefix->length) return RECORD_SHORT_ATTRIBUTE;
|
||||
if (attr->prefix->length == 1 && attr->prefix->bytes[0] >= 'a' && attr->prefix->bytes[0] <= 'z')
|
||||
{
|
||||
return RECORD_PREFIX_ATTRIBUTE_A + attr->prefix->bytes[0] - 'a';
|
||||
}
|
||||
return RECORD_ATTRIBUTE;
|
||||
};
|
||||
|
||||
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 enum record_type get_text_record_type( const WS_XML_TEXT *text, BOOL attr )
|
||||
{
|
||||
const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text;
|
||||
if (!utf8 || utf8->value.length <= 0xff) return attr ? RECORD_CHARS8_TEXT : RECORD_CHARS8_TEXT_WITH_ENDELEMENT;
|
||||
return 0;
|
||||
};
|
||||
|
||||
static HRESULT write_attribute_value_bin( struct writer *writer, const WS_XML_TEXT *text )
|
||||
{
|
||||
WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text;
|
||||
enum record_type type = get_text_record_type( text, TRUE );
|
||||
HRESULT hr;
|
||||
|
||||
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
|
||||
write_char( writer, type );
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case RECORD_CHARS8_TEXT:
|
||||
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
|
||||
if (!utf8 || !utf8->value.length) write_char( writer, 0 );
|
||||
else
|
||||
{
|
||||
write_char( writer, utf8->value.length );
|
||||
if ((hr = write_grow_buffer( writer, utf8->value.length )) != S_OK) return hr;
|
||||
write_bytes( writer, utf8->value.bytes, utf8->value.length );
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
default:
|
||||
ERR( "unhandled record type %u\n", type );
|
||||
return WS_E_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT write_attribute_bin( struct writer *writer, const WS_XML_ATTRIBUTE *attr )
|
||||
{
|
||||
enum record_type type = get_attr_record_type( attr );
|
||||
HRESULT hr;
|
||||
|
||||
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
|
||||
write_char( writer, type );
|
||||
|
||||
if (type >= RECORD_PREFIX_ATTRIBUTE_A && type <= RECORD_PREFIX_ATTRIBUTE_Z)
|
||||
{
|
||||
if ((hr = write_string( writer, attr->localName->bytes, attr->localName->length )) != S_OK) return hr;
|
||||
return write_attribute_value_bin( writer, attr->value );
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case RECORD_SHORT_ATTRIBUTE:
|
||||
if ((hr = write_string( writer, attr->localName->bytes, attr->localName->length )) != S_OK) return hr;
|
||||
break;
|
||||
|
||||
case RECORD_ATTRIBUTE:
|
||||
if ((hr = write_string( writer, attr->prefix->bytes, attr->prefix->length )) != S_OK) return hr;
|
||||
if ((hr = write_string( writer, attr->localName->bytes, attr->localName->length )) != S_OK) return hr;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR( "unhandled record type %u\n", type );
|
||||
return WS_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return write_attribute_value_bin( writer, attr->value );
|
||||
}
|
||||
|
||||
static HRESULT write_attribute( struct writer *writer, const WS_XML_ATTRIBUTE *attr )
|
||||
{
|
||||
switch (writer->output_enc)
|
||||
{
|
||||
case WS_XML_WRITER_ENCODING_TYPE_TEXT: return write_attribute_text( writer, attr );
|
||||
case WS_XML_WRITER_ENCODING_TYPE_BINARY: return write_attribute_bin( writer, attr );
|
||||
default:
|
||||
ERR( "unhandled encoding %u\n", writer->output_enc );
|
||||
return WS_E_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
static inline BOOL is_current_namespace( struct writer *writer, const WS_XML_STRING *ns )
|
||||
{
|
||||
return (WsXmlStringEquals( writer->current_ns, ns, NULL ) == S_OK);
|
||||
|
@ -647,60 +793,6 @@ static enum record_type get_xmlns_record_type( const WS_XML_ATTRIBUTE *attr )
|
|||
return RECORD_XMLNS_ATTRIBUTE;
|
||||
};
|
||||
|
||||
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_namespace_attribute_bin( struct writer *writer, const WS_XML_ATTRIBUTE *attr )
|
||||
{
|
||||
enum record_type type = get_xmlns_record_type( attr );
|
||||
|
@ -1003,6 +1095,7 @@ static HRESULT write_endelement_text( struct writer *writer, const WS_XML_ELEMEN
|
|||
static HRESULT write_endelement_bin( struct writer *writer )
|
||||
{
|
||||
HRESULT hr;
|
||||
if (node_type( writer->current ) == WS_XML_NODE_TYPE_TEXT) return S_OK;
|
||||
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
|
||||
write_char( writer, RECORD_ENDELEMENT );
|
||||
return S_OK;
|
||||
|
@ -1138,7 +1231,7 @@ static HRESULT write_add_attribute( struct writer *writer, const WS_XML_STRING *
|
|||
|
||||
if (!(attr = heap_alloc_zero( sizeof(*attr) ))) return E_OUTOFMEMORY;
|
||||
|
||||
if (!prefix && ns->length > 0) prefix = elem->prefix;
|
||||
if (!prefix && ns->length) prefix = elem->prefix;
|
||||
|
||||
attr->singleQuote = !!single;
|
||||
if (prefix && !(attr->prefix = alloc_xml_string( prefix->bytes, prefix->length )))
|
||||
|
@ -1859,13 +1952,11 @@ static HRESULT write_add_text_node( struct writer *writer, const WS_XML_TEXT *va
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT write_text( struct writer *writer, ULONG offset )
|
||||
static HRESULT write_text_text( struct writer *writer, const WS_XML_TEXT *text, ULONG offset )
|
||||
{
|
||||
const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)writer->current;
|
||||
const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text->text;
|
||||
const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text;
|
||||
HRESULT hr;
|
||||
|
||||
if (!writer->current->parent) return WS_E_INVALID_FORMAT;
|
||||
if (node_type( writer->current->parent ) == WS_XML_NODE_TYPE_ELEMENT)
|
||||
{
|
||||
const struct escape *escapes[3] = { &escape_lt, &escape_gt, &escape_amp };
|
||||
|
@ -1881,8 +1972,55 @@ static HRESULT write_text( struct writer *writer, ULONG offset )
|
|||
return WS_E_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
static HRESULT write_text_bin( struct writer *writer, const WS_XML_TEXT *text, ULONG offset )
|
||||
{
|
||||
const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text;
|
||||
enum record_type type = get_text_record_type( text, FALSE );
|
||||
HRESULT hr;
|
||||
|
||||
if (offset)
|
||||
{
|
||||
FIXME( "no support for appending text in binary mode\n" );
|
||||
return WS_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case RECORD_CHARS8_TEXT_WITH_ENDELEMENT:
|
||||
if ((hr = write_grow_buffer( writer, 2 )) != S_OK) return hr;
|
||||
write_char( writer, type );
|
||||
if (!utf8 || !utf8->value.length) write_char( writer, 0 );
|
||||
else
|
||||
{
|
||||
write_char( writer, utf8->value.length );
|
||||
if ((hr = write_grow_buffer( writer, utf8->value.length )) != S_OK) return hr;
|
||||
write_bytes( writer, utf8->value.bytes, utf8->value.length );
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
default:
|
||||
FIXME( "unhandled record type %u\n", type );
|
||||
return WS_E_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT write_text( struct writer *writer, const WS_XML_TEXT *text, ULONG offset )
|
||||
{
|
||||
if (!writer->current->parent) return WS_E_INVALID_FORMAT;
|
||||
|
||||
switch (writer->output_enc)
|
||||
{
|
||||
case WS_XML_WRITER_ENCODING_TYPE_TEXT: return write_text_text( writer, text, offset );
|
||||
case WS_XML_WRITER_ENCODING_TYPE_BINARY: return write_text_bin( writer, text, offset );
|
||||
default:
|
||||
ERR( "unhandled encoding %u\n", writer->output_enc );
|
||||
return WS_E_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT write_text_node( struct writer *writer, const WS_XML_TEXT *text )
|
||||
{
|
||||
WS_XML_TEXT_NODE *node = (WS_XML_TEXT_NODE *)writer->current;
|
||||
ULONG offset;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -1891,10 +2029,10 @@ static HRESULT write_text_node( struct writer *writer, const WS_XML_TEXT *text )
|
|||
{
|
||||
offset = 0;
|
||||
if ((hr = write_add_text_node( writer, text )) != S_OK) return hr;
|
||||
node = (WS_XML_TEXT_NODE *)writer->current;
|
||||
}
|
||||
else
|
||||
{
|
||||
WS_XML_TEXT_NODE *node = (WS_XML_TEXT_NODE *)writer->current;
|
||||
WS_XML_UTF8_TEXT *new, *old = (WS_XML_UTF8_TEXT *)node->text;
|
||||
|
||||
offset = old->value.length;
|
||||
|
@ -1903,7 +2041,7 @@ static HRESULT write_text_node( struct writer *writer, const WS_XML_TEXT *text )
|
|||
node->text = &new->text;
|
||||
}
|
||||
|
||||
if ((hr = write_text( writer, offset )) != S_OK) return hr;
|
||||
if ((hr = write_text( writer, node->text, offset )) != S_OK) return hr;
|
||||
|
||||
writer->state = WRITER_STATE_TEXT;
|
||||
return S_OK;
|
||||
|
@ -3539,7 +3677,7 @@ static HRESULT write_tree_node( struct writer *writer )
|
|||
case WS_XML_NODE_TYPE_TEXT:
|
||||
if (writer->state == WRITER_STATE_STARTELEMENT && (hr = write_endstartelement( writer )) != S_OK)
|
||||
return hr;
|
||||
if ((hr = write_text( writer, 0 )) != S_OK) return hr;
|
||||
if ((hr = write_text( writer, ((const WS_XML_TEXT_NODE *)writer->current)->text, 0 )) != S_OK) return hr;
|
||||
writer->state = WRITER_STATE_TEXT;
|
||||
return S_OK;
|
||||
|
||||
|
|
Loading…
Reference in a new issue