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