Home | History | Annotate | Download | only in fm2js
      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 };
     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 };
     97 CXFA_FMSimpleExpression::CXFA_FMSimpleExpression(FX_DWORD line, XFA_FM_TOKEN op)
     98     : m_line(line), m_op(op) {}
     99 void CXFA_FMSimpleExpression::ToJavaScript(CFX_WideTextBuf& javascript) {}
    100 void CXFA_FMSimpleExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {}
    101 XFA_FM_TOKEN CXFA_FMSimpleExpression::GetOperatorToken() const {
    102   return m_op;
    103 }
    104 CXFA_FMNullExpression::CXFA_FMNullExpression(FX_DWORD line)
    105     : CXFA_FMSimpleExpression(line, TOKnull) {}
    106 void CXFA_FMNullExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
    107   javascript << FX_WSTRC(L"null");
    108 }
    109 CXFA_FMNumberExpression::CXFA_FMNumberExpression(FX_DWORD line,
    110                                                  CFX_WideStringC wsNumber)
    111     : CXFA_FMSimpleExpression(line, TOKnumber), m_wsNumber(wsNumber) {}
    112 void CXFA_FMNumberExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
    113   javascript << m_wsNumber;
    114 }
    115 CXFA_FMStringExpression::CXFA_FMStringExpression(FX_DWORD line,
    116                                                  CFX_WideStringC wsString)
    117     : CXFA_FMSimpleExpression(line, TOKstring), m_wsString(wsString) {}
    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 }
    143 CXFA_FMIdentifierExpressionn::CXFA_FMIdentifierExpressionn(
    144     FX_DWORD line,
    145     CFX_WideStringC wsIdentifier)
    146     : CXFA_FMSimpleExpression(line, TOKidentifier),
    147       m_wsIdentifier(wsIdentifier) {}
    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 }
    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) {}
    176 CXFA_FMUnaryExpression::~CXFA_FMUnaryExpression() {
    177   if (m_pExp != 0) {
    178     delete m_pExp;
    179     m_pExp = 0;
    180   }
    181 }
    182 void CXFA_FMUnaryExpression::ToJavaScript(CFX_WideTextBuf& javascript) {}
    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) {}
    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 }
    198 void CXFA_FMBinExpression::ToJavaScript(CFX_WideTextBuf& javascript) {}
    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) {}
    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 }
    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 }
    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) {}
    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 }
    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) {}
    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 }
    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) {}
    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 }
    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) {}
    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 }
    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) {}
    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 }
    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) {}
    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 }
    399 CXFA_FMPosExpression::CXFA_FMPosExpression(FX_DWORD line,
    400                                            CXFA_FMSimpleExpression* pExp)
    401     : CXFA_FMUnaryExpression(line, TOKplus, pExp) {}
    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 }
    408 CXFA_FMNegExpression::CXFA_FMNegExpression(FX_DWORD line,
    409                                            CXFA_FMSimpleExpression* pExp)
    410     : CXFA_FMUnaryExpression(line, TOKminus, pExp) {}
    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 }
    417 CXFA_FMNotExpression::CXFA_FMNotExpression(FX_DWORD line,
    418                                            CXFA_FMSimpleExpression* pExp)
    419     : CXFA_FMUnaryExpression(line, TOKksnot, pExp) {}
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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) {}
    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 }
    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) {}
    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 }
    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) {}
    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 }
    687 CXFA_FMMethodCallExpression::CXFA_FMMethodCallExpression(
    688     FX_DWORD line,
    689     CXFA_FMSimpleExpression* pAccessorExp1,
    690     CXFA_FMSimpleExpression* pCallExp)
    691     : CXFA_FMBinExpression(line, TOKdot, pAccessorExp1, pCallExp) {}
    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