00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "absl/strings/numbers.h"
00019
00020 #include <algorithm>
00021 #include <cassert>
00022 #include <cfloat>
00023 #include <cmath>
00024 #include <cstdint>
00025 #include <cstdio>
00026 #include <cstdlib>
00027 #include <cstring>
00028 #include <iterator>
00029 #include <limits>
00030 #include <memory>
00031 #include <utility>
00032
00033 #include "absl/base/internal/bits.h"
00034 #include "absl/base/internal/raw_logging.h"
00035 #include "absl/strings/ascii.h"
00036 #include "absl/strings/charconv.h"
00037 #include "absl/strings/internal/memutil.h"
00038 #include "absl/strings/match.h"
00039 #include "absl/strings/str_cat.h"
00040
00041 namespace absl {
00042
00043 bool SimpleAtof(absl::string_view str, float* out) {
00044 *out = 0.0;
00045 str = StripAsciiWhitespace(str);
00046 if (!str.empty() && str[0] == '+') {
00047 str.remove_prefix(1);
00048 }
00049 auto result = absl::from_chars(str.data(), str.data() + str.size(), *out);
00050 if (result.ec == std::errc::invalid_argument) {
00051 return false;
00052 }
00053 if (result.ptr != str.data() + str.size()) {
00054
00055 return false;
00056 }
00057
00058
00059 if (result.ec == std::errc::result_out_of_range) {
00060 if (*out > 1.0) {
00061 *out = std::numeric_limits<float>::infinity();
00062 } else if (*out < -1.0) {
00063 *out = -std::numeric_limits<float>::infinity();
00064 }
00065 }
00066 return true;
00067 }
00068
00069 bool SimpleAtod(absl::string_view str, double* out) {
00070 *out = 0.0;
00071 str = StripAsciiWhitespace(str);
00072 if (!str.empty() && str[0] == '+') {
00073 str.remove_prefix(1);
00074 }
00075 auto result = absl::from_chars(str.data(), str.data() + str.size(), *out);
00076 if (result.ec == std::errc::invalid_argument) {
00077 return false;
00078 }
00079 if (result.ptr != str.data() + str.size()) {
00080
00081 return false;
00082 }
00083
00084
00085 if (result.ec == std::errc::result_out_of_range) {
00086 if (*out > 1.0) {
00087 *out = std::numeric_limits<double>::infinity();
00088 } else if (*out < -1.0) {
00089 *out = -std::numeric_limits<double>::infinity();
00090 }
00091 }
00092 return true;
00093 }
00094
00095 namespace {
00096
00097
00098
00099
00100
00101
00102
00103 inline void PutTwoDigits(size_t i, char* buf) {
00104 static const char two_ASCII_digits[100][2] = {
00105 {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'},
00106 {'0', '5'}, {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'},
00107 {'1', '0'}, {'1', '1'}, {'1', '2'}, {'1', '3'}, {'1', '4'},
00108 {'1', '5'}, {'1', '6'}, {'1', '7'}, {'1', '8'}, {'1', '9'},
00109 {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'}, {'2', '4'},
00110 {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'},
00111 {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'},
00112 {'3', '5'}, {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'},
00113 {'4', '0'}, {'4', '1'}, {'4', '2'}, {'4', '3'}, {'4', '4'},
00114 {'4', '5'}, {'4', '6'}, {'4', '7'}, {'4', '8'}, {'4', '9'},
00115 {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'}, {'5', '4'},
00116 {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'},
00117 {'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'},
00118 {'6', '5'}, {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'},
00119 {'7', '0'}, {'7', '1'}, {'7', '2'}, {'7', '3'}, {'7', '4'},
00120 {'7', '5'}, {'7', '6'}, {'7', '7'}, {'7', '8'}, {'7', '9'},
00121 {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'}, {'8', '4'},
00122 {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'},
00123 {'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'},
00124 {'9', '5'}, {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}
00125 };
00126 assert(i < 100);
00127 memcpy(buf, two_ASCII_digits[i], 2);
00128 }
00129
00130 }
00131
00132 bool SimpleAtob(absl::string_view str, bool* out) {
00133 ABSL_RAW_CHECK(out != nullptr, "Output pointer must not be nullptr.");
00134 if (EqualsIgnoreCase(str, "true") || EqualsIgnoreCase(str, "t") ||
00135 EqualsIgnoreCase(str, "yes") || EqualsIgnoreCase(str, "y") ||
00136 EqualsIgnoreCase(str, "1")) {
00137 *out = true;
00138 return true;
00139 }
00140 if (EqualsIgnoreCase(str, "false") || EqualsIgnoreCase(str, "f") ||
00141 EqualsIgnoreCase(str, "no") || EqualsIgnoreCase(str, "n") ||
00142 EqualsIgnoreCase(str, "0")) {
00143 *out = false;
00144 return true;
00145 }
00146 return false;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 namespace {
00162
00163
00164 const char one_ASCII_final_digits[10][2] {
00165 {'0', 0}, {'1', 0}, {'2', 0}, {'3', 0}, {'4', 0},
00166 {'5', 0}, {'6', 0}, {'7', 0}, {'8', 0}, {'9', 0},
00167 };
00168
00169 }
00170
00171 char* numbers_internal::FastIntToBuffer(uint32_t i, char* buffer) {
00172 uint32_t digits;
00173
00174
00175
00176
00177
00178
00179 if (i >= 1000000000) {
00180 digits = i / 100000000;
00181 i -= digits * 100000000;
00182 PutTwoDigits(digits, buffer);
00183 buffer += 2;
00184 lt100_000_000:
00185 digits = i / 1000000;
00186 i -= digits * 1000000;
00187 PutTwoDigits(digits, buffer);
00188 buffer += 2;
00189 lt1_000_000:
00190 digits = i / 10000;
00191 i -= digits * 10000;
00192 PutTwoDigits(digits, buffer);
00193 buffer += 2;
00194 lt10_000:
00195 digits = i / 100;
00196 i -= digits * 100;
00197 PutTwoDigits(digits, buffer);
00198 buffer += 2;
00199 lt100:
00200 digits = i;
00201 PutTwoDigits(digits, buffer);
00202 buffer += 2;
00203 *buffer = 0;
00204 return buffer;
00205 }
00206
00207 if (i < 100) {
00208 digits = i;
00209 if (i >= 10) goto lt100;
00210 memcpy(buffer, one_ASCII_final_digits[i], 2);
00211 return buffer + 1;
00212 }
00213 if (i < 10000) {
00214 if (i >= 1000) goto lt10_000;
00215 digits = i / 100;
00216 i -= digits * 100;
00217 *buffer++ = '0' + digits;
00218 goto lt100;
00219 }
00220 if (i < 1000000) {
00221 if (i >= 100000) goto lt1_000_000;
00222 digits = i / 10000;
00223 i -= digits * 10000;
00224 *buffer++ = '0' + digits;
00225 goto lt10_000;
00226 }
00227 if (i < 100000000) {
00228 if (i >= 10000000) goto lt100_000_000;
00229 digits = i / 1000000;
00230 i -= digits * 1000000;
00231 *buffer++ = '0' + digits;
00232 goto lt1_000_000;
00233 }
00234
00235 digits = i / 100000000;
00236 i -= digits * 100000000;
00237 *buffer++ = '0' + digits;
00238 goto lt100_000_000;
00239 }
00240
00241 char* numbers_internal::FastIntToBuffer(int32_t i, char* buffer) {
00242 uint32_t u = i;
00243 if (i < 0) {
00244 *buffer++ = '-';
00245
00246
00247
00248 u = 0 - u;
00249 }
00250 return numbers_internal::FastIntToBuffer(u, buffer);
00251 }
00252
00253 char* numbers_internal::FastIntToBuffer(uint64_t i, char* buffer) {
00254 uint32_t u32 = static_cast<uint32_t>(i);
00255 if (u32 == i) return numbers_internal::FastIntToBuffer(u32, buffer);
00256
00257
00258 uint64_t top_1to11 = i / 1000000000;
00259 u32 = static_cast<uint32_t>(i - top_1to11 * 1000000000);
00260 uint32_t top_1to11_32 = static_cast<uint32_t>(top_1to11);
00261
00262 if (top_1to11_32 == top_1to11) {
00263 buffer = numbers_internal::FastIntToBuffer(top_1to11_32, buffer);
00264 } else {
00265
00266 uint32_t top_8to9 = static_cast<uint32_t>(top_1to11 / 100);
00267 uint32_t mid_2 = static_cast<uint32_t>(top_1to11 - top_8to9 * 100);
00268 buffer = numbers_internal::FastIntToBuffer(top_8to9, buffer);
00269 PutTwoDigits(mid_2, buffer);
00270 buffer += 2;
00271 }
00272
00273
00274 uint32_t digits = u32 / 10000000;
00275 u32 -= digits * 10000000;
00276 PutTwoDigits(digits, buffer);
00277 buffer += 2;
00278 digits = u32 / 100000;
00279 u32 -= digits * 100000;
00280 PutTwoDigits(digits, buffer);
00281 buffer += 2;
00282 digits = u32 / 1000;
00283 u32 -= digits * 1000;
00284 PutTwoDigits(digits, buffer);
00285 buffer += 2;
00286 digits = u32 / 10;
00287 u32 -= digits * 10;
00288 PutTwoDigits(digits, buffer);
00289 buffer += 2;
00290 memcpy(buffer, one_ASCII_final_digits[u32], 2);
00291 return buffer + 1;
00292 }
00293
00294 char* numbers_internal::FastIntToBuffer(int64_t i, char* buffer) {
00295 uint64_t u = i;
00296 if (i < 0) {
00297 *buffer++ = '-';
00298 u = 0 - u;
00299 }
00300 return numbers_internal::FastIntToBuffer(u, buffer);
00301 }
00302
00303
00304
00305
00306 static std::pair<uint64_t, uint64_t> Mul32(std::pair<uint64_t, uint64_t> num,
00307 uint32_t mul) {
00308 uint64_t bits0_31 = num.second & 0xFFFFFFFF;
00309 uint64_t bits32_63 = num.second >> 32;
00310 uint64_t bits64_95 = num.first & 0xFFFFFFFF;
00311 uint64_t bits96_127 = num.first >> 32;
00312
00313
00314
00315
00316
00317
00318
00319
00320 bits0_31 *= mul;
00321 bits32_63 *= mul;
00322 bits64_95 *= mul;
00323 bits96_127 *= mul;
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 uint64_t bits0_63 = bits0_31 + (bits32_63 << 32);
00335 uint64_t bits64_127 = bits64_95 + (bits96_127 << 32) + (bits32_63 >> 32) +
00336 (bits0_63 < bits0_31);
00337 uint64_t bits128_up = (bits96_127 >> 32) + (bits64_127 < bits64_95);
00338 if (bits128_up == 0) return {bits64_127, bits0_63};
00339
00340 int shift = 64 - base_internal::CountLeadingZeros64(bits128_up);
00341 uint64_t lo = (bits0_63 >> shift) + (bits64_127 << (64 - shift));
00342 uint64_t hi = (bits64_127 >> shift) + (bits128_up << (64 - shift));
00343 return {hi, lo};
00344 }
00345
00346
00347
00348
00349 static std::pair<uint64_t, uint64_t> PowFive(uint64_t num, int expfive) {
00350 std::pair<uint64_t, uint64_t> result = {num, 0};
00351 while (expfive >= 13) {
00352
00353 result = Mul32(result, 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5);
00354 expfive -= 13;
00355 }
00356 constexpr int powers_of_five[13] = {
00357 1,
00358 5,
00359 5 * 5,
00360 5 * 5 * 5,
00361 5 * 5 * 5 * 5,
00362 5 * 5 * 5 * 5 * 5,
00363 5 * 5 * 5 * 5 * 5 * 5,
00364 5 * 5 * 5 * 5 * 5 * 5 * 5,
00365 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
00366 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
00367 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
00368 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
00369 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5};
00370 result = Mul32(result, powers_of_five[expfive & 15]);
00371 int shift = base_internal::CountLeadingZeros64(result.first);
00372 if (shift != 0) {
00373 result.first = (result.first << shift) + (result.second >> (64 - shift));
00374 result.second = (result.second << shift);
00375 }
00376 return result;
00377 }
00378
00379 struct ExpDigits {
00380 int32_t exponent;
00381 char digits[6];
00382 };
00383
00384
00385
00386
00387
00388
00389
00390 static ExpDigits SplitToSix(const double value) {
00391 ExpDigits exp_dig;
00392 int exp = 5;
00393 double d = value;
00394
00395
00396
00397
00398
00399
00400 if (d >= 999999.5) {
00401 if (d >= 1e+261) exp += 256, d *= 1e-256;
00402 if (d >= 1e+133) exp += 128, d *= 1e-128;
00403 if (d >= 1e+69) exp += 64, d *= 1e-64;
00404 if (d >= 1e+37) exp += 32, d *= 1e-32;
00405 if (d >= 1e+21) exp += 16, d *= 1e-16;
00406 if (d >= 1e+13) exp += 8, d *= 1e-8;
00407 if (d >= 1e+9) exp += 4, d *= 1e-4;
00408 if (d >= 1e+7) exp += 2, d *= 1e-2;
00409 if (d >= 1e+6) exp += 1, d *= 1e-1;
00410 } else {
00411 if (d < 1e-250) exp -= 256, d *= 1e256;
00412 if (d < 1e-122) exp -= 128, d *= 1e128;
00413 if (d < 1e-58) exp -= 64, d *= 1e64;
00414 if (d < 1e-26) exp -= 32, d *= 1e32;
00415 if (d < 1e-10) exp -= 16, d *= 1e16;
00416 if (d < 1e-2) exp -= 8, d *= 1e8;
00417 if (d < 1e+2) exp -= 4, d *= 1e4;
00418 if (d < 1e+4) exp -= 2, d *= 1e2;
00419 if (d < 1e+5) exp -= 1, d *= 1e1;
00420 }
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 uint64_t d64k = d * 65536;
00431 int dddddd;
00432 if ((d64k % 65536) == 32767 || (d64k % 65536) == 32768) {
00433
00434
00435
00436
00437
00438 dddddd = static_cast<int>(d64k / 65536);
00439
00440
00441
00442 int exp2;
00443 double m = std::frexp(value, &exp2);
00444 uint64_t mantissa = m * (32768.0 * 65536.0 * 65536.0 * 65536.0);
00445
00446
00447
00448
00449
00450 mantissa <<= 1;
00451 exp2 -= 64;
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 std::pair<uint64_t, uint64_t> edge, val;
00463 if (exp >= 6) {
00464
00465
00466
00467 edge = PowFive(2 * dddddd + 1, exp - 5);
00468
00469 val.first = mantissa;
00470 val.second = 0;
00471 } else {
00472
00473
00474
00475 edge = PowFive(2 * dddddd + 1, 0);
00476
00477 val = PowFive(mantissa, 5 - exp);
00478 }
00479
00480
00481 if (val > edge) {
00482 dddddd++;
00483 } else if (val == edge) {
00484 dddddd += (dddddd & 1);
00485 }
00486 } else {
00487
00488 dddddd = static_cast<int>((d64k + 32768) / 65536);
00489 }
00490 if (dddddd == 1000000) {
00491 dddddd = 100000;
00492 exp += 1;
00493 }
00494 exp_dig.exponent = exp;
00495
00496 int two_digits = dddddd / 10000;
00497 dddddd -= two_digits * 10000;
00498 PutTwoDigits(two_digits, &exp_dig.digits[0]);
00499
00500 two_digits = dddddd / 100;
00501 dddddd -= two_digits * 100;
00502 PutTwoDigits(two_digits, &exp_dig.digits[2]);
00503
00504 PutTwoDigits(dddddd, &exp_dig.digits[4]);
00505 return exp_dig;
00506 }
00507
00508
00509
00510 size_t numbers_internal::SixDigitsToBuffer(double d, char* const buffer) {
00511 static_assert(std::numeric_limits<float>::is_iec559,
00512 "IEEE-754/IEC-559 support only");
00513
00514 char* out = buffer;
00515
00516
00517
00518 if (std::isnan(d)) {
00519 strcpy(out, "nan");
00520 return 3;
00521 }
00522 if (d == 0) {
00523 if (std::signbit(d)) *out++ = '-';
00524 *out++ = '0';
00525 *out = 0;
00526 return out - buffer;
00527 }
00528 if (d < 0) {
00529 *out++ = '-';
00530 d = -d;
00531 }
00532 if (std::isinf(d)) {
00533 strcpy(out, "inf");
00534 return out + 3 - buffer;
00535 }
00536
00537 auto exp_dig = SplitToSix(d);
00538 int exp = exp_dig.exponent;
00539 const char* digits = exp_dig.digits;
00540 out[0] = '0';
00541 out[1] = '.';
00542 switch (exp) {
00543 case 5:
00544 memcpy(out, &digits[0], 6), out += 6;
00545 *out = 0;
00546 return out - buffer;
00547 case 4:
00548 memcpy(out, &digits[0], 5), out += 5;
00549 if (digits[5] != '0') {
00550 *out++ = '.';
00551 *out++ = digits[5];
00552 }
00553 *out = 0;
00554 return out - buffer;
00555 case 3:
00556 memcpy(out, &digits[0], 4), out += 4;
00557 if ((digits[5] | digits[4]) != '0') {
00558 *out++ = '.';
00559 *out++ = digits[4];
00560 if (digits[5] != '0') *out++ = digits[5];
00561 }
00562 *out = 0;
00563 return out - buffer;
00564 case 2:
00565 memcpy(out, &digits[0], 3), out += 3;
00566 *out++ = '.';
00567 memcpy(out, &digits[3], 3);
00568 out += 3;
00569 while (out[-1] == '0') --out;
00570 if (out[-1] == '.') --out;
00571 *out = 0;
00572 return out - buffer;
00573 case 1:
00574 memcpy(out, &digits[0], 2), out += 2;
00575 *out++ = '.';
00576 memcpy(out, &digits[2], 4);
00577 out += 4;
00578 while (out[-1] == '0') --out;
00579 if (out[-1] == '.') --out;
00580 *out = 0;
00581 return out - buffer;
00582 case 0:
00583 memcpy(out, &digits[0], 1), out += 1;
00584 *out++ = '.';
00585 memcpy(out, &digits[1], 5);
00586 out += 5;
00587 while (out[-1] == '0') --out;
00588 if (out[-1] == '.') --out;
00589 *out = 0;
00590 return out - buffer;
00591 case -4:
00592 out[2] = '0';
00593 ++out;
00594 ABSL_FALLTHROUGH_INTENDED;
00595 case -3:
00596 out[2] = '0';
00597 ++out;
00598 ABSL_FALLTHROUGH_INTENDED;
00599 case -2:
00600 out[2] = '0';
00601 ++out;
00602 ABSL_FALLTHROUGH_INTENDED;
00603 case -1:
00604 out += 2;
00605 memcpy(out, &digits[0], 6);
00606 out += 6;
00607 while (out[-1] == '0') --out;
00608 *out = 0;
00609 return out - buffer;
00610 }
00611 assert(exp < -4 || exp >= 6);
00612 out[0] = digits[0];
00613 assert(out[1] == '.');
00614 out += 2;
00615 memcpy(out, &digits[1], 5), out += 5;
00616 while (out[-1] == '0') --out;
00617 if (out[-1] == '.') --out;
00618 *out++ = 'e';
00619 if (exp > 0) {
00620 *out++ = '+';
00621 } else {
00622 *out++ = '-';
00623 exp = -exp;
00624 }
00625 if (exp > 99) {
00626 int dig1 = exp / 100;
00627 exp -= dig1 * 100;
00628 *out++ = '0' + dig1;
00629 }
00630 PutTwoDigits(exp, out);
00631 out += 2;
00632 *out = 0;
00633 return out - buffer;
00634 }
00635
00636 namespace {
00637
00638
00639
00640 static const int8_t kAsciiToInt[256] = {
00641 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
00642 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
00643 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 0, 1, 2, 3, 4, 5,
00644 6, 7, 8, 9, 36, 36, 36, 36, 36, 36, 36, 10, 11, 12, 13, 14, 15, 16, 17,
00645 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
00646 36, 36, 36, 36, 36, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
00647 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36, 36, 36,
00648 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
00649 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
00650 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
00651 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
00652 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
00653 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
00654 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36};
00655
00656
00657 inline bool safe_parse_sign_and_base(absl::string_view* text ,
00658 int* base_ptr ,
00659 bool* negative_ptr ) {
00660 if (text->data() == nullptr) {
00661 return false;
00662 }
00663
00664 const char* start = text->data();
00665 const char* end = start + text->size();
00666 int base = *base_ptr;
00667
00668
00669 while (start < end && absl::ascii_isspace(start[0])) {
00670 ++start;
00671 }
00672 while (start < end && absl::ascii_isspace(end[-1])) {
00673 --end;
00674 }
00675 if (start >= end) {
00676 return false;
00677 }
00678
00679
00680 *negative_ptr = (start[0] == '-');
00681 if (*negative_ptr || start[0] == '+') {
00682 ++start;
00683 if (start >= end) {
00684 return false;
00685 }
00686 }
00687
00688
00689
00690
00691
00692 if (base == 0) {
00693 if (end - start >= 2 && start[0] == '0' &&
00694 (start[1] == 'x' || start[1] == 'X')) {
00695 base = 16;
00696 start += 2;
00697 if (start >= end) {
00698
00699 return false;
00700 }
00701 } else if (end - start >= 1 && start[0] == '0') {
00702 base = 8;
00703 start += 1;
00704 } else {
00705 base = 10;
00706 }
00707 } else if (base == 16) {
00708 if (end - start >= 2 && start[0] == '0' &&
00709 (start[1] == 'x' || start[1] == 'X')) {
00710 start += 2;
00711 if (start >= end) {
00712
00713 return false;
00714 }
00715 }
00716 } else if (base >= 2 && base <= 36) {
00717
00718 } else {
00719 return false;
00720 }
00721 *text = absl::string_view(start, end - start);
00722 *base_ptr = base;
00723 return true;
00724 }
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 template <typename IntType>
00756 struct LookupTables {
00757 static const IntType kVmaxOverBase[];
00758 static const IntType kVminOverBase[];
00759 };
00760
00761
00762
00763
00764 #define X_OVER_BASE_INITIALIZER(X) \
00765 { \
00766 0, 0, X / 2, X / 3, X / 4, X / 5, X / 6, X / 7, X / 8, X / 9, X / 10, \
00767 X / 11, X / 12, X / 13, X / 14, X / 15, X / 16, X / 17, X / 18, \
00768 X / 19, X / 20, X / 21, X / 22, X / 23, X / 24, X / 25, X / 26, \
00769 X / 27, X / 28, X / 29, X / 30, X / 31, X / 32, X / 33, X / 34, \
00770 X / 35, X / 36, \
00771 }
00772
00773 template <typename IntType>
00774 const IntType LookupTables<IntType>::kVmaxOverBase[] =
00775 X_OVER_BASE_INITIALIZER(std::numeric_limits<IntType>::max());
00776
00777 template <typename IntType>
00778 const IntType LookupTables<IntType>::kVminOverBase[] =
00779 X_OVER_BASE_INITIALIZER(std::numeric_limits<IntType>::min());
00780
00781 #undef X_OVER_BASE_INITIALIZER
00782
00783 template <typename IntType>
00784 inline bool safe_parse_positive_int(absl::string_view text, int base,
00785 IntType* value_p) {
00786 IntType value = 0;
00787 const IntType vmax = std::numeric_limits<IntType>::max();
00788 assert(vmax > 0);
00789 assert(base >= 0);
00790 assert(vmax >= static_cast<IntType>(base));
00791 const IntType vmax_over_base = LookupTables<IntType>::kVmaxOverBase[base];
00792 const char* start = text.data();
00793 const char* end = start + text.size();
00794
00795 for (; start < end; ++start) {
00796 unsigned char c = static_cast<unsigned char>(start[0]);
00797 int digit = kAsciiToInt[c];
00798 if (digit >= base) {
00799 *value_p = value;
00800 return false;
00801 }
00802 if (value > vmax_over_base) {
00803 *value_p = vmax;
00804 return false;
00805 }
00806 value *= base;
00807 if (value > vmax - digit) {
00808 *value_p = vmax;
00809 return false;
00810 }
00811 value += digit;
00812 }
00813 *value_p = value;
00814 return true;
00815 }
00816
00817 template <typename IntType>
00818 inline bool safe_parse_negative_int(absl::string_view text, int base,
00819 IntType* value_p) {
00820 IntType value = 0;
00821 const IntType vmin = std::numeric_limits<IntType>::min();
00822 assert(vmin < 0);
00823 assert(vmin <= 0 - base);
00824 IntType vmin_over_base = LookupTables<IntType>::kVminOverBase[base];
00825
00826
00827
00828
00829
00830 if (vmin % base > 0) {
00831 vmin_over_base += 1;
00832 }
00833 const char* start = text.data();
00834 const char* end = start + text.size();
00835
00836 for (; start < end; ++start) {
00837 unsigned char c = static_cast<unsigned char>(start[0]);
00838 int digit = kAsciiToInt[c];
00839 if (digit >= base) {
00840 *value_p = value;
00841 return false;
00842 }
00843 if (value < vmin_over_base) {
00844 *value_p = vmin;
00845 return false;
00846 }
00847 value *= base;
00848 if (value < vmin + digit) {
00849 *value_p = vmin;
00850 return false;
00851 }
00852 value -= digit;
00853 }
00854 *value_p = value;
00855 return true;
00856 }
00857
00858
00859
00860 template <typename IntType>
00861 inline bool safe_int_internal(absl::string_view text, IntType* value_p,
00862 int base) {
00863 *value_p = 0;
00864 bool negative;
00865 if (!safe_parse_sign_and_base(&text, &base, &negative)) {
00866 return false;
00867 }
00868 if (!negative) {
00869 return safe_parse_positive_int(text, base, value_p);
00870 } else {
00871 return safe_parse_negative_int(text, base, value_p);
00872 }
00873 }
00874
00875 template <typename IntType>
00876 inline bool safe_uint_internal(absl::string_view text, IntType* value_p,
00877 int base) {
00878 *value_p = 0;
00879 bool negative;
00880 if (!safe_parse_sign_and_base(&text, &base, &negative) || negative) {
00881 return false;
00882 }
00883 return safe_parse_positive_int(text, base, value_p);
00884 }
00885 }
00886
00887 namespace numbers_internal {
00888 bool safe_strto32_base(absl::string_view text, int32_t* value, int base) {
00889 return safe_int_internal<int32_t>(text, value, base);
00890 }
00891
00892 bool safe_strto64_base(absl::string_view text, int64_t* value, int base) {
00893 return safe_int_internal<int64_t>(text, value, base);
00894 }
00895
00896 bool safe_strtou32_base(absl::string_view text, uint32_t* value, int base) {
00897 return safe_uint_internal<uint32_t>(text, value, base);
00898 }
00899
00900 bool safe_strtou64_base(absl::string_view text, uint64_t* value, int base) {
00901 return safe_uint_internal<uint64_t>(text, value, base);
00902 }
00903 }
00904
00905 }