Changeset View
Changeset View
Standalone View
Standalone View
src/util/moneystr.cpp
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2015 The Bitcoin Core developers | // Copyright (c) 2009-2015 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <util/moneystr.h> | #include <util/moneystr.h> | ||||
#include <tinyformat.h> | #include <tinyformat.h> | ||||
#include <util/strencodings.h> | #include <util/strencodings.h> | ||||
#include <util/string.h> | #include <util/string.h> | ||||
std::string FormatMoney(const Amount amt) { | std::string FormatMoney(const Amount amt) { | ||||
// Note: not using straight sprintf here because we do NOT want localized | // Note: not using straight sprintf here because we do NOT want localized | ||||
// number formatting. | // number formatting. | ||||
Amount amt_abs = amt > Amount::zero() ? amt : -amt; | Amount amt_abs = amt > Amount::zero() ? amt : -amt; | ||||
const auto currency = Currency::get(); | |||||
std::string str = | std::string str = | ||||
strprintf("%d.%08d", amt_abs / COIN, (amt_abs % COIN) / SATOSHI); | strprintf("%d.%0*d", amt_abs / currency.unit(), currency.decimals(), | ||||
(amt_abs % currency.unit()) / currency.subunit()); | |||||
// Right-trim excess zeros before the decimal point: | // Right-trim excess zeros before the decimal point: | ||||
int nTrim = 0; | int nTrim = 0; | ||||
for (int i = str.size() - 1; (str[i] == '0' && IsDigit(str[i - 2])); --i) { | for (int i = str.size() - 1; (str[i] == '0' && IsDigit(str[i - 2])); --i) { | ||||
++nTrim; | ++nTrim; | ||||
} | } | ||||
if (nTrim) { | if (nTrim) { | ||||
str.erase(str.size() - nTrim, nTrim); | str.erase(str.size() - nTrim, nTrim); | ||||
Show All 9 Lines | bool ParseMoney(const std::string &money_string, Amount &nRet) { | ||||
if (!ValidAsCString(money_string)) { | if (!ValidAsCString(money_string)) { | ||||
return false; | return false; | ||||
} | } | ||||
const std::string str = TrimString(money_string); | const std::string str = TrimString(money_string); | ||||
if (str.empty()) { | if (str.empty()) { | ||||
return false; | return false; | ||||
} | } | ||||
const auto currency = Currency::get(); | |||||
std::string strWhole; | std::string strWhole; | ||||
Amount nUnits = Amount::zero(); | Amount nUnits = Amount::zero(); | ||||
const char *p = str.c_str(); | const char *p = str.c_str(); | ||||
for (; *p; p++) { | for (; *p; p++) { | ||||
if (*p == '.') { | if (*p == '.') { | ||||
p++; | p++; | ||||
Amount nMult = COIN / 10; | Amount nMult = currency.unit() / 10; | ||||
while (IsDigit(*p) && (nMult > Amount::zero())) { | while (IsDigit(*p) && (nMult > Amount::zero())) { | ||||
nUnits += (*p++ - '0') * nMult; | nUnits += (*p++ - '0') * nMult; | ||||
nMult /= 10; | nMult /= 10; | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
if (IsSpace(*p)) { | if (IsSpace(*p)) { | ||||
return false; | return false; | ||||
} | } | ||||
if (!IsDigit(*p)) { | if (!IsDigit(*p)) { | ||||
return false; | return false; | ||||
} | } | ||||
strWhole.insert(strWhole.end(), *p); | strWhole.insert(strWhole.end(), *p); | ||||
} | } | ||||
if (*p) { | if (*p) { | ||||
return false; | return false; | ||||
} | } | ||||
// guard against 63 bit overflow | // guard against 63 bit overflow | ||||
if (strWhole.size() > 10) { | if (strWhole.size() > 10) { | ||||
return false; | return false; | ||||
} | } | ||||
if (nUnits < Amount::zero() || nUnits > COIN) { | if (nUnits < Amount::zero() || nUnits > currency.unit()) { | ||||
return false; | return false; | ||||
} | } | ||||
Amount nWhole = atoi64(strWhole) * COIN; | Amount nWhole = atoi64(strWhole) * currency.unit(); | ||||
nRet = nWhole + Amount(nUnits); | nRet = nWhole + Amount(nUnits); | ||||
return true; | return true; | ||||
} | } |