1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #ifndef _XFA_UTILS_H_
8 #define _XFA_UTILS_H_
9 FX_BOOL XFA_FDEExtension_ResolveNamespaceQualifier(
10     IFDE_XMLElement* pNode,
11     const CFX_WideStringC& wsQualifier,
12     CFX_WideString& wsNamespaceURI);
13 template <class NodeType, class TraverseStrategy>
14 class CXFA_NodeIteratorTemplate {
15  public:
m_pRoot(pRootNode)16   CXFA_NodeIteratorTemplate(NodeType* pRootNode = NULL) : m_pRoot(pRootNode) {
17     if (pRootNode) {
18       m_NodeStack.Push(pRootNode);
19     }
20   }
Init(NodeType * pRootNode)21   FX_BOOL Init(NodeType* pRootNode) {
22     if (!pRootNode) {
23       return FALSE;
24     }
25     m_pRoot = pRootNode;
26     m_NodeStack.RemoveAll();
27     m_NodeStack.Push(pRootNode);
28     return TRUE;
29   }
Clear()30   void Clear() { m_NodeStack.RemoveAll(); }
Reset()31   void Reset() {
32     Clear();
33     if (m_pRoot) {
34       m_NodeStack.Push(m_pRoot);
35     }
36   }
SetCurrent(NodeType * pCurNode)37   FX_BOOL SetCurrent(NodeType* pCurNode) {
38     m_NodeStack.RemoveAll();
39     if (pCurNode) {
40       CFX_StackTemplate<NodeType*> revStack;
41       NodeType* pNode;
42       for (pNode = pCurNode; pNode && pNode != m_pRoot;
43            pNode = TraverseStrategy::GetParent(pNode)) {
44         revStack.Push(pNode);
45       }
46       if (!pNode) {
47         return FALSE;
48       }
49       revStack.Push(m_pRoot);
50       while (revStack.GetSize()) {
51         m_NodeStack.Push(*revStack.GetTopElement());
52         revStack.Pop();
53       }
54     }
55     return TRUE;
56   }
GetCurrent()57   NodeType* GetCurrent() const {
58     return m_NodeStack.GetSize() ? *m_NodeStack.GetTopElement() : NULL;
59   }
GetRoot()60   NodeType* GetRoot() const { return m_pRoot; }
MoveToPrev()61   NodeType* MoveToPrev() {
62     int32_t nStackLength = m_NodeStack.GetSize();
63     if (nStackLength == 1) {
64       return NULL;
65     } else if (nStackLength > 1) {
66       NodeType* pCurItem = *m_NodeStack.GetTopElement();
67       m_NodeStack.Pop();
68       NodeType* pParentItem = *m_NodeStack.GetTopElement();
69       NodeType* pParentFirstChildItem =
70           TraverseStrategy::GetFirstChild(pParentItem);
71       if (pCurItem == pParentFirstChildItem) {
72         return pParentItem;
73       }
74       NodeType *pPrevItem = pParentFirstChildItem, *pPrevItemNext = NULL;
75       for (; pPrevItem; pPrevItem = pPrevItemNext) {
76         pPrevItemNext = TraverseStrategy::GetNextSibling(pPrevItem);
77         if (!pPrevItemNext || pPrevItemNext == pCurItem) {
78           break;
79         }
80       }
81       m_NodeStack.Push(pPrevItem);
82     } else {
83       m_NodeStack.RemoveAll();
84       if (m_pRoot) {
85         m_NodeStack.Push(m_pRoot);
86       }
87     }
88     if (m_NodeStack.GetSize() > 0) {
89       NodeType* pChildItem = *m_NodeStack.GetTopElement();
90       while ((pChildItem = TraverseStrategy::GetFirstChild(pChildItem)) !=
91              NULL) {
92         while (NodeType* pNextItem =
93                    TraverseStrategy::GetNextSibling(pChildItem)) {
94           pChildItem = pNextItem;
95         }
96         m_NodeStack.Push(pChildItem);
97       }
98       return *m_NodeStack.GetTopElement();
99     }
100     return NULL;
101   }
MoveToNext()102   NodeType* MoveToNext() {
103     NodeType** ppNode = NULL;
104     NodeType* pCurrent = GetCurrent();
105     while (m_NodeStack.GetSize() > 0) {
106       while ((ppNode = m_NodeStack.GetTopElement()) != NULL) {
107         if (pCurrent != *ppNode) {
108           return *ppNode;
109         }
110         NodeType* pChild = TraverseStrategy::GetFirstChild(*ppNode);
111         if (pChild == NULL) {
112           break;
113         }
114         m_NodeStack.Push(pChild);
115       }
116       while ((ppNode = m_NodeStack.GetTopElement()) != NULL) {
117         NodeType* pNext = TraverseStrategy::GetNextSibling(*ppNode);
118         m_NodeStack.Pop();
119         if (m_NodeStack.GetSize() == 0) {
120           break;
121         }
122         if (pNext) {
123           m_NodeStack.Push(pNext);
124           break;
125         }
126       }
127     }
128     return NULL;
129   }
SkipChildrenAndMoveToNext()130   NodeType* SkipChildrenAndMoveToNext() {
131     NodeType** ppNode = NULL;
132     while ((ppNode = m_NodeStack.GetTopElement()) != NULL) {
133       NodeType* pNext = TraverseStrategy::GetNextSibling(*ppNode);
134       m_NodeStack.Pop();
135       if (m_NodeStack.GetSize() == 0) {
136         break;
137       }
138       if (pNext) {
139         m_NodeStack.Push(pNext);
140         break;
141       }
142     }
143     return GetCurrent();
144   }
145 
146  protected:
147   NodeType* m_pRoot;
148   CFX_StackTemplate<NodeType*> m_NodeStack;
149 };
150 template <class KeyType>
151 class CXFA_PtrSetTemplate : private CFX_MapPtrToPtr {
152  public:
CXFA_PtrSetTemplate()153   CXFA_PtrSetTemplate() : CFX_MapPtrToPtr(10) {}
154 
GetCount()155   int GetCount() const { return CFX_MapPtrToPtr::GetCount(); }
156 
IsEmpty()157   FX_BOOL IsEmpty() const { return CFX_MapPtrToPtr::IsEmpty(); }
158 
Lookup(KeyType key)159   FX_BOOL Lookup(KeyType key) const {
160     void* pValue = NULL;
161     return CFX_MapPtrToPtr::Lookup((void*)key, pValue);
162   }
163 
164   FX_BOOL operator[](KeyType key) { return Lookup(key); }
165 
Add(KeyType key)166   void Add(KeyType key) { CFX_MapPtrToPtr::SetAt((void*)key, (void*)key); }
167 
RemoveKey(KeyType key)168   FX_BOOL RemoveKey(KeyType key) {
169     return CFX_MapPtrToPtr::RemoveKey((void*)key);
170   }
171 
RemoveAll()172   void RemoveAll() { CFX_MapPtrToPtr::RemoveAll(); }
173 
GetStartPosition()174   FX_POSITION GetStartPosition() const {
175     return CFX_MapPtrToPtr::GetStartPosition();
176   }
177 
GetNextAssoc(FX_POSITION & rNextPosition,KeyType & rKey)178   void GetNextAssoc(FX_POSITION& rNextPosition, KeyType& rKey) const {
179     void* pKey = NULL;
180     void* pValue = NULL;
181     CFX_MapPtrToPtr::GetNextAssoc(rNextPosition, pKey, pValue);
182     rKey = (KeyType)(uintptr_t)pKey;
183   }
184 };
185 class CXFA_Node;
186 class CXFA_WidgetData;
187 #include "fxfa_localevalue.h"
188 CXFA_Node* XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType);
189 CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData);
190 CFX_WideString XFA_NumericLimit(const CFX_WideString& wsValue,
191                                 int32_t iLead,
192                                 int32_t iTread);
193 FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString& wsStringVal);
194 FX_DOUBLE XFA_ByteStringToDouble(const CFX_ByteStringC& szStringVal);
195 int32_t XFA_MapRotation(int32_t nRotation);
196 #ifndef XFA_PARSE_HAS_LINEIDENTIFIER
197 #define XFA_PARSE_HAS_LINEIDENTIFIER
198 #endif
199 FX_BOOL XFA_RecognizeRichText(IFDE_XMLElement* pRichTextXMLNode);
200 void XFA_GetPlainTextFromRichText(IFDE_XMLNode* pXMLNode,
201                                   CFX_WideString& wsPlainText);
202 FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode);
203 IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString& wsBuffer);
204 FX_BOOL XFA_IsLayoutElement(XFA_ELEMENT eElement,
205                             FX_BOOL bLayoutContainer = FALSE);
206 FX_BOOL XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence);
207 FX_BOOL XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout);
208 FX_BOOL XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout);
209 void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node* pDataNode);
210 void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode,
211                                          IFX_Stream* pStream,
212                                          const FX_CHAR* pChecksum = NULL,
213                                          FX_BOOL bSaveXML = FALSE);
214 #endif
215