LCOV - code coverage report
Current view: top level - src/util - moneystr.cpp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 51 52 98.1 %
Date: 2026-06-25 07:23:51 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      149186 : 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      149186 :     int64_t quotient = n / COIN;
      22      149186 :     int64_t remainder = n % COIN;
      23      149186 :     if (n < 0) {
      24          12 :         quotient = -quotient;
      25          12 :         remainder = -remainder;
      26          12 :     }
      27      149186 :     std::string str = strprintf("%d.%08d", quotient, remainder);
      28             : 
      29             :     // Right-trim excess zeros before the decimal point:
      30      149186 :     int nTrim = 0;
      31      912446 :     for (int i = str.size()-1; (str[i] == '0' && IsDigit(str[i-2])); --i)
      32      374722 :         ++nTrim;
      33      149186 :     if (nTrim)
      34      119508 :         str.erase(str.size()-nTrim, nTrim);
      35             : 
      36      149186 :     if (n < 0)
      37          12 :         str.insert(uint32_t{0}, 1, '-');
      38      149186 :     return str;
      39      149186 : }
      40             : 
      41             : 
      42         137 : std::optional<CAmount> ParseMoney(const std::string& money_string)
      43             : {
      44         137 :     if (!ContainsNoNUL(money_string)) {
      45           6 :         return std::nullopt;
      46             :     }
      47         131 :     const std::string str = TrimString(money_string);
      48         131 :     if (str.empty()) {
      49           6 :         return std::nullopt;
      50             :     }
      51             : 
      52         125 :     std::string strWhole;
      53         125 :     int64_t nUnits = 0;
      54         125 :     const char* p = str.c_str();
      55         344 :     for (; *p; p++)
      56             :     {
      57         309 :         if (*p == '.')
      58             :         {
      59          76 :             p++;
      60          76 :             int64_t nMult = COIN / 10;
      61         313 :             while (IsDigit(*p) && (nMult > 0))
      62             :             {
      63         237 :                 nUnits += nMult * (*p++ - '0');
      64         237 :                 nMult /= 10;
      65             :             }
      66          76 :             break;
      67             :         }
      68         233 :         if (IsSpace(*p))
      69           8 :             return std::nullopt;
      70         225 :         if (!IsDigit(*p))
      71           6 :             return std::nullopt;
      72         219 :         strWhole.insert(strWhole.end(), *p);
      73         219 :     }
      74         111 :     if (*p) {
      75           8 :         return std::nullopt;
      76             :     }
      77         103 :     if (strWhole.size() > 10) // guard against 63 bit overflow
      78           2 :         return std::nullopt;
      79         101 :     if (nUnits < 0 || nUnits > COIN)
      80           0 :         return std::nullopt;
      81         101 :     int64_t nWhole = LocaleIndependentAtoi<int64_t>(strWhole);
      82         101 :     CAmount value = nWhole * COIN + nUnits;
      83             : 
      84         101 :     if (!MoneyRange(value)) {
      85           2 :         return std::nullopt;
      86             :     }
      87             : 
      88          99 :     return value;
      89         137 : }

Generated by: LCOV version 1.16