webservices: Add support for dictionary strings in the writer.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e558858d0f
commit
51d934abbc
|
@ -467,17 +467,21 @@ static HRESULT get_env_namespace( WS_ENVELOPE_VERSION ver, WS_XML_STRING *str )
|
|||
case WS_ENVELOPE_VERSION_SOAP_1_1:
|
||||
str->bytes = (BYTE *)ns_env_1_1;
|
||||
str->length = sizeof(ns_env_1_1)/sizeof(ns_env_1_1[0]) - 1;
|
||||
return S_OK;
|
||||
break;
|
||||
|
||||
case WS_ENVELOPE_VERSION_SOAP_1_2:
|
||||
str->bytes = (BYTE *)ns_env_1_2;
|
||||
str->length = sizeof(ns_env_1_2)/sizeof(ns_env_1_2[0]) - 1;
|
||||
return S_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR( "unhandled envelope version %u\n", ver );
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
str->dictionary = NULL;
|
||||
str->id = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT get_addr_namespace( WS_ADDRESSING_VERSION ver, WS_XML_STRING *str )
|
||||
|
@ -487,22 +491,26 @@ static HRESULT get_addr_namespace( WS_ADDRESSING_VERSION ver, WS_XML_STRING *str
|
|||
case WS_ADDRESSING_VERSION_0_9:
|
||||
str->bytes = (BYTE *)ns_addr_0_9;
|
||||
str->length = sizeof(ns_addr_0_9)/sizeof(ns_addr_0_9[0]) - 1;
|
||||
return S_OK;
|
||||
break;
|
||||
|
||||
case WS_ADDRESSING_VERSION_1_0:
|
||||
str->bytes = (BYTE *)ns_addr_1_0;
|
||||
str->length = sizeof(ns_addr_1_0)/sizeof(ns_addr_1_0[0]) - 1;
|
||||
return S_OK;
|
||||
break;
|
||||
|
||||
case WS_ADDRESSING_VERSION_TRANSPORT:
|
||||
str->bytes = NULL;
|
||||
str->length = 0;
|
||||
return S_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR( "unhandled addressing version %u\n", ver );
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
str->dictionary = NULL;
|
||||
str->id = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const WS_XML_STRING *get_header_name( WS_HEADER_TYPE type )
|
||||
|
|
|
@ -161,9 +161,9 @@ static WS_XML_ATTRIBUTE *dup_attribute( const WS_XML_ATTRIBUTE *src )
|
|||
dst->isXmlNs = src->isXmlNs;
|
||||
|
||||
if (!prefix) dst->prefix = NULL;
|
||||
else if (!(dst->prefix = alloc_xml_string( prefix->bytes, prefix->length ))) goto error;
|
||||
if (!(dst->localName = alloc_xml_string( localname->bytes, localname->length ))) goto error;
|
||||
if (!(dst->ns = alloc_xml_string( ns->bytes, ns->length ))) goto error;
|
||||
else if (!(dst->prefix = dup_xml_string( prefix ))) goto error;
|
||||
if (!(dst->localName = dup_xml_string( localname ))) goto error;
|
||||
if (!(dst->ns = dup_xml_string( ns ))) goto error;
|
||||
|
||||
if (text)
|
||||
{
|
||||
|
@ -214,9 +214,9 @@ static struct node *dup_element_node( const WS_XML_ELEMENT_NODE *src )
|
|||
if (count && !(dst->attributes = dup_attributes( attrs, count ))) goto error;
|
||||
dst->attributeCount = count;
|
||||
|
||||
if (prefix && !(dst->prefix = alloc_xml_string( prefix->bytes, prefix->length ))) goto error;
|
||||
if (localname && !(dst->localName = alloc_xml_string( localname->bytes, localname->length ))) goto error;
|
||||
if (ns && !(dst->ns = alloc_xml_string( ns->bytes, ns->length ))) goto error;
|
||||
if (prefix && !(dst->prefix = dup_xml_string( prefix ))) goto error;
|
||||
if (localname && !(dst->localName = dup_xml_string( localname ))) goto error;
|
||||
if (ns && !(dst->ns = dup_xml_string( ns ))) goto error;
|
||||
return node;
|
||||
|
||||
error:
|
||||
|
@ -797,6 +797,20 @@ WS_XML_STRING *alloc_xml_string( const unsigned char *data, ULONG len )
|
|||
return ret;
|
||||
}
|
||||
|
||||
WS_XML_STRING *dup_xml_string( const WS_XML_STRING *src )
|
||||
{
|
||||
WS_XML_STRING *ret;
|
||||
|
||||
if (!src->dictionary) return alloc_xml_string( src->bytes, src->length );
|
||||
|
||||
if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
|
||||
ret->length = src->length;
|
||||
ret->bytes = src->bytes;
|
||||
ret->dictionary = src->dictionary;
|
||||
ret->id = src->id;
|
||||
return ret;
|
||||
}
|
||||
|
||||
WS_XML_UTF8_TEXT *alloc_utf8_text( const unsigned char *data, ULONG len )
|
||||
{
|
||||
WS_XML_UTF8_TEXT *ret;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
TESTDLL = webservices.dll
|
||||
IMPORTS = webservices user32 ws2_32
|
||||
IMPORTS = webservices user32 rpcrt4 ws2_32
|
||||
|
||||
C_SRCS = \
|
||||
channel.c \
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include "windows.h"
|
||||
#include "rpc.h"
|
||||
#include "webservices.h"
|
||||
#include "wine/test.h"
|
||||
|
||||
|
@ -3592,6 +3593,144 @@ static void test_namespaces(void)
|
|||
WsFreeWriter( writer );
|
||||
}
|
||||
|
||||
static const WS_XML_STRING *init_xmlstring_dict( WS_XML_DICTIONARY *dict, ULONG id, WS_XML_STRING *str )
|
||||
{
|
||||
if (id >= dict->stringCount) return NULL;
|
||||
str->length = dict->strings[id].length;
|
||||
str->bytes = dict->strings[id].bytes;
|
||||
str->dictionary = dict;
|
||||
str->id = id;
|
||||
return str;
|
||||
}
|
||||
|
||||
static void test_dictionary(void)
|
||||
{
|
||||
static const char res[] =
|
||||
{0x42,0x04,0x01};
|
||||
static const char res2[] =
|
||||
{0x42,0x06,0x01};
|
||||
static const char res3[] =
|
||||
{0x53,0x06,0x0b,0x01,'p',0x0a,0x01};
|
||||
static const char res4[] =
|
||||
{0x43,0x02,'p','2',0x06,0x0b,0x02,'p','2',0x0a,0x01};
|
||||
static const char res100[] =
|
||||
{0x42,0x06,0x06,0x06,0x98,0x00,0x01};
|
||||
static const char res101[] =
|
||||
{0x42,0x06,0x1b,0x06,0x98,0x00,0x0b,0x01,'p',0x0a,0x01};
|
||||
static const char res102[] =
|
||||
{0x42,0x06,0x07,0x02,'p','2',0x06,0x98,0x00,0x0b,0x02,'p','2',0x0a,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}};
|
||||
WS_XML_STRING prefix, localname, ns, strings[6];
|
||||
const WS_XML_STRING *prefix_ptr, *localname_ptr, *ns_ptr;
|
||||
WS_XML_DICTIONARY dict;
|
||||
WS_XML_WRITER *writer;
|
||||
HRESULT hr;
|
||||
ULONG i;
|
||||
static const struct
|
||||
{
|
||||
ULONG prefix;
|
||||
ULONG localname;
|
||||
ULONG ns;
|
||||
const char *result;
|
||||
int len_result;
|
||||
}
|
||||
elem_tests[] =
|
||||
{
|
||||
{ ~0u, 2, 0, res, sizeof(res) }, /* short dictionary element, invalid dict id */
|
||||
{ ~0u, 3, 0, res2, sizeof(res2) }, /* short dictionary element */
|
||||
{ 1, 3, 5, res3, sizeof(res3) }, /* single character prefix dictionary element */
|
||||
{ 4, 3, 5, res4, sizeof(res4) }, /* dictionary element */
|
||||
};
|
||||
static const struct
|
||||
{
|
||||
ULONG prefix;
|
||||
ULONG localname;
|
||||
ULONG ns;
|
||||
const char *result;
|
||||
int len_result;
|
||||
}
|
||||
attr_tests[] =
|
||||
{
|
||||
{ ~0u, 3, 0, res100, sizeof(res100) }, /* short dictionary attribute */
|
||||
{ 1, 3, 5, res101, sizeof(res101) }, /* single character prefix dictionary attribute */
|
||||
{ 4, 3, 5, res102, sizeof(res102) }, /* dictionary attribute */
|
||||
};
|
||||
|
||||
hr = WsCreateWriter( NULL, 0, &writer, NULL );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
strings[0].length = 0;
|
||||
strings[0].bytes = NULL;
|
||||
strings[0].dictionary = &dict;
|
||||
strings[0].id = 0;
|
||||
strings[1].length = 1;
|
||||
strings[1].bytes = (BYTE *)"p";
|
||||
strings[1].dictionary = &dict;
|
||||
strings[1].id = 1;
|
||||
strings[2].length = 1;
|
||||
strings[2].bytes = (BYTE *)"t";
|
||||
strings[2].dictionary = &dict;
|
||||
strings[2].id = ~0u;
|
||||
strings[3].length = 1;
|
||||
strings[3].bytes = (BYTE *)"u";
|
||||
strings[3].dictionary = &dict;
|
||||
strings[3].id = 3;
|
||||
strings[4].length = 2;
|
||||
strings[4].bytes = (BYTE *)"p2";
|
||||
strings[4].dictionary = &dict;
|
||||
strings[4].id = 4;
|
||||
strings[5].length = 2;
|
||||
strings[5].bytes = (BYTE *)"ns";
|
||||
strings[5].dictionary = &dict;
|
||||
strings[5].id = 5;
|
||||
|
||||
UuidCreate( &dict.guid );
|
||||
dict.strings = strings;
|
||||
dict.stringCount = sizeof(strings)/sizeof(strings[0]);
|
||||
dict.isConst = TRUE;
|
||||
|
||||
bin.staticDictionary = &dict;
|
||||
|
||||
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_dict( &dict, elem_tests[i].prefix, &prefix );
|
||||
localname_ptr = init_xmlstring_dict( &dict, elem_tests[i].localname, &localname );
|
||||
ns_ptr = init_xmlstring_dict( &dict, elem_tests[i].ns, &ns );
|
||||
|
||||
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_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_dict( &dict, attr_tests[i].prefix, &prefix );
|
||||
localname_ptr = init_xmlstring_dict( &dict, attr_tests[i].localname, &localname );
|
||||
ns_ptr = init_xmlstring_dict( &dict, attr_tests[i].ns, &ns );
|
||||
|
||||
hr = WsWriteStartElement( writer, NULL, &strings[3], &strings[0], 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 );
|
||||
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 );
|
||||
}
|
||||
|
||||
START_TEST(writer)
|
||||
{
|
||||
test_WsCreateWriter();
|
||||
|
@ -3631,4 +3770,5 @@ START_TEST(writer)
|
|||
test_WsWriteCharsUtf8();
|
||||
test_binary_encoding();
|
||||
test_namespaces();
|
||||
test_dictionary();
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ void free_xmlbuf( struct xmlbuf * ) DECLSPEC_HIDDEN;
|
|||
|
||||
const char *debugstr_xmlstr( const WS_XML_STRING * ) DECLSPEC_HIDDEN;
|
||||
WS_XML_STRING *alloc_xml_string( const unsigned char *, ULONG ) DECLSPEC_HIDDEN;
|
||||
WS_XML_STRING *dup_xml_string( const WS_XML_STRING * ) DECLSPEC_HIDDEN;
|
||||
WS_XML_UTF8_TEXT *alloc_utf8_text( const unsigned char *, ULONG ) DECLSPEC_HIDDEN;
|
||||
HRESULT append_attribute( WS_XML_ELEMENT_NODE *, WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN;
|
||||
void free_attribute( WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -566,20 +566,12 @@ static HRESULT write_attribute_text( struct writer *writer, const WS_XML_ATTRIBU
|
|||
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 (len > 0x7fffffff) return E_INVALIDARG;
|
||||
|
||||
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
|
||||
if (len < 0x80)
|
||||
{
|
||||
|
@ -630,6 +622,14 @@ static HRESULT write_string( struct writer *writer, const BYTE *bytes, ULONG len
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT write_dict_string( struct writer *writer, ULONG id )
|
||||
{
|
||||
HRESULT hr;
|
||||
if (id > 0x3fffffff) return E_INVALIDARG;
|
||||
if ((hr = write_int31( writer, id << 1 )) != S_OK) return hr;
|
||||
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;
|
||||
|
@ -660,11 +660,27 @@ static HRESULT write_attribute_value_bin( struct writer *writer, const WS_XML_TE
|
|||
return S_OK;
|
||||
|
||||
default:
|
||||
ERR( "unhandled record type %u\n", type );
|
||||
ERR( "unhandled record type %02x\n", type );
|
||||
return WS_E_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
static enum record_type get_attr_record_type( const WS_XML_ATTRIBUTE *attr )
|
||||
{
|
||||
if (!attr->prefix || !attr->prefix->length)
|
||||
{
|
||||
if (attr->localName->dictionary) return RECORD_SHORT_DICTIONARY_ATTRIBUTE;
|
||||
return RECORD_SHORT_ATTRIBUTE;
|
||||
}
|
||||
if (attr->prefix->length == 1 && attr->prefix->bytes[0] >= 'a' && attr->prefix->bytes[0] <= 'z')
|
||||
{
|
||||
if (attr->localName->dictionary) return RECORD_PREFIX_DICTIONARY_ATTRIBUTE_A + attr->prefix->bytes[0] - 'a';
|
||||
return RECORD_PREFIX_ATTRIBUTE_A + attr->prefix->bytes[0] - 'a';
|
||||
}
|
||||
if (attr->localName->dictionary) return RECORD_DICTIONARY_ATTRIBUTE;
|
||||
return RECORD_ATTRIBUTE;
|
||||
};
|
||||
|
||||
static HRESULT write_attribute_bin( struct writer *writer, const WS_XML_ATTRIBUTE *attr )
|
||||
{
|
||||
enum record_type type = get_attr_record_type( attr );
|
||||
|
@ -678,6 +694,11 @@ static HRESULT write_attribute_bin( struct writer *writer, const WS_XML_ATTRIBUT
|
|||
if ((hr = write_string( writer, attr->localName->bytes, attr->localName->length )) != S_OK) return hr;
|
||||
return write_attribute_value_bin( writer, attr->value );
|
||||
}
|
||||
if (type >= RECORD_PREFIX_DICTIONARY_ATTRIBUTE_A && type <= RECORD_PREFIX_DICTIONARY_ATTRIBUTE_Z)
|
||||
{
|
||||
if ((hr = write_dict_string( writer, attr->localName->id )) != S_OK) return hr;
|
||||
return write_attribute_value_bin( writer, attr->value );
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
@ -690,8 +711,17 @@ static HRESULT write_attribute_bin( struct writer *writer, const WS_XML_ATTRIBUT
|
|||
if ((hr = write_string( writer, attr->localName->bytes, attr->localName->length )) != S_OK) return hr;
|
||||
break;
|
||||
|
||||
case RECORD_SHORT_DICTIONARY_ATTRIBUTE:
|
||||
if ((hr = write_dict_string( writer, attr->localName->id )) != S_OK) return hr;
|
||||
break;
|
||||
|
||||
case RECORD_DICTIONARY_ATTRIBUTE:
|
||||
if ((hr = write_string( writer, attr->prefix->bytes, attr->prefix->length )) != S_OK) return hr;
|
||||
if ((hr = write_dict_string( writer, attr->localName->id )) != S_OK) return hr;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR( "unhandled record type %u\n", type );
|
||||
ERR( "unhandled record type %02x\n", type );
|
||||
return WS_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
@ -789,7 +819,12 @@ static HRESULT write_namespace_attribute_text( struct writer *writer, const WS_X
|
|||
|
||||
static enum record_type get_xmlns_record_type( const WS_XML_ATTRIBUTE *attr )
|
||||
{
|
||||
if (!attr->prefix || !attr->prefix->length) return RECORD_SHORT_XMLNS_ATTRIBUTE;
|
||||
if (!attr->prefix || !attr->prefix->length)
|
||||
{
|
||||
if (attr->ns->dictionary) return RECORD_SHORT_DICTIONARY_XMLNS_ATTRIBUTE;
|
||||
return RECORD_SHORT_XMLNS_ATTRIBUTE;
|
||||
}
|
||||
if (attr->ns->dictionary) return RECORD_DICTIONARY_XMLNS_ATTRIBUTE;
|
||||
return RECORD_XMLNS_ATTRIBUTE;
|
||||
};
|
||||
|
||||
|
@ -810,8 +845,15 @@ static HRESULT write_namespace_attribute_bin( struct writer *writer, const WS_XM
|
|||
if ((hr = write_string( writer, attr->prefix->bytes, attr->prefix->length )) != S_OK) return hr;
|
||||
break;
|
||||
|
||||
case RECORD_SHORT_DICTIONARY_XMLNS_ATTRIBUTE:
|
||||
return write_dict_string( writer, attr->ns->id );
|
||||
|
||||
case RECORD_DICTIONARY_XMLNS_ATTRIBUTE:
|
||||
if ((hr = write_string( writer, attr->prefix->bytes, attr->prefix->length )) != S_OK) return hr;
|
||||
return write_dict_string( writer, attr->ns->id );
|
||||
|
||||
default:
|
||||
ERR( "unhandled record type %u\n", type );
|
||||
ERR( "unhandled record type %02x\n", type );
|
||||
return WS_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
@ -841,12 +883,12 @@ static HRESULT add_namespace_attribute( struct writer *writer, const WS_XML_STRI
|
|||
|
||||
attr->singleQuote = !!single;
|
||||
attr->isXmlNs = 1;
|
||||
if (prefix && !(attr->prefix = alloc_xml_string( prefix->bytes, prefix->length )))
|
||||
if (prefix && !(attr->prefix = dup_xml_string( prefix )))
|
||||
{
|
||||
free_attribute( attr );
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (!(attr->ns = alloc_xml_string( ns->bytes, ns->length )))
|
||||
if (!(attr->ns = dup_xml_string( ns )))
|
||||
{
|
||||
free_attribute( attr );
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -889,7 +931,7 @@ static BOOL namespace_in_scope( const WS_XML_ELEMENT_NODE *elem, const WS_XML_ST
|
|||
static HRESULT set_current_namespace( struct writer *writer, const WS_XML_STRING *ns )
|
||||
{
|
||||
WS_XML_STRING *str;
|
||||
if (!(str = alloc_xml_string( ns->bytes, ns->length ))) return E_OUTOFMEMORY;
|
||||
if (!(str = dup_xml_string( ns ))) return E_OUTOFMEMORY;
|
||||
heap_free( writer->current_ns );
|
||||
writer->current_ns = str;
|
||||
return S_OK;
|
||||
|
@ -989,11 +1031,17 @@ static HRESULT write_startelement_text( struct writer *writer )
|
|||
|
||||
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 || !elem->prefix->length)
|
||||
{
|
||||
if (elem->localName->dictionary) return RECORD_SHORT_DICTIONARY_ELEMENT;
|
||||
return RECORD_SHORT_ELEMENT;
|
||||
}
|
||||
if (elem->prefix->length == 1 && elem->prefix->bytes[0] >= 'a' && elem->prefix->bytes[0] <= 'z')
|
||||
{
|
||||
if (elem->localName->dictionary) return RECORD_PREFIX_DICTIONARY_ELEMENT_A + elem->prefix->bytes[0] - 'a';
|
||||
return RECORD_PREFIX_ELEMENT_A + elem->prefix->bytes[0] - 'a';
|
||||
}
|
||||
if (elem->localName->dictionary) return RECORD_DICTIONARY_ELEMENT;
|
||||
return RECORD_ELEMENT;
|
||||
};
|
||||
|
||||
|
@ -1011,6 +1059,11 @@ static HRESULT write_startelement_bin( struct writer *writer )
|
|||
if ((hr = write_string( writer, elem->localName->bytes, elem->localName->length )) != S_OK) return hr;
|
||||
return write_attributes( writer, elem );
|
||||
}
|
||||
if (type >= RECORD_PREFIX_DICTIONARY_ELEMENT_A && type <= RECORD_PREFIX_DICTIONARY_ELEMENT_Z)
|
||||
{
|
||||
if ((hr = write_dict_string( writer, elem->localName->id )) != S_OK) return hr;
|
||||
return write_attributes( writer, elem );
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
@ -1023,8 +1076,17 @@ static HRESULT write_startelement_bin( struct writer *writer )
|
|||
if ((hr = write_string( writer, elem->localName->bytes, elem->localName->length )) != S_OK) return hr;
|
||||
break;
|
||||
|
||||
case RECORD_SHORT_DICTIONARY_ELEMENT:
|
||||
if ((hr = write_dict_string( writer, elem->localName->id )) != S_OK) return hr;
|
||||
break;
|
||||
|
||||
case RECORD_DICTIONARY_ELEMENT:
|
||||
if ((hr = write_string( writer, elem->prefix->bytes, elem->prefix->length )) != S_OK) return hr;
|
||||
if ((hr = write_dict_string( writer, elem->localName->id )) != S_OK) return hr;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR( "unhandled record type %u\n", type );
|
||||
ERR( "unhandled record type %02x\n", type );
|
||||
return WS_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
@ -1234,17 +1296,17 @@ static HRESULT write_add_attribute( struct writer *writer, const WS_XML_STRING *
|
|||
if (!prefix && ns->length) prefix = elem->prefix;
|
||||
|
||||
attr->singleQuote = !!single;
|
||||
if (prefix && !(attr->prefix = alloc_xml_string( prefix->bytes, prefix->length )))
|
||||
if (prefix && !(attr->prefix = dup_xml_string( prefix )))
|
||||
{
|
||||
free_attribute( attr );
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (!(attr->localName = alloc_xml_string( localname->bytes, localname->length )))
|
||||
if (!(attr->localName = dup_xml_string( localname )))
|
||||
{
|
||||
free_attribute( attr );
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (!(attr->ns = alloc_xml_string( ns->bytes, ns->length )))
|
||||
if (!(attr->ns = dup_xml_string( ns )))
|
||||
{
|
||||
free_attribute( attr );
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -1439,17 +1501,17 @@ static HRESULT write_add_element_node( struct writer *writer, const WS_XML_STRIN
|
|||
if (!(node = alloc_node( WS_XML_NODE_TYPE_ELEMENT ))) return E_OUTOFMEMORY;
|
||||
elem = &node->hdr;
|
||||
|
||||
if (prefix && !(elem->prefix = alloc_xml_string( prefix->bytes, prefix->length )))
|
||||
if (prefix && !(elem->prefix = dup_xml_string( prefix )))
|
||||
{
|
||||
free_node( node );
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (!(elem->localName = alloc_xml_string( localname->bytes, localname->length )))
|
||||
if (!(elem->localName = dup_xml_string( localname )))
|
||||
{
|
||||
free_node( node );
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (!(elem->ns = alloc_xml_string( ns->bytes, ns->length )))
|
||||
if (!(elem->ns = dup_xml_string( ns )))
|
||||
{
|
||||
free_node( node );
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -1999,7 +2061,7 @@ static HRESULT write_text_bin( struct writer *writer, const WS_XML_TEXT *text, U
|
|||
return S_OK;
|
||||
|
||||
default:
|
||||
FIXME( "unhandled record type %u\n", type );
|
||||
FIXME( "unhandled record type %02x\n", type );
|
||||
return WS_E_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue