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