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 114267 : std::string FormatMoney(const CAmount& n) 13 : { 14 : // Note: not using straight sprintf here because we do NOT want 15 : // localized number formatting. 16 114267 : int64_t n_abs = (n > 0 ? n : -n); 17 114267 : int64_t quotient = n_abs/COIN; 18 114267 : int64_t remainder = n_abs%COIN; 19 114267 : std::string str = strprintf("%d.%08d", quotient, remainder); 20 : 21 : // Right-trim excess zeros before the decimal point: 22 : int nTrim = 0; 23 486838 : for (int i = str.size()-1; (str[i] == '0' && IsDigit(str[i-2])); --i) 24 372571 : ++nTrim; 25 114267 : if (nTrim) 26 113885 : str.erase(str.size()-nTrim, nTrim); 27 : 28 114267 : if (n < 0) 29 7 : str.insert((unsigned int)0, 1, '-'); 30 : return str; 31 114267 : } 32 : 33 : 34 880 : bool ParseMoney(const std::string& money_string, CAmount& nRet) 35 : { 36 880 : if (!ValidAsCString(money_string)) { 37 6 : return false; 38 : } 39 874 : const std::string str = TrimString(money_string); 40 874 : if (str.empty()) { 41 6 : return false; 42 : } 43 : 44 868 : std::string strWhole; 45 860 : int64_t nUnits = 0; 46 868 : const char* p = str.c_str(); 47 1834 : for (; *p; p++) 48 : { 49 1786 : if (*p == '.') 50 : { 51 812 : p++; 52 : int64_t nMult = COIN / 10; 53 4093 : while (IsDigit(*p) && (nMult > 0)) 54 : { 55 3281 : nUnits += nMult * (*p++ - '0'); 56 3281 : nMult /= 10; 57 : } 58 : break; 59 : } 60 974 : if (IsSpace(*p)) 61 6 : return false; 62 968 : if (!IsDigit(*p)) 63 2 : return false; 64 966 : strWhole.insert(strWhole.end(), *p); 65 : } 66 860 : if (*p) { 67 4 : return false; 68 : } 69 856 : if (strWhole.size() > 10) // guard against 63 bit overflow 70 2 : return false; 71 854 : if (nUnits < 0 || nUnits > COIN) 72 0 : return false; 73 854 : int64_t nWhole = atoi64(strWhole); 74 854 : CAmount nValue = nWhole*COIN + nUnits; 75 : 76 854 : nRet = nValue; 77 : return true; 78 880 : }