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