LCOV - code coverage report
Current view: top level - src - utilstrencodings.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 268 287 93.4 %
Date: 2015-10-12 22:39:14 Functions: 26 28 92.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 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 "utilstrencodings.h"
       7             : 
       8             : #include "tinyformat.h"
       9             : 
      10             : #include <cstdlib>
      11             : #include <cstring>
      12             : #include <errno.h>
      13             : #include <limits>
      14             : 
      15             : using namespace std;
      16             : 
      17         406 : static const string CHARS_ALPHA_NUM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
      18             : 
      19         609 : static const string SAFE_CHARS[] =
      20             : {
      21             :     CHARS_ALPHA_NUM + " .,;-_/:?@()", // SAFE_CHARS_DEFAULT
      22             :     CHARS_ALPHA_NUM + " .,;-_?@" // SAFE_CHARS_UA_COMMENT
      23         203 : };
      24             : 
      25       45953 : string SanitizeString(const string& str, int rule)
      26             : {
      27             :     string strResult;
      28      736394 :     for (std::string::size_type i = 0; i < str.size(); i++)
      29             :     {
      30      322244 :         if (SAFE_CHARS[rule].find(str[i]) != std::string::npos)
      31      322218 :             strResult.push_back(str[i]);
      32             :     }
      33       45953 :     return strResult;
      34             : }
      35             : 
      36             : const signed char p_util_hexdigit[256] =
      37             : { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      38             :   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      39             :   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      40             :   0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
      41             :   -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      42             :   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      43             :   -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      44             :   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      45             :   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      46             :   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      47             :   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      48             :   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      49             :   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      50             :   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      51             :   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      52             :   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
      53             : 
      54      394875 : signed char HexDigit(char c)
      55             : {
      56      993834 :     return p_util_hexdigit[(unsigned char)c];
      57             : }
      58             : 
      59        1785 : bool IsHex(const string& str)
      60             : {
      61      297619 :     for(std::string::const_iterator it(str.begin()); it != str.end(); ++it)
      62             :     {
      63      292288 :         if (HexDigit(*it) < 0)
      64             :             return false;
      65             :     }
      66        3544 :     return (str.size() > 0) && (str.size()%2 == 0);
      67             : }
      68             : 
      69        3643 : vector<unsigned char> ParseHex(const char* psz)
      70             : {
      71             :     // convert hex dump to vector
      72             :     vector<unsigned char> vch;
      73             :     while (true)
      74             :     {
      75      228233 :         while (isspace(*psz))
      76           4 :             psz++;
      77      456458 :         signed char c = HexDigit(*psz++);
      78      228229 :         if (c == (signed char)-1)
      79             :             break;
      80      224586 :         unsigned char n = (c << 4);
      81      449172 :         c = HexDigit(*psz++);
      82      224586 :         if (c == (signed char)-1)
      83             :             break;
      84      224586 :         n |= c;
      85      224586 :         vch.push_back(n);
      86             :     }
      87        3643 :     return vch;
      88             : }
      89             : 
      90        3017 : vector<unsigned char> ParseHex(const string& str)
      91             : {
      92        3017 :     return ParseHex(str.c_str());
      93             : }
      94             : 
      95         194 : string EncodeBase64(const unsigned char* pch, size_t len)
      96             : {
      97             :     static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      98             : 
      99         388 :     string strRet="";
     100         194 :     strRet.reserve((len+2)/3*4);
     101             : 
     102         194 :     int mode=0, left=0;
     103         194 :     const unsigned char *pchEnd = pch+len;
     104             : 
     105        1404 :     while (pch<pchEnd)
     106             :     {
     107        1016 :         int enc = *(pch++);
     108        1016 :         switch (mode)
     109             :         {
     110             :             case 0: // we have no bits
     111         403 :                 strRet += pbase64[enc >> 2];
     112         403 :                 left = (enc & 3) << 4;
     113         403 :                 mode = 1;
     114         403 :                 break;
     115             : 
     116             :             case 1: // we have two bits
     117         401 :                 strRet += pbase64[left | (enc >> 4)];
     118         401 :                 left = (enc & 15) << 2;
     119         401 :                 mode = 2;
     120         401 :                 break;
     121             : 
     122             :             case 2: // we have four bits
     123         212 :                 strRet += pbase64[left | (enc >> 6)];
     124         212 :                 strRet += pbase64[enc & 63];
     125             :                 mode = 0;
     126             :                 break;
     127             :         }
     128             :     }
     129             : 
     130         194 :     if (mode)
     131             :     {
     132         191 :         strRet += pbase64[left];
     133             :         strRet += '=';
     134         191 :         if (mode == 1)
     135             :             strRet += '=';
     136             :     }
     137             : 
     138         194 :     return strRet;
     139             : }
     140             : 
     141         193 : string EncodeBase64(const string& str)
     142             : {
     143         193 :     return EncodeBase64((const unsigned char*)str.c_str(), str.size());
     144             : }
     145             : 
     146        3542 : vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
     147             : {
     148             :     static const int decode64_table[256] =
     149             :     {
     150             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     151             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     152             :         -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
     153             :         -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
     154             :         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
     155             :         29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
     156             :         49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     157             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     158             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     159             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     160             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     161             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     162             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
     163             :     };
     164             : 
     165        3542 :     if (pfInvalid)
     166           3 :         *pfInvalid = false;
     167             : 
     168             :     vector<unsigned char> vchRet;
     169        3542 :     vchRet.reserve(strlen(p)*3/4);
     170             : 
     171             :     int mode = 0;
     172             :     int left = 0;
     173             : 
     174             :     while (1)
     175             :     {
     176       52140 :          int dec = decode64_table[(unsigned char)*p];
     177       52140 :          if (dec == -1) break;
     178       48598 :          p++;
     179       48598 :          switch (mode)
     180             :          {
     181             :              case 0: // we have no bits and get 6
     182       13034 :                  left = dec;
     183       13034 :                  mode = 1;
     184       13034 :                  break;
     185             : 
     186             :               case 1: // we have 6 bits and keep 4
     187       13034 :                   vchRet.push_back((left<<2) | (dec>>4));
     188       13034 :                   left = dec & 15;
     189       13034 :                   mode = 2;
     190       13034 :                   break;
     191             : 
     192             :              case 2: // we have 4 bits and get 6, we keep 2
     193       13029 :                  vchRet.push_back((left<<4) | (dec>>2));
     194       13029 :                  left = dec & 3;
     195       13029 :                  mode = 3;
     196       13029 :                  break;
     197             : 
     198             :              case 3: // we have 2 bits and get 6
     199        9501 :                  vchRet.push_back((left<<6) | dec);
     200        9501 :                  mode = 0;
     201        9501 :                  break;
     202             :          }
     203             :     }
     204             : 
     205        3542 :     if (pfInvalid)
     206           3 :         switch (mode)
     207             :         {
     208             :             case 0: // 4n base64 characters processed: ok
     209             :                 break;
     210             : 
     211             :             case 1: // 4n+1 base64 character processed: impossible
     212           0 :                 *pfInvalid = true;
     213           0 :                 break;
     214             : 
     215             :             case 2: // 4n+2 base64 characters processed: require '=='
     216           0 :                 if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
     217           0 :                     *pfInvalid = true;
     218             :                 break;
     219             : 
     220             :             case 3: // 4n+3 base64 characters processed: require '='
     221           3 :                 if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
     222           0 :                     *pfInvalid = true;
     223             :                 break;
     224             :         }
     225             : 
     226        3542 :     return vchRet;
     227             : }
     228             : 
     229        3526 : string DecodeBase64(const string& str)
     230             : {
     231        3526 :     vector<unsigned char> vchRet = DecodeBase64(str.c_str());
     232       21153 :     return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size());
     233             : }
     234             : 
     235          11 : string EncodeBase32(const unsigned char* pch, size_t len)
     236             : {
     237             :     static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
     238             : 
     239          22 :     string strRet="";
     240          11 :     strRet.reserve((len+4)/5*8);
     241             : 
     242          11 :     int mode=0, left=0;
     243          11 :     const unsigned char *pchEnd = pch+len;
     244             : 
     245          83 :     while (pch<pchEnd)
     246             :     {
     247          61 :         int enc = *(pch++);
     248          61 :         switch (mode)
     249             :         {
     250             :             case 0: // we have no bits
     251          15 :                 strRet += pbase32[enc >> 3];
     252          15 :                 left = (enc & 7) << 2;
     253          15 :                 mode = 1;
     254          15 :                 break;
     255             : 
     256             :             case 1: // we have three bits
     257          13 :                 strRet += pbase32[left | (enc >> 6)];
     258          13 :                 strRet += pbase32[(enc >> 1) & 31];
     259          13 :                 left = (enc & 1) << 4;
     260          13 :                 mode = 2;
     261          13 :                 break;
     262             : 
     263             :             case 2: // we have one bit
     264          12 :                 strRet += pbase32[left | (enc >> 4)];
     265          12 :                 left = (enc & 15) << 1;
     266          12 :                 mode = 3;
     267          12 :                 break;
     268             : 
     269             :             case 3: // we have four bits
     270          11 :                 strRet += pbase32[left | (enc >> 7)];
     271          11 :                 strRet += pbase32[(enc >> 2) & 31];
     272          11 :                 left = (enc & 3) << 3;
     273          11 :                 mode = 4;
     274          11 :                 break;
     275             : 
     276             :             case 4: // we have two bits
     277          10 :                 strRet += pbase32[left | (enc >> 5)];
     278          10 :                 strRet += pbase32[enc & 31];
     279             :                 mode = 0;
     280             :         }
     281             :     }
     282             : 
     283             :     static const int nPadding[5] = {0, 6, 4, 3, 1};
     284          11 :     if (mode)
     285             :     {
     286           5 :         strRet += pbase32[left];
     287          20 :         for (int n=0; n<nPadding[mode]; n++)
     288             :              strRet += '=';
     289             :     }
     290             : 
     291          11 :     return strRet;
     292             : }
     293             : 
     294           7 : string EncodeBase32(const string& str)
     295             : {
     296           7 :     return EncodeBase32((const unsigned char*)str.c_str(), str.size());
     297             : }
     298             : 
     299          11 : vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid)
     300             : {
     301             :     static const int decode32_table[256] =
     302             :     {
     303             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     304             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     305             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
     306             :         -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
     307             :         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1,  0,  1,  2,
     308             :          3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
     309             :         23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     310             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     311             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     312             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     313             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     314             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     315             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
     316             :     };
     317             : 
     318          11 :     if (pfInvalid)
     319           0 :         *pfInvalid = false;
     320             : 
     321             :     vector<unsigned char> vchRet;
     322          11 :     vchRet.reserve((strlen(p))*5/8);
     323             : 
     324             :     int mode = 0;
     325             :     int left = 0;
     326             : 
     327             :     while (1)
     328             :     {
     329         111 :          int dec = decode32_table[(unsigned char)*p];
     330         111 :          if (dec == -1) break;
     331         100 :          p++;
     332         100 :          switch (mode)
     333             :          {
     334             :              case 0: // we have no bits and get 5
     335          15 :                  left = dec;
     336          15 :                  mode = 1;
     337          15 :                  break;
     338             : 
     339             :               case 1: // we have 5 bits and keep 2
     340          15 :                   vchRet.push_back((left<<3) | (dec>>2));
     341          15 :                   left = dec & 3;
     342          15 :                   mode = 2;
     343          15 :                   break;
     344             : 
     345             :              case 2: // we have 2 bits and keep 7
     346          13 :                  left = left << 5 | dec;
     347          13 :                  mode = 3;
     348          13 :                  break;
     349             : 
     350             :              case 3: // we have 7 bits and keep 4
     351          13 :                  vchRet.push_back((left<<1) | (dec>>4));
     352          13 :                  left = dec & 15;
     353          13 :                  mode = 4;
     354          13 :                  break;
     355             : 
     356             :              case 4: // we have 4 bits, and keep 1
     357          12 :                  vchRet.push_back((left<<4) | (dec>>1));
     358          12 :                  left = dec & 1;
     359          12 :                  mode = 5;
     360          12 :                  break;
     361             : 
     362             :              case 5: // we have 1 bit, and keep 6
     363          11 :                  left = left << 5 | dec;
     364          11 :                  mode = 6;
     365          11 :                  break;
     366             : 
     367             :              case 6: // we have 6 bits, and keep 3
     368          11 :                  vchRet.push_back((left<<2) | (dec>>3));
     369          11 :                  left = dec & 7;
     370          11 :                  mode = 7;
     371          11 :                  break;
     372             : 
     373             :              case 7: // we have 3 bits, and keep 0
     374          10 :                  vchRet.push_back((left<<5) | dec);
     375          10 :                  mode = 0;
     376          10 :                  break;
     377             :          }
     378             :     }
     379             : 
     380          11 :     if (pfInvalid)
     381           0 :         switch (mode)
     382             :         {
     383             :             case 0: // 8n base32 characters processed: ok
     384             :                 break;
     385             : 
     386             :             case 1: // 8n+1 base32 characters processed: impossible
     387             :             case 3: //   +3
     388             :             case 6: //   +6
     389           0 :                 *pfInvalid = true;
     390           0 :                 break;
     391             : 
     392             :             case 2: // 8n+2 base32 characters processed: require '======'
     393           0 :                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1)
     394           0 :                     *pfInvalid = true;
     395             :                 break;
     396             : 
     397             :             case 4: // 8n+4 base32 characters processed: require '===='
     398           0 :                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1)
     399           0 :                     *pfInvalid = true;
     400             :                 break;
     401             : 
     402             :             case 5: // 8n+5 base32 characters processed: require '==='
     403           0 :                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1)
     404           0 :                     *pfInvalid = true;
     405             :                 break;
     406             : 
     407             :             case 7: // 8n+7 base32 characters processed: require '='
     408           0 :                 if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1)
     409           0 :                     *pfInvalid = true;
     410             :                 break;
     411             :         }
     412             : 
     413          11 :     return vchRet;
     414             : }
     415             : 
     416           7 : string DecodeBase32(const string& str)
     417             : {
     418           7 :     vector<unsigned char> vchRet = DecodeBase32(str.c_str());
     419          39 :     return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size());
     420             : }
     421             : 
     422         439 : static bool ParsePrechecks(const std::string& str)
     423             : {
     424         439 :     if (str.empty()) // No empty string allowed
     425             :         return false;
     426         869 :     if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed
     427             :         return false;
     428         430 :     if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
     429             :         return false;
     430         427 :     return true;
     431             : }
     432             : 
     433         401 : bool ParseInt32(const std::string& str, int32_t *out)
     434             : {
     435         401 :     if (!ParsePrechecks(str))
     436             :         return false;
     437         397 :     char *endp = NULL;
     438         397 :     errno = 0; // strtol will not set errno if valid
     439         397 :     long int n = strtol(str.c_str(), &endp, 10);
     440         397 :     if(out) *out = (int32_t)n;
     441             :     // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
     442             :     // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
     443             :     // platforms the size of these types may be different.
     444         397 :     return endp && *endp == 0 && !errno &&
     445         745 :         n >= std::numeric_limits<int32_t>::min() &&
     446         397 :         n <= std::numeric_limits<int32_t>::max();
     447             : }
     448             : 
     449          20 : bool ParseInt64(const std::string& str, int64_t *out)
     450             : {
     451          20 :     if (!ParsePrechecks(str))
     452             :         return false;
     453          16 :     char *endp = NULL;
     454          16 :     errno = 0; // strtoll will not set errno if valid
     455          16 :     long long int n = strtoll(str.c_str(), &endp, 10);
     456          16 :     if(out) *out = (int64_t)n;
     457             :     // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
     458             :     // we still have to check that the returned value is within the range of an *int64_t*.
     459          16 :     return endp && *endp == 0 && !errno &&
     460          16 :         n >= std::numeric_limits<int64_t>::min() &&
     461          16 :         n <= std::numeric_limits<int64_t>::max();
     462             : }
     463             : 
     464          18 : bool ParseDouble(const std::string& str, double *out)
     465             : {
     466          18 :     if (!ParsePrechecks(str))
     467             :         return false;
     468          14 :     if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
     469             :         return false;
     470          13 :     std::istringstream text(str);
     471          13 :     text.imbue(std::locale::classic());
     472             :     double result;
     473             :     text >> result;
     474          13 :     if(out) *out = result;
     475          24 :     return text.eof() && !text.fail();
     476             : }
     477             : 
     478           8 : std::string FormatParagraph(const std::string& in, size_t width, size_t indent)
     479             : {
     480           8 :     std::stringstream out;
     481             :     size_t col = 0;
     482             :     size_t ptr = 0;
     483          36 :     while(ptr < in.size())
     484             :     {
     485             :         // Find beginning of next word
     486          29 :         ptr = in.find_first_not_of(' ', ptr);
     487          29 :         if (ptr == std::string::npos)
     488             :             break;
     489             :         // Find end of next word
     490          28 :         size_t endword = in.find_first_of(' ', ptr);
     491          28 :         if (endword == std::string::npos)
     492           6 :             endword = in.size();
     493             :         // Add newline and indentation if this wraps over the allowed width
     494          28 :         if (col > 0)
     495             :         {
     496          21 :             if ((col + endword - ptr) > width)
     497             :             {
     498             :                 out << '\n';
     499           4 :                 for(size_t i=0; i<indent; ++i)
     500             :                     out << ' ';
     501             :                 col = 0;
     502             :             } else
     503             :                 out << ' ';
     504             :         }
     505             :         // Append word
     506          56 :         out << in.substr(ptr, endword - ptr);
     507          28 :         col += endword - ptr + 1;
     508          28 :         ptr = endword;
     509             :     }
     510           8 :     return out.str();
     511             : }
     512             : 
     513        1896 : std::string i64tostr(int64_t n)
     514             : {
     515        1896 :     return strprintf("%d", n);
     516             : }
     517             : 
     518           0 : std::string itostr(int n)
     519             : {
     520           0 :     return strprintf("%d", n);
     521             : }
     522             : 
     523        2765 : int64_t atoi64(const char* psz)
     524             : {
     525             : #ifdef _MSC_VER
     526             :     return _atoi64(psz);
     527             : #else
     528        2765 :     return strtoll(psz, NULL, 10);
     529             : #endif
     530             : }
     531             : 
     532        8608 : int64_t atoi64(const std::string& str)
     533             : {
     534             : #ifdef _MSC_VER
     535             :     return _atoi64(str.c_str());
     536             : #else
     537        8608 :     return strtoll(str.c_str(), NULL, 10);
     538             : #endif
     539             : }
     540             : 
     541         459 : int atoi(const std::string& str)
     542             : {
     543         918 :     return atoi(str.c_str());
     544             : }
     545             : 
     546             : /** Upper bound for mantissa.
     547             :  * 10^18-1 is the largest arbitrary decimal that will fit in a signed 64-bit integer.
     548             :  * Larger integers cannot consist of arbitrary combinations of 0-9:
     549             :  *
     550             :  *   999999999999999999  1^18-1
     551             :  *  9223372036854775807  (1<<63)-1  (max int64_t)
     552             :  *  9999999999999999999  1^19-1     (would overflow)
     553             :  */
     554             : static const int64_t UPPER_BOUND = 1000000000000000000LL - 1LL;
     555             : 
     556             : /** Helper function for ParseFixedPoint */
     557             : static inline bool ProcessMantissaDigit(char ch, int64_t &mantissa, int &mantissa_tzeros)
     558             : {
     559        1243 :     if(ch == '0')
     560         676 :         ++mantissa_tzeros;
     561             :     else {
     562         968 :         for (int i=0; i<=mantissa_tzeros; ++i) {
     563         979 :             if (mantissa > (UPPER_BOUND / 10LL))
     564             :                 return false; /* overflow */
     565         968 :             mantissa *= 10;
     566             :         }
     567         556 :         mantissa += ch - '0';
     568         556 :         mantissa_tzeros = 0;
     569             :     }
     570             :     return true;
     571             : }
     572             : 
     573         265 : bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
     574             : {
     575         265 :     int64_t mantissa = 0;
     576         265 :     int64_t exponent = 0;
     577         265 :     int mantissa_tzeros = 0;
     578         265 :     bool mantissa_sign = false;
     579         265 :     bool exponent_sign = false;
     580         265 :     int ptr = 0;
     581         265 :     int end = val.size();
     582         265 :     int point_ofs = 0;
     583             : 
     584         265 :     if (ptr < end && val[ptr] == '-') {
     585          17 :         mantissa_sign = true;
     586          17 :         ++ptr;
     587             :     }
     588         265 :     if (ptr < end)
     589             :     {
     590         526 :         if (val[ptr] == '0') {
     591             :             /* pass single 0 */
     592         123 :             ++ptr;
     593         140 :         } else if (val[ptr] >= '1' && val[ptr] <= '9') {
     594        1108 :             while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
     595        1326 :                 if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))
     596             :                     return false; /* overflow */
     597         442 :                 ++ptr;
     598             :             }
     599             :         } else return false; /* missing expected digit */
     600             :     } else return false; /* empty string or loose '-' */
     601         468 :     if (ptr < end && val[ptr] == '.')
     602             :     {
     603         197 :         ++ptr;
     604         393 :         if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9')
     605             :         {
     606        1797 :             while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
     607        2403 :                 if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))
     608             :                     return false; /* overflow */
     609         790 :                 ++ptr;
     610         790 :                 ++point_ofs;
     611             :             }
     612             :         } else return false; /* missing expected digit */
     613             :     }
     614         269 :     if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E'))
     615             :     {
     616          18 :         ++ptr;
     617          35 :         if (ptr < end && val[ptr] == '+')
     618           4 :             ++ptr;
     619          27 :         else if (ptr < end && val[ptr] == '-') {
     620          10 :             exponent_sign = true;
     621          10 :             ++ptr;
     622             :         }
     623          34 :         if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
     624          60 :             while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
     625          22 :                 if (exponent > (UPPER_BOUND / 10LL))
     626             :                     return false; /* overflow */
     627          44 :                 exponent = exponent * 10 + val[ptr] - '0';
     628          22 :                 ++ptr;
     629             :             }
     630             :         } else return false; /* missing expected digit */
     631             :     }
     632         245 :     if (ptr != end)
     633             :         return false; /* trailing garbage */
     634             : 
     635             :     /* finalize exponent */
     636         241 :     if (exponent_sign)
     637           9 :         exponent = -exponent;
     638         241 :     exponent = exponent - point_ofs + mantissa_tzeros;
     639             : 
     640             :     /* finalize mantissa */
     641         241 :     if (mantissa_sign)
     642           7 :         mantissa = -mantissa;
     643             : 
     644             :     /* convert to one 64-bit fixed-point value */
     645         241 :     exponent += decimals;
     646         241 :     if (exponent < 0)
     647             :         return false; /* cannot represent values smaller than 10^-decimals */
     648         235 :     if (exponent >= 18)
     649             :         return false; /* cannot represent values larger than or equal to 10^(18-decimals) */
     650             : 
     651        1497 :     for (int i=0; i < exponent; ++i) {
     652        1498 :         if (mantissa > (UPPER_BOUND / 10LL) || mantissa < -(UPPER_BOUND / 10LL))
     653             :             return false; /* overflow */
     654        1497 :         mantissa *= 10;
     655             :     }
     656         230 :     if (mantissa > UPPER_BOUND || mantissa < -UPPER_BOUND)
     657             :         return false; /* overflow */
     658             : 
     659         230 :     if (amount_out)
     660         230 :         *amount_out = mantissa;
     661             : 
     662             :     return true;
     663         609 : }
     664             : 

Generated by: LCOV version 1.11