webservices: Protect readers with a critical section.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
dea8708079
commit
36c5252265
|
@ -834,6 +834,8 @@ struct prefix
|
||||||
|
|
||||||
struct reader
|
struct reader
|
||||||
{
|
{
|
||||||
|
ULONG magic;
|
||||||
|
CRITICAL_SECTION cs;
|
||||||
ULONG read_size;
|
ULONG read_size;
|
||||||
ULONG read_pos;
|
ULONG read_pos;
|
||||||
const unsigned char *read_bufptr;
|
const unsigned char *read_bufptr;
|
||||||
|
@ -854,6 +856,8 @@ struct reader
|
||||||
struct prop prop[sizeof(reader_props)/sizeof(reader_props[0])];
|
struct prop prop[sizeof(reader_props)/sizeof(reader_props[0])];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define READER_MAGIC (('R' << 24) | ('E' << 16) | ('A' << 8) | 'D')
|
||||||
|
|
||||||
static struct reader *alloc_reader(void)
|
static struct reader *alloc_reader(void)
|
||||||
{
|
{
|
||||||
static const ULONG count = sizeof(reader_props)/sizeof(reader_props[0]);
|
static const ULONG count = sizeof(reader_props)/sizeof(reader_props[0]);
|
||||||
|
@ -868,6 +872,10 @@ static struct reader *alloc_reader(void)
|
||||||
}
|
}
|
||||||
ret->nb_prefixes = ret->nb_prefixes_allocated = 1;
|
ret->nb_prefixes = ret->nb_prefixes_allocated = 1;
|
||||||
|
|
||||||
|
ret->magic = READER_MAGIC;
|
||||||
|
InitializeCriticalSection( &ret->cs );
|
||||||
|
ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": reader.cs");
|
||||||
|
|
||||||
prop_init( reader_props, count, ret->prop, &ret[1] );
|
prop_init( reader_props, count, ret->prop, &ret[1] );
|
||||||
ret->prop_count = count;
|
ret->prop_count = count;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -888,19 +896,23 @@ static void clear_prefixes( struct prefix *prefixes, ULONG count )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_reader( struct reader *reader )
|
|
||||||
{
|
|
||||||
if (!reader) return;
|
|
||||||
destroy_nodes( reader->root );
|
|
||||||
clear_prefixes( reader->prefixes, reader->nb_prefixes );
|
|
||||||
heap_free( reader->prefixes );
|
|
||||||
heap_free( reader );
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT copy_node( WS_XML_READER *handle, struct node **node )
|
HRESULT copy_node( WS_XML_READER *handle, struct node **node )
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
return dup_tree( node, reader->current );
|
HRESULT hr;
|
||||||
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = dup_tree( node, reader->current );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT set_prefix( struct prefix *prefix, const WS_XML_STRING *str, const WS_XML_STRING *ns )
|
static HRESULT set_prefix( struct prefix *prefix, const WS_XML_STRING *str, const WS_XML_STRING *ns )
|
||||||
|
@ -981,18 +993,28 @@ static void read_insert_node( struct reader *reader, struct node *parent, struct
|
||||||
reader->current = reader->last = node;
|
reader->current = reader->last = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT read_init_state( struct reader *reader )
|
static void free_reader( struct reader *reader )
|
||||||
|
{
|
||||||
|
destroy_nodes( reader->root );
|
||||||
|
clear_prefixes( reader->prefixes, reader->nb_prefixes );
|
||||||
|
heap_free( reader->prefixes );
|
||||||
|
reader->cs.DebugInfo->Spare[0] = 0;
|
||||||
|
DeleteCriticalSection( &reader->cs );
|
||||||
|
heap_free( reader );
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT init_reader( struct reader *reader )
|
||||||
{
|
{
|
||||||
struct node *node;
|
struct node *node;
|
||||||
|
|
||||||
|
reader->state = READER_STATE_INITIAL;
|
||||||
destroy_nodes( reader->root );
|
destroy_nodes( reader->root );
|
||||||
reader->root = NULL;
|
reader->root = reader->current = NULL;
|
||||||
reader->input_buf = NULL;
|
reader->current_attr = 0;
|
||||||
clear_prefixes( reader->prefixes, reader->nb_prefixes );
|
clear_prefixes( reader->prefixes, reader->nb_prefixes );
|
||||||
reader->nb_prefixes = 1;
|
reader->nb_prefixes = 1;
|
||||||
if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
|
if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
|
||||||
read_insert_eof( reader, node );
|
read_insert_eof( reader, node );
|
||||||
reader->state = READER_STATE_INITIAL;
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1031,7 +1053,7 @@ HRESULT WINAPI WsCreateReader( const WS_XML_READER_PROPERTY *properties, ULONG c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hr = read_init_state( reader )) != S_OK)
|
if ((hr = init_reader( reader )) != S_OK)
|
||||||
{
|
{
|
||||||
free_reader( reader );
|
free_reader( reader );
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -1049,6 +1071,20 @@ void WINAPI WsFreeReader( WS_XML_READER *handle )
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
|
|
||||||
TRACE( "%p\n", handle );
|
TRACE( "%p\n", handle );
|
||||||
|
|
||||||
|
if (!reader) return;
|
||||||
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reader->magic = 0;
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
free_reader( reader );
|
free_reader( reader );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1065,10 +1101,19 @@ HRESULT WINAPI WsFillReader( WS_XML_READER *handle, ULONG min_size, const WS_ASY
|
||||||
|
|
||||||
if (!reader) return E_INVALIDARG;
|
if (!reader) return E_INVALIDARG;
|
||||||
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: add support for stream input */
|
/* FIXME: add support for stream input */
|
||||||
reader->read_size = min( min_size, reader->input_size );
|
reader->read_size = min( min_size, reader->input_size );
|
||||||
reader->read_pos = 0;
|
reader->read_pos = 0;
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,7 +1135,20 @@ HRESULT WINAPI WsGetNamespaceFromPrefix( WS_XML_READER *handle, const WS_XML_STR
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader || !prefix || !ns) return E_INVALIDARG;
|
if (!reader || !prefix || !ns) return E_INVALIDARG;
|
||||||
if (reader->state != READER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reader->state != READER_STATE_STARTELEMENT)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return WS_E_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
if (!prefix->length)
|
if (!prefix->length)
|
||||||
{
|
{
|
||||||
|
@ -1130,6 +1188,8 @@ HRESULT WINAPI WsGetNamespaceFromPrefix( WS_XML_READER *handle, const WS_XML_STR
|
||||||
*ns = NULL;
|
*ns = NULL;
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,7 +1206,17 @@ HRESULT WINAPI WsGetReaderNode( WS_XML_READER *handle, const WS_XML_NODE **node,
|
||||||
|
|
||||||
if (!reader || !node) return E_INVALIDARG;
|
if (!reader || !node) return E_INVALIDARG;
|
||||||
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
*node = &reader->current->hdr.node;
|
*node = &reader->current->hdr.node;
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1157,23 +1227,44 @@ HRESULT WINAPI WsGetReaderProperty( WS_XML_READER *handle, WS_XML_READER_PROPERT
|
||||||
void *buf, ULONG size, WS_ERROR *error )
|
void *buf, ULONG size, WS_ERROR *error )
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "%p %u %p %u %p\n", handle, id, buf, size, error );
|
TRACE( "%p %u %p %u %p\n", handle, id, buf, size, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader->input_type) return WS_E_INVALID_OPERATION;
|
if (!reader) return E_INVALIDARG;
|
||||||
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reader->input_type)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return WS_E_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
if (id == WS_XML_READER_PROPERTY_CHARSET)
|
if (id == WS_XML_READER_PROPERTY_CHARSET)
|
||||||
{
|
{
|
||||||
WS_CHARSET charset;
|
WS_CHARSET charset;
|
||||||
HRESULT hr;
|
if ((hr = prop_get( reader->prop, reader->prop_count, id, &charset, size )) != S_OK) goto done;
|
||||||
|
if (!charset)
|
||||||
if ((hr = prop_get( reader->prop, reader->prop_count, id, &charset, size )) != S_OK) return hr;
|
{
|
||||||
if (!charset) return WS_E_INVALID_FORMAT;
|
hr = WS_E_INVALID_FORMAT;
|
||||||
*(WS_CHARSET *)buf = charset;
|
goto done;
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
return prop_get( reader->prop, reader->prop_count, id, buf, size );
|
*(WS_CHARSET *)buf = charset;
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
else hr = prop_get( reader->prop, reader->prop_count, id, buf, size );
|
||||||
|
|
||||||
|
done:
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -1391,8 +1482,7 @@ static HRESULT parse_name( const unsigned char *str, unsigned int len,
|
||||||
|
|
||||||
static int codepoint_to_utf8( int cp, unsigned char *dst )
|
static int codepoint_to_utf8( int cp, unsigned char *dst )
|
||||||
{
|
{
|
||||||
if (!cp)
|
if (!cp) return -1;
|
||||||
return -1;
|
|
||||||
if (cp < 0x80)
|
if (cp < 0x80)
|
||||||
{
|
{
|
||||||
*dst = cp;
|
*dst = cp;
|
||||||
|
@ -1476,7 +1566,7 @@ static HRESULT decode_text( const unsigned char *str, ULONG len, unsigned char *
|
||||||
|
|
||||||
p++; len--;
|
p++; len--;
|
||||||
if (!len) return WS_E_INVALID_FORMAT;
|
if (!len) return WS_E_INVALID_FORMAT;
|
||||||
else if (*p == 'x')
|
if (*p == 'x')
|
||||||
{
|
{
|
||||||
p++; len--;
|
p++; len--;
|
||||||
|
|
||||||
|
@ -2040,12 +2130,25 @@ static HRESULT read_node( struct reader *reader )
|
||||||
HRESULT WINAPI WsReadEndElement( WS_XML_READER *handle, WS_ERROR *error )
|
HRESULT WINAPI WsReadEndElement( WS_XML_READER *handle, WS_ERROR *error )
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "%p %p\n", handle, error );
|
TRACE( "%p %p\n", handle, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader) return E_INVALIDARG;
|
if (!reader) return E_INVALIDARG;
|
||||||
return read_endelement( reader );
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = read_endelement( reader );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -2054,12 +2157,25 @@ HRESULT WINAPI WsReadEndElement( WS_XML_READER *handle, WS_ERROR *error )
|
||||||
HRESULT WINAPI WsReadNode( WS_XML_READER *handle, WS_ERROR *error )
|
HRESULT WINAPI WsReadNode( WS_XML_READER *handle, WS_ERROR *error )
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "%p %p\n", handle, error );
|
TRACE( "%p %p\n", handle, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader) return E_INVALIDARG;
|
if (!reader) return E_INVALIDARG;
|
||||||
return read_node( reader );
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = read_node( reader );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -2068,12 +2184,25 @@ HRESULT WINAPI WsReadNode( WS_XML_READER *handle, WS_ERROR *error )
|
||||||
HRESULT WINAPI WsReadStartElement( WS_XML_READER *handle, WS_ERROR *error )
|
HRESULT WINAPI WsReadStartElement( WS_XML_READER *handle, WS_ERROR *error )
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "%p %p\n", handle, error );
|
TRACE( "%p %p\n", handle, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader) return E_INVALIDARG;
|
if (!reader) return E_INVALIDARG;
|
||||||
return read_startelement( reader );
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = read_startelement( reader );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -2083,6 +2212,7 @@ HRESULT WINAPI WsReadToStartElement( WS_XML_READER *handle, const WS_XML_STRING
|
||||||
const WS_XML_STRING *ns, BOOL *found, WS_ERROR *error )
|
const WS_XML_STRING *ns, BOOL *found, WS_ERROR *error )
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "%p %s %s %p %p\n", handle, debugstr_xmlstr(localname), debugstr_xmlstr(ns), found, error );
|
TRACE( "%p %s %s %p %p\n", handle, debugstr_xmlstr(localname), debugstr_xmlstr(ns), found, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
@ -2090,7 +2220,18 @@ HRESULT WINAPI WsReadToStartElement( WS_XML_READER *handle, const WS_XML_STRING
|
||||||
if (!reader) return E_INVALIDARG;
|
if (!reader) return E_INVALIDARG;
|
||||||
if (localname || ns) FIXME( "name and/or namespace not verified\n" );
|
if (localname || ns) FIXME( "name and/or namespace not verified\n" );
|
||||||
|
|
||||||
return read_to_startelement( reader, found );
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = read_to_startelement( reader, found );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL move_to_root_element( struct node *root, struct node **current )
|
BOOL move_to_root_element( struct node *root, struct node **current )
|
||||||
|
@ -2369,14 +2510,31 @@ static HRESULT read_move_to( struct reader *reader, WS_MOVE_TO move, BOOL *found
|
||||||
HRESULT WINAPI WsMoveReader( WS_XML_READER *handle, WS_MOVE_TO move, BOOL *found, WS_ERROR *error )
|
HRESULT WINAPI WsMoveReader( WS_XML_READER *handle, WS_MOVE_TO move, BOOL *found, WS_ERROR *error )
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "%p %u %p %p\n", handle, move, found, error );
|
TRACE( "%p %u %p %p\n", handle, move, found, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader) return E_INVALIDARG;
|
if (!reader) return E_INVALIDARG;
|
||||||
if (!reader->input_type) return WS_E_INVALID_OPERATION;
|
|
||||||
|
|
||||||
return read_move_to( reader, move, found );
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reader->input_type)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return WS_E_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = read_move_to( reader, move, found );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -2385,19 +2543,32 @@ HRESULT WINAPI WsMoveReader( WS_XML_READER *handle, WS_MOVE_TO move, BOOL *found
|
||||||
HRESULT WINAPI WsReadStartAttribute( WS_XML_READER *handle, ULONG index, WS_ERROR *error )
|
HRESULT WINAPI WsReadStartAttribute( WS_XML_READER *handle, ULONG index, WS_ERROR *error )
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
WS_XML_ELEMENT_NODE *elem;
|
const WS_XML_ELEMENT_NODE *elem;
|
||||||
|
|
||||||
TRACE( "%p %u %p\n", handle, index, error );
|
TRACE( "%p %u %p\n", handle, index, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader) return E_INVALIDARG;
|
if (!reader) return E_INVALIDARG;
|
||||||
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
elem = &reader->current->hdr;
|
elem = &reader->current->hdr;
|
||||||
if (reader->state != READER_STATE_STARTELEMENT || index >= elem->attributeCount)
|
if (reader->state != READER_STATE_STARTELEMENT || index >= elem->attributeCount)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return WS_E_INVALID_FORMAT;
|
return WS_E_INVALID_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
reader->current_attr = index;
|
reader->current_attr = index;
|
||||||
reader->state = READER_STATE_STARTATTRIBUTE;
|
reader->state = READER_STATE_STARTATTRIBUTE;
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2413,10 +2584,23 @@ HRESULT WINAPI WsReadEndAttribute( WS_XML_READER *handle, WS_ERROR *error )
|
||||||
|
|
||||||
if (!reader) return E_INVALIDARG;
|
if (!reader) return E_INVALIDARG;
|
||||||
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
if (reader->state != READER_STATE_STARTATTRIBUTE)
|
if (reader->state != READER_STATE_STARTATTRIBUTE)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return WS_E_INVALID_FORMAT;
|
return WS_E_INVALID_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
reader->state = READER_STATE_STARTELEMENT;
|
reader->state = READER_STATE_STARTELEMENT;
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3010,6 +3194,7 @@ HRESULT WINAPI WsFindAttribute( WS_XML_READER *handle, const WS_XML_STRING *loca
|
||||||
WS_ERROR *error )
|
WS_ERROR *error )
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
TRACE( "%p %s %s %d %p %p\n", handle, debugstr_xmlstr(localname), debugstr_xmlstr(ns),
|
TRACE( "%p %s %s %d %p %p\n", handle, debugstr_xmlstr(localname), debugstr_xmlstr(ns),
|
||||||
required, index, error );
|
required, index, error );
|
||||||
|
@ -3017,16 +3202,32 @@ HRESULT WINAPI WsFindAttribute( WS_XML_READER *handle, const WS_XML_STRING *loca
|
||||||
|
|
||||||
if (!reader || !localname || !ns || !index) return E_INVALIDARG;
|
if (!reader || !localname || !ns || !index) return E_INVALIDARG;
|
||||||
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
if (node_type( reader->current ) != WS_XML_NODE_TYPE_ELEMENT)
|
if (node_type( reader->current ) != WS_XML_NODE_TYPE_ELEMENT)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return WS_E_INVALID_OPERATION;
|
return WS_E_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
if (!find_attribute( reader, localname, ns, index ))
|
if (!find_attribute( reader, localname, ns, index ))
|
||||||
{
|
{
|
||||||
if (required) return WS_E_INVALID_FORMAT;
|
if (required) hr = WS_E_INVALID_FORMAT;
|
||||||
|
else
|
||||||
|
{
|
||||||
*index = ~0u;
|
*index = ~0u;
|
||||||
return S_FALSE;
|
hr = S_FALSE;
|
||||||
}
|
}
|
||||||
return S_OK;
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT read_get_text( struct reader *reader, WS_TYPE_MAPPING mapping,
|
static HRESULT read_get_text( struct reader *reader, WS_TYPE_MAPPING mapping,
|
||||||
|
@ -4485,21 +4686,34 @@ HRESULT WINAPI WsReadType( WS_XML_READER *handle, WS_TYPE_MAPPING mapping, WS_TY
|
||||||
|
|
||||||
if (!reader || !value) return E_INVALIDARG;
|
if (!reader || !value) return E_INVALIDARG;
|
||||||
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
if ((hr = read_type( reader, mapping, type, NULL, NULL, desc, option, heap, value, size )) != S_OK)
|
if ((hr = read_type( reader, mapping, type, NULL, NULL, desc, option, heap, value, size )) != S_OK)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return hr;
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
switch (mapping)
|
switch (mapping)
|
||||||
{
|
{
|
||||||
case WS_ELEMENT_TYPE_MAPPING:
|
case WS_ELEMENT_TYPE_MAPPING:
|
||||||
if ((hr = read_node( reader )) != S_OK) return hr;
|
hr = read_node( reader );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!read_end_of_data( reader )) return WS_E_INVALID_FORMAT;
|
if (hr == S_OK && !read_end_of_data( reader )) hr = WS_E_INVALID_FORMAT;
|
||||||
return S_OK;
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -4510,14 +4724,26 @@ HRESULT WINAPI WsReadElement( WS_XML_READER *handle, const WS_ELEMENT_DESCRIPTIO
|
||||||
WS_ERROR *error )
|
WS_ERROR *error )
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "%p %p %u %p %p %u %p\n", handle, desc, option, heap, value, size, error );
|
TRACE( "%p %p %u %p %p %u %p\n", handle, desc, option, heap, value, size, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader || !desc || !value) return E_INVALIDARG;
|
if (!reader || !desc || !value) return E_INVALIDARG;
|
||||||
|
|
||||||
return read_type( reader, WS_ELEMENT_TYPE_MAPPING, desc->type, desc->elementLocalName,
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = read_type( reader, WS_ELEMENT_TYPE_MAPPING, desc->type, desc->elementLocalName,
|
||||||
desc->elementNs, desc->typeDescription, option, heap, value, size );
|
desc->elementNs, desc->typeDescription, option, heap, value, size );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -4528,14 +4754,26 @@ HRESULT WINAPI WsReadValue( WS_XML_READER *handle, WS_VALUE_TYPE value_type, voi
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
WS_TYPE type = map_value_type( value_type );
|
WS_TYPE type = map_value_type( value_type );
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "%p %u %p %u %p\n", handle, type, value, size, error );
|
TRACE( "%p %u %p %u %p\n", handle, type, value, size, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader || !value || type == ~0u) return E_INVALIDARG;
|
if (!reader || !value || type == ~0u) return E_INVALIDARG;
|
||||||
|
|
||||||
return read_type( reader, WS_ELEMENT_TYPE_MAPPING, type, NULL, NULL, NULL, WS_READ_REQUIRED_VALUE,
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = read_type( reader, WS_ELEMENT_TYPE_MAPPING, type, NULL, NULL, NULL, WS_READ_REQUIRED_VALUE,
|
||||||
NULL, value, size );
|
NULL, value, size );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline BOOL is_utf8( const unsigned char *data, ULONG size, ULONG *offset )
|
static inline BOOL is_utf8( const unsigned char *data, ULONG size, ULONG *offset )
|
||||||
|
@ -4584,6 +4822,8 @@ static void set_input_buffer( struct reader *reader, struct xmlbuf *buf, const u
|
||||||
reader->read_size = reader->input_size;
|
reader->read_size = reader->input_size;
|
||||||
reader->read_pos = 0;
|
reader->read_pos = 0;
|
||||||
reader->read_bufptr = reader->input_data;
|
reader->read_bufptr = reader->input_data;
|
||||||
|
|
||||||
|
reader->text_conv_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -4595,22 +4835,30 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
struct node *node;
|
struct node *node;
|
||||||
HRESULT hr;
|
|
||||||
ULONG i, offset = 0;
|
ULONG i, offset = 0;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "%p %p %p %p %u %p\n", handle, encoding, input, properties, count, error );
|
TRACE( "%p %p %p %p %u %p\n", handle, encoding, input, properties, count, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader) return E_INVALIDARG;
|
if (!reader) return E_INVALIDARG;
|
||||||
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
hr = prop_set( reader->prop, reader->prop_count, properties[i].id, properties[i].value,
|
hr = prop_set( reader->prop, reader->prop_count, properties[i].id, properties[i].value,
|
||||||
properties[i].valueSize );
|
properties[i].valueSize );
|
||||||
if (hr != S_OK) return hr;
|
if (hr != S_OK) goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hr = read_init_state( reader )) != S_OK) return hr;
|
if ((hr = init_reader( reader )) != S_OK) goto done;
|
||||||
|
|
||||||
switch (encoding->encodingType)
|
switch (encoding->encodingType)
|
||||||
{
|
{
|
||||||
|
@ -4623,7 +4871,8 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
|
||||||
if (input->inputType != WS_XML_READER_INPUT_TYPE_BUFFER)
|
if (input->inputType != WS_XML_READER_INPUT_TYPE_BUFFER)
|
||||||
{
|
{
|
||||||
FIXME( "charset detection on input type %u not supported\n", input->inputType );
|
FIXME( "charset detection on input type %u not supported\n", input->inputType );
|
||||||
return E_NOTIMPL;
|
hr = E_NOTIMPL;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (charset == WS_CHARSET_AUTO)
|
if (charset == WS_CHARSET_AUTO)
|
||||||
|
@ -4631,13 +4880,15 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
|
||||||
|
|
||||||
hr = prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET,
|
hr = prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET,
|
||||||
&charset, sizeof(charset) );
|
&charset, sizeof(charset) );
|
||||||
if (hr != S_OK) return hr;
|
if (hr != S_OK) goto done;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
FIXME( "encoding type %u not supported\n", encoding->encodingType );
|
FIXME( "encoding type %u not supported\n", encoding->encodingType );
|
||||||
return E_NOTIMPL;
|
hr = E_NOTIMPL;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (input->inputType)
|
switch (input->inputType)
|
||||||
{
|
{
|
||||||
case WS_XML_READER_INPUT_TYPE_BUFFER:
|
case WS_XML_READER_INPUT_TYPE_BUFFER:
|
||||||
|
@ -4649,12 +4900,16 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
FIXME( "input type %u not supported\n", input->inputType );
|
FIXME( "input type %u not supported\n", input->inputType );
|
||||||
return E_NOTIMPL;
|
hr = E_NOTIMPL;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY;
|
if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY;
|
||||||
read_insert_bof( reader, node );
|
else read_insert_bof( reader, node );
|
||||||
return S_OK;
|
|
||||||
|
done:
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -4668,32 +4923,43 @@ HRESULT WINAPI WsSetInputToBuffer( WS_XML_READER *handle, WS_XML_BUFFER *buffer,
|
||||||
struct xmlbuf *xmlbuf = (struct xmlbuf *)buffer;
|
struct xmlbuf *xmlbuf = (struct xmlbuf *)buffer;
|
||||||
WS_CHARSET charset;
|
WS_CHARSET charset;
|
||||||
struct node *node;
|
struct node *node;
|
||||||
HRESULT hr;
|
|
||||||
ULONG i, offset = 0;
|
ULONG i, offset = 0;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "%p %p %p %u %p\n", handle, buffer, properties, count, error );
|
TRACE( "%p %p %p %u %p\n", handle, buffer, properties, count, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader || !xmlbuf) return E_INVALIDARG;
|
if (!reader || !xmlbuf) return E_INVALIDARG;
|
||||||
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
hr = prop_set( reader->prop, reader->prop_count, properties[i].id, properties[i].value,
|
hr = prop_set( reader->prop, reader->prop_count, properties[i].id, properties[i].value,
|
||||||
properties[i].valueSize );
|
properties[i].valueSize );
|
||||||
if (hr != S_OK) return hr;
|
if (hr != S_OK) goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hr = read_init_state( reader )) != S_OK) return hr;
|
if ((hr = init_reader( reader )) != S_OK) goto done;
|
||||||
|
|
||||||
charset = detect_charset( xmlbuf->ptr, xmlbuf->size, &offset );
|
charset = detect_charset( xmlbuf->ptr, xmlbuf->size, &offset );
|
||||||
hr = prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET,
|
hr = prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET, &charset,
|
||||||
&charset, sizeof(charset) );
|
sizeof(charset) );
|
||||||
if (hr != S_OK) return hr;
|
if (hr != S_OK) goto done;
|
||||||
|
|
||||||
set_input_buffer( reader, xmlbuf, (const unsigned char *)xmlbuf->ptr + offset, xmlbuf->size - offset );
|
set_input_buffer( reader, xmlbuf, (const unsigned char *)xmlbuf->ptr + offset, xmlbuf->size - offset );
|
||||||
if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY;
|
if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY;
|
||||||
read_insert_bof( reader, node );
|
else read_insert_bof( reader, node );
|
||||||
return S_OK;
|
|
||||||
|
done:
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -4722,10 +4988,25 @@ HRESULT WINAPI WsGetReaderPosition( WS_XML_READER *handle, WS_XML_NODE_POSITION
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader || !pos) return E_INVALIDARG;
|
if (!reader || !pos) return E_INVALIDARG;
|
||||||
if (!reader->input_buf) return WS_E_INVALID_OPERATION;
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reader->input_buf)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return WS_E_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
pos->buffer = (WS_XML_BUFFER *)reader->input_buf;
|
pos->buffer = (WS_XML_BUFFER *)reader->input_buf;
|
||||||
pos->node = reader->current;
|
pos->node = reader->current;
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4739,10 +5020,25 @@ HRESULT WINAPI WsSetReaderPosition( WS_XML_READER *handle, const WS_XML_NODE_POS
|
||||||
TRACE( "%p %p %p\n", handle, pos, error );
|
TRACE( "%p %p %p\n", handle, pos, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader || !pos || (struct xmlbuf *)pos->buffer != reader->input_buf) return E_INVALIDARG;
|
if (!reader || !pos) return E_INVALIDARG;
|
||||||
if (!reader->input_buf) return WS_E_INVALID_OPERATION;
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC || (struct xmlbuf *)pos->buffer != reader->input_buf)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reader->input_buf)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return WS_E_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
reader->current = pos->node;
|
reader->current = pos->node;
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4766,8 +5062,26 @@ HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count,
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader) return E_INVALIDARG;
|
if (!reader) return E_INVALIDARG;
|
||||||
if (!reader->input_type) return WS_E_INVALID_OPERATION;
|
|
||||||
if (!count) return E_INVALIDARG;
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reader->input_type)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return WS_E_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && bytes)
|
if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && bytes)
|
||||||
|
@ -4775,11 +5089,17 @@ HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count,
|
||||||
const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current;
|
const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current;
|
||||||
WS_XML_BASE64_TEXT base64;
|
WS_XML_BASE64_TEXT base64;
|
||||||
|
|
||||||
if ((hr = utf8_to_base64( (const WS_XML_UTF8_TEXT *)text->text, &base64 )) != S_OK) return hr;
|
if ((hr = utf8_to_base64( (const WS_XML_UTF8_TEXT *)text->text, &base64 )) != S_OK)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
if (reader->text_conv_offset == base64.length)
|
if (reader->text_conv_offset == base64.length)
|
||||||
{
|
{
|
||||||
heap_free( base64.bytes );
|
heap_free( base64.bytes );
|
||||||
return read_node( reader );
|
hr = read_node( reader );
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
*count = min( base64.length - reader->text_conv_offset, max_count );
|
*count = min( base64.length - reader->text_conv_offset, max_count );
|
||||||
memcpy( bytes, base64.bytes + reader->text_conv_offset, *count );
|
memcpy( bytes, base64.bytes + reader->text_conv_offset, *count );
|
||||||
|
@ -4787,6 +5107,7 @@ HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count,
|
||||||
heap_free( base64.bytes );
|
heap_free( base64.bytes );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4810,8 +5131,26 @@ HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader) return E_INVALIDARG;
|
if (!reader) return E_INVALIDARG;
|
||||||
if (!reader->input_type) return WS_E_INVALID_OPERATION;
|
|
||||||
if (!count) return E_INVALIDARG;
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reader->input_type)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return WS_E_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && chars)
|
if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && chars)
|
||||||
|
@ -4820,11 +5159,17 @@ HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count
|
||||||
WS_XML_UTF16_TEXT utf16;
|
WS_XML_UTF16_TEXT utf16;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if ((hr = utf8_to_utf16( (const WS_XML_UTF8_TEXT *)text->text, &utf16 )) != S_OK) return hr;
|
if ((hr = utf8_to_utf16( (const WS_XML_UTF8_TEXT *)text->text, &utf16 )) != S_OK)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
if (reader->text_conv_offset == utf16.byteCount / sizeof(WCHAR))
|
if (reader->text_conv_offset == utf16.byteCount / sizeof(WCHAR))
|
||||||
{
|
{
|
||||||
heap_free( utf16.bytes );
|
heap_free( utf16.bytes );
|
||||||
return read_node( reader );
|
hr = read_node( reader );
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
*count = min( utf16.byteCount / sizeof(WCHAR) - reader->text_conv_offset, max_count );
|
*count = min( utf16.byteCount / sizeof(WCHAR) - reader->text_conv_offset, max_count );
|
||||||
memcpy( chars, utf16.bytes + reader->text_conv_offset * sizeof(WCHAR), *count * sizeof(WCHAR) );
|
memcpy( chars, utf16.bytes + reader->text_conv_offset * sizeof(WCHAR), *count * sizeof(WCHAR) );
|
||||||
|
@ -4832,6 +5177,7 @@ HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count
|
||||||
heap_free( utf16.bytes );
|
heap_free( utf16.bytes );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4841,13 +5187,32 @@ HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count
|
||||||
HRESULT WINAPI WsReadCharsUtf8( WS_XML_READER *handle, BYTE *bytes, ULONG max_count, ULONG *count, WS_ERROR *error )
|
HRESULT WINAPI WsReadCharsUtf8( WS_XML_READER *handle, BYTE *bytes, ULONG max_count, ULONG *count, WS_ERROR *error )
|
||||||
{
|
{
|
||||||
struct reader *reader = (struct reader *)handle;
|
struct reader *reader = (struct reader *)handle;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "%p %p %u %p %p\n", handle, bytes, max_count, count, error );
|
TRACE( "%p %p %u %p %p\n", handle, bytes, max_count, count, error );
|
||||||
if (error) FIXME( "ignoring error parameter\n" );
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
if (!reader) return E_INVALIDARG;
|
if (!reader) return E_INVALIDARG;
|
||||||
if (!reader->input_type) return WS_E_INVALID_OPERATION;
|
|
||||||
if (!count) return E_INVALIDARG;
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reader->input_type)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return WS_E_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && bytes)
|
if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && bytes)
|
||||||
|
@ -4855,12 +5220,18 @@ HRESULT WINAPI WsReadCharsUtf8( WS_XML_READER *handle, BYTE *bytes, ULONG max_co
|
||||||
const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current;
|
const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current;
|
||||||
const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text->text;
|
const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text->text;
|
||||||
|
|
||||||
if (reader->text_conv_offset == utf8->value.length) return read_node( reader );
|
if (reader->text_conv_offset == utf8->value.length)
|
||||||
|
{
|
||||||
|
hr = read_node( reader );
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
*count = min( utf8->value.length - reader->text_conv_offset, max_count );
|
*count = min( utf8->value.length - reader->text_conv_offset, max_count );
|
||||||
memcpy( bytes, utf8->value.bytes + reader->text_conv_offset, *count );
|
memcpy( bytes, utf8->value.bytes + reader->text_conv_offset, *count );
|
||||||
reader->text_conv_offset += *count;
|
reader->text_conv_offset += *count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4934,8 +5305,16 @@ HRESULT read_output_params( WS_XML_READER *handle, WS_HEAP *heap, const WS_ELEME
|
||||||
|
|
||||||
if (desc->type != WS_STRUCT_TYPE || !(desc_struct = desc->typeDescription)) return E_INVALIDARG;
|
if (desc->type != WS_STRUCT_TYPE || !(desc_struct = desc->typeDescription)) return E_INVALIDARG;
|
||||||
|
|
||||||
|
EnterCriticalSection( &reader->cs );
|
||||||
|
|
||||||
|
if (reader->magic != READER_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
if ((hr = start_mapping( reader, WS_ELEMENT_TYPE_MAPPING, desc->elementLocalName, desc->elementNs )) != S_OK)
|
if ((hr = start_mapping( reader, WS_ELEMENT_TYPE_MAPPING, desc->elementLocalName, desc->elementNs )) != S_OK)
|
||||||
return hr;
|
goto done;
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
@ -4943,18 +5322,19 @@ HRESULT read_output_params( WS_XML_READER *handle, WS_HEAP *heap, const WS_ELEME
|
||||||
if (params[i].parameterType == WS_PARAMETER_TYPE_MESSAGES)
|
if (params[i].parameterType == WS_PARAMETER_TYPE_MESSAGES)
|
||||||
{
|
{
|
||||||
FIXME( "messages type not supported\n" );
|
FIXME( "messages type not supported\n" );
|
||||||
return E_NOTIMPL;
|
hr = E_NOTIMPL;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
if ((hr = get_param_desc( desc_struct, params[i].outputMessageIndex, &desc_field )) != S_OK) return hr;
|
if ((hr = get_param_desc( desc_struct, params[i].outputMessageIndex, &desc_field )) != S_OK) goto done;
|
||||||
if (params[i].parameterType == WS_PARAMETER_TYPE_NORMAL)
|
if (params[i].parameterType == WS_PARAMETER_TYPE_NORMAL)
|
||||||
{
|
{
|
||||||
void *ptr = *(void **)args[i];
|
void *ptr = *(void **)args[i];
|
||||||
if ((hr = read_param( reader, desc_field, heap, ptr )) != S_OK) return hr;
|
if ((hr = read_param( reader, desc_field, heap, ptr )) != S_OK) goto done;
|
||||||
}
|
}
|
||||||
else if (params[i].parameterType == WS_PARAMETER_TYPE_ARRAY)
|
else if (params[i].parameterType == WS_PARAMETER_TYPE_ARRAY)
|
||||||
{
|
{
|
||||||
void **ptr = *(void ***)args[i];
|
void **ptr = *(void ***)args[i];
|
||||||
if ((hr = read_param_array( reader, desc_field, heap, ptr, &len )) != S_OK) return hr;
|
if ((hr = read_param_array( reader, desc_field, heap, ptr, &len )) != S_OK) goto done;
|
||||||
set_array_len( params, count, params[i].outputMessageIndex, len, args );
|
set_array_len( params, count, params[i].outputMessageIndex, len, args );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4965,5 +5345,9 @@ HRESULT read_output_params( WS_XML_READER *handle, WS_HEAP *heap, const WS_ELEME
|
||||||
parent->flags |= NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT;
|
parent->flags |= NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return end_mapping( reader, WS_ELEMENT_TYPE_MAPPING );
|
hr = end_mapping( reader, WS_ELEMENT_TYPE_MAPPING );
|
||||||
|
|
||||||
|
done:
|
||||||
|
LeaveCriticalSection( &reader->cs );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue