summaryrefslogtreecommitdiff
path: root/xfa/fxfa/parser/xfa_utils.h
diff options
context:
space:
mode:
authorTom Sepez <tsepez@chromium.org>2017-03-06 14:00:07 -0800
committerChromium commit bot <commit-bot@chromium.org>2017-03-06 22:24:25 +0000
commit312ce172c276089309214a027450241edb2aa399 (patch)
tree9143bde61367041afe042b0e5a0658119a2070bf /xfa/fxfa/parser/xfa_utils.h
parent22c70125a888930effa9d10d6afc4f8188d94691 (diff)
downloadpdfium-312ce172c276089309214a027450241edb2aa399.tar.xz
Remove CFX_StackTemplate in xfa_utils.h.
Tree traversal doesn't require a stack as we always have parent pointers in nodes. Break the code into smaller units to help make more comprehensible what is going on. Remove init methods and force callers to pass us root in the constructor. The operations are complicated by the lack of a last child or previous sibling pointer in our nodes. Change-Id: Ia32bb44354352686cb79ccd67fe8aa5cd5ccef58 Reviewed-on: https://pdfium-review.googlesource.com/2913 Commit-Queue: Tom Sepez <tsepez@chromium.org> Reviewed-by: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'xfa/fxfa/parser/xfa_utils.h')
-rw-r--r--xfa/fxfa/parser/xfa_utils.h208
1 files changed, 94 insertions, 114 deletions
diff --git a/xfa/fxfa/parser/xfa_utils.h b/xfa/fxfa/parser/xfa_utils.h
index d09afda0f9..865d0c9fae 100644
--- a/xfa/fxfa/parser/xfa_utils.h
+++ b/xfa/fxfa/parser/xfa_utils.h
@@ -26,140 +26,120 @@ bool XFA_FDEExtension_ResolveNamespaceQualifier(
template <class NodeType, class TraverseStrategy>
class CXFA_NodeIteratorTemplate {
public:
- explicit CXFA_NodeIteratorTemplate(NodeType* pRootNode = nullptr)
- : m_pRoot(pRootNode), m_NodeStack(100) {
- if (pRootNode) {
- m_NodeStack.Push(pRootNode);
- }
- }
- bool Init(NodeType* pRootNode) {
- if (!pRootNode) {
+ explicit CXFA_NodeIteratorTemplate(NodeType* pRoot)
+ : m_pRoot(pRoot), m_pCurrent(pRoot) {}
+
+ NodeType* GetRoot() const { return m_pRoot; }
+ NodeType* GetCurrent() const { return m_pCurrent; }
+
+ void Reset() { m_pCurrent = m_pRoot; }
+ bool SetCurrent(NodeType* pNode) {
+ if (!RootReachableFromNode(pNode)) {
+ m_pCurrent = nullptr;
return false;
}
- m_pRoot = pRootNode;
- m_NodeStack.RemoveAll(false);
- m_NodeStack.Push(pRootNode);
- return true;
- }
- void Clear() { m_NodeStack.RemoveAll(false); }
- void Reset() {
- Clear();
- if (m_pRoot) {
- m_NodeStack.Push(m_pRoot);
- }
- }
- bool SetCurrent(NodeType* pCurNode) {
- m_NodeStack.RemoveAll(false);
- if (pCurNode) {
- CFX_StackTemplate<NodeType*> revStack(100);
- NodeType* pNode;
- for (pNode = pCurNode; pNode && pNode != m_pRoot;
- pNode = TraverseStrategy::GetParent(pNode)) {
- revStack.Push(pNode);
- }
- if (!pNode) {
- return false;
- }
- revStack.Push(m_pRoot);
- while (revStack.GetSize()) {
- m_NodeStack.Push(*revStack.GetTopElement());
- revStack.Pop();
- }
- }
+ m_pCurrent = pNode;
return true;
}
- NodeType* GetCurrent() const {
- return m_NodeStack.GetSize() ? *m_NodeStack.GetTopElement() : nullptr;
- }
- NodeType* GetRoot() const { return m_pRoot; }
+
NodeType* MoveToPrev() {
- int32_t nStackLength = m_NodeStack.GetSize();
- if (nStackLength == 1) {
+ if (!m_pRoot)
return nullptr;
- } else if (nStackLength > 1) {
- NodeType* pCurItem = *m_NodeStack.GetTopElement();
- m_NodeStack.Pop();
- NodeType* pParentItem = *m_NodeStack.GetTopElement();
- NodeType* pParentFirstChildItem =
- TraverseStrategy::GetFirstChild(pParentItem);
- if (pCurItem == pParentFirstChildItem) {
- return pParentItem;
- }
- NodeType *pPrevItem = pParentFirstChildItem, *pPrevItemNext = nullptr;
- for (; pPrevItem; pPrevItem = pPrevItemNext) {
- pPrevItemNext = TraverseStrategy::GetNextSibling(pPrevItem);
- if (!pPrevItemNext || pPrevItemNext == pCurItem) {
- break;
- }
- }
- m_NodeStack.Push(pPrevItem);
- } else {
- m_NodeStack.RemoveAll(false);
- if (m_pRoot) {
- m_NodeStack.Push(m_pRoot);
- }
+ if (!m_pCurrent) {
+ m_pCurrent = LastDescendant(m_pRoot);
+ return m_pCurrent;
}
- if (m_NodeStack.GetSize() > 0) {
- NodeType* pChildItem = *m_NodeStack.GetTopElement();
- while ((pChildItem = TraverseStrategy::GetFirstChild(pChildItem)) !=
- nullptr) {
- while (NodeType* pNextItem =
- TraverseStrategy::GetNextSibling(pChildItem)) {
- pChildItem = pNextItem;
- }
- m_NodeStack.Push(pChildItem);
- }
- return *m_NodeStack.GetTopElement();
+ NodeType* pSibling = PreviousSiblingWithinSubtree(m_pCurrent);
+ if (pSibling) {
+ m_pCurrent = LastDescendant(pSibling);
+ return m_pCurrent;
+ }
+ NodeType* pParent = ParentWithinSubtree(m_pCurrent);
+ if (pParent) {
+ m_pCurrent = pParent;
+ return m_pCurrent;
}
return nullptr;
}
+
NodeType* MoveToNext() {
- NodeType** ppNode = nullptr;
- NodeType* pCurrent = GetCurrent();
- while (m_NodeStack.GetSize() > 0) {
- while ((ppNode = m_NodeStack.GetTopElement()) != nullptr) {
- if (pCurrent != *ppNode) {
- return *ppNode;
- }
- NodeType* pChild = TraverseStrategy::GetFirstChild(*ppNode);
- if (!pChild) {
- break;
- }
- m_NodeStack.Push(pChild);
- }
- while ((ppNode = m_NodeStack.GetTopElement()) != nullptr) {
- NodeType* pNext = TraverseStrategy::GetNextSibling(*ppNode);
- m_NodeStack.Pop();
- if (m_NodeStack.GetSize() == 0) {
- break;
- }
- if (pNext) {
- m_NodeStack.Push(pNext);
- break;
- }
- }
+ if (!m_pRoot || !m_pCurrent)
+ return nullptr;
+ NodeType* pChild = TraverseStrategy::GetFirstChild(m_pCurrent);
+ if (pChild) {
+ m_pCurrent = pChild;
+ return m_pCurrent;
}
- return nullptr;
+ return SkipChildrenAndMoveToNext();
}
+
NodeType* SkipChildrenAndMoveToNext() {
- NodeType** ppNode = nullptr;
- while ((ppNode = m_NodeStack.GetTopElement()) != nullptr) {
- NodeType* pNext = TraverseStrategy::GetNextSibling(*ppNode);
- m_NodeStack.Pop();
- if (m_NodeStack.GetSize() == 0) {
- break;
- }
- if (pNext) {
- m_NodeStack.Push(pNext);
- break;
+ if (!m_pRoot)
+ return nullptr;
+ NodeType* pNode = m_pCurrent;
+ while (pNode) {
+ NodeType* pSibling = NextSiblingWithinSubtree(pNode);
+ if (pSibling) {
+ m_pCurrent = pSibling;
+ return m_pCurrent;
}
+ pNode = ParentWithinSubtree(pNode);
}
- return GetCurrent();
+ m_pCurrent = nullptr;
+ return m_pCurrent;
}
protected:
+ bool RootReachableFromNode(NodeType* pNode) {
+ if (!pNode)
+ return false;
+ if (pNode == m_pRoot)
+ return true;
+ return RootReachableFromNode(TraverseStrategy::GetParent(pNode));
+ }
+
+ NodeType* ParentWithinSubtree(NodeType* pNode) {
+ if (!pNode || pNode == m_pRoot)
+ return nullptr;
+ return TraverseStrategy::GetParent(pNode);
+ }
+
+ NodeType* NextSiblingWithinSubtree(NodeType* pNode) {
+ if (pNode == m_pRoot)
+ return nullptr;
+ return TraverseStrategy::GetNextSibling(pNode);
+ }
+
+ NodeType* PreviousSiblingWithinSubtree(NodeType* pNode) {
+ NodeType* pParent = ParentWithinSubtree(pNode);
+ if (!pParent)
+ return nullptr;
+ NodeType* pCurrent = TraverseStrategy::GetFirstChild(pParent);
+ NodeType* pPrevious = nullptr;
+ while (pCurrent != pNode) {
+ pPrevious = pCurrent;
+ pCurrent = TraverseStrategy::GetNextSibling(pCurrent);
+ }
+ return pPrevious;
+ }
+
+ NodeType* LastChild(NodeType* pNode) {
+ NodeType* pPrevious = nullptr;
+ NodeType* pChild = TraverseStrategy::GetFirstChild(pNode);
+ while (pChild) {
+ pPrevious = pChild;
+ pChild = NextSiblingWithinSubtree(pChild);
+ }
+ return pPrevious;
+ }
+
+ NodeType* LastDescendant(NodeType* pNode) {
+ NodeType* pChild = LastChild(pNode);
+ return pChild ? LastDescendant(pChild) : pNode;
+ }
+
NodeType* m_pRoot;
- CFX_StackTemplate<NodeType*> m_NodeStack;
+ NodeType* m_pCurrent;
};
CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData);