// 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 | |
#include "xfa/src/foxitlib.h" | |
#include "xfa/src/fxfa/src/common/xfa_utils.h" | |
#include "xfa/src/fxfa/src/common/xfa_object.h" | |
#include "xfa/src/fxfa/src/common/xfa_document.h" | |
#include "xfa/src/fxfa/src/common/xfa_parser.h" | |
#include "xfa/src/fxfa/src/common/xfa_script.h" | |
#include "xfa/src/fxfa/src/common/xfa_docdata.h" | |
#include "xfa/src/fxfa/src/common/xfa_doclayout.h" | |
#include "xfa/src/fxfa/src/common/xfa_localemgr.h" | |
#include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h" | |
#include "xfa_script_resolveprocessor.h" | |
#include "xfa_script_nodehelper.h" | |
#include "xfa_script_imp.h" | |
CXFA_ResolveProcessor::CXFA_ResolveProcessor(void) | |
: m_pNodeHelper(NULL), m_iCurStart(0) { | |
m_pNodeHelper = new CXFA_NodeHelper; | |
} | |
CXFA_ResolveProcessor::~CXFA_ResolveProcessor(void) { | |
if (m_pNodeHelper) { | |
delete m_pNodeHelper; | |
m_pNodeHelper = NULL; | |
} | |
} | |
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes(CXFA_ResolveNodesData& rnd) { | |
if (rnd.m_CurNode == NULL) { | |
return -1; | |
} | |
if (!rnd.m_CurNode->IsNode()) { | |
if (rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) { | |
return XFA_ResolveNodes_ForAttributeRs(rnd.m_CurNode, rnd, rnd.m_wsName); | |
} | |
return 0; | |
} | |
if (rnd.m_dwStyles & XFA_RESOLVENODE_AnyChild) { | |
return XFA_ResolveNodes_AnyChild(rnd); | |
} | |
FX_WCHAR wch = rnd.m_wsName.GetAt(0); | |
switch (wch) { | |
case '$': | |
return XFA_ResolveNodes_Dollar(rnd); | |
case '!': | |
return XFA_ResolveNodes_Excalmatory(rnd); | |
case '#': | |
return XFA_ResolveNodes_NumberSign(rnd); | |
case '*': | |
return XFA_ResolveNodes_Asterisk(rnd); | |
case '.': | |
return XFA_ResolveNodes_AnyChild(rnd); | |
default: | |
break; | |
} | |
if (rnd.m_uHashName == XFA_HASHCODE_This && rnd.m_nLevel == 0) { | |
rnd.m_Nodes.Add(rnd.m_pSC->GetThisObject()); | |
return 1; | |
} else if (rnd.m_CurNode->GetClassID() == XFA_ELEMENT_Xfa) { | |
CXFA_Object* pObjNode = | |
rnd.m_pSC->GetDocument()->GetXFANode(rnd.m_uHashName); | |
if (pObjNode) { | |
rnd.m_Nodes.Add(pObjNode); | |
} else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) { | |
rnd.m_Nodes.Add(rnd.m_CurNode); | |
} else if ((rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) && | |
XFA_ResolveNodes_ForAttributeRs(rnd.m_CurNode, rnd, | |
rnd.m_wsName)) { | |
return 1; | |
} | |
if (rnd.m_Nodes.GetSize() > 0) { | |
XFA_ResolveNode_FilterCondition(rnd, rnd.m_wsCondition); | |
} | |
return rnd.m_Nodes.GetSize(); | |
} | |
int32_t nRet = XFA_ResolveNodes_Normal(rnd); | |
if (nRet < 1 && rnd.m_uHashName == XFA_HASHCODE_Xfa) { | |
rnd.m_Nodes.Add(rnd.m_pSC->GetDocument()->GetRoot()); | |
} | |
return rnd.m_Nodes.GetSize(); | |
} | |
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_AnyChild( | |
CXFA_ResolveNodesData& rnd) { | |
CFX_WideString wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1); | |
CFX_WideString wsCondition = rnd.m_wsCondition; | |
CXFA_Node* findNode = NULL; | |
CXFA_NodeArray siblings; | |
FX_BOOL bClassName = FALSE; | |
if (wsName.GetAt(0) == '#') { | |
bClassName = TRUE; | |
wsName = wsName.Right(wsName.GetLength() - 1); | |
} | |
findNode = m_pNodeHelper->XFA_ResolveNodes_GetOneChild( | |
(CXFA_Node*)rnd.m_CurNode, wsName, bClassName); | |
if (findNode == NULL) { | |
return 0; | |
} | |
if (wsCondition.IsEmpty()) { | |
rnd.m_Nodes.Add(findNode); | |
return rnd.m_Nodes.GetSize(); | |
} | |
m_pNodeHelper->XFA_CountSiblings(findNode, XFA_LOGIC_Transparent, | |
(CXFA_NodeArray*)&rnd.m_Nodes, bClassName); | |
XFA_ResolveNode_FilterCondition(rnd, wsCondition); | |
return rnd.m_Nodes.GetSize(); | |
} | |
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Dollar( | |
CXFA_ResolveNodesData& rnd) { | |
CXFA_ObjArray& nodes = rnd.m_Nodes; | |
CFX_WideString wsName = rnd.m_wsName; | |
CFX_WideString wsCondition = rnd.m_wsCondition; | |
int32_t iNameLen = wsName.GetLength(); | |
if (iNameLen == 1) { | |
nodes.Add(rnd.m_CurNode); | |
return 1; | |
} | |
if (rnd.m_nLevel > 0) { | |
return -1; | |
} | |
FX_DWORD dwNameHash = | |
FX_HashCode_String_GetW((const FX_WCHAR*)wsName + 1, iNameLen - 1); | |
if (dwNameHash == XFA_HASHCODE_Xfa) { | |
nodes.Add(rnd.m_pSC->GetDocument()->GetRoot()); | |
} else { | |
CXFA_Object* pObjNode = rnd.m_pSC->GetDocument()->GetXFANode(dwNameHash); | |
if (pObjNode) { | |
rnd.m_Nodes.Add(pObjNode); | |
} | |
} | |
if (rnd.m_Nodes.GetSize() > 0) { | |
XFA_ResolveNode_FilterCondition(rnd, wsCondition); | |
} | |
return rnd.m_Nodes.GetSize(); | |
} | |
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Excalmatory( | |
CXFA_ResolveNodesData& rnd) { | |
if (rnd.m_nLevel > 0) { | |
return 0; | |
} | |
CXFA_Node* datasets = | |
(CXFA_Node*)rnd.m_pSC->GetDocument()->GetXFANode(XFA_HASHCODE_Datasets); | |
if (datasets == NULL) { | |
return 0; | |
} | |
CXFA_ResolveNodesData rndFind; | |
rndFind.m_pSC = rnd.m_pSC; | |
rndFind.m_CurNode = datasets; | |
rndFind.m_wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1); | |
rndFind.m_uHashName = | |
FX_HashCode_String_GetW(rndFind.m_wsName, rndFind.m_wsName.GetLength()); | |
rndFind.m_nLevel = rnd.m_nLevel + 1; | |
rndFind.m_dwStyles = XFA_RESOLVENODE_Children; | |
rndFind.m_wsCondition = rnd.m_wsCondition; | |
XFA_ResolveNodes(rndFind); | |
if (rndFind.m_Nodes.GetSize() > 0) { | |
rnd.m_Nodes.Append(rndFind.m_Nodes); | |
rndFind.m_Nodes.RemoveAll(); | |
} | |
return rnd.m_Nodes.GetSize(); | |
} | |
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_NumberSign( | |
CXFA_ResolveNodesData& rnd) { | |
CFX_WideString wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1); | |
CFX_WideString wsCondition = rnd.m_wsCondition; | |
CXFA_Node* curNode = (CXFA_Node*)rnd.m_CurNode; | |
if (XFA_ResolveNodes_ForAttributeRs(curNode, rnd, wsName)) { | |
return 1; | |
} | |
CXFA_ResolveNodesData rndFind; | |
rndFind.m_pSC = rnd.m_pSC; | |
rndFind.m_nLevel = rnd.m_nLevel + 1; | |
rndFind.m_dwStyles = rnd.m_dwStyles; | |
rndFind.m_dwStyles |= XFA_RESOLVENODE_TagName; | |
rndFind.m_dwStyles &= ~XFA_RESOLVENODE_Attributes; | |
rndFind.m_wsName = wsName; | |
rndFind.m_uHashName = | |
FX_HashCode_String_GetW(rndFind.m_wsName, rndFind.m_wsName.GetLength()); | |
rndFind.m_wsCondition = wsCondition; | |
rndFind.m_CurNode = curNode; | |
XFA_ResolveNodes_Normal(rndFind); | |
if (rndFind.m_Nodes.GetSize() > 0) { | |
if (wsCondition.GetLength() == 0 && rndFind.m_Nodes.Find(curNode) >= 0) { | |
rnd.m_Nodes.Add(curNode); | |
} else { | |
rnd.m_Nodes.Append(rndFind.m_Nodes); | |
rndFind.m_Nodes.RemoveAll(); | |
} | |
} | |
return rnd.m_Nodes.GetSize(); | |
} | |
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_ForAttributeRs( | |
CXFA_Object* curNode, | |
CXFA_ResolveNodesData& rnd, | |
const CFX_WideStringC& strAttr) { | |
XFA_LPCSCRIPTATTRIBUTEINFO lpScriptAttribute = | |
XFA_GetScriptAttributeByName(curNode->GetClassID(), strAttr); | |
if (lpScriptAttribute) { | |
rnd.m_pScriptAttribute = lpScriptAttribute; | |
rnd.m_Nodes.Add(curNode); | |
rnd.m_dwFlag = XFA_RESOVENODE_RSTYPE_Attribute; | |
return 1; | |
} | |
return 0; | |
} | |
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Normal( | |
CXFA_ResolveNodesData& rnd) { | |
if (rnd.m_nLevel > 32) { | |
return 0; | |
} | |
if (!rnd.m_CurNode->IsNode()) { | |
return 0; | |
} | |
CXFA_Node* curNode = (CXFA_Node*)rnd.m_CurNode; | |
CXFA_ObjArray& nodes = rnd.m_Nodes; | |
int32_t nNum = nodes.GetSize(); | |
FX_DWORD dwStyles = rnd.m_dwStyles; | |
CFX_WideString& wsName = rnd.m_wsName; | |
uint32_t uNameHash = rnd.m_uHashName; | |
CFX_WideString& wsCondition = rnd.m_wsCondition; | |
CXFA_ResolveNodesData rndFind; | |
rndFind.m_wsName = rnd.m_wsName; | |
rndFind.m_wsCondition = rnd.m_wsCondition; | |
rndFind.m_pSC = rnd.m_pSC; | |
rndFind.m_nLevel = rnd.m_nLevel + 1; | |
rndFind.m_uHashName = uNameHash; | |
CXFA_NodeArray children; | |
CXFA_NodeArray properties; | |
CXFA_Node* pVariablesNode = NULL; | |
CXFA_Node* pPageSetNode = NULL; | |
CXFA_Node* pChild = curNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
while (pChild) { | |
if (pChild->GetClassID() == XFA_ELEMENT_Variables) { | |
pVariablesNode = pChild; | |
pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling); | |
continue; | |
} else if (pChild->GetClassID() == XFA_ELEMENT_PageSet) { | |
pPageSetNode = pChild; | |
pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling); | |
continue; | |
} else { | |
XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement( | |
curNode->GetClassID(), pChild->GetClassID(), XFA_XDPPACKET_UNKNOWN); | |
if (pPropert) { | |
properties.Add(pChild); | |
} else { | |
children.Add(pChild); | |
} | |
} | |
pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling); | |
} | |
if ((dwStyles & XFA_RESOLVENODE_Properties) && pVariablesNode) { | |
uint32_t uPropHash = pVariablesNode->GetClassHashCode(); | |
if (uPropHash == uNameHash) { | |
nodes.Add(pVariablesNode); | |
} else { | |
rndFind.m_CurNode = pVariablesNode; | |
XFA_ResolveNodes_SetStylesForChild(dwStyles, rndFind); | |
CFX_WideString wsSaveCondition = rndFind.m_wsCondition; | |
rndFind.m_wsCondition.Empty(); | |
XFA_ResolveNodes_Normal(rndFind); | |
rndFind.m_wsCondition = wsSaveCondition; | |
if (rndFind.m_Nodes.GetSize() > 0) { | |
nodes.Append(rndFind.m_Nodes); | |
rndFind.m_Nodes.RemoveAll(); | |
} | |
} | |
if (nodes.GetSize() > nNum) { | |
XFA_ResolveNode_FilterCondition(rnd, wsCondition); | |
if (nodes.GetSize() > 0) { | |
return 1; | |
} | |
return 0; | |
} | |
} | |
if (dwStyles & XFA_RESOLVENODE_Children) { | |
FX_BOOL bSetFlag = FALSE; | |
if (pPageSetNode && (dwStyles & XFA_RESOLVENODE_Properties)) { | |
children.Add(pPageSetNode); | |
} | |
for (int32_t i = 0; i < children.GetSize(); i++) { | |
CXFA_Node* child = children[i]; | |
if (dwStyles & XFA_RESOLVENODE_TagName) { | |
if (child->GetClassHashCode() == uNameHash) { | |
nodes.Add(child); | |
} | |
} else if (child->GetNameHash() == uNameHash) { | |
nodes.Add(child); | |
} | |
if (m_pNodeHelper->XFA_NodeIsTransparent(child) && | |
child->GetClassID() != XFA_ELEMENT_PageSet) { | |
if (!bSetFlag) { | |
XFA_ResolveNodes_SetStylesForChild(dwStyles, rndFind); | |
bSetFlag = TRUE; | |
} | |
rndFind.m_CurNode = child; | |
CFX_WideString wsSaveCondition = rndFind.m_wsCondition; | |
rndFind.m_wsCondition.Empty(); | |
XFA_ResolveNodes_Normal(rndFind); | |
rndFind.m_wsCondition = wsSaveCondition; | |
if (rndFind.m_Nodes.GetSize() > 0) { | |
nodes.Append(rndFind.m_Nodes); | |
rndFind.m_Nodes.RemoveAll(); | |
} | |
} | |
} | |
if (nodes.GetSize() > nNum) { | |
if (!(dwStyles & XFA_RESOLVENODE_ALL)) { | |
CXFA_NodeArray upArrayNodes; | |
if (m_pNodeHelper->XFA_NodeIsTransparent((CXFA_Node*)curNode)) { | |
m_pNodeHelper->XFA_CountSiblings( | |
(CXFA_Node*)nodes[0], XFA_LOGIC_Transparent, &upArrayNodes, | |
!!(dwStyles & XFA_RESOLVENODE_TagName)); | |
} | |
if (upArrayNodes.GetSize() > nodes.GetSize()) { | |
upArrayNodes[0] = (CXFA_Node*)nodes[0]; | |
nodes.RemoveAll(); | |
nodes.Append((CXFA_ObjArray&)upArrayNodes); | |
upArrayNodes.RemoveAll(); | |
} | |
} | |
XFA_ResolveNode_FilterCondition(rnd, wsCondition); | |
if (nodes.GetSize() > 0) { | |
return 1; | |
} | |
return 0; | |
} | |
} | |
if (dwStyles & XFA_RESOLVENODE_Attributes) { | |
if (XFA_ResolveNodes_ForAttributeRs(curNode, rnd, wsName)) { | |
return 1; | |
} | |
} | |
if (dwStyles & XFA_RESOLVENODE_Properties) { | |
for (int32_t i = 0; i < properties.GetSize(); i++) { | |
CXFA_Node* childProperty = properties[i]; | |
if (childProperty->IsUnnamed()) { | |
uint32_t uPropHash = childProperty->GetClassHashCode(); | |
if (uPropHash == uNameHash) { | |
nodes.Add(childProperty); | |
} | |
} else if (childProperty->GetNameHash() == uNameHash && | |
childProperty->GetClassID() != XFA_ELEMENT_Extras && | |
childProperty->GetClassID() != XFA_ELEMENT_Items) { | |
nodes.Add(childProperty); | |
} | |
} | |
if (nodes.GetSize() > nNum) { | |
XFA_ResolveNode_FilterCondition(rnd, wsCondition); | |
if (nodes.GetSize() > 0) { | |
return 1; | |
} | |
return 0; | |
} | |
CXFA_Node* pProp = NULL; | |
if (XFA_ELEMENT_Subform == curNode->GetClassID() && | |
XFA_HASHCODE_Occur == uNameHash) { | |
CXFA_Node* pInstanceManager = | |
((CXFA_Node*)curNode)->GetInstanceMgrOfSubform(); | |
if (pInstanceManager) { | |
pProp = pInstanceManager->GetProperty(0, XFA_ELEMENT_Occur, TRUE); | |
} | |
} else { | |
XFA_LPCELEMENTINFO pElement = XFA_GetElementByName(wsName); | |
if (pElement) { | |
pProp = ((CXFA_Node*)curNode) | |
->GetProperty(0, pElement->eName, | |
pElement->eName != XFA_ELEMENT_PageSet); | |
} | |
} | |
if (pProp) { | |
nodes.Add(pProp); | |
return nodes.GetSize(); | |
} | |
} | |
CXFA_Node* parentNode = m_pNodeHelper->XFA_ResolveNodes_GetParent( | |
(CXFA_Node*)curNode, XFA_LOGIC_NoTransparent); | |
uint32_t uCurClassHash = curNode->GetClassHashCode(); | |
if (parentNode == NULL) { | |
if (uCurClassHash == uNameHash) { | |
nodes.Add((CXFA_Node*)curNode); | |
XFA_ResolveNode_FilterCondition(rnd, wsCondition); | |
if (nodes.GetSize() > 0) { | |
return 1; | |
} | |
} | |
return 0; | |
} | |
if (dwStyles & XFA_RESOLVENODE_Siblings) { | |
CXFA_Node* child = parentNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
FX_DWORD dwSubStyles = | |
XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties; | |
if (dwStyles & XFA_RESOLVENODE_TagName) { | |
dwSubStyles |= XFA_RESOLVENODE_TagName; | |
} | |
if (dwStyles & XFA_RESOLVENODE_ALL) { | |
dwSubStyles |= XFA_RESOLVENODE_ALL; | |
} | |
rndFind.m_dwStyles = dwSubStyles; | |
while (child) { | |
if (child == curNode) { | |
if (dwStyles & XFA_RESOLVENODE_TagName) { | |
if (uCurClassHash == uNameHash) { | |
nodes.Add(curNode); | |
} | |
} else { | |
if (child->GetNameHash() == uNameHash) { | |
nodes.Add(curNode); | |
if (rnd.m_nLevel == 0 && wsCondition.GetLength() == 0) { | |
nodes.RemoveAll(); | |
nodes.Add(curNode); | |
return 1; | |
} | |
} | |
} | |
child = child->GetNodeItem(XFA_NODEITEM_NextSibling); | |
continue; | |
} | |
if (dwStyles & XFA_RESOLVENODE_TagName) { | |
if (child->GetClassHashCode() == uNameHash) { | |
nodes.Add(child); | |
} | |
} else if (child->GetNameHash() == uNameHash) { | |
nodes.Add(child); | |
} | |
XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement( | |
parentNode->GetClassID(), child->GetClassID(), XFA_XDPPACKET_UNKNOWN); | |
FX_BOOL bInnerSearch = FALSE; | |
if (pPropert) { | |
if ((child->GetClassID() == XFA_ELEMENT_Variables || | |
child->GetClassID() == XFA_ELEMENT_PageSet)) { | |
bInnerSearch = TRUE; | |
} | |
} else { | |
if (m_pNodeHelper->XFA_NodeIsTransparent(child)) { | |
bInnerSearch = TRUE; | |
} | |
} | |
if (bInnerSearch) { | |
rndFind.m_CurNode = child; | |
CFX_WideString wsOriginCondition = rndFind.m_wsCondition; | |
rndFind.m_wsCondition.Empty(); | |
FX_DWORD dwOriginStyle = rndFind.m_dwStyles; | |
rndFind.m_dwStyles = dwOriginStyle | XFA_RESOLVENODE_ALL; | |
XFA_ResolveNodes_Normal(rndFind); | |
rndFind.m_dwStyles = dwOriginStyle; | |
rndFind.m_wsCondition = wsOriginCondition; | |
if (rndFind.m_Nodes.GetSize() > 0) { | |
nodes.Append(rndFind.m_Nodes); | |
rndFind.m_Nodes.RemoveAll(); | |
} | |
} | |
child = child->GetNodeItem(XFA_NODEITEM_NextSibling); | |
} | |
if (nodes.GetSize() > nNum) { | |
if (m_pNodeHelper->XFA_NodeIsTransparent(parentNode)) { | |
CXFA_NodeArray upArrayNodes; | |
m_pNodeHelper->XFA_CountSiblings( | |
(CXFA_Node*)nodes[0], XFA_LOGIC_Transparent, &upArrayNodes, | |
!!(dwStyles & XFA_RESOLVENODE_TagName)); | |
if (upArrayNodes.GetSize() > nodes.GetSize()) { | |
upArrayNodes[0] = (CXFA_Node*)nodes[0]; | |
nodes.RemoveAll(); | |
nodes.Append((CXFA_ObjArray&)upArrayNodes); | |
upArrayNodes.RemoveAll(); | |
} | |
} | |
XFA_ResolveNode_FilterCondition(rnd, wsCondition); | |
if (nodes.GetSize() > 0) { | |
return 1; | |
} | |
return 0; | |
} | |
} | |
if (dwStyles & XFA_RESOLVENODE_Parent) { | |
FX_DWORD dwSubStyles = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent | | |
XFA_RESOLVENODE_Properties; | |
if (dwStyles & XFA_RESOLVENODE_TagName) { | |
dwSubStyles |= XFA_RESOLVENODE_TagName; | |
} | |
if (dwStyles & XFA_RESOLVENODE_ALL) { | |
dwSubStyles |= XFA_RESOLVENODE_ALL; | |
} | |
rndFind.m_dwStyles = dwSubStyles; | |
rndFind.m_CurNode = parentNode; | |
CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray(); | |
array.Add(parentNode); | |
XFA_ResolveNodes_Normal(rndFind); | |
if (rndFind.m_Nodes.GetSize() > 0) { | |
nodes.Append(rndFind.m_Nodes); | |
rndFind.m_Nodes.RemoveAll(); | |
} | |
if (nodes.GetSize() > nNum) { | |
return 1; | |
} | |
} | |
return 0; | |
} | |
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Asterisk( | |
CXFA_ResolveNodesData& rnd) { | |
CXFA_Node* curNode = (CXFA_Node*)rnd.m_CurNode; | |
CXFA_ObjArray& nodes = rnd.m_Nodes; | |
CXFA_NodeArray array; | |
curNode->GetNodeList(array, | |
XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties); | |
nodes.Append((CXFA_ObjArray&)array); | |
return nodes.GetSize(); | |
} | |
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_PopStack( | |
CFX_Int32Array& stack) { | |
int32_t nType = -1; | |
int32_t iSize = stack.GetSize() - 1; | |
if (iSize > -1) { | |
nType = stack[iSize]; | |
stack.RemoveAt(iSize, 1); | |
} | |
return nType; | |
} | |
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_GetFilter( | |
const CFX_WideStringC& wsExpression, | |
int32_t nStart, | |
CXFA_ResolveNodesData& rnd) { | |
FXSYS_assert(nStart > -1); | |
int32_t iLength = wsExpression.GetLength(); | |
if (nStart >= iLength) { | |
return 0; | |
} | |
CFX_WideString& wsName = rnd.m_wsName; | |
CFX_WideString& wsCondition = rnd.m_wsCondition; | |
FX_WCHAR* pNameBuf = wsName.GetBuffer(iLength - nStart); | |
FX_WCHAR* pConditionBuf = wsCondition.GetBuffer(iLength - nStart); | |
int32_t nNameCount = 0; | |
int32_t nConditionCount = 0; | |
CFX_Int32Array stack; | |
int32_t nType = -1; | |
const FX_WCHAR* pSrc = wsExpression.GetPtr(); | |
FX_WCHAR wPrev = 0, wCur; | |
FX_BOOL bIsCondition = FALSE; | |
while (nStart < iLength) { | |
wCur = pSrc[nStart++]; | |
if (wCur == '.') { | |
if (wPrev == '\\') { | |
pNameBuf[nNameCount - 1] = wPrev = '.'; | |
continue; | |
} | |
if (nNameCount == 0) { | |
pNameBuf[nNameCount++] = wCur; | |
continue; | |
} | |
FX_WCHAR wLookahead = nStart < iLength ? pSrc[nStart] : 0; | |
if (wLookahead != '[' && wLookahead != '(') { | |
if (nType < 0) { | |
break; | |
} | |
} | |
} | |
if (wCur == '[' || wCur == '(') { | |
bIsCondition = TRUE; | |
} else if (wCur == '.' && nStart < iLength && | |
(pSrc[nStart] == '[' || pSrc[nStart] == '(')) { | |
bIsCondition = TRUE; | |
} | |
if (bIsCondition) { | |
pConditionBuf[nConditionCount++] = wCur; | |
} else { | |
pNameBuf[nNameCount++] = wCur; | |
} | |
FX_BOOL bRecursive = TRUE; | |
switch (nType) { | |
case 0: | |
if (wCur == ']') { | |
nType = XFA_ResolveNodes_PopStack(stack); | |
bRecursive = FALSE; | |
} | |
break; | |
case 1: | |
if (wCur == ')') { | |
nType = XFA_ResolveNodes_PopStack(stack); | |
bRecursive = FALSE; | |
} | |
break; | |
case 2: | |
if (wCur == '"') { | |
nType = XFA_ResolveNodes_PopStack(stack); | |
bRecursive = FALSE; | |
} | |
break; | |
} | |
if (bRecursive) { | |
switch (wCur) { | |
case '[': | |
stack.Add(nType); | |
nType = 0; | |
break; | |
case '(': | |
stack.Add(nType); | |
nType = 1; | |
break; | |
case '"': | |
stack.Add(nType); | |
nType = 2; | |
break; | |
} | |
} | |
wPrev = wCur; | |
} | |
if (stack.GetSize() > 0) { | |
return -1; | |
} | |
wsName.ReleaseBuffer(nNameCount); | |
wsName.TrimLeft(); | |
wsName.TrimRight(); | |
wsCondition.ReleaseBuffer(nConditionCount); | |
wsCondition.TrimLeft(); | |
wsCondition.TrimRight(); | |
rnd.m_uHashName = FX_HashCode_String_GetW(wsName, wsName.GetLength()); | |
return nStart; | |
} | |
void CXFA_ResolveProcessor::XFA_ResolveNode_ConditionArray( | |
int32_t iCurIndex, | |
CFX_WideString wsCondition, | |
int32_t iFoundCount, | |
CXFA_ResolveNodesData& rnd) { | |
CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes; | |
int32_t iLen = wsCondition.GetLength(); | |
FX_BOOL bRelative = FALSE; | |
FX_BOOL bAll = FALSE; | |
int32_t i = 1; | |
for (; i < iLen; ++i) { | |
FX_WCHAR ch = wsCondition[i]; | |
if (ch == ' ') { | |
continue; | |
} | |
if (ch == '+' || ch == '-') { | |
bRelative = TRUE; | |
break; | |
} else if (ch == '*') { | |
bAll = TRUE; | |
break; | |
} else { | |
break; | |
} | |
} | |
if (bAll) { | |
if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) { | |
if (rnd.m_dwStyles & XFA_RESOLVENODE_Bind) { | |
m_pNodeHelper->m_pCreateParent = (CXFA_Node*)rnd.m_CurNode; | |
m_pNodeHelper->m_iCreateCount = 1; | |
findNodes.RemoveAll(); | |
m_pNodeHelper->m_iCurAllStart = -1; | |
m_pNodeHelper->m_pAllStartParent = NULL; | |
} else { | |
if (m_pNodeHelper->m_iCurAllStart == -1) { | |
m_pNodeHelper->m_iCurAllStart = m_iCurStart; | |
m_pNodeHelper->m_pAllStartParent = (CXFA_Node*)rnd.m_CurNode; | |
} | |
} | |
} else if (rnd.m_dwStyles & XFA_RESOLVENODE_BindNew) { | |
if (m_pNodeHelper->m_iCurAllStart == -1) { | |
m_pNodeHelper->m_iCurAllStart = m_iCurStart; | |
} | |
} | |
return; | |
} | |
if (iFoundCount == 1 && !iLen) { | |
return; | |
} | |
CFX_WideString wsIndex; | |
wsIndex = wsCondition.Mid(i, iLen - 1 - i); | |
int32_t iIndex = wsIndex.GetInteger(); | |
if (bRelative) { | |
iIndex += iCurIndex; | |
} | |
if (iFoundCount <= iIndex || iIndex < 0) { | |
if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) { | |
m_pNodeHelper->m_pCreateParent = (CXFA_Node*)rnd.m_CurNode; | |
m_pNodeHelper->m_iCreateCount = iIndex - iFoundCount + 1; | |
} | |
findNodes.RemoveAll(); | |
} else { | |
CXFA_Node* ret = findNodes[iIndex]; | |
findNodes.RemoveAll(); | |
findNodes.Add(ret); | |
} | |
} | |
void CXFA_ResolveProcessor::XFA_ResolveNode_DoPredicateFilter( | |
int32_t iCurIndex, | |
CFX_WideString wsCondition, | |
int32_t iFoundCount, | |
CXFA_ResolveNodesData& rnd) { | |
CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes; | |
FXSYS_assert(iFoundCount == findNodes.GetSize()); | |
CFX_WideString wsExpression; | |
IXFA_ScriptContext* pContext = NULL; | |
XFA_SCRIPTLANGTYPE eLangType = XFA_SCRIPTLANGTYPE_Unkown; | |
if (wsCondition.Left(2) == FX_WSTRC(L".[") && | |
wsCondition.Right(1) == FX_WSTRC(L"]")) { | |
eLangType = XFA_SCRIPTLANGTYPE_Formcalc; | |
} else if (wsCondition.Left(2) == FX_WSTRC(L".(") && | |
wsCondition.Right(1) == FX_WSTRC(L")")) { | |
eLangType = XFA_SCRIPTLANGTYPE_Javascript; | |
} else { | |
return; | |
} | |
pContext = rnd.m_pSC; | |
wsExpression = wsCondition.Mid(2, wsCondition.GetLength() - 3); | |
for (int32_t i = iFoundCount - 1; i >= 0; i--) { | |
CXFA_Object* node = findNodes[i]; | |
FX_BOOL bRet = FALSE; | |
FXJSE_HVALUE pRetValue = FXJSE_Value_Create(rnd.m_pSC->GetRuntime()); | |
bRet = pContext->RunScript(eLangType, wsExpression, pRetValue, node); | |
if (!bRet || !FXJSE_Value_ToBoolean(pRetValue)) { | |
findNodes.RemoveAt(i); | |
} | |
FXJSE_Value_Release(pRetValue); | |
} | |
} | |
void CXFA_ResolveProcessor::XFA_ResolveNode_FilterCondition( | |
CXFA_ResolveNodesData& rnd, | |
CFX_WideString wsCondition) { | |
CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes; | |
int32_t iCurrIndex = 0; | |
const CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray(); | |
int32_t iSize = array.GetSize(); | |
if (iSize) { | |
CXFA_Node* curNode = array[iSize - 1]; | |
FX_BOOL bIsProperty = m_pNodeHelper->XFA_NodeIsProperty(curNode); | |
if (curNode->IsUnnamed() || | |
(bIsProperty && curNode->GetClassID() != XFA_ELEMENT_PageSet)) { | |
iCurrIndex = m_pNodeHelper->XFA_GetIndex(curNode, XFA_LOGIC_Transparent, | |
bIsProperty, TRUE); | |
} else { | |
iCurrIndex = m_pNodeHelper->XFA_GetIndex(curNode, XFA_LOGIC_Transparent, | |
bIsProperty, FALSE); | |
} | |
} | |
int32_t iFoundCount = findNodes.GetSize(); | |
wsCondition.TrimLeft(); | |
wsCondition.TrimRight(); | |
int32_t iLen = wsCondition.GetLength(); | |
if (!iLen) { | |
if (rnd.m_dwStyles & XFA_RESOLVENODE_ALL) { | |
return; | |
} | |
if (iFoundCount == 1) { | |
return; | |
} | |
if (iFoundCount <= iCurrIndex) { | |
if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) { | |
m_pNodeHelper->m_pCreateParent = (CXFA_Node*)rnd.m_CurNode; | |
m_pNodeHelper->m_iCreateCount = iCurrIndex - iFoundCount + 1; | |
} | |
findNodes.RemoveAll(); | |
return; | |
} else { | |
CXFA_Node* ret = findNodes[iCurrIndex]; | |
findNodes.RemoveAll(); | |
findNodes.Add(ret); | |
return; | |
} | |
} | |
FX_WCHAR wTypeChar = wsCondition[0]; | |
switch (wTypeChar) { | |
case '[': | |
XFA_ResolveNode_ConditionArray(iCurrIndex, wsCondition, iFoundCount, rnd); | |
return; | |
case '(': | |
return; | |
case '"': | |
return; | |
case '.': | |
if (iLen > 1 && (wsCondition[1] == '[' || wsCondition[1] == '(')) { | |
XFA_ResolveNode_DoPredicateFilter(iCurrIndex, wsCondition, iFoundCount, | |
rnd); | |
} | |
default: | |
return; | |
} | |
} | |
void CXFA_ResolveProcessor::XFA_ResolveNodes_SetStylesForChild( | |
FX_DWORD dwParentStyles, | |
CXFA_ResolveNodesData& rnd) { | |
FX_DWORD dwSubStyles = XFA_RESOLVENODE_Children; | |
if (dwParentStyles & XFA_RESOLVENODE_TagName) { | |
dwSubStyles |= XFA_RESOLVENODE_TagName; | |
} | |
dwSubStyles &= ~XFA_RESOLVENODE_Parent; | |
dwSubStyles &= ~XFA_RESOLVENODE_Siblings; | |
dwSubStyles &= ~XFA_RESOLVENODE_Properties; | |
dwSubStyles |= XFA_RESOLVENODE_ALL; | |
rnd.m_dwStyles = dwSubStyles; | |
} | |
int32_t CXFA_ResolveProcessor::XFA_ResolveNode_SetResultCreateNode( | |
XFA_RESOLVENODE_RS& resolveNodeRS, | |
CFX_WideString& wsLastCondition) { | |
if (m_pNodeHelper->m_pCreateParent) { | |
resolveNodeRS.nodes.Add(m_pNodeHelper->m_pCreateParent); | |
} else { | |
m_pNodeHelper->XFA_CreateNode_ForCondition(wsLastCondition); | |
} | |
resolveNodeRS.dwFlags = m_pNodeHelper->m_iCreateFlag; | |
if (resolveNodeRS.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) { | |
if (m_pNodeHelper->m_iCurAllStart != -1) { | |
resolveNodeRS.dwFlags = XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll; | |
} | |
} | |
return resolveNodeRS.nodes.GetSize(); | |
} | |
void CXFA_ResolveProcessor::XFA_ResolveNode_SetIndexDataBind( | |
CFX_WideString& wsNextCondition, | |
int32_t& iIndex, | |
int32_t iCount) { | |
if (m_pNodeHelper->XFA_CreateNode_ForCondition(wsNextCondition)) { | |
if (m_pNodeHelper->m_eLastCreateType == XFA_ELEMENT_DataGroup) { | |
iIndex = 0; | |
} else { | |
iIndex = iCount - 1; | |
} | |
} else { | |
iIndex = iCount - 1; | |
} | |
} |