Conv.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. /*
  2. * Copyright 2011-present Facebook, Inc.
  3. *
  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
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  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.
  15. */
  16. #include <folly/Conv.h>
  17. #include <array>
  18. namespace folly {
  19. namespace detail {
  20. namespace {
  21. /**
  22. * Finds the first non-digit in a string. The number of digits
  23. * searched depends on the precision of the Tgt integral. Assumes the
  24. * string starts with NO whitespace and NO sign.
  25. *
  26. * The semantics of the routine is:
  27. * for (;; ++b) {
  28. * if (b >= e || !isdigit(*b)) return b;
  29. * }
  30. *
  31. * Complete unrolling marks bottom-line (i.e. entire conversion)
  32. * improvements of 20%.
  33. */
  34. inline const char* findFirstNonDigit(const char* b, const char* e) {
  35. for (; b < e; ++b) {
  36. auto const c = static_cast<unsigned>(*b) - '0';
  37. if (c >= 10) {
  38. break;
  39. }
  40. }
  41. return b;
  42. }
  43. // Maximum value of number when represented as a string
  44. template <class T>
  45. struct MaxString {
  46. static const char* const value;
  47. };
  48. template <>
  49. const char* const MaxString<uint8_t>::value = "255";
  50. template <>
  51. const char* const MaxString<uint16_t>::value = "65535";
  52. template <>
  53. const char* const MaxString<uint32_t>::value = "4294967295";
  54. #if __SIZEOF_LONG__ == 4
  55. template <>
  56. const char* const MaxString<unsigned long>::value = "4294967295";
  57. #else
  58. template <>
  59. const char* const MaxString<unsigned long>::value = "18446744073709551615";
  60. #endif
  61. static_assert(
  62. sizeof(unsigned long) >= 4,
  63. "Wrong value for MaxString<unsigned long>::value,"
  64. " please update.");
  65. template <>
  66. const char* const MaxString<unsigned long long>::value = "18446744073709551615";
  67. static_assert(
  68. sizeof(unsigned long long) >= 8,
  69. "Wrong value for MaxString<unsigned long long>::value"
  70. ", please update.");
  71. #if FOLLY_HAVE_INT128_T
  72. template <>
  73. const char* const MaxString<__uint128_t>::value =
  74. "340282366920938463463374607431768211455";
  75. #endif
  76. /*
  77. * Lookup tables that converts from a decimal character value to an integral
  78. * binary value, shifted by a decimal "shift" multiplier.
  79. * For all character values in the range '0'..'9', the table at those
  80. * index locations returns the actual decimal value shifted by the multiplier.
  81. * For all other values, the lookup table returns an invalid OOR value.
  82. */
  83. // Out-of-range flag value, larger than the largest value that can fit in
  84. // four decimal bytes (9999), but four of these added up together should
  85. // still not overflow uint16_t.
  86. constexpr int32_t OOR = 10000;
  87. alignas(16) constexpr uint16_t shift1[] = {
  88. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
  89. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
  90. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
  91. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
  92. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, 1, // 40
  93. 2, 3, 4, 5, 6, 7, 8, 9, OOR, OOR,
  94. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
  95. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
  96. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
  97. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
  98. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
  99. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
  100. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
  101. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
  102. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
  103. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
  104. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
  105. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
  106. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
  107. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
  108. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
  109. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
  110. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
  111. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
  112. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
  113. OOR, OOR, OOR, OOR, OOR, OOR // 250
  114. };
  115. alignas(16) constexpr uint16_t shift10[] = {
  116. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
  117. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
  118. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
  119. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
  120. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, 10, // 40
  121. 20, 30, 40, 50, 60, 70, 80, 90, OOR, OOR,
  122. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
  123. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
  124. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
  125. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
  126. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
  127. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
  128. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
  129. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
  130. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
  131. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
  132. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
  133. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
  134. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
  135. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
  136. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
  137. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
  138. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
  139. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
  140. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
  141. OOR, OOR, OOR, OOR, OOR, OOR // 250
  142. };
  143. alignas(16) constexpr uint16_t shift100[] = {
  144. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
  145. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
  146. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
  147. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
  148. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, 100, // 40
  149. 200, 300, 400, 500, 600, 700, 800, 900, OOR, OOR,
  150. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
  151. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
  152. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
  153. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
  154. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
  155. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
  156. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
  157. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
  158. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
  159. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
  160. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
  161. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
  162. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
  163. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
  164. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
  165. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
  166. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
  167. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
  168. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
  169. OOR, OOR, OOR, OOR, OOR, OOR // 250
  170. };
  171. alignas(16) constexpr uint16_t shift1000[] = {
  172. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
  173. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
  174. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
  175. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
  176. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, 1000, // 40
  177. 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, OOR, OOR,
  178. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
  179. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
  180. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
  181. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
  182. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
  183. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
  184. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
  185. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
  186. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
  187. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
  188. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
  189. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
  190. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
  191. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
  192. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
  193. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
  194. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
  195. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
  196. OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
  197. OOR, OOR, OOR, OOR, OOR, OOR // 250
  198. };
  199. struct ErrorString {
  200. const char* string;
  201. bool quote;
  202. };
  203. // Keep this in sync with ConversionCode in Conv.h
  204. constexpr const std::array<
  205. ErrorString,
  206. static_cast<std::size_t>(ConversionCode::NUM_ERROR_CODES)>
  207. kErrorStrings{{
  208. {"Success", true},
  209. {"Empty input string", true},
  210. {"No digits found in input string", true},
  211. {"Integer overflow when parsing bool (must be 0 or 1)", true},
  212. {"Invalid value for bool", true},
  213. {"Non-digit character found", true},
  214. {"Invalid leading character", true},
  215. {"Overflow during conversion", true},
  216. {"Negative overflow during conversion", true},
  217. {"Unable to convert string to floating point value", true},
  218. {"Non-whitespace character found after end of conversion", true},
  219. {"Overflow during arithmetic conversion", false},
  220. {"Negative overflow during arithmetic conversion", false},
  221. {"Loss of precision during arithmetic conversion", false},
  222. }};
  223. // Check if ASCII is really ASCII
  224. using IsAscii =
  225. bool_constant<'A' == 65 && 'Z' == 90 && 'a' == 97 && 'z' == 122>;
  226. // The code in this file that uses tolower() really only cares about
  227. // 7-bit ASCII characters, so we can take a nice shortcut here.
  228. inline char tolower_ascii(char in) {
  229. return IsAscii::value ? in | 0x20 : char(std::tolower(in));
  230. }
  231. inline bool bool_str_cmp(const char** b, size_t len, const char* value) {
  232. // Can't use strncasecmp, since we want to ensure that the full value matches
  233. const char* p = *b;
  234. const char* e = *b + len;
  235. const char* v = value;
  236. while (*v != '\0') {
  237. if (p == e || tolower_ascii(*p) != *v) { // value is already lowercase
  238. return false;
  239. }
  240. ++p;
  241. ++v;
  242. }
  243. *b = p;
  244. return true;
  245. }
  246. } // namespace
  247. Expected<bool, ConversionCode> str_to_bool(StringPiece* src) noexcept {
  248. auto b = src->begin(), e = src->end();
  249. for (;; ++b) {
  250. if (b >= e) {
  251. return makeUnexpected(ConversionCode::EMPTY_INPUT_STRING);
  252. }
  253. if (!std::isspace(*b)) {
  254. break;
  255. }
  256. }
  257. bool result;
  258. size_t len = size_t(e - b);
  259. switch (*b) {
  260. case '0':
  261. case '1': {
  262. result = false;
  263. for (; b < e && isdigit(*b); ++b) {
  264. if (result || (*b != '0' && *b != '1')) {
  265. return makeUnexpected(ConversionCode::BOOL_OVERFLOW);
  266. }
  267. result = (*b == '1');
  268. }
  269. break;
  270. }
  271. case 'y':
  272. case 'Y':
  273. result = true;
  274. if (!bool_str_cmp(&b, len, "yes")) {
  275. ++b; // accept the single 'y' character
  276. }
  277. break;
  278. case 'n':
  279. case 'N':
  280. result = false;
  281. if (!bool_str_cmp(&b, len, "no")) {
  282. ++b;
  283. }
  284. break;
  285. case 't':
  286. case 'T':
  287. result = true;
  288. if (!bool_str_cmp(&b, len, "true")) {
  289. ++b;
  290. }
  291. break;
  292. case 'f':
  293. case 'F':
  294. result = false;
  295. if (!bool_str_cmp(&b, len, "false")) {
  296. ++b;
  297. }
  298. break;
  299. case 'o':
  300. case 'O':
  301. if (bool_str_cmp(&b, len, "on")) {
  302. result = true;
  303. } else if (bool_str_cmp(&b, len, "off")) {
  304. result = false;
  305. } else {
  306. return makeUnexpected(ConversionCode::BOOL_INVALID_VALUE);
  307. }
  308. break;
  309. default:
  310. return makeUnexpected(ConversionCode::BOOL_INVALID_VALUE);
  311. }
  312. src->assign(b, e);
  313. return result;
  314. }
  315. /**
  316. * StringPiece to double, with progress information. Alters the
  317. * StringPiece parameter to munch the already-parsed characters.
  318. */
  319. template <class Tgt>
  320. Expected<Tgt, ConversionCode> str_to_floating(StringPiece* src) noexcept {
  321. using namespace double_conversion;
  322. static StringToDoubleConverter conv(
  323. StringToDoubleConverter::ALLOW_TRAILING_JUNK |
  324. StringToDoubleConverter::ALLOW_LEADING_SPACES,
  325. 0.0,
  326. // return this for junk input string
  327. std::numeric_limits<double>::quiet_NaN(),
  328. nullptr,
  329. nullptr);
  330. if (src->empty()) {
  331. return makeUnexpected(ConversionCode::EMPTY_INPUT_STRING);
  332. }
  333. int length;
  334. auto result = conv.StringToDouble(
  335. src->data(),
  336. static_cast<int>(src->size()),
  337. &length); // processed char count
  338. if (!std::isnan(result)) {
  339. // If we get here with length = 0, the input string is empty.
  340. // If we get here with result = 0.0, it's either because the string
  341. // contained only whitespace, or because we had an actual zero value
  342. // (with potential trailing junk). If it was only whitespace, we
  343. // want to raise an error; length will point past the last character
  344. // that was processed, so we need to check if that character was
  345. // whitespace or not.
  346. if (length == 0 ||
  347. (result == 0.0 && std::isspace((*src)[size_t(length) - 1]))) {
  348. return makeUnexpected(ConversionCode::EMPTY_INPUT_STRING);
  349. }
  350. if (length >= 2) {
  351. const char* suffix = src->data() + length - 1;
  352. // double_conversion doesn't update length correctly when there is an
  353. // incomplete exponent specifier. Converting "12e-f-g" shouldn't consume
  354. // any more than "12", but it will consume "12e-".
  355. // "123-" should only parse "123"
  356. if (*suffix == '-' || *suffix == '+') {
  357. --suffix;
  358. --length;
  359. }
  360. // "12e-f-g" or "12euro" should only parse "12"
  361. if (*suffix == 'e' || *suffix == 'E') {
  362. --length;
  363. }
  364. }
  365. src->advance(size_t(length));
  366. return Tgt(result);
  367. }
  368. auto* e = src->end();
  369. auto* b =
  370. std::find_if_not(src->begin(), e, [](char c) { return std::isspace(c); });
  371. // There must be non-whitespace, otherwise we would have caught this above
  372. assert(b < e);
  373. size_t size = size_t(e - b);
  374. bool negative = false;
  375. if (*b == '-') {
  376. negative = true;
  377. ++b;
  378. --size;
  379. }
  380. result = 0.0;
  381. switch (tolower_ascii(*b)) {
  382. case 'i':
  383. if (size >= 3 && tolower_ascii(b[1]) == 'n' &&
  384. tolower_ascii(b[2]) == 'f') {
  385. if (size >= 8 && tolower_ascii(b[3]) == 'i' &&
  386. tolower_ascii(b[4]) == 'n' && tolower_ascii(b[5]) == 'i' &&
  387. tolower_ascii(b[6]) == 't' && tolower_ascii(b[7]) == 'y') {
  388. b += 8;
  389. } else {
  390. b += 3;
  391. }
  392. result = std::numeric_limits<Tgt>::infinity();
  393. }
  394. break;
  395. case 'n':
  396. if (size >= 3 && tolower_ascii(b[1]) == 'a' &&
  397. tolower_ascii(b[2]) == 'n') {
  398. b += 3;
  399. result = std::numeric_limits<Tgt>::quiet_NaN();
  400. }
  401. break;
  402. default:
  403. break;
  404. }
  405. if (result == 0.0) {
  406. // All bets are off
  407. return makeUnexpected(ConversionCode::STRING_TO_FLOAT_ERROR);
  408. }
  409. if (negative) {
  410. result = -result;
  411. }
  412. src->assign(b, e);
  413. return Tgt(result);
  414. }
  415. template Expected<float, ConversionCode> str_to_floating<float>(
  416. StringPiece* src) noexcept;
  417. template Expected<double, ConversionCode> str_to_floating<double>(
  418. StringPiece* src) noexcept;
  419. /**
  420. * This class takes care of additional processing needed for signed values,
  421. * like leading sign character and overflow checks.
  422. */
  423. template <typename T, bool IsSigned = std::is_signed<T>::value>
  424. class SignedValueHandler;
  425. template <typename T>
  426. class SignedValueHandler<T, true> {
  427. public:
  428. ConversionCode init(const char*& b) {
  429. negative_ = false;
  430. if (!std::isdigit(*b)) {
  431. if (*b == '-') {
  432. negative_ = true;
  433. } else if (UNLIKELY(*b != '+')) {
  434. return ConversionCode::INVALID_LEADING_CHAR;
  435. }
  436. ++b;
  437. }
  438. return ConversionCode::SUCCESS;
  439. }
  440. ConversionCode overflow() {
  441. return negative_ ? ConversionCode::NEGATIVE_OVERFLOW
  442. : ConversionCode::POSITIVE_OVERFLOW;
  443. }
  444. template <typename U>
  445. Expected<T, ConversionCode> finalize(U value) {
  446. T rv;
  447. if (negative_) {
  448. rv = T(-value);
  449. if (UNLIKELY(rv > 0)) {
  450. return makeUnexpected(ConversionCode::NEGATIVE_OVERFLOW);
  451. }
  452. } else {
  453. rv = T(value);
  454. if (UNLIKELY(rv < 0)) {
  455. return makeUnexpected(ConversionCode::POSITIVE_OVERFLOW);
  456. }
  457. }
  458. return rv;
  459. }
  460. private:
  461. bool negative_;
  462. };
  463. // For unsigned types, we don't need any extra processing
  464. template <typename T>
  465. class SignedValueHandler<T, false> {
  466. public:
  467. ConversionCode init(const char*&) {
  468. return ConversionCode::SUCCESS;
  469. }
  470. ConversionCode overflow() {
  471. return ConversionCode::POSITIVE_OVERFLOW;
  472. }
  473. Expected<T, ConversionCode> finalize(T value) {
  474. return value;
  475. }
  476. };
  477. /**
  478. * String represented as a pair of pointers to char to signed/unsigned
  479. * integrals. Assumes NO whitespace before or after, and also that the
  480. * string is composed entirely of digits (and an optional sign only for
  481. * signed types). String may be empty, in which case digits_to returns
  482. * an appropriate error.
  483. */
  484. template <class Tgt>
  485. inline Expected<Tgt, ConversionCode> digits_to(
  486. const char* b,
  487. const char* const e) noexcept {
  488. using UT = typename std::make_unsigned<Tgt>::type;
  489. assert(b <= e);
  490. SignedValueHandler<Tgt> sgn;
  491. auto err = sgn.init(b);
  492. if (UNLIKELY(err != ConversionCode::SUCCESS)) {
  493. return makeUnexpected(err);
  494. }
  495. size_t size = size_t(e - b);
  496. /* Although the string is entirely made of digits, we still need to
  497. * check for overflow.
  498. */
  499. if (size > std::numeric_limits<UT>::digits10) {
  500. // Leading zeros?
  501. if (b < e && *b == '0') {
  502. for (++b;; ++b) {
  503. if (b == e) {
  504. return Tgt(0); // just zeros, e.g. "0000"
  505. }
  506. if (*b != '0') {
  507. size = size_t(e - b);
  508. break;
  509. }
  510. }
  511. }
  512. if (size > std::numeric_limits<UT>::digits10 &&
  513. (size != std::numeric_limits<UT>::digits10 + 1 ||
  514. strncmp(b, MaxString<UT>::value, size) > 0)) {
  515. return makeUnexpected(sgn.overflow());
  516. }
  517. }
  518. // Here we know that the number won't overflow when
  519. // converted. Proceed without checks.
  520. UT result = 0;
  521. for (; e - b >= 4; b += 4) {
  522. result *= static_cast<UT>(10000);
  523. const int32_t r0 = shift1000[static_cast<size_t>(b[0])];
  524. const int32_t r1 = shift100[static_cast<size_t>(b[1])];
  525. const int32_t r2 = shift10[static_cast<size_t>(b[2])];
  526. const int32_t r3 = shift1[static_cast<size_t>(b[3])];
  527. const auto sum = r0 + r1 + r2 + r3;
  528. if (sum >= OOR) {
  529. goto outOfRange;
  530. }
  531. result += UT(sum);
  532. }
  533. switch (e - b) {
  534. case 3: {
  535. const int32_t r0 = shift100[static_cast<size_t>(b[0])];
  536. const int32_t r1 = shift10[static_cast<size_t>(b[1])];
  537. const int32_t r2 = shift1[static_cast<size_t>(b[2])];
  538. const auto sum = r0 + r1 + r2;
  539. if (sum >= OOR) {
  540. goto outOfRange;
  541. }
  542. result = UT(1000 * result + sum);
  543. break;
  544. }
  545. case 2: {
  546. const int32_t r0 = shift10[static_cast<size_t>(b[0])];
  547. const int32_t r1 = shift1[static_cast<size_t>(b[1])];
  548. const auto sum = r0 + r1;
  549. if (sum >= OOR) {
  550. goto outOfRange;
  551. }
  552. result = UT(100 * result + sum);
  553. break;
  554. }
  555. case 1: {
  556. const int32_t sum = shift1[static_cast<size_t>(b[0])];
  557. if (sum >= OOR) {
  558. goto outOfRange;
  559. }
  560. result = UT(10 * result + sum);
  561. break;
  562. }
  563. default:
  564. assert(b == e);
  565. if (size == 0) {
  566. return makeUnexpected(ConversionCode::NO_DIGITS);
  567. }
  568. break;
  569. }
  570. return sgn.finalize(result);
  571. outOfRange:
  572. return makeUnexpected(ConversionCode::NON_DIGIT_CHAR);
  573. }
  574. template Expected<char, ConversionCode> digits_to<char>(
  575. const char*,
  576. const char*) noexcept;
  577. template Expected<signed char, ConversionCode> digits_to<signed char>(
  578. const char*,
  579. const char*) noexcept;
  580. template Expected<unsigned char, ConversionCode> digits_to<unsigned char>(
  581. const char*,
  582. const char*) noexcept;
  583. template Expected<short, ConversionCode> digits_to<short>(
  584. const char*,
  585. const char*) noexcept;
  586. template Expected<unsigned short, ConversionCode> digits_to<unsigned short>(
  587. const char*,
  588. const char*) noexcept;
  589. template Expected<int, ConversionCode> digits_to<int>(
  590. const char*,
  591. const char*) noexcept;
  592. template Expected<unsigned int, ConversionCode> digits_to<unsigned int>(
  593. const char*,
  594. const char*) noexcept;
  595. template Expected<long, ConversionCode> digits_to<long>(
  596. const char*,
  597. const char*) noexcept;
  598. template Expected<unsigned long, ConversionCode> digits_to<unsigned long>(
  599. const char*,
  600. const char*) noexcept;
  601. template Expected<long long, ConversionCode> digits_to<long long>(
  602. const char*,
  603. const char*) noexcept;
  604. template Expected<unsigned long long, ConversionCode>
  605. digits_to<unsigned long long>(const char*, const char*) noexcept;
  606. #if FOLLY_HAVE_INT128_T
  607. template Expected<__int128, ConversionCode> digits_to<__int128>(
  608. const char*,
  609. const char*) noexcept;
  610. template Expected<unsigned __int128, ConversionCode>
  611. digits_to<unsigned __int128>(const char*, const char*) noexcept;
  612. #endif
  613. /**
  614. * StringPiece to integrals, with progress information. Alters the
  615. * StringPiece parameter to munch the already-parsed characters.
  616. */
  617. template <class Tgt>
  618. Expected<Tgt, ConversionCode> str_to_integral(StringPiece* src) noexcept {
  619. using UT = typename std::make_unsigned<Tgt>::type;
  620. auto b = src->data(), past = src->data() + src->size();
  621. for (;; ++b) {
  622. if (UNLIKELY(b >= past)) {
  623. return makeUnexpected(ConversionCode::EMPTY_INPUT_STRING);
  624. }
  625. if (!std::isspace(*b)) {
  626. break;
  627. }
  628. }
  629. SignedValueHandler<Tgt> sgn;
  630. auto err = sgn.init(b);
  631. if (UNLIKELY(err != ConversionCode::SUCCESS)) {
  632. return makeUnexpected(err);
  633. }
  634. if (std::is_signed<Tgt>::value && UNLIKELY(b >= past)) {
  635. return makeUnexpected(ConversionCode::NO_DIGITS);
  636. }
  637. if (UNLIKELY(!isdigit(*b))) {
  638. return makeUnexpected(ConversionCode::NON_DIGIT_CHAR);
  639. }
  640. auto m = findFirstNonDigit(b + 1, past);
  641. auto tmp = digits_to<UT>(b, m);
  642. if (UNLIKELY(!tmp.hasValue())) {
  643. return makeUnexpected(
  644. tmp.error() == ConversionCode::POSITIVE_OVERFLOW ? sgn.overflow()
  645. : tmp.error());
  646. }
  647. auto res = sgn.finalize(tmp.value());
  648. if (res.hasValue()) {
  649. src->advance(size_t(m - src->data()));
  650. }
  651. return res;
  652. }
  653. template Expected<char, ConversionCode> str_to_integral<char>(
  654. StringPiece* src) noexcept;
  655. template Expected<signed char, ConversionCode> str_to_integral<signed char>(
  656. StringPiece* src) noexcept;
  657. template Expected<unsigned char, ConversionCode> str_to_integral<unsigned char>(
  658. StringPiece* src) noexcept;
  659. template Expected<short, ConversionCode> str_to_integral<short>(
  660. StringPiece* src) noexcept;
  661. template Expected<unsigned short, ConversionCode>
  662. str_to_integral<unsigned short>(StringPiece* src) noexcept;
  663. template Expected<int, ConversionCode> str_to_integral<int>(
  664. StringPiece* src) noexcept;
  665. template Expected<unsigned int, ConversionCode> str_to_integral<unsigned int>(
  666. StringPiece* src) noexcept;
  667. template Expected<long, ConversionCode> str_to_integral<long>(
  668. StringPiece* src) noexcept;
  669. template Expected<unsigned long, ConversionCode> str_to_integral<unsigned long>(
  670. StringPiece* src) noexcept;
  671. template Expected<long long, ConversionCode> str_to_integral<long long>(
  672. StringPiece* src) noexcept;
  673. template Expected<unsigned long long, ConversionCode>
  674. str_to_integral<unsigned long long>(StringPiece* src) noexcept;
  675. #if FOLLY_HAVE_INT128_T
  676. template Expected<__int128, ConversionCode> str_to_integral<__int128>(
  677. StringPiece* src) noexcept;
  678. template Expected<unsigned __int128, ConversionCode>
  679. str_to_integral<unsigned __int128>(StringPiece* src) noexcept;
  680. #endif
  681. } // namespace detail
  682. ConversionError makeConversionError(ConversionCode code, StringPiece input) {
  683. using namespace detail;
  684. static_assert(
  685. std::is_unsigned<std::underlying_type<ConversionCode>::type>::value,
  686. "ConversionCode should be unsigned");
  687. assert((std::size_t)code < kErrorStrings.size());
  688. const ErrorString& err = kErrorStrings[(std::size_t)code];
  689. if (code == ConversionCode::EMPTY_INPUT_STRING && input.empty()) {
  690. return {err.string, code};
  691. }
  692. std::string tmp(err.string);
  693. tmp.append(": ");
  694. if (err.quote) {
  695. tmp.append(1, '"');
  696. }
  697. if (input.size() > 0) {
  698. tmp.append(input.data(), input.size());
  699. }
  700. if (err.quote) {
  701. tmp.append(1, '"');
  702. }
  703. return {tmp, code};
  704. }
  705. } // namespace folly