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