[3/4] webservices: Add a builtin dictionary.
Hans Leidekker
hans at codeweavers.com
Tue May 30 03:09:07 CDT 2017
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/webservices/msg.c | 2 +-
dlls/webservices/reader.c | 301 +++++++++++++++++++++++++--------
dlls/webservices/tests/reader.c | 2 +-
dlls/webservices/webservices_private.h | 1 +
dlls/webservices/writer.c | 41 +++--
5 files changed, 261 insertions(+), 86 deletions(-)
diff --git a/dlls/webservices/msg.c b/dlls/webservices/msg.c
index 2c6667a..3032c83 100644
--- a/dlls/webservices/msg.c
+++ b/dlls/webservices/msg.c
@@ -119,7 +119,7 @@ static void free_header( struct header *header )
{
heap_free( header->name.bytes );
heap_free( header->ns.bytes );
- if (header->mapped) heap_free( header->u.text );
+ if (header->mapped) free_xml_string( header->u.text );
heap_free( header );
}
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 8485ad6..01b464f 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -70,6 +70,202 @@ HRESULT prop_get( const struct prop *prop, ULONG count, ULONG id, void *buf, ULO
return S_OK;
}
+static CRITICAL_SECTION dict_cs;
+static CRITICAL_SECTION_DEBUG dict_cs_debug =
+{
+ 0, 0, &dict_cs,
+ {&dict_cs_debug.ProcessLocksList,
+ &dict_cs_debug.ProcessLocksList},
+ 0, 0, {(DWORD_PTR)(__FILE__ ": dict_cs")}
+};
+static CRITICAL_SECTION dict_cs = {&dict_cs_debug, -1, 0, 0, 0, 0};
+
+static ULONG dict_size, *dict_sorted;
+static WS_XML_DICTIONARY dict_builtin =
+{
+ {0x82704485,0x222a,0x4f7c,{0xb9,0x7b,0xe9,0xa4,0x62,0xa9,0x66,0x2b}}
+};
+
+static inline int cmp_string( const unsigned char *str, ULONG len, const unsigned char *str2, ULONG len2 )
+{
+ if (len < len2) return -1;
+ else if (len > len2) return 1;
+ while (len--)
+ {
+ if (*str == *str2) { str++; str2++; }
+ else return *str - *str2;
+ }
+ return 0;
+}
+
+/* return -1 and string id if found, sort index if not found */
+static int find_string( const unsigned char *data, ULONG len, ULONG *id )
+{
+ int i, c, min = 0, max = dict_builtin.stringCount - 1;
+ while (min <= max)
+ {
+ i = (min + max) / 2;
+ c = cmp_string( data, len,
+ dict_builtin.strings[dict_sorted[i]].bytes,
+ dict_builtin.strings[dict_sorted[i]].length );
+ if (c < 0)
+ max = i - 1;
+ else if (c > 0)
+ min = i + 1;
+ else
+ {
+ *id = dict_builtin.strings[dict_sorted[i]].id;
+ return -1;
+ }
+ }
+ return max + 1;
+}
+
+#define MIN_DICTIONARY_SIZE 256
+#define MAX_DICTIONARY_SIZE 2048
+
+static BOOL grow_dict( ULONG size )
+{
+ WS_XML_STRING *tmp;
+ ULONG new_size, *tmp_sorted;
+
+ if (dict_size >= dict_builtin.stringCount + size) return TRUE;
+ if (dict_size + size > MAX_DICTIONARY_SIZE) return FALSE;
+
+ if (!dict_builtin.strings)
+ {
+ new_size = max( MIN_DICTIONARY_SIZE, size );
+ if (!(dict_builtin.strings = heap_alloc( new_size * sizeof(WS_XML_STRING) ))) return FALSE;
+ if (!(dict_sorted = heap_alloc( new_size * sizeof(ULONG) )))
+ {
+ heap_free( dict_builtin.strings );
+ dict_builtin.strings = NULL;
+ return FALSE;
+ }
+ dict_size = new_size;
+ return TRUE;
+ }
+
+ new_size = max( dict_size * 2, size );
+ if (!(tmp = heap_realloc( dict_builtin.strings, new_size * sizeof(*tmp) ))) return FALSE;
+ dict_builtin.strings = tmp;
+ if (!(tmp_sorted = heap_realloc( dict_sorted, new_size * sizeof(*tmp_sorted) ))) return FALSE;
+ dict_sorted = tmp_sorted;
+
+ dict_size = new_size;
+ return TRUE;
+}
+
+static BOOL insert_string( unsigned char *data, ULONG len, int i, ULONG *ret_id )
+{
+ ULONG id = dict_builtin.stringCount;
+ if (!grow_dict( 1 )) return FALSE;
+ memmove( &dict_sorted[i] + 1, &dict_sorted[i], (dict_builtin.stringCount - i) * sizeof(WS_XML_STRING *) );
+ dict_sorted[i] = id;
+
+ dict_builtin.strings[id].length = len;
+ dict_builtin.strings[id].bytes = data;
+ dict_builtin.strings[id].dictionary = &dict_builtin;
+ dict_builtin.strings[id].id = id;
+ dict_builtin.stringCount++;
+ *ret_id = id;
+ return TRUE;
+}
+
+static HRESULT add_xml_string( WS_XML_STRING *str )
+{
+ int index;
+ ULONG id;
+
+ if (str->dictionary) return S_OK;
+
+ EnterCriticalSection( &dict_cs );
+ if ((index = find_string( str->bytes, str->length, &id )) == -1)
+ {
+ heap_free( str->bytes );
+ *str = dict_builtin.strings[id];
+ LeaveCriticalSection( &dict_cs );
+ return S_OK;
+ }
+ if (insert_string( str->bytes, str->length, index, &id ))
+ {
+ *str = dict_builtin.strings[id];
+ LeaveCriticalSection( &dict_cs );
+ return S_OK;
+ }
+ LeaveCriticalSection( &dict_cs );
+ return WS_E_QUOTA_EXCEEDED;
+}
+
+WS_XML_STRING *alloc_xml_string( const unsigned char *data, ULONG len )
+{
+ WS_XML_STRING *ret;
+
+ if (!(ret = heap_alloc_zero( sizeof(*ret) ))) return NULL;
+ if ((ret->length = len) && !(ret->bytes = heap_alloc( len )))
+ {
+ heap_free( ret );
+ return NULL;
+ }
+ if (data)
+ {
+ memcpy( ret->bytes, data, len );
+ if (add_xml_string( ret ) != S_OK) WARN( "string not added to dictionary\n" );
+ }
+ return ret;
+}
+
+void free_xml_string( WS_XML_STRING *str )
+{
+ if (!str) return;
+ if (!str->dictionary) heap_free( str->bytes );
+ heap_free( str );
+}
+
+WS_XML_STRING *dup_xml_string( const WS_XML_STRING *src )
+{
+ WS_XML_STRING *ret;
+ unsigned char *data;
+ int index;
+ ULONG id;
+
+ if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+ if (src->dictionary)
+ {
+ *ret = *src;
+ return ret;
+ }
+
+ EnterCriticalSection( &dict_cs );
+ if ((index = find_string( src->bytes, src->length, &id )) == -1)
+ {
+ *ret = dict_builtin.strings[id];
+ LeaveCriticalSection( &dict_cs );
+ return ret;
+ }
+ if (!(data = heap_alloc( src->length )))
+ {
+ heap_free( ret );
+ LeaveCriticalSection( &dict_cs );
+ return NULL;
+ }
+ memcpy( data, src->bytes, src->length );
+ if (insert_string( data, src->length, index, &id ))
+ {
+ *ret = dict_builtin.strings[id];
+ LeaveCriticalSection( &dict_cs );
+ return ret;
+ }
+ LeaveCriticalSection( &dict_cs );
+
+ WARN( "string not added to dictionary\n" );
+ ret->length = src->length;
+ ret->bytes = data;
+ ret->dictionary = NULL;
+ ret->id = 0;
+ return ret;
+}
+
struct node *alloc_node( WS_XML_NODE_TYPE type )
{
struct node *ret;
@@ -84,9 +280,9 @@ struct node *alloc_node( WS_XML_NODE_TYPE type )
void free_attribute( WS_XML_ATTRIBUTE *attr )
{
if (!attr) return;
- heap_free( attr->prefix );
- heap_free( attr->localName );
- heap_free( attr->ns );
+ free_xml_string( attr->prefix );
+ free_xml_string( attr->localName );
+ free_xml_string( attr->ns );
heap_free( attr->value );
heap_free( attr );
}
@@ -103,9 +299,9 @@ void free_node( struct node *node )
for (i = 0; i < elem->attributeCount; i++) free_attribute( elem->attributes[i] );
heap_free( elem->attributes );
- heap_free( elem->prefix );
- heap_free( elem->localName );
- heap_free( elem->ns );
+ free_xml_string( elem->prefix );
+ free_xml_string( elem->localName );
+ free_xml_string( elem->ns );
break;
}
case WS_XML_NODE_TYPE_TEXT:
@@ -351,8 +547,8 @@ enum reader_state
struct prefix
{
- WS_XML_STRING str;
- WS_XML_STRING ns;
+ WS_XML_STRING *str;
+ WS_XML_STRING *ns;
};
struct reader
@@ -411,13 +607,10 @@ static void clear_prefixes( struct prefix *prefixes, ULONG count )
ULONG i;
for (i = 0; i < count; i++)
{
- heap_free( prefixes[i].str.bytes );
- prefixes[i].str.bytes = NULL;
- prefixes[i].str.length = 0;
-
- heap_free( prefixes[i].ns.bytes );
- prefixes[i].ns.bytes = NULL;
- prefixes[i].ns.length = 0;
+ free_xml_string( prefixes[i].str );
+ prefixes[i].str = NULL;
+ free_xml_string( prefixes[i].ns );
+ prefixes[i].ns = NULL;
}
}
@@ -425,17 +618,11 @@ static HRESULT set_prefix( struct prefix *prefix, const WS_XML_STRING *str, cons
{
if (str)
{
- heap_free( prefix->str.bytes );
- if (!(prefix->str.bytes = heap_alloc( str->length ))) return E_OUTOFMEMORY;
- memcpy( prefix->str.bytes, str->bytes, str->length );
- prefix->str.length = str->length;
+ free_xml_string( prefix->str );
+ if (!(prefix->str = dup_xml_string( str ))) return E_OUTOFMEMORY;
}
-
- heap_free( prefix->ns.bytes );
- if (!(prefix->ns.bytes = heap_alloc( ns->length ))) return E_OUTOFMEMORY;
- memcpy( prefix->ns.bytes, ns->bytes, ns->length );
- prefix->ns.length = ns->length;
-
+ if (prefix->ns) free_xml_string( prefix->ns );
+ if (!(prefix->ns = dup_xml_string( ns ))) return E_OUTOFMEMORY;
return S_OK;
}
@@ -446,7 +633,7 @@ static HRESULT bind_prefix( struct reader *reader, const WS_XML_STRING *prefix,
for (i = 0; i < reader->nb_prefixes; i++)
{
- if (WsXmlStringEquals( prefix, &reader->prefixes[i].str, NULL ) == S_OK)
+ if (WsXmlStringEquals( prefix, reader->prefixes[i].str, NULL ) == S_OK)
return set_prefix( &reader->prefixes[i], NULL, ns );
}
if (i >= reader->nb_prefixes_allocated)
@@ -457,7 +644,6 @@ static HRESULT bind_prefix( struct reader *reader, const WS_XML_STRING *prefix,
reader->prefixes = tmp;
reader->nb_prefixes_allocated *= 2;
}
-
if ((hr = set_prefix( &reader->prefixes[i], prefix, ns )) != S_OK) return hr;
reader->nb_prefixes++;
return S_OK;
@@ -468,8 +654,8 @@ static const WS_XML_STRING *get_namespace( struct reader *reader, const WS_XML_S
ULONG i;
for (i = 0; i < reader->nb_prefixes; i++)
{
- if (WsXmlStringEquals( prefix, &reader->prefixes[i].str, NULL ) == S_OK)
- return &reader->prefixes[i].ns;
+ if (WsXmlStringEquals( prefix, reader->prefixes[i].str, NULL ) == S_OK)
+ return reader->prefixes[i].ns;
}
return NULL;
}
@@ -511,7 +697,9 @@ static void free_reader( struct reader *reader )
static HRESULT init_reader( struct reader *reader )
{
+ static const WS_XML_STRING empty = {0, NULL};
struct node *node;
+ HRESULT hr;
reader->state = READER_STATE_INITIAL;
destroy_nodes( reader->root );
@@ -519,10 +707,12 @@ static HRESULT init_reader( struct reader *reader )
reader->current_attr = 0;
clear_prefixes( reader->prefixes, reader->nb_prefixes );
reader->nb_prefixes = 1;
+ if ((hr = bind_prefix( reader, &empty, &empty )) != S_OK) return hr;
+
if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
read_insert_eof( reader, node );
reader->input_enc = WS_XML_READER_ENCODING_TYPE_TEXT;
- reader->dict = NULL;
+ reader->dict = &dict_builtin;
return S_OK;
}
@@ -786,33 +976,6 @@ HRESULT WINAPI WsGetXmlAttribute( WS_XML_READER *handle, const WS_XML_STRING *at
return E_NOTIMPL;
}
-WS_XML_STRING *alloc_xml_string( const unsigned char *data, ULONG len )
-{
- WS_XML_STRING *ret;
-
- if (!(ret = heap_alloc( sizeof(*ret) + len ))) return NULL;
- ret->length = len;
- ret->bytes = len ? (BYTE *)(ret + 1) : NULL;
- ret->dictionary = NULL;
- ret->id = 0;
- if (data) memcpy( ret->bytes, data, 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;
@@ -1036,7 +1199,7 @@ static HRESULT parse_name( const unsigned char *str, ULONG len, WS_XML_STRING **
if (!(*prefix = alloc_xml_string( prefix_ptr, prefix_len ))) return E_OUTOFMEMORY;
if (!(*localname = alloc_xml_string( localname_ptr, localname_len )))
{
- heap_free( *prefix );
+ free_xml_string( *prefix );
*prefix = NULL;
return E_OUTOFMEMORY;
}
@@ -1274,8 +1437,12 @@ static HRESULT read_string( struct reader *reader, WS_XML_STRING **str )
HRESULT hr;
if ((hr = read_int31( reader, &len )) != S_OK) return hr;
if (!(*str = alloc_xml_string( NULL, len ))) return E_OUTOFMEMORY;
- if ((hr = read_bytes( reader, (*str)->bytes, len )) == S_OK) return S_OK;
- heap_free( *str );
+ if ((hr = read_bytes( reader, (*str)->bytes, len )) == S_OK)
+ {
+ if (add_xml_string( *str ) != S_OK) WARN( "string not added to dictionary\n" );
+ return S_OK;
+ }
+ free_xml_string( *str );
return hr;
}
@@ -1350,11 +1517,11 @@ static HRESULT read_attribute_text( struct reader *reader, WS_XML_ATTRIBUTE **re
if ((hr = parse_name( start, len, &prefix, &localname )) != S_OK) goto error;
if (WsXmlStringEquals( prefix, &xmlns, NULL ) == S_OK)
{
- heap_free( prefix );
+ free_xml_string( prefix );
attr->isXmlNs = 1;
if (!(attr->prefix = alloc_xml_string( localname->bytes, localname->length )))
{
- heap_free( localname );
+ free_xml_string( localname );
hr = E_OUTOFMEMORY;
goto error;
}
@@ -1524,15 +1691,15 @@ static HRESULT set_namespaces( struct reader *reader, WS_XML_ELEMENT_NODE *elem
ULONG i;
if (!(ns = get_namespace( reader, elem->prefix ))) return WS_E_INVALID_FORMAT;
- if (!(elem->ns = alloc_xml_string( ns->bytes, ns->length ))) return E_OUTOFMEMORY;
- if (!elem->ns->length) elem->ns->bytes = (BYTE *)(elem->ns + 1); /* quirk */
+ if (!(elem->ns = dup_xml_string( ns ))) return E_OUTOFMEMORY;
for (i = 0; i < elem->attributeCount; i++)
{
WS_XML_ATTRIBUTE *attr = elem->attributes[i];
if (attr->isXmlNs || WsXmlStringEquals( attr->prefix, &xml, NULL ) == S_OK) continue;
if (!(ns = get_namespace( reader, attr->prefix ))) return WS_E_INVALID_FORMAT;
- if (!(attr->ns = alloc_xml_string( ns->bytes, ns->length ))) return E_OUTOFMEMORY;
+ if (!(attr->ns = alloc_xml_string( NULL, ns->length ))) return E_OUTOFMEMORY;
+ if (attr->ns->length) memcpy( attr->ns->bytes, ns->bytes, ns->length );
}
return S_OK;
}
@@ -1990,8 +2157,8 @@ static HRESULT read_endelement_text( struct reader *reader )
if ((hr = parse_name( start, len, &prefix, &localname )) != S_OK) return hr;
parent = find_startelement( reader, prefix, localname );
- heap_free( prefix );
- heap_free( localname );
+ free_xml_string( prefix );
+ free_xml_string( localname );
if (!parent) return WS_E_INVALID_FORMAT;
reader->current = LIST_ENTRY( list_tail( &parent->children ), struct node, entry );
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index 7eab4b8..0e21e86 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -4554,7 +4554,7 @@ static void test_binary_encoding(void)
ok( elem->prefix->bytes == NULL, "bytes set\n" );
ok( elem->localName->length == 1, "got %u\n", elem->localName->length );
ok( !memcmp( elem->localName->bytes, "t", 1 ), "wrong name\n" );
- todo_wine ok( elem->localName->dictionary != NULL, "dictionary not set\n" );
+ ok( elem->localName->dictionary != NULL, "dictionary not set\n" );
ok( !elem->ns->length, "got %u\n", elem->ns->length );
ok( elem->ns->bytes != NULL, "bytes not set\n" );
ok( !elem->attributeCount, "got %u\n", elem->attributeCount );
diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h
index d117eba..db839b4 100644
--- a/dlls/webservices/webservices_private.h
+++ b/dlls/webservices/webservices_private.h
@@ -36,6 +36,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;
+void free_xml_string( 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;
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index d22d5e4..1b1ac5d 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -83,6 +83,7 @@ struct writer
WS_XML_WRITER_OUTPUT_TYPE output_type;
struct xmlbuf *output_buf;
WS_HEAP *output_heap;
+ WS_XML_DICTIONARY *dict;
ULONG prop_count;
struct prop prop[sizeof(writer_props)/sizeof(writer_props[0])];
};
@@ -109,7 +110,7 @@ static struct writer *alloc_writer(void)
static void free_writer( struct writer *writer )
{
destroy_nodes( writer->root );
- heap_free( writer->current_ns );
+ free_xml_string( writer->current_ns );
WsFreeHeap( writer->output_heap );
writer->cs.DebugInfo->Spare[0] = 0;
@@ -157,13 +158,14 @@ static HRESULT init_writer( struct writer *writer )
writer->write_bufptr = NULL;
destroy_nodes( writer->root );
writer->root = writer->current = NULL;
- heap_free( writer->current_ns );
+ free_xml_string( writer->current_ns );
writer->current_ns = NULL;
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;
+ writer->dict = NULL;
return S_OK;
}
@@ -379,7 +381,9 @@ HRESULT WINAPI WsSetOutput( WS_XML_WRITER *handle, const WS_XML_WRITER_ENCODING
}
case WS_XML_WRITER_ENCODING_TYPE_BINARY:
{
+ WS_XML_WRITER_BINARY_ENCODING *bin = (WS_XML_WRITER_BINARY_ENCODING *)encoding;
writer->output_enc = WS_XML_WRITER_ENCODING_TYPE_BINARY;
+ writer->dict = bin->staticDictionary;
break;
}
default:
@@ -665,25 +669,26 @@ static HRESULT write_attribute_value_bin( struct writer *writer, const WS_XML_TE
}
}
-static enum record_type get_attr_record_type( const WS_XML_ATTRIBUTE *attr )
+static enum record_type get_attr_record_type( const WS_XML_ATTRIBUTE *attr, BOOL use_dict )
{
if (!attr->prefix || !attr->prefix->length)
{
- if (attr->localName->dictionary) return RECORD_SHORT_DICTIONARY_ATTRIBUTE;
+ if (use_dict) 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';
+ if (use_dict) 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;
+ if (use_dict) 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 );
+ BOOL use_dict = (writer->dict && attr->localName->dictionary == writer->dict);
+ enum record_type type = get_attr_record_type( attr, use_dict );
HRESULT hr;
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
@@ -817,20 +822,21 @@ static HRESULT write_namespace_attribute_text( struct writer *writer, const WS_X
return S_OK;
}
-static enum record_type get_xmlns_record_type( const WS_XML_ATTRIBUTE *attr )
+static enum record_type get_xmlns_record_type( const WS_XML_ATTRIBUTE *attr, BOOL use_dict )
{
if (!attr->prefix || !attr->prefix->length)
{
- if (attr->ns->dictionary) return RECORD_SHORT_DICTIONARY_XMLNS_ATTRIBUTE;
+ if (use_dict) return RECORD_SHORT_DICTIONARY_XMLNS_ATTRIBUTE;
return RECORD_SHORT_XMLNS_ATTRIBUTE;
}
- if (attr->ns->dictionary) return RECORD_DICTIONARY_XMLNS_ATTRIBUTE;
+ if (use_dict) return RECORD_DICTIONARY_XMLNS_ATTRIBUTE;
return RECORD_XMLNS_ATTRIBUTE;
};
static HRESULT write_namespace_attribute_bin( struct writer *writer, const WS_XML_ATTRIBUTE *attr )
{
- enum record_type type = get_xmlns_record_type( attr );
+ BOOL use_dict = (writer->dict && attr->ns->dictionary == writer->dict);
+ enum record_type type = get_xmlns_record_type( attr, use_dict );
HRESULT hr;
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
@@ -932,7 +938,7 @@ static HRESULT set_current_namespace( struct writer *writer, const WS_XML_STRING
{
WS_XML_STRING *str;
if (!(str = dup_xml_string( ns ))) return E_OUTOFMEMORY;
- heap_free( writer->current_ns );
+ free_xml_string( writer->current_ns );
writer->current_ns = str;
return S_OK;
}
@@ -1029,26 +1035,27 @@ static HRESULT write_startelement_text( struct writer *writer )
return write_attributes( writer, elem );
}
-static enum record_type get_elem_record_type( const WS_XML_ELEMENT_NODE *elem )
+static enum record_type get_elem_record_type( const WS_XML_ELEMENT_NODE *elem, BOOL use_dict )
{
if (!elem->prefix || !elem->prefix->length)
{
- if (elem->localName->dictionary) return RECORD_SHORT_DICTIONARY_ELEMENT;
+ if (use_dict) 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';
+ if (use_dict) 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;
+ if (use_dict) return RECORD_DICTIONARY_ELEMENT;
return RECORD_ELEMENT;
};
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 );
+ BOOL use_dict = (writer->dict && elem->localName->dictionary == writer->dict);
+ enum record_type type = get_elem_record_type( elem, use_dict );
HRESULT hr;
if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
--
2.1.4
More information about the wine-patches
mailing list