| // 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_FXFA_PARSER_XFA_UTILS_H_ |
| #define XFA_FXFA_PARSER_XFA_UTILS_H_ |
| |
| #include "xfa/fde/xml/fde_xml.h" |
| #include "xfa/fxfa/include/fxfa_basic.h" |
| |
| class CFDE_XMLElement; |
| class CFDE_XMLNode; |
| class CXFA_LocaleValue; |
| |
| inline FX_BOOL XFA_IsSpace(FX_WCHAR c) { |
| return (c == 0x20) || (c == 0x0d) || (c == 0x0a) || (c == 0x09); |
| } |
| inline FX_BOOL XFA_IsDigit(FX_WCHAR c) { |
| return c >= '0' && c <= '9'; |
| } |
| |
| FX_BOOL XFA_FDEExtension_ResolveNamespaceQualifier( |
| CFDE_XMLElement* pNode, |
| const CFX_WideStringC& wsQualifier, |
| CFX_WideString& wsNamespaceURI); |
| template <class NodeType, class TraverseStrategy> |
| class CXFA_NodeIteratorTemplate { |
| public: |
| CXFA_NodeIteratorTemplate(NodeType* pRootNode = NULL) : m_pRoot(pRootNode) { |
| if (pRootNode) { |
| m_NodeStack.Push(pRootNode); |
| } |
| } |
| FX_BOOL Init(NodeType* pRootNode) { |
| if (!pRootNode) { |
| return FALSE; |
| } |
| m_pRoot = pRootNode; |
| m_NodeStack.RemoveAll(); |
| m_NodeStack.Push(pRootNode); |
| return TRUE; |
| } |
| void Clear() { m_NodeStack.RemoveAll(); } |
| void Reset() { |
| Clear(); |
| if (m_pRoot) { |
| m_NodeStack.Push(m_pRoot); |
| } |
| } |
| FX_BOOL SetCurrent(NodeType* pCurNode) { |
| m_NodeStack.RemoveAll(); |
| if (pCurNode) { |
| CFX_StackTemplate<NodeType*> revStack; |
| 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(); |
| } |
| } |
| return TRUE; |
| } |
| NodeType* GetCurrent() const { |
| return m_NodeStack.GetSize() ? *m_NodeStack.GetTopElement() : NULL; |
| } |
| NodeType* GetRoot() const { return m_pRoot; } |
| NodeType* MoveToPrev() { |
| int32_t nStackLength = m_NodeStack.GetSize(); |
| if (nStackLength == 1) { |
| return NULL; |
| } 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 = NULL; |
| for (; pPrevItem; pPrevItem = pPrevItemNext) { |
| pPrevItemNext = TraverseStrategy::GetNextSibling(pPrevItem); |
| if (!pPrevItemNext || pPrevItemNext == pCurItem) { |
| break; |
| } |
| } |
| m_NodeStack.Push(pPrevItem); |
| } else { |
| m_NodeStack.RemoveAll(); |
| if (m_pRoot) { |
| m_NodeStack.Push(m_pRoot); |
| } |
| } |
| if (m_NodeStack.GetSize() > 0) { |
| NodeType* pChildItem = *m_NodeStack.GetTopElement(); |
| while ((pChildItem = TraverseStrategy::GetFirstChild(pChildItem)) != |
| NULL) { |
| while (NodeType* pNextItem = |
| TraverseStrategy::GetNextSibling(pChildItem)) { |
| pChildItem = pNextItem; |
| } |
| m_NodeStack.Push(pChildItem); |
| } |
| return *m_NodeStack.GetTopElement(); |
| } |
| return NULL; |
| } |
| NodeType* MoveToNext() { |
| NodeType** ppNode = NULL; |
| NodeType* pCurrent = GetCurrent(); |
| while (m_NodeStack.GetSize() > 0) { |
| while ((ppNode = m_NodeStack.GetTopElement())) { |
| if (pCurrent != *ppNode) { |
| return *ppNode; |
| } |
| NodeType* pChild = TraverseStrategy::GetFirstChild(*ppNode); |
| if (pChild == NULL) { |
| break; |
| } |
| m_NodeStack.Push(pChild); |
| } |
| while ((ppNode = m_NodeStack.GetTopElement())) { |
| NodeType* pNext = TraverseStrategy::GetNextSibling(*ppNode); |
| m_NodeStack.Pop(); |
| if (m_NodeStack.GetSize() == 0) { |
| break; |
| } |
| if (pNext) { |
| m_NodeStack.Push(pNext); |
| break; |
| } |
| } |
| } |
| return NULL; |
| } |
| NodeType* SkipChildrenAndMoveToNext() { |
| NodeType** ppNode = NULL; |
| while ((ppNode = m_NodeStack.GetTopElement())) { |
| NodeType* pNext = TraverseStrategy::GetNextSibling(*ppNode); |
| m_NodeStack.Pop(); |
| if (m_NodeStack.GetSize() == 0) { |
| break; |
| } |
| if (pNext) { |
| m_NodeStack.Push(pNext); |
| break; |
| } |
| } |
| return GetCurrent(); |
| } |
| |
| protected: |
| NodeType* m_pRoot; |
| CFX_StackTemplate<NodeType*> m_NodeStack; |
| }; |
| template <class KeyType> |
| class CXFA_PtrSetTemplate : private CFX_MapPtrToPtr { |
| public: |
| CXFA_PtrSetTemplate() : CFX_MapPtrToPtr(10) {} |
| |
| int GetCount() const { return CFX_MapPtrToPtr::GetCount(); } |
| |
| FX_BOOL IsEmpty() const { return CFX_MapPtrToPtr::IsEmpty(); } |
| |
| FX_BOOL Lookup(KeyType key) const { |
| void* pValue = NULL; |
| return CFX_MapPtrToPtr::Lookup((void*)key, pValue); |
| } |
| |
| FX_BOOL operator[](KeyType key) { return Lookup(key); } |
| |
| void Add(KeyType key) { CFX_MapPtrToPtr::SetAt((void*)key, (void*)key); } |
| |
| FX_BOOL RemoveKey(KeyType key) { |
| return CFX_MapPtrToPtr::RemoveKey((void*)key); |
| } |
| |
| void RemoveAll() { CFX_MapPtrToPtr::RemoveAll(); } |
| |
| FX_POSITION GetStartPosition() const { |
| return CFX_MapPtrToPtr::GetStartPosition(); |
| } |
| |
| void GetNextAssoc(FX_POSITION& rNextPosition, KeyType& rKey) const { |
| void* pKey = NULL; |
| void* pValue = NULL; |
| CFX_MapPtrToPtr::GetNextAssoc(rNextPosition, pKey, pValue); |
| rKey = (KeyType)(uintptr_t)pKey; |
| } |
| }; |
| class CXFA_Node; |
| class CXFA_WidgetData; |
| |
| CXFA_Node* XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType); |
| CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData); |
| FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString& wsStringVal); |
| FX_DOUBLE XFA_ByteStringToDouble(const CFX_ByteStringC& szStringVal); |
| int32_t XFA_MapRotation(int32_t nRotation); |
| |
| FX_BOOL XFA_RecognizeRichText(CFDE_XMLElement* pRichTextXMLNode); |
| void XFA_GetPlainTextFromRichText(CFDE_XMLNode* pXMLNode, |
| CFX_WideString& wsPlainText); |
| FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode); |
| IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString& wsBuffer); |
| FX_BOOL XFA_IsLayoutElement(XFA_ELEMENT eElement, |
| FX_BOOL bLayoutContainer = FALSE); |
| |
| void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node* pDataNode); |
| void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode, |
| IFX_Stream* pStream, |
| const FX_CHAR* pChecksum = NULL, |
| FX_BOOL bSaveXML = FALSE); |
| |
| #endif // XFA_FXFA_PARSER_XFA_UTILS_H_ |