Cleanup CFDE_XMLCharData and CFDE_XMLText

This Cl switchs CFDE_XMLCharData to subclass CFDE_XMLText and cleans up
the code which was the same except for the accessor names.

Change-Id: I85ebf4f3f19f0d15be4dd77a71b89ca8083f4b1e
Reviewed-on: https://pdfium-review.googlesource.com/3672
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: Nicolás Peña <npm@chromium.org>
diff --git a/xfa/fde/xml/cfde_xmlchardata.cpp b/xfa/fde/xml/cfde_xmlchardata.cpp
index 2339307..bb29919 100644
--- a/xfa/fde/xml/cfde_xmlchardata.cpp
+++ b/xfa/fde/xml/cfde_xmlchardata.cpp
@@ -6,8 +6,10 @@
 
 #include "xfa/fde/xml/cfde_xmlchardata.h"
 
+#include "third_party/base/ptr_util.h"
+
 CFDE_XMLCharData::CFDE_XMLCharData(const CFX_WideString& wsCData)
-    : CFDE_XMLNode(), m_wsCharData(wsCData) {}
+    : CFDE_XMLText(wsCData) {}
 
 CFDE_XMLCharData::~CFDE_XMLCharData() {}
 
@@ -15,7 +17,6 @@
   return FDE_XMLNODE_CharData;
 }
 
-CFDE_XMLNode* CFDE_XMLCharData::Clone(bool bRecursive) {
-  CFDE_XMLCharData* pClone = new CFDE_XMLCharData(m_wsCharData);
-  return pClone;
+std::unique_ptr<CFDE_XMLNode> CFDE_XMLCharData::Clone() {
+  return pdfium::MakeUnique<CFDE_XMLCharData>(GetText());
 }
diff --git a/xfa/fde/xml/cfde_xmlchardata.h b/xfa/fde/xml/cfde_xmlchardata.h
index ea1d3aa..56babbc 100644
--- a/xfa/fde/xml/cfde_xmlchardata.h
+++ b/xfa/fde/xml/cfde_xmlchardata.h
@@ -7,23 +7,18 @@
 #ifndef XFA_FDE_XML_CFDE_XMLCHARDATA_H_
 #define XFA_FDE_XML_CFDE_XMLCHARDATA_H_
 
-#include "core/fxcrt/fx_string.h"
-#include "xfa/fde/xml/cfde_xmlnode.h"
+#include <memory>
 
-class CFDE_XMLCharData : public CFDE_XMLNode {
+#include "core/fxcrt/fx_string.h"
+#include "xfa/fde/xml/cfde_xmltext.h"
+
+class CFDE_XMLCharData : public CFDE_XMLText {
  public:
   explicit CFDE_XMLCharData(const CFX_WideString& wsCData);
   ~CFDE_XMLCharData() override;
 
   FDE_XMLNODETYPE GetType() const override;
-  CFDE_XMLNode* Clone(bool bRecursive) override;
-
-  void GetCharData(CFX_WideString& wsCharData) const {
-    wsCharData = m_wsCharData;
-  }
-  void SetCharData(const CFX_WideString& wsCData) { m_wsCharData = wsCData; }
-
-  CFX_WideString m_wsCharData;
+  std::unique_ptr<CFDE_XMLNode> Clone() override;
 };
 
 #endif  // XFA_FDE_XML_CFDE_XMLCHARDATA_H_
diff --git a/xfa/fde/xml/cfde_xmldoc.cpp b/xfa/fde/xml/cfde_xmldoc.cpp
index bc526ae..5d427fb 100644
--- a/xfa/fde/xml/cfde_xmldoc.cpp
+++ b/xfa/fde/xml/cfde_xmldoc.cpp
@@ -98,7 +98,8 @@
         ws = L"?>";
         pXMLStream->WriteString(ws.c_str(), ws.GetLength());
       }
-    } break;
+      break;
+    }
     case FDE_XMLNODE_Element: {
       CFX_WideString ws;
       ws = L"<";
@@ -137,24 +138,26 @@
         ws = L"\n/>";
       }
       pXMLStream->WriteString(ws.c_str(), ws.GetLength());
-    } break;
+      break;
+    }
     case FDE_XMLNODE_Text: {
-      CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText;
+      CFX_WideString ws = static_cast<CFDE_XMLText*>(pNode)->GetText();
       ws.Replace(L"&", L"&amp;");
       ws.Replace(L"<", L"&lt;");
       ws.Replace(L">", L"&gt;");
       ws.Replace(L"\'", L"&apos;");
       ws.Replace(L"\"", L"&quot;");
       pXMLStream->WriteString(ws.c_str(), ws.GetLength());
-    } break;
+      break;
+    }
     case FDE_XMLNODE_CharData: {
       CFX_WideString ws = L"<![CDATA[";
-      ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData;
+      ws += static_cast<CFDE_XMLCharData*>(pNode)->GetText();
       ws += L"]]>";
       pXMLStream->WriteString(ws.c_str(), ws.GetLength());
-    } break;
-    case FDE_XMLNODE_Unknown:
       break;
+    }
+    case FDE_XMLNODE_Unknown:
     default:
       break;
   }
diff --git a/xfa/fde/xml/cfde_xmlelement.cpp b/xfa/fde/xml/cfde_xmlelement.cpp
index aca27c5..646eea2 100644
--- a/xfa/fde/xml/cfde_xmlelement.cpp
+++ b/xfa/fde/xml/cfde_xmlelement.cpp
@@ -7,6 +7,7 @@
 #include "xfa/fde/xml/cfde_xmlelement.h"
 
 #include "core/fxcrt/fx_ext.h"
+#include "third_party/base/ptr_util.h"
 #include "third_party/base/stl_util.h"
 #include "xfa/fde/xml/cfde_xmlchardata.h"
 #include "xfa/fde/xml/cfde_xmltext.h"
@@ -22,29 +23,23 @@
   return FDE_XMLNODE_Element;
 }
 
-CFDE_XMLNode* CFDE_XMLElement::Clone(bool bRecursive) {
-  CFDE_XMLElement* pClone = new CFDE_XMLElement(m_wsTag);
-  if (!pClone)
-    return nullptr;
-
+std::unique_ptr<CFDE_XMLNode> CFDE_XMLElement::Clone() {
+  auto pClone = pdfium::MakeUnique<CFDE_XMLElement>(m_wsTag);
   pClone->m_Attributes = m_Attributes;
-  if (bRecursive) {
-    CloneChildren(pClone);
-  } else {
-    CFX_WideString wsText;
-    CFDE_XMLNode* pChild = m_pChild;
-    while (pChild) {
-      switch (pChild->GetType()) {
-        case FDE_XMLNODE_Text:
-          wsText += ((CFDE_XMLText*)pChild)->m_wsText;
-          break;
-        default:
-          break;
-      }
-      pChild = pChild->m_pNext;
+
+  CFX_WideString wsText;
+  CFDE_XMLNode* pChild = m_pChild;
+  while (pChild) {
+    switch (pChild->GetType()) {
+      case FDE_XMLNODE_Text:
+        wsText += static_cast<CFDE_XMLText*>(pChild)->GetText();
+        break;
+      default:
+        break;
     }
-    pClone->SetTextData(wsText);
+    pChild = pChild->m_pNext;
   }
+  pClone->SetTextData(wsText);
   return pClone;
 }
 
@@ -202,10 +197,8 @@
   while (pChild) {
     switch (pChild->GetType()) {
       case FDE_XMLNODE_Text:
-        buffer << ((CFDE_XMLText*)pChild)->m_wsText;
-        break;
       case FDE_XMLNODE_CharData:
-        buffer << ((CFDE_XMLCharData*)pChild)->m_wsCharData;
+        buffer << static_cast<CFDE_XMLText*>(pChild)->GetText();
         break;
       default:
         break;
diff --git a/xfa/fde/xml/cfde_xmlelement.h b/xfa/fde/xml/cfde_xmlelement.h
index 8f61035..c4c522e 100644
--- a/xfa/fde/xml/cfde_xmlelement.h
+++ b/xfa/fde/xml/cfde_xmlelement.h
@@ -7,6 +7,7 @@
 #ifndef XFA_FDE_XML_CFDE_XMLELEMENT_H_
 #define XFA_FDE_XML_CFDE_XMLELEMENT_H_
 
+#include <memory>
 #include <vector>
 
 #include "core/fxcrt/fx_string.h"
@@ -19,7 +20,7 @@
 
   // CFDE_XMLNode
   FDE_XMLNODETYPE GetType() const override;
-  CFDE_XMLNode* Clone(bool bRecursive) override;
+  std::unique_ptr<CFDE_XMLNode> Clone() override;
 
   void GetTagName(CFX_WideString& wsTag) const;
   void GetLocalTagName(CFX_WideString& wsTag) const;
diff --git a/xfa/fde/xml/cfde_xmlinstruction.cpp b/xfa/fde/xml/cfde_xmlinstruction.cpp
index 64c980b..2229b47 100644
--- a/xfa/fde/xml/cfde_xmlinstruction.cpp
+++ b/xfa/fde/xml/cfde_xmlinstruction.cpp
@@ -7,6 +7,7 @@
 #include "xfa/fde/xml/cfde_xmlinstruction.h"
 
 #include "core/fxcrt/fx_ext.h"
+#include "third_party/base/ptr_util.h"
 #include "third_party/base/stl_util.h"
 
 CFDE_XMLInstruction::CFDE_XMLInstruction(const CFX_WideString& wsTarget)
@@ -20,16 +21,10 @@
   return FDE_XMLNODE_Instruction;
 }
 
-CFDE_XMLNode* CFDE_XMLInstruction::Clone(bool bRecursive) {
-  CFDE_XMLInstruction* pClone = new CFDE_XMLInstruction(m_wsTarget);
-  if (!pClone)
-    return nullptr;
-
+std::unique_ptr<CFDE_XMLNode> CFDE_XMLInstruction::Clone() {
+  auto pClone = pdfium::MakeUnique<CFDE_XMLInstruction>(m_wsTarget);
   pClone->m_Attributes = m_Attributes;
   pClone->m_TargetData = m_TargetData;
-  if (bRecursive)
-    CloneChildren(pClone);
-
   return pClone;
 }
 
diff --git a/xfa/fde/xml/cfde_xmlinstruction.h b/xfa/fde/xml/cfde_xmlinstruction.h
index 58dc5f1..4e891e1 100644
--- a/xfa/fde/xml/cfde_xmlinstruction.h
+++ b/xfa/fde/xml/cfde_xmlinstruction.h
@@ -7,6 +7,7 @@
 #ifndef XFA_FDE_XML_CFDE_XMLINSTRUCTION_H_
 #define XFA_FDE_XML_CFDE_XMLINSTRUCTION_H_
 
+#include <memory>
 #include <vector>
 
 #include "core/fxcrt/fx_string.h"
@@ -19,7 +20,7 @@
 
   // CFDE_XMLNode
   FDE_XMLNODETYPE GetType() const override;
-  CFDE_XMLNode* Clone(bool bRecursive) override;
+  std::unique_ptr<CFDE_XMLNode> Clone() override;
 
   void GetTargetName(CFX_WideString& wsTarget) const { wsTarget = m_wsTarget; }
   int32_t CountAttributes() const;
diff --git a/xfa/fde/xml/cfde_xmlnode.cpp b/xfa/fde/xml/cfde_xmlnode.cpp
index bd86c0b..22bd262 100644
--- a/xfa/fde/xml/cfde_xmlnode.cpp
+++ b/xfa/fde/xml/cfde_xmlnode.cpp
@@ -325,7 +325,7 @@
   return pNode;
 }
 
-CFDE_XMLNode* CFDE_XMLNode::Clone(bool bRecursive) {
+std::unique_ptr<CFDE_XMLNode> CFDE_XMLNode::Clone() {
   return nullptr;
 }
 
@@ -379,7 +379,8 @@
         ws = L"?>";
         pXMLStream->WriteString(ws.c_str(), ws.GetLength());
       }
-    } break;
+      break;
+    }
     case FDE_XMLNODE_Element: {
       CFX_WideString ws;
       ws = L"<";
@@ -418,41 +419,27 @@
         ws = L"\n/>";
       }
       pXMLStream->WriteString(ws.c_str(), ws.GetLength());
-    } break;
+      break;
+    }
     case FDE_XMLNODE_Text: {
-      CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText;
+      CFX_WideString ws = static_cast<CFDE_XMLText*>(pNode)->GetText();
       ws.Replace(L"&", L"&amp;");
       ws.Replace(L"<", L"&lt;");
       ws.Replace(L">", L"&gt;");
       ws.Replace(L"\'", L"&apos;");
       ws.Replace(L"\"", L"&quot;");
       pXMLStream->WriteString(ws.c_str(), ws.GetLength());
-    } break;
+      break;
+    }
     case FDE_XMLNODE_CharData: {
       CFX_WideString ws = L"<![CDATA[";
-      ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData;
+      ws += static_cast<CFDE_XMLCharData*>(pNode)->GetText();
       ws += L"]]>";
       pXMLStream->WriteString(ws.c_str(), ws.GetLength());
-    } break;
-    case FDE_XMLNODE_Unknown:
       break;
+    }
+    case FDE_XMLNODE_Unknown:
     default:
       break;
   }
 }
-
-void CFDE_XMLNode::CloneChildren(CFDE_XMLNode* pClone) {
-  if (!m_pChild) {
-    return;
-  }
-  CFDE_XMLNode* pNext = m_pChild;
-  CFDE_XMLNode* pCloneNext = pNext->Clone(true);
-  pClone->InsertChildNode(pCloneNext);
-  pNext = pNext->m_pNext;
-  while (pNext) {
-    CFDE_XMLNode* pChild = pNext->Clone(true);
-    pCloneNext->InsertNodeItem(CFDE_XMLNode::NextSibling, pChild);
-    pCloneNext = pChild;
-    pNext = pNext->m_pNext;
-  }
-}
diff --git a/xfa/fde/xml/cfde_xmlnode.h b/xfa/fde/xml/cfde_xmlnode.h
index 178150f..3cfcd5c 100644
--- a/xfa/fde/xml/cfde_xmlnode.h
+++ b/xfa/fde/xml/cfde_xmlnode.h
@@ -7,6 +7,8 @@
 #ifndef XFA_FDE_XML_CFDE_XMLNODE_H_
 #define XFA_FDE_XML_CFDE_XMLNODE_H_
 
+#include <memory>
+
 #include "core/fxcrt/cfx_retain_ptr.h"
 #include "xfa/fgas/crt/ifgas_stream.h"
 
@@ -44,7 +46,7 @@
   virtual ~CFDE_XMLNode();
 
   virtual FDE_XMLNODETYPE GetType() const;
-  virtual CFDE_XMLNode* Clone(bool bRecursive);
+  virtual std::unique_ptr<CFDE_XMLNode> Clone();
 
   int32_t CountChildNodes() const;
   CFDE_XMLNode* GetChildNode(int32_t index) const;
@@ -52,7 +54,6 @@
   int32_t InsertChildNode(CFDE_XMLNode* pNode, int32_t index = -1);
   void RemoveChildNode(CFDE_XMLNode* pNode);
   void DeleteChildren();
-  void CloneChildren(CFDE_XMLNode* pClone);
 
   CFDE_XMLNode* GetPath(const wchar_t* pPath,
                         int32_t iLength = -1,
diff --git a/xfa/fde/xml/cfde_xmltext.cpp b/xfa/fde/xml/cfde_xmltext.cpp
index 6bc2d64..2af66ac 100644
--- a/xfa/fde/xml/cfde_xmltext.cpp
+++ b/xfa/fde/xml/cfde_xmltext.cpp
@@ -6,6 +6,8 @@
 
 #include "xfa/fde/xml/cfde_xmltext.h"
 
+#include "third_party/base/ptr_util.h"
+
 CFDE_XMLText::CFDE_XMLText(const CFX_WideString& wsText)
     : CFDE_XMLNode(), m_wsText(wsText) {}
 
@@ -15,7 +17,6 @@
   return FDE_XMLNODE_Text;
 }
 
-CFDE_XMLNode* CFDE_XMLText::Clone(bool bRecursive) {
-  CFDE_XMLText* pClone = new CFDE_XMLText(m_wsText);
-  return pClone;
+std::unique_ptr<CFDE_XMLNode> CFDE_XMLText::Clone() {
+  return pdfium::MakeUnique<CFDE_XMLText>(m_wsText);
 }
diff --git a/xfa/fde/xml/cfde_xmltext.h b/xfa/fde/xml/cfde_xmltext.h
index 6f3945b..6987c49 100644
--- a/xfa/fde/xml/cfde_xmltext.h
+++ b/xfa/fde/xml/cfde_xmltext.h
@@ -7,6 +7,8 @@
 #ifndef XFA_FDE_XML_CFDE_XMLTEXT_H_
 #define XFA_FDE_XML_CFDE_XMLTEXT_H_
 
+#include <memory>
+
 #include "core/fxcrt/fx_string.h"
 #include "xfa/fde/xml/cfde_xmlnode.h"
 
@@ -17,11 +19,12 @@
 
   // CFDE_XMLNode
   FDE_XMLNODETYPE GetType() const override;
-  CFDE_XMLNode* Clone(bool bRecursive) override;
+  std::unique_ptr<CFDE_XMLNode> Clone() override;
 
-  void GetText(CFX_WideString& wsText) const { wsText = m_wsText; }
+  CFX_WideString GetText() const { return m_wsText; }
   void SetText(const CFX_WideString& wsText) { m_wsText = wsText; }
 
+ private:
   CFX_WideString m_wsText;
 };
 
diff --git a/xfa/fxfa/app/cxfa_textlayout.cpp b/xfa/fxfa/app/cxfa_textlayout.cpp
index 718f90b..c32717b 100644
--- a/xfa/fxfa/app/cxfa_textlayout.cpp
+++ b/xfa/fxfa/app/cxfa_textlayout.cpp
@@ -773,7 +773,7 @@
             bContentNode ? pParentStyle.Get() : pStyle.Get());
         CFX_WideString wsText;
         if (bContentNode && iTabCount == 0) {
-          static_cast<CFDE_XMLText*>(pXMLNode)->GetText(wsText);
+          wsText = static_cast<CFDE_XMLText*>(pXMLNode)->GetText();
         } else if (wsName == L"br") {
           wsText = L'\n';
         } else if (wsName == L"li") {
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 61107bf..2079127 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -517,22 +517,21 @@
   MergeAllData(pClone);
   pClone->UpdateNameHash();
   if (IsNeedSavingXMLNode()) {
-    CFDE_XMLNode* pCloneXML = nullptr;
+    std::unique_ptr<CFDE_XMLNode> pCloneXML;
     if (IsAttributeInXML()) {
       CFX_WideString wsName;
       GetAttribute(XFA_ATTRIBUTE_Name, wsName, false);
-      CFDE_XMLElement* pCloneXMLElement = new CFDE_XMLElement(wsName);
+      auto pCloneXMLElement = pdfium::MakeUnique<CFDE_XMLElement>(wsName);
       CFX_WideStringC wsValue = GetCData(XFA_ATTRIBUTE_Value);
       if (!wsValue.IsEmpty()) {
         pCloneXMLElement->SetTextData(CFX_WideString(wsValue));
       }
-      pCloneXML = pCloneXMLElement;
-      pCloneXMLElement = nullptr;
+      pCloneXML.reset(pCloneXMLElement.release());
       pClone->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_Unknown);
     } else {
-      pCloneXML = m_pXMLNode->Clone(false);
+      pCloneXML = m_pXMLNode->Clone();
     }
-    pClone->SetXMLMappingNode(pCloneXML);
+    pClone->SetXMLMappingNode(pCloneXML.release());
     pClone->SetFlag(XFA_NodeFlag_OwnXMLNode, false);
   }
   if (bRecursive) {
@@ -1303,13 +1302,16 @@
     pFakeRoot->SetCData(XFA_ATTRIBUTE_ContentType,
                         CFX_WideString(wsContentType));
   }
-  CFDE_XMLNode* pFakeXMLRoot = pFakeRoot->GetXMLMappingNode();
+
+  std::unique_ptr<CFDE_XMLNode> pFakeXMLRoot(pFakeRoot->GetXMLMappingNode());
   if (!pFakeXMLRoot) {
     CFDE_XMLNode* pThisXMLRoot = GetXMLMappingNode();
-    pFakeXMLRoot = pThisXMLRoot ? pThisXMLRoot->Clone(false) : nullptr;
+    pFakeXMLRoot = pThisXMLRoot ? pThisXMLRoot->Clone() : nullptr;
   }
-  if (!pFakeXMLRoot)
-    pFakeXMLRoot = new CFDE_XMLElement(CFX_WideString(GetClassName()));
+  if (!pFakeXMLRoot) {
+    pFakeXMLRoot =
+        pdfium::MakeUnique<CFDE_XMLElement>(CFX_WideString(GetClassName()));
+  }
 
   if (bIgnoreRoot) {
     CFDE_XMLNode* pXMLChild = pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
@@ -1327,57 +1329,54 @@
     }
     pFakeXMLRoot->InsertChildNode(pXMLNode);
   }
-  pParser->ConstructXFANode(pFakeRoot, pFakeXMLRoot);
+  pParser->ConstructXFANode(pFakeRoot, pFakeXMLRoot.get());
   pFakeRoot = pParser->GetRootNode();
-  if (pFakeRoot) {
-    if (bOverwrite) {
-      CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild);
-      CXFA_Node* pNewChild = pFakeRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
-      int32_t index = 0;
-      while (pNewChild) {
-        CXFA_Node* pItem = pNewChild->GetNodeItem(XFA_NODEITEM_NextSibling);
-        pFakeRoot->RemoveChild(pNewChild);
-        InsertChild(index++, pNewChild);
-        pNewChild->SetFlag(XFA_NodeFlag_Initialized, true);
-        pNewChild = pItem;
-      }
-      while (pChild) {
-        CXFA_Node* pItem = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
-        RemoveChild(pChild);
-        pFakeRoot->InsertChild(pChild);
-        pChild = pItem;
-      }
-      if (GetPacketID() == XFA_XDPPACKET_Form &&
-          GetElementType() == XFA_Element::ExData) {
-        CFDE_XMLNode* pTempXMLNode = GetXMLMappingNode();
-        SetXMLMappingNode(pFakeXMLRoot);
-        SetFlag(XFA_NodeFlag_OwnXMLNode, false);
-        if (pTempXMLNode && !pTempXMLNode->GetNodeItem(CFDE_XMLNode::Parent)) {
-          pFakeXMLRoot = pTempXMLNode;
-        } else {
-          pFakeXMLRoot = nullptr;
-        }
-      }
-      MoveBufferMapData(pFakeRoot, this, XFA_CalcData, true);
-    } else {
-      CXFA_Node* pChild = pFakeRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
-      while (pChild) {
-        CXFA_Node* pItem = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
-        pFakeRoot->RemoveChild(pChild);
-        InsertChild(pChild);
-        pChild->SetFlag(XFA_NodeFlag_Initialized, true);
-        pChild = pItem;
-      }
+  if (!pFakeRoot)
+    return;
+
+  if (bOverwrite) {
+    CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild);
+    CXFA_Node* pNewChild = pFakeRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+    int32_t index = 0;
+    while (pNewChild) {
+      CXFA_Node* pItem = pNewChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+      pFakeRoot->RemoveChild(pNewChild);
+      InsertChild(index++, pNewChild);
+      pNewChild->SetFlag(XFA_NodeFlag_Initialized, true);
+      pNewChild = pItem;
     }
-    if (pFakeXMLRoot) {
-      pFakeRoot->SetXMLMappingNode(pFakeXMLRoot);
-      pFakeRoot->SetFlag(XFA_NodeFlag_OwnXMLNode, false);
+    while (pChild) {
+      CXFA_Node* pItem = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+      RemoveChild(pChild);
+      pFakeRoot->InsertChild(pChild);
+      pChild = pItem;
     }
-    pFakeRoot->SetFlag(XFA_NodeFlag_HasRemovedChildren, false);
+    if (GetPacketID() == XFA_XDPPACKET_Form &&
+        GetElementType() == XFA_Element::ExData) {
+      CFDE_XMLNode* pTempXMLNode = GetXMLMappingNode();
+      SetXMLMappingNode(pFakeXMLRoot.release());
+      SetFlag(XFA_NodeFlag_OwnXMLNode, false);
+      if (pTempXMLNode && !pTempXMLNode->GetNodeItem(CFDE_XMLNode::Parent))
+        pFakeXMLRoot.reset(pTempXMLNode);
+      else
+        pFakeXMLRoot = nullptr;
+    }
+    MoveBufferMapData(pFakeRoot, this, XFA_CalcData, true);
   } else {
-    delete pFakeXMLRoot;
-    pFakeXMLRoot = nullptr;
+    CXFA_Node* pChild = pFakeRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+    while (pChild) {
+      CXFA_Node* pItem = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+      pFakeRoot->RemoveChild(pChild);
+      InsertChild(pChild);
+      pChild->SetFlag(XFA_NodeFlag_Initialized, true);
+      pChild = pItem;
+    }
   }
+  if (pFakeXMLRoot) {
+    pFakeRoot->SetXMLMappingNode(pFakeXMLRoot.release());
+    pFakeRoot->SetFlag(XFA_NodeFlag_OwnXMLNode, false);
+  }
+  pFakeRoot->SetFlag(XFA_NodeFlag_HasRemovedChildren, false);
 }
 
 void CXFA_Node::Script_NodeClass_SaveFilteredXML(CFXJSE_Arguments* pArguments) {
diff --git a/xfa/fxfa/parser/cxfa_simple_parser.cpp b/xfa/fxfa/parser/cxfa_simple_parser.cpp
index 06e2e5d..cb6a90d 100644
--- a/xfa/fxfa/parser/cxfa_simple_parser.cpp
+++ b/xfa/fxfa/parser/cxfa_simple_parser.cpp
@@ -213,24 +213,16 @@
         wsOutput += wsTextData;
         break;
       }
-      case FDE_XMLNODE_Text: {
-        CFX_WideString wsText;
-        static_cast<CFDE_XMLText*>(pXMLChild)->GetText(wsText);
+      case FDE_XMLNODE_Text:
+      case FDE_XMLNODE_CharData: {
+        CFX_WideString wsText =
+            static_cast<CFDE_XMLText*>(pXMLChild)->GetText();
         if (IsStringAllWhitespace(wsText))
           continue;
 
         wsOutput = wsText;
         break;
       }
-      case FDE_XMLNODE_CharData: {
-        CFX_WideString wsCharData;
-        static_cast<CFDE_XMLCharData*>(pXMLChild)->GetCharData(wsCharData);
-        if (IsStringAllWhitespace(wsCharData))
-          continue;
-
-        wsOutput = wsCharData;
-        break;
-      }
       default:
         ASSERT(false);
         break;
@@ -1004,10 +996,8 @@
     } else {
       if (eNodeType == FDE_XMLNODE_Element)
         break;
-      if (eNodeType == FDE_XMLNODE_Text)
-        static_cast<CFDE_XMLText*>(pXMLChild)->GetText(wsValue);
-      else if (eNodeType == FDE_XMLNODE_CharData)
-        static_cast<CFDE_XMLCharData*>(pXMLChild)->GetCharData(wsValue);
+      if (eNodeType == FDE_XMLNODE_Text || eNodeType == FDE_XMLNODE_CharData)
+        wsValue = static_cast<CFDE_XMLText*>(pXMLChild)->GetText();
     }
     break;
   }
@@ -1140,29 +1130,10 @@
         pXFAChild->SetFlag(XFA_NodeFlag_Initialized, false);
         continue;
       }
-      case FDE_XMLNODE_CharData: {
-        CFDE_XMLCharData* pXMLCharData =
-            static_cast<CFDE_XMLCharData*>(pXMLChild);
-        CFX_WideString wsCharData;
-        pXMLCharData->GetCharData(wsCharData);
-        if (IsStringAllWhitespace(wsCharData))
-          continue;
-
-        CXFA_Node* pXFAChild = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets,
-                                                      XFA_Element::DataValue);
-        if (!pXFAChild)
-          return;
-
-        pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsCharData);
-        pXFANode->InsertChild(pXFAChild);
-        pXFAChild->SetXMLMappingNode(pXMLCharData);
-        pXFAChild->SetFlag(XFA_NodeFlag_Initialized, false);
-        continue;
-      }
+      case FDE_XMLNODE_CharData:
       case FDE_XMLNODE_Text: {
         CFDE_XMLText* pXMLText = static_cast<CFDE_XMLText*>(pXMLChild);
-        CFX_WideString wsText;
-        pXMLText->GetText(wsText);
+        CFX_WideString wsText = pXMLText->GetText();
         if (IsStringAllWhitespace(wsText))
           continue;
 
@@ -1199,14 +1170,8 @@
       continue;
 
     CFX_WideString wsText;
-    if (eNodeType == FDE_XMLNODE_Text) {
-      static_cast<CFDE_XMLText*>(pXMLChild)->GetText(wsText);
-      if (!pXMLCurValueNode)
-        pXMLCurValueNode = pXMLChild;
-
-      wsCurValueTextBuf << wsText;
-    } else if (eNodeType == FDE_XMLNODE_CharData) {
-      static_cast<CFDE_XMLCharData*>(pXMLChild)->GetCharData(wsText);
+    if (eNodeType == FDE_XMLNODE_Text || eNodeType == FDE_XMLNODE_CharData) {
+      wsText = static_cast<CFDE_XMLText*>(pXMLChild)->GetText();
       if (!pXMLCurValueNode)
         pXMLCurValueNode = pXMLChild;
 
diff --git a/xfa/fxfa/parser/xfa_utils.cpp b/xfa/fxfa/parser/xfa_utils.cpp
index df180f2..57d9751 100644
--- a/xfa/fxfa/parser/xfa_utils.cpp
+++ b/xfa/fxfa/parser/xfa_utils.cpp
@@ -192,17 +192,15 @@
           wsPlainText += L"\n";
         }
       }
-    } break;
-    case FDE_XMLNODE_Text: {
-      CFX_WideString wsContent;
-      static_cast<CFDE_XMLText*>(pXMLNode)->GetText(wsContent);
-      wsPlainText += wsContent;
-    } break;
+      break;
+    }
+    case FDE_XMLNODE_Text:
     case FDE_XMLNODE_CharData: {
-      CFX_WideString wsCharData;
-      static_cast<CFDE_XMLCharData*>(pXMLNode)->GetCharData(wsCharData);
-      wsPlainText += wsCharData;
-    } break;
+      CFX_WideString wsContent =
+          static_cast<CFDE_XMLText*>(pXMLNode)->GetText();
+      wsPlainText += wsContent;
+      break;
+    }
     default:
       break;
   }