Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(452)

Side by Side Diff: xfa/fxfa/fm2js/xfa_fm2jscontext.cpp

Issue 2042843003: xfa_fm2jscontext method cleanup - pt V (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "xfa/fxfa/fm2js/xfa_fm2jscontext.h" 7 #include "xfa/fxfa/fm2js/xfa_fm2jscontext.h"
8 8
9 #include <time.h> 9 #include <time.h>
10 10
(...skipping 2378 matching lines...) Expand 10 before | Expand all | Expand 10 after
2389 iHour = pLocal->tm_hour - pGmt->tm_hour; 2389 iHour = pLocal->tm_hour - pGmt->tm_hour;
2390 iMin = pLocal->tm_min - pGmt->tm_min; 2390 iMin = pLocal->tm_min - pGmt->tm_min;
2391 iSec = pLocal->tm_sec - pGmt->tm_sec; 2391 iSec = pLocal->tm_sec - pGmt->tm_sec;
2392 } 2392 }
2393 2393
2394 // static 2394 // static
2395 void CXFA_FM2JSContext::Apr(CFXJSE_Value* pThis, 2395 void CXFA_FM2JSContext::Apr(CFXJSE_Value* pThis,
2396 const CFX_ByteStringC& szFuncName, 2396 const CFX_ByteStringC& szFuncName,
2397 CFXJSE_Arguments& args) { 2397 CFXJSE_Arguments& args) {
2398 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr); 2398 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr);
2399 if (args.GetLength() == 3) { 2399 if (args.GetLength() != 3) {
2400 FX_BOOL bFlags = FALSE; 2400 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Apr");
2401 FX_DOUBLE nPrincipal = 0; 2401 return;
2402 FX_DOUBLE nPayment = 0; 2402 }
2403 FX_DOUBLE nPeriods = 0; 2403
2404 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0); 2404 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2405 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1); 2405 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2406 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2); 2406 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2407 bFlags = 2407 if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2408 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) || 2408 ValueIsNull(pThis, argThree.get())) {
2409 ValueIsNull(pThis, argThree.get())); 2409 FXJSE_Value_SetNull(args.GetReturnValue());
2410 if (bFlags) { 2410 return;
2411 }
2412
2413 FX_DOUBLE nPrincipal = ValueToDouble(pThis, argOne.get());
2414 FX_DOUBLE nPayment = ValueToDouble(pThis, argTwo.get());
2415 FX_DOUBLE nPeriods = ValueToDouble(pThis, argThree.get());
2416 if (nPrincipal <= 0 || nPayment <= 0 || nPeriods <= 0) {
2417 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2418 return;
2419 }
2420
2421 FX_DOUBLE r =
2422 2 * (nPeriods * nPayment - nPrincipal) / (nPeriods * nPrincipal);
2423 FX_DOUBLE nTemp = 1;
2424 for (int32_t i = 0; i < nPeriods; ++i)
2425 nTemp *= (1 + r);
2426
2427 FX_DOUBLE nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
2428 while (fabs(nRet) > kFinancialPrecision) {
2429 FX_DOUBLE nDerivative =
2430 ((nTemp + r * nPeriods * (nTemp / (1 + r))) * (nTemp - 1) -
2431 (r * nTemp * nPeriods * (nTemp / (1 + r)))) /
2432 ((nTemp - 1) * (nTemp - 1));
2433 if (nDerivative == 0) {
2411 FXJSE_Value_SetNull(args.GetReturnValue()); 2434 FXJSE_Value_SetNull(args.GetReturnValue());
2412 } else { 2435 return;
2413 nPrincipal = ValueToDouble(pThis, argOne.get());
2414 nPayment = ValueToDouble(pThis, argTwo.get());
2415 nPeriods = ValueToDouble(pThis, argThree.get());
2416 bFlags = ((nPrincipal <= 0) || (nPayment <= 0) || (nPeriods <= 0));
2417 if (bFlags) {
2418 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2419 } else {
2420 FX_DOUBLE r =
2421 2 * (nPeriods * nPayment - nPrincipal) / (nPeriods * nPrincipal);
2422 FX_DOUBLE nTemp = 1;
2423 for (int32_t i = 0; i < nPeriods; ++i) {
2424 nTemp *= (1 + r);
2425 }
2426 FX_DOUBLE nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
2427 while (fabs(nRet) > kFinancialPrecision && !bFlags) {
2428 FX_DOUBLE nDerivative = 0;
2429 nDerivative =
2430 ((nTemp + r * nPeriods * (nTemp / (1 + r))) * (nTemp - 1) -
2431 (r * nTemp * nPeriods * (nTemp / (1 + r)))) /
2432 ((nTemp - 1) * (nTemp - 1));
2433 if (nDerivative == 0) {
2434 bFlags = TRUE;
2435 continue;
2436 }
2437 r = r - nRet / nDerivative;
2438 nTemp = 1;
2439 for (int32_t i = 0; i < nPeriods; ++i) {
2440 nTemp *= (1 + r);
2441 }
2442 nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
2443 }
2444 if (bFlags) {
2445 FXJSE_Value_SetNull(args.GetReturnValue());
2446 } else {
2447 r = r * 12;
2448 FXJSE_Value_SetDouble(args.GetReturnValue(), r);
2449 }
2450 }
2451 } 2436 }
2452 } else { 2437
2453 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Apr"); 2438 r = r - nRet / nDerivative;
2439 nTemp = 1;
2440 for (int32_t i = 0; i < nPeriods; ++i) {
2441 nTemp *= (1 + r);
2442 }
2443 nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
2454 } 2444 }
2445 FXJSE_Value_SetDouble(args.GetReturnValue(), r * 12);
2455 } 2446 }
2456 2447
2457 // static 2448 // static
2458 void CXFA_FM2JSContext::CTerm(CFXJSE_Value* pThis, 2449 void CXFA_FM2JSContext::CTerm(CFXJSE_Value* pThis,
2459 const CFX_ByteStringC& szFuncName, 2450 const CFX_ByteStringC& szFuncName,
2460 CFXJSE_Arguments& args) { 2451 CFXJSE_Arguments& args) {
2461 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr); 2452 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr);
2462 if (args.GetLength() == 3) { 2453 if (args.GetLength() != 3) {
2463 FX_BOOL bFlags = FALSE;
2464 FX_FLOAT nRate = 0;
2465 FX_FLOAT nFutureValue = 0;
2466 FX_FLOAT nInitAmount = 0;
2467 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2468 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2469 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2470 bFlags =
2471 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2472 ValueIsNull(pThis, argThree.get()));
2473 if (bFlags) {
2474 FXJSE_Value_SetNull(args.GetReturnValue());
2475 } else {
2476 nRate = ValueToFloat(pThis, argOne.get());
2477 nFutureValue = ValueToFloat(pThis, argTwo.get());
2478 nInitAmount = ValueToFloat(pThis, argThree.get());
2479 bFlags = ((nRate <= 0) || (nFutureValue <= 0) || (nInitAmount <= 0));
2480 if (bFlags) {
2481 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2482 } else {
2483 FXJSE_Value_SetFloat(args.GetReturnValue(),
2484 FXSYS_log((FX_FLOAT)(nFutureValue / nInitAmount)) /
2485 FXSYS_log((FX_FLOAT)(1 + nRate)));
2486 }
2487 }
2488 } else {
2489 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"CTerm"); 2454 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"CTerm");
2455 return;
2490 } 2456 }
2457
2458 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2459 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2460 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2461 if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2462 ValueIsNull(pThis, argThree.get())) {
2463 FXJSE_Value_SetNull(args.GetReturnValue());
2464 return;
2465 }
2466
2467 FX_FLOAT nRate = ValueToFloat(pThis, argOne.get());
2468 FX_FLOAT nFutureValue = ValueToFloat(pThis, argTwo.get());
2469 FX_FLOAT nInitAmount = ValueToFloat(pThis, argThree.get());
2470 if ((nRate <= 0) || (nFutureValue <= 0) || (nInitAmount <= 0)) {
2471 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2472 return;
2473 }
2474
2475 FXJSE_Value_SetFloat(args.GetReturnValue(),
2476 FXSYS_log((FX_FLOAT)(nFutureValue / nInitAmount)) /
2477 FXSYS_log((FX_FLOAT)(1 + nRate)));
2491 } 2478 }
2492 2479
2493 // static 2480 // static
2494 void CXFA_FM2JSContext::FV(CFXJSE_Value* pThis, 2481 void CXFA_FM2JSContext::FV(CFXJSE_Value* pThis,
2495 const CFX_ByteStringC& szFuncName, 2482 const CFX_ByteStringC& szFuncName,
2496 CFXJSE_Arguments& args) { 2483 CFXJSE_Arguments& args) {
2497 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr); 2484 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr);
2498 if (args.GetLength() == 3) { 2485 if (args.GetLength() != 3) {
2499 FX_BOOL bFlags = FALSE; 2486 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"FV");
2500 FX_DOUBLE nAmount = 0; 2487 return;
2501 FX_DOUBLE nRate = 0; 2488 }
2502 FX_DOUBLE nPeriod = 0; 2489
2503 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0); 2490 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2504 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1); 2491 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2505 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2); 2492 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2506 bFlags = 2493 if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2507 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) || 2494 ValueIsNull(pThis, argThree.get())) {
2508 ValueIsNull(pThis, argThree.get())); 2495 FXJSE_Value_SetNull(args.GetReturnValue());
2509 if (bFlags) { 2496 return;
2510 FXJSE_Value_SetNull(args.GetReturnValue()); 2497 }
2511 } else { 2498
2512 nAmount = ValueToDouble(pThis, argOne.get()); 2499 FX_DOUBLE nAmount = ValueToDouble(pThis, argOne.get());
2513 nRate = ValueToDouble(pThis, argTwo.get()); 2500 FX_DOUBLE nRate = ValueToDouble(pThis, argTwo.get());
2514 nPeriod = ValueToDouble(pThis, argThree.get()); 2501 FX_DOUBLE nPeriod = ValueToDouble(pThis, argThree.get());
2515 bFlags = ((nRate < 0) || (nPeriod <= 0) || (nAmount <= 0)); 2502 if ((nRate < 0) || (nPeriod <= 0) || (nAmount <= 0)) {
2516 if (bFlags) { 2503 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2517 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH); 2504 return;
2518 } else { 2505 }
2519 FX_DOUBLE dResult = 0; 2506
2520 if (!nRate) { 2507 FX_DOUBLE dResult = 0;
2521 dResult = nAmount * nPeriod; 2508 if (nRate) {
2522 } else { 2509 FX_DOUBLE nTemp = 1;
2523 FX_DOUBLE nTemp = 1; 2510 for (int i = 0; i < nPeriod; ++i) {
2524 for (int i = 0; i < nPeriod; ++i) { 2511 nTemp *= 1 + nRate;
2525 nTemp *= 1 + nRate;
2526 }
2527 dResult = nAmount * (nTemp - 1) / nRate;
2528 }
2529 FXJSE_Value_SetDouble(args.GetReturnValue(), dResult);
2530 }
2531 } 2512 }
2513 dResult = nAmount * (nTemp - 1) / nRate;
2532 } else { 2514 } else {
2533 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"FV"); 2515 dResult = nAmount * nPeriod;
2534 } 2516 }
2517
2518 FXJSE_Value_SetDouble(args.GetReturnValue(), dResult);
2535 } 2519 }
2536 2520
2537 // static 2521 // static
2538 void CXFA_FM2JSContext::IPmt(CFXJSE_Value* pThis, 2522 void CXFA_FM2JSContext::IPmt(CFXJSE_Value* pThis,
2539 const CFX_ByteStringC& szFuncName, 2523 const CFX_ByteStringC& szFuncName,
2540 CFXJSE_Arguments& args) { 2524 CFXJSE_Arguments& args) {
2541 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr); 2525 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr);
2542 if (args.GetLength() == 5) { 2526 if (args.GetLength() != 5) {
2543 FX_BOOL bFlags = FALSE;
2544 FX_FLOAT nPrincpalAmount = 0;
2545 FX_FLOAT nRate = 0;
2546 FX_FLOAT nPayment = 0;
2547 FX_FLOAT nFirstMonth = 0;
2548 FX_FLOAT nNumberOfMonths = 0;
2549 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2550 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2551 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2552 std::unique_ptr<CFXJSE_Value> argFour = GetSimpleValue(pThis, args, 3);
2553 std::unique_ptr<CFXJSE_Value> argFive = GetSimpleValue(pThis, args, 4);
2554 bFlags =
2555 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2556 ValueIsNull(pThis, argThree.get()) ||
2557 ValueIsNull(pThis, argFour.get()) ||
2558 ValueIsNull(pThis, argFive.get()));
2559 if (bFlags) {
2560 FXJSE_Value_SetNull(args.GetReturnValue());
2561 } else {
2562 nPrincpalAmount = ValueToFloat(pThis, argOne.get());
2563 nRate = ValueToFloat(pThis, argTwo.get());
2564 nPayment = ValueToFloat(pThis, argThree.get());
2565 nFirstMonth = ValueToFloat(pThis, argFour.get());
2566 nNumberOfMonths = ValueToFloat(pThis, argFive.get());
2567 bFlags = ((nPrincpalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
2568 (nFirstMonth < 0) || (nNumberOfMonths < 0));
2569 if (bFlags) {
2570 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2571 } else {
2572 FX_FLOAT fResult = 0;
2573 FX_FLOAT nRateOfMonth = nRate / 12;
2574 int32_t iNums =
2575 (int32_t)((FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount)) -
2576 FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount -
2577 nRateOfMonth))) /
2578 FXSYS_log10((FX_FLOAT)(1 + nRateOfMonth)));
2579 int32_t iEnd = (int32_t)(nFirstMonth + nNumberOfMonths - 1);
2580 if (iEnd > iNums) {
2581 iEnd = iNums;
2582 }
2583 FX_FLOAT nSum = 0;
2584 if (nPayment < nPrincpalAmount * nRateOfMonth) {
2585 bFlags = TRUE;
2586 fResult = 0;
2587 }
2588 if (!bFlags) {
2589 int32_t i = 0;
2590 for (i = 0; i < nFirstMonth - 1; ++i) {
2591 nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
2592 }
2593 for (; i < iEnd; ++i) {
2594 nSum += nPrincpalAmount * nRateOfMonth;
2595 nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
2596 }
2597 fResult = nSum;
2598 }
2599 FXJSE_Value_SetFloat(args.GetReturnValue(), fResult);
2600 }
2601 }
2602 } else {
2603 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"IPmt"); 2527 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"IPmt");
2528 return;
2604 } 2529 }
2530
2531 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2532 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2533 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2534 std::unique_ptr<CFXJSE_Value> argFour = GetSimpleValue(pThis, args, 3);
2535 std::unique_ptr<CFXJSE_Value> argFive = GetSimpleValue(pThis, args, 4);
2536 if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2537 ValueIsNull(pThis, argThree.get()) || ValueIsNull(pThis, argFour.get()) ||
2538 ValueIsNull(pThis, argFive.get())) {
2539 FXJSE_Value_SetNull(args.GetReturnValue());
2540 return;
2541 }
2542
2543 FX_FLOAT nPrincipalAmount = ValueToFloat(pThis, argOne.get());
2544 FX_FLOAT nRate = ValueToFloat(pThis, argTwo.get());
2545 FX_FLOAT nPayment = ValueToFloat(pThis, argThree.get());
2546 FX_FLOAT nFirstMonth = ValueToFloat(pThis, argFour.get());
2547 FX_FLOAT nNumberOfMonths = ValueToFloat(pThis, argFive.get());
2548 if ((nPrincipalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
2549 (nFirstMonth < 0) || (nNumberOfMonths < 0)) {
2550 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2551 return;
2552 }
2553
2554 FX_FLOAT nRateOfMonth = nRate / 12;
2555 int32_t iNums = (int32_t)(
2556 (FXSYS_log10((FX_FLOAT)(nPayment / nPrincipalAmount)) -
2557 FXSYS_log10((FX_FLOAT)(nPayment / nPrincipalAmount - nRateOfMonth))) /
2558 FXSYS_log10((FX_FLOAT)(1 + nRateOfMonth)));
2559 int32_t iEnd = std::min((int32_t)(nFirstMonth + nNumberOfMonths - 1), iNums);
2560
2561 if (nPayment < nPrincipalAmount * nRateOfMonth) {
2562 FXJSE_Value_SetFloat(args.GetReturnValue(), 0);
2563 return;
2564 }
2565
2566 int32_t i = 0;
2567 for (i = 0; i < nFirstMonth - 1; ++i)
2568 nPrincipalAmount -= nPayment - nPrincipalAmount * nRateOfMonth;
2569
2570 FX_FLOAT nSum = 0;
2571 for (; i < iEnd; ++i) {
2572 nSum += nPrincipalAmount * nRateOfMonth;
2573 nPrincipalAmount -= nPayment - nPrincipalAmount * nRateOfMonth;
2574 }
2575 FXJSE_Value_SetFloat(args.GetReturnValue(), nSum);
2605 } 2576 }
2606 2577
2607 // static 2578 // static
2608 void CXFA_FM2JSContext::NPV(CFXJSE_Value* pThis, 2579 void CXFA_FM2JSContext::NPV(CFXJSE_Value* pThis,
2609 const CFX_ByteStringC& szFuncName, 2580 const CFX_ByteStringC& szFuncName,
2610 CFXJSE_Arguments& args) { 2581 CFXJSE_Arguments& args) {
2611 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr); 2582 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr);
2612 int32_t argc = args.GetLength(); 2583 int32_t argc = args.GetLength();
2613 if (argc > 2) { 2584 if (argc < 3) {
2614 FX_BOOL bFlags = FALSE; 2585 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"NPV");
2615 std::vector<std::unique_ptr<CFXJSE_Value>> argValues; 2586 return;
2616 for (int32_t i = 0; i < argc; i++) { 2587 }
2617 argValues.push_back(GetSimpleValue(pThis, args, i)); 2588
2618 if (ValueIsNull(pThis, argValues[i].get())) { 2589 std::vector<std::unique_ptr<CFXJSE_Value>> argValues;
2619 bFlags = TRUE; 2590 for (int32_t i = 0; i < argc; i++) {
2620 } 2591 argValues.push_back(GetSimpleValue(pThis, args, i));
2592 if (ValueIsNull(pThis, argValues[i].get())) {
2593 FXJSE_Value_SetNull(args.GetReturnValue());
2594 return;
2621 } 2595 }
2622 if (!bFlags && argc > 0) {
2623 FX_DOUBLE nRate = 0;
2624 nRate = ValueToDouble(pThis, argValues[0].get());
2625 if (nRate <= 0) {
2626 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2627 } else {
2628 FX_DOUBLE* pData = FX_Alloc(FX_DOUBLE, argc - 1);
2629 for (int32_t i = 1; i < argc; i++) {
2630 pData[i - 1] = ValueToDouble(pThis, argValues[i].get());
2631 }
2632 FX_DOUBLE nSum = 0;
2633 int32_t iIndex = 0;
2634 for (int32_t i = 0; i < argc - 1; i++) {
2635 FX_DOUBLE nTemp = 1;
2636 for (int32_t j = 0; j <= i; j++) {
2637 nTemp *= 1 + nRate;
2638 }
2639 FX_DOUBLE nNum = pData[iIndex++];
2640 nSum += nNum / nTemp;
2641 }
2642 FXJSE_Value_SetDouble(args.GetReturnValue(), nSum);
2643 FX_Free(pData);
2644 pData = nullptr;
2645 }
2646 } else {
2647 FXJSE_Value_SetNull(args.GetReturnValue());
2648 }
2649 } else {
2650 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"NPV");
2651 } 2596 }
2597
2598 FX_DOUBLE nRate = ValueToDouble(pThis, argValues[0].get());
2599 if (nRate <= 0) {
2600 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2601 return;
2602 }
2603
2604 std::vector<FX_DOUBLE> data(argc - 1);
2605 for (int32_t i = 1; i < argc; i++)
2606 data.push_back(ValueToDouble(pThis, argValues[i].get()));
2607
2608 FX_DOUBLE nSum = 0;
2609 int32_t iIndex = 0;
2610 for (int32_t i = 0; i < argc - 1; i++) {
2611 FX_DOUBLE nTemp = 1;
2612 for (int32_t j = 0; j <= i; j++)
2613 nTemp *= 1 + nRate;
2614
2615 FX_DOUBLE nNum = data[iIndex++];
2616 nSum += nNum / nTemp;
2617 }
2618 FXJSE_Value_SetDouble(args.GetReturnValue(), nSum);
2652 } 2619 }
2653 2620
2654 // static 2621 // static
2655 void CXFA_FM2JSContext::Pmt(CFXJSE_Value* pThis, 2622 void CXFA_FM2JSContext::Pmt(CFXJSE_Value* pThis,
2656 const CFX_ByteStringC& szFuncName, 2623 const CFX_ByteStringC& szFuncName,
2657 CFXJSE_Arguments& args) { 2624 CFXJSE_Arguments& args) {
2658 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr); 2625 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr);
2659 if (args.GetLength() == 3) { 2626 if (args.GetLength() != 3) {
2660 FX_BOOL bFlags = FALSE;
2661 FX_FLOAT nPrincipal = 0;
2662 FX_FLOAT nRate = 0;
2663 FX_FLOAT nPeriods = 0;
2664 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2665 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2666 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2667 bFlags =
2668 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2669 ValueIsNull(pThis, argThree.get()));
2670 if (bFlags) {
2671 FXJSE_Value_SetNull(args.GetReturnValue());
2672 } else {
2673 nPrincipal = ValueToFloat(pThis, argOne.get());
2674 nRate = ValueToFloat(pThis, argTwo.get());
2675 nPeriods = ValueToFloat(pThis, argThree.get());
2676 bFlags = ((nPrincipal <= 0) || (nRate <= 0) || (nPeriods <= 0));
2677 if (bFlags) {
2678 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2679 } else {
2680 FX_FLOAT nSum = 0;
2681 FX_FLOAT nTmp = 1 + nRate;
2682 nSum = nTmp;
2683 for (int32_t i = 0; i < nPeriods - 1; ++i) {
2684 nSum *= nTmp;
2685 }
2686 FXJSE_Value_SetFloat(args.GetReturnValue(),
2687 (nPrincipal * nRate * nSum) / (nSum - 1));
2688 }
2689 }
2690 } else {
2691 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Pmt"); 2627 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Pmt");
2628 return;
2692 } 2629 }
2630
2631 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2632 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2633 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2634 if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2635 ValueIsNull(pThis, argThree.get())) {
2636 FXJSE_Value_SetNull(args.GetReturnValue());
2637 return;
2638 }
2639
2640 FX_FLOAT nPrincipal = ValueToFloat(pThis, argOne.get());
2641 FX_FLOAT nRate = ValueToFloat(pThis, argTwo.get());
2642 FX_FLOAT nPeriods = ValueToFloat(pThis, argThree.get());
2643 if ((nPrincipal <= 0) || (nRate <= 0) || (nPeriods <= 0)) {
2644 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2645 return;
2646 }
2647
2648 FX_FLOAT nTmp = 1 + nRate;
2649 FX_FLOAT nSum = nTmp;
2650 for (int32_t i = 0; i < nPeriods - 1; ++i)
2651 nSum *= nTmp;
2652
2653 FXJSE_Value_SetFloat(args.GetReturnValue(),
2654 (nPrincipal * nRate * nSum) / (nSum - 1));
2693 } 2655 }
2694 2656
2695 // static 2657 // static
2696 void CXFA_FM2JSContext::PPmt(CFXJSE_Value* pThis, 2658 void CXFA_FM2JSContext::PPmt(CFXJSE_Value* pThis,
2697 const CFX_ByteStringC& szFuncName, 2659 const CFX_ByteStringC& szFuncName,
2698 CFXJSE_Arguments& args) { 2660 CFXJSE_Arguments& args) {
2699 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr); 2661 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr);
2700 if (args.GetLength() == 5) { 2662 if (args.GetLength() != 5) {
2701 FX_BOOL bFlags = FALSE;
2702 FX_FLOAT nPrincpalAmount = 0;
2703 FX_FLOAT nRate = 0;
2704 FX_FLOAT nPayment = 0;
2705 FX_FLOAT nFirstMonth = 0;
2706 FX_FLOAT nNumberOfMonths = 0;
2707 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2708 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2709 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2710 std::unique_ptr<CFXJSE_Value> argFour = GetSimpleValue(pThis, args, 3);
2711 std::unique_ptr<CFXJSE_Value> argFive = GetSimpleValue(pThis, args, 4);
2712 bFlags =
2713 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2714 ValueIsNull(pThis, argThree.get()) ||
2715 ValueIsNull(pThis, argFour.get()) ||
2716 ValueIsNull(pThis, argFive.get()));
2717 if (bFlags) {
2718 FXJSE_Value_SetNull(args.GetReturnValue());
2719 } else {
2720 nPrincpalAmount = ValueToFloat(pThis, argOne.get());
2721 nRate = ValueToFloat(pThis, argTwo.get());
2722 nPayment = ValueToFloat(pThis, argThree.get());
2723 nFirstMonth = ValueToFloat(pThis, argFour.get());
2724 nNumberOfMonths = ValueToFloat(pThis, argFive.get());
2725 bFlags = ((nPrincpalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
2726 (nFirstMonth < 0) || (nNumberOfMonths < 0));
2727 if (bFlags) {
2728 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2729 } else {
2730 int32_t iEnd = (int32_t)(nFirstMonth + nNumberOfMonths - 1);
2731 FX_FLOAT nSum = 0;
2732 FX_FLOAT nRateOfMonth = nRate / 12;
2733 int32_t iNums =
2734 (int32_t)((FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount)) -
2735 FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount -
2736 nRateOfMonth))) /
2737 FXSYS_log10((FX_FLOAT)(1 + nRateOfMonth)));
2738 if (iEnd > iNums) {
2739 iEnd = iNums;
2740 }
2741 if (nPayment < nPrincpalAmount * nRateOfMonth) {
2742 bFlags = TRUE;
2743 }
2744 if (!bFlags) {
2745 int32_t i = 0;
2746 for (i = 0; i < nFirstMonth - 1; ++i) {
2747 nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
2748 }
2749 FX_FLOAT nTemp = 0;
2750 for (; i < iEnd; ++i) {
2751 nTemp = nPayment - nPrincpalAmount * nRateOfMonth;
2752 nSum += nTemp;
2753 nPrincpalAmount -= nTemp;
2754 }
2755 FXJSE_Value_SetFloat(args.GetReturnValue(), nSum);
2756 } else {
2757 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2758 }
2759 }
2760 }
2761 } else {
2762 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"PPmt"); 2663 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"PPmt");
2664 return;
2763 } 2665 }
2666
2667 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2668 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2669 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2670 std::unique_ptr<CFXJSE_Value> argFour = GetSimpleValue(pThis, args, 3);
2671 std::unique_ptr<CFXJSE_Value> argFive = GetSimpleValue(pThis, args, 4);
2672 if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2673 ValueIsNull(pThis, argThree.get()) || ValueIsNull(pThis, argFour.get()) ||
2674 ValueIsNull(pThis, argFive.get())) {
2675 FXJSE_Value_SetNull(args.GetReturnValue());
2676 return;
2677 }
2678
2679 FX_FLOAT nPrincipalAmount = ValueToFloat(pThis, argOne.get());
2680 FX_FLOAT nRate = ValueToFloat(pThis, argTwo.get());
2681 FX_FLOAT nPayment = ValueToFloat(pThis, argThree.get());
2682 FX_FLOAT nFirstMonth = ValueToFloat(pThis, argFour.get());
2683 FX_FLOAT nNumberOfMonths = ValueToFloat(pThis, argFive.get());
2684 if ((nPrincipalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
2685 (nFirstMonth < 0) || (nNumberOfMonths < 0)) {
2686 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2687 return;
2688 }
2689
2690 FX_FLOAT nRateOfMonth = nRate / 12;
2691 int32_t iNums = (int32_t)(
2692 (FXSYS_log10((FX_FLOAT)(nPayment / nPrincipalAmount)) -
2693 FXSYS_log10((FX_FLOAT)(nPayment / nPrincipalAmount - nRateOfMonth))) /
2694 FXSYS_log10((FX_FLOAT)(1 + nRateOfMonth)));
2695 int32_t iEnd = std::min((int32_t)(nFirstMonth + nNumberOfMonths - 1), iNums);
2696 if (nPayment < nPrincipalAmount * nRateOfMonth) {
2697 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2698 return;
2699 }
2700
2701 int32_t i = 0;
2702 for (i = 0; i < nFirstMonth - 1; ++i)
2703 nPrincipalAmount -= nPayment - nPrincipalAmount * nRateOfMonth;
2704
2705 FX_FLOAT nTemp = 0;
2706 FX_FLOAT nSum = 0;
2707 for (; i < iEnd; ++i) {
2708 nTemp = nPayment - nPrincipalAmount * nRateOfMonth;
2709 nSum += nTemp;
2710 nPrincipalAmount -= nTemp;
2711 }
2712 FXJSE_Value_SetFloat(args.GetReturnValue(), nSum);
2764 } 2713 }
2765 2714
2766 // static 2715 // static
2767 void CXFA_FM2JSContext::PV(CFXJSE_Value* pThis, 2716 void CXFA_FM2JSContext::PV(CFXJSE_Value* pThis,
2768 const CFX_ByteStringC& szFuncName, 2717 const CFX_ByteStringC& szFuncName,
2769 CFXJSE_Arguments& args) { 2718 CFXJSE_Arguments& args) {
2770 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr); 2719 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr);
2771 if (args.GetLength() == 3) { 2720 if (args.GetLength() != 3) {
2772 FX_BOOL bFlags = FALSE;
2773 FX_DOUBLE nAmount = 0;
2774 FX_DOUBLE nRate = 0;
2775 FX_DOUBLE nPeriod = 0;
2776 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2777 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2778 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2779 bFlags =
2780 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2781 ValueIsNull(pThis, argThree.get()));
2782 if (bFlags) {
2783 FXJSE_Value_SetNull(args.GetReturnValue());
2784 } else {
2785 nAmount = ValueToDouble(pThis, argOne.get());
2786 nRate = ValueToDouble(pThis, argTwo.get());
2787 nPeriod = ValueToDouble(pThis, argThree.get());
2788 bFlags = ((nAmount <= 0) || (nRate < 0) || (nPeriod <= 0));
2789 if (bFlags) {
2790 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2791 } else {
2792 FX_DOUBLE nTemp = 1;
2793 for (int32_t i = 0; i < nPeriod; ++i) {
2794 nTemp *= 1 + nRate;
2795 }
2796 nTemp = 1 / nTemp;
2797 FXJSE_Value_SetDouble(args.GetReturnValue(),
2798 nAmount * ((1 - nTemp) / nRate));
2799 }
2800 }
2801 } else {
2802 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"PV"); 2721 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"PV");
2722 return;
2803 } 2723 }
2724
2725 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2726 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2727 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2728 if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2729 ValueIsNull(pThis, argThree.get())) {
2730 FXJSE_Value_SetNull(args.GetReturnValue());
2731 return;
2732 }
2733
2734 FX_DOUBLE nAmount = ValueToDouble(pThis, argOne.get());
2735 FX_DOUBLE nRate = ValueToDouble(pThis, argTwo.get());
2736 FX_DOUBLE nPeriod = ValueToDouble(pThis, argThree.get());
2737 if ((nAmount <= 0) || (nRate < 0) || (nPeriod <= 0)) {
2738 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2739 return;
2740 }
2741
2742 FX_DOUBLE nTemp = 1;
2743 for (int32_t i = 0; i < nPeriod; ++i)
2744 nTemp *= 1 + nRate;
2745
2746 nTemp = 1 / nTemp;
2747 FXJSE_Value_SetDouble(args.GetReturnValue(), nAmount * ((1 - nTemp) / nRate));
2804 } 2748 }
2805 2749
2806 // static 2750 // static
2807 void CXFA_FM2JSContext::Rate(CFXJSE_Value* pThis, 2751 void CXFA_FM2JSContext::Rate(CFXJSE_Value* pThis,
2808 const CFX_ByteStringC& szFuncName, 2752 const CFX_ByteStringC& szFuncName,
2809 CFXJSE_Arguments& args) { 2753 CFXJSE_Arguments& args) {
2810 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr); 2754 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr);
2811 if (args.GetLength() == 3) { 2755 if (args.GetLength() != 3) {
2812 FX_BOOL bFlags = FALSE;
2813 FX_FLOAT nFuture = 0;
2814 FX_FLOAT nPresent = 0;
2815 FX_FLOAT nTotalNumber = 0;
2816 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2817 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2818 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2819 bFlags =
2820 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2821 ValueIsNull(pThis, argThree.get()));
2822 if (bFlags) {
2823 FXJSE_Value_SetNull(args.GetReturnValue());
2824 } else {
2825 nFuture = ValueToFloat(pThis, argOne.get());
2826 nPresent = ValueToFloat(pThis, argTwo.get());
2827 nTotalNumber = ValueToFloat(pThis, argThree.get());
2828 bFlags = ((nFuture <= 0) || (nPresent < 0) || (nTotalNumber <= 0));
2829 if (bFlags) {
2830 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2831 } else {
2832 FXJSE_Value_SetFloat(args.GetReturnValue(),
2833 (FXSYS_pow((FX_FLOAT)(nFuture / nPresent),
2834 (FX_FLOAT)(1 / nTotalNumber)) -
2835 1));
2836 }
2837 }
2838 } else {
2839 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Rate"); 2756 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Rate");
2757 return;
2840 } 2758 }
2759
2760 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2761 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2762 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2763 if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2764 ValueIsNull(pThis, argThree.get())) {
2765 FXJSE_Value_SetNull(args.GetReturnValue());
2766 return;
2767 }
2768
2769 FX_FLOAT nFuture = ValueToFloat(pThis, argOne.get());
2770 FX_FLOAT nPresent = ValueToFloat(pThis, argTwo.get());
2771 FX_FLOAT nTotalNumber = ValueToFloat(pThis, argThree.get());
2772 if ((nFuture <= 0) || (nPresent < 0) || (nTotalNumber <= 0)) {
2773 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2774 return;
2775 }
2776
2777 FXJSE_Value_SetFloat(
2778 args.GetReturnValue(),
2779 (FXSYS_pow((FX_FLOAT)(nFuture / nPresent), (FX_FLOAT)(1 / nTotalNumber)) -
2780 1));
2841 } 2781 }
2842 2782
2843 // static 2783 // static
2844 void CXFA_FM2JSContext::Term(CFXJSE_Value* pThis, 2784 void CXFA_FM2JSContext::Term(CFXJSE_Value* pThis,
2845 const CFX_ByteStringC& szFuncName, 2785 const CFX_ByteStringC& szFuncName,
2846 CFXJSE_Arguments& args) { 2786 CFXJSE_Arguments& args) {
2847 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr); 2787 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr);
2848 if (args.GetLength() == 3) { 2788 if (args.GetLength() != 3) {
2849 FX_BOOL bFlags = FALSE;
2850 FX_FLOAT nMount = 0;
2851 FX_FLOAT nRate = 0;
2852 FX_FLOAT nFuture = 0;
2853 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2854 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2855 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2856 bFlags =
2857 (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2858 ValueIsNull(pThis, argThree.get()));
2859 if (bFlags) {
2860 FXJSE_Value_SetNull(args.GetReturnValue());
2861 } else {
2862 nMount = ValueToFloat(pThis, argOne.get());
2863 nRate = ValueToFloat(pThis, argTwo.get());
2864 nFuture = ValueToFloat(pThis, argThree.get());
2865 bFlags = ((nMount <= 0) || (nRate <= 0) || (nFuture <= 0));
2866 if (bFlags) {
2867 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2868 } else {
2869 FXJSE_Value_SetFloat(
2870 args.GetReturnValue(),
2871 (FXSYS_log((FX_FLOAT)(nFuture / nMount * nRate) + 1) /
2872 FXSYS_log((FX_FLOAT)(1 + nRate))));
2873 }
2874 }
2875 } else {
2876 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Term"); 2789 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Term");
2790 return;
2877 } 2791 }
2792
2793 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2794 std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
2795 std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
2796 if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
2797 ValueIsNull(pThis, argThree.get())) {
2798 FXJSE_Value_SetNull(args.GetReturnValue());
2799 return;
2800 }
2801
2802 FX_FLOAT nMount = ValueToFloat(pThis, argOne.get());
2803 FX_FLOAT nRate = ValueToFloat(pThis, argTwo.get());
2804 FX_FLOAT nFuture = ValueToFloat(pThis, argThree.get());
2805 if ((nMount <= 0) || (nRate <= 0) || (nFuture <= 0)) {
2806 pContext->ThrowException(XFA_IDS_ARGUMENT_MISMATCH);
2807 return;
2808 }
2809
2810 FXJSE_Value_SetFloat(args.GetReturnValue(),
2811 (FXSYS_log((FX_FLOAT)(nFuture / nMount * nRate) + 1) /
2812 FXSYS_log((FX_FLOAT)(1 + nRate))));
2878 } 2813 }
2879 2814
2880 // static 2815 // static
2881 void CXFA_FM2JSContext::Choose(CFXJSE_Value* pThis, 2816 void CXFA_FM2JSContext::Choose(CFXJSE_Value* pThis,
2882 const CFX_ByteStringC& szFuncName, 2817 const CFX_ByteStringC& szFuncName,
2883 CFXJSE_Arguments& args) { 2818 CFXJSE_Arguments& args) {
2884 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr); 2819 CXFA_FM2JSContext* pContext = ToJSContext(pThis, nullptr);
2885 int32_t argc = args.GetLength(); 2820 int32_t argc = args.GetLength();
2886 if (argc > 1) { 2821 if (argc < 2) {
2887 v8::Isolate* pIsolate = pContext->GetScriptRuntime(); 2822 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Choose");
2888 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0); 2823 return;
2889 FX_BOOL argOneIsNull = FALSE; 2824 }
2890 int32_t iIndex = 0; 2825
2891 argOneIsNull = ValueIsNull(pThis, argOne.get()); 2826 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
2892 if (!argOneIsNull) { 2827 if (ValueIsNull(pThis, argOne.get())) {
2893 iIndex = (int32_t)ValueToFloat(pThis, argOne.get()); 2828 FXJSE_Value_SetNull(args.GetReturnValue());
2894 } 2829 return;
2895 if (argOneIsNull) { 2830 }
2896 FXJSE_Value_SetNull(args.GetReturnValue()); 2831
2897 } else if (iIndex < 1) { 2832 int32_t iIndex = (int32_t)ValueToFloat(pThis, argOne.get());
2898 FXJSE_Value_SetUTF8String(args.GetReturnValue(), ""); 2833 if (iIndex < 1) {
2834 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
2835 return;
2836 }
2837
2838 FX_BOOL bFound = FALSE;
2839 FX_BOOL bStopCounterFlags = FALSE;
2840 int32_t iArgIndex = 1;
2841 int32_t iValueIndex = 0;
2842 v8::Isolate* pIsolate = pContext->GetScriptRuntime();
2843 while (!bFound && !bStopCounterFlags && (iArgIndex < argc)) {
2844 std::unique_ptr<CFXJSE_Value> argIndexValue = args.GetValue(iArgIndex);
2845 if (FXJSE_Value_IsArray(argIndexValue.get())) {
2846 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
2847 FXJSE_Value_GetObjectProp(argIndexValue.get(), "length",
2848 lengthValue.get());
2849 int32_t iLength = FXJSE_Value_ToInteger(lengthValue.get());
2850 if (iLength > 3)
2851 bStopCounterFlags = TRUE;
2852
2853 iValueIndex += (iLength - 2);
2854 if (iValueIndex >= iIndex) {
2855 std::unique_ptr<CFXJSE_Value> propertyValue(new CFXJSE_Value(pIsolate));
2856 std::unique_ptr<CFXJSE_Value> jsObjectValue(new CFXJSE_Value(pIsolate));
2857 std::unique_ptr<CFXJSE_Value> newPropertyValue(
2858 new CFXJSE_Value(pIsolate));
2859 FXJSE_Value_GetObjectPropByIdx(argIndexValue.get(), 1,
2860 propertyValue.get());
2861 FXJSE_Value_GetObjectPropByIdx(argIndexValue.get(),
2862 ((iLength - 1) - (iValueIndex - iIndex)),
2863 jsObjectValue.get());
2864 if (FXJSE_Value_IsNull(propertyValue.get())) {
2865 GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
2866 } else {
2867 CFX_ByteString propStr;
2868 FXJSE_Value_ToUTF8String(propertyValue.get(), propStr);
2869 FXJSE_Value_GetObjectProp(jsObjectValue.get(), propStr.AsStringC(),
2870 newPropertyValue.get());
2871 }
2872 CFX_ByteString bsChoosed;
2873 ValueToUTF8String(newPropertyValue.get(), bsChoosed);
2874 FXJSE_Value_SetUTF8String(args.GetReturnValue(), bsChoosed.AsStringC());
2875 bFound = TRUE;
2876 }
2899 } else { 2877 } else {
2900 FX_BOOL bFound = FALSE; 2878 iValueIndex++;
2901 FX_BOOL bStopCounterFlags = FALSE; 2879 if (iValueIndex == iIndex) {
2902 int32_t iArgIndex = 1; 2880 CFX_ByteString bsChoosed;
2903 int32_t iValueIndex = 0; 2881 ValueToUTF8String(argIndexValue.get(), bsChoosed);
2904 while (!bFound && !bStopCounterFlags && (iArgIndex < argc)) { 2882 FXJSE_Value_SetUTF8String(args.GetReturnValue(), bsChoosed.AsStringC());
2905 std::unique_ptr<CFXJSE_Value> argIndexValue = args.GetValue(iArgIndex); 2883 bFound = TRUE;
2906 if (FXJSE_Value_IsArray(argIndexValue.get())) {
2907 std::unique_ptr<CFXJSE_Value> lengthValue(new CFXJSE_Value(pIsolate));
2908 FXJSE_Value_GetObjectProp(argIndexValue.get(), "length",
2909 lengthValue.get());
2910 int32_t iLength = FXJSE_Value_ToInteger(lengthValue.get());
2911 if (iLength > 3) {
2912 bStopCounterFlags = TRUE;
2913 }
2914 iValueIndex += (iLength - 2);
2915 if (iValueIndex >= iIndex) {
2916 std::unique_ptr<CFXJSE_Value> propertyValue(
2917 new CFXJSE_Value(pIsolate));
2918 std::unique_ptr<CFXJSE_Value> jsObjectValue(
2919 new CFXJSE_Value(pIsolate));
2920 std::unique_ptr<CFXJSE_Value> newPropertyValue(
2921 new CFXJSE_Value(pIsolate));
2922 FXJSE_Value_GetObjectPropByIdx(argIndexValue.get(), 1,
2923 propertyValue.get());
2924 FXJSE_Value_GetObjectPropByIdx(
2925 argIndexValue.get(), ((iLength - 1) - (iValueIndex - iIndex)),
2926 jsObjectValue.get());
2927 if (FXJSE_Value_IsNull(propertyValue.get())) {
2928 GetObjectDefaultValue(jsObjectValue.get(),
2929 newPropertyValue.get());
2930 } else {
2931 CFX_ByteString propStr;
2932 FXJSE_Value_ToUTF8String(propertyValue.get(), propStr);
2933 FXJSE_Value_GetObjectProp(jsObjectValue.get(),
2934 propStr.AsStringC(),
2935 newPropertyValue.get());
2936 }
2937 CFX_ByteString bsChoosed;
2938 ValueToUTF8String(newPropertyValue.get(), bsChoosed);
2939 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
2940 bsChoosed.AsStringC());
2941 bFound = TRUE;
2942 }
2943 } else {
2944 iValueIndex++;
2945 if (iValueIndex == iIndex) {
2946 CFX_ByteString bsChoosed;
2947 ValueToUTF8String(argIndexValue.get(), bsChoosed);
2948 FXJSE_Value_SetUTF8String(args.GetReturnValue(),
2949 bsChoosed.AsStringC());
2950 bFound = TRUE;
2951 }
2952 }
2953 iArgIndex++;
2954 }
2955 if (!bFound) {
2956 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
2957 } 2884 }
2958 } 2885 }
2959 } else { 2886 iArgIndex++;
2960 pContext->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Choose");
2961 } 2887 }
2888 if (!bFound)
2889 FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
2962 } 2890 }
2963 2891
2964 // static 2892 // static
2965 void CXFA_FM2JSContext::Exists(CFXJSE_Value* pThis, 2893 void CXFA_FM2JSContext::Exists(CFXJSE_Value* pThis,
2966 const CFX_ByteStringC& szFuncName, 2894 const CFX_ByteStringC& szFuncName,
2967 CFXJSE_Arguments& args) { 2895 CFXJSE_Arguments& args) {
2968 if (args.GetLength() == 1) { 2896 if (args.GetLength() != 1) {
2969 std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
2970 FXJSE_Value_SetInteger(args.GetReturnValue(),
2971 FXJSE_Value_IsObject(argOne.get()));
2972 } else {
2973 ToJSContext(pThis, nullptr) 2897 ToJSContext(pThis, nullptr)
2974 ->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Exists"); 2898 ->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Exists");
2899 return;
2975 } 2900 }
2901
2902 FXJSE_Value_SetInteger(args.GetReturnValue(),
2903 FXJSE_Value_IsObject(args.GetValue(0).get()));
2976 } 2904 }
2977 2905
2978 // static 2906 // static
2979 void CXFA_FM2JSContext::HasValue(CFXJSE_Value* pThis, 2907 void CXFA_FM2JSContext::HasValue(CFXJSE_Value* pThis,
2980 const CFX_ByteStringC& szFuncName, 2908 const CFX_ByteStringC& szFuncName,
2981 CFXJSE_Arguments& args) { 2909 CFXJSE_Arguments& args) {
2982 if (args.GetLength() == 1) { 2910 if (args.GetLength() != 1) {
2983 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2984 if (FXJSE_Value_IsUTF8String(argOne.get())) {
2985 CFX_ByteString valueStr;
2986 FXJSE_Value_ToUTF8String(argOne.get(), valueStr);
2987 valueStr.TrimLeft();
2988 FXJSE_Value_SetInteger(args.GetReturnValue(), (!valueStr.IsEmpty()));
2989 } else if (FXJSE_Value_IsNumber(argOne.get()) ||
2990 FXJSE_Value_IsBoolean(argOne.get())) {
2991 FXJSE_Value_SetInteger(args.GetReturnValue(), TRUE);
2992 } else {
2993 FXJSE_Value_SetInteger(args.GetReturnValue(), FALSE);
2994 }
2995 } else {
2996 ToJSContext(pThis, nullptr) 2911 ToJSContext(pThis, nullptr)
2997 ->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"HasValue"); 2912 ->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"HasValue");
2913 return;
2998 } 2914 }
2915
2916 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2917 if (!FXJSE_Value_IsUTF8String(argOne.get())) {
2918 FXJSE_Value_SetInteger(args.GetReturnValue(),
2919 FXJSE_Value_IsNumber(argOne.get()) ||
2920 FXJSE_Value_IsBoolean(argOne.get()));
2921 return;
2922 }
2923
2924 CFX_ByteString valueStr;
2925 FXJSE_Value_ToUTF8String(argOne.get(), valueStr);
2926 valueStr.TrimLeft();
2927 FXJSE_Value_SetInteger(args.GetReturnValue(), (!valueStr.IsEmpty()));
2999 } 2928 }
3000 2929
3001 // static 2930 // static
3002 void CXFA_FM2JSContext::Oneof(CFXJSE_Value* pThis, 2931 void CXFA_FM2JSContext::Oneof(CFXJSE_Value* pThis,
3003 const CFX_ByteStringC& szFuncName, 2932 const CFX_ByteStringC& szFuncName,
3004 CFXJSE_Arguments& args) { 2933 CFXJSE_Arguments& args) {
3005 if (args.GetLength() > 1) { 2934 if (args.GetLength() < 2) {
3006 FX_BOOL bFlags = FALSE;
3007 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
3008 CFXJSE_Value** parametersValue = nullptr;
3009 int32_t iCount = 0;
3010 unfoldArgs(pThis, args, parametersValue, iCount, 1);
3011 for (int32_t i = 0; i < iCount; i++) {
3012 if (simpleValueCompare(pThis, argOne.get(), parametersValue[i])) {
3013 bFlags = TRUE;
3014 break;
3015 }
3016 }
3017 FXJSE_Value_SetInteger(args.GetReturnValue(), bFlags);
3018 for (int32_t i = 0; i < iCount; i++) {
3019 delete parametersValue[i];
3020 }
3021 FX_Free(parametersValue);
3022 } else {
3023 ToJSContext(pThis, nullptr) 2935 ToJSContext(pThis, nullptr)
3024 ->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Oneof"); 2936 ->ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"Oneof");
2937 return;
3025 } 2938 }
2939
2940 FX_BOOL bFlags = FALSE;
2941 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
2942 CFXJSE_Value** parametersValue = nullptr;
2943 int32_t iCount = 0;
2944 unfoldArgs(pThis, args, parametersValue, iCount, 1);
2945 for (int32_t i = 0; i < iCount; i++) {
2946 if (simpleValueCompare(pThis, argOne.get(), parametersValue[i])) {
2947 bFlags = TRUE;
2948 break;
2949 }
2950 }
2951 for (int32_t i = 0; i < iCount; i++)
2952 delete parametersValue[i];
2953 FX_Free(parametersValue);
2954
2955 FXJSE_Value_SetInteger(args.GetReturnValue(), bFlags);
3026 } 2956 }
3027 2957
3028 // static 2958 // static
3029 void CXFA_FM2JSContext::Within(CFXJSE_Value* pThis, 2959 void CXFA_FM2JSContext::Within(CFXJSE_Value* pThis,
3030 const CFX_ByteStringC& szFuncName, 2960 const CFX_ByteStringC& szFuncName,
3031 CFXJSE_Arguments& args) { 2961 CFXJSE_Arguments& args) {
3032 if (args.GetLength() == 3) { 2962 if (args.GetLength() == 3) {
3033 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0); 2963 std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
3034 if (FXJSE_Value_IsNull(argOne.get())) { 2964 if (FXJSE_Value_IsNull(argOne.get())) {
3035 FXJSE_Value_SetUndefined(args.GetReturnValue()); 2965 FXJSE_Value_SetUndefined(args.GetReturnValue());
(...skipping 3734 matching lines...) Expand 10 before | Expand all | Expand 10 after
6770 CFX_WideString wsFormat; 6700 CFX_WideString wsFormat;
6771 pAppProvider->LoadString(iStringID, wsFormat); 6701 pAppProvider->LoadString(iStringID, wsFormat);
6772 CFX_WideString wsMessage; 6702 CFX_WideString wsMessage;
6773 va_list arg_ptr; 6703 va_list arg_ptr;
6774 va_start(arg_ptr, iStringID); 6704 va_start(arg_ptr, iStringID);
6775 wsMessage.FormatV(wsFormat.c_str(), arg_ptr); 6705 wsMessage.FormatV(wsFormat.c_str(), arg_ptr);
6776 va_end(arg_ptr); 6706 va_end(arg_ptr);
6777 FXJSE_ThrowMessage( 6707 FXJSE_ThrowMessage(
6778 "", FX_UTF8Encode(wsMessage.c_str(), wsMessage.GetLength()).AsStringC()); 6708 "", FX_UTF8Encode(wsMessage.c_str(), wsMessage.GetLength()).AsStringC());
6779 } 6709 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698