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_FXFA_PARSER_XFA_UTILS_H_
8 #define XFA_FXFA_PARSER_XFA_UTILS_H_
9 
10 #include "xfa/fde/xml/fde_xml.h"
11 #include "xfa/fgas/crt/fgas_stream.h"
12 #include "xfa/fgas/crt/fgas_utils.h"
13 #include "xfa/fxfa/include/fxfa_basic.h"
14 
15 class CFDE_XMLElement;
16 class CFDE_XMLNode;
17 class CXFA_LocaleValue;
18 class CXFA_Node;
19 class CXFA_WidgetData;
20 
21 FX_BOOL XFA_FDEExtension_ResolveNamespaceQualifier(
22     CFDE_XMLElement* pNode,
23     const CFX_WideStringC& wsQualifier,
24     CFX_WideString& wsNamespaceURI);
25 
26 template <class NodeType, class TraverseStrategy>
27 class CXFA_NodeIteratorTemplate {
28  public:
29   CXFA_NodeIteratorTemplate(NodeType* pRootNode = nullptr)
m_pRoot(pRootNode)30       : m_pRoot(pRootNode) {
31     if (pRootNode) {
32       m_NodeStack.Push(pRootNode);
33     }
34   }
Init(NodeType * pRootNode)35   FX_BOOL Init(NodeType* pRootNode) {
36     if (!pRootNode) {
37       return FALSE;
38     }
39     m_pRoot = pRootNode;
40     m_NodeStack.RemoveAll();
41     m_NodeStack.Push(pRootNode);
42     return TRUE;
43   }
Clear()44   void Clear() { m_NodeStack.RemoveAll(); }
Reset()45   void Reset() {
46     Clear();
47     if (m_pRoot) {
48       m_NodeStack.Push(m_pRoot);
49     }
50   }
SetCurrent(NodeType * pCurNode)51   FX_BOOL SetCurrent(NodeType* pCurNode) {
52     m_NodeStack.RemoveAll();
53     if (pCurNode) {
54       CFX_StackTemplate<NodeType*> revStack;
55       NodeType* pNode;
56       for (pNode = pCurNode; pNode && pNode != m_pRoot;
57            pNode = TraverseStrategy::GetParent(pNode)) {
58         revStack.Push(pNode);
59       }
60       if (!pNode) {
61         return FALSE;
62       }
63       revStack.Push(m_pRoot);
64       while (revStack.GetSize()) {
65         m_NodeStack.Push(*revStack.GetTopElement());
66         revStack.Pop();
67       }
68     }
69     return TRUE;
70   }
GetCurrent()71   NodeType* GetCurrent() const {
72     return m_NodeStack.GetSize() ? *m_NodeStack.GetTopElement() : nullptr;
73   }
GetRoot()74   NodeType* GetRoot() const { return m_pRoot; }
MoveToPrev()75   NodeType* MoveToPrev() {
76     int32_t nStackLength = m_NodeStack.GetSize();
77     if (nStackLength == 1) {
78       return nullptr;
79     } else if (nStackLength > 1) {
80       NodeType* pCurItem = *m_NodeStack.GetTopElement();
81       m_NodeStack.Pop();
82       NodeType* pParentItem = *m_NodeStack.GetTopElement();
83       NodeType* pParentFirstChildItem =
84           TraverseStrategy::GetFirstChild(pParentItem);
85       if (pCurItem == pParentFirstChildItem) {
86         return pParentItem;
87       }
88       NodeType *pPrevItem = pParentFirstChildItem, *pPrevItemNext = nullptr;
89       for (; pPrevItem; pPrevItem = pPrevItemNext) {
90         pPrevItemNext = TraverseStrategy::GetNextSibling(pPrevItem);
91         if (!pPrevItemNext || pPrevItemNext == pCurItem) {
92           break;
93         }
94       }
95       m_NodeStack.Push(pPrevItem);
96     } else {
97       m_NodeStack.RemoveAll();
98       if (m_pRoot) {
99         m_NodeStack.Push(m_pRoot);
100       }
101     }
102     if (m_NodeStack.GetSize() > 0) {
103       NodeType* pChildItem = *m_NodeStack.GetTopElement();
104       while ((pChildItem = TraverseStrategy::GetFirstChild(pChildItem)) !=
105              nullptr) {
106         while (NodeType* pNextItem =
107                    TraverseStrategy::GetNextSibling(pChildItem)) {
108           pChildItem = pNextItem;
109         }
110         m_NodeStack.Push(pChildItem);
111       }
112       return *m_NodeStack.GetTopElement();
113     }
114     return nullptr;
115   }
MoveToNext()116   NodeType* MoveToNext() {
117     NodeType** ppNode = nullptr;
118     NodeType* pCurrent = GetCurrent();
119     while (m_NodeStack.GetSize() > 0) {
120       while ((ppNode = m_NodeStack.GetTopElement()) != nullptr) {
121         if (pCurrent != *ppNode) {
122           return *ppNode;
123         }
124         NodeType* pChild = TraverseStrategy::GetFirstChild(*ppNode);
125         if (!pChild) {
126           break;
127         }
128         m_NodeStack.Push(pChild);
129       }
130       while ((ppNode = m_NodeStack.GetTopElement()) != nullptr) {
131         NodeType* pNext = TraverseStrategy::GetNextSibling(*ppNode);
132         m_NodeStack.Pop();
133         if (m_NodeStack.GetSize() == 0) {
134           break;
135         }
136         if (pNext) {
137           m_NodeStack.Push(pNext);
138           break;
139         }
140       }
141     }
142     return nullptr;
143   }
SkipChildrenAndMoveToNext()144   NodeType* SkipChildrenAndMoveToNext() {
145     NodeType** ppNode = nullptr;
146     while ((ppNode = m_NodeStack.GetTopElement()) != nullptr) {
147       NodeType* pNext = TraverseStrategy::GetNextSibling(*ppNode);
148       m_NodeStack.Pop();
149       if (m_NodeStack.GetSize() == 0) {
150         break;
151       }
152       if (pNext) {
153         m_NodeStack.Push(pNext);
154         break;
155       }
156     }
157     return GetCurrent();
158   }
159 
160  protected:
161   NodeType* m_pRoot;
162   CFX_StackTemplate<NodeType*> m_NodeStack;
163 };
164 
165 CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData);
166 FX_DOUBLE XFA_ByteStringToDouble(const CFX_ByteStringC& szStringVal);
167 int32_t XFA_MapRotation(int32_t nRotation);
168 
169 FX_BOOL XFA_RecognizeRichText(CFDE_XMLElement* pRichTextXMLNode);
170 void XFA_GetPlainTextFromRichText(CFDE_XMLNode* pXMLNode,
171                                   CFX_WideString& wsPlainText);
172 FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode);
173 IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString& wsBuffer);
174 
175 void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node* pDataNode);
176 void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode,
177                                          IFX_Stream* pStream,
178                                          const FX_CHAR* pChecksum = nullptr,
179                                          FX_BOOL bSaveXML = FALSE);
180 
181 #endif  // XFA_FXFA_PARSER_XFA_UTILS_H_
182