Use the variable name _ for unused return values
[bitcoinplatinum.git] / src / utilstrencodings.cpp
blobfd233f67579ccea3a6c6a269376392955ad77ae9
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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.
6 #include "utilstrencodings.h"
8 #include "tinyformat.h"
10 #include <cstdlib>
11 #include <cstring>
12 #include <errno.h>
13 #include <limits>
15 static const std::string CHARS_ALPHA_NUM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
17 static const std::string SAFE_CHARS[] =
19 CHARS_ALPHA_NUM + " .,;-_/:?@()", // SAFE_CHARS_DEFAULT
20 CHARS_ALPHA_NUM + " .,;-_?@", // SAFE_CHARS_UA_COMMENT
21 CHARS_ALPHA_NUM + ".-_", // SAFE_CHARS_FILENAME
24 std::string SanitizeString(const std::string& str, int rule)
26 std::string strResult;
27 for (std::string::size_type i = 0; i < str.size(); i++)
29 if (SAFE_CHARS[rule].find(str[i]) != std::string::npos)
30 strResult.push_back(str[i]);
32 return strResult;
35 const signed char p_util_hexdigit[256] =
36 { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
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 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
40 -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
41 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
42 -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
43 -1,-1,-1,-1,-1,-1,-1,-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, };
53 signed char HexDigit(char c)
55 return p_util_hexdigit[(unsigned char)c];
58 bool IsHex(const std::string& str)
60 for(std::string::const_iterator it(str.begin()); it != str.end(); ++it)
62 if (HexDigit(*it) < 0)
63 return false;
65 return (str.size() > 0) && (str.size()%2 == 0);
68 std::vector<unsigned char> ParseHex(const char* psz)
70 // convert hex dump to vector
71 std::vector<unsigned char> vch;
72 while (true)
74 while (isspace(*psz))
75 psz++;
76 signed char c = HexDigit(*psz++);
77 if (c == (signed char)-1)
78 break;
79 unsigned char n = (c << 4);
80 c = HexDigit(*psz++);
81 if (c == (signed char)-1)
82 break;
83 n |= c;
84 vch.push_back(n);
86 return vch;
89 std::vector<unsigned char> ParseHex(const std::string& str)
91 return ParseHex(str.c_str());
94 void SplitHostPort(std::string in, int &portOut, std::string &hostOut) {
95 size_t colon = in.find_last_of(':');
96 // if a : is found, and it either follows a [...], or no other : is in the string, treat it as port separator
97 bool fHaveColon = colon != in.npos;
98 bool fBracketed = fHaveColon && (in[0]=='[' && in[colon-1]==']'); // if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is safe
99 bool fMultiColon = fHaveColon && (in.find_last_of(':',colon-1) != in.npos);
100 if (fHaveColon && (colon==0 || fBracketed || !fMultiColon)) {
101 int32_t n;
102 if (ParseInt32(in.substr(colon + 1), &n) && n > 0 && n < 0x10000) {
103 in = in.substr(0, colon);
104 portOut = n;
107 if (in.size()>0 && in[0] == '[' && in[in.size()-1] == ']')
108 hostOut = in.substr(1, in.size()-2);
109 else
110 hostOut = in;
113 std::string EncodeBase64(const unsigned char* pch, size_t len)
115 static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
117 std::string strRet = "";
118 strRet.reserve((len+2)/3*4);
120 int mode=0, left=0;
121 const unsigned char *pchEnd = pch+len;
123 while (pch<pchEnd)
125 int enc = *(pch++);
126 switch (mode)
128 case 0: // we have no bits
129 strRet += pbase64[enc >> 2];
130 left = (enc & 3) << 4;
131 mode = 1;
132 break;
134 case 1: // we have two bits
135 strRet += pbase64[left | (enc >> 4)];
136 left = (enc & 15) << 2;
137 mode = 2;
138 break;
140 case 2: // we have four bits
141 strRet += pbase64[left | (enc >> 6)];
142 strRet += pbase64[enc & 63];
143 mode = 0;
144 break;
148 if (mode)
150 strRet += pbase64[left];
151 strRet += '=';
152 if (mode == 1)
153 strRet += '=';
156 return strRet;
159 std::string EncodeBase64(const std::string& str)
161 return EncodeBase64((const unsigned char*)str.c_str(), str.size());
164 std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
166 static const int decode64_table[256] =
168 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
169 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
170 -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
171 -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
172 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
173 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
174 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
175 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
176 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
177 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
178 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
179 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
180 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
183 if (pfInvalid)
184 *pfInvalid = false;
186 std::vector<unsigned char> vchRet;
187 vchRet.reserve(strlen(p)*3/4);
189 int mode = 0;
190 int left = 0;
192 while (1)
194 int dec = decode64_table[(unsigned char)*p];
195 if (dec == -1) break;
196 p++;
197 switch (mode)
199 case 0: // we have no bits and get 6
200 left = dec;
201 mode = 1;
202 break;
204 case 1: // we have 6 bits and keep 4
205 vchRet.push_back((left<<2) | (dec>>4));
206 left = dec & 15;
207 mode = 2;
208 break;
210 case 2: // we have 4 bits and get 6, we keep 2
211 vchRet.push_back((left<<4) | (dec>>2));
212 left = dec & 3;
213 mode = 3;
214 break;
216 case 3: // we have 2 bits and get 6
217 vchRet.push_back((left<<6) | dec);
218 mode = 0;
219 break;
223 if (pfInvalid)
224 switch (mode)
226 case 0: // 4n base64 characters processed: ok
227 break;
229 case 1: // 4n+1 base64 character processed: impossible
230 *pfInvalid = true;
231 break;
233 case 2: // 4n+2 base64 characters processed: require '=='
234 if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
235 *pfInvalid = true;
236 break;
238 case 3: // 4n+3 base64 characters processed: require '='
239 if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
240 *pfInvalid = true;
241 break;
244 return vchRet;
247 std::string DecodeBase64(const std::string& str)
249 std::vector<unsigned char> vchRet = DecodeBase64(str.c_str());
250 return std::string((const char*)vchRet.data(), vchRet.size());
253 std::string EncodeBase32(const unsigned char* pch, size_t len)
255 static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
257 std::string strRet="";
258 strRet.reserve((len+4)/5*8);
260 int mode=0, left=0;
261 const unsigned char *pchEnd = pch+len;
263 while (pch<pchEnd)
265 int enc = *(pch++);
266 switch (mode)
268 case 0: // we have no bits
269 strRet += pbase32[enc >> 3];
270 left = (enc & 7) << 2;
271 mode = 1;
272 break;
274 case 1: // we have three bits
275 strRet += pbase32[left | (enc >> 6)];
276 strRet += pbase32[(enc >> 1) & 31];
277 left = (enc & 1) << 4;
278 mode = 2;
279 break;
281 case 2: // we have one bit
282 strRet += pbase32[left | (enc >> 4)];
283 left = (enc & 15) << 1;
284 mode = 3;
285 break;
287 case 3: // we have four bits
288 strRet += pbase32[left | (enc >> 7)];
289 strRet += pbase32[(enc >> 2) & 31];
290 left = (enc & 3) << 3;
291 mode = 4;
292 break;
294 case 4: // we have two bits
295 strRet += pbase32[left | (enc >> 5)];
296 strRet += pbase32[enc & 31];
297 mode = 0;
301 static const int nPadding[5] = {0, 6, 4, 3, 1};
302 if (mode)
304 strRet += pbase32[left];
305 for (int n=0; n<nPadding[mode]; n++)
306 strRet += '=';
309 return strRet;
312 std::string EncodeBase32(const std::string& str)
314 return EncodeBase32((const unsigned char*)str.c_str(), str.size());
317 std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid)
319 static const int decode32_table[256] =
321 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
322 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
323 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
324 -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
325 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2,
326 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
327 23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
328 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
329 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
330 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
331 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
332 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
333 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
336 if (pfInvalid)
337 *pfInvalid = false;
339 std::vector<unsigned char> vchRet;
340 vchRet.reserve((strlen(p))*5/8);
342 int mode = 0;
343 int left = 0;
345 while (1)
347 int dec = decode32_table[(unsigned char)*p];
348 if (dec == -1) break;
349 p++;
350 switch (mode)
352 case 0: // we have no bits and get 5
353 left = dec;
354 mode = 1;
355 break;
357 case 1: // we have 5 bits and keep 2
358 vchRet.push_back((left<<3) | (dec>>2));
359 left = dec & 3;
360 mode = 2;
361 break;
363 case 2: // we have 2 bits and keep 7
364 left = left << 5 | dec;
365 mode = 3;
366 break;
368 case 3: // we have 7 bits and keep 4
369 vchRet.push_back((left<<1) | (dec>>4));
370 left = dec & 15;
371 mode = 4;
372 break;
374 case 4: // we have 4 bits, and keep 1
375 vchRet.push_back((left<<4) | (dec>>1));
376 left = dec & 1;
377 mode = 5;
378 break;
380 case 5: // we have 1 bit, and keep 6
381 left = left << 5 | dec;
382 mode = 6;
383 break;
385 case 6: // we have 6 bits, and keep 3
386 vchRet.push_back((left<<2) | (dec>>3));
387 left = dec & 7;
388 mode = 7;
389 break;
391 case 7: // we have 3 bits, and keep 0
392 vchRet.push_back((left<<5) | dec);
393 mode = 0;
394 break;
398 if (pfInvalid)
399 switch (mode)
401 case 0: // 8n base32 characters processed: ok
402 break;
404 case 1: // 8n+1 base32 characters processed: impossible
405 case 3: // +3
406 case 6: // +6
407 *pfInvalid = true;
408 break;
410 case 2: // 8n+2 base32 characters processed: require '======'
411 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1)
412 *pfInvalid = true;
413 break;
415 case 4: // 8n+4 base32 characters processed: require '===='
416 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1)
417 *pfInvalid = true;
418 break;
420 case 5: // 8n+5 base32 characters processed: require '==='
421 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1)
422 *pfInvalid = true;
423 break;
425 case 7: // 8n+7 base32 characters processed: require '='
426 if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1)
427 *pfInvalid = true;
428 break;
431 return vchRet;
434 std::string DecodeBase32(const std::string& str)
436 std::vector<unsigned char> vchRet = DecodeBase32(str.c_str());
437 return std::string((const char*)vchRet.data(), vchRet.size());
440 static bool ParsePrechecks(const std::string& str)
442 if (str.empty()) // No empty string allowed
443 return false;
444 if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed
445 return false;
446 if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
447 return false;
448 return true;
451 bool ParseInt32(const std::string& str, int32_t *out)
453 if (!ParsePrechecks(str))
454 return false;
455 char *endp = nullptr;
456 errno = 0; // strtol will not set errno if valid
457 long int n = strtol(str.c_str(), &endp, 10);
458 if(out) *out = (int32_t)n;
459 // Note that strtol returns a *long int*, so even if strtol doesn't report an over/underflow
460 // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
461 // platforms the size of these types may be different.
462 return endp && *endp == 0 && !errno &&
463 n >= std::numeric_limits<int32_t>::min() &&
464 n <= std::numeric_limits<int32_t>::max();
467 bool ParseInt64(const std::string& str, int64_t *out)
469 if (!ParsePrechecks(str))
470 return false;
471 char *endp = nullptr;
472 errno = 0; // strtoll will not set errno if valid
473 long long int n = strtoll(str.c_str(), &endp, 10);
474 if(out) *out = (int64_t)n;
475 // Note that strtoll returns a *long long int*, so even if strtol doesn't report an over/underflow
476 // we still have to check that the returned value is within the range of an *int64_t*.
477 return endp && *endp == 0 && !errno &&
478 n >= std::numeric_limits<int64_t>::min() &&
479 n <= std::numeric_limits<int64_t>::max();
482 bool ParseUInt32(const std::string& str, uint32_t *out)
484 if (!ParsePrechecks(str))
485 return false;
486 if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoul accepts these by default if they fit in the range
487 return false;
488 char *endp = nullptr;
489 errno = 0; // strtoul will not set errno if valid
490 unsigned long int n = strtoul(str.c_str(), &endp, 10);
491 if(out) *out = (uint32_t)n;
492 // Note that strtoul returns a *unsigned long int*, so even if it doesn't report an over/underflow
493 // we still have to check that the returned value is within the range of an *uint32_t*. On 64-bit
494 // platforms the size of these types may be different.
495 return endp && *endp == 0 && !errno &&
496 n <= std::numeric_limits<uint32_t>::max();
499 bool ParseUInt64(const std::string& str, uint64_t *out)
501 if (!ParsePrechecks(str))
502 return false;
503 if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoull accepts these by default if they fit in the range
504 return false;
505 char *endp = nullptr;
506 errno = 0; // strtoull will not set errno if valid
507 unsigned long long int n = strtoull(str.c_str(), &endp, 10);
508 if(out) *out = (uint64_t)n;
509 // Note that strtoull returns a *unsigned long long int*, so even if it doesn't report an over/underflow
510 // we still have to check that the returned value is within the range of an *uint64_t*.
511 return endp && *endp == 0 && !errno &&
512 n <= std::numeric_limits<uint64_t>::max();
516 bool ParseDouble(const std::string& str, double *out)
518 if (!ParsePrechecks(str))
519 return false;
520 if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
521 return false;
522 std::istringstream text(str);
523 text.imbue(std::locale::classic());
524 double result;
525 text >> result;
526 if(out) *out = result;
527 return text.eof() && !text.fail();
530 std::string FormatParagraph(const std::string& in, size_t width, size_t indent)
532 std::stringstream out;
533 size_t ptr = 0;
534 size_t indented = 0;
535 while (ptr < in.size())
537 size_t lineend = in.find_first_of('\n', ptr);
538 if (lineend == std::string::npos) {
539 lineend = in.size();
541 const size_t linelen = lineend - ptr;
542 const size_t rem_width = width - indented;
543 if (linelen <= rem_width) {
544 out << in.substr(ptr, linelen + 1);
545 ptr = lineend + 1;
546 indented = 0;
547 } else {
548 size_t finalspace = in.find_last_of(" \n", ptr + rem_width);
549 if (finalspace == std::string::npos || finalspace < ptr) {
550 // No place to break; just include the entire word and move on
551 finalspace = in.find_first_of("\n ", ptr);
552 if (finalspace == std::string::npos) {
553 // End of the string, just add it and break
554 out << in.substr(ptr);
555 break;
558 out << in.substr(ptr, finalspace - ptr) << "\n";
559 if (in[finalspace] == '\n') {
560 indented = 0;
561 } else if (indent) {
562 out << std::string(indent, ' ');
563 indented = indent;
565 ptr = finalspace + 1;
568 return out.str();
571 std::string i64tostr(int64_t n)
573 return strprintf("%d", n);
576 std::string itostr(int n)
578 return strprintf("%d", n);
581 int64_t atoi64(const char* psz)
583 #ifdef _MSC_VER
584 return _atoi64(psz);
585 #else
586 return strtoll(psz, nullptr, 10);
587 #endif
590 int64_t atoi64(const std::string& str)
592 #ifdef _MSC_VER
593 return _atoi64(str.c_str());
594 #else
595 return strtoll(str.c_str(), nullptr, 10);
596 #endif
599 int atoi(const std::string& str)
601 return atoi(str.c_str());
604 /** Upper bound for mantissa.
605 * 10^18-1 is the largest arbitrary decimal that will fit in a signed 64-bit integer.
606 * Larger integers cannot consist of arbitrary combinations of 0-9:
608 * 999999999999999999 1^18-1
609 * 9223372036854775807 (1<<63)-1 (max int64_t)
610 * 9999999999999999999 1^19-1 (would overflow)
612 static const int64_t UPPER_BOUND = 1000000000000000000LL - 1LL;
614 /** Helper function for ParseFixedPoint */
615 static inline bool ProcessMantissaDigit(char ch, int64_t &mantissa, int &mantissa_tzeros)
617 if(ch == '0')
618 ++mantissa_tzeros;
619 else {
620 for (int i=0; i<=mantissa_tzeros; ++i) {
621 if (mantissa > (UPPER_BOUND / 10LL))
622 return false; /* overflow */
623 mantissa *= 10;
625 mantissa += ch - '0';
626 mantissa_tzeros = 0;
628 return true;
631 bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
633 int64_t mantissa = 0;
634 int64_t exponent = 0;
635 int mantissa_tzeros = 0;
636 bool mantissa_sign = false;
637 bool exponent_sign = false;
638 int ptr = 0;
639 int end = val.size();
640 int point_ofs = 0;
642 if (ptr < end && val[ptr] == '-') {
643 mantissa_sign = true;
644 ++ptr;
646 if (ptr < end)
648 if (val[ptr] == '0') {
649 /* pass single 0 */
650 ++ptr;
651 } else if (val[ptr] >= '1' && val[ptr] <= '9') {
652 while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
653 if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))
654 return false; /* overflow */
655 ++ptr;
657 } else return false; /* missing expected digit */
658 } else return false; /* empty string or loose '-' */
659 if (ptr < end && val[ptr] == '.')
661 ++ptr;
662 if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9')
664 while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
665 if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))
666 return false; /* overflow */
667 ++ptr;
668 ++point_ofs;
670 } else return false; /* missing expected digit */
672 if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E'))
674 ++ptr;
675 if (ptr < end && val[ptr] == '+')
676 ++ptr;
677 else if (ptr < end && val[ptr] == '-') {
678 exponent_sign = true;
679 ++ptr;
681 if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
682 while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
683 if (exponent > (UPPER_BOUND / 10LL))
684 return false; /* overflow */
685 exponent = exponent * 10 + val[ptr] - '0';
686 ++ptr;
688 } else return false; /* missing expected digit */
690 if (ptr != end)
691 return false; /* trailing garbage */
693 /* finalize exponent */
694 if (exponent_sign)
695 exponent = -exponent;
696 exponent = exponent - point_ofs + mantissa_tzeros;
698 /* finalize mantissa */
699 if (mantissa_sign)
700 mantissa = -mantissa;
702 /* convert to one 64-bit fixed-point value */
703 exponent += decimals;
704 if (exponent < 0)
705 return false; /* cannot represent values smaller than 10^-decimals */
706 if (exponent >= 18)
707 return false; /* cannot represent values larger than or equal to 10^(18-decimals) */
709 for (int i=0; i < exponent; ++i) {
710 if (mantissa > (UPPER_BOUND / 10LL) || mantissa < -(UPPER_BOUND / 10LL))
711 return false; /* overflow */
712 mantissa *= 10;
714 if (mantissa > UPPER_BOUND || mantissa < -UPPER_BOUND)
715 return false; /* overflow */
717 if (amount_out)
718 *amount_out = mantissa;
720 return true;