[PATCH 5/5] webservices: Send incremental string table updates with messages in the same session.
Hans Leidekker
hans at codeweavers.com
Wed Jun 20 08:04:48 CDT 2018
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/webservices/channel.c | 31 +++++++++++++++++--------------
dlls/webservices/string.c | 18 +++++++++++++++++-
dlls/webservices/webservices_private.h | 3 +++
dlls/webservices/writer.c | 19 +++++++++++++++++++
4 files changed, 56 insertions(+), 15 deletions(-)
diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c
index 79d431f279..5963faf00d 100644
--- a/dlls/webservices/channel.c
+++ b/dlls/webservices/channel.c
@@ -1009,22 +1009,26 @@ static inline ULONG size_length( ULONG size )
return 5;
}
-static ULONG string_table_size( const WS_XML_DICTIONARY *dict )
+static ULONG string_table_size( const struct dictionary *dict )
{
ULONG i, size = 0;
- for (i = 0; i < dict->stringCount; i++)
- size += size_length( dict->strings[i].length ) + dict->strings[i].length;
+ for (i = 0; i < dict->dict.stringCount; i++)
+ {
+ if (dict->sequence[i] == dict->current_sequence)
+ size += size_length( dict->dict.strings[i].length ) + dict->dict.strings[i].length;
+ }
return size;
}
-static HRESULT send_string_table( SOCKET socket, const WS_XML_DICTIONARY *dict )
+static HRESULT send_string_table( SOCKET socket, const struct dictionary *dict )
{
ULONG i;
HRESULT hr;
- for (i = 0; i < dict->stringCount; i++)
+ for (i = 0; i < dict->dict.stringCount; i++)
{
- if ((hr = send_size( socket, dict->strings[i].length )) != S_OK) return hr;
- if ((hr = send_bytes( socket, dict->strings[i].bytes, dict->strings[i].length )) != S_OK) return hr;
+ if (dict->sequence[i] != dict->current_sequence) continue;
+ if ((hr = send_size( socket, dict->dict.strings[i].length )) != S_OK) return hr;
+ if ((hr = send_bytes( socket, dict->dict.strings[i].bytes, dict->dict.strings[i].length )) != S_OK) return hr;
}
return S_OK;
}
@@ -1154,13 +1158,13 @@ static HRESULT receive_preamble_ack( struct channel *channel )
static HRESULT send_sized_envelope( struct channel *channel, BYTE *data, ULONG len )
{
- ULONG table_size = string_table_size( &channel->dict_send.dict );
+ ULONG table_size = string_table_size( &channel->dict_send );
HRESULT hr;
if ((hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_SIZED_ENVELOPE )) != S_OK) return hr;
if ((hr = send_size( channel->u.tcp.socket, size_length(table_size) + table_size + len )) != S_OK) return hr;
if ((hr = send_size( channel->u.tcp.socket, table_size )) != S_OK) return hr;
- if ((hr = send_string_table( channel->u.tcp.socket, &channel->dict_send.dict )) != S_OK) return hr;
+ if ((hr = send_string_table( channel->u.tcp.socket, &channel->dict_send )) != S_OK) return hr;
return send_bytes( channel->u.tcp.socket, data, len );
}
@@ -1285,11 +1289,8 @@ static HRESULT init_writer( struct channel *channel )
return WsSetOutput( channel->writer, &text.encoding, &buf.output, NULL, 0, NULL );
case WS_ENCODING_XML_BINARY_SESSION_1:
- clear_dict( &channel->dict_send );
- bin.staticDictionary = (WS_XML_DICTIONARY *)&dict_builtin_static.dict;
- bin.dynamicStringCallback = dict_cb;
- bin.dynamicStringCallbackState = &channel->dict_send;
- return WsSetOutput( channel->writer, &bin.encoding, &buf.output, NULL, 0, NULL );
+ bin.staticDictionary = (WS_XML_DICTIONARY *)&dict_builtin_static.dict;
+ /* fall through */
case WS_ENCODING_XML_BINARY_1:
return WsSetOutput( channel->writer, &bin.encoding, &buf.output, NULL, 0, NULL );
@@ -1307,6 +1308,8 @@ static HRESULT write_message( struct channel *channel, WS_MESSAGE *msg, const WS
if ((hr = writer_set_lookup( channel->writer, TRUE )) != S_OK) return hr;
if ((hr = WsWriteEnvelopeStart( msg, channel->writer, NULL, NULL, NULL )) != S_OK) return hr;
if ((hr = writer_set_lookup( channel->writer, FALSE )) != S_OK) return hr;
+ channel->dict_send.current_sequence++;
+ if ((hr = writer_set_dict_callback( channel->writer, dict_cb, &channel->dict_send )) != S_OK) return hr;
if ((hr = WsWriteBody( msg, desc, option, body, size, NULL )) != S_OK) return hr;
return WsWriteEnvelopeEnd( msg, NULL );
}
diff --git a/dlls/webservices/string.c b/dlls/webservices/string.c
index 18c55e3833..0bb77df946 100644
--- a/dlls/webservices/string.c
+++ b/dlls/webservices/string.c
@@ -91,7 +91,7 @@ int find_string( const struct dictionary *dict, const unsigned char *data, ULONG
static HRESULT grow_dict( struct dictionary *dict, ULONG size )
{
WS_XML_STRING *tmp;
- ULONG new_size, *tmp_sorted;
+ ULONG new_size, *tmp_sorted, *tmp_sequence;
assert( !dict->dict.isConst );
if (dict->size >= dict->dict.stringCount + size) return S_OK;
@@ -107,6 +107,14 @@ static HRESULT grow_dict( struct dictionary *dict, ULONG size )
dict->dict.strings = NULL;
return E_OUTOFMEMORY;
}
+ if (!(dict->sequence = heap_alloc( new_size * sizeof(*dict->sequence) )))
+ {
+ heap_free( dict->dict.strings );
+ dict->dict.strings = NULL;
+ heap_free( dict->sorted );
+ dict->sorted = NULL;
+ return E_OUTOFMEMORY;
+ }
dict->size = new_size;
return S_OK;
}
@@ -116,6 +124,8 @@ static HRESULT grow_dict( struct dictionary *dict, ULONG size )
dict->dict.strings = tmp;
if (!(tmp_sorted = heap_realloc( dict->sorted, new_size * sizeof(*tmp_sorted) ))) return E_OUTOFMEMORY;
dict->sorted = tmp_sorted;
+ if (!(tmp_sequence = heap_realloc( dict->sequence, new_size * sizeof(*tmp_sequence) ))) return E_OUTOFMEMORY;
+ dict->sequence = tmp_sequence;
dict->size = new_size;
return S_OK;
@@ -131,6 +141,9 @@ void clear_dict( struct dictionary *dict )
dict->dict.stringCount = 0;
heap_free( dict->sorted );
dict->sorted = NULL;
+ heap_free( dict->sequence );
+ dict->sequence = NULL;
+ dict->current_sequence = 0;
dict->size = 0;
}
@@ -149,6 +162,9 @@ HRESULT insert_string( struct dictionary *dict, unsigned char *data, ULONG len,
dict->dict.strings[id].dictionary = &dict->dict;
dict->dict.strings[id].id = id;
dict->dict.stringCount++;
+
+ dict->sequence[id] = dict->current_sequence;
+
if (ret_id) *ret_id = id;
return S_OK;
}
diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h
index bfc3202a64..d981527bb2 100644
--- a/dlls/webservices/webservices_private.h
+++ b/dlls/webservices/webservices_private.h
@@ -43,6 +43,8 @@ struct dictionary
WS_XML_DICTIONARY dict;
ULONG *sorted;
ULONG size;
+ ULONG current_sequence;
+ ULONG *sequence;
};
struct dictionary dict_builtin DECLSPEC_HIDDEN;
const struct dictionary dict_builtin_static DECLSPEC_HIDDEN;
@@ -51,6 +53,7 @@ int find_string( const struct dictionary *, const unsigned char *, ULONG, ULONG
HRESULT insert_string( struct dictionary *, unsigned char *, ULONG, int, ULONG * ) DECLSPEC_HIDDEN;
void clear_dict( struct dictionary * ) DECLSPEC_HIDDEN;
HRESULT writer_set_lookup( WS_XML_WRITER *, BOOL ) DECLSPEC_HIDDEN;
+HRESULT writer_set_dict_callback( WS_XML_WRITER *, WS_DYNAMIC_STRING_CALLBACK, void * ) DECLSPEC_HIDDEN;
const char *debugstr_xmlstr( const WS_XML_STRING * ) DECLSPEC_HIDDEN;
WS_XML_STRING *alloc_xml_string( const unsigned char *, ULONG ) DECLSPEC_HIDDEN;
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index b3d130a52c..95d4caddb9 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -4866,3 +4866,22 @@ HRESULT writer_set_lookup( WS_XML_WRITER *handle, BOOL enable )
LeaveCriticalSection( &writer->cs );
return S_OK;
}
+
+HRESULT writer_set_dict_callback( WS_XML_WRITER *handle, WS_DYNAMIC_STRING_CALLBACK cb, void *state )
+{
+ struct writer *writer = (struct writer *)handle;
+
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ writer->dict_cb = cb;
+ writer->dict_cb_state = state;
+
+ LeaveCriticalSection( &writer->cs );
+ return S_OK;
+}
--
2.11.0
More information about the wine-devel
mailing list