1 #include <util/tokenstr.h>
2
3 #include <tinyformat.h>
4 #include <util/strencodings.h>
5 #include <util/string.h>
6
powBase10(unsigned int exponent)7 dev::s256 powBase10(unsigned int exponent)
8 {
9 if(exponent == 0)
10 return 0;
11 dev::s256 power = 1;
12 for(unsigned int i = 0; i < exponent; i++){
13 power *= 10;
14 }
15 return power;
16 }
17
FormatToken(const unsigned int & decimals,const dev::s256 & n)18 std::string FormatToken(const unsigned int& decimals, const dev::s256& n)
19 {
20 // Note: not using straight sprintf here because we do NOT want
21 // localized number formatting.
22 dev::s256 coin = powBase10(decimals);
23 dev::s256 n_abs = (n > 0 ? n : -n);
24 dev::s256 quotient = n_abs/coin;
25 dev::s256 remainder = n_abs%coin;
26 std::string strQuotient = quotient.str();
27 std::string strRemainder = remainder.str();
28 while(strRemainder.size() < decimals)
29 strRemainder.insert(0, 1, '0');
30 std::string str = strprintf("%s.%s", strQuotient, strRemainder);
31
32 if (n < 0)
33 str.insert((unsigned int)0, 1, '-');
34 return str;
35 }
36
37
ParseToken(const unsigned int & decimals,const std::string & token_string,dev::s256 & nRet)38 bool ParseToken(const unsigned int& decimals, const std::string& token_string, dev::s256& nRet)
39 {
40 if (!ValidAsCString(token_string)) {
41 return false;
42 }
43 const std::string str = TrimString(token_string);
44 if (str.empty()) {
45 return false;
46 }
47
48 dev::s256 coin = powBase10(decimals);
49 std::string strWhole;
50 dev::s256 nUnits = 0;
51 const char* p = str.c_str();
52 for (; *p; p++)
53 {
54 if (*p == '.')
55 {
56 p++;
57 dev::s256 nMult = coin / 10;
58 while (IsDigit(*p) && (nMult > 0))
59 {
60 nUnits += nMult * (*p++ - '0');
61 nMult /= 10;
62 }
63 break;
64 }
65 if (IsSpace(*p))
66 return false;
67 if (!IsDigit(*p))
68 return false;
69 strWhole.insert(strWhole.end(), *p);
70 }
71 if (*p) {
72 return false;
73 }
74 if (strWhole.size() > (77 - decimals)) // guard against 256 bit overflow
75 return false;
76 if (nUnits < 0 || nUnits > coin)
77 return false;
78 dev::s256 nWhole = dev::s256(strWhole);
79 dev::s256 nValue = nWhole*coin + nUnits;
80
81 nRet = nValue;
82 return true;
83 }
84