[6/8] webservices: Implement WsMoveWriter.
Hans Leidekker
hans at codeweavers.com
Tue Jun 21 07:04:46 CDT 2016
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/webservices/reader.c | 151 +++++++++++++++++++--------------
dlls/webservices/tests/writer.c | 71 ++++++++++++++++
dlls/webservices/webservices.spec | 2 +-
dlls/webservices/webservices_private.h | 13 +++
dlls/webservices/writer.c | 87 +++++++++++++++++++
5 files changed, 258 insertions(+), 66 deletions(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 8f2d8fb..b8dfed4 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -1549,24 +1549,24 @@ HRESULT WINAPI WsReadToStartElement( WS_XML_READER *handle, const WS_XML_STRING
return read_to_startelement( reader, found );
}
-static BOOL move_to_root_element( struct reader *reader )
+BOOL move_to_root_element( struct node *root, struct node **current )
{
struct list *ptr;
struct node *node;
- if (!(ptr = list_head( &reader->root->children ))) return FALSE;
+ if (!(ptr = list_head( &root->children ))) return FALSE;
node = LIST_ENTRY( ptr, struct node, entry );
if (node_type( node ) == WS_XML_NODE_TYPE_ELEMENT)
{
- reader->current = node;
+ *current = node;
return TRUE;
}
- while ((ptr = list_next( &reader->root->children, &node->entry )))
+ while ((ptr = list_next( &root->children, &node->entry )))
{
struct node *next = LIST_ENTRY( ptr, struct node, entry );
if (node_type( next ) == WS_XML_NODE_TYPE_ELEMENT)
{
- reader->current = next;
+ *current = next;
return TRUE;
}
node = next;
@@ -1574,17 +1574,18 @@ static BOOL move_to_root_element( struct reader *reader )
return FALSE;
}
-static BOOL move_to_next_element( struct reader *reader )
+BOOL move_to_next_element( struct node **current )
{
struct list *ptr;
- struct node *node = reader->current;
+ struct node *node = *current, *parent = (*current)->parent;
- while ((ptr = list_next( &node->parent->children, &node->entry )))
+ if (!parent) return FALSE;
+ while ((ptr = list_next( &parent->children, &node->entry )))
{
struct node *next = LIST_ENTRY( ptr, struct node, entry );
if (node_type( next ) == WS_XML_NODE_TYPE_ELEMENT)
{
- reader->current = next;
+ *current = next;
return TRUE;
}
node = next;
@@ -1592,17 +1593,18 @@ static BOOL move_to_next_element( struct reader *reader )
return FALSE;
}
-static BOOL move_to_prev_element( struct reader *reader )
+BOOL move_to_prev_element( struct node **current )
{
struct list *ptr;
- struct node *node = reader->current;
+ struct node *node = *current, *parent = (*current)->parent;
- while ((ptr = list_prev( &node->parent->children, &node->entry )))
+ if (!parent) return FALSE;
+ while ((ptr = list_prev( &parent->children, &node->entry )))
{
struct node *prev = LIST_ENTRY( ptr, struct node, entry );
if (node_type( prev ) == WS_XML_NODE_TYPE_ELEMENT)
{
- reader->current = prev;
+ *current = prev;
return TRUE;
}
node = prev;
@@ -1610,35 +1612,35 @@ static BOOL move_to_prev_element( struct reader *reader )
return FALSE;
}
-static BOOL move_to_child_element( struct reader *reader )
+BOOL move_to_child_element( struct node **current )
{
struct list *ptr;
- struct node *node;
+ struct node *child, *node = *current;
- if (!(ptr = list_head( &reader->current->children ))) return FALSE;
- node = LIST_ENTRY( ptr, struct node, entry );
- if (node_type( node ) == WS_XML_NODE_TYPE_ELEMENT)
+ if (!(ptr = list_head( &node->children ))) return FALSE;
+ child = LIST_ENTRY( ptr, struct node, entry );
+ if (node_type( child ) == WS_XML_NODE_TYPE_ELEMENT)
{
- reader->current = node;
+ *current = child;
return TRUE;
}
- while ((ptr = list_next( &reader->current->children, &node->entry )))
+ while ((ptr = list_next( &node->children, &child->entry )))
{
struct node *next = LIST_ENTRY( ptr, struct node, entry );
if (node_type( next ) == WS_XML_NODE_TYPE_ELEMENT)
{
- reader->current = next;
+ *current = next;
return TRUE;
}
- node = next;
+ child = next;
}
return FALSE;
}
-static BOOL move_to_end_element( struct reader *reader )
+BOOL move_to_end_element( struct node **current )
{
struct list *ptr;
- struct node *node = reader->current;
+ struct node *node = *current;
if (node_type( node ) != WS_XML_NODE_TYPE_ELEMENT) return FALSE;
@@ -1647,81 +1649,105 @@ static BOOL move_to_end_element( struct reader *reader )
struct node *tail = LIST_ENTRY( ptr, struct node, entry );
if (node_type( tail ) == WS_XML_NODE_TYPE_END_ELEMENT)
{
- reader->current = tail;
+ *current = tail;
return TRUE;
}
}
return FALSE;
}
-static BOOL move_to_parent_element( struct reader *reader )
+BOOL move_to_parent_element( struct node **current )
{
- struct node *parent = reader->current->parent;
+ struct node *parent = (*current)->parent;
if (parent && (node_type( parent ) == WS_XML_NODE_TYPE_ELEMENT ||
node_type( parent ) == WS_XML_NODE_TYPE_BOF))
{
- reader->current = parent;
+ *current = parent;
return TRUE;
}
return FALSE;
}
-static BOOL move_to_first_node( struct reader *reader )
+BOOL move_to_first_node( struct node **current )
{
struct list *ptr;
- if ((ptr = list_head( &reader->current->parent->children )))
+ struct node *node = *current;
+
+ if ((ptr = list_head( &node->parent->children )))
{
- reader->current = LIST_ENTRY( ptr, struct node, entry );
+ *current = LIST_ENTRY( ptr, struct node, entry );
return TRUE;
}
return FALSE;
}
-static BOOL move_to_next_node( struct reader *reader )
+BOOL move_to_next_node( struct node **current )
{
struct list *ptr;
- if ((ptr = list_next( &reader->current->parent->children, &reader->current->entry )))
+ struct node *node = *current;
+
+ if ((ptr = list_next( &node->parent->children, &node->entry )))
{
- reader->current = LIST_ENTRY( ptr, struct node, entry );
+ *current = LIST_ENTRY( ptr, struct node, entry );
return TRUE;
}
return FALSE;
}
-static BOOL move_to_prev_node( struct reader *reader )
+BOOL move_to_prev_node( struct node **current )
{
struct list *ptr;
- if ((ptr = list_prev( &reader->current->parent->children, &reader->current->entry )))
+ struct node *node = *current;
+
+ if ((ptr = list_prev( &node->parent->children, &node->entry )))
{
- reader->current = LIST_ENTRY( ptr, struct node, entry );
+ *current = LIST_ENTRY( ptr, struct node, entry );
return TRUE;
}
return FALSE;
}
-static BOOL move_to_child_node( struct reader *reader )
+BOOL move_to_bof( struct node *root, struct node **current )
+{
+ *current = root;
+ return TRUE;
+}
+
+BOOL move_to_eof( struct node *root, struct node **current )
{
struct list *ptr;
- if ((ptr = list_head( &reader->current->children )))
+ if ((ptr = list_tail( &root->children )))
{
- reader->current = LIST_ENTRY( ptr, struct node, entry );
+ *current = LIST_ENTRY( ptr, struct node, entry );
return TRUE;
}
return FALSE;
}
-static BOOL move_to_parent_node( struct reader *reader )
+BOOL move_to_child_node( struct node **current )
{
- struct node *parent = reader->current->parent;
+ struct list *ptr;
+ struct node *node = *current;
+
+ if ((ptr = list_head( &node->children )))
+ {
+ *current = LIST_ENTRY( ptr, struct node, entry );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static BOOL move_to_parent_node( struct node **current )
+{
+ struct node *parent = (*current)->parent;
if (!parent) return FALSE;
- reader->current = parent;
+ *current = parent;
return TRUE;
}
static HRESULT read_move_to( struct reader *reader, WS_MOVE_TO move, BOOL *found )
{
- struct list *ptr;
BOOL success = FALSE;
HRESULT hr = S_OK;
@@ -1733,56 +1759,51 @@ static HRESULT read_move_to( struct reader *reader, WS_MOVE_TO move, BOOL *found
switch (move)
{
case WS_MOVE_TO_ROOT_ELEMENT:
- success = move_to_root_element( reader );
+ success = move_to_root_element( reader->root, &reader->current );
break;
case WS_MOVE_TO_NEXT_ELEMENT:
- success = move_to_next_element( reader );
+ success = move_to_next_element( &reader->current );
break;
case WS_MOVE_TO_PREVIOUS_ELEMENT:
- success = move_to_prev_element( reader );
+ success = move_to_prev_element( &reader->current );
break;
case WS_MOVE_TO_CHILD_ELEMENT:
- success = move_to_child_element( reader );
+ success = move_to_child_element( &reader->current );
break;
case WS_MOVE_TO_END_ELEMENT:
- success = move_to_end_element( reader );
+ success = move_to_end_element( &reader->current );
break;
case WS_MOVE_TO_PARENT_ELEMENT:
- success = move_to_parent_element( reader );
+ success = move_to_parent_element( &reader->current );
break;
case WS_MOVE_TO_FIRST_NODE:
- success = move_to_first_node( reader );
+ success = move_to_first_node( &reader->current );
break;
case WS_MOVE_TO_NEXT_NODE:
- success = move_to_next_node( reader );
+ success = move_to_next_node( &reader->current );
break;
case WS_MOVE_TO_PREVIOUS_NODE:
- success = move_to_prev_node( reader );
+ success = move_to_prev_node( &reader->current );
break;
case WS_MOVE_TO_CHILD_NODE:
- success = move_to_child_node( reader );
+ success = move_to_child_node( &reader->current );
break;
case WS_MOVE_TO_BOF:
- reader->current = reader->root;
- success = TRUE;
+ success = move_to_bof( reader->root, &reader->current );
break;
case WS_MOVE_TO_EOF:
- if ((ptr = list_tail( &reader->root->children )))
- {
- reader->current = LIST_ENTRY( ptr, struct node, entry );
- success = TRUE;
- }
+ success = move_to_eof( reader->root, &reader->current );
break;
default:
@@ -3186,10 +3207,10 @@ static BOOL is_empty_text_node( const struct node *node )
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;
+ if (move_to_child_node( &reader->current )) return S_OK;
+ if (move_to_next_node( &reader->current )) return S_OK;
+ if (!move_to_parent_node( &reader->current )) return WS_E_INVALID_FORMAT;
+ if (move_to_next_node( &reader->current )) return S_OK;
return WS_E_INVALID_FORMAT;
}
diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c
index 4e22887..b223544 100644
--- a/dlls/webservices/tests/writer.c
+++ b/dlls/webservices/tests/writer.c
@@ -1415,6 +1415,76 @@ static void test_complex_struct_type(void)
WsFreeHeap( heap );
}
+static void test_WsMoveWriter(void)
+{
+ WS_XML_STRING localname = {1, (BYTE *)"a"}, localname2 = {1, (BYTE *)"b"}, ns = {0, NULL};
+ WS_HEAP *heap;
+ WS_XML_WRITER *writer;
+ WS_XML_BUFFER *buffer;
+ HRESULT hr;
+
+ hr = WsMoveWriter( NULL, WS_MOVE_TO_EOF, NULL, NULL );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+ hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsCreateWriter( NULL, 0, &writer, NULL ) ;
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = set_output( writer );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ /* writer must be set to an XML buffer */
+ hr = WsMoveWriter( writer, WS_MOVE_TO_EOF, NULL, NULL );
+ todo_wine ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
+ hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsMoveWriter( writer, WS_MOVE_TO_EOF, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ /* <a><b/></a> */
+ hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsWriteStartElement( writer, NULL, &localname2, &ns, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsWriteEndElement( writer, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsWriteEndElement( writer, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsMoveWriter( writer, WS_MOVE_TO_EOF, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsMoveWriter( writer, WS_MOVE_TO_ROOT_ELEMENT, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsMoveWriter( writer, WS_MOVE_TO_CHILD_ELEMENT, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsMoveWriter( writer, WS_MOVE_TO_END_ELEMENT, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsMoveWriter( writer, WS_MOVE_TO_PARENT_ELEMENT, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsMoveWriter( writer, WS_MOVE_TO_END_ELEMENT, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsMoveWriter( writer, WS_MOVE_TO_BOF, NULL, NULL );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+ WsFreeWriter( writer );
+ WsFreeHeap( heap );
+}
START_TEST(writer)
{
@@ -1434,4 +1504,5 @@ START_TEST(writer)
test_WsWriteXmlnsAttribute();
test_WsGetPrefixFromNamespace();
test_complex_struct_type();
+ test_WsMoveWriter();
}
diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec
index 0093fc0..5754c61 100644
--- a/dlls/webservices/webservices.spec
+++ b/dlls/webservices/webservices.spec
@@ -94,7 +94,7 @@
@ stub WsMarkHeaderAsUnderstood
@ stub WsMatchPolicyAlternative
@ stdcall WsMoveReader(ptr long ptr ptr)
-@ stub WsMoveWriter
+@ stdcall WsMoveWriter(ptr long ptr ptr)
@ stdcall WsOpenChannel(ptr ptr ptr ptr)
@ stub WsOpenListener
@ stub WsOpenServiceHost
diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h
index fc888ee..74ee5a4 100644
--- a/dlls/webservices/webservices_private.h
+++ b/dlls/webservices/webservices_private.h
@@ -52,6 +52,19 @@ static inline WS_XML_NODE_TYPE node_type( const struct node *node )
return node->hdr.node.nodeType;
}
+BOOL move_to_root_element( struct node *, struct node ** ) DECLSPEC_HIDDEN;
+BOOL move_to_next_element( struct node ** ) DECLSPEC_HIDDEN;
+BOOL move_to_prev_element( struct node ** ) DECLSPEC_HIDDEN;
+BOOL move_to_child_element( struct node ** ) DECLSPEC_HIDDEN;
+BOOL move_to_end_element( struct node ** ) DECLSPEC_HIDDEN;
+BOOL move_to_parent_element( struct node ** ) DECLSPEC_HIDDEN;
+BOOL move_to_first_node( struct node ** ) DECLSPEC_HIDDEN;
+BOOL move_to_next_node( struct node ** ) DECLSPEC_HIDDEN;
+BOOL move_to_prev_node( struct node ** ) DECLSPEC_HIDDEN;
+BOOL move_to_bof( struct node *, struct node ** ) DECLSPEC_HIDDEN;
+BOOL move_to_eof( struct node *, struct node ** ) DECLSPEC_HIDDEN;
+BOOL move_to_child_node( struct node ** ) DECLSPEC_HIDDEN;
+
struct prop_desc
{
ULONG size;
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index bf4c61b..583e7fa 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -1714,3 +1714,90 @@ HRESULT WINAPI WsWriteXmlnsAttribute( WS_XML_WRITER *handle, const WS_XML_STRING
if (namespace_in_scope( &writer->current->hdr, prefix, ns )) return S_OK;
return write_add_namespace_attribute( writer, prefix, ns, single );
}
+
+static HRESULT write_move_to( struct writer *writer, WS_MOVE_TO move, BOOL *found )
+{
+ BOOL success = FALSE;
+ struct node *node = writer->current;
+
+ switch (move)
+ {
+ case WS_MOVE_TO_ROOT_ELEMENT:
+ success = move_to_root_element( writer->root, &node );
+ break;
+
+ case WS_MOVE_TO_NEXT_ELEMENT:
+ success = move_to_next_element( &node );
+ break;
+
+ case WS_MOVE_TO_PREVIOUS_ELEMENT:
+ success = move_to_prev_element( &node );
+ break;
+
+ case WS_MOVE_TO_CHILD_ELEMENT:
+ success = move_to_child_element( &node );
+ break;
+
+ case WS_MOVE_TO_END_ELEMENT:
+ success = move_to_end_element( &node );
+ break;
+
+ case WS_MOVE_TO_PARENT_ELEMENT:
+ success = move_to_parent_element( &node );
+ break;
+
+ case WS_MOVE_TO_FIRST_NODE:
+ success = move_to_first_node( &node );
+ break;
+
+ case WS_MOVE_TO_NEXT_NODE:
+ success = move_to_next_node( &node );
+ break;
+
+ case WS_MOVE_TO_PREVIOUS_NODE:
+ success = move_to_prev_node( &node );
+ break;
+
+ case WS_MOVE_TO_CHILD_NODE:
+ success = move_to_child_node( &node );
+ break;
+
+ case WS_MOVE_TO_BOF:
+ success = move_to_bof( writer->root, &node );
+ break;
+
+ case WS_MOVE_TO_EOF:
+ success = move_to_eof( writer->root, &node );
+ break;
+
+ default:
+ FIXME( "unhandled move %u\n", move );
+ return E_NOTIMPL;
+ }
+
+ if (success && node == writer->root) return E_INVALIDARG;
+ writer->current = node;
+
+ if (found)
+ {
+ *found = success;
+ return S_OK;
+ }
+ return success ? S_OK : WS_E_INVALID_FORMAT;
+}
+
+/**************************************************************************
+ * WsMoveWriter [webservices.@]
+ */
+HRESULT WINAPI WsMoveWriter( WS_XML_WRITER *handle, WS_MOVE_TO move, BOOL *found, WS_ERROR *error )
+{
+ struct writer *writer = (struct writer *)handle;
+
+ TRACE( "%p %u %p %p\n", handle, move, found, error );
+ if (error) FIXME( "ignoring error parameter\n" );
+
+ if (!writer) return E_INVALIDARG;
+ if (!writer->output_type) return WS_E_INVALID_OPERATION;
+
+ return write_move_to( writer, move, found );
+}
--
2.8.1
More information about the wine-patches
mailing list