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