Piotr Caban : msxml3: Add support for CDATA nodes in node_get_text.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Dec 21 15:10:33 CST 2015


Module: wine
Branch: master
Commit: 028d5e5179807b7be8abfb79a3877eeed58c5f3c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=028d5e5179807b7be8abfb79a3877eeed58c5f3c

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Dec 21 11:41:26 2015 +0100

msxml3: Add support for CDATA nodes in node_get_text.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msxml3/node.c         | 77 +++++++++++++++++++++++++++-------------------
 dlls/msxml3/tests/domdoc.c |  4 +--
 2 files changed, 48 insertions(+), 33 deletions(-)

diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c
index 17e3838..72fa92f 100644
--- a/dlls/msxml3/node.c
+++ b/dlls/msxml3/node.c
@@ -723,31 +723,15 @@ HRESULT node_clone(xmlnode *This, VARIANT_BOOL deep, IXMLDOMNode **cloneNode)
     return S_OK;
 }
 
-static inline xmlChar* trim_whitespace(xmlChar* str)
-{
-    xmlChar* ret = str;
-    int len;
-
-    if (!str)
-        return NULL;
-
-    while (*ret && isspace(*ret))
-        ++ret;
-    len = xmlStrlen(ret);
-    if (len)
-        while (isspace(ret[len-1])) --len;
-
-    ret = xmlStrndup(ret, len);
-    xmlFree(str);
-    return ret;
-}
-
-static xmlChar* do_get_text(xmlNodePtr node, BOOL trim, BOOL *trail_ig_ws)
+static xmlChar* do_get_text(xmlNodePtr node, BOOL trim, DWORD *first, DWORD *last, BOOL *trail_ig_ws)
 {
     xmlNodePtr child;
     xmlChar* str;
     BOOL preserving = is_preserving_whitespace(node);
 
+    *first = -1;
+    *last = 0;
+
     if (!node->children)
     {
         str = xmlNodeGetContent(node);
@@ -757,6 +741,7 @@ static xmlChar* do_get_text(xmlNodePtr node, BOOL trim, BOOL *trail_ig_ws)
     {
         BOOL ig_ws = FALSE;
         xmlChar* tmp;
+        DWORD pos = 0;
         str = xmlStrdup(BAD_CAST "");
 
         if (node->type != XML_DOCUMENT_NODE)
@@ -767,9 +752,17 @@ static xmlChar* do_get_text(xmlNodePtr node, BOOL trim, BOOL *trail_ig_ws)
         {
             switch (child->type)
             {
-            case XML_ELEMENT_NODE:
-                tmp = do_get_text(child, FALSE, trail_ig_ws);
+            case XML_ELEMENT_NODE: {
+                DWORD node_first, node_last;
+
+                tmp = do_get_text(child, FALSE, &node_first, &node_last, trail_ig_ws);
+
+                if (node_first!=-1 && pos+node_first<*first)
+                    *first = pos+node_first;
+                if (node_last && pos+node_last>*last)
+                    *last = pos+node_last;
                 break;
+            }
             case XML_TEXT_NODE:
                 tmp = xmlNodeGetContent(child);
                 if (!preserving && tmp[0])
@@ -797,17 +790,22 @@ static xmlChar* do_get_text(xmlNodePtr node, BOOL trim, BOOL *trail_ig_ws)
                 break;
             }
 
-            if (tmp)
+            if ((tmp && *tmp) || child->type==XML_CDATA_SECTION_NODE)
             {
-                if (*tmp)
+                if (ig_ws && str[0])
                 {
-                    if (ig_ws && str[0])
-                        str = xmlStrcat(str, BAD_CAST " ");
-                    str = xmlStrcat(str, tmp);
-                    ig_ws = FALSE;
+                    str = xmlStrcat(str, BAD_CAST " ");
+                    pos++;
                 }
-                xmlFree(tmp);
+                if (tmp && *tmp) str = xmlStrcat(str, tmp);
+                if (child->type==XML_CDATA_SECTION_NODE && pos<*first)
+                    *first = pos;
+                if (tmp && *tmp) pos += xmlStrlen(tmp);
+                if (child->type==XML_CDATA_SECTION_NODE && pos>*last)
+                    *last = pos;
+                ig_ws = FALSE;
             }
+            if (tmp) xmlFree(tmp);
 
             if (!ig_ws)
             {
@@ -830,7 +828,23 @@ static xmlChar* do_get_text(xmlNodePtr node, BOOL trim, BOOL *trail_ig_ws)
     case XML_DOCUMENT_NODE:
     case XML_DOCUMENT_FRAG_NODE:
         if (trim && !preserving)
-            str = trim_whitespace(str);
+        {
+            xmlChar* ret = str;
+            int len;
+
+            if (!str)
+                break;
+
+            for (ret = str; *ret && isspace(*ret) && (*first)--; ret++)
+                if (*last) (*last)--;
+            for (len = xmlStrlen(ret)-1; len >= 0 && len >= *last; len--)
+                if(!isspace(ret[len])) break;
+
+            ret = xmlStrndup(ret, len+1);
+            xmlFree(str);
+            str = ret;
+            break;
+        }
         break;
     default:
         break;
@@ -843,11 +857,12 @@ HRESULT node_get_text(const xmlnode *This, BSTR *text)
 {
     BSTR str = NULL;
     xmlChar *content;
+    DWORD first, last;
     BOOL tmp;
 
     if (!text) return E_INVALIDARG;
 
-    content = do_get_text(This->node, TRUE, &tmp);
+    content = do_get_text(This->node, TRUE, &first, &last, &tmp);
     if (content)
     {
         str = bstr_from_xmlChar(content);
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 4201bac..1926f50 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -4178,7 +4178,7 @@ static inline void _check_ws_ignored(int line, const char *ver, IXMLDOMDocument2
     }
     else
     {
-        todo_wine helper_expect_bstr_and_release(bstr, " This is a description.");
+        helper_expect_bstr_and_release(bstr, " This is a description.");
     }
     IXMLDOMNode_Release(node1);
 
@@ -4213,7 +4213,7 @@ static inline void _check_ws_preserved(int line, const char *ver, IXMLDOMDocumen
     helper_ole_check_ver(IXMLDOMNode_get_text(node1, &bstr));
     if (str)
     {
-        todo_wine helper_expect_bstr_and_release(bstr, str);
+        helper_expect_bstr_and_release(bstr, str);
     }
     else
     {




More information about the wine-cvs mailing list