summaryrefslogtreecommitdiff
path: root/xfa/src/fgas/crt/fgas_utils.h
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2016-03-09 13:49:00 -0500
committerDan Sinclair <dsinclair@chromium.org>2016-03-09 13:49:00 -0500
commit9332e0c2fced598a632e3bbe905b6f63b1f5b06b (patch)
treea8957a09cb34ecd28afcd6ebbed309d9c60e4644 /xfa/src/fgas/crt/fgas_utils.h
parent8388037a5c58d60043b11c03a8efe78c54c65a4b (diff)
downloadpdfium-9332e0c2fced598a632e3bbe905b6f63b1f5b06b.tar.xz
Cleanup the xfa/src/fgas directory.
This CL moves the code from xfa/src/fgas/src up one level. It then takes the headers in xfa/src/fgas/include and moves them to their correct folder. The src/ and include/ directories are then removed. In some cases, when moving from include/ there was another header with the same name. Those headers were either folded together, or the content of the conflicting folder moved to an anonymous namespace in the cpp file as they were not used anywhere else. Files with duplicate names as core/src/crt were renamed to be fgas_ instead of fx_. (e.g. fgas_system.h, fgas_memory.h, fgas_stream.h) R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1776303002 .
Diffstat (limited to 'xfa/src/fgas/crt/fgas_utils.h')
-rw-r--r--xfa/src/fgas/crt/fgas_utils.h737
1 files changed, 737 insertions, 0 deletions
diff --git a/xfa/src/fgas/crt/fgas_utils.h b/xfa/src/fgas/crt/fgas_utils.h
new file mode 100644
index 0000000000..f52255a5d3
--- /dev/null
+++ b/xfa/src/fgas/crt/fgas_utils.h
@@ -0,0 +1,737 @@
+// Copyright 2014 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.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_SRC_FGAS_CRT_FGAS_UTILS_H_
+#define XFA_SRC_FGAS_CRT_FGAS_UTILS_H_
+
+#include "core/include/fxcrt/fx_coordinates.h"
+#include "xfa/src/fgas/crt/fgas_memory.h"
+
+class FX_BASEARRAYDATA;
+
+template <class baseType>
+class CFX_CPLTree;
+
+class CFX_BaseArray : public CFX_Target {
+ protected:
+ CFX_BaseArray(int32_t iGrowSize, int32_t iBlockSize);
+ ~CFX_BaseArray();
+ int32_t GetSize() const;
+ int32_t GetBlockSize() const;
+ uint8_t* AddSpaceTo(int32_t index);
+ uint8_t* GetAt(int32_t index) const;
+ uint8_t* GetBuffer() const;
+ int32_t Append(const CFX_BaseArray& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1);
+ int32_t Copy(const CFX_BaseArray& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1);
+ int32_t RemoveLast(int32_t iCount = -1);
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE);
+
+ FX_BASEARRAYDATA* m_pData;
+};
+
+template <class baseType>
+class CFX_BaseArrayTemplate : public CFX_BaseArray {
+ public:
+ CFX_BaseArrayTemplate(int32_t iGrowSize = 100)
+ : CFX_BaseArray(iGrowSize, sizeof(baseType)) {}
+ CFX_BaseArrayTemplate(int32_t iGrowSize, int32_t iBlockSize)
+ : CFX_BaseArray(iGrowSize, iBlockSize) {}
+ int32_t GetSize() const { return CFX_BaseArray::GetSize(); }
+ int32_t GetBlockSize() const { return CFX_BaseArray::GetBlockSize(); }
+ baseType* AddSpace() {
+ return (baseType*)CFX_BaseArray::AddSpaceTo(CFX_BaseArray::GetSize());
+ }
+ int32_t Add(const baseType& element) {
+ int32_t index = CFX_BaseArray::GetSize();
+ *(baseType*)CFX_BaseArray::AddSpaceTo(index) = element;
+ return index;
+ }
+ baseType* GetBuffer() const { return (baseType*)CFX_BaseArray::GetBuffer(); }
+ baseType& GetAt(int32_t index) const {
+ return *(baseType*)CFX_BaseArray::GetAt(index);
+ }
+ baseType* GetPtrAt(int32_t index) const {
+ return (baseType*)CFX_BaseArray::GetAt(index);
+ }
+ void SetAt(int32_t index, const baseType& element) {
+ *(baseType*)CFX_BaseArray::GetAt(index) = element;
+ }
+ void SetAtGrow(int32_t index, const baseType& element) {
+ *(baseType*)CFX_BaseArray::AddSpaceTo(index) = element;
+ }
+ int32_t Append(const CFX_BaseArrayTemplate& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1) {
+ return CFX_BaseArray::Append(src, iStart, iCount);
+ }
+ int32_t Copy(const CFX_BaseArrayTemplate& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1) {
+ return CFX_BaseArray::Copy(src, iStart, iCount);
+ }
+ int32_t RemoveLast(int32_t iCount = -1) {
+ return CFX_BaseArray::RemoveLast(iCount);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE) {
+ CFX_BaseArray::RemoveAll(bLeaveMemory);
+ }
+};
+typedef CFX_BaseArrayTemplate<void*> CFDE_PtrArray;
+typedef CFX_BaseArrayTemplate<FX_DWORD> CFDE_DWordArray;
+typedef CFX_BaseArrayTemplate<FX_WORD> CFDE_WordArray;
+
+template <class baseType>
+class CFX_ObjectBaseArrayTemplate : public CFX_BaseArray {
+ public:
+ CFX_ObjectBaseArrayTemplate(int32_t iGrowSize = 100)
+ : CFX_BaseArray(iGrowSize, sizeof(baseType)) {}
+ ~CFX_ObjectBaseArrayTemplate() { RemoveAll(FALSE); }
+ int32_t GetSize() const { return CFX_BaseArray::GetSize(); }
+ int32_t GetBlockSize() const { return CFX_BaseArray::GetBlockSize(); }
+ int32_t Add(const baseType& element) {
+ int32_t index = CFX_BaseArray::GetSize();
+ baseType* p = (baseType*)CFX_BaseArray::AddSpaceTo(index);
+ new ((void*)p) baseType(element);
+ return index;
+ }
+ baseType& GetAt(int32_t index) const {
+ return *(baseType*)CFX_BaseArray::GetAt(index);
+ }
+ baseType* GetPtrAt(int32_t index) const {
+ return (baseType*)CFX_BaseArray::GetAt(index);
+ }
+ int32_t Append(const CFX_ObjectBaseArrayTemplate& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1) {
+ FXSYS_assert(GetBlockSize() == src.GetBlockSize());
+ if (iCount == 0) {
+ return 0;
+ }
+ int32_t iSize = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iSize);
+ if (iCount < 0) {
+ iCount = iSize;
+ }
+ if (iStart + iCount > iSize) {
+ iCount = iSize - iStart;
+ }
+ if (iCount < 1) {
+ return 0;
+ }
+ iSize = CFX_BaseArray::GetSize();
+ CFX_BaseArray::AddSpaceTo(iSize + iCount - 1);
+ uint8_t** pStart = CFX_BaseArray::GetAt(iSize);
+ int32_t iBlockSize = CFX_BaseArray::GetBlockSize();
+ iSize = iStart + iCount;
+ for (int32_t i = iStart; i < iSize; i++) {
+ FXTARGET_NewWith((void*)pStart) baseType(src.GetAt(i));
+ pStart += iBlockSize;
+ }
+ return iCount;
+ }
+ int32_t Copy(const CFX_ObjectBaseArrayTemplate& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1) {
+ FXSYS_assert(GetBlockSize() == src.GetBlockSize());
+ if (iCount == 0) {
+ return 0;
+ }
+ int32_t iSize = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iSize);
+ if (iCount < 0) {
+ iCount = iSize;
+ }
+ if (iStart + iCount > iSize) {
+ iCount = iSize - iStart;
+ }
+ if (iCount < 1) {
+ return 0;
+ }
+ RemoveAll(TRUE);
+ CFX_BaseArray::AddSpaceTo(iCount - 1);
+ uint8_t** pStart = CFX_BaseArray::GetAt(0);
+ int32_t iBlockSize = CFX_BaseArray::GetBlockSize();
+ iSize = iStart + iCount;
+ for (int32_t i = iStart; i < iSize; i++) {
+ new ((void*)pStart) baseType(src.GetAt(i));
+ pStart += iBlockSize;
+ }
+ return iCount;
+ }
+ int32_t RemoveLast(int32_t iCount = -1) {
+ int32_t iSize = CFX_BaseArray::GetSize();
+ if (iCount < 0 || iCount > iSize) {
+ iCount = iSize;
+ }
+ if (iCount == 0) {
+ return iSize;
+ }
+ for (int32_t i = iSize - iCount; i < iSize; i++) {
+ ((baseType*)GetPtrAt(i))->~baseType();
+ }
+ return CFX_BaseArray::RemoveLast(iCount);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE) {
+ int32_t iSize = CFX_BaseArray::GetSize();
+ for (int32_t i = 0; i < iSize; i++) {
+ ((baseType*)GetPtrAt(i))->~baseType();
+ }
+ CFX_BaseArray::RemoveAll(bLeaveMemory);
+ }
+};
+
+class CFX_BaseMassArrayImp : public CFX_Target {
+ public:
+ CFX_BaseMassArrayImp(int32_t iChunkSize, int32_t iBlockSize);
+ ~CFX_BaseMassArrayImp();
+ uint8_t* AddSpace() { return AddSpaceTo(m_iBlockCount); }
+ uint8_t* AddSpaceTo(int32_t index);
+ uint8_t* GetAt(int32_t index) const;
+ int32_t Append(const CFX_BaseMassArrayImp& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1);
+ int32_t Copy(const CFX_BaseMassArrayImp& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1);
+ int32_t RemoveLast(int32_t iCount = -1);
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE);
+ int32_t m_iChunkSize;
+ int32_t m_iBlockSize;
+ int32_t m_iChunkCount;
+ int32_t m_iBlockCount;
+ CFX_PtrArray* m_pData;
+
+ protected:
+ void Append(int32_t iDstStart,
+ const CFX_BaseMassArrayImp& src,
+ int32_t iSrcStart = 0,
+ int32_t iSrcCount = -1);
+};
+
+class CFX_BaseMassArray : public CFX_Target {
+ protected:
+ CFX_BaseMassArray(int32_t iChunkSize, int32_t iBlockSize);
+ ~CFX_BaseMassArray();
+ int32_t GetSize() const;
+ uint8_t* AddSpaceTo(int32_t index);
+ uint8_t* GetAt(int32_t index) const;
+ int32_t Append(const CFX_BaseMassArray& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1);
+ int32_t Copy(const CFX_BaseMassArray& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1);
+ int32_t RemoveLast(int32_t iCount = -1);
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE);
+ CFX_BaseMassArrayImp* m_pData;
+};
+
+template <class baseType>
+class CFX_MassArrayTemplate : public CFX_BaseMassArray {
+ public:
+ CFX_MassArrayTemplate(int32_t iChunkSize = 100)
+ : CFX_BaseMassArray(iChunkSize, sizeof(baseType)) {}
+ CFX_MassArrayTemplate(int32_t iChunkSize, int32_t iBlockSize)
+ : CFX_BaseMassArray(iChunkSize, iBlockSize) {}
+ int32_t GetSize() const { return CFX_BaseMassArray::GetSize(); }
+ baseType* AddSpace() {
+ return (baseType*)CFX_BaseMassArray::AddSpaceTo(
+ CFX_BaseMassArray::GetSize());
+ }
+ int32_t Add(const baseType& element) {
+ int32_t index = CFX_BaseMassArray::GetSize();
+ *(baseType*)CFX_BaseMassArray::AddSpaceTo(index) = element;
+ return index;
+ }
+ baseType& GetAt(int32_t index) const {
+ return *(baseType*)CFX_BaseMassArray::GetAt(index);
+ }
+ baseType* GetPtrAt(int32_t index) const {
+ return (baseType*)CFX_BaseMassArray::GetAt(index);
+ }
+ void SetAt(int32_t index, const baseType& element) {
+ *(baseType*)CFX_BaseMassArray::GetAt(index) = element;
+ }
+ void SetAtGrow(int32_t index, const baseType& element) {
+ *(baseType*)CFX_BaseMassArray::AddSpaceTo(index) = element;
+ }
+ int32_t Append(const CFX_MassArrayTemplate& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1) {
+ return CFX_BaseMassArray::Append(src, iStart, iCount);
+ }
+ int32_t Copy(const CFX_MassArrayTemplate& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1) {
+ return CFX_BaseMassArray::Copy(src, iStart, iCount);
+ }
+ int32_t RemoveLast(int32_t iCount = -1) {
+ return CFX_BaseMassArray::RemoveLast(iCount);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE) {
+ CFX_BaseMassArray::RemoveAll(bLeaveMemory);
+ }
+};
+typedef CFX_MassArrayTemplate<void*> CFX_PtrMassArray;
+typedef CFX_MassArrayTemplate<int32_t> CFX_Int32MassArray;
+typedef CFX_MassArrayTemplate<FX_DWORD> CFX_DWordMassArray;
+typedef CFX_MassArrayTemplate<FX_WORD> CFX_WordMassArray;
+typedef CFX_MassArrayTemplate<CFX_Rect> CFX_RectMassArray;
+typedef CFX_MassArrayTemplate<CFX_RectF> CFX_RectFMassArray;
+
+template <class baseType>
+class CFX_ObjectMassArrayTemplate : public CFX_BaseMassArray {
+ public:
+ CFX_ObjectMassArrayTemplate(int32_t iChunkSize = 100)
+ : CFX_BaseMassArray(iChunkSize, sizeof(baseType)) {}
+ ~CFX_ObjectMassArrayTemplate() { RemoveAll(FALSE); }
+ int32_t GetSize() const { return CFX_BaseMassArray::GetSize(); }
+ int32_t Add(const baseType& element) {
+ int32_t index = CFX_BaseMassArray::GetSize();
+ baseType* p = (baseType*)CFX_BaseMassArray::AddSpaceTo(index);
+ new ((void*)p) baseType(element);
+ return index;
+ }
+ baseType& GetAt(int32_t index) const {
+ return *(baseType*)CFX_BaseMassArray::GetAt(index);
+ }
+ baseType* GetPtrAt(int32_t index) const {
+ return (baseType*)CFX_BaseMassArray::GetAt(index);
+ }
+ int32_t Append(const CFX_ObjectMassArrayTemplate& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1) {
+ if (iCount == 0) {
+ return CFX_BaseMassArray::GetSize();
+ }
+ int32_t iSize = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iSize);
+ if (iCount < 0) {
+ iCount = iSize;
+ }
+ int32_t iEnd = iStart + iCount;
+ if (iEnd > iSize) {
+ iEnd = iSize;
+ }
+ for (int32_t i = iStart; i < iEnd; i++) {
+ Add(src.GetAt(i));
+ }
+ return CFX_BaseMassArray::GetSize();
+ }
+ int32_t Copy(const CFX_ObjectMassArrayTemplate& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1) {
+ if (iCount == 0) {
+ return CFX_BaseMassArray::GetSize();
+ }
+ int32_t iSize = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iSize);
+ if (iCount < 0) {
+ iCount = iSize;
+ }
+ int32_t iEnd = iStart + iCount;
+ if (iEnd > iSize) {
+ iEnd = iSize;
+ }
+ RemoveAll(TRUE);
+ for (int32_t i = iStart; i < iEnd; i++) {
+ Add(src.GetAt(i));
+ }
+ return CFX_BaseMassArray::GetSize();
+ }
+ int32_t RemoveLast(int32_t iCount = -1) {
+ int32_t iSize = CFX_BaseMassArray::GetSize();
+ if (iCount < 0 || iCount > iSize) {
+ iCount = iSize;
+ }
+ if (iCount == 0) {
+ return iSize;
+ }
+ for (int32_t i = iSize - iCount; i < iSize; i++) {
+ ((baseType*)GetPtrAt(i))->~baseType();
+ }
+ return CFX_BaseMassArray::RemoveLast(iCount);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE) {
+ int32_t iSize = CFX_BaseMassArray::GetSize();
+ for (int32_t i = 0; i < iSize; i++) {
+ ((baseType*)GetPtrAt(i))->~baseType();
+ }
+ CFX_BaseMassArray::RemoveAll(bLeaveMemory);
+ }
+};
+
+class CFX_BaseDiscreteArray : public CFX_Target {
+ protected:
+ CFX_BaseDiscreteArray(int32_t iChunkSize, int32_t iBlockSize);
+ ~CFX_BaseDiscreteArray();
+ uint8_t* AddSpaceTo(int32_t index);
+ uint8_t* GetAt(int32_t index) const;
+ void RemoveAll();
+ void* m_pData;
+};
+
+template <class baseType>
+class CFX_DiscreteArrayTemplate : public CFX_BaseDiscreteArray {
+ public:
+ CFX_DiscreteArrayTemplate(int32_t iChunkSize = 100)
+ : CFX_BaseDiscreteArray(iChunkSize, sizeof(baseType)) {}
+ baseType& GetAt(int32_t index, const baseType& defValue) const {
+ baseType* p = (baseType*)CFX_BaseDiscreteArray::GetAt(index);
+ return p == NULL ? (baseType&)defValue : *p;
+ }
+ baseType* GetPtrAt(int32_t index) const {
+ return (baseType*)CFX_BaseDiscreteArray::GetAt(index);
+ }
+ void SetAtGrow(int32_t index, const baseType& element) {
+ *(baseType*)CFX_BaseDiscreteArray::AddSpaceTo(index) = element;
+ }
+ void RemoveAll() { CFX_BaseDiscreteArray::RemoveAll(); }
+};
+typedef CFX_DiscreteArrayTemplate<void*> CFX_PtrDiscreteArray;
+typedef CFX_DiscreteArrayTemplate<FX_DWORD> CFX_DWordDiscreteArray;
+typedef CFX_DiscreteArrayTemplate<FX_WORD> CFX_WordDiscreteArray;
+
+class CFX_BaseStack : public CFX_Target {
+ protected:
+ CFX_BaseStack(int32_t iChunkSize, int32_t iBlockSize);
+ ~CFX_BaseStack();
+ uint8_t* Push();
+ void Pop();
+ uint8_t* GetTopElement() const;
+ int32_t GetSize() const;
+ uint8_t* GetAt(int32_t index) const;
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE);
+ CFX_BaseMassArrayImp* m_pData;
+};
+
+template <class baseType>
+class CFX_StackTemplate : public CFX_BaseStack {
+ public:
+ CFX_StackTemplate(int32_t iChunkSize = 100)
+ : CFX_BaseStack(iChunkSize, sizeof(baseType)) {}
+ int32_t Push(const baseType& element) {
+ int32_t index = CFX_BaseStack::GetSize();
+ *(baseType*)CFX_BaseStack::Push() = element;
+ return index;
+ }
+ void Pop() { CFX_BaseStack::Pop(); }
+ baseType* GetTopElement() const {
+ return (baseType*)CFX_BaseStack::GetTopElement();
+ }
+ int32_t GetSize() const { return CFX_BaseStack::GetSize(); }
+ baseType* GetAt(int32_t index) const {
+ return (baseType*)CFX_BaseStack::GetAt(index);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE) {
+ CFX_BaseStack::RemoveAll(bLeaveMemory);
+ }
+};
+typedef CFX_StackTemplate<void*> CFX_PtrStack;
+typedef CFX_StackTemplate<FX_DWORD> CFX_DWordStack;
+typedef CFX_StackTemplate<FX_WORD> CFX_WordStack;
+typedef CFX_StackTemplate<int32_t> CFX_Int32Stack;
+
+template <class baseType>
+class CFX_ObjectStackTemplate : public CFX_BaseStack {
+ public:
+ CFX_ObjectStackTemplate(int32_t iChunkSize = 100)
+ : CFX_BaseStack(iChunkSize, sizeof(baseType)) {}
+ ~CFX_ObjectStackTemplate() { RemoveAll(); }
+ int32_t Push(const baseType& element) {
+ int32_t index = CFX_BaseStack::GetSize();
+ baseType* p = (baseType*)CFX_BaseStack::Push();
+ new ((void*)p) baseType(element);
+ return index;
+ }
+ void Pop() {
+ baseType* p = (baseType*)CFX_BaseStack::GetTopElement();
+ if (p != NULL) {
+ p->~baseType();
+ }
+ CFX_BaseStack::Pop();
+ }
+ baseType* GetTopElement() const {
+ return (baseType*)CFX_BaseStack::GetTopElement();
+ }
+ int32_t GetSize() const { return CFX_BaseStack::GetSize(); }
+ baseType* GetAt(int32_t index) const {
+ return (baseType*)CFX_BaseStack::GetAt(index);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE) {
+ int32_t iSize = CFX_BaseStack::GetSize();
+ for (int32_t i = 0; i < iSize; i++) {
+ ((baseType*)CFX_BaseStack::GetAt(i))->~baseType();
+ }
+ CFX_BaseStack::RemoveAll(bLeaveMemory);
+ }
+ int32_t Copy(const CFX_ObjectStackTemplate& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1) {
+ if (iCount == 0) {
+ return CFX_BaseStack::GetSize();
+ }
+ int32_t iSize = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iSize);
+ if (iCount < 0) {
+ iCount = iSize;
+ }
+ int32_t iEnd = iStart + iCount;
+ if (iEnd > iSize) {
+ iEnd = iSize;
+ }
+ RemoveAll(TRUE);
+ for (int32_t i = iStart; i < iEnd; i++) {
+ Push(*src.GetAt(i));
+ }
+ return CFX_BaseStack::GetSize();
+ }
+};
+
+template <class baseType>
+class CFX_CPLTreeNode : public CFX_Target {
+ public:
+ typedef CFX_CPLTreeNode<baseType> CPLTreeNode;
+ CFX_CPLTreeNode()
+ : m_pParentNode(NULL),
+ m_pChildNode(NULL),
+ m_pPrevNode(NULL),
+ m_pNextNode(NULL),
+ m_Data() {}
+ enum TreeNode {
+ Root = 0,
+ Parent,
+ FirstSibling,
+ PreviousSibling,
+ NextSibling,
+ LastSibling,
+ FirstNeighbor,
+ PreviousNeighbor,
+ NextNeighbor,
+ LastNeighbor,
+ FirstChild,
+ LastChild
+ };
+ CPLTreeNode* GetNode(TreeNode eNode) const {
+ switch (eNode) {
+ case Root: {
+ CPLTreeNode* pParent = (CPLTreeNode*)this;
+ CPLTreeNode* pTemp;
+ while ((pTemp = pParent->m_pParentNode) != NULL) {
+ pParent = pTemp;
+ }
+ return pParent;
+ }
+ case Parent:
+ return m_pParentNode;
+ case FirstSibling: {
+ CPLTreeNode* pNode = (CPLTreeNode*)this;
+ CPLTreeNode* pTemp;
+ while ((pTemp = pNode->m_pPrevNode) != NULL) {
+ pNode = pTemp;
+ }
+ return pNode == (CPLTreeNode*)this ? NULL : pNode;
+ }
+ case PreviousSibling:
+ return m_pPrevNode;
+ case NextSibling:
+ return m_pNextNode;
+ case LastSibling: {
+ CPLTreeNode* pNode = (CPLTreeNode*)this;
+ CPLTreeNode* pTemp;
+ while ((pTemp = pNode->m_pNextNode) != NULL) {
+ pNode = pTemp;
+ }
+ return pNode == (CPLTreeNode*)this ? NULL : pNode;
+ }
+ case FirstNeighbor: {
+ CPLTreeNode* pParent = (CPLTreeNode*)this;
+ CPLTreeNode* pTemp;
+ while ((pTemp = pParent->m_pParentNode) != NULL) {
+ pParent = pTemp;
+ }
+ return pParent == (CPLTreeNode*)this ? NULL : pParent;
+ }
+ case PreviousNeighbor: {
+ if (m_pPrevNode == NULL) {
+ return m_pParentNode;
+ }
+ CPLTreeNode* pNode = m_pPrevNode;
+ CPLTreeNode* pTemp;
+ while ((pTemp = pNode->m_pChildNode) != NULL) {
+ pNode = pTemp;
+ while ((pTemp = pNode->m_pNextNode) != NULL) {
+ pNode = pTemp;
+ }
+ }
+ return pNode;
+ }
+ case NextNeighbor: {
+ if (m_pChildNode != NULL) {
+ return m_pChildNode;
+ }
+ if (m_pNextNode != NULL) {
+ return m_pNextNode;
+ }
+ CPLTreeNode* pNode = m_pParentNode;
+ while (pNode != NULL) {
+ if (pNode->m_pNextNode != NULL) {
+ return pNode->m_pNextNode;
+ }
+ pNode = pNode->m_pParentNode;
+ }
+ return NULL;
+ }
+ case LastNeighbor: {
+ CPLTreeNode* pNode = (CPLTreeNode*)this;
+ CPLTreeNode* pTemp;
+ while ((pTemp = pNode->m_pParentNode) != NULL) {
+ pNode = pTemp;
+ }
+ while (TRUE) {
+ CPLTreeNode* pTemp;
+ while ((pTemp = pNode->m_pNextNode) != NULL) {
+ pNode = pTemp;
+ }
+ if (pNode->m_pChildNode == NULL) {
+ break;
+ }
+ pNode = pNode->m_pChildNode;
+ }
+ return pNode == (CPLTreeNode*)this ? NULL : pNode;
+ }
+ case FirstChild:
+ return m_pChildNode;
+ case LastChild: {
+ if (m_pChildNode == NULL) {
+ return NULL;
+ }
+ CPLTreeNode* pChild = m_pChildNode;
+ CPLTreeNode* pTemp;
+ while ((pTemp = pChild->m_pNextNode) != NULL) {
+ pChild = pTemp;
+ }
+ return pChild;
+ }
+ default:
+ break;
+ }
+ return NULL;
+ }
+ void SetParentNode(CPLTreeNode* pNode) { m_pParentNode = pNode; }
+ int32_t CountChildNodes() const {
+ int32_t iCount = 0;
+ CPLTreeNode* pNode = m_pChildNode;
+ while (pNode) {
+ iCount++;
+ pNode = pNode->m_pNextNode;
+ }
+ return iCount;
+ }
+ CPLTreeNode* GetChildNode(int32_t iIndex) const {
+ int32_t iCount = 0;
+ CPLTreeNode* pNode = m_pChildNode;
+ while (pNode) {
+ if (iIndex == iCount) {
+ return pNode;
+ }
+ iCount++;
+ pNode = pNode->m_pNextNode;
+ }
+ return NULL;
+ }
+ int32_t GetNodeIndex() const {
+ int32_t index = 0;
+ CPLTreeNode* pNode = m_pPrevNode;
+ while (pNode != NULL) {
+ index++;
+ pNode = pNode->m_pPrevNode;
+ }
+ return index;
+ }
+ FX_BOOL IsParentNode(const CPLTreeNode* pNode) const {
+ CPLTreeNode* pParent = m_pParentNode;
+ while (pParent != NULL) {
+ if (pParent == pNode) {
+ return TRUE;
+ }
+ pParent = pParent->GetTreeNode(Parent);
+ }
+ return FALSE;
+ }
+ FX_BOOL IsChildNode(const CPLTreeNode* pNode) const {
+ if (pNode == NULL) {
+ return FALSE;
+ }
+ return pNode->IsParentNode((const CPLTreeNode*)this);
+ }
+ void SetChildNode(CPLTreeNode* pNode) { m_pChildNode = pNode; }
+ void SetPrevNode(CPLTreeNode* pNode) { m_pPrevNode = pNode; }
+ void SetNextNode(CPLTreeNode* pNode) { m_pNextNode = pNode; }
+ int32_t GetNodeLevel() const {
+ int32_t iLevel = 0;
+ CPLTreeNode* pNode = (CPLTreeNode*)this;
+ while ((pNode = pNode->m_pParentNode) != NULL) {
+ iLevel++;
+ }
+ return iLevel;
+ }
+ bool IsRootNode() const { return !m_pParentNode; }
+ baseType GetData() const { return m_Data; }
+ void SetData(baseType data) { m_Data = data; }
+
+ protected:
+ CPLTreeNode* m_pParentNode;
+ CPLTreeNode* m_pChildNode;
+ CPLTreeNode* m_pPrevNode;
+ CPLTreeNode* m_pNextNode;
+ baseType m_Data;
+ friend class CFX_CPLTree<baseType>;
+};
+
+template <class baseType>
+class CFX_CPLTree {
+ public:
+ typedef CFX_CPLTreeNode<baseType> CPLTreeNode;
+ CFX_CPLTree() : m_Root() {}
+ ~CFX_CPLTree() {
+ CPLTreeNode* pNode = m_Root.GetNode(CPLTreeNode::LastNeighbor);
+ while (pNode != NULL) {
+ if (pNode->IsRootNode()) {
+ break;
+ }
+ CPLTreeNode* pTemp = pNode->GetNode(CPLTreeNode::PreviousNeighbor);
+ delete pNode;
+ pNode = pTemp;
+ }
+ }
+ CPLTreeNode* GetRoot() { return &m_Root; }
+ CPLTreeNode* AddChild(baseType data, CPLTreeNode* pParent = NULL) {
+ if (pParent == NULL) {
+ pParent = &m_Root;
+ }
+ CPLTreeNode* pChild = new CPLTreeNode;
+ pChild->SetParentNode(pParent);
+ pChild->SetData(data);
+ if (pParent->m_pChildNode == NULL) {
+ pParent->m_pChildNode = pChild;
+ } else {
+ CPLTreeNode* pLast = pParent->GetNode(CPLTreeNode::LastChild);
+ pChild->SetPrevNode(pLast);
+ pLast->SetNextNode(pChild);
+ }
+ return pChild;
+ }
+
+ protected:
+ CPLTreeNode m_Root;
+};
+
+#endif // XFA_SRC_FGAS_CRT_FGAS_UTILS_H_