webservices: Reset the reader position if the next node doesn't match the type to read.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7fb361d763
commit
297dd85ca5
|
@ -410,6 +410,7 @@ struct reader
|
||||||
struct node *root;
|
struct node *root;
|
||||||
struct node *current;
|
struct node *current;
|
||||||
ULONG current_attr;
|
ULONG current_attr;
|
||||||
|
struct node *last;
|
||||||
struct prefix *prefixes;
|
struct prefix *prefixes;
|
||||||
ULONG nb_prefixes;
|
ULONG nb_prefixes;
|
||||||
ULONG nb_prefixes_allocated;
|
ULONG nb_prefixes_allocated;
|
||||||
|
@ -524,14 +525,14 @@ static void read_insert_eof( struct reader *reader, struct node *eof )
|
||||||
eof->parent = reader->root;
|
eof->parent = reader->root;
|
||||||
list_add_tail( &reader->root->children, &eof->entry );
|
list_add_tail( &reader->root->children, &eof->entry );
|
||||||
}
|
}
|
||||||
reader->current = eof;
|
reader->current = reader->last = eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_insert_bof( struct reader *reader, struct node *bof )
|
static void read_insert_bof( struct reader *reader, struct node *bof )
|
||||||
{
|
{
|
||||||
reader->root->parent = bof;
|
reader->root->parent = bof;
|
||||||
list_add_tail( &bof->children, &reader->root->entry );
|
list_add_tail( &bof->children, &reader->root->entry );
|
||||||
reader->current = reader->root = bof;
|
reader->current = reader->last = reader->root = bof;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_insert_node( struct reader *reader, struct node *parent, struct node *node )
|
static void read_insert_node( struct reader *reader, struct node *parent, struct node *node )
|
||||||
|
@ -543,7 +544,7 @@ static void read_insert_node( struct reader *reader, struct node *parent, struct
|
||||||
list_add_before( eof, &node->entry );
|
list_add_before( eof, &node->entry );
|
||||||
}
|
}
|
||||||
else list_add_tail( &parent->children, &node->entry );
|
else list_add_tail( &parent->children, &node->entry );
|
||||||
reader->current = node;
|
reader->current = reader->last = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT read_init_state( struct reader *reader )
|
static HRESULT read_init_state( struct reader *reader )
|
||||||
|
@ -1650,6 +1651,58 @@ static BOOL move_to_parent_element( struct reader *reader )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL move_to_first_node( struct reader *reader )
|
||||||
|
{
|
||||||
|
struct list *ptr;
|
||||||
|
if ((ptr = list_head( &reader->current->parent->children )))
|
||||||
|
{
|
||||||
|
reader->current = LIST_ENTRY( ptr, struct node, entry );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL move_to_next_node( struct reader *reader )
|
||||||
|
{
|
||||||
|
struct list *ptr;
|
||||||
|
if ((ptr = list_next( &reader->current->parent->children, &reader->current->entry )))
|
||||||
|
{
|
||||||
|
reader->current = LIST_ENTRY( ptr, struct node, entry );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL move_to_prev_node( struct reader *reader )
|
||||||
|
{
|
||||||
|
struct list *ptr;
|
||||||
|
if ((ptr = list_prev( &reader->current->parent->children, &reader->current->entry )))
|
||||||
|
{
|
||||||
|
reader->current = LIST_ENTRY( ptr, struct node, entry );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL move_to_child_node( struct reader *reader )
|
||||||
|
{
|
||||||
|
struct list *ptr;
|
||||||
|
if ((ptr = list_head( &reader->current->children )))
|
||||||
|
{
|
||||||
|
reader->current = LIST_ENTRY( ptr, struct node, entry );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL move_to_parent_node( struct reader *reader )
|
||||||
|
{
|
||||||
|
struct node *parent = reader->current->parent;
|
||||||
|
if (!parent) return FALSE;
|
||||||
|
reader->current = parent;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT read_move_to( struct reader *reader, WS_MOVE_TO move, BOOL *found )
|
static HRESULT read_move_to( struct reader *reader, WS_MOVE_TO move, BOOL *found )
|
||||||
{
|
{
|
||||||
struct list *ptr;
|
struct list *ptr;
|
||||||
|
@ -1688,35 +1741,19 @@ static HRESULT read_move_to( struct reader *reader, WS_MOVE_TO move, BOOL *found
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WS_MOVE_TO_FIRST_NODE:
|
case WS_MOVE_TO_FIRST_NODE:
|
||||||
if ((ptr = list_head( &reader->current->parent->children )))
|
success = move_to_first_node( reader );
|
||||||
{
|
|
||||||
reader->current = LIST_ENTRY( ptr, struct node, entry );
|
|
||||||
success = TRUE;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WS_MOVE_TO_NEXT_NODE:
|
case WS_MOVE_TO_NEXT_NODE:
|
||||||
if ((ptr = list_next( &reader->current->parent->children, &reader->current->entry )))
|
success = move_to_next_node( reader );
|
||||||
{
|
|
||||||
reader->current = LIST_ENTRY( ptr, struct node, entry );
|
|
||||||
success = TRUE;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WS_MOVE_TO_PREVIOUS_NODE:
|
case WS_MOVE_TO_PREVIOUS_NODE:
|
||||||
if ((ptr = list_prev( &reader->current->parent->children, &reader->current->entry )))
|
success = move_to_prev_node( reader );
|
||||||
{
|
|
||||||
reader->current = LIST_ENTRY( ptr, struct node, entry );
|
|
||||||
success = TRUE;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WS_MOVE_TO_CHILD_NODE:
|
case WS_MOVE_TO_CHILD_NODE:
|
||||||
if ((ptr = list_head( &reader->current->children )))
|
success = move_to_child_node( reader );
|
||||||
{
|
|
||||||
reader->current = LIST_ENTRY( ptr, struct node, entry );
|
|
||||||
success = TRUE;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WS_MOVE_TO_BOF:
|
case WS_MOVE_TO_BOF:
|
||||||
|
@ -2836,6 +2873,16 @@ static BOOL is_empty_text_node( const struct node *node )
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT read_next_node( struct reader *reader )
|
||||||
|
{
|
||||||
|
if (reader->current == reader->last) return read_node( reader );
|
||||||
|
if (move_to_child_node( reader )) return S_OK;
|
||||||
|
if (move_to_next_node( reader )) return S_OK;
|
||||||
|
if (!move_to_parent_node( reader )) return WS_E_INVALID_FORMAT;
|
||||||
|
if (move_to_next_node( reader )) return S_OK;
|
||||||
|
return WS_E_INVALID_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
/* skips comment and empty text nodes */
|
/* skips comment and empty text nodes */
|
||||||
static HRESULT read_type_next_node( struct reader *reader )
|
static HRESULT read_type_next_node( struct reader *reader )
|
||||||
{
|
{
|
||||||
|
@ -2844,7 +2891,7 @@ static HRESULT read_type_next_node( struct reader *reader )
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
WS_XML_NODE_TYPE type;
|
WS_XML_NODE_TYPE type;
|
||||||
|
|
||||||
if ((hr = read_node( reader )) != S_OK) return hr;
|
if ((hr = read_next_node( reader )) != S_OK) return hr;
|
||||||
type = node_type( reader->current );
|
type = node_type( reader->current );
|
||||||
if (type == WS_XML_NODE_TYPE_COMMENT ||
|
if (type == WS_XML_NODE_TYPE_COMMENT ||
|
||||||
(type == WS_XML_NODE_TYPE_TEXT && is_empty_text_node( reader->current ))) continue;
|
(type == WS_XML_NODE_TYPE_TEXT && is_empty_text_node( reader->current ))) continue;
|
||||||
|
@ -2852,22 +2899,41 @@ static HRESULT read_type_next_node( struct reader *reader )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL match_current_element( struct reader *reader, const WS_XML_STRING *localname,
|
||||||
|
const WS_XML_STRING *ns )
|
||||||
|
{
|
||||||
|
const WS_XML_ELEMENT_NODE *elem = &reader->current->hdr;
|
||||||
|
if (node_type( reader->current ) != WS_XML_NODE_TYPE_ELEMENT) return FALSE;
|
||||||
|
return WsXmlStringEquals( localname, elem->localName, NULL ) == S_OK &&
|
||||||
|
WsXmlStringEquals( ns, elem->ns, NULL ) == S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT read_type_next_element_node( struct reader *reader, const WS_XML_STRING *localname,
|
static HRESULT read_type_next_element_node( struct reader *reader, const WS_XML_STRING *localname,
|
||||||
const WS_XML_STRING *ns )
|
const WS_XML_STRING *ns )
|
||||||
{
|
{
|
||||||
const WS_XML_ELEMENT_NODE *elem;
|
struct node *node;
|
||||||
|
ULONG attr;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
BOOL found;
|
|
||||||
|
|
||||||
if (!localname) return S_OK; /* assume reader is already correctly positioned */
|
if (!localname) return S_OK; /* assume reader is already correctly positioned */
|
||||||
if ((hr = read_to_startelement( reader, &found )) != S_OK) return hr;
|
if (reader->current == reader->last)
|
||||||
if (!found) return WS_E_INVALID_FORMAT;
|
{
|
||||||
|
BOOL found;
|
||||||
|
if ((hr = read_to_startelement( reader, &found )) != S_OK) return hr;
|
||||||
|
if (!found) return WS_E_INVALID_FORMAT;
|
||||||
|
}
|
||||||
|
if (match_current_element( reader, localname, ns )) return S_OK;
|
||||||
|
|
||||||
elem = &reader->current->hdr;
|
node = reader->current;
|
||||||
if (WsXmlStringEquals( localname, elem->localName, NULL ) == S_OK &&
|
attr = reader->current_attr;
|
||||||
WsXmlStringEquals( ns, elem->ns, NULL ) == S_OK) return S_OK;
|
|
||||||
|
|
||||||
return read_type_next_node( reader );
|
if ((hr = read_type_next_node( reader )) != S_OK) return hr;
|
||||||
|
if (match_current_element( reader, localname, ns )) return S_OK;
|
||||||
|
|
||||||
|
reader->current = node;
|
||||||
|
reader->current_attr = attr;
|
||||||
|
|
||||||
|
return WS_E_INVALID_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG get_type_size( WS_TYPE type, const WS_STRUCT_DESCRIPTION *desc )
|
static ULONG get_type_size( WS_TYPE type, const WS_STRUCT_DESCRIPTION *desc )
|
||||||
|
@ -2967,11 +3033,13 @@ static HRESULT read_type_text( struct reader *reader, const WS_FIELD_DESCRIPTION
|
||||||
WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size )
|
WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size )
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
BOOL found;
|
if (reader->current == reader->last)
|
||||||
|
{
|
||||||
if ((hr = read_to_startelement( reader, &found )) != S_OK) return S_OK;
|
BOOL found;
|
||||||
if (!found) return WS_E_INVALID_FORMAT;
|
if ((hr = read_to_startelement( reader, &found )) != S_OK) return S_OK;
|
||||||
if ((hr = read_node( reader )) != S_OK) return hr;
|
if (!found) return WS_E_INVALID_FORMAT;
|
||||||
|
}
|
||||||
|
if ((hr = read_next_node( reader )) != S_OK) return hr;
|
||||||
if (node_type( reader->current ) != WS_XML_NODE_TYPE_TEXT) return WS_E_INVALID_FORMAT;
|
if (node_type( reader->current ) != WS_XML_NODE_TYPE_TEXT) return WS_E_INVALID_FORMAT;
|
||||||
|
|
||||||
return read_type( reader, WS_ANY_ELEMENT_TYPE_MAPPING, desc->type, NULL, NULL,
|
return read_type( reader, WS_ANY_ELEMENT_TYPE_MAPPING, desc->type, NULL, NULL,
|
||||||
|
|
Loading…
Reference in New Issue