Bitcoin ABC  0.22.12
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 <tinyformat.h>
9 #include <util/strencodings.h>
10 #include <util/string.h>
11 
12 std::string FormatMoney(const Amount amt) {
13  // Note: not using straight sprintf here because we do NOT want localized
14  // number formatting.
15  Amount amt_abs = amt > Amount::zero() ? amt : -amt;
16  std::string str =
17  strprintf("%d.%08d", amt_abs / COIN, (amt_abs % COIN) / SATOSHI);
18 
19  // Right-trim excess zeros before the decimal point:
20  int nTrim = 0;
21  for (int i = str.size() - 1; (str[i] == '0' && IsDigit(str[i - 2])); --i) {
22  ++nTrim;
23  }
24  if (nTrim) {
25  str.erase(str.size() - nTrim, nTrim);
26  }
27 
28  if (amt < Amount::zero()) {
29  str.insert((unsigned int)0, 1, '-');
30  }
31  return str;
32 }
33 
34 bool ParseMoney(const std::string &money_string, Amount &nRet) {
35  if (!ValidAsCString(money_string)) {
36  return false;
37  }
38  const std::string str = TrimString(money_string);
39  if (str.empty()) {
40  return false;
41  }
42 
43  std::string strWhole;
44  Amount nUnits = Amount::zero();
45  const char *p = str.c_str();
46  for (; *p; p++) {
47  if (*p == '.') {
48  p++;
49  Amount nMult = COIN / 10;
50  while (IsDigit(*p) && (nMult > Amount::zero())) {
51  nUnits += (*p++ - '0') * nMult;
52  nMult /= 10;
53  }
54  break;
55  }
56  if (IsSpace(*p)) {
57  return false;
58  }
59  if (!IsDigit(*p)) {
60  return false;
61  }
62  strWhole.insert(strWhole.end(), *p);
63  }
64  if (*p) {
65  return false;
66  }
67  // guard against 63 bit overflow
68  if (strWhole.size() > 10) {
69  return false;
70  }
71  if (nUnits < Amount::zero() || nUnits > COIN) {
72  return false;
73  }
74 
75  Amount nWhole = atoi64(strWhole) * COIN;
76 
77  nRet = nWhole + Amount(nUnits);
78  return true;
79 }
static constexpr Amount zero()
Definition: amount.h:35
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1201
NODISCARD bool ValidAsCString(const std::string &str) noexcept
Check if a string does not contain any embedded NUL (\0) characters.
Definition: string.h:60
constexpr bool IsDigit(char c)
Tests if the given character is a decimal digit.
Definition: strencodings.h:74
Definition: amount.h:17
static constexpr Amount SATOSHI
Definition: amount.h:151
static constexpr Amount COIN
Definition: amount.h:153
NODISCARD std::string TrimString(const std::string &str, const std::string &pattern=" \\\)
Definition: string.h:17
int64_t atoi64(const char *psz)
bool ParseMoney(const std::string &money_string, Amount &nRet)
Parse an amount denoted in full coins.
Definition: moneystr.cpp:34
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
Definition: strencodings.h:90
std::string FormatMoney(const Amount amt)
Money parsing/formatting utilities.
Definition: moneystr.cpp:12