blob: df51ff6baa5dc73f2fd6ff8c8eb3b17c605e3a52 [file]
// 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_UTILS_H_
#define _XFA_UTILS_H_
FX_BOOL XFA_FDEExtension_ResolveNamespaceQualifier(IFDE_XMLElement* pNode, FX_WSTR wsQualifier, CFX_WideString& wsNamespaceURI);
template <class NodeType, class TraverseStrategy>
class CXFA_NodeIteratorTemplate : public CFX_Object
{
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()
{
return m_NodeStack.GetSize() ? *m_NodeStack.GetTopElement() : NULL;
}
NodeType* GetRoot()
{
return m_pRoot;
}
NodeType* MoveToPrev()
{
NodeType *pCurrent = GetCurrent();
FX_INT32 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()) != NULL) {
if (pCurrent != *ppNode) {
return *ppNode;
}
NodeType *pChild = TraverseStrategy::GetFirstChild(*ppNode);
if (pChild == NULL) {
break;
}
m_NodeStack.Push(pChild);
}
while ((ppNode = m_NodeStack.GetTopElement()) != NULL) {
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()) != NULL) {
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
{
FX_LPVOID 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)(FX_UINTPTR)pKey;
}
};
class CXFA_Node;
class CXFA_WidgetData;
#include "fxfa_localevalue.h"
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, FX_INT32 iLead, FX_INT32 iTread);
FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString &wsStringVal);
FX_DOUBLE XFA_ByteStringToDouble(FX_BSTR szStringVal);
#ifndef XFA_PARSE_HAS_LINEIDENTIFIER
#define XFA_PARSE_HAS_LINEIDENTIFIER
#endif
FX_BOOL XFA_RecognizeRichText(IFDE_XMLElement* pRichTextXMLNode);
void XFA_GetPlainTextFromRichText(IFDE_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, FX_LPCSTR pChecksum = NULL, FX_BOOL bSaveXML = FALSE);
#endif