LCOV - code coverage report
Current view: top level - src/util - moneystr.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 50 52 96.2 %
Date: 2023-10-05 15:40:34 Functions: 3 3 100.0 %
Branches: 45 60 75.0 %

           Branch data     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                 :     355089 : 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                 :     355089 :     int64_t quotient = n / COIN;
      22                 :     355089 :     int64_t remainder = n % COIN;
      23         [ +  + ]:     355089 :     if (n < 0) {
      24                 :     142851 :         quotient = -quotient;
      25                 :     142851 :         remainder = -remainder;
      26                 :     142851 :     }
      27                 :     355089 :     std::string str = strprintf("%d.%08d", quotient, remainder);
      28                 :            : 
      29                 :            :     // Right-trim excess zeros before the decimal point:
      30                 :     355089 :     int nTrim = 0;
      31   [ +  -  +  +  :     527013 :     for (int i = str.size()-1; (str[i] == '0' && IsDigit(str[i-2])); --i)
          +  -  +  -  +  
                      + ]
      32                 :      83108 :         ++nTrim;
      33         [ +  + ]:     355089 :     if (nTrim)
      34         [ +  - ]:      35456 :         str.erase(str.size()-nTrim, nTrim);
      35                 :            : 
      36         [ +  + ]:     355089 :     if (n < 0)
      37         [ +  - ]:     142851 :         str.insert(uint32_t{0}, 1, '-');
      38                 :     355089 :     return str;
      39         [ +  - ]:     355089 : }
      40                 :            : 
      41                 :            : 
      42                 :        222 : std::optional<CAmount> ParseMoney(const std::string& money_string)
      43                 :            : {
      44         [ +  + ]:        222 :     if (!ContainsNoNUL(money_string)) {
      45                 :          1 :         return std::nullopt;
      46                 :            :     }
      47                 :        221 :     const std::string str = TrimString(money_string);
      48         [ +  + ]:        221 :     if (str.empty()) {
      49                 :          1 :         return std::nullopt;
      50                 :            :     }
      51                 :            : 
      52                 :        220 :     std::string strWhole;
      53                 :        220 :     int64_t nUnits = 0;
      54                 :        220 :     const char* p = str.c_str();
      55         [ +  + ]:     611263 :     for (; *p; p++)
      56                 :            :     {
      57         [ +  + ]:     611228 :         if (*p == '.')
      58                 :            :         {
      59                 :         60 :             p++;
      60                 :         60 :             int64_t nMult = COIN / 10;
      61   [ +  -  +  +  :        433 :             while (IsDigit(*p) && (nMult > 0))
                   +  + ]
      62                 :            :             {
      63                 :        373 :                 nUnits += nMult * (*p++ - '0');
      64                 :        373 :                 nMult /= 10;
      65                 :            :             }
      66                 :         60 :             break;
      67                 :            :         }
      68         [ +  - ]:     611168 :         if (IsSpace(*p))
      69                 :          0 :             return std::nullopt;
      70   [ +  -  +  + ]:     611168 :         if (!IsDigit(*p))
      71                 :        125 :             return std::nullopt;
      72         [ +  - ]:     611043 :         strWhole.insert(strWhole.end(), *p);
      73                 :     611043 :     }
      74         [ +  + ]:        268 :     if (*p) {
      75                 :         10 :         return std::nullopt;
      76                 :            :     }
      77         [ +  + ]:         85 :     if (strWhole.size() > 10) // guard against 63 bit overflow
      78                 :         35 :         return std::nullopt;
      79   [ +  -  +  - ]:         50 :     if (nUnits < 0 || nUnits > COIN)
      80                 :          0 :         return std::nullopt;
      81         [ +  - ]:         50 :     int64_t nWhole = LocaleIndependentAtoi<int64_t>(strWhole);
      82                 :         50 :     CAmount value = nWhole * COIN + nUnits;
      83                 :            : 
      84   [ +  -  +  + ]:         50 :     if (!MoneyRange(value)) {
      85                 :          9 :         return std::nullopt;
      86                 :            :     }
      87                 :            : 
      88         [ +  - ]:         41 :     return value;
      89                 :        222 : }

Generated by: LCOV version 1.14