Make CXFA_Node inherit from fxcrt::TreeNode<>
Remove explicit pointer manipulations from this class, relying
on TreeNode to keep the tree consistent.
Change-Id: I0836e23ad2dbcaa11d9ed125b8bcd93be92ba0a3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/53511
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 737e05d..8f45335 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -1014,7 +1014,7 @@
}
CXFA_Node* CXFA_Node::GetNextContainerSibling() const {
- for (auto* pNode = next_sibling_; pNode; pNode = pNode->next_sibling_) {
+ for (auto* pNode = GetNextSibling(); pNode; pNode = pNode->GetNextSibling()) {
if (pNode->GetObjectType() == XFA_ObjectType::ContainerNode)
return pNode;
}
@@ -1022,7 +1022,7 @@
}
CXFA_Node* CXFA_Node::GetPrevContainerSibling() const {
- for (auto* pNode = prev_sibling_; pNode; pNode = pNode->prev_sibling_) {
+ for (auto* pNode = GetPrevSibling(); pNode; pNode = pNode->GetPrevSibling()) {
if (pNode->GetObjectType() == XFA_ObjectType::ContainerNode)
return pNode;
}
@@ -1030,7 +1030,7 @@
}
CXFA_Node* CXFA_Node::GetFirstContainerChild() const {
- for (auto* pNode = first_child_; pNode; pNode = pNode->next_sibling_) {
+ for (auto* pNode = GetFirstChild(); pNode; pNode = pNode->GetNextSibling()) {
if (pNode->GetObjectType() == XFA_ObjectType::ContainerNode)
return pNode;
}
@@ -1038,7 +1038,7 @@
}
CXFA_Node* CXFA_Node::GetContainerParent() const {
- for (auto* pNode = parent_; pNode; pNode = pNode->parent_) {
+ for (auto* pNode = GetParent(); pNode; pNode = pNode->GetParent()) {
if (pNode->GetObjectType() == XFA_ObjectType::ContainerNode)
return pNode;
}
@@ -1109,8 +1109,8 @@
XFA_Element eTypeFilter) {
if (eTypeFilter != XFA_Element::Unknown) {
std::vector<CXFA_Node*> nodes;
- for (CXFA_Node* pChild = first_child_; pChild;
- pChild = pChild->next_sibling_) {
+ for (CXFA_Node* pChild = GetFirstChild(); pChild;
+ pChild = pChild->GetNextSibling()) {
if (pChild->GetElementType() == eTypeFilter)
nodes.push_back(pChild);
}
@@ -1119,8 +1119,8 @@
if (dwTypeFilter == (XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties)) {
std::vector<CXFA_Node*> nodes;
- for (CXFA_Node* pChild = first_child_; pChild;
- pChild = pChild->next_sibling_)
+ for (CXFA_Node* pChild = GetFirstChild(); pChild;
+ pChild = pChild->GetNextSibling())
nodes.push_back(pChild);
return nodes;
}
@@ -1132,8 +1132,8 @@
bool bFilterProperties = !!(dwTypeFilter & XFA_NODEFILTER_Properties);
bool bFilterOneOfProperties = !!(dwTypeFilter & XFA_NODEFILTER_OneOfProperty);
std::vector<CXFA_Node*> nodes;
- for (CXFA_Node* pChild = first_child_; pChild;
- pChild = pChild->next_sibling_) {
+ for (CXFA_Node* pChild = GetFirstChild(); pChild;
+ pChild = pChild->GetNextSibling()) {
if (HasProperty(pChild->GetElementType())) {
if (bFilterProperties) {
nodes.push_back(pChild);
@@ -1475,7 +1475,7 @@
size_t CXFA_Node::CountChildren(XFA_Element eType, bool bOnlyChild) {
size_t count = 0;
- for (CXFA_Node* pNode = first_child_; pNode;
+ for (CXFA_Node* pNode = GetFirstChild(); pNode;
pNode = pNode->GetNextSibling()) {
if (pNode->GetElementType() != eType && eType != XFA_Element::Unknown)
continue;
@@ -1490,7 +1490,7 @@
XFA_Element eType,
bool bOnlyChild) const {
size_t count = 0;
- for (CXFA_Node* pNode = first_child_; pNode;
+ for (CXFA_Node* pNode = GetFirstChild(); pNode;
pNode = pNode->GetNextSibling()) {
if (pNode->GetElementType() != eType && eType != XFA_Element::Unknown)
continue;
@@ -1505,46 +1505,22 @@
}
void CXFA_Node::InsertChild(int32_t index, CXFA_Node* pNode) {
- CHECK(pNode);
- CHECK(!pNode->parent_);
-
- pNode->parent_ = this;
+ CHECK(!pNode->GetParent());
pNode->ClearFlag(XFA_NodeFlag_HasRemovedChildren);
- if (!first_child_) {
- ASSERT(!last_child_);
-
- pNode->prev_sibling_ = nullptr;
- pNode->next_sibling_ = nullptr;
- first_child_ = pNode;
- last_child_ = pNode;
+ CXFA_Node* pPrev = GetFirstChild();
+ if (!pPrev) {
+ AppendFirstChild(pNode);
index = 0;
- } else if (index == 0) {
- pNode->prev_sibling_ = nullptr;
- pNode->next_sibling_ = first_child_;
- first_child_->prev_sibling_ = pNode;
- first_child_ = pNode;
} else if (index < 0) {
- pNode->prev_sibling_ = last_child_;
- pNode->next_sibling_ = nullptr;
- last_child_->next_sibling_ = pNode;
- last_child_ = pNode;
+ AppendLastChild(pNode);
+ } else if (index == 0) {
+ AppendFirstChild(pNode);
} else {
- CXFA_Node* pPrev = first_child_;
int32_t count = 0;
- while (++count < index && pPrev->next_sibling_)
- pPrev = pPrev->next_sibling_;
-
- pNode->prev_sibling_ = pPrev;
- pNode->next_sibling_ = pPrev->next_sibling_;
- if (pPrev->next_sibling_)
- pPrev->next_sibling_->prev_sibling_ = pNode;
- pPrev->next_sibling_ = pNode;
-
- // Move the last child pointer if needed.
- if (pPrev == last_child_)
- last_child_ = pNode;
-
+ while (++count < index && pPrev->GetNextSibling())
+ pPrev = pPrev->GetNextSibling();
+ InsertAfter(pNode, pPrev);
index = count;
}
@@ -1560,18 +1536,18 @@
}
void CXFA_Node::InsertChild(CXFA_Node* pNode, CXFA_Node* pBeforeNode) {
- CHECK(!pBeforeNode || pBeforeNode->parent_ == this);
+ CHECK(!pBeforeNode || pBeforeNode->GetParent() == this);
int32_t index = -1;
- if (!first_child_ || pBeforeNode == first_child_) {
+ if (!GetFirstChild() || pBeforeNode == GetFirstChild()) {
index = 0;
} else if (!pBeforeNode) {
index = -1;
} else {
index = 0;
- CXFA_Node* prev = first_child_;
+ CXFA_Node* prev = GetFirstChild();
while (prev && prev != pBeforeNode) {
- prev = prev->next_sibling_;
+ prev = prev->GetNextSibling();
++index;
}
}
@@ -1580,28 +1556,10 @@
void CXFA_Node::RemoveChild(CXFA_Node* pNode, bool bNotify) {
CHECK(pNode);
- CHECK_EQ(pNode->parent_, this);
+ CHECK_EQ(pNode->GetParent(), this);
pNode->SetFlag(XFA_NodeFlag_HasRemovedChildren);
-
- if (first_child_ == pNode && last_child_ == pNode) {
- first_child_ = nullptr;
- last_child_ = nullptr;
- } else if (first_child_ == pNode) {
- first_child_ = pNode->next_sibling_;
- first_child_->prev_sibling_ = nullptr;
- } else if (last_child_ == pNode) {
- last_child_ = pNode->prev_sibling_;
- last_child_->next_sibling_ = nullptr;
- } else {
- CXFA_Node* pPrev = pNode->prev_sibling_;
- pPrev->next_sibling_ = pNode->next_sibling_;
- pPrev->next_sibling_->prev_sibling_ = pPrev;
- }
- pNode->next_sibling_ = nullptr;
- pNode->prev_sibling_ = nullptr;
- pNode->parent_ = nullptr;
-
+ TreeNode<CXFA_Node>::RemoveChild(pNode);
OnRemoved(bNotify);
if (!IsNeedSavingXMLNode() || !pNode->xml_node_)
@@ -1781,7 +1739,7 @@
if (m_uNodeFlags & dwFlag)
return true;
if (dwFlag == XFA_NodeFlag_HasRemovedChildren)
- return parent_ && parent_->HasFlag(dwFlag);
+ return GetParent() && GetParent()->HasFlag(dwFlag);
return false;
}
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h
index 2daae05..182bbae 100644
--- a/xfa/fxfa/parser/cxfa_node.h
+++ b/xfa/fxfa/parser/cxfa_node.h
@@ -12,6 +12,7 @@
#include <vector>
#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/tree_node.h"
#include "core/fxge/fx_dib.h"
#include "third_party/base/optional.h"
#include "third_party/base/span.h"
@@ -71,7 +72,7 @@
XFA_NodeFlag_LayoutGeneratedNode = 1 << 6
};
-class CXFA_Node : public CXFA_Object {
+class CXFA_Node : public CXFA_Object, public TreeNode<CXFA_Node> {
public:
struct PropertyData {
XFA_Element property;
@@ -169,12 +170,6 @@
CXFA_Node* Clone(bool bRecursive);
- CXFA_Node* GetNextSibling() const { return next_sibling_; }
- CXFA_Node* GetPrevSibling() const { return prev_sibling_; }
- CXFA_Node* GetFirstChild() const { return first_child_; }
- CXFA_Node* GetLastChild() const { return last_child_; }
- CXFA_Node* GetParent() const { return parent_; }
-
CXFA_Node* GetNextContainerSibling() const;
CXFA_Node* GetPrevContainerSibling() const;
CXFA_Node* GetFirstContainerChild() const;
@@ -487,17 +482,6 @@
pdfium::span<const PropertyData> const m_Properties;
pdfium::span<const AttributeData> const m_Attributes;
const uint32_t m_ValidPackets;
-
- // These members are responsible for building the CXFA_Node tree. Node
- // pointers within the tree (or in objects owned by nodes in the tree)
- // can't be UnownedPtr<> because the cleanup process will remove the nodes
- // in an order that doesn't necessarily match up to the tree structure.
- CXFA_Node* parent_ = nullptr; // Raw, intra-tree node pointer.
- CXFA_Node* next_sibling_ = nullptr; // Raw, intra-tree node pointer.
- CXFA_Node* prev_sibling_ = nullptr; // Raw, intra-tree node pointer.
- CXFA_Node* first_child_ = nullptr; // Raw, intra-tree node pointer.
- CXFA_Node* last_child_ = nullptr; // Raw, intra-tree node pointer.
-
UnownedPtr<CFX_XMLNode> xml_node_;
const XFA_PacketType m_ePacket;
uint8_t m_ExecuteRecursionDepth = 0;
@@ -509,7 +493,6 @@
bool m_bPreNull = true;
bool is_widget_ready_ = false;
std::unique_ptr<CXFA_WidgetLayoutData> m_pLayoutData;
-
CXFA_Ui* ui_ = nullptr;
XFA_FFWidgetType ff_widget_type_ = XFA_FFWidgetType::kNone;
};