diff options
author | Dan Sinclair <dsinclair@chromium.org> | 2017-05-16 15:14:02 -0400 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-05-17 03:08:06 +0000 |
commit | 2e9d47ac2c9a4ebf0821d10c766fafa85e6d3cb9 (patch) | |
tree | 212ca832851067eb5f40cf49c1dc2ffe81a24ada /xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp | |
parent | 7876609b3540137663d48282ad94ba42a3749e73 (diff) | |
download | pdfium-2e9d47ac2c9a4ebf0821d10c766fafa85e6d3cb9.tar.xz |
Rename formcalc files to better match contents
Most files match the contents. The expression files are named to match
their base type even though they contain all the expression
subclasses.
Change-Id: I3b7705c7b206a9fa1afae8b677f765e8b788e84d
Reviewed-on: https://pdfium-review.googlesource.com/5492
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: Nicolás Peña <npm@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Diffstat (limited to 'xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp')
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp | 854 |
1 files changed, 854 insertions, 0 deletions
diff --git a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp new file mode 100644 index 0000000000..3b4dc7017d --- /dev/null +++ b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp @@ -0,0 +1,854 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fxfa/fm2js/cxfa_fmsimpleexpression.h" + +#include <utility> + +#include "core/fxcrt/fx_extension.h" + +namespace { + +const wchar_t* const gs_lpStrExpFuncName[] = { + L"foxit_xfa_formcalc_runtime.assign_value_operator", + L"foxit_xfa_formcalc_runtime.logical_or_operator", + L"foxit_xfa_formcalc_runtime.logical_and_operator", + L"foxit_xfa_formcalc_runtime.equality_operator", + L"foxit_xfa_formcalc_runtime.notequality_operator", + L"foxit_xfa_formcalc_runtime.less_operator", + L"foxit_xfa_formcalc_runtime.lessequal_operator", + L"foxit_xfa_formcalc_runtime.greater_operator", + L"foxit_xfa_formcalc_runtime.greaterequal_operator", + L"foxit_xfa_formcalc_runtime.plus_operator", + L"foxit_xfa_formcalc_runtime.minus_operator", + L"foxit_xfa_formcalc_runtime.multiple_operator", + L"foxit_xfa_formcalc_runtime.divide_operator", + L"foxit_xfa_formcalc_runtime.positive_operator", + L"foxit_xfa_formcalc_runtime.negative_operator", + L"foxit_xfa_formcalc_runtime.logical_not_operator", + L"foxit_xfa_formcalc_runtime.", + L"foxit_xfa_formcalc_runtime.dot_accessor", + L"foxit_xfa_formcalc_runtime.dotdot_accessor", + L"foxit_xfa_formcalc_runtime.concat_fm_object", + L"foxit_xfa_formcalc_runtime.is_fm_object", + L"foxit_xfa_formcalc_runtime.is_fm_array", + L"foxit_xfa_formcalc_runtime.get_fm_value", + L"foxit_xfa_formcalc_runtime.get_fm_jsobj", + L"foxit_xfa_formcalc_runtime.fm_var_filter", +}; + +struct XFA_FMBuildInFunc { + uint32_t m_uHash; + const wchar_t* m_buildinfunc; +}; + +const XFA_FMBuildInFunc g_BuildInFuncs[] = { + {0x0001f1f5, L"At"}, {0x00020b9c, L"FV"}, + {0x00021aef, L"If"}, {0x00023ee6, L"PV"}, + {0x04b5c9ee, L"Encode"}, {0x08e96685, L"DateFmt"}, + {0x09f99db6, L"Abs"}, {0x09f9e583, L"Apr"}, + {0x09fa043e, L"Avg"}, {0x0a9782a0, L"Get"}, + {0x0b1b09df, L"Len"}, {0x0b3543a6, L"Max"}, + {0x0b356ca4, L"Min"}, {0x0b358b60, L"Mod"}, + {0x0b4fded4, L"NPV"}, {0x0b846bf1, L"Pmt"}, + {0x0b8494f9, L"Put"}, {0x0bb8df5d, L"Ref"}, + {0x0bd37a99, L"Str"}, {0x0bd37fb5, L"Sum"}, + {0x1048469b, L"Cterm"}, {0x11e03660, L"Exists"}, + {0x126236e6, L"Post"}, {0x127c6661, L"PPmt"}, + {0x193ade3e, L"Right"}, {0x1ec8ab2c, L"Rate"}, + {0x20e476dc, L"IsoTime2Num"}, {0x23eb6816, L"TimeFmt"}, + {0x24fb17b0, L"LocalDateFmt"}, {0x28dee6e9, L"Format"}, + {0x2d0890b8, L"Term"}, {0x2d71b00f, L"Time"}, + {0x2f890fb1, L"Num2Time"}, {0x3767511d, L"Ceil"}, + {0x3ffd1941, L"LocalTimeFmt"}, {0x442f68c8, L"Round"}, + {0x46fd1128, L"Eval"}, {0x4d629440, L"Date2Num"}, + {0x4dcf25f8, L"Concat"}, {0x4e00255d, L"UnitValue"}, + {0x55a5cc29, L"Lower"}, {0x5e43e04c, L"WordNum"}, + {0x620ce6ba, L"Ipmt"}, {0x6f544d49, L"Count"}, + {0x7e241013, L"Within"}, {0x9b9a6e2b, L"IsoDate2Num"}, + {0xb2c941c2, L"UnitType"}, {0xb598a1f7, L"Uuid"}, + {0xbde9abde, L"Date"}, {0xc0010b80, L"Num2Date"}, + {0xc1f6144c, L"Upper"}, {0xc44028f7, L"Oneof"}, + {0xc62c1b2c, L"Space"}, {0xd0ff50f9, L"HasValue"}, + {0xd1537042, L"Floor"}, {0xd2ac9cf1, L"Time2Num"}, + {0xd907aee5, L"Num2GMTime"}, {0xdf24f7c4, L"Decode"}, + {0xe2664803, L"Substr"}, {0xe3e7b528, L"Stuff"}, + {0xe6792d4e, L"Rtrim"}, {0xe8c23f5b, L"Parse"}, + {0xea18d121, L"Choose"}, {0xebfef69c, L"Replace"}, + {0xf5ad782b, L"Left"}, {0xf7bb2248, L"Ltrim"}, +}; + +struct XFA_FMSOMMethod { + uint32_t m_uHash; + const wchar_t* m_wsSomMethodName; + uint32_t m_dParameters; +}; +const XFA_FMSOMMethod gs_FMSomMethods[] = { + {0x00000068, L"h", 0x01}, + {0x00000077, L"w", 0x01}, + {0x00000078, L"x", 0x01}, + {0x00000079, L"y", 0x01}, + {0x05eb5b0f, L"pageSpan", 0x01}, + {0x10f1b1bd, L"page", 0x01}, + {0x3bf1c2a5, L"absPageSpan", 0x01}, + {0x3c752495, L"verify", 0x0d}, + {0x44c352ad, L"formNodes", 0x01}, + {0x5775c2cc, L"absPageInBatch", 0x01}, + {0x5ee00996, L"setElement", 0x01}, + {0x7033bfd5, L"insert", 0x03}, + {0x8c5feb32, L"sheetInBatch", 0x01}, + {0x8f3a8379, L"sheet", 0x01}, + {0x92dada4f, L"saveFilteredXML", 0x01}, + {0x9cab7cae, L"remove", 0x01}, + {0xa68635f1, L"sign", 0x61}, + {0xaac241c8, L"isRecordGroup", 0x01}, + {0xd8ed1467, L"clear", 0x01}, + {0xda12e518, L"append", 0x01}, + {0xe74f0653, L"absPage", 0x01}, +}; + +} // namespace + +CFX_WideStringC XFA_FM_EXPTypeToString( + XFA_FM_SimpleExpressionType simpleExpType) { + return gs_lpStrExpFuncName[simpleExpType]; +} + +CXFA_FMSimpleExpression::CXFA_FMSimpleExpression(uint32_t line, XFA_FM_TOKEN op) + : m_line(line), m_op(op) {} + +bool CXFA_FMSimpleExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + return true; +} + +bool CXFA_FMSimpleExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + return true; +} + +XFA_FM_TOKEN CXFA_FMSimpleExpression::GetOperatorToken() const { + return m_op; +} + +CXFA_FMNullExpression::CXFA_FMNullExpression(uint32_t line) + : CXFA_FMSimpleExpression(line, TOKnull) {} + +bool CXFA_FMNullExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + javascript << L"null"; + return true; +} + +CXFA_FMNumberExpression::CXFA_FMNumberExpression(uint32_t line, + CFX_WideStringC wsNumber) + : CXFA_FMSimpleExpression(line, TOKnumber), m_wsNumber(wsNumber) {} + +CXFA_FMNumberExpression::~CXFA_FMNumberExpression() {} + +bool CXFA_FMNumberExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + javascript << m_wsNumber; + return true; +} + +CXFA_FMStringExpression::CXFA_FMStringExpression(uint32_t line, + CFX_WideStringC wsString) + : CXFA_FMSimpleExpression(line, TOKstring), m_wsString(wsString) {} + +CXFA_FMStringExpression::~CXFA_FMStringExpression() {} + +bool CXFA_FMStringExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CFX_WideString tempStr(m_wsString); + if (tempStr.GetLength() <= 2) { + javascript << tempStr; + return true; + } + javascript.AppendChar(L'\"'); + for (int32_t i = 1; i < tempStr.GetLength() - 1; i++) { + wchar_t oneChar = tempStr[i]; + switch (oneChar) { + case L'\"': + i++; + javascript << L"\\\""; + break; + case 0x0d: + break; + case 0x0a: + javascript << L"\\n"; + break; + default: + javascript.AppendChar(oneChar); + break; + } + } + javascript.AppendChar(L'\"'); + return true; +} + +CXFA_FMIdentifierExpression::CXFA_FMIdentifierExpression( + uint32_t line, + CFX_WideStringC wsIdentifier) + : CXFA_FMSimpleExpression(line, TOKidentifier), + m_wsIdentifier(wsIdentifier) {} + +CXFA_FMIdentifierExpression::~CXFA_FMIdentifierExpression() {} + +bool CXFA_FMIdentifierExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CFX_WideString tempStr(m_wsIdentifier); + if (tempStr == L"$") { + tempStr = L"this"; + } else if (tempStr == L"!") { + tempStr = L"xfa.datasets"; + } else if (tempStr == L"$data") { + tempStr = L"xfa.datasets.data"; + } else if (tempStr == L"$event") { + tempStr = L"xfa.event"; + } else if (tempStr == L"$form") { + tempStr = L"xfa.form"; + } else if (tempStr == L"$host") { + tempStr = L"xfa.host"; + } else if (tempStr == L"$layout") { + tempStr = L"xfa.layout"; + } else if (tempStr == L"$template") { + tempStr = L"xfa.template"; + } else if (tempStr[0] == L'!') { + tempStr = EXCLAMATION_IN_IDENTIFIER + tempStr.Mid(1); + } + javascript << tempStr; + return true; +} + +CXFA_FMUnaryExpression::CXFA_FMUnaryExpression( + uint32_t line, + XFA_FM_TOKEN op, + std::unique_ptr<CXFA_FMSimpleExpression> pExp) + : CXFA_FMSimpleExpression(line, op), m_pExp(std::move(pExp)) {} + +CXFA_FMUnaryExpression::~CXFA_FMUnaryExpression() {} + +bool CXFA_FMUnaryExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + return true; +} + +CXFA_FMBinExpression::CXFA_FMBinExpression( + uint32_t line, + XFA_FM_TOKEN op, + std::unique_ptr<CXFA_FMSimpleExpression> pExp1, + std::unique_ptr<CXFA_FMSimpleExpression> pExp2) + : CXFA_FMSimpleExpression(line, op), + m_pExp1(std::move(pExp1)), + m_pExp2(std::move(pExp2)) {} + +CXFA_FMBinExpression::~CXFA_FMBinExpression() {} + +bool CXFA_FMBinExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + return true; +} + +CXFA_FMAssignExpression::CXFA_FMAssignExpression( + uint32_t line, + XFA_FM_TOKEN op, + std::unique_ptr<CXFA_FMSimpleExpression> pExp1, + std::unique_ptr<CXFA_FMSimpleExpression> pExp2) + : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} + +bool CXFA_FMAssignExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + javascript << L"if ("; + javascript << gs_lpStrExpFuncName[ISFMOBJECT]; + javascript << L"("; + CFX_WideTextBuf tempExp1; + if (!m_pExp1->ToJavaScript(tempExp1)) + return false; + javascript << tempExp1; + javascript << L"))\n{\n"; + javascript << gs_lpStrExpFuncName[ASSIGN]; + javascript << L"("; + javascript << tempExp1; + javascript << L", "; + if (CFXA_IsTooBig(javascript)) + return false; + + CFX_WideTextBuf tempExp2; + if (!m_pExp2->ToJavaScript(tempExp2)) + return false; + javascript << tempExp2; + javascript << L");\n}\n"; + if (m_pExp1->GetOperatorToken() == TOKidentifier && + tempExp1.AsStringC() != L"this") { + javascript << L"else\n{\n"; + javascript << tempExp1; + javascript << L" = "; + javascript << gs_lpStrExpFuncName[ASSIGN]; + javascript << L"("; + javascript << tempExp1; + javascript << L", "; + javascript << tempExp2; + javascript << L");\n}\n"; + } + return !CFXA_IsTooBig(javascript); +} + +bool CXFA_FMAssignExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + javascript << L"if ("; + javascript << gs_lpStrExpFuncName[ISFMOBJECT]; + javascript << L"("; + CFX_WideTextBuf tempExp1; + if (!m_pExp1->ToJavaScript(tempExp1)) + return false; + javascript << tempExp1; + javascript << L"))\n{\n"; + javascript << RUNTIMEFUNCTIONRETURNVALUE; + javascript << L" = "; + javascript << gs_lpStrExpFuncName[ASSIGN]; + javascript << L"("; + javascript << tempExp1; + javascript << L", "; + if (CFXA_IsTooBig(javascript)) + return false; + + CFX_WideTextBuf tempExp2; + if (!m_pExp2->ToJavaScript(tempExp2)) + return false; + javascript << tempExp2; + javascript << L");\n}\n"; + if (m_pExp1->GetOperatorToken() == TOKidentifier && + tempExp1.AsStringC() != L"this") { + javascript << L"else\n{\n"; + javascript << RUNTIMEFUNCTIONRETURNVALUE; + javascript << L" = "; + javascript << tempExp1; + javascript << L" = "; + javascript << gs_lpStrExpFuncName[ASSIGN]; + javascript << L"("; + javascript << tempExp1; + javascript << L", "; + javascript << tempExp2; + javascript << L");\n}\n"; + } + return !CFXA_IsTooBig(javascript); +} + +CXFA_FMLogicalOrExpression::CXFA_FMLogicalOrExpression( + uint32_t line, + XFA_FM_TOKEN op, + std::unique_ptr<CXFA_FMSimpleExpression> pExp1, + std::unique_ptr<CXFA_FMSimpleExpression> pExp2) + : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} + +bool CXFA_FMLogicalOrExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + javascript << gs_lpStrExpFuncName[LOGICALOR]; + javascript << L"("; + if (!m_pExp1->ToJavaScript(javascript)) + return false; + javascript << L", "; + if (!m_pExp2->ToJavaScript(javascript)) + return false; + javascript << L")"; + return !CFXA_IsTooBig(javascript); +} + +CXFA_FMLogicalAndExpression::CXFA_FMLogicalAndExpression( + uint32_t line, + XFA_FM_TOKEN op, + std::unique_ptr<CXFA_FMSimpleExpression> pExp1, + std::unique_ptr<CXFA_FMSimpleExpression> pExp2) + : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} + +bool CXFA_FMLogicalAndExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + javascript << gs_lpStrExpFuncName[LOGICALAND]; + javascript << L"("; + if (!m_pExp1->ToJavaScript(javascript)) + return false; + javascript << L", "; + if (!m_pExp2->ToJavaScript(javascript)) + return false; + javascript << L")"; + return !CFXA_IsTooBig(javascript); +} + +CXFA_FMEqualityExpression::CXFA_FMEqualityExpression( + uint32_t line, + XFA_FM_TOKEN op, + std::unique_ptr<CXFA_FMSimpleExpression> pExp1, + std::unique_ptr<CXFA_FMSimpleExpression> pExp2) + : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} + +bool CXFA_FMEqualityExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + switch (m_op) { + case TOKeq: + case TOKkseq: + javascript << gs_lpStrExpFuncName[EQUALITY]; + break; + case TOKne: + case TOKksne: + javascript << gs_lpStrExpFuncName[NOTEQUALITY]; + break; + default: + ASSERT(false); + break; + } + javascript << L"("; + if (!m_pExp1->ToJavaScript(javascript)) + return false; + javascript << L", "; + if (!m_pExp2->ToJavaScript(javascript)) + return false; + javascript << L")"; + return !CFXA_IsTooBig(javascript); +} + +CXFA_FMRelationalExpression::CXFA_FMRelationalExpression( + uint32_t line, + XFA_FM_TOKEN op, + std::unique_ptr<CXFA_FMSimpleExpression> pExp1, + std::unique_ptr<CXFA_FMSimpleExpression> pExp2) + : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} + +bool CXFA_FMRelationalExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + switch (m_op) { + case TOKlt: + case TOKkslt: + javascript << gs_lpStrExpFuncName[LESS]; + break; + case TOKgt: + case TOKksgt: + javascript << gs_lpStrExpFuncName[GREATER]; + break; + case TOKle: + case TOKksle: + javascript << gs_lpStrExpFuncName[LESSEQUAL]; + break; + case TOKge: + case TOKksge: + javascript << gs_lpStrExpFuncName[GREATEREQUAL]; + break; + default: + ASSERT(false); + break; + } + javascript << L"("; + if (!m_pExp1->ToJavaScript(javascript)) + return false; + javascript << L", "; + if (!m_pExp2->ToJavaScript(javascript)) + return false; + javascript << L")"; + return !CFXA_IsTooBig(javascript); +} + +CXFA_FMAdditiveExpression::CXFA_FMAdditiveExpression( + uint32_t line, + XFA_FM_TOKEN op, + std::unique_ptr<CXFA_FMSimpleExpression> pExp1, + std::unique_ptr<CXFA_FMSimpleExpression> pExp2) + : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} + +bool CXFA_FMAdditiveExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + switch (m_op) { + case TOKplus: + javascript << gs_lpStrExpFuncName[PLUS]; + break; + case TOKminus: + javascript << gs_lpStrExpFuncName[MINUS]; + break; + default: + ASSERT(false); + break; + } + javascript << L"("; + if (!m_pExp1->ToJavaScript(javascript)) + return false; + javascript << L", "; + if (!m_pExp2->ToJavaScript(javascript)) + return false; + javascript << L")"; + return !CFXA_IsTooBig(javascript); +} + +CXFA_FMMultiplicativeExpression::CXFA_FMMultiplicativeExpression( + uint32_t line, + XFA_FM_TOKEN op, + std::unique_ptr<CXFA_FMSimpleExpression> pExp1, + std::unique_ptr<CXFA_FMSimpleExpression> pExp2) + : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} + +bool CXFA_FMMultiplicativeExpression::ToJavaScript( + CFX_WideTextBuf& javascript) { + switch (m_op) { + case TOKmul: + javascript << gs_lpStrExpFuncName[MULTIPLE]; + break; + case TOKdiv: + javascript << gs_lpStrExpFuncName[DIVIDE]; + break; + default: + ASSERT(false); + break; + } + javascript << L"("; + if (!m_pExp1->ToJavaScript(javascript)) + return false; + javascript << L", "; + if (!m_pExp2->ToJavaScript(javascript)) + return false; + javascript << L")"; + return !CFXA_IsTooBig(javascript); +} + +CXFA_FMPosExpression::CXFA_FMPosExpression( + uint32_t line, + std::unique_ptr<CXFA_FMSimpleExpression> pExp) + : CXFA_FMUnaryExpression(line, TOKplus, std::move(pExp)) {} + +bool CXFA_FMPosExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + javascript << gs_lpStrExpFuncName[POSITIVE]; + javascript << L"("; + if (!m_pExp->ToJavaScript(javascript)) + return false; + javascript << L")"; + return true; +} + +CXFA_FMNegExpression::CXFA_FMNegExpression( + uint32_t line, + std::unique_ptr<CXFA_FMSimpleExpression> pExp) + : CXFA_FMUnaryExpression(line, TOKminus, std::move(pExp)) {} + +bool CXFA_FMNegExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + javascript << gs_lpStrExpFuncName[NEGATIVE]; + javascript << L"("; + if (!m_pExp->ToJavaScript(javascript)) + return false; + javascript << L")"; + return true; +} + +CXFA_FMNotExpression::CXFA_FMNotExpression( + uint32_t line, + std::unique_ptr<CXFA_FMSimpleExpression> pExp) + : CXFA_FMUnaryExpression(line, TOKksnot, std::move(pExp)) {} + +bool CXFA_FMNotExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + javascript << gs_lpStrExpFuncName[NOT]; + javascript << L"("; + if (!m_pExp->ToJavaScript(javascript)) + return false; + javascript << L")"; + return true; +} + +CXFA_FMCallExpression::CXFA_FMCallExpression( + uint32_t line, + std::unique_ptr<CXFA_FMSimpleExpression> pExp, + std::vector<std::unique_ptr<CXFA_FMSimpleExpression>>&& pArguments, + bool bIsSomMethod) + : CXFA_FMUnaryExpression(line, TOKcall, std::move(pExp)), + m_bIsSomMethod(bIsSomMethod), + m_Arguments(std::move(pArguments)) {} + +CXFA_FMCallExpression::~CXFA_FMCallExpression() {} + +bool CXFA_FMCallExpression::IsBuildInFunc(CFX_WideTextBuf* funcName) { + uint32_t uHash = FX_HashCode_GetW(funcName->AsStringC(), true); + const XFA_FMBuildInFunc* pEnd = g_BuildInFuncs + FX_ArraySize(g_BuildInFuncs); + const XFA_FMBuildInFunc* pFunc = + std::lower_bound(g_BuildInFuncs, pEnd, uHash, + [](const XFA_FMBuildInFunc& func, uint32_t hash) { + return func.m_uHash < hash; + }); + if (pFunc < pEnd && uHash == pFunc->m_uHash) { + funcName->Clear(); + *funcName << pFunc->m_buildinfunc; + return true; + } + return false; +} + +uint32_t CXFA_FMCallExpression::IsMethodWithObjParam( + const CFX_WideStringC& methodName) { + uint32_t uHash = FX_HashCode_GetW(methodName, false); + XFA_FMSOMMethod somMethodWithObjPara; + uint32_t parameters = 0x00; + int32_t iStart = 0, + iEnd = (sizeof(gs_FMSomMethods) / sizeof(gs_FMSomMethods[0])) - 1; + int32_t iMid = (iStart + iEnd) / 2; + do { + iMid = (iStart + iEnd) / 2; + somMethodWithObjPara = gs_FMSomMethods[iMid]; + if (uHash == somMethodWithObjPara.m_uHash) { + parameters = somMethodWithObjPara.m_dParameters; + break; + } else if (uHash < somMethodWithObjPara.m_uHash) { + iEnd = iMid - 1; + } else { + iStart = iMid + 1; + } + } while (iStart <= iEnd); + return parameters; +} + +bool CXFA_FMCallExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CFX_WideTextBuf funcName; + if (!m_pExp->ToJavaScript(funcName)) + return false; + if (m_bIsSomMethod) { + javascript << funcName; + javascript << L"("; + uint32_t methodPara = IsMethodWithObjParam(funcName.AsStringC()); + if (methodPara > 0) { + for (size_t i = 0; i < m_Arguments.size(); ++i) { + // Currently none of our expressions use objects for a parameter over + // the 6th. Make sure we don't overflow the shift when doing this + // check. If we ever need more the 32 object params we can revisit. + if (i < 32 && (methodPara & (0x01 << i)) > 0) { + javascript << gs_lpStrExpFuncName[GETFMJSOBJ]; + } else { + javascript << gs_lpStrExpFuncName[GETFMVALUE]; + } + javascript << L"("; + const auto& expr = m_Arguments[i]; + if (!expr->ToJavaScript(javascript)) + return false; + javascript << L")"; + if (i + 1 < m_Arguments.size()) { + javascript << L", "; + } + if (CFXA_IsTooBig(javascript)) + return false; + } + } else { + for (const auto& expr : m_Arguments) { + javascript << gs_lpStrExpFuncName[GETFMVALUE]; + javascript << L"("; + if (!expr->ToJavaScript(javascript)) + return false; + javascript << L")"; + if (expr != m_Arguments.back()) + javascript << L", "; + if (CFXA_IsTooBig(javascript)) + return false; + } + } + javascript << L")"; + } else { + bool isEvalFunc = false; + bool isExistsFunc = false; + if (IsBuildInFunc(&funcName)) { + if (funcName.AsStringC() == L"Eval") { + isEvalFunc = true; + javascript << L"eval.call(this, "; + javascript << gs_lpStrExpFuncName[CALL]; + javascript << L"Translate"; + } else if (funcName.AsStringC() == L"Exists") { + isExistsFunc = true; + javascript << gs_lpStrExpFuncName[CALL]; + javascript << funcName; + } else { + javascript << gs_lpStrExpFuncName[CALL]; + javascript << funcName; + } + } else { + javascript << funcName; + } + javascript << L"("; + if (isExistsFunc) { + javascript << L"\n(\nfunction ()\n{\ntry\n{\n"; + if (!m_Arguments.empty()) { + const auto& expr = m_Arguments[0]; + javascript << L"return "; + if (!expr->ToJavaScript(javascript)) + return false; + javascript << L";\n}\n"; + } else { + javascript << L"return 0;\n}\n"; + } + javascript << L"catch(accessExceptions)\n"; + javascript << L"{\nreturn 0;\n}\n}\n).call(this)\n"; + } else { + for (const auto& expr : m_Arguments) { + if (!expr->ToJavaScript(javascript)) + return false; + if (expr != m_Arguments.back()) + javascript << L", "; + if (CFXA_IsTooBig(javascript)) + return false; + } + } + javascript << L")"; + if (isEvalFunc) { + javascript << L")"; + } + } + return true; +} + +CXFA_FMDotAccessorExpression::CXFA_FMDotAccessorExpression( + uint32_t line, + std::unique_ptr<CXFA_FMSimpleExpression> pAccessor, + XFA_FM_TOKEN op, + CFX_WideStringC wsIdentifier, + std::unique_ptr<CXFA_FMSimpleExpression> pIndexExp) + : CXFA_FMBinExpression(line, + op, + std::move(pAccessor), + std::move(pIndexExp)), + m_wsIdentifier(wsIdentifier) {} + +CXFA_FMDotAccessorExpression::~CXFA_FMDotAccessorExpression() {} + +bool CXFA_FMDotAccessorExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + javascript << gs_lpStrExpFuncName[DOT]; + javascript << L"("; + CFX_WideTextBuf tempExp1; + if (m_pExp1) { + if (!m_pExp1->ToJavaScript(tempExp1)) + return false; + javascript << tempExp1; + } else { + javascript << L"null"; + } + javascript << L", "; + javascript << L"\""; + if (CFXA_IsTooBig(javascript)) + return false; + + if (m_pExp1 && m_pExp1->GetOperatorToken() == TOKidentifier) + javascript << tempExp1; + javascript << L"\", "; + if (m_op == TOKdotscream) { + javascript << L"\"#"; + javascript << m_wsIdentifier; + javascript << L"\", "; + } else if (m_op == TOKdotstar) { + javascript << L"\"*\", "; + } else if (m_op == TOKcall) { + javascript << L"\"\", "; + } else { + javascript << L"\""; + javascript << m_wsIdentifier; + javascript << L"\", "; + } + if (!m_pExp2->ToJavaScript(javascript)) + return false; + javascript << L")"; + return !CFXA_IsTooBig(javascript); +} + +CXFA_FMIndexExpression::CXFA_FMIndexExpression( + uint32_t line, + XFA_FM_AccessorIndex accessorIndex, + std::unique_ptr<CXFA_FMSimpleExpression> pIndexExp, + bool bIsStarIndex) + : CXFA_FMUnaryExpression(line, TOKlbracket, std::move(pIndexExp)), + m_accessorIndex(accessorIndex), + m_bIsStarIndex(bIsStarIndex) {} + +bool CXFA_FMIndexExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + switch (m_accessorIndex) { + case ACCESSOR_NO_INDEX: + javascript << L"0"; + break; + case ACCESSOR_NO_RELATIVEINDEX: + javascript << L"1"; + break; + case ACCESSOR_POSITIVE_INDEX: + javascript << L"2"; + break; + case ACCESSOR_NEGATIVE_INDEX: + javascript << L"3"; + break; + default: + javascript << L"0"; + } + if (!m_bIsStarIndex) { + javascript << L", "; + if (m_pExp) { + if (!m_pExp->ToJavaScript(javascript)) + return false; + } else { + javascript << L"0"; + } + } + return true; +} + +CXFA_FMDotDotAccessorExpression::CXFA_FMDotDotAccessorExpression( + uint32_t line, + std::unique_ptr<CXFA_FMSimpleExpression> pAccessor, + XFA_FM_TOKEN op, + CFX_WideStringC wsIdentifier, + std::unique_ptr<CXFA_FMSimpleExpression> pIndexExp) + : CXFA_FMBinExpression(line, + op, + std::move(pAccessor), + std::move(pIndexExp)), + m_wsIdentifier(wsIdentifier) {} + +CXFA_FMDotDotAccessorExpression::~CXFA_FMDotDotAccessorExpression() {} + +bool CXFA_FMDotDotAccessorExpression::ToJavaScript( + CFX_WideTextBuf& javascript) { + javascript << gs_lpStrExpFuncName[DOTDOT]; + javascript << L"("; + CFX_WideTextBuf tempExp1; + if (!m_pExp1->ToJavaScript(tempExp1)) + return false; + javascript << tempExp1; + javascript << L", "; + javascript << L"\""; + if (CFXA_IsTooBig(javascript)) + return false; + + if (m_pExp1->GetOperatorToken() == TOKidentifier) + javascript << tempExp1; + javascript << L"\", "; + javascript << L"\""; + javascript << m_wsIdentifier; + javascript << L"\", "; + if (!m_pExp2->ToJavaScript(javascript)) + return false; + javascript << L")"; + return !CFXA_IsTooBig(javascript); +} + +CXFA_FMMethodCallExpression::CXFA_FMMethodCallExpression( + uint32_t line, + std::unique_ptr<CXFA_FMSimpleExpression> pAccessorExp1, + std::unique_ptr<CXFA_FMSimpleExpression> pCallExp) + : CXFA_FMBinExpression(line, + TOKdot, + std::move(pAccessorExp1), + std::move(pCallExp)) {} + +bool CXFA_FMMethodCallExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + javascript << L"(\nfunction ()\n{\n"; + javascript << L"var method_return_value = null;\n"; + javascript << L"var accessor_object = "; + if (!m_pExp1->ToJavaScript(javascript)) + return false; + javascript << L";\n"; + javascript << L"if ("; + javascript << gs_lpStrExpFuncName[ISFMARRAY]; + javascript << L"(accessor_object))\n{\n"; + javascript << L"for(var index = accessor_object.length - 1; index > 1; " + L"index--)\n{\n"; + javascript << L"method_return_value = accessor_object[index]."; + if (CFXA_IsTooBig(javascript)) + return false; + + CFX_WideTextBuf tempExp2; + if (!m_pExp2->ToJavaScript(tempExp2)) + return false; + javascript << tempExp2; + javascript << L";\n}\n}\n"; + javascript << L"else\n{\nmethod_return_value = accessor_object."; + javascript << tempExp2; + javascript << L";\n}\n"; + javascript << L"return method_return_value;\n"; + javascript << L"}\n).call(this)"; + return !CFXA_IsTooBig(javascript); +} + +bool CFXA_IsTooBig(const CFX_WideTextBuf& javascript) { + return javascript.GetSize() > 256 * 1024 * 1024; +} |