diff --git a/dlls/webservices/msg.c b/dlls/webservices/msg.c index 37ce3a3bd30..7b7b52668a9 100644 --- a/dlls/webservices/msg.c +++ b/dlls/webservices/msg.c @@ -1833,7 +1833,7 @@ HRESULT message_set_action( WS_MESSAGE *handle, const WS_XML_STRING *action ) else { WS_XML_STRING *str; - if (!(str = dup_xml_string( action ))) hr = E_OUTOFMEMORY; + if (!(str = dup_xml_string( action, FALSE ))) hr = E_OUTOFMEMORY; else { free_xml_string( msg->action ); diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 50431bfacfe..798e5f75f1e 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -156,9 +156,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 = dup_xml_string( prefix ))) goto error; - if (!(dst->localName = dup_xml_string( localname ))) goto error; - if (!(dst->ns = dup_xml_string( ns ))) goto error; + else if (!(dst->prefix = dup_xml_string( prefix, FALSE ))) goto error; + if (!(dst->localName = dup_xml_string( localname, FALSE ))) goto error; + if (!(dst->ns = dup_xml_string( ns, FALSE ))) goto error; if (text) { @@ -209,9 +209,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 = 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; + if (prefix && !(dst->prefix = dup_xml_string( prefix, FALSE ))) goto error; + if (localname && !(dst->localName = dup_xml_string( localname, FALSE ))) goto error; + if (ns && !(dst->ns = dup_xml_string( ns, FALSE ))) goto error; return node; error: @@ -420,10 +420,10 @@ static HRESULT set_prefix( struct prefix *prefix, const WS_XML_STRING *str, cons if (str) { free_xml_string( prefix->str ); - if (!(prefix->str = dup_xml_string( str ))) return E_OUTOFMEMORY; + if (!(prefix->str = dup_xml_string( str, FALSE ))) return E_OUTOFMEMORY; } if (prefix->ns) free_xml_string( prefix->ns ); - if (!(prefix->ns = dup_xml_string( ns ))) return E_OUTOFMEMORY; + if (!(prefix->ns = dup_xml_string( ns, FALSE ))) return E_OUTOFMEMORY; return S_OK; } @@ -1113,7 +1113,7 @@ static HRESULT parse_qname( const BYTE *str, ULONG len, WS_XML_STRING **prefix_r if ((hr = split_qname( str, len, &prefix, &localname )) != S_OK) return hr; if (!(*prefix_ret = alloc_xml_string( NULL, prefix.length ))) return E_OUTOFMEMORY; - if (!(*localname_ret = dup_xml_string( &localname ))) + if (!(*localname_ret = dup_xml_string( &localname, FALSE ))) { free_xml_string( *prefix_ret ); return E_OUTOFMEMORY; @@ -1821,7 +1821,7 @@ 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 = dup_xml_string( ns ))) return E_OUTOFMEMORY; + if (!(elem->ns = dup_xml_string( ns, FALSE ))) return E_OUTOFMEMORY; for (i = 0; i < elem->attributeCount; i++) { diff --git a/dlls/webservices/string.c b/dlls/webservices/string.c index e53a364a0d1..75e8b752ca8 100644 --- a/dlls/webservices/string.c +++ b/dlls/webservices/string.c @@ -210,7 +210,7 @@ void free_xml_string( WS_XML_STRING *str ) heap_free( str ); } -WS_XML_STRING *dup_xml_string( const WS_XML_STRING *src ) +WS_XML_STRING *dup_xml_string( const WS_XML_STRING *src, BOOL use_static_dict ) { WS_XML_STRING *ret; unsigned char *data; @@ -224,6 +224,11 @@ WS_XML_STRING *dup_xml_string( const WS_XML_STRING *src ) *ret = *src; return ret; } + if (use_static_dict && (index = find_string( &dict_builtin_static, src->bytes, src->length, &id )) == -1) + { + *ret = dict_builtin_static.dict.strings[id]; + return ret; + } EnterCriticalSection( &dict_cs ); if ((index = find_string( &dict_builtin, src->bytes, src->length, &id )) == -1) { diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index 958733ccd0b..da032136b19 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -51,10 +51,11 @@ int find_string( const struct dictionary *, const unsigned char *, ULONG, ULONG HRESULT insert_string( struct dictionary *, unsigned char *, ULONG, int, ULONG * ) DECLSPEC_HIDDEN; HRESULT CALLBACK insert_string_cb( void *, const WS_XML_STRING *, BOOL *, ULONG *, WS_ERROR * ) DECLSPEC_HIDDEN; void clear_dict( struct dictionary * ) DECLSPEC_HIDDEN; +HRESULT writer_enable_lookup( WS_XML_WRITER * ) 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_STRING *dup_xml_string( const WS_XML_STRING *, BOOL ) DECLSPEC_HIDDEN; HRESULT add_xml_string( WS_XML_STRING * ) DECLSPEC_HIDDEN; void free_xml_string( WS_XML_STRING * ) DECLSPEC_HIDDEN; HRESULT append_attribute( WS_XML_ELEMENT_NODE *, WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN; diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 7216fc17f2c..4eba2dbeea2 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -86,6 +86,7 @@ struct writer struct xmlbuf *output_buf; WS_HEAP *output_heap; const WS_XML_DICTIONARY *dict; + BOOL dict_do_lookup; WS_DYNAMIC_STRING_CALLBACK dict_cb; void *dict_cb_state; ULONG prop_count; @@ -171,6 +172,7 @@ static HRESULT init_writer( struct writer *writer ) writer->output_enc = WS_XML_WRITER_ENCODING_TYPE_TEXT; writer->output_charset = WS_CHARSET_UTF8; writer->dict = NULL; + writer->dict_do_lookup = FALSE; writer->dict_cb = NULL; writer->dict_cb_state = NULL; return S_OK; @@ -1131,12 +1133,12 @@ static HRESULT add_namespace_attribute( struct writer *writer, const WS_XML_STRI attr->singleQuote = !!single; attr->isXmlNs = 1; - if (prefix && !(attr->prefix = dup_xml_string( prefix ))) + if (prefix && !(attr->prefix = dup_xml_string( prefix, writer->dict_do_lookup ))) { free_attribute( attr ); return E_OUTOFMEMORY; } - if (!(attr->ns = dup_xml_string( ns ))) + if (!(attr->ns = dup_xml_string( ns, writer->dict_do_lookup ))) { free_attribute( attr ); return E_OUTOFMEMORY; @@ -1179,7 +1181,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 = dup_xml_string( ns ))) return E_OUTOFMEMORY; + if (!(str = dup_xml_string( ns, writer->dict_do_lookup ))) return E_OUTOFMEMORY; free_xml_string( writer->current_ns ); writer->current_ns = str; return S_OK; @@ -1545,17 +1547,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 = dup_xml_string( prefix ))) + if (prefix && !(attr->prefix = dup_xml_string( prefix, writer->dict_do_lookup ))) { free_attribute( attr ); return E_OUTOFMEMORY; } - if (!(attr->localName = dup_xml_string( localname ))) + if (!(attr->localName = dup_xml_string( localname, writer->dict_do_lookup ))) { free_attribute( attr ); return E_OUTOFMEMORY; } - if (!(attr->ns = dup_xml_string( ns ))) + if (!(attr->ns = dup_xml_string( ns, writer->dict_do_lookup ))) { free_attribute( attr ); return E_OUTOFMEMORY; @@ -1750,17 +1752,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 = dup_xml_string( prefix ))) + if (prefix && !(elem->prefix = dup_xml_string( prefix, writer->dict_do_lookup ))) { free_node( node ); return E_OUTOFMEMORY; } - if (!(elem->localName = dup_xml_string( localname ))) + if (!(elem->localName = dup_xml_string( localname, writer->dict_do_lookup ))) { free_node( node ); return E_OUTOFMEMORY; } - if (!(elem->ns = dup_xml_string( ns ))) + if (!(elem->ns = dup_xml_string( ns, writer->dict_do_lookup ))) { free_node( node ); return E_OUTOFMEMORY; @@ -4730,3 +4732,21 @@ done: LeaveCriticalSection( &writer->cs ); return hr; } + +HRESULT writer_enable_lookup( WS_XML_WRITER *handle ) +{ + struct writer *writer = (struct writer *)handle; + + EnterCriticalSection( &writer->cs ); + + if (writer->magic != WRITER_MAGIC) + { + LeaveCriticalSection( &writer->cs ); + return E_INVALIDARG; + } + + writer->dict_do_lookup = TRUE; + + LeaveCriticalSection( &writer->cs ); + return S_OK; +}