Home | History | Annotate | Download | only in parser
      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 #include "xfa/src/foxitlib.h"
      8 #include "xfa/src/fxfa/src/common/xfa_utils.h"
      9 #include "xfa/src/fxfa/src/common/xfa_object.h"
     10 #include "xfa/src/fxfa/src/common/xfa_document.h"
     11 #include "xfa/src/fxfa/src/common/xfa_parser.h"
     12 #include "xfa/src/fxfa/src/common/xfa_script.h"
     13 #include "xfa/src/fxfa/src/common/xfa_docdata.h"
     14 #include "xfa/src/fxfa/src/common/xfa_doclayout.h"
     15 #include "xfa/src/fxfa/src/common/xfa_localemgr.h"
     16 #include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h"
     17 #include "xfa_script_resolveprocessor.h"
     18 #include "xfa_script_nodehelper.h"
     19 #include "xfa_script_imp.h"
     20 CXFA_ResolveProcessor::CXFA_ResolveProcessor(void)
     21     : m_pNodeHelper(NULL), m_iCurStart(0) {
     22   m_pNodeHelper = new CXFA_NodeHelper;
     23 }
     24 CXFA_ResolveProcessor::~CXFA_ResolveProcessor(void) {
     25   if (m_pNodeHelper) {
     26     delete m_pNodeHelper;
     27     m_pNodeHelper = NULL;
     28   }
     29 }
     30 int32_t CXFA_ResolveProcessor::XFA_ResolveNodes(CXFA_ResolveNodesData& rnd) {
     31   if (rnd.m_CurNode == NULL) {
     32     return -1;
     33   }
     34   if (!rnd.m_CurNode->IsNode()) {
     35     if (rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) {
     36       return XFA_ResolveNodes_ForAttributeRs(rnd.m_CurNode, rnd, rnd.m_wsName);
     37     }
     38     return 0;
     39   }
     40   if (rnd.m_dwStyles & XFA_RESOLVENODE_AnyChild) {
     41     return XFA_ResolveNodes_AnyChild(rnd);
     42   }
     43   FX_WCHAR wch = rnd.m_wsName.GetAt(0);
     44   switch (wch) {
     45     case '$':
     46       return XFA_ResolveNodes_Dollar(rnd);
     47     case '!':
     48       return XFA_ResolveNodes_Excalmatory(rnd);
     49     case '#':
     50       return XFA_ResolveNodes_NumberSign(rnd);
     51     case '*':
     52       return XFA_ResolveNodes_Asterisk(rnd);
     53     case '.':
     54       return XFA_ResolveNodes_AnyChild(rnd);
     55     default:
     56       break;
     57   }
     58   if (rnd.m_uHashName == XFA_HASHCODE_This && rnd.m_nLevel == 0) {
     59     rnd.m_Nodes.Add(rnd.m_pSC->GetThisObject());
     60     return 1;
     61   } else if (rnd.m_CurNode->GetClassID() == XFA_ELEMENT_Xfa) {
     62     CXFA_Object* pObjNode =
     63         rnd.m_pSC->GetDocument()->GetXFANode(rnd.m_uHashName);
     64     if (pObjNode) {
     65       rnd.m_Nodes.Add(pObjNode);
     66     } else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) {
     67       rnd.m_Nodes.Add(rnd.m_CurNode);
     68     } else if ((rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) &&
     69                XFA_ResolveNodes_ForAttributeRs(rnd.m_CurNode, rnd,
     70                                                rnd.m_wsName)) {
     71       return 1;
     72     }
     73     if (rnd.m_Nodes.GetSize() > 0) {
     74       XFA_ResolveNode_FilterCondition(rnd, rnd.m_wsCondition);
     75     }
     76     return rnd.m_Nodes.GetSize();
     77   }
     78   int32_t nRet = XFA_ResolveNodes_Normal(rnd);
     79   if (nRet < 1 && rnd.m_uHashName == XFA_HASHCODE_Xfa) {
     80     rnd.m_Nodes.Add(rnd.m_pSC->GetDocument()->GetRoot());
     81   }
     82   return rnd.m_Nodes.GetSize();
     83 }
     84 int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_AnyChild(
     85     CXFA_ResolveNodesData& rnd) {
     86   CFX_WideString wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
     87   CFX_WideString wsCondition = rnd.m_wsCondition;
     88   CXFA_Node* findNode = NULL;
     89   CXFA_NodeArray siblings;
     90   FX_BOOL bClassName = FALSE;
     91   if (wsName.GetAt(0) == '#') {
     92     bClassName = TRUE;
     93     wsName = wsName.Right(wsName.GetLength() - 1);
     94   }
     95   findNode = m_pNodeHelper->XFA_ResolveNodes_GetOneChild(
     96       (CXFA_Node*)rnd.m_CurNode, wsName, bClassName);
     97   if (findNode == NULL) {
     98     return 0;
     99   }
    100   if (wsCondition.IsEmpty()) {
    101     rnd.m_Nodes.Add(findNode);
    102     return rnd.m_Nodes.GetSize();
    103   }
    104   m_pNodeHelper->XFA_CountSiblings(findNode, XFA_LOGIC_Transparent,
    105                                    (CXFA_NodeArray*)&rnd.m_Nodes, bClassName);
    106   XFA_ResolveNode_FilterCondition(rnd, wsCondition);
    107   return rnd.m_Nodes.GetSize();
    108 }
    109 int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Dollar(
    110     CXFA_ResolveNodesData& rnd) {
    111   CXFA_ObjArray& nodes = rnd.m_Nodes;
    112   CFX_WideString wsName = rnd.m_wsName;
    113   CFX_WideString wsCondition = rnd.m_wsCondition;
    114   int32_t iNameLen = wsName.GetLength();
    115   if (iNameLen == 1) {
    116     nodes.Add(rnd.m_CurNode);
    117     return 1;
    118   }
    119   if (rnd.m_nLevel > 0) {
    120     return -1;
    121   }
    122   FX_DWORD dwNameHash =
    123       FX_HashCode_String_GetW((const FX_WCHAR*)wsName + 1, iNameLen - 1);
    124   if (dwNameHash == XFA_HASHCODE_Xfa) {
    125     nodes.Add(rnd.m_pSC->GetDocument()->GetRoot());
    126   } else {
    127     CXFA_Object* pObjNode = rnd.m_pSC->GetDocument()->GetXFANode(dwNameHash);
    128     if (pObjNode) {
    129       rnd.m_Nodes.Add(pObjNode);
    130     }
    131   }
    132   if (rnd.m_Nodes.GetSize() > 0) {
    133     XFA_ResolveNode_FilterCondition(rnd, wsCondition);
    134   }
    135   return rnd.m_Nodes.GetSize();
    136 }
    137 int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Excalmatory(
    138     CXFA_ResolveNodesData& rnd) {
    139   if (rnd.m_nLevel > 0) {
    140     return 0;
    141   }
    142   CXFA_Node* datasets =
    143       (CXFA_Node*)rnd.m_pSC->GetDocument()->GetXFANode(XFA_HASHCODE_Datasets);
    144   if (datasets == NULL) {
    145     return 0;
    146   }
    147   CXFA_ResolveNodesData rndFind;
    148   rndFind.m_pSC = rnd.m_pSC;
    149   rndFind.m_CurNode = datasets;
    150   rndFind.m_wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
    151   rndFind.m_uHashName =
    152       FX_HashCode_String_GetW(rndFind.m_wsName, rndFind.m_wsName.GetLength());
    153   rndFind.m_nLevel = rnd.m_nLevel + 1;
    154   rndFind.m_dwStyles = XFA_RESOLVENODE_Children;
    155   rndFind.m_wsCondition = rnd.m_wsCondition;
    156   XFA_ResolveNodes(rndFind);
    157   if (rndFind.m_Nodes.GetSize() > 0) {
    158     rnd.m_Nodes.Append(rndFind.m_Nodes);
    159     rndFind.m_Nodes.RemoveAll();
    160   }
    161   return rnd.m_Nodes.GetSize();
    162 }
    163 int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_NumberSign(
    164     CXFA_ResolveNodesData& rnd) {
    165   CFX_WideString wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
    166   CFX_WideString wsCondition = rnd.m_wsCondition;
    167   CXFA_Node* curNode = (CXFA_Node*)rnd.m_CurNode;
    168   if (XFA_ResolveNodes_ForAttributeRs(curNode, rnd, wsName)) {
    169     return 1;
    170   }
    171   CXFA_ResolveNodesData rndFind;
    172   rndFind.m_pSC = rnd.m_pSC;
    173   rndFind.m_nLevel = rnd.m_nLevel + 1;
    174   rndFind.m_dwStyles = rnd.m_dwStyles;
    175   rndFind.m_dwStyles |= XFA_RESOLVENODE_TagName;
    176   rndFind.m_dwStyles &= ~XFA_RESOLVENODE_Attributes;
    177   rndFind.m_wsName = wsName;
    178   rndFind.m_uHashName =
    179       FX_HashCode_String_GetW(rndFind.m_wsName, rndFind.m_wsName.GetLength());
    180   rndFind.m_wsCondition = wsCondition;
    181   rndFind.m_CurNode = curNode;
    182   XFA_ResolveNodes_Normal(rndFind);
    183   if (rndFind.m_Nodes.GetSize() > 0) {
    184     if (wsCondition.GetLength() == 0 && rndFind.m_Nodes.Find(curNode) >= 0) {
    185       rnd.m_Nodes.Add(curNode);
    186     } else {
    187       rnd.m_Nodes.Append(rndFind.m_Nodes);
    188       rndFind.m_Nodes.RemoveAll();
    189     }
    190   }
    191   return rnd.m_Nodes.GetSize();
    192 }
    193 int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_ForAttributeRs(
    194     CXFA_Object* curNode,
    195     CXFA_ResolveNodesData& rnd,
    196     const CFX_WideStringC& strAttr) {
    197   XFA_LPCSCRIPTATTRIBUTEINFO lpScriptAttribute =
    198       XFA_GetScriptAttributeByName(curNode->GetClassID(), strAttr);
    199   if (lpScriptAttribute) {
    200     rnd.m_pScriptAttribute = lpScriptAttribute;
    201     rnd.m_Nodes.Add(curNode);
    202     rnd.m_dwFlag = XFA_RESOVENODE_RSTYPE_Attribute;
    203     return 1;
    204   }
    205   return 0;
    206 }
    207 int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Normal(
    208     CXFA_ResolveNodesData& rnd) {
    209   if (rnd.m_nLevel > 32) {
    210     return 0;
    211   }
    212   if (!rnd.m_CurNode->IsNode()) {
    213     return 0;
    214   }
    215   CXFA_Node* curNode = (CXFA_Node*)rnd.m_CurNode;
    216   CXFA_ObjArray& nodes = rnd.m_Nodes;
    217   int32_t nNum = nodes.GetSize();
    218   FX_DWORD dwStyles = rnd.m_dwStyles;
    219   CFX_WideString& wsName = rnd.m_wsName;
    220   uint32_t uNameHash = rnd.m_uHashName;
    221   CFX_WideString& wsCondition = rnd.m_wsCondition;
    222   CXFA_ResolveNodesData rndFind;
    223   rndFind.m_wsName = rnd.m_wsName;
    224   rndFind.m_wsCondition = rnd.m_wsCondition;
    225   rndFind.m_pSC = rnd.m_pSC;
    226   rndFind.m_nLevel = rnd.m_nLevel + 1;
    227   rndFind.m_uHashName = uNameHash;
    228   CXFA_NodeArray children;
    229   CXFA_NodeArray properties;
    230   CXFA_Node* pVariablesNode = NULL;
    231   CXFA_Node* pPageSetNode = NULL;
    232   CXFA_Node* pChild = curNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    233   while (pChild) {
    234     if (pChild->GetClassID() == XFA_ELEMENT_Variables) {
    235       pVariablesNode = pChild;
    236       pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
    237       continue;
    238     } else if (pChild->GetClassID() == XFA_ELEMENT_PageSet) {
    239       pPageSetNode = pChild;
    240       pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
    241       continue;
    242     } else {
    243       XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement(
    244           curNode->GetClassID(), pChild->GetClassID(), XFA_XDPPACKET_UNKNOWN);
    245       if (pPropert) {
    246         properties.Add(pChild);
    247       } else {
    248         children.Add(pChild);
    249       }
    250     }
    251     pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
    252   }
    253   if ((dwStyles & XFA_RESOLVENODE_Properties) && pVariablesNode) {
    254     uint32_t uPropHash = pVariablesNode->GetClassHashCode();
    255     if (uPropHash == uNameHash) {
    256       nodes.Add(pVariablesNode);
    257     } else {
    258       rndFind.m_CurNode = pVariablesNode;
    259       XFA_ResolveNodes_SetStylesForChild(dwStyles, rndFind);
    260       CFX_WideString wsSaveCondition = rndFind.m_wsCondition;
    261       rndFind.m_wsCondition.Empty();
    262       XFA_ResolveNodes_Normal(rndFind);
    263       rndFind.m_wsCondition = wsSaveCondition;
    264       if (rndFind.m_Nodes.GetSize() > 0) {
    265         nodes.Append(rndFind.m_Nodes);
    266         rndFind.m_Nodes.RemoveAll();
    267       }
    268     }
    269     if (nodes.GetSize() > nNum) {
    270       XFA_ResolveNode_FilterCondition(rnd, wsCondition);
    271       if (nodes.GetSize() > 0) {
    272         return 1;
    273       }
    274       return 0;
    275     }
    276   }
    277   if (dwStyles & XFA_RESOLVENODE_Children) {
    278     FX_BOOL bSetFlag = FALSE;
    279     if (pPageSetNode && (dwStyles & XFA_RESOLVENODE_Properties)) {
    280       children.Add(pPageSetNode);
    281     }
    282     for (int32_t i = 0; i < children.GetSize(); i++) {
    283       CXFA_Node* child = children[i];
    284       if (dwStyles & XFA_RESOLVENODE_TagName) {
    285         if (child->GetClassHashCode() == uNameHash) {
    286           nodes.Add(child);
    287         }
    288       } else if (child->GetNameHash() == uNameHash) {
    289         nodes.Add(child);
    290       }
    291       if (m_pNodeHelper->XFA_NodeIsTransparent(child) &&
    292           child->GetClassID() != XFA_ELEMENT_PageSet) {
    293         if (!bSetFlag) {
    294           XFA_ResolveNodes_SetStylesForChild(dwStyles, rndFind);
    295           bSetFlag = TRUE;
    296         }
    297         rndFind.m_CurNode = child;
    298         CFX_WideString wsSaveCondition = rndFind.m_wsCondition;
    299         rndFind.m_wsCondition.Empty();
    300         XFA_ResolveNodes_Normal(rndFind);
    301         rndFind.m_wsCondition = wsSaveCondition;
    302         if (rndFind.m_Nodes.GetSize() > 0) {
    303           nodes.Append(rndFind.m_Nodes);
    304           rndFind.m_Nodes.RemoveAll();
    305         }
    306       }
    307     }
    308     if (nodes.GetSize() > nNum) {
    309       if (!(dwStyles & XFA_RESOLVENODE_ALL)) {
    310         CXFA_NodeArray upArrayNodes;
    311         if (m_pNodeHelper->XFA_NodeIsTransparent((CXFA_Node*)curNode)) {
    312           m_pNodeHelper->XFA_CountSiblings(
    313               (CXFA_Node*)nodes[0], XFA_LOGIC_Transparent, &upArrayNodes,
    314               !!(dwStyles & XFA_RESOLVENODE_TagName));
    315         }
    316         if (upArrayNodes.GetSize() > nodes.GetSize()) {
    317           upArrayNodes[0] = (CXFA_Node*)nodes[0];
    318           nodes.RemoveAll();
    319           nodes.Append((CXFA_ObjArray&)upArrayNodes);
    320           upArrayNodes.RemoveAll();
    321         }
    322       }
    323       XFA_ResolveNode_FilterCondition(rnd, wsCondition);
    324       if (nodes.GetSize() > 0) {
    325         return 1;
    326       }
    327       return 0;
    328     }
    329   }
    330   if (dwStyles & XFA_RESOLVENODE_Attributes) {
    331     if (XFA_ResolveNodes_ForAttributeRs(curNode, rnd, wsName)) {
    332       return 1;
    333     }
    334   }
    335   if (dwStyles & XFA_RESOLVENODE_Properties) {
    336     for (int32_t i = 0; i < properties.GetSize(); i++) {
    337       CXFA_Node* childProperty = properties[i];
    338       if (childProperty->IsUnnamed()) {
    339         uint32_t uPropHash = childProperty->GetClassHashCode();
    340         if (uPropHash == uNameHash) {
    341           nodes.Add(childProperty);
    342         }
    343       } else if (childProperty->GetNameHash() == uNameHash &&
    344                  childProperty->GetClassID() != XFA_ELEMENT_Extras &&
    345                  childProperty->GetClassID() != XFA_ELEMENT_Items) {
    346         nodes.Add(childProperty);
    347       }
    348     }
    349     if (nodes.GetSize() > nNum) {
    350       XFA_ResolveNode_FilterCondition(rnd, wsCondition);
    351       if (nodes.GetSize() > 0) {
    352         return 1;
    353       }
    354       return 0;
    355     }
    356     CXFA_Node* pProp = NULL;
    357     if (XFA_ELEMENT_Subform == curNode->GetClassID() &&
    358         XFA_HASHCODE_Occur == uNameHash) {
    359       CXFA_Node* pInstanceManager =
    360           ((CXFA_Node*)curNode)->GetInstanceMgrOfSubform();
    361       if (pInstanceManager) {
    362         pProp = pInstanceManager->GetProperty(0, XFA_ELEMENT_Occur, TRUE);
    363       }
    364     } else {
    365       XFA_LPCELEMENTINFO pElement = XFA_GetElementByName(wsName);
    366       if (pElement) {
    367         pProp = ((CXFA_Node*)curNode)
    368                     ->GetProperty(0, pElement->eName,
    369                                   pElement->eName != XFA_ELEMENT_PageSet);
    370       }
    371     }
    372     if (pProp) {
    373       nodes.Add(pProp);
    374       return nodes.GetSize();
    375     }
    376   }
    377   CXFA_Node* parentNode = m_pNodeHelper->XFA_ResolveNodes_GetParent(
    378       (CXFA_Node*)curNode, XFA_LOGIC_NoTransparent);
    379   uint32_t uCurClassHash = curNode->GetClassHashCode();
    380   if (parentNode == NULL) {
    381     if (uCurClassHash == uNameHash) {
    382       nodes.Add((CXFA_Node*)curNode);
    383       XFA_ResolveNode_FilterCondition(rnd, wsCondition);
    384       if (nodes.GetSize() > 0) {
    385         return 1;
    386       }
    387     }
    388     return 0;
    389   }
    390   if (dwStyles & XFA_RESOLVENODE_Siblings) {
    391     CXFA_Node* child = parentNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    392     FX_DWORD dwSubStyles =
    393         XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties;
    394     if (dwStyles & XFA_RESOLVENODE_TagName) {
    395       dwSubStyles |= XFA_RESOLVENODE_TagName;
    396     }
    397     if (dwStyles & XFA_RESOLVENODE_ALL) {
    398       dwSubStyles |= XFA_RESOLVENODE_ALL;
    399     }
    400     rndFind.m_dwStyles = dwSubStyles;
    401     while (child) {
    402       if (child == curNode) {
    403         if (dwStyles & XFA_RESOLVENODE_TagName) {
    404           if (uCurClassHash == uNameHash) {
    405             nodes.Add(curNode);
    406           }
    407         } else {
    408           if (child->GetNameHash() == uNameHash) {
    409             nodes.Add(curNode);
    410             if (rnd.m_nLevel == 0 && wsCondition.GetLength() == 0) {
    411               nodes.RemoveAll();
    412               nodes.Add(curNode);
    413               return 1;
    414             }
    415           }
    416         }
    417         child = child->GetNodeItem(XFA_NODEITEM_NextSibling);
    418         continue;
    419       }
    420       if (dwStyles & XFA_RESOLVENODE_TagName) {
    421         if (child->GetClassHashCode() == uNameHash) {
    422           nodes.Add(child);
    423         }
    424       } else if (child->GetNameHash() == uNameHash) {
    425         nodes.Add(child);
    426       }
    427       XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement(
    428           parentNode->GetClassID(), child->GetClassID(), XFA_XDPPACKET_UNKNOWN);
    429       FX_BOOL bInnerSearch = FALSE;
    430       if (pPropert) {
    431         if ((child->GetClassID() == XFA_ELEMENT_Variables ||
    432              child->GetClassID() == XFA_ELEMENT_PageSet)) {
    433           bInnerSearch = TRUE;
    434         }
    435       } else {
    436         if (m_pNodeHelper->XFA_NodeIsTransparent(child)) {
    437           bInnerSearch = TRUE;
    438         }
    439       }
    440       if (bInnerSearch) {
    441         rndFind.m_CurNode = child;
    442         CFX_WideString wsOriginCondition = rndFind.m_wsCondition;
    443         rndFind.m_wsCondition.Empty();
    444         FX_DWORD dwOriginStyle = rndFind.m_dwStyles;
    445         rndFind.m_dwStyles = dwOriginStyle | XFA_RESOLVENODE_ALL;
    446         XFA_ResolveNodes_Normal(rndFind);
    447         rndFind.m_dwStyles = dwOriginStyle;
    448         rndFind.m_wsCondition = wsOriginCondition;
    449         if (rndFind.m_Nodes.GetSize() > 0) {
    450           nodes.Append(rndFind.m_Nodes);
    451           rndFind.m_Nodes.RemoveAll();
    452         }
    453       }
    454       child = child->GetNodeItem(XFA_NODEITEM_NextSibling);
    455     }
    456     if (nodes.GetSize() > nNum) {
    457       if (m_pNodeHelper->XFA_NodeIsTransparent(parentNode)) {
    458         CXFA_NodeArray upArrayNodes;
    459         m_pNodeHelper->XFA_CountSiblings(
    460             (CXFA_Node*)nodes[0], XFA_LOGIC_Transparent, &upArrayNodes,
    461             !!(dwStyles & XFA_RESOLVENODE_TagName));
    462         if (upArrayNodes.GetSize() > nodes.GetSize()) {
    463           upArrayNodes[0] = (CXFA_Node*)nodes[0];
    464           nodes.RemoveAll();
    465           nodes.Append((CXFA_ObjArray&)upArrayNodes);
    466           upArrayNodes.RemoveAll();
    467         }
    468       }
    469       XFA_ResolveNode_FilterCondition(rnd, wsCondition);
    470       if (nodes.GetSize() > 0) {
    471         return 1;
    472       }
    473       return 0;
    474     }
    475   }
    476   if (dwStyles & XFA_RESOLVENODE_Parent) {
    477     FX_DWORD dwSubStyles = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent |
    478                            XFA_RESOLVENODE_Properties;
    479     if (dwStyles & XFA_RESOLVENODE_TagName) {
    480       dwSubStyles |= XFA_RESOLVENODE_TagName;
    481     }
    482     if (dwStyles & XFA_RESOLVENODE_ALL) {
    483       dwSubStyles |= XFA_RESOLVENODE_ALL;
    484     }
    485     rndFind.m_dwStyles = dwSubStyles;
    486     rndFind.m_CurNode = parentNode;
    487     CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray();
    488     array.Add(parentNode);
    489     XFA_ResolveNodes_Normal(rndFind);
    490     if (rndFind.m_Nodes.GetSize() > 0) {
    491       nodes.Append(rndFind.m_Nodes);
    492       rndFind.m_Nodes.RemoveAll();
    493     }
    494     if (nodes.GetSize() > nNum) {
    495       return 1;
    496     }
    497   }
    498   return 0;
    499 }
    500 int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Asterisk(
    501     CXFA_ResolveNodesData& rnd) {
    502   CXFA_Node* curNode = (CXFA_Node*)rnd.m_CurNode;
    503   CXFA_ObjArray& nodes = rnd.m_Nodes;
    504   CXFA_NodeArray array;
    505   curNode->GetNodeList(array,
    506                        XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties);
    507   nodes.Append((CXFA_ObjArray&)array);
    508   return nodes.GetSize();
    509 }
    510 int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_PopStack(
    511     CFX_Int32Array& stack) {
    512   int32_t nType = -1;
    513   int32_t iSize = stack.GetSize() - 1;
    514   if (iSize > -1) {
    515     nType = stack[iSize];
    516     stack.RemoveAt(iSize, 1);
    517   }
    518   return nType;
    519 }
    520 int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_GetFilter(
    521     const CFX_WideStringC& wsExpression,
    522     int32_t nStart,
    523     CXFA_ResolveNodesData& rnd) {
    524   FXSYS_assert(nStart > -1);
    525   int32_t iLength = wsExpression.GetLength();
    526   if (nStart >= iLength) {
    527     return 0;
    528   }
    529   CFX_WideString& wsName = rnd.m_wsName;
    530   CFX_WideString& wsCondition = rnd.m_wsCondition;
    531   FX_WCHAR* pNameBuf = wsName.GetBuffer(iLength - nStart);
    532   FX_WCHAR* pConditionBuf = wsCondition.GetBuffer(iLength - nStart);
    533   int32_t nNameCount = 0;
    534   int32_t nConditionCount = 0;
    535   CFX_Int32Array stack;
    536   int32_t nType = -1;
    537   const FX_WCHAR* pSrc = wsExpression.GetPtr();
    538   FX_WCHAR wPrev = 0, wCur;
    539   FX_BOOL bIsCondition = FALSE;
    540   while (nStart < iLength) {
    541     wCur = pSrc[nStart++];
    542     if (wCur == '.') {
    543       if (wPrev == '\\') {
    544         pNameBuf[nNameCount - 1] = wPrev = '.';
    545         continue;
    546       }
    547       if (nNameCount == 0) {
    548         pNameBuf[nNameCount++] = wCur;
    549         continue;
    550       }
    551       FX_WCHAR wLookahead = nStart < iLength ? pSrc[nStart] : 0;
    552       if (wLookahead != '[' && wLookahead != '(') {
    553         if (nType < 0) {
    554           break;
    555         }
    556       }
    557     }
    558     if (wCur == '[' || wCur == '(') {
    559       bIsCondition = TRUE;
    560     } else if (wCur == '.' && nStart < iLength &&
    561                (pSrc[nStart] == '[' || pSrc[nStart] == '(')) {
    562       bIsCondition = TRUE;
    563     }
    564     if (bIsCondition) {
    565       pConditionBuf[nConditionCount++] = wCur;
    566     } else {
    567       pNameBuf[nNameCount++] = wCur;
    568     }
    569     FX_BOOL bRecursive = TRUE;
    570     switch (nType) {
    571       case 0:
    572         if (wCur == ']') {
    573           nType = XFA_ResolveNodes_PopStack(stack);
    574           bRecursive = FALSE;
    575         }
    576         break;
    577       case 1:
    578         if (wCur == ')') {
    579           nType = XFA_ResolveNodes_PopStack(stack);
    580           bRecursive = FALSE;
    581         }
    582         break;
    583       case 2:
    584         if (wCur == '"') {
    585           nType = XFA_ResolveNodes_PopStack(stack);
    586           bRecursive = FALSE;
    587         }
    588         break;
    589     }
    590     if (bRecursive) {
    591       switch (wCur) {
    592         case '[':
    593           stack.Add(nType);
    594           nType = 0;
    595           break;
    596         case '(':
    597           stack.Add(nType);
    598           nType = 1;
    599           break;
    600         case '"':
    601           stack.Add(nType);
    602           nType = 2;
    603           break;
    604       }
    605     }
    606     wPrev = wCur;
    607   }
    608   if (stack.GetSize() > 0) {
    609     return -1;
    610   }
    611   wsName.ReleaseBuffer(nNameCount);
    612   wsName.TrimLeft();
    613   wsName.TrimRight();
    614   wsCondition.ReleaseBuffer(nConditionCount);
    615   wsCondition.TrimLeft();
    616   wsCondition.TrimRight();
    617   rnd.m_uHashName = FX_HashCode_String_GetW(wsName, wsName.GetLength());
    618   return nStart;
    619 }
    620 void CXFA_ResolveProcessor::XFA_ResolveNode_ConditionArray(
    621     int32_t iCurIndex,
    622     CFX_WideString wsCondition,
    623     int32_t iFoundCount,
    624     CXFA_ResolveNodesData& rnd) {
    625   CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
    626   int32_t iLen = wsCondition.GetLength();
    627   FX_BOOL bRelative = FALSE;
    628   FX_BOOL bAll = FALSE;
    629   int32_t i = 1;
    630   for (; i < iLen; ++i) {
    631     FX_WCHAR ch = wsCondition[i];
    632     if (ch == ' ') {
    633       continue;
    634     }
    635     if (ch == '+' || ch == '-') {
    636       bRelative = TRUE;
    637       break;
    638     } else if (ch == '*') {
    639       bAll = TRUE;
    640       break;
    641     } else {
    642       break;
    643     }
    644   }
    645   if (bAll) {
    646     if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
    647       if (rnd.m_dwStyles & XFA_RESOLVENODE_Bind) {
    648         m_pNodeHelper->m_pCreateParent = (CXFA_Node*)rnd.m_CurNode;
    649         m_pNodeHelper->m_iCreateCount = 1;
    650         findNodes.RemoveAll();
    651         m_pNodeHelper->m_iCurAllStart = -1;
    652         m_pNodeHelper->m_pAllStartParent = NULL;
    653       } else {
    654         if (m_pNodeHelper->m_iCurAllStart == -1) {
    655           m_pNodeHelper->m_iCurAllStart = m_iCurStart;
    656           m_pNodeHelper->m_pAllStartParent = (CXFA_Node*)rnd.m_CurNode;
    657         }
    658       }
    659     } else if (rnd.m_dwStyles & XFA_RESOLVENODE_BindNew) {
    660       if (m_pNodeHelper->m_iCurAllStart == -1) {
    661         m_pNodeHelper->m_iCurAllStart = m_iCurStart;
    662       }
    663     }
    664     return;
    665   }
    666   if (iFoundCount == 1 && !iLen) {
    667     return;
    668   }
    669   CFX_WideString wsIndex;
    670   wsIndex = wsCondition.Mid(i, iLen - 1 - i);
    671   int32_t iIndex = wsIndex.GetInteger();
    672   if (bRelative) {
    673     iIndex += iCurIndex;
    674   }
    675   if (iFoundCount <= iIndex || iIndex < 0) {
    676     if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
    677       m_pNodeHelper->m_pCreateParent = (CXFA_Node*)rnd.m_CurNode;
    678       m_pNodeHelper->m_iCreateCount = iIndex - iFoundCount + 1;
    679     }
    680     findNodes.RemoveAll();
    681   } else {
    682     CXFA_Node* ret = findNodes[iIndex];
    683     findNodes.RemoveAll();
    684     findNodes.Add(ret);
    685   }
    686 }
    687 void CXFA_ResolveProcessor::XFA_ResolveNode_DoPredicateFilter(
    688     int32_t iCurIndex,
    689     CFX_WideString wsCondition,
    690     int32_t iFoundCount,
    691     CXFA_ResolveNodesData& rnd) {
    692   CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
    693   FXSYS_assert(iFoundCount == findNodes.GetSize());
    694   CFX_WideString wsExpression;
    695   IXFA_ScriptContext* pContext = NULL;
    696   XFA_SCRIPTLANGTYPE eLangType = XFA_SCRIPTLANGTYPE_Unkown;
    697   if (wsCondition.Left(2) == FX_WSTRC(L".[") &&
    698       wsCondition.Right(1) == FX_WSTRC(L"]")) {
    699     eLangType = XFA_SCRIPTLANGTYPE_Formcalc;
    700   } else if (wsCondition.Left(2) == FX_WSTRC(L".(") &&
    701              wsCondition.Right(1) == FX_WSTRC(L")")) {
    702     eLangType = XFA_SCRIPTLANGTYPE_Javascript;
    703   } else {
    704     return;
    705   }
    706   pContext = rnd.m_pSC;
    707   wsExpression = wsCondition.Mid(2, wsCondition.GetLength() - 3);
    708   for (int32_t i = iFoundCount - 1; i >= 0; i--) {
    709     CXFA_Object* node = findNodes[i];
    710     FX_BOOL bRet = FALSE;
    711     FXJSE_HVALUE pRetValue = FXJSE_Value_Create(rnd.m_pSC->GetRuntime());
    712     bRet = pContext->RunScript(eLangType, wsExpression, pRetValue, node);
    713     if (!bRet || !FXJSE_Value_ToBoolean(pRetValue)) {
    714       findNodes.RemoveAt(i);
    715     }
    716     FXJSE_Value_Release(pRetValue);
    717   }
    718   return;
    719 }
    720 void CXFA_ResolveProcessor::XFA_ResolveNode_FilterCondition(
    721     CXFA_ResolveNodesData& rnd,
    722     CFX_WideString wsCondition) {
    723   CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
    724   int32_t iCurrIndex = 0;
    725   const CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray();
    726   int32_t iSize = array.GetSize();
    727   if (iSize) {
    728     CXFA_Node* curNode = array[iSize - 1];
    729     FX_BOOL bIsProperty = m_pNodeHelper->XFA_NodeIsProperty(curNode);
    730     if (curNode->IsUnnamed() ||
    731         (bIsProperty && curNode->GetClassID() != XFA_ELEMENT_PageSet)) {
    732       iCurrIndex = m_pNodeHelper->XFA_GetIndex(curNode, XFA_LOGIC_Transparent,
    733                                                bIsProperty, TRUE);
    734     } else {
    735       iCurrIndex = m_pNodeHelper->XFA_GetIndex(curNode, XFA_LOGIC_Transparent,
    736                                                bIsProperty, FALSE);
    737     }
    738   }
    739   int32_t iFoundCount = findNodes.GetSize();
    740   wsCondition.TrimLeft();
    741   wsCondition.TrimRight();
    742   int32_t iLen = wsCondition.GetLength();
    743   if (!iLen) {
    744     if (rnd.m_dwStyles & XFA_RESOLVENODE_ALL) {
    745       return;
    746     }
    747     if (iFoundCount == 1) {
    748       return;
    749     }
    750     if (iFoundCount <= iCurrIndex) {
    751       if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
    752         m_pNodeHelper->m_pCreateParent = (CXFA_Node*)rnd.m_CurNode;
    753         m_pNodeHelper->m_iCreateCount = iCurrIndex - iFoundCount + 1;
    754       }
    755       findNodes.RemoveAll();
    756       return;
    757     } else {
    758       CXFA_Node* ret = findNodes[iCurrIndex];
    759       findNodes.RemoveAll();
    760       findNodes.Add(ret);
    761       return;
    762     }
    763   }
    764   FX_WCHAR wTypeChar = wsCondition[0];
    765   switch (wTypeChar) {
    766     case '[':
    767       XFA_ResolveNode_ConditionArray(iCurrIndex, wsCondition, iFoundCount, rnd);
    768       return;
    769     case '(':
    770       return;
    771     case '"':
    772       return;
    773     case '.':
    774       if (iLen > 1 && (wsCondition[1] == '[' || wsCondition[1] == '(')) {
    775         XFA_ResolveNode_DoPredicateFilter(iCurrIndex, wsCondition, iFoundCount,
    776                                           rnd);
    777       }
    778     default:
    779       return;
    780   }
    781 }
    782 void CXFA_ResolveProcessor::XFA_ResolveNodes_SetStylesForChild(
    783     FX_DWORD dwParentStyles,
    784     CXFA_ResolveNodesData& rnd) {
    785   FX_DWORD dwSubStyles = XFA_RESOLVENODE_Children;
    786   if (dwParentStyles & XFA_RESOLVENODE_TagName) {
    787     dwSubStyles |= XFA_RESOLVENODE_TagName;
    788   }
    789   dwSubStyles &= ~XFA_RESOLVENODE_Parent;
    790   dwSubStyles &= ~XFA_RESOLVENODE_Siblings;
    791   dwSubStyles &= ~XFA_RESOLVENODE_Properties;
    792   dwSubStyles |= XFA_RESOLVENODE_ALL;
    793   rnd.m_dwStyles = dwSubStyles;
    794 }
    795 int32_t CXFA_ResolveProcessor::XFA_ResolveNode_SetResultCreateNode(
    796     XFA_RESOLVENODE_RS& resolveNodeRS,
    797     CFX_WideString& wsLastCondition) {
    798   if (m_pNodeHelper->m_pCreateParent) {
    799     resolveNodeRS.nodes.Add(m_pNodeHelper->m_pCreateParent);
    800   } else {
    801     m_pNodeHelper->XFA_CreateNode_ForCondition(wsLastCondition);
    802   }
    803   resolveNodeRS.dwFlags = m_pNodeHelper->m_iCreateFlag;
    804   if (resolveNodeRS.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) {
    805     if (m_pNodeHelper->m_iCurAllStart != -1) {
    806       resolveNodeRS.dwFlags = XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll;
    807     }
    808   }
    809   return resolveNodeRS.nodes.GetSize();
    810 }
    811 void CXFA_ResolveProcessor::XFA_ResolveNode_SetIndexDataBind(
    812     CFX_WideString& wsNextCondition,
    813     int32_t& iIndex,
    814     int32_t iCount) {
    815   if (m_pNodeHelper->XFA_CreateNode_ForCondition(wsNextCondition)) {
    816     if (m_pNodeHelper->m_eLastCreateType == XFA_ELEMENT_DataGroup) {
    817       iIndex = 0;
    818     } else {
    819       iIndex = iCount - 1;
    820     }
    821   } else {
    822     iIndex = iCount - 1;
    823   }
    824 }
    825