Split retain_tree_node.h into non-retained tree_node.h version.
Enables a smaller follow-on CL in XFA.
Change-Id: I971ea6254eaefa2bf61bde9a56874d12bb5f7bfe
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/53492
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcrt/BUILD.gn b/core/fxcrt/BUILD.gn
index 2221af1..f74c3d3 100644
--- a/core/fxcrt/BUILD.gn
+++ b/core/fxcrt/BUILD.gn
@@ -61,6 +61,7 @@
"string_data_template.h",
"string_pool_template.h",
"string_view_template.h",
+ "tree_node.h",
"unowned_ptr.h",
"weak_ptr.h",
"widestring.cpp",
diff --git a/core/fxcrt/retained_tree_node.h b/core/fxcrt/retained_tree_node.h
index 8b29e69..e091fb5 100644
--- a/core/fxcrt/retained_tree_node.h
+++ b/core/fxcrt/retained_tree_node.h
@@ -6,6 +6,7 @@
#define CORE_FXCRT_RETAINED_TREE_NODE_H_
#include "core/fxcrt/retain_ptr.h"
+#include "core/fxcrt/tree_node.h"
#include "third_party/base/logging.h"
namespace fxcrt {
@@ -14,95 +15,36 @@
// and the parent node also "retains" its children but doesn't always have
// a direct pointer to them.
template <typename T>
-class RetainedTreeNode {
+class RetainedTreeNode : public TreeNode<T> {
public:
template <typename U, typename... Args>
friend RetainPtr<U> pdfium::MakeRetain(Args&&... args);
- T* GetParent() const { return m_pParent; }
- T* GetFirstChild() const { return m_pFirstChild; }
- T* GetLastChild() const { return m_pLastChild; }
- T* GetNextSibling() const { return m_pNextSibling; }
- T* GetPrevSibling() const { return m_pPrevSibling; }
-
void AppendFirstChild(const RetainPtr<T>& child) {
- BecomeParent(child);
- if (m_pFirstChild) {
- m_pFirstChild->m_pPrevSibling = child.Get();
- child->m_pNextSibling = m_pFirstChild;
- m_pFirstChild = child.Get();
- } else {
- m_pFirstChild = child.Get();
- m_pLastChild = child.Get();
- }
+ TreeNode<T>::AppendFirstChild(child.Get());
}
void AppendLastChild(const RetainPtr<T>& child) {
- BecomeParent(child);
- if (m_pLastChild) {
- m_pLastChild->m_pNextSibling = child.Get();
- child->m_pPrevSibling = m_pLastChild;
- m_pLastChild = child.Get();
- } else {
- m_pFirstChild = child.Get();
- m_pLastChild = child.Get();
- }
+ TreeNode<T>::AppendLastChild(child.Get());
}
void InsertBefore(const RetainPtr<T>& child, T* other) {
- if (!other) {
- AppendLastChild(child);
- return;
- }
- CHECK(other->m_pParent == this);
- BecomeParent(child);
- child->m_pNextSibling = other;
- child->m_pPrevSibling = other->m_pPrevSibling;
- if (other->m_pPrevSibling)
- other->m_pPrevSibling->m_pNextSibling = child.Get();
- else
- m_pFirstChild = child.Get();
- other->m_pPrevSibling = child.Get();
+ TreeNode<T>::InsertBefore(child.Get(), other);
}
void InsertAfter(const RetainPtr<T>& child, T* other) {
- if (!other) {
- AppendFirstChild(child);
- return;
- }
- CHECK(other->m_pParent == this);
- BecomeParent(child);
- child->m_pNextSibling = other->m_pNextSibling;
- child->m_pPrevSibling = other;
- if (other->m_pNextSibling)
- other->m_pNextSibling->m_pPrevSibling = child.Get();
- else
- m_pLastChild = child.Get();
- other->m_pNextSibling = child.Get();
+ TreeNode<T>::InsertAfter(child.Get(), other);
}
void RemoveChild(const RetainPtr<T>& child) {
- CHECK(child->m_pParent == this);
- if (child->m_pNextSibling)
- child->m_pNextSibling->m_pPrevSibling = child->m_pPrevSibling;
- else
- m_pLastChild = child->m_pPrevSibling;
-
- if (child->m_pPrevSibling)
- child->m_pPrevSibling->m_pNextSibling = child->m_pNextSibling;
- else
- m_pFirstChild = child->m_pNextSibling;
-
- child->m_pParent = nullptr;
- child->m_pPrevSibling = nullptr;
- child->m_pNextSibling = nullptr;
+ TreeNode<T>::RemoveChild(child.Get());
}
protected:
RetainedTreeNode() = default;
- virtual ~RetainedTreeNode() {
- while (m_pFirstChild)
- RemoveChild(pdfium::WrapRetain(m_pFirstChild));
+ ~RetainedTreeNode() override {
+ while (auto* pChild = TreeNode<T>::GetFirstChild())
+ RemoveChild(pdfium::WrapRetain(pChild));
}
private:
@@ -118,25 +60,11 @@
void Retain() { ++m_nRefCount; }
void Release() {
ASSERT(m_nRefCount > 0);
- if (--m_nRefCount == 0 && !m_pParent)
+ if (--m_nRefCount == 0 && !TreeNode<T>::GetParent())
delete this;
}
- // Child left in state where sibling members need subsequent adjustment.
- void BecomeParent(const RetainPtr<T>& child) {
- if (child->m_pParent)
- child->m_pParent->RemoveChild(child);
- child->m_pParent = static_cast<T*>(this);
- ASSERT(!child->m_pNextSibling);
- ASSERT(!child->m_pPrevSibling);
- }
-
intptr_t m_nRefCount = 0;
- T* m_pParent = nullptr; // Raw, intra-tree pointer.
- T* m_pFirstChild = nullptr; // Raw, intra-tree pointer.
- T* m_pLastChild = nullptr; // Raw, intra-tree pointer.
- T* m_pNextSibling = nullptr; // Raw, intra-tree pointer
- T* m_pPrevSibling = nullptr; // Raw, intra-tree pointer
};
} // namespace fxcrt
diff --git a/core/fxcrt/tree_node.h b/core/fxcrt/tree_node.h
new file mode 100644
index 0000000..7bded93
--- /dev/null
+++ b/core/fxcrt/tree_node.h
@@ -0,0 +1,120 @@
+// Copyright 2019 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CORE_FXCRT_TREE_NODE_H_
+#define CORE_FXCRT_TREE_NODE_H_
+
+#include "core/fxcrt/fx_system.h"
+#include "third_party/base/logging.h"
+
+namespace fxcrt {
+
+// Implements the usual DOM/XML-ish trees.
+template <typename T>
+class TreeNode {
+ public:
+ TreeNode() = default;
+ virtual ~TreeNode() = default;
+
+ T* GetParent() const { return m_pParent; }
+ T* GetFirstChild() const { return m_pFirstChild; }
+ T* GetLastChild() const { return m_pLastChild; }
+ T* GetNextSibling() const { return m_pNextSibling; }
+ T* GetPrevSibling() const { return m_pPrevSibling; }
+
+ void AppendFirstChild(T* child) {
+ BecomeParent(child);
+ if (m_pFirstChild) {
+ m_pFirstChild->m_pPrevSibling = child;
+ child->m_pNextSibling = m_pFirstChild;
+ m_pFirstChild = child;
+ } else {
+ m_pFirstChild = child;
+ m_pLastChild = child;
+ }
+ }
+
+ void AppendLastChild(T* child) {
+ BecomeParent(child);
+ if (m_pLastChild) {
+ m_pLastChild->m_pNextSibling = child;
+ child->m_pPrevSibling = m_pLastChild;
+ m_pLastChild = child;
+ } else {
+ m_pFirstChild = child;
+ m_pLastChild = child;
+ }
+ }
+
+ void InsertBefore(T* child, T* other) {
+ if (!other) {
+ AppendLastChild(child);
+ return;
+ }
+ CHECK(other->m_pParent == this);
+ BecomeParent(child);
+ child->m_pNextSibling = other;
+ child->m_pPrevSibling = other->m_pPrevSibling;
+ if (other->m_pPrevSibling)
+ other->m_pPrevSibling->m_pNextSibling = child;
+ else
+ m_pFirstChild = child;
+ other->m_pPrevSibling = child;
+ }
+
+ void InsertAfter(T* child, T* other) {
+ if (!other) {
+ AppendFirstChild(child);
+ return;
+ }
+ CHECK(other->m_pParent == this);
+ BecomeParent(child);
+ child->m_pNextSibling = other->m_pNextSibling;
+ child->m_pPrevSibling = other;
+ if (other->m_pNextSibling)
+ other->m_pNextSibling->m_pPrevSibling = child;
+ else
+ m_pLastChild = child;
+ other->m_pNextSibling = child;
+ }
+
+ void RemoveChild(T* child) {
+ CHECK(child->m_pParent == this);
+ if (child->m_pNextSibling)
+ child->m_pNextSibling->m_pPrevSibling = child->m_pPrevSibling;
+ else
+ m_pLastChild = child->m_pPrevSibling;
+
+ if (child->m_pPrevSibling)
+ child->m_pPrevSibling->m_pNextSibling = child->m_pNextSibling;
+ else
+ m_pFirstChild = child->m_pNextSibling;
+
+ child->m_pParent = nullptr;
+ child->m_pPrevSibling = nullptr;
+ child->m_pNextSibling = nullptr;
+ }
+
+ private:
+ // Child left in state where sibling members need subsequent adjustment.
+ void BecomeParent(T* child) {
+ if (child->m_pParent)
+ child->m_pParent->TreeNode<T>::RemoveChild(child);
+ child->m_pParent = static_cast<T*>(this);
+ ASSERT(!child->m_pNextSibling);
+ ASSERT(!child->m_pPrevSibling);
+ }
+
+ T* m_pParent = nullptr; // Raw, intra-tree pointer.
+ T* m_pFirstChild = nullptr; // Raw, intra-tree pointer.
+ T* m_pLastChild = nullptr; // Raw, intra-tree pointer.
+ T* m_pNextSibling = nullptr; // Raw, intra-tree pointer
+ T* m_pPrevSibling = nullptr; // Raw, intra-tree pointer
+};
+
+} // namespace fxcrt
+
+using fxcrt::TreeNode;
+
+#endif // CORE_FXCRT_TREE_NODE_H_