2 * Copyright 2016 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #define FOLLY_CONV_INTERNAL
17 #include <folly/Conv.h>
22 extern const char digit1[101] =
23 "00000000001111111111222222222233333333334444444444"
24 "55555555556666666666777777777788888888889999999999";
25 extern const char digit2[101] =
26 "01234567890123456789012345678901234567890123456789"
27 "01234567890123456789012345678901234567890123456789";
29 template <> const char *const MaxString<bool>::value = "true";
30 template <> const char *const MaxString<uint8_t>::value = "255";
31 template <> const char *const MaxString<uint16_t>::value = "65535";
32 template <> const char *const MaxString<uint32_t>::value = "4294967295";
33 #if __SIZEOF_LONG__ == 4
34 template <> const char *const MaxString<unsigned long>::value =
37 template <> const char *const MaxString<unsigned long>::value =
38 "18446744073709551615";
40 static_assert(sizeof(unsigned long) >= 4,
41 "Wrong value for MaxString<unsigned long>::value,"
43 template <> const char *const MaxString<unsigned long long>::value =
44 "18446744073709551615";
45 static_assert(sizeof(unsigned long long) >= 8,
46 "Wrong value for MaxString<unsigned long long>::value"
49 #ifdef FOLLY_HAVE_INT128_T
50 template <> const char *const MaxString<__uint128_t>::value =
51 "340282366920938463463374607431768211455";
56 * Lookup tables that converts from a decimal character value to an integral
57 * binary value, shifted by a decimal "shift" multiplier.
58 * For all character values in the range '0'..'9', the table at those
59 * index locations returns the actual decimal value shifted by the multiplier.
60 * For all other values, the lookup table returns an invalid OOR value.
62 // Out-of-range flag value, larger than the largest value that can fit in
63 // four decimal bytes (9999), but four of these added up together should
64 // still not overflow uint16_t.
65 constexpr int32_t OOR = 10000;
67 FOLLY_ALIGNED(16) constexpr uint16_t shift1[] = {
68 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
69 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
70 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
71 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
72 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
73 1, 2, 3, 4, 5, 6, 7, 8, 9, OOR, OOR,
74 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
75 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
76 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
77 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
78 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
79 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
80 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
81 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
82 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
83 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
84 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
85 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
86 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
87 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
88 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
89 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
90 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
91 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
92 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
93 OOR, OOR, OOR, OOR, OOR, OOR // 250
96 FOLLY_ALIGNED(16) constexpr uint16_t shift10[] = {
97 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
98 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
99 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
100 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
101 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
102 10, 20, 30, 40, 50, 60, 70, 80, 90, OOR, OOR,
103 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
104 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
105 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
106 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
107 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
108 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
109 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
110 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
111 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
112 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
113 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
114 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
115 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
116 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
117 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
118 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
119 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
120 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
121 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
122 OOR, OOR, OOR, OOR, OOR, OOR // 250
125 FOLLY_ALIGNED(16) constexpr uint16_t shift100[] = {
126 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
127 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
128 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
129 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
130 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
131 100, 200, 300, 400, 500, 600, 700, 800, 900, OOR, OOR,
132 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
133 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
134 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
135 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
136 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
137 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
138 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
139 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
140 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
141 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
142 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
143 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
144 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
145 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
146 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
147 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
148 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
149 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
150 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
151 OOR, OOR, OOR, OOR, OOR, OOR // 250
154 FOLLY_ALIGNED(16) constexpr uint16_t shift1000[] = {
155 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
156 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
157 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
158 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
159 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
160 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, OOR, OOR,
161 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
162 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
163 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
164 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
165 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
166 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
167 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
168 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
169 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
170 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
171 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
172 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
173 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
174 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
175 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
176 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
177 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
178 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
179 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
180 OOR, OOR, OOR, OOR, OOR, OOR // 250
184 inline bool bool_str_cmp(const char** b, size_t len, const char* value) {
185 // Can't use strncasecmp, since we want to ensure that the full value matches
187 const char* e = *b + len;
188 const char* v = value;
190 if (p == e || tolower(*p) != *v) { // value is already lowercase
201 bool str_to_bool(StringPiece* src) {
202 auto b = src->begin(), e = src->end();
204 FOLLY_RANGE_CHECK_STRINGPIECE(
205 b < e, "No non-whitespace characters found in input string", *src);
206 if (!isspace(*b)) break;
215 for (; b < e && isdigit(*b); ++b) {
216 FOLLY_RANGE_CHECK_STRINGPIECE(
217 !result && (*b == '0' || *b == '1'),
218 "Integer overflow when parsing bool: must be 0 or 1", *src);
219 result = (*b == '1');
226 if (!bool_str_cmp(&b, len, "yes")) {
227 ++b; // accept the single 'y' character
233 if (!bool_str_cmp(&b, len, "no")) {
240 if (!bool_str_cmp(&b, len, "true")) {
247 if (!bool_str_cmp(&b, len, "false")) {
253 if (bool_str_cmp(&b, len, "on")) {
255 } else if (bool_str_cmp(&b, len, "off")) {
258 FOLLY_RANGE_CHECK_STRINGPIECE(false, "Invalid value for bool", *src);
262 FOLLY_RANGE_CHECK_STRINGPIECE(false, "Invalid value for bool", *src);
271 * StringPiece to double, with progress information. Alters the
272 * StringPiece parameter to munch the already-parsed characters.
275 Tgt str_to_floating(StringPiece* src) {
276 using namespace double_conversion;
277 static StringToDoubleConverter
278 conv(StringToDoubleConverter::ALLOW_TRAILING_JUNK
279 | StringToDoubleConverter::ALLOW_LEADING_SPACES,
281 // return this for junk input string
282 std::numeric_limits<double>::quiet_NaN(),
285 FOLLY_RANGE_CHECK_STRINGPIECE(!src->empty(),
286 "No digits found in input string", *src);
289 auto result = conv.StringToDouble(src->data(),
290 static_cast<int>(src->size()),
291 &length); // processed char count
293 if (!std::isnan(result)) {
294 src->advance(length);
298 for (;; src->advance(1)) {
300 throw std::range_error("Unable to convert an empty string"
301 " to a floating point value.");
303 if (!isspace(src->front())) {
308 // Was that "inf[inity]"?
309 if (src->size() >= 3 && toupper((*src)[0]) == 'I'
310 && toupper((*src)[1]) == 'N' && toupper((*src)[2]) == 'F') {
311 if (src->size() >= 8 &&
312 toupper((*src)[3]) == 'I' &&
313 toupper((*src)[4]) == 'N' &&
314 toupper((*src)[5]) == 'I' &&
315 toupper((*src)[6]) == 'T' &&
316 toupper((*src)[7]) == 'Y') {
321 return std::numeric_limits<Tgt>::infinity();
324 // Was that "-inf[inity]"?
325 if (src->size() >= 4 && toupper((*src)[0]) == '-'
326 && toupper((*src)[1]) == 'I' && toupper((*src)[2]) == 'N'
327 && toupper((*src)[3]) == 'F') {
328 if (src->size() >= 9 &&
329 toupper((*src)[4]) == 'I' &&
330 toupper((*src)[5]) == 'N' &&
331 toupper((*src)[6]) == 'I' &&
332 toupper((*src)[7]) == 'T' &&
333 toupper((*src)[8]) == 'Y') {
338 return -std::numeric_limits<Tgt>::infinity();
342 if (src->size() >= 3 && toupper((*src)[0]) == 'N'
343 && toupper((*src)[1]) == 'A' && toupper((*src)[2]) == 'N') {
345 return std::numeric_limits<Tgt>::quiet_NaN();
349 if (src->size() >= 4 &&
350 toupper((*src)[0]) == '-' &&
351 toupper((*src)[1]) == 'N' &&
352 toupper((*src)[2]) == 'A' &&
353 toupper((*src)[3]) == 'N') {
355 return -std::numeric_limits<Tgt>::quiet_NaN();
359 throw std::range_error("Unable to convert \"" + src->toString()
360 + "\" to a floating point value.");
365 float str_to_float(StringPiece* src) {
366 return str_to_floating<float>(src);
369 double str_to_double(StringPiece* src) {
370 return str_to_floating<double>(src);
374 * String represented as a pair of pointers to char to unsigned
375 * integrals. Assumes NO whitespace before or after, and also that the
376 * string is composed entirely of digits. Tgt must be unsigned, and no
377 * sign is allowed in the string (even it's '+'). String may be empty,
378 * in which case digits_to throws.
381 Tgt digits_to(const char* b, const char* e) {
383 static_assert(!std::is_signed<Tgt>::value, "Unsigned type expected");
386 const size_t size = e - b;
388 /* Although the string is entirely made of digits, we still need to
389 * check for overflow.
391 if (size >= std::numeric_limits<Tgt>::digits10 + 1) {
392 // Leading zeros? If so, recurse to keep things simple
393 if (b < e && *b == '0') {
396 return 0; // just zeros, e.g. "0000"
398 return digits_to<Tgt>(b, e);
401 FOLLY_RANGE_CHECK_BEGIN_END(
402 size == std::numeric_limits<Tgt>::digits10 + 1 &&
403 strncmp(b, detail::MaxString<Tgt>::value, size) <= 0,
404 "Numeric overflow upon conversion",
409 // Here we know that the number won't overflow when
410 // converted. Proceed without checks.
414 for (; e - b >= 4; b += 4) {
416 const int32_t r0 = shift1000[static_cast<size_t>(b[0])];
417 const int32_t r1 = shift100[static_cast<size_t>(b[1])];
418 const int32_t r2 = shift10[static_cast<size_t>(b[2])];
419 const int32_t r3 = shift1[static_cast<size_t>(b[3])];
420 const auto sum = r0 + r1 + r2 + r3;
421 assert(sum < OOR && "Assumption: string only has digits");
427 const int32_t r0 = shift100[static_cast<size_t>(b[0])];
428 const int32_t r1 = shift10[static_cast<size_t>(b[1])];
429 const int32_t r2 = shift1[static_cast<size_t>(b[2])];
430 const auto sum = r0 + r1 + r2;
431 assert(sum < OOR && "Assumption: string only has digits");
432 return result * 1000 + sum;
435 const int32_t r0 = shift10[static_cast<size_t>(b[0])];
436 const int32_t r1 = shift1[static_cast<size_t>(b[1])];
437 const auto sum = r0 + r1;
438 assert(sum < OOR && "Assumption: string only has digits");
439 return result * 100 + sum;
442 const int32_t sum = shift1[static_cast<size_t>(b[0])];
443 assert(sum < OOR && "Assumption: string only has digits");
444 return result * 10 + sum;
449 FOLLY_RANGE_CHECK_BEGIN_END(
450 size > 0, "Found no digits to convert in input", b, e);
454 template unsigned char digits_to<unsigned char>(const char* b, const char* e);
455 template unsigned short digits_to<unsigned short>(const char* b, const char* e);
456 template unsigned int digits_to<unsigned int>(const char* b, const char* e);
457 template unsigned long digits_to<unsigned long>(const char* b, const char* e);
458 template unsigned long long digits_to<unsigned long long>(const char* b,
460 #if FOLLY_HAVE_INT128_T
461 template unsigned __int128 digits_to<unsigned __int128>(const char* b,
465 } // namespace detail