webservices: Store standard headers in an XML buffer.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
31963d7da4
commit
f3d6591155
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
#include "webservices_private.h"
|
#include "webservices_private.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(webservices);
|
WINE_DEFAULT_DEBUG_CHANNEL(webservices);
|
||||||
|
@ -50,10 +51,15 @@ static const struct prop_desc msg_props[] =
|
||||||
|
|
||||||
struct header
|
struct header
|
||||||
{
|
{
|
||||||
WS_HEADER_TYPE type;
|
WS_HEADER_TYPE type;
|
||||||
WS_XML_STRING name;
|
BOOL mapped;
|
||||||
BOOL mapped;
|
WS_XML_STRING name;
|
||||||
WS_XML_UTF8_TEXT text;
|
WS_XML_STRING ns;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
WS_XML_BUFFER *buf;
|
||||||
|
WS_XML_STRING *text;
|
||||||
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msg
|
struct msg
|
||||||
|
@ -99,6 +105,8 @@ static struct msg *alloc_msg(void)
|
||||||
static void free_header( struct header *header )
|
static void free_header( struct header *header )
|
||||||
{
|
{
|
||||||
heap_free( header->name.bytes );
|
heap_free( header->name.bytes );
|
||||||
|
heap_free( header->ns.bytes );
|
||||||
|
if (header->mapped) heap_free( header->u.text );
|
||||||
heap_free( header );
|
heap_free( header );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,22 +393,6 @@ static const WS_XML_STRING *get_header_name( WS_HEADER_TYPE type )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT write_header( WS_XML_WRITER *writer, const struct header *header )
|
|
||||||
{
|
|
||||||
static const WS_XML_STRING prefix_s = {1, (BYTE *)"s"}, prefix_a = {1, (BYTE *)"a"};
|
|
||||||
static const WS_XML_STRING understand = {14, (BYTE *)"mustUnderstand"}, ns = {0, NULL};
|
|
||||||
const WS_XML_STRING *localname = get_header_name( header->type );
|
|
||||||
WS_XML_INT32_TEXT one = {{WS_XML_TEXT_TYPE_INT32}, 1};
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if ((hr = WsWriteStartElement( writer, &prefix_a, localname, &ns, NULL )) != S_OK) return hr;
|
|
||||||
if ((hr = WsWriteStartAttribute( writer, &prefix_s, &understand, &ns, FALSE, NULL )) != S_OK) return hr;
|
|
||||||
if ((hr = WsWriteText( writer, &one.text, NULL )) != S_OK) return hr;
|
|
||||||
if ((hr = WsWriteEndAttribute( writer, NULL )) != S_OK) return hr;
|
|
||||||
if ((hr = WsWriteText( writer, &header->text.text, NULL )) != S_OK) return hr;
|
|
||||||
return WsWriteEndElement( writer, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT write_envelope_start( struct msg *msg, WS_XML_WRITER *writer )
|
static HRESULT write_envelope_start( struct msg *msg, WS_XML_WRITER *writer )
|
||||||
{
|
{
|
||||||
static const char anonymous[] = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";
|
static const char anonymous[] = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";
|
||||||
|
@ -432,7 +424,8 @@ static HRESULT write_envelope_start( struct msg *msg, WS_XML_WRITER *writer )
|
||||||
|
|
||||||
for (i = 0; i < msg->header_count; i++)
|
for (i = 0; i < msg->header_count; i++)
|
||||||
{
|
{
|
||||||
if (!msg->header[i]->mapped && (hr = write_header( writer, msg->header[i] )) != S_OK) return hr;
|
if (msg->header[i]->mapped) continue;
|
||||||
|
if ((hr = WsWriteXmlBuffer( writer, msg->header[i]->u.buf, NULL )) != S_OK) return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg->version_addr == WS_ADDRESSING_VERSION_0_9)
|
if (msg->version_addr == WS_ADDRESSING_VERSION_0_9)
|
||||||
|
@ -452,7 +445,7 @@ static HRESULT write_envelope_start( struct msg *msg, WS_XML_WRITER *writer )
|
||||||
return WsWriteStartElement( writer, &prefix_s, &body, &ns_env, NULL ); /* <s:Body> */
|
return WsWriteStartElement( writer, &prefix_s, &body, &ns_env, NULL ); /* <s:Body> */
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT write_envelope_end( struct msg *msg, WS_XML_WRITER *writer )
|
static HRESULT write_envelope_end( WS_XML_WRITER *writer )
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
if ((hr = WsWriteEndElement( writer, NULL )) != S_OK) return hr; /* </s:Body> */
|
if ((hr = WsWriteEndElement( writer, NULL )) != S_OK) return hr; /* </s:Body> */
|
||||||
|
@ -466,7 +459,7 @@ static HRESULT write_envelope( struct msg *msg )
|
||||||
if (!msg->buf && (hr = WsCreateXmlBuffer( msg->heap, NULL, 0, &msg->buf, NULL )) != S_OK) return hr;
|
if (!msg->buf && (hr = WsCreateXmlBuffer( msg->heap, NULL, 0, &msg->buf, NULL )) != S_OK) return hr;
|
||||||
if ((hr = WsSetOutputToBuffer( msg->writer, msg->buf, NULL, 0, NULL )) != S_OK) return hr;
|
if ((hr = WsSetOutputToBuffer( msg->writer, msg->buf, NULL, 0, NULL )) != S_OK) return hr;
|
||||||
if ((hr = write_envelope_start( msg, msg->writer )) != S_OK) return hr;
|
if ((hr = write_envelope_start( msg, msg->writer )) != S_OK) return hr;
|
||||||
return write_envelope_end( msg, msg->writer );
|
return write_envelope_end( msg->writer );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -511,7 +504,7 @@ HRESULT WINAPI WsWriteEnvelopeEnd( WS_MESSAGE *handle, WS_ERROR *error )
|
||||||
if (!handle) return E_INVALIDARG;
|
if (!handle) return E_INVALIDARG;
|
||||||
if (msg->state != WS_MESSAGE_STATE_WRITING) return WS_E_INVALID_OPERATION;
|
if (msg->state != WS_MESSAGE_STATE_WRITING) return WS_E_INVALID_OPERATION;
|
||||||
|
|
||||||
if ((hr = write_envelope_end( msg, msg->writer_body )) != S_OK) return hr;
|
if ((hr = write_envelope_end( msg->writer_body )) != S_OK) return hr;
|
||||||
|
|
||||||
msg->state = WS_MESSAGE_STATE_DONE;
|
msg->state = WS_MESSAGE_STATE_DONE;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -567,87 +560,89 @@ HRESULT WINAPI WsInitializeMessage( WS_MESSAGE *handle, WS_MESSAGE_INITIALIZATIO
|
||||||
return write_envelope( msg );
|
return write_envelope( msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void set_utf8_text( WS_XML_UTF8_TEXT *text, BYTE *bytes, ULONG len )
|
static HRESULT grow_header_array( struct msg *msg, ULONG size )
|
||||||
{
|
{
|
||||||
text->text.textType = WS_XML_TEXT_TYPE_UTF8;
|
struct header **tmp;
|
||||||
text->value.bytes = bytes;
|
if (size <= msg->header_size) return S_OK;
|
||||||
text->value.length = len;
|
if (!(tmp = heap_realloc( msg->header, 2 * msg->header_size * sizeof(struct header *) )))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
msg->header = tmp;
|
||||||
|
msg->header_size *= 2;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT alloc_header( WS_HEADER_TYPE type, const WS_XML_STRING *name, BOOL mapped, WS_TYPE value_type,
|
static struct header *alloc_header( WS_HEADER_TYPE type, BOOL mapped, const WS_XML_STRING *name,
|
||||||
WS_WRITE_OPTION option, const void *value, ULONG size, struct header **ret )
|
const WS_XML_STRING *ns )
|
||||||
{
|
{
|
||||||
struct header *header;
|
struct header *ret;
|
||||||
|
if (!(ret = heap_alloc_zero( sizeof(*ret) ))) return NULL;
|
||||||
switch (value_type)
|
|
||||||
{
|
|
||||||
case WS_WSZ_TYPE:
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
const WCHAR *src;
|
|
||||||
|
|
||||||
if (option != WS_WRITE_REQUIRED_POINTER || size != sizeof(WCHAR *)) return E_INVALIDARG;
|
|
||||||
|
|
||||||
src = *(const WCHAR **)value;
|
|
||||||
len = WideCharToMultiByte( CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL ) - 1;
|
|
||||||
if (!(header = heap_alloc_zero( sizeof(*header) + len ))) return E_OUTOFMEMORY;
|
|
||||||
set_utf8_text( &header->text, (BYTE *)(header + 1), len );
|
|
||||||
WideCharToMultiByte( CP_UTF8, 0, src, -1, (char *)header->text.value.bytes, len, NULL, NULL );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WS_XML_STRING_TYPE:
|
|
||||||
{
|
|
||||||
const WS_XML_STRING *str = value;
|
|
||||||
|
|
||||||
if (option != WS_WRITE_REQUIRED_VALUE)
|
|
||||||
{
|
|
||||||
FIXME( "unhandled write option %u\n", option );
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
if (size != sizeof(*str)) return E_INVALIDARG;
|
|
||||||
if (!(header = heap_alloc_zero( sizeof(*header) + str->length ))) return E_OUTOFMEMORY;
|
|
||||||
set_utf8_text( &header->text, (BYTE *)(header + 1), str->length );
|
|
||||||
memcpy( header->text.value.bytes, str->bytes, str->length );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WS_STRING_TYPE:
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
const WS_STRING *str = value;
|
|
||||||
|
|
||||||
if (option != WS_WRITE_REQUIRED_VALUE)
|
|
||||||
{
|
|
||||||
FIXME( "unhandled write option %u\n", option );
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
if (size != sizeof(*str)) return E_INVALIDARG;
|
|
||||||
len = WideCharToMultiByte( CP_UTF8, 0, str->chars, str->length, NULL, 0, NULL, NULL );
|
|
||||||
if (!(header = heap_alloc_zero( sizeof(*header) + len ))) return E_OUTOFMEMORY;
|
|
||||||
set_utf8_text( &header->text, (BYTE *)(header + 1), len );
|
|
||||||
WideCharToMultiByte( CP_UTF8, 0, str->chars, str->length, (char *)header->text.value.bytes,
|
|
||||||
len, NULL, NULL );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
FIXME( "unhandled type %u\n", value_type );
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name && name->length)
|
if (name && name->length)
|
||||||
{
|
{
|
||||||
if (!(header->name.bytes = heap_alloc( name->length )))
|
if (!(ret->name.bytes = heap_alloc( name->length )))
|
||||||
{
|
{
|
||||||
heap_free( header );
|
free_header( ret );
|
||||||
return E_OUTOFMEMORY;
|
return NULL;
|
||||||
}
|
}
|
||||||
memcpy( header->name.bytes, name->bytes, name->length );
|
memcpy( ret->name.bytes, name->bytes, name->length );
|
||||||
header->name.length = name->length;
|
ret->name.length = name->length;
|
||||||
}
|
}
|
||||||
header->type = type;
|
if (ns && ns->length)
|
||||||
header->mapped = mapped;
|
{
|
||||||
|
if (!(ret->ns.bytes = heap_alloc( ns->length )))
|
||||||
|
{
|
||||||
|
free_header( ret );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy( ret->ns.bytes, ns->bytes, ns->length );
|
||||||
|
ret->ns.length = ns->length;
|
||||||
|
}
|
||||||
|
ret->type = type;
|
||||||
|
ret->mapped = mapped;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
*ret = header;
|
static HRESULT write_standard_header( WS_XML_WRITER *writer, const WS_XML_STRING *name, WS_TYPE value_type,
|
||||||
return S_OK;
|
WS_WRITE_OPTION option, const void *value, ULONG size )
|
||||||
|
{
|
||||||
|
static const WS_XML_STRING prefix_s = {1, (BYTE *)"s"}, prefix_a = {1, (BYTE *)"a"};
|
||||||
|
static const WS_XML_STRING understand = {14, (BYTE *)"mustUnderstand"}, ns = {0, NULL};
|
||||||
|
WS_XML_INT32_TEXT one = {{WS_XML_TEXT_TYPE_INT32}, 1};
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if ((hr = WsWriteStartElement( writer, &prefix_a, name, &ns, NULL )) != S_OK) return hr;
|
||||||
|
if ((hr = WsWriteStartAttribute( writer, &prefix_s, &understand, &ns, FALSE, NULL )) != S_OK) return hr;
|
||||||
|
if ((hr = WsWriteText( writer, &one.text, NULL )) != S_OK) return hr;
|
||||||
|
if ((hr = WsWriteEndAttribute( writer, NULL )) != S_OK) return hr;
|
||||||
|
if ((hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, value_type, NULL, option, value, size,
|
||||||
|
NULL )) != S_OK) return hr;
|
||||||
|
return WsWriteEndElement( writer, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT build_standard_header( WS_HEAP *heap, WS_HEADER_TYPE type, WS_TYPE value_type,
|
||||||
|
WS_WRITE_OPTION option, const void *value, ULONG size,
|
||||||
|
struct header **ret )
|
||||||
|
{
|
||||||
|
const WS_XML_STRING *name = get_header_name( type );
|
||||||
|
struct header *header;
|
||||||
|
WS_XML_WRITER *writer;
|
||||||
|
WS_XML_BUFFER *buf;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!(header = alloc_header( type, FALSE, name, NULL ))) return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
if ((hr = WsCreateWriter( NULL, 0, &writer, NULL )) != S_OK) goto done;
|
||||||
|
if ((hr = WsCreateXmlBuffer( heap, NULL, 0, &buf, NULL )) != S_OK) goto done;
|
||||||
|
if ((hr = WsSetOutputToBuffer( writer, buf, NULL, 0, NULL )) != S_OK) goto done;
|
||||||
|
if ((hr = write_standard_header( writer, name, value_type, option, value, size )) != S_OK)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
header->u.buf = buf;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (hr != S_OK) free_header( header );
|
||||||
|
else *ret = header;
|
||||||
|
WsFreeWriter( writer );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -679,25 +674,27 @@ HRESULT WINAPI WsSetHeader( WS_MESSAGE *handle, WS_HEADER_TYPE type, WS_TYPE val
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
if (msg->header_count == msg->header_size)
|
if ((hr = grow_header_array( msg, msg->header_count + 1 )) != S_OK) return hr;
|
||||||
{
|
i = msg->header_count;
|
||||||
struct header **tmp;
|
|
||||||
if (!(tmp = heap_realloc( msg->header, 2 * msg->header_size * sizeof(struct header *) )))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
msg->header = tmp;
|
|
||||||
msg->header_size *= 2;
|
|
||||||
}
|
|
||||||
i = msg->header_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hr = alloc_header( type, NULL, FALSE, value_type, option, value, size, &header )) != S_OK)
|
if ((hr = build_standard_header( msg->heap, type, value_type, option, value, size, &header )) != S_OK)
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
if (found) free_header( msg->header[i] );
|
if (!found) msg->header_count++;
|
||||||
|
else free_header( msg->header[i] );
|
||||||
|
|
||||||
msg->header[i] = header;
|
msg->header[i] = header;
|
||||||
return write_envelope( msg );
|
return write_envelope( msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void remove_header( struct msg *msg, ULONG i )
|
||||||
|
{
|
||||||
|
free_header( msg->header[i] );
|
||||||
|
memmove( &msg->header[i], &msg->header[i + 1], (msg->header_count - i) * sizeof(struct header *) );
|
||||||
|
msg->header_count--;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* WsRemoveHeader [webservices.@]
|
* WsRemoveHeader [webservices.@]
|
||||||
*/
|
*/
|
||||||
|
@ -718,9 +715,7 @@ HRESULT WINAPI WsRemoveHeader( WS_MESSAGE *handle, WS_HEADER_TYPE type, WS_ERROR
|
||||||
{
|
{
|
||||||
if (msg->header[i]->type == type)
|
if (msg->header[i]->type == type)
|
||||||
{
|
{
|
||||||
free_header( msg->header[i] );
|
remove_header( msg, i );
|
||||||
memmove( &msg->header[i], &msg->header[i + 1], (msg->header_count - i) * sizeof(struct header *) );
|
|
||||||
msg->header_count--;
|
|
||||||
removed = TRUE;
|
removed = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -730,6 +725,93 @@ HRESULT WINAPI WsRemoveHeader( WS_MESSAGE *handle, WS_HEADER_TYPE type, WS_ERROR
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT build_mapped_header( const WS_XML_STRING *name, WS_TYPE type, WS_WRITE_OPTION option,
|
||||||
|
const void *value, ULONG size, struct header **ret )
|
||||||
|
{
|
||||||
|
struct header *header;
|
||||||
|
|
||||||
|
if (!(header = alloc_header( 0, TRUE, name, NULL ))) return E_OUTOFMEMORY;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case WS_WSZ_TYPE:
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
const WCHAR *src;
|
||||||
|
|
||||||
|
if (option != WS_WRITE_REQUIRED_POINTER || size != sizeof(WCHAR *))
|
||||||
|
{
|
||||||
|
free_header( header );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
src = *(const WCHAR **)value;
|
||||||
|
len = WideCharToMultiByte( CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL ) - 1;
|
||||||
|
if (!(header->u.text = alloc_xml_string( NULL, len )))
|
||||||
|
{
|
||||||
|
free_header( header );
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
WideCharToMultiByte( CP_UTF8, 0, src, -1, (char *)header->u.text->bytes, len, NULL, NULL );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WS_XML_STRING_TYPE:
|
||||||
|
{
|
||||||
|
const WS_XML_STRING *str = value;
|
||||||
|
|
||||||
|
if (option != WS_WRITE_REQUIRED_VALUE)
|
||||||
|
{
|
||||||
|
FIXME( "unhandled write option %u\n", option );
|
||||||
|
free_header( header );
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
if (size != sizeof(*str))
|
||||||
|
{
|
||||||
|
free_header( header );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
if (!(header->u.text = alloc_xml_string( NULL, str->length )))
|
||||||
|
{
|
||||||
|
free_header( header );
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
memcpy( header->u.text->bytes, str->bytes, str->length );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WS_STRING_TYPE:
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
const WS_STRING *str = value;
|
||||||
|
|
||||||
|
if (option != WS_WRITE_REQUIRED_VALUE)
|
||||||
|
{
|
||||||
|
FIXME( "unhandled write option %u\n", option );
|
||||||
|
free_header( header );
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
if (size != sizeof(*str))
|
||||||
|
{
|
||||||
|
free_header( header );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
len = WideCharToMultiByte( CP_UTF8, 0, str->chars, str->length, NULL, 0, NULL, NULL );
|
||||||
|
if (!(header->u.text = alloc_xml_string( NULL, len )))
|
||||||
|
{
|
||||||
|
free_header( header );
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
WideCharToMultiByte( CP_UTF8, 0, str->chars, str->length, (char *)header->u.text->bytes,
|
||||||
|
len, NULL, NULL );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
FIXME( "unhandled type %u\n", type );
|
||||||
|
free_header( header );
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = header;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* WsAddMappedHeader [webservices.@]
|
* WsAddMappedHeader [webservices.@]
|
||||||
*/
|
*/
|
||||||
|
@ -760,21 +842,15 @@ HRESULT WINAPI WsAddMappedHeader( WS_MESSAGE *handle, const WS_XML_STRING *name,
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
if (msg->header_count == msg->header_size)
|
if ((hr = grow_header_array( msg, msg->header_count + 1 )) != S_OK) return hr;
|
||||||
{
|
i = msg->header_count;
|
||||||
struct header **tmp;
|
|
||||||
if (!(tmp = heap_realloc( msg->header, 2 * msg->header_size * sizeof(struct header *) )))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
msg->header = tmp;
|
|
||||||
msg->header_size *= 2;
|
|
||||||
}
|
|
||||||
i = msg->header_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hr = alloc_header( 0, name, TRUE, WS_XML_STRING_TYPE, option, value, size, &header )) != S_OK)
|
if ((hr = build_mapped_header( name, type, option, value, size, &header )) != S_OK) return hr;
|
||||||
return hr;
|
|
||||||
|
if (!found) msg->header_count++;
|
||||||
|
else free_header( msg->header[i] );
|
||||||
|
|
||||||
if (found) free_header( msg->header[i] );
|
|
||||||
msg->header[i] = header;
|
msg->header[i] = header;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -798,9 +874,7 @@ HRESULT WINAPI WsRemoveMappedHeader( WS_MESSAGE *handle, const WS_XML_STRING *na
|
||||||
if (msg->header[i]->type || !msg->header[i]->mapped) continue;
|
if (msg->header[i]->type || !msg->header[i]->mapped) continue;
|
||||||
if (WsXmlStringEquals( name, &msg->header[i]->name, NULL ) == S_OK)
|
if (WsXmlStringEquals( name, &msg->header[i]->name, NULL ) == S_OK)
|
||||||
{
|
{
|
||||||
free_header( msg->header[i] );
|
remove_header( msg, i );
|
||||||
memmove( &msg->header[i], &msg->header[i + 1], (msg->header_count - i) * sizeof(struct header *) );
|
|
||||||
msg->header_count--;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue