Bitcoin ABC 0.33.10
P2P Digital Currency
moneystr.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2015 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
13std::string FormatMoney(const Amount amt) {
14 // Note: not using straight sprintf here because we do NOT want localized
15 // number formatting.
16 const auto &currency = Currency::get();
17 int64_t quotient = amt / currency.baseunit;
18 int64_t remainder = (amt % currency.baseunit) / currency.subunit;
19 if (amt < Amount::zero()) {
20 quotient = -quotient;
21 remainder = -remainder;
22 }
23 std::string str =
24 strprintf("%d.%0*d", quotient, currency.decimals, remainder);
25
26 // Right-trim excess zeros before the decimal point:
27 int nTrim = 0;
28 for (int i = str.size() - 1; (str[i] == '0' && IsDigit(str[i - 2])); --i) {
29 ++nTrim;
30 }
31 if (nTrim) {
32 str.erase(str.size() - nTrim, nTrim);
33 }
34
35 if (amt < Amount::zero()) {
36 str.insert((unsigned int)0, 1, '-');
37 }
38 return str;
39}
40
41bool ParseMoney(const std::string &money_string, Amount &nRet) {
42 if (!util::ContainsNoNUL(money_string)) {
43 return false;
44 }
45 const std::string str = util::TrimString(money_string);
46 if (str.empty()) {
47 return false;
48 }
49
50 const auto &currency = Currency::get();
51 std::string strWhole;
52 Amount nUnits = Amount::zero();
53 const char *p = str.c_str();
54 for (; *p; p++) {
55 if (*p == '.') {
56 p++;
57 Amount nMult = currency.baseunit / 10;
58 while (IsDigit(*p) && (nMult > Amount::zero())) {
59 nUnits += (*p++ - '0') * nMult;
60 nMult /= 10;
61 }
62 break;
63 }
64 if (IsSpace(*p)) {
65 return false;
66 }
67 if (!IsDigit(*p)) {
68 return false;
69 }
70 strWhole.insert(strWhole.end(), *p);
71 }
72 if (*p) {
73 return false;
74 }
75
76 // Make sure the following overflow check is meaningful. It's fine to assert
77 // because it's on no critical path, and it's very unlikely to support a 19
78 // decimal (or more) currency anyway.
79 assert(currency.decimals <= 18);
80
81 // guard against 63 bit overflow
82 if (strWhole.size() > (size_t(18) - currency.decimals)) {
83 return false;
84 }
85 if (nUnits < Amount::zero() || nUnits > currency.baseunit) {
86 return false;
87 }
88
89 Amount nWhole =
90 LocaleIndependentAtoi<int64_t>(strWhole) * currency.baseunit;
91
92 nRet = nWhole + Amount(nUnits);
93 return true;
94}
std::string FormatMoney(const Amount amt)
Do not use these functions to represent or parse monetary amounts to or from JSON but use AmountFromV...
Definition: moneystr.cpp:13
bool ParseMoney(const std::string &money_string, Amount &nRet)
Parse an amount denoted in full coins.
Definition: moneystr.cpp:41
std::string TrimString(std::string_view str, std::string_view pattern=" \f\n\r\t\v")
Definition: string.h:80
bool ContainsNoNUL(std::string_view str) noexcept
Check if a string does not contain any embedded NUL (\0) characters.
Definition: string.h:140
constexpr bool IsDigit(char c)
Tests if the given character is a decimal digit.
Definition: strencodings.h:133
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
Definition: strencodings.h:149
Definition: amount.h:23
static constexpr Amount zero() noexcept
Definition: amount.h:36
static const Currency & get()
Definition: amount.cpp:25
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1202
assert(!tx.IsCoinBase())