Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxfa / src / fm2js / xfa_simpleexpression.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 "xfa_fm2js.h"\r
8 static CFX_WideStringC gs_lpStrExpFuncName[] = {\r
9     FX_WSTRC(L"foxit_xfa_formcalc_runtime.assign_value_operator"),\r
10     FX_WSTRC(L"foxit_xfa_formcalc_runtime.logical_or_operator"),\r
11     FX_WSTRC(L"foxit_xfa_formcalc_runtime.logical_and_operator"),\r
12     FX_WSTRC(L"foxit_xfa_formcalc_runtime.equality_operator"),\r
13     FX_WSTRC(L"foxit_xfa_formcalc_runtime.notequality_operator"),\r
14     FX_WSTRC(L"foxit_xfa_formcalc_runtime.less_operator"),\r
15     FX_WSTRC(L"foxit_xfa_formcalc_runtime.lessequal_operator"),\r
16     FX_WSTRC(L"foxit_xfa_formcalc_runtime.greater_operator"),\r
17     FX_WSTRC(L"foxit_xfa_formcalc_runtime.greaterequal_operator"),\r
18     FX_WSTRC(L"foxit_xfa_formcalc_runtime.plus_operator"),\r
19     FX_WSTRC(L"foxit_xfa_formcalc_runtime.minus_operator"),\r
20     FX_WSTRC(L"foxit_xfa_formcalc_runtime.multiple_operator"),\r
21     FX_WSTRC(L"foxit_xfa_formcalc_runtime.divide_operator"),\r
22     FX_WSTRC(L"foxit_xfa_formcalc_runtime.positive_operator"),\r
23     FX_WSTRC(L"foxit_xfa_formcalc_runtime.negative_operator"),\r
24     FX_WSTRC(L"foxit_xfa_formcalc_runtime.logical_not_operator"),\r
25     FX_WSTRC(L"foxit_xfa_formcalc_runtime."),\r
26     FX_WSTRC(L"foxit_xfa_formcalc_runtime.dot_accessor"),\r
27     FX_WSTRC(L"foxit_xfa_formcalc_runtime.dotdot_accessor"),\r
28     FX_WSTRC(L"foxit_xfa_formcalc_runtime.concat_fm_object"),\r
29     FX_WSTRC(L"foxit_xfa_formcalc_runtime.is_fm_object"),\r
30     FX_WSTRC(L"foxit_xfa_formcalc_runtime.is_fm_array"),\r
31     FX_WSTRC(L"foxit_xfa_formcalc_runtime.get_fm_value"),\r
32     FX_WSTRC(L"foxit_xfa_formcalc_runtime.get_fm_jsobj"),\r
33     FX_WSTRC(L"foxit_xfa_formcalc_runtime.fm_var_filter"),\r
34 };\r
35 CFX_WideStringC XFA_FM_EXPTypeToString(XFA_FM_SimpleExpressionType simpleExpType)\r
36 {\r
37     return gs_lpStrExpFuncName[simpleExpType];\r
38 }\r
39 static XFA_FMBuildInFunc buildInFuncs[] = {\r
40     {0x0001f1f5, (FX_LPCWSTR)L"At"},\r
41     {0x00020b9c, (FX_LPCWSTR)L"FV"},\r
42     {0x00021aef, (FX_LPCWSTR)L"If"},\r
43     {0x00023ee6, (FX_LPCWSTR)L"PV"},\r
44     {0x04b5c9ee, (FX_LPCWSTR)L"Encode"},\r
45     {0x08e96685, (FX_LPCWSTR)L"DateFmt"},\r
46     {0x09f99db6, (FX_LPCWSTR)L"Abs"},\r
47     {0x09f9e583, (FX_LPCWSTR)L"Apr"},\r
48     {0x09fa043e, (FX_LPCWSTR)L"Avg"},\r
49     {0x0a9782a0, (FX_LPCWSTR)L"Get"},\r
50     {0x0b1b09df, (FX_LPCWSTR)L"Len"},\r
51     {0x0b3543a6, (FX_LPCWSTR)L"Max"},\r
52     {0x0b356ca4, (FX_LPCWSTR)L"Min"},\r
53     {0x0b358b60, (FX_LPCWSTR)L"Mod"},\r
54     {0x0b4fded4, (FX_LPCWSTR)L"NPV"},\r
55     {0x0b846bf1, (FX_LPCWSTR)L"Pmt"},\r
56     {0x0b8494f9, (FX_LPCWSTR)L"Put"},\r
57     {0x0bb8df5d, (FX_LPCWSTR)L"Ref"},\r
58     {0x0bd37a99, (FX_LPCWSTR)L"Str"},\r
59     {0x0bd37fb5, (FX_LPCWSTR)L"Sum"},\r
60     {0x1048469b, (FX_LPCWSTR)L"Cterm"},\r
61     {0x11e03660, (FX_LPCWSTR)L"Exists"},\r
62     {0x126236e6, (FX_LPCWSTR)L"Post"},\r
63     {0x127c6661, (FX_LPCWSTR)L"PPmt"},\r
64     {0x193ade3e, (FX_LPCWSTR)L"Right"},\r
65     {0x1ec8ab2c, (FX_LPCWSTR)L"Rate"},\r
66     {0x20e476dc, (FX_LPCWSTR)L"IsoTime2Num"},\r
67     {0x23eb6816, (FX_LPCWSTR)L"TimeFmt"},\r
68     {0x24fb17b0, (FX_LPCWSTR)L"LocalDateFmt"},\r
69     {0x28dee6e9, (FX_LPCWSTR)L"Format"},\r
70     {0x2d0890b8, (FX_LPCWSTR)L"Term"},\r
71     {0x2d71b00f, (FX_LPCWSTR)L"Time"},\r
72     {0x2f890fb1, (FX_LPCWSTR)L"Num2Time"},\r
73     {0x3767511d, (FX_LPCWSTR)L"Ceil"},\r
74     {0x3ffd1941, (FX_LPCWSTR)L"LocalTimeFmt"},\r
75     {0x442f68c8, (FX_LPCWSTR)L"Round"},\r
76     {0x46fd1128, (FX_LPCWSTR)L"Eval"},\r
77     {0x4d629440, (FX_LPCWSTR)L"Date2Num"},\r
78     {0x4dcf25f8, (FX_LPCWSTR)L"Concat"},\r
79     {0x4e00255d, (FX_LPCWSTR)L"UnitValue"},\r
80     {0x55a5cc29, (FX_LPCWSTR)L"Lower"},\r
81     {0x5e43e04c, (FX_LPCWSTR)L"WordNum"},\r
82     {0x620ce6ba, (FX_LPCWSTR)L"Ipmt"},\r
83     {0x6f544d49, (FX_LPCWSTR)L"Count"},\r
84     {0x7e241013, (FX_LPCWSTR)L"Within"},\r
85     {0x9b9a6e2b, (FX_LPCWSTR)L"IsoDate2Num"},\r
86     {0xb2c941c2, (FX_LPCWSTR)L"UnitType"},\r
87     {0xb598a1f7, (FX_LPCWSTR)L"Uuid"},\r
88     {0xbde9abde, (FX_LPCWSTR)L"Date"},\r
89     {0xc0010b80, (FX_LPCWSTR)L"Num2Date"},\r
90     {0xc1f6144c, (FX_LPCWSTR)L"Upper"},\r
91     {0xc44028f7, (FX_LPCWSTR)L"Oneof"},\r
92     {0xc62c1b2c, (FX_LPCWSTR)L"Space"},\r
93     {0xd0ff50f9, (FX_LPCWSTR)L"HasValue"},\r
94     {0xd1537042, (FX_LPCWSTR)L"Floor"},\r
95     {0xd2ac9cf1, (FX_LPCWSTR)L"Time2Num"},\r
96     {0xd907aee5, (FX_LPCWSTR)L"Num2GMTime"},\r
97     {0xdf24f7c4, (FX_LPCWSTR)L"Decode"},\r
98     {0xe2664803, (FX_LPCWSTR)L"Substr"},\r
99     {0xe3e7b528, (FX_LPCWSTR)L"Stuff"},\r
100     {0xe6792d4e, (FX_LPCWSTR)L"Rtrim"},\r
101     {0xe8c23f5b, (FX_LPCWSTR)L"Parse"},\r
102     {0xea18d121, (FX_LPCWSTR)L"Choose"},\r
103     {0xebfef69c, (FX_LPCWSTR)L"Replace"},\r
104     {0xf5ad782b, (FX_LPCWSTR)L"Left"},\r
105     {0xf7bb2248, (FX_LPCWSTR)L"Ltrim"},\r
106 };\r
107 static const XFA_FMSOMMethod gs_FMSomMethods[] = {\r
108     {0x00000068, (FX_LPCWSTR)L"h",                              0x01},\r
109     {0x00000077, (FX_LPCWSTR)L"w",                              0x01},\r
110     {0x00000078, (FX_LPCWSTR)L"x",                              0x01},\r
111     {0x00000079, (FX_LPCWSTR)L"y",                              0x01},\r
112     {0x05eb5b0f, (FX_LPCWSTR)L"pageSpan",               0x01},\r
113     {0x10f1b1bd, (FX_LPCWSTR)L"page",                   0x01},\r
114     {0x3bf1c2a5, (FX_LPCWSTR)L"absPageSpan",    0x01},\r
115     {0x3c752495, (FX_LPCWSTR)L"verify",                 0x0d},\r
116     {0x44c352ad, (FX_LPCWSTR)L"formNodes",              0x01},\r
117     {0x5775c2cc, (FX_LPCWSTR)L"absPageInBatch", 0x01},\r
118     {0x5ee00996, (FX_LPCWSTR)L"setElement",             0x01},\r
119     {0x7033bfd5, (FX_LPCWSTR)L"insert",                 0x03},\r
120     {0x8c5feb32, (FX_LPCWSTR)L"sheetInBatch",   0x01},\r
121     {0x8f3a8379, (FX_LPCWSTR)L"sheet",                  0x01},\r
122     {0x92dada4f, (FX_LPCWSTR)L"saveFilteredXML", 0x01},\r
123     {0x9cab7cae, (FX_LPCWSTR)L"remove",                 0x01},\r
124     {0xa68635f1, (FX_LPCWSTR)L"sign",                   0x61},\r
125     {0xaac241c8, (FX_LPCWSTR)L"isRecordGroup",  0x01},\r
126     {0xd8ed1467, (FX_LPCWSTR)L"clear",                  0x01},\r
127     {0xda12e518, (FX_LPCWSTR)L"append",                 0x01},\r
128     {0xe74f0653, (FX_LPCWSTR)L"absPage",                0x01},\r
129 };\r
130 CXFA_FMSimpleExpression::CXFA_FMSimpleExpression(FX_DWORD line, XFA_FM_TOKEN op)\r
131     : m_line(line),\r
132       m_op(op)\r
133 {\r
134 }\r
135 void CXFA_FMSimpleExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
136 {\r
137 }\r
138 void CXFA_FMSimpleExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)\r
139 {}\r
140 XFA_FM_TOKEN CXFA_FMSimpleExpression::GetOperatorToken()const\r
141 {\r
142     return m_op;\r
143 }\r
144 CXFA_FMNullExpression::CXFA_FMNullExpression(FX_DWORD line)\r
145     : CXFA_FMSimpleExpression(line,  TOKnull)\r
146 {\r
147 }\r
148 void CXFA_FMNullExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
149 {\r
150     javascript << FX_WSTRC(L"null");\r
151 }\r
152 CXFA_FMNumberExpression::CXFA_FMNumberExpression(FX_DWORD line, CFX_WideStringC wsNumber)\r
153     : CXFA_FMSimpleExpression(line, TOKnumber), m_wsNumber(wsNumber)\r
154 {\r
155 }\r
156 void CXFA_FMNumberExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
157 {\r
158     javascript << m_wsNumber;\r
159 }\r
160 CXFA_FMStringExpression::CXFA_FMStringExpression(FX_DWORD line, CFX_WideStringC wsString)\r
161     : CXFA_FMSimpleExpression(line, TOKstring),\r
162       m_wsString(wsString)\r
163 {\r
164 }\r
165 void CXFA_FMStringExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
166 {\r
167     CFX_WideString tempStr = m_wsString;\r
168     if (tempStr.GetLength() > 2) {\r
169         javascript.AppendChar(L'\"');\r
170         FX_WCHAR oneChar;\r
171         for (FX_INT16 i = 1; i < tempStr.GetLength() - 1; i++) {\r
172             oneChar = tempStr[i];\r
173             switch (oneChar) {\r
174                 case L'\"': {\r
175                         i++;\r
176                         javascript << FX_WSTRC(L"\\\"");\r
177                     }\r
178                     break;\r
179                 case 0x0d:\r
180                     break;\r
181                 case 0x0a: {\r
182                         javascript << FX_WSTRC(L"\\n");\r
183                     }\r
184                     break;\r
185                 default: {\r
186                         javascript.AppendChar(oneChar);\r
187                     }\r
188                     break;\r
189             }\r
190         }\r
191         javascript.AppendChar(L'\"');\r
192     } else {\r
193         javascript << tempStr;\r
194     }\r
195 }\r
196 CXFA_FMIdentifierExpressionn::CXFA_FMIdentifierExpressionn(FX_DWORD line, CFX_WideStringC wsIdentifier)\r
197     : CXFA_FMSimpleExpression(line, TOKidentifier), m_wsIdentifier(wsIdentifier)\r
198 {\r
199 }\r
200 void CXFA_FMIdentifierExpressionn::ToJavaScript(CFX_WideTextBuf& javascript)\r
201 {\r
202     CFX_WideString tempStr = m_wsIdentifier;\r
203     if (tempStr.Equal(FX_WSTRC(L"$"))) {\r
204         tempStr = FX_WSTRC(L"this");\r
205     } else if (tempStr.Equal(FX_WSTRC(L"!"))) {\r
206         tempStr = FX_WSTRC(L"xfa.datasets");\r
207     } else if (tempStr.Equal(FX_WSTRC(L"$data"))) {\r
208         tempStr = FX_WSTRC(L"xfa.datasets.data");\r
209     } else if (tempStr.Equal(FX_WSTRC(L"$event"))) {\r
210         tempStr = FX_WSTRC(L"xfa.event");\r
211     } else if (tempStr.Equal(FX_WSTRC(L"$form"))) {\r
212         tempStr = FX_WSTRC(L"xfa.form");\r
213     } else if (tempStr.Equal(FX_WSTRC(L"$host"))) {\r
214         tempStr = FX_WSTRC(L"xfa.host");\r
215     } else if (tempStr.Equal(FX_WSTRC(L"$layout"))) {\r
216         tempStr = FX_WSTRC(L"xfa.layout");\r
217     } else if (tempStr.Equal(FX_WSTRC(L"$template"))) {\r
218         tempStr = FX_WSTRC(L"xfa.template");\r
219     } else if (tempStr[0] == L'!') {\r
220         tempStr = EXCLAMATION_IN_IDENTIFIER + tempStr.Mid(1);\r
221     }\r
222     javascript << tempStr;\r
223     return;\r
224 }\r
225 CXFA_FMUnaryExpression::CXFA_FMUnaryExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp)\r
226     : CXFA_FMSimpleExpression(line, op), m_pExp(pExp)\r
227 {\r
228 }\r
229 CXFA_FMUnaryExpression::~CXFA_FMUnaryExpression()\r
230 {\r
231     if (m_pExp != 0) {\r
232         delete m_pExp;\r
233         m_pExp = 0;\r
234     }\r
235 }\r
236 void CXFA_FMUnaryExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
237 {\r
238 }\r
239 CXFA_FMBinExpression::CXFA_FMBinExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )\r
240     : CXFA_FMSimpleExpression(line, op),\r
241       m_pExp1(pExp1),\r
242       m_pExp2(pExp2)\r
243 {\r
244 }\r
245 CXFA_FMBinExpression::~CXFA_FMBinExpression()\r
246 {\r
247     if (m_pExp1 != 0) {\r
248         delete m_pExp1;\r
249         m_pExp1 = 0;\r
250     }\r
251     if (m_pExp2 != 0) {\r
252         delete m_pExp2;\r
253         m_pExp2 = 0;\r
254     }\r
255 }\r
256 void CXFA_FMBinExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
257 {\r
258 }\r
259 CXFA_FMAssignExpression::CXFA_FMAssignExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )\r
260     : CXFA_FMBinExpression(line, op, pExp1, pExp2)\r
261 {\r
262 }\r
263 void CXFA_FMAssignExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
264 {\r
265     javascript << FX_WSTRC(L"if (");\r
266     javascript << gs_lpStrExpFuncName[ISFMOBJECT];\r
267     javascript << FX_WSTRC(L"(");\r
268     m_pExp1->ToJavaScript(javascript);\r
269     javascript << FX_WSTRC(L"))\n{\n");\r
270     javascript << gs_lpStrExpFuncName[ASSIGN];\r
271     javascript << FX_WSTRC(L"(");\r
272     m_pExp1->ToJavaScript(javascript);\r
273     javascript << FX_WSTRC(L", ");\r
274     m_pExp2->ToJavaScript(javascript);\r
275     javascript << FX_WSTRC(L");\n}\n");\r
276     CFX_WideTextBuf tempExp1;\r
277     m_pExp1->ToJavaScript(tempExp1);\r
278     if (m_pExp1->GetOperatorToken() == TOKidentifier && tempExp1.GetWideString() != FX_WSTRC(L"this")) {\r
279         javascript << FX_WSTRC(L"else\n{\n");\r
280         javascript << tempExp1;\r
281         javascript << FX_WSTRC(L" = ");\r
282         javascript << gs_lpStrExpFuncName[ASSIGN];\r
283         javascript << FX_WSTRC(L"(");\r
284         m_pExp1->ToJavaScript(javascript);\r
285         javascript << FX_WSTRC(L", ");\r
286         m_pExp2->ToJavaScript(javascript);\r
287         javascript << FX_WSTRC(L");\n}\n");\r
288     }\r
289 }\r
290 void CXFA_FMAssignExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)\r
291 {\r
292     javascript << FX_WSTRC(L"if (");\r
293     javascript << gs_lpStrExpFuncName[ISFMOBJECT];\r
294     javascript << FX_WSTRC(L"(");\r
295     m_pExp1->ToJavaScript(javascript);\r
296     javascript << FX_WSTRC(L"))\n{\n");\r
297     javascript << RUNTIMEFUNCTIONRETURNVALUE;\r
298     javascript << FX_WSTRC(L" = ");\r
299     javascript << gs_lpStrExpFuncName[ASSIGN];\r
300     javascript << FX_WSTRC(L"(");\r
301     m_pExp1->ToJavaScript(javascript);\r
302     javascript << FX_WSTRC(L", ");\r
303     m_pExp2->ToJavaScript(javascript);\r
304     javascript << FX_WSTRC(L");\n}\n");\r
305     CFX_WideTextBuf tempExp1;\r
306     m_pExp1->ToJavaScript(tempExp1);\r
307     if (m_pExp1->GetOperatorToken() == TOKidentifier && tempExp1.GetWideString() != FX_WSTRC(L"this")) {\r
308         javascript << FX_WSTRC(L"else\n{\n");\r
309         javascript << RUNTIMEFUNCTIONRETURNVALUE;\r
310         javascript << FX_WSTRC(L" = ");\r
311         javascript << tempExp1;\r
312         javascript << FX_WSTRC(L" = ");\r
313         javascript << gs_lpStrExpFuncName[ASSIGN];\r
314         javascript << FX_WSTRC(L"(");\r
315         m_pExp1->ToJavaScript(javascript);\r
316         javascript << FX_WSTRC(L", ");\r
317         m_pExp2->ToJavaScript(javascript);\r
318         javascript << FX_WSTRC(L");\n}\n");\r
319     }\r
320 }\r
321 CXFA_FMLogicalOrExpression::CXFA_FMLogicalOrExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2)\r
322     : CXFA_FMBinExpression(line, op, pExp1, pExp2)\r
323 {\r
324 }\r
325 void CXFA_FMLogicalOrExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
326 {\r
327     javascript << gs_lpStrExpFuncName[LOGICALOR];\r
328     javascript << FX_WSTRC(L"(");\r
329     m_pExp1->ToJavaScript(javascript);\r
330     javascript << FX_WSTRC(L", ");\r
331     m_pExp2->ToJavaScript(javascript);\r
332     javascript << FX_WSTRC(L")");\r
333 }\r
334 CXFA_FMLogicalAndExpression::CXFA_FMLogicalAndExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )\r
335     : CXFA_FMBinExpression(line, op, pExp1, pExp2)\r
336 {\r
337 }\r
338 void CXFA_FMLogicalAndExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
339 {\r
340     javascript << gs_lpStrExpFuncName[LOGICALAND];\r
341     javascript << FX_WSTRC(L"(");\r
342     m_pExp1->ToJavaScript(javascript);\r
343     javascript << FX_WSTRC(L", ");\r
344     m_pExp2->ToJavaScript(javascript);\r
345     javascript << FX_WSTRC(L")");\r
346 }\r
347 CXFA_FMEqualityExpression::CXFA_FMEqualityExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )\r
348     : CXFA_FMBinExpression(line, op, pExp1, pExp2)\r
349 {\r
350 }\r
351 void CXFA_FMEqualityExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
352 {\r
353     switch(m_op) {\r
354         case TOKeq:\r
355         case TOKkseq:\r
356             javascript << gs_lpStrExpFuncName[EQUALITY];\r
357             break;\r
358         case TOKne:\r
359         case TOKksne:\r
360             javascript << gs_lpStrExpFuncName[NOTEQUALITY];\r
361             break;\r
362         default:\r
363             FXSYS_assert(FALSE);\r
364             break;\r
365     }\r
366     javascript << FX_WSTRC(L"(");\r
367     m_pExp1->ToJavaScript(javascript);\r
368     javascript << FX_WSTRC(L", ");\r
369     m_pExp2->ToJavaScript(javascript);\r
370     javascript << FX_WSTRC(L")");\r
371 }\r
372 CXFA_FMRelationalExpression::CXFA_FMRelationalExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )\r
373     : CXFA_FMBinExpression(line, op, pExp1, pExp2)\r
374 {\r
375 }\r
376 void CXFA_FMRelationalExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
377 {\r
378     switch (m_op) {\r
379         case TOKlt:\r
380         case TOKkslt:\r
381             javascript << gs_lpStrExpFuncName[LESS];\r
382             break;\r
383         case TOKgt:\r
384         case TOKksgt:\r
385             javascript << gs_lpStrExpFuncName[GREATER];\r
386             break;\r
387         case TOKle:\r
388         case TOKksle:\r
389             javascript << gs_lpStrExpFuncName[LESSEQUAL];\r
390             break;\r
391         case TOKge:\r
392         case TOKksge:\r
393             javascript << gs_lpStrExpFuncName[GREATEREQUAL];\r
394             break;\r
395         default:\r
396             FXSYS_assert(FALSE);\r
397             break;\r
398     }\r
399     javascript << FX_WSTRC(L"(");\r
400     m_pExp1->ToJavaScript(javascript);\r
401     javascript << FX_WSTRC(L", ");\r
402     m_pExp2->ToJavaScript(javascript);\r
403     javascript << FX_WSTRC(L")");\r
404 }\r
405 CXFA_FMAdditiveExpression::CXFA_FMAdditiveExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )\r
406     : CXFA_FMBinExpression(line, op, pExp1, pExp2)\r
407 {\r
408 }\r
409 void CXFA_FMAdditiveExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
410 {\r
411     switch (m_op) {\r
412         case TOKplus:\r
413             javascript << gs_lpStrExpFuncName[PLUS];\r
414             break;\r
415         case TOKminus:\r
416             javascript << gs_lpStrExpFuncName[MINUS];\r
417             break;\r
418         default:\r
419             FXSYS_assert(FALSE);\r
420             break;\r
421     }\r
422     javascript << FX_WSTRC(L"(");\r
423     m_pExp1->ToJavaScript(javascript);\r
424     javascript << FX_WSTRC(L", ");\r
425     m_pExp2->ToJavaScript(javascript);\r
426     javascript << FX_WSTRC(L")");\r
427 }\r
428 CXFA_FMMultiplicativeExpression::CXFA_FMMultiplicativeExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )\r
429     : CXFA_FMBinExpression(line, op, pExp1, pExp2)\r
430 {\r
431 }\r
432 void CXFA_FMMultiplicativeExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
433 {\r
434     switch (m_op) {\r
435         case TOKmul:\r
436             javascript << gs_lpStrExpFuncName[MULTIPLE];\r
437             break;\r
438         case TOKdiv:\r
439             javascript << gs_lpStrExpFuncName[DIVIDE];\r
440             break;\r
441         default:\r
442             FXSYS_assert(FALSE);\r
443             break;\r
444     }\r
445     javascript << FX_WSTRC(L"(");\r
446     m_pExp1->ToJavaScript(javascript);\r
447     javascript << FX_WSTRC(L", ");\r
448     m_pExp2->ToJavaScript(javascript);\r
449     javascript << FX_WSTRC(L")");\r
450 }\r
451 CXFA_FMPosExpression::CXFA_FMPosExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExp ) : CXFA_FMUnaryExpression(line, TOKplus, pExp)\r
452 {\r
453 }\r
454 void CXFA_FMPosExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
455 {\r
456     javascript << gs_lpStrExpFuncName[POSITIVE];\r
457     javascript << FX_WSTRC(L"(");\r
458     m_pExp->ToJavaScript(javascript);\r
459     javascript << FX_WSTRC(L")");\r
460 }\r
461 CXFA_FMNegExpression::CXFA_FMNegExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExp )\r
462     : CXFA_FMUnaryExpression(line, TOKminus, pExp)\r
463 {\r
464 }\r
465 void CXFA_FMNegExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
466 {\r
467     javascript << gs_lpStrExpFuncName[NEGATIVE];\r
468     javascript << FX_WSTRC(L"(");\r
469     m_pExp->ToJavaScript(javascript);\r
470     javascript << FX_WSTRC(L")");\r
471 }\r
472 CXFA_FMNotExpression::CXFA_FMNotExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExp )\r
473     : CXFA_FMUnaryExpression(line, TOKksnot, pExp)\r
474 {\r
475 }\r
476 void CXFA_FMNotExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
477 {\r
478     javascript << gs_lpStrExpFuncName[NOT];\r
479     javascript << FX_WSTRC(L"(");\r
480     m_pExp->ToJavaScript(javascript);\r
481     javascript << FX_WSTRC(L")");\r
482 }\r
483 CXFA_FMCallExpression::CXFA_FMCallExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExp, CFX_PtrArray *pArguments, FX_BOOL bIsSomMethod)\r
484     : CXFA_FMUnaryExpression(line, TOKcall, pExp),\r
485       m_pArguments(pArguments),\r
486       m_bIsSomMethod(bIsSomMethod)\r
487 {\r
488 }\r
489 CXFA_FMCallExpression::~CXFA_FMCallExpression()\r
490 {\r
491     if (m_pArguments) {\r
492         FX_INT32 argc = m_pArguments->GetSize();\r
493         FX_INT32 index = 0;\r
494         CXFA_FMSimpleExpression *e = 0;\r
495         while (index < argc) {\r
496             e = (CXFA_FMSimpleExpression *)m_pArguments->GetAt(index);\r
497             delete e;\r
498             index++;\r
499         }\r
500         m_pArguments->RemoveAll();\r
501         delete m_pArguments;\r
502         m_pArguments = 0;\r
503     }\r
504 }\r
505 FX_BOOL CXFA_FMCallExpression::IsBuildInFunc(CFX_WideTextBuf& funcName)\r
506 {\r
507     FX_INT32 iLength = funcName.GetLength();\r
508     FX_UINT32 uHash = FX_HashCode_String_GetW(funcName.GetBuffer(), iLength, TRUE);\r
509     XFA_FMBuildInFunc buildinfunction;\r
510     FX_INT32 iStart = 0, iEnd = (sizeof(buildInFuncs) / sizeof(buildInFuncs[0])) - 1;\r
511     FX_INT32 iMid = (iStart + iEnd) / 2;\r
512     do {\r
513         iMid = (iStart + iEnd) / 2;\r
514         buildinfunction = buildInFuncs[iMid];\r
515         if (uHash == buildinfunction.m_uHash) {\r
516             funcName.Clear();\r
517             funcName << buildinfunction.m_buildinfunc;\r
518             return TRUE;\r
519         } else if (uHash < buildinfunction.m_uHash) {\r
520             iEnd = iMid - 1;\r
521         } else {\r
522             iStart = iMid + 1;\r
523         }\r
524     } while (iStart <= iEnd);\r
525     return FALSE;\r
526 }\r
527 FX_DWORD CXFA_FMCallExpression::IsSomMethodWithObjPara(FX_WSTR methodName)\r
528 {\r
529     FX_INT32 iLength = methodName.GetLength();\r
530     FX_UINT32 uHash = FX_HashCode_String_GetW(methodName.GetPtr(), iLength);\r
531     XFA_FMSOMMethod somMethodWithObjPara;\r
532     FX_DWORD parameters = 0x00;\r
533     FX_INT32 iStart = 0, iEnd = (sizeof(gs_FMSomMethods) / sizeof(gs_FMSomMethods[0])) - 1;\r
534     FX_INT32 iMid = (iStart + iEnd) / 2;\r
535     do {\r
536         iMid = (iStart + iEnd) / 2;\r
537         somMethodWithObjPara = gs_FMSomMethods[iMid];\r
538         if (uHash == somMethodWithObjPara.m_uHash) {\r
539             parameters = somMethodWithObjPara.m_dParameters;\r
540             break;\r
541         } else if (uHash < somMethodWithObjPara.m_uHash) {\r
542             iEnd = iMid - 1;\r
543         } else {\r
544             iStart = iMid + 1;\r
545         }\r
546     } while (iStart <= iEnd);\r
547     return parameters;\r
548 }\r
549 void CXFA_FMCallExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
550 {\r
551     CFX_WideTextBuf funcName;\r
552     m_pExp->ToJavaScript(funcName);\r
553     if (m_bIsSomMethod) {\r
554         javascript << funcName;\r
555         javascript << FX_WSTRC(L"(");\r
556         if (m_pArguments) {\r
557             FX_INT32 argc = m_pArguments->GetSize();\r
558             FX_INT32 index = 0;\r
559             FX_DWORD methodPara = IsSomMethodWithObjPara(funcName.GetWideString());\r
560             if (methodPara > 0) {\r
561                 CXFA_FMSimpleExpression *e = 0;\r
562                 while (index < argc) {\r
563                     if ((methodPara & (0x01 << index)) > 0) {\r
564                         javascript << gs_lpStrExpFuncName[GETFMJSOBJ];\r
565                     } else {\r
566                         javascript << gs_lpStrExpFuncName[GETFMVALUE];\r
567                     }\r
568                     javascript << FX_WSTRC(L"(");\r
569                     e = (CXFA_FMSimpleExpression *)m_pArguments->GetAt(index);\r
570                     e->ToJavaScript(javascript);\r
571                     javascript << FX_WSTRC(L")");\r
572                     if (index + 1 < argc) {\r
573                         javascript << FX_WSTRC(L", ");\r
574                     }\r
575                     index++;\r
576                 }\r
577             } else {\r
578                 CXFA_FMSimpleExpression *e = 0;\r
579                 while (index < argc) {\r
580                     javascript << gs_lpStrExpFuncName[GETFMVALUE];\r
581                     javascript << FX_WSTRC(L"(");\r
582                     e = (CXFA_FMSimpleExpression *)m_pArguments->GetAt(index);\r
583                     e->ToJavaScript(javascript);\r
584                     javascript << FX_WSTRC(L")");\r
585                     if (index + 1 < argc) {\r
586                         javascript << FX_WSTRC(L", ");\r
587                     }\r
588                     index++;\r
589                 }\r
590             }\r
591         }\r
592         javascript << FX_WSTRC(L")");\r
593     } else {\r
594         FX_BOOL isEvalFunc = FALSE;\r
595         FX_BOOL isExistsFunc = FALSE;\r
596         if (IsBuildInFunc(funcName)) {\r
597             if (funcName.GetWideString() == FX_WSTRC(L"Eval")) {\r
598                 isEvalFunc = TRUE;\r
599                 javascript << FX_WSTRC(L"eval.call(this, ");\r
600                 javascript << gs_lpStrExpFuncName[CALL];\r
601                 javascript << FX_WSTRC(L"Translate");\r
602             } else if (funcName.GetWideString() == FX_WSTRC(L"Exists")) {\r
603                 isExistsFunc = TRUE;\r
604                 javascript << gs_lpStrExpFuncName[CALL];\r
605                 javascript << funcName;\r
606             } else {\r
607                 javascript << gs_lpStrExpFuncName[CALL];\r
608                 javascript << funcName;\r
609             }\r
610         } else {\r
611             javascript << funcName;\r
612         }\r
613         javascript << FX_WSTRC(L"(");\r
614         if (isExistsFunc) {\r
615             javascript << FX_WSTRC(L"\n(\nfunction ()\n{\ntry\n{\n");\r
616             if (m_pArguments &&  m_pArguments->GetSize() > 0) {\r
617                 CXFA_FMSimpleExpression *e = (CXFA_FMSimpleExpression *)m_pArguments->GetAt(0);\r
618                 javascript << FX_WSTRC(L"return ");\r
619                 e->ToJavaScript(javascript);\r
620                 javascript << FX_WSTRC(L";\n}\n");\r
621             } else {\r
622                 javascript << FX_WSTRC(L"return 0;\n}\n");\r
623             }\r
624             javascript << FX_WSTRC(L"catch(accessExceptions)\n{\nreturn 0;\n}\n}\n).call(this)\n");\r
625         } else if (m_pArguments) {\r
626             FX_INT32 argc = m_pArguments->GetSize();\r
627             FX_INT32 index = 0;\r
628             CXFA_FMSimpleExpression *e = 0;\r
629             while (index < argc) {\r
630                 e = (CXFA_FMSimpleExpression *)m_pArguments->GetAt(index);\r
631                 e->ToJavaScript(javascript);\r
632                 if (index + 1 < argc) {\r
633                     javascript << FX_WSTRC(L", ");\r
634                 }\r
635                 index++;\r
636             }\r
637         }\r
638         javascript << FX_WSTRC(L")");\r
639         if (isEvalFunc) {\r
640             javascript << FX_WSTRC(L")");\r
641         }\r
642     }\r
643 }\r
644 CXFA_FMDotAccessorExpression::CXFA_FMDotAccessorExpression(FX_DWORD line, CXFA_FMSimpleExpression *pAccessor, XFA_FM_TOKEN op,\r
645         CFX_WideStringC wsIdentifier, CXFA_FMSimpleExpression *pIndexExp)\r
646     : CXFA_FMBinExpression(line, op, pAccessor, pIndexExp),\r
647       m_wsIdentifier(wsIdentifier)\r
648 {}\r
649 void CXFA_FMDotAccessorExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
650 {\r
651     javascript << gs_lpStrExpFuncName[DOT];\r
652     javascript << FX_WSTRC(L"(");\r
653     if(m_pExp1) {\r
654         m_pExp1->ToJavaScript(javascript);\r
655     } else {\r
656         javascript << FX_WSTRC(L"null");\r
657     }\r
658     javascript << FX_WSTRC(L", ");\r
659     javascript << FX_WSTRC(L"\"");\r
660     if (m_pExp1 && m_pExp1->GetOperatorToken() == TOKidentifier) {\r
661         m_pExp1->ToJavaScript(javascript);\r
662     }\r
663     javascript << FX_WSTRC(L"\", ");\r
664     if (m_op == TOKdotscream) {\r
665         javascript << FX_WSTRC(L"\"#");\r
666         javascript << m_wsIdentifier;\r
667         javascript << FX_WSTRC(L"\", ");\r
668     } else if (m_op == TOKdotstar) {\r
669         javascript << FX_WSTRC(L"\"*\", ");\r
670     } else if (m_op == TOKcall) {\r
671         javascript << FX_WSTRC(L"\"\", ");\r
672     } else {\r
673         javascript << FX_WSTRC(L"\"");\r
674         javascript << m_wsIdentifier;\r
675         javascript << FX_WSTRC(L"\", ");\r
676     }\r
677     m_pExp2->ToJavaScript(javascript);\r
678     javascript << FX_WSTRC(L")");\r
679 }\r
680 CXFA_FMIndexExpression::CXFA_FMIndexExpression(FX_DWORD line, XFA_FM_AccessorIndex accessorIndex,\r
681         CXFA_FMSimpleExpression *pIndexExp, FX_BOOL bIsStarIndex)\r
682     : CXFA_FMUnaryExpression(line, TOKlbracket, pIndexExp),\r
683       m_accessorIndex(accessorIndex),\r
684       m_bIsStarIndex(bIsStarIndex)\r
685 {}\r
686 void CXFA_FMIndexExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
687 {\r
688     switch(m_accessorIndex) {\r
689         case ACCESSOR_NO_INDEX:\r
690             javascript << FX_WSTRC(L"0");\r
691             break;\r
692         case ACCESSOR_NO_RELATIVEINDEX:\r
693             javascript << FX_WSTRC(L"1");\r
694             break;\r
695         case ACCESSOR_POSITIVE_INDEX:\r
696             javascript << FX_WSTRC(L"2");\r
697             break;\r
698         case ACCESSOR_NEGATIVE_INDEX:\r
699             javascript << FX_WSTRC(L"3");\r
700             break;\r
701         default:\r
702             javascript << FX_WSTRC(L"0");\r
703     }\r
704     if (!m_bIsStarIndex) {\r
705         javascript << FX_WSTRC(L", ");\r
706         if (m_pExp) {\r
707             m_pExp->ToJavaScript(javascript);\r
708         } else {\r
709             javascript << FX_WSTRC(L"0");\r
710         }\r
711     }\r
712 }\r
713 CXFA_FMDotDotAccessorExpression::CXFA_FMDotDotAccessorExpression(FX_DWORD line, CXFA_FMSimpleExpression *pAccessor, XFA_FM_TOKEN op,\r
714         CFX_WideStringC wsIdentifier, CXFA_FMSimpleExpression *pIndexExp)\r
715     : CXFA_FMBinExpression(line, op, pAccessor, pIndexExp),\r
716       m_wsIdentifier(wsIdentifier)\r
717 {}\r
718 void CXFA_FMDotDotAccessorExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
719 {\r
720     javascript << gs_lpStrExpFuncName[DOTDOT];\r
721     javascript << FX_WSTRC(L"(");\r
722     m_pExp1->ToJavaScript(javascript);\r
723     javascript << FX_WSTRC(L", ");\r
724     javascript << FX_WSTRC(L"\"");\r
725     if (m_pExp1 && m_pExp1->GetOperatorToken() == TOKidentifier) {\r
726         m_pExp1->ToJavaScript(javascript);\r
727     }\r
728     javascript << FX_WSTRC(L"\", ");\r
729     javascript << FX_WSTRC(L"\"");\r
730     javascript << m_wsIdentifier;\r
731     javascript << FX_WSTRC(L"\", ");\r
732     m_pExp2->ToJavaScript(javascript);\r
733     javascript << FX_WSTRC(L")");\r
734 }\r
735 CXFA_FMMethodCallExpression::CXFA_FMMethodCallExpression(FX_DWORD line, CXFA_FMSimpleExpression *pAccessorExp1, CXFA_FMSimpleExpression *pCallExp)\r
736     : CXFA_FMBinExpression(line, TOKdot, pAccessorExp1, pCallExp)\r
737 {\r
738 }\r
739 void CXFA_FMMethodCallExpression::ToJavaScript(CFX_WideTextBuf& javascript)\r
740 {\r
741     javascript << FX_WSTRC(L"(\nfunction ()\n{\n");\r
742     javascript << FX_WSTRC(L"var method_return_value = null;\n");\r
743     javascript << FX_WSTRC(L"var accessor_object = ");\r
744     m_pExp1->ToJavaScript(javascript);\r
745     javascript << FX_WSTRC(L";\n");\r
746     javascript << FX_WSTRC(L"if (");\r
747     javascript << gs_lpStrExpFuncName[ISFMARRAY];\r
748     javascript << FX_WSTRC(L"(accessor_object))\n{\n");\r
749     javascript << FX_WSTRC(L"for(var index = accessor_object.length - 1; index > 1; index--)\n{\n");\r
750     javascript << FX_WSTRC(L"method_return_value = accessor_object[index].");\r
751     m_pExp2->ToJavaScript(javascript);\r
752     javascript << FX_WSTRC(L";\n}\n}\n");\r
753     javascript << FX_WSTRC(L"else\n{\nmethod_return_value = accessor_object.");\r
754     m_pExp2->ToJavaScript(javascript);\r
755     javascript << FX_WSTRC(L";\n}\n");\r
756     javascript << FX_WSTRC(L"return method_return_value;\n");\r
757     javascript << FX_WSTRC(L"}\n).call(this)");\r
758 }\r