Module: wine Branch: master Commit: 48975081b8c0a260febe98a21a15fa70639d017c URL: http://source.winehq.org/git/wine.git/?a=commit;h=48975081b8c0a260febe98a21a...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Feb 3 15:43:46 2016 +0100
webservices: Parse CDATA nodes.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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(); }