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