webservices: Send incremental string table updates with messages in the same session.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d120f7f841
commit
3c3ab8911e
|
@ -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 );
|
||||
/* 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 );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue