OLD | NEW |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |