Branch data Line data Source code
# 1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto # 2 : : // Copyright (c) 2009-2020 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 <tinyformat.h> # 9 : : #include <util/strencodings.h> # 10 : : #include <util/string.h> # 11 : : # 12 : : std::string FormatMoney(const CAmount n) # 13 : 123458 : { # 14 : : // Note: not using straight sprintf here because we do NOT want # 15 : : // localized number formatting. # 16 : 123458 : static_assert(COIN > 1); # 17 : 123458 : int64_t quotient = n / COIN; # 18 : 123458 : int64_t remainder = n % COIN; # 19 [ + + ]: 123458 : if (n < 0) { # 20 : 15 : quotient = -quotient; # 21 : 15 : remainder = -remainder; # 22 : 15 : } # 23 : 123458 : std::string str = strprintf("%d.%08d", quotient, remainder); # 24 : : # 25 : : // Right-trim excess zeros before the decimal point: # 26 : 123458 : int nTrim = 0; # 27 [ + + ][ + + ]: 541277 : for (int i = str.size()-1; (str[i] == '0' && IsDigit(str[i-2])); --i) # 28 : 417819 : ++nTrim; # 29 [ + + ]: 123458 : if (nTrim) # 30 : 122841 : str.erase(str.size()-nTrim, nTrim); # 31 : : # 32 [ + + ]: 123458 : if (n < 0) # 33 : 15 : str.insert((unsigned int)0, 1, '-'); # 34 : 123458 : return str; # 35 : 123458 : } # 36 : : # 37 : : # 38 : : bool ParseMoney(const std::string& money_string, CAmount& nRet) # 39 : 857 : { # 40 [ + + ]: 857 : if (!ValidAsCString(money_string)) { # 41 : 6 : return false; # 42 : 6 : } # 43 : 851 : const std::string str = TrimString(money_string); # 44 [ + + ]: 851 : if (str.empty()) { # 45 : 6 : return false; # 46 : 6 : } # 47 : : # 48 : 845 : std::string strWhole; # 49 : 845 : int64_t nUnits = 0; # 50 : 845 : const char* p = str.c_str(); # 51 [ + + ]: 1788 : for (; *p; p++) # 52 : 1778 : { # 53 [ + + ]: 1778 : if (*p == '.') # 54 : 827 : { # 55 : 827 : p++; # 56 : 827 : int64_t nMult = COIN / 10; # 57 [ + + ][ + + ]: 4191 : while (IsDigit(*p) && (nMult > 0)) # 58 : 3364 : { # 59 : 3364 : nUnits += nMult * (*p++ - '0'); # 60 : 3364 : nMult /= 10; # 61 : 3364 : } # 62 : 827 : break; # 63 : 827 : } # 64 [ + + ]: 951 : if (IsSpace(*p)) # 65 : 6 : return false; # 66 [ + + ]: 945 : if (!IsDigit(*p)) # 67 : 2 : return false; # 68 : 943 : strWhole.insert(strWhole.end(), *p); # 69 : 943 : } # 70 [ + + ]: 845 : if (*p) { # 71 : 4 : return false; # 72 : 4 : } # 73 [ + + ]: 833 : if (strWhole.size() > 10) // guard against 63 bit overflow # 74 : 2 : return false; # 75 [ - + ][ - + ]: 831 : if (nUnits < 0 || nUnits > COIN) # 76 : 0 : return false; # 77 : 831 : int64_t nWhole = atoi64(strWhole); # 78 : 831 : CAmount nValue = nWhole*COIN + nUnits; # 79 : : # 80 : 831 : nRet = nValue; # 81 : 831 : return true; # 82 : 831 : }