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