// 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/include/fxfa/fxfa_basic.h" class CFDE_XMLElement; class CFDE_XMLNode; class CXFA_LocaleValue; 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); CFX_WideString XFA_NumericLimit(const CFX_WideString& wsValue, int32_t iLead, int32_t iTread); 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); FX_BOOL XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence); FX_BOOL XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout); FX_BOOL XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout); 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_