Scorum
asset.cpp
Go to the documentation of this file.
2 #include <boost/rational.hpp>
3 #include <boost/multiprecision/cpp_int.hpp>
4 
5 /*
6 
7 The bounds on asset serialization are as follows:
8 
9 index : field
10 0 : decimals
11 1..6 : symbol
12  7 : \0
13 */
14 
15 namespace scorum {
16 namespace protocol {
18 
19 void asset::_check_symbol()
20 {
21  FC_ASSERT(SCORUM_SYMBOL == _symbol || SP_SYMBOL == _symbol,
22  "Invalid asset symbol received. ${1} not either ${2} or ${3}.",
23  ("1", _symbol)("2", SCORUM_SYMBOL)("3", SP_SYMBOL));
24 }
25 
26 void asset::_set_decimals(uint8_t d)
27 {
28  FC_ASSERT(d < 15);
29  auto a = (char*)&_symbol;
30  a[0] = d;
31 }
32 
33 uint8_t asset::decimals() const
34 {
35  auto a = (const char*)&_symbol;
36  uint8_t result = uint8_t(a[0]);
37  FC_ASSERT(result < 15);
38  return result;
39 }
40 
41 std::string asset::symbol_name() const
42 {
43  auto a = (const char*)&_symbol;
44  FC_ASSERT(a[7] == 0);
45  return &a[1];
46 }
47 
48 int64_t asset::precision() const
49 {
50  static int64_t table[] = { 1,
51  10,
52  100,
53  1000,
54  10000,
55  100000,
56  1000000,
57  10000000,
58  100000000ll,
59  1000000000ll,
60  10000000000ll,
61  100000000000ll,
62  1000000000000ll,
63  10000000000000ll,
64  100000000000000ll };
65  uint8_t d = decimals();
66  return table[d];
67 }
68 
69 std::string asset::to_string() const
70 {
71  int64_t prec = precision();
72  std::string result = fc::to_string(amount.value / prec);
73  if (prec > 1)
74  {
75  auto fract = amount.value % prec;
76  // prec is a power of ten, so for example when working with
77  // 7.005 we have fract = 5, prec = 1000. So prec+fract=1005
78  // has the correct number of zeros and we can simply trim the
79  // leading 1.
80  result += "." + fc::to_string(prec + fract).erase(0, 1);
81  }
82  return result + " " + symbol_name();
83 }
84 
85 asset asset::from_string(const std::string& from)
86 {
87  try
88  {
89  std::string s = fc::trim(from);
90  auto space_pos = s.find(" ");
91  auto dot_pos = s.find(".");
92 
93  FC_ASSERT(space_pos != std::string::npos);
94 
95  asset result;
96  result._symbol = uint64_t(0);
97  auto sy = (char*)&result._symbol;
98 
99  if (dot_pos != std::string::npos)
100  {
101  FC_ASSERT(space_pos > dot_pos);
102 
103  auto intpart = s.substr(0, dot_pos);
104  auto fractpart = "1" + s.substr(dot_pos + 1, space_pos - dot_pos - 1);
105  result._set_decimals(fractpart.size() - 1);
106 
107  result.amount = fc::to_int64(intpart);
108  result.amount.value *= result.precision();
109  result.amount.value += fc::to_int64(fractpart);
110  result.amount.value -= result.precision();
111  }
112  else
113  {
114  auto intpart = s.substr(0, space_pos);
115  result.amount = fc::to_int64(intpart);
116  result._set_decimals(0);
117  }
118  auto symbol = s.substr(space_pos + 1);
119  size_t symbol_size = symbol.size();
120 
121  if (symbol_size > 0)
122  {
123  FC_ASSERT(symbol_size <= 6);
124  memcpy(sy + 1, symbol.c_str(), symbol_size);
125  }
126 
127  result._check_symbol();
128  return result;
129  }
130  FC_CAPTURE_AND_RETHROW((from))
131 }
132 }
133 } // scorum::protocol
#define SP_SYMBOL
Definition: config.hpp:104
#define SCORUM_SYMBOL
Definition: config.hpp:102
boost::multiprecision::int128_t int128_t
Definition: asset.cpp:17
Definition: asset.cpp:15
asset_symbol_type symbol() const
Definition: asset.hpp:32
std::string to_string() const
Definition: asset.cpp:69
int64_t precision() const
Definition: asset.cpp:48
share_type amount
Definition: asset.hpp:31
static asset from_string(const std::string &from)
Definition: asset.cpp:85
std::string symbol_name() const
Definition: asset.cpp:41
uint8_t decimals() const
Definition: asset.cpp:33