LCOV - code coverage report
Current view: top level - src/util - moneystr.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 18 52 34.6 %
Date: 2023-09-26 12:08:55 Functions: 2 3 66.7 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2022 The Bitcoin Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #include <util/moneystr.h>
       7             : 
       8             : #include <consensus/amount.h>
       9             : #include <tinyformat.h>
      10             : #include <util/strencodings.h>
      11             : #include <util/string.h>
      12             : 
      13             : #include <cstdint>
      14             : #include <optional>
      15             : 
      16        4665 : std::string FormatMoney(const CAmount n)
      17             : {
      18             :     // Note: not using straight sprintf here because we do NOT want
      19             :     // localized number formatting.
      20             :     static_assert(COIN > 1);
      21        4665 :     int64_t quotient = n / COIN;
      22        4665 :     int64_t remainder = n % COIN;
      23        4665 :     if (n < 0) {
      24        3389 :         quotient = -quotient;
      25        3389 :         remainder = -remainder;
      26        3389 :     }
      27        4665 :     std::string str = strprintf("%d.%08d", quotient, remainder);
      28             : 
      29             :     // Right-trim excess zeros before the decimal point:
      30        4665 :     int nTrim = 0;
      31        6156 :     for (int i = str.size()-1; (str[i] == '0' && IsDigit(str[i-2])); --i)
      32         718 :         ++nTrim;
      33        4665 :     if (nTrim)
      34         396 :         str.erase(str.size()-nTrim, nTrim);
      35             : 
      36        4665 :     if (n < 0)
      37        3389 :         str.insert(uint32_t{0}, 1, '-');
      38        4665 :     return str;
      39        4665 : }
      40             : 
      41             : 
      42           0 : std::optional<CAmount> ParseMoney(const std::string& money_string)
      43             : {
      44           0 :     if (!ContainsNoNUL(money_string)) {
      45           0 :         return std::nullopt;
      46             :     }
      47           0 :     const std::string str = TrimString(money_string);
      48           0 :     if (str.empty()) {
      49           0 :         return std::nullopt;
      50             :     }
      51             : 
      52           0 :     std::string strWhole;
      53           0 :     int64_t nUnits = 0;
      54           0 :     const char* p = str.c_str();
      55           0 :     for (; *p; p++)
      56             :     {
      57           0 :         if (*p == '.')
      58             :         {
      59           0 :             p++;
      60           0 :             int64_t nMult = COIN / 10;
      61           0 :             while (IsDigit(*p) && (nMult > 0))
      62             :             {
      63           0 :                 nUnits += nMult * (*p++ - '0');
      64           0 :                 nMult /= 10;
      65             :             }
      66           0 :             break;
      67             :         }
      68           0 :         if (IsSpace(*p))
      69           0 :             return std::nullopt;
      70           0 :         if (!IsDigit(*p))
      71           0 :             return std::nullopt;
      72           0 :         strWhole.insert(strWhole.end(), *p);
      73           0 :     }
      74           2 :     if (*p) {
      75           0 :         return std::nullopt;
      76             :     }
      77           0 :     if (strWhole.size() > 10) // guard against 63 bit overflow
      78           0 :         return std::nullopt;
      79           0 :     if (nUnits < 0 || nUnits > COIN)
      80           0 :         return std::nullopt;
      81           0 :     int64_t nWhole = LocaleIndependentAtoi<int64_t>(strWhole);
      82           0 :     CAmount value = nWhole * COIN + nUnits;
      83             : 
      84           0 :     if (!MoneyRange(value)) {
      85           0 :         return std::nullopt;
      86             :     }
      87             : 
      88           0 :     return value;
      89           0 : }

Generated by: LCOV version 1.14