Hans Leidekker : webservices: Parse CDATA nodes.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Feb 3 10:23:54 CST 2016
Module: wine
Branch: master
Commit: 48975081b8c0a260febe98a21a15fa70639d017c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=48975081b8c0a260febe98a21a15fa70639d017c
Author: Hans Leidekker <hans at codeweavers.com>
Date: Wed Feb 3 15:43:46 2016 +0100
webservices: Parse CDATA nodes.
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/webservices/reader.c | 69 +++++++++++++++++++++++++++++++++++++++--
dlls/webservices/tests/reader.c | 67 +++++++++++++++++++++++++++++++++++++++
2 files changed, 134 insertions(+), 2 deletions(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 515ed1e..9391cf8 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -329,6 +329,8 @@ void free_node( struct node *node )
heap_free( comment->value.bytes );
break;
}
+ case WS_XML_NODE_TYPE_CDATA:
+ case WS_XML_NODE_TYPE_END_CDATA:
case WS_XML_NODE_TYPE_END_ELEMENT:
case WS_XML_NODE_TYPE_EOF:
case WS_XML_NODE_TYPE_BOF:
@@ -386,8 +388,11 @@ enum reader_state
READER_STATE_STARTELEMENT,
READER_STATE_STARTATTRIBUTE,
READER_STATE_STARTENDELEMENT,
+ READER_STATE_STARTCDATA,
+ READER_STATE_CDATA,
READER_STATE_TEXT,
READER_STATE_ENDELEMENT,
+ READER_STATE_ENDCDATA,
READER_STATE_COMMENT,
READER_STATE_EOF
};
@@ -1168,6 +1173,63 @@ static HRESULT read_comment( struct reader *reader )
return S_OK;
}
+static HRESULT read_startcdata( struct reader *reader )
+{
+ struct node *node;
+
+ if (read_cmp( reader, "<![CDATA[", 9 )) return WS_E_INVALID_FORMAT;
+ read_skip( reader, 9 );
+
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_CDATA ))) return E_OUTOFMEMORY;
+ read_insert_node( reader, reader->current, node );
+ reader->state = READER_STATE_STARTCDATA;
+ return S_OK;
+}
+
+static HRESULT read_cdata( struct reader *reader )
+{
+ unsigned int len = 0, ch, skip;
+ const unsigned char *start;
+ struct node *node;
+ WS_XML_TEXT_NODE *text;
+ WS_XML_UTF8_TEXT *utf8;
+
+ start = read_current_ptr( reader );
+ for (;;)
+ {
+ if (!read_cmp( reader, "]]>", 3 )) break;
+ if (!(ch = read_utf8_char( reader, &skip ))) return WS_E_INVALID_FORMAT;
+ read_skip( reader, skip );
+ len += skip;
+ }
+
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return E_OUTOFMEMORY;
+ text = (WS_XML_TEXT_NODE *)node;
+ if (!(utf8 = alloc_utf8_text( start, len )))
+ {
+ heap_free( node );
+ return E_OUTOFMEMORY;
+ }
+ text->text = &utf8->text;
+
+ read_insert_node( reader, reader->current, node );
+ reader->state = READER_STATE_CDATA;
+ return S_OK;
+}
+
+static HRESULT read_endcdata( struct reader *reader )
+{
+ struct node *node;
+
+ if (read_cmp( reader, "]]>", 3 )) return WS_E_INVALID_FORMAT;
+ read_skip( reader, 3 );
+
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_END_CDATA ))) return E_OUTOFMEMORY;
+ read_insert_node( reader, reader->current->parent, node );
+ reader->state = READER_STATE_ENDCDATA;
+ return S_OK;
+}
+
static HRESULT read_node( struct reader *reader )
{
HRESULT hr;
@@ -1181,13 +1243,16 @@ static HRESULT read_node( struct reader *reader )
reader->state = READER_STATE_EOF;
return S_OK;
}
- if (!read_cmp( reader, "<?", 2 ))
+ if (reader->state == READER_STATE_STARTCDATA) return read_cdata( reader );
+ else if (reader->state == READER_STATE_CDATA) return read_endcdata( reader );
+ else if (!read_cmp( reader, "<?", 2 ))
{
hr = read_xmldecl( reader );
if (FAILED( hr )) return hr;
}
else if (!read_cmp( reader, "</", 2 )) return read_endelement( reader );
- else if (!read_cmp( reader, "<!", 2 )) return read_comment( reader );
+ else if (!read_cmp( reader, "<![CDATA[", 9 )) return read_startcdata( reader );
+ else if (!read_cmp( reader, "<!--", 4 )) return read_comment( reader );
else if (!read_cmp( reader, "<", 1 )) return read_startelement( reader );
else return read_text( reader );
}
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index 958d08c..f9b2ea9 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -1805,6 +1805,72 @@ static void test_simple_struct_type(void)
WsFreeHeap( heap );
}
+static void test_cdata(void)
+{
+ static const char test[] = "<t><![CDATA[<data>]]></t>";
+ HRESULT hr;
+ WS_XML_READER *reader;
+ const WS_XML_NODE *node;
+
+ hr = WsCreateReader( NULL, 0, &reader, NULL ) ;
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = set_input( reader, test, sizeof(test) - 1 );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsFillReader( reader, sizeof(test) - 1, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsReadNode( reader, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsGetReaderNode( reader, &node, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType );
+
+ hr = WsReadNode( reader, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsGetReaderNode( reader, &node, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ if (node) ok( node->nodeType == WS_XML_NODE_TYPE_CDATA, "got %u\n", node->nodeType );
+
+ hr = WsReadNode( reader, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsGetReaderNode( reader, &node, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ if (node)
+ {
+ WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node;
+ ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType );
+ ok( text->text != NULL, "text not set\n" );
+ if (text->text)
+ {
+ WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text;
+ ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType );
+ ok( utf8->value.length == 6, "got %u\n", utf8->value.length );
+ ok( !memcmp( utf8->value.bytes, "<data>", 6 ), "wrong data\n" );
+ }
+ }
+
+ hr = WsReadNode( reader, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsGetReaderNode( reader, &node, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_CDATA, "got %u\n", node->nodeType );
+
+ hr = WsReadNode( reader, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsGetReaderNode( reader, &node, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType );
+
+ WsFreeReader( reader );
+}
+
START_TEST(reader)
{
test_WsCreateError();
@@ -1823,4 +1889,5 @@ START_TEST(reader)
test_WsAlloc();
test_WsMoveReader();
test_simple_struct_type();
+ test_cdata();
}
More information about the wine-cvs
mailing list