LCOV - code coverage report
Current view: top level - src/util - moneystr.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 51 52 98.1 %
Date: 2026-06-25 07:23:43 Functions: 2 2 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2021 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      216929 : 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      216929 :     int64_t quotient = n / COIN;
      22      216929 :     int64_t remainder = n % COIN;
      23      216929 :     if (n < 0) {
      24          24 :         quotient = -quotient;
      25          24 :         remainder = -remainder;
      26          24 :     }
      27      216929 :     std::string str = strprintf("%d.%08d", quotient, remainder);
      28             : 
      29             :     // Right-trim excess zeros before the decimal point:
      30      216929 :     int nTrim = 0;
      31     1639925 :     for (int i = str.size()-1; (str[i] == '0' && IsDigit(str[i-2])); --i)
      32      685924 :         ++nTrim;
      33      216929 :     if (nTrim)
      34      184087 :         str.erase(str.size()-nTrim, nTrim);
      35             : 
      36      216929 :     if (n < 0)
      37          24 :         str.insert(uint32_t{0}, 1, '-');
      38      216929 :     return str;
      39      216929 : }
      40             : 
      41             : 
      42        2538 : std::optional<CAmount> ParseMoney(const std::string& money_string)
      43             : {
      44        2538 :     if (!ContainsNoNUL(money_string)) {
      45           6 :         return std::nullopt;
      46             :     }
      47        2532 :     const std::string str = TrimString(money_string);
      48        2532 :     if (str.empty()) {
      49           6 :         return std::nullopt;
      50             :     }
      51             : 
      52        2526 :     std::string strWhole;
      53        2526 :     int64_t nUnits = 0;
      54        2526 :     const char* p = str.c_str();
      55        5146 :     for (; *p; p++)
      56             :     {
      57        4989 :         if (*p == '.')
      58             :         {
      59        2355 :             p++;
      60        2355 :             int64_t nMult = COIN / 10;
      61       13935 :             while (IsDigit(*p) && (nMult > 0))
      62             :             {
      63       11580 :                 nUnits += nMult * (*p++ - '0');
      64       11580 :                 nMult /= 10;
      65             :             }
      66        2355 :             break;
      67             :         }
      68        2634 :         if (IsSpace(*p))
      69           8 :             return std::nullopt;
      70        2626 :         if (!IsDigit(*p))
      71           6 :             return std::nullopt;
      72        2620 :         strWhole.insert(strWhole.end(), *p);
      73        2620 :     }
      74        2512 :     if (*p) {
      75           8 :         return std::nullopt;
      76             :     }
      77        2504 :     if (strWhole.size() > 10) // guard against 63 bit overflow
      78           2 :         return std::nullopt;
      79        2502 :     if (nUnits < 0 || nUnits > COIN)
      80           0 :         return std::nullopt;
      81        2502 :     int64_t nWhole = LocaleIndependentAtoi<int64_t>(strWhole);
      82        2502 :     CAmount value = nWhole * COIN + nUnits;
      83             : 
      84        2502 :     if (!MoneyRange(value)) {
      85           2 :         return std::nullopt;
      86             :     }
      87             : 
      88        2500 :     return value;
      89        2538 : }

Generated by: LCOV version 1.16