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 :
|