MCPcopy Create free account
hub / github.com/bcndev/bytecoin / get_integer_impl2

Function get_integer_impl2

src/common/JsonValue.cpp:478–532  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

476
477template<class T>
478T get_integer_impl2(const std::string &str) {
479 try {
480 // Most integers are integers, fast path
481 return common::integer_cast<T>(str);
482 } catch (const std::exception &) {
483 }
484 // But if not, we try maximally adhere to standard.
485 // We parse example values below as integers without losing precision
486 // 20000000000000000000000000000000E-31
487 // 0.000000000000000000000000000000003E33
488 // 92233720368547758060E-1
489 // 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001811234E206
490 try {
491 std::string ip;
492 std::string fp;
493 std::string ep;
494 size_t zpos = 0; // fast detect of ip == "0" || ip == "-0"
495 split_number_to_parts(str, zpos, ip, fp, ep);
496 if (!ep.empty()) {
497 int ex = common::integer_cast<int>(ep);
498 // If fp not empty or number is zero, cannot shift right
499 if (fp.empty() && (ip.size() != zpos + 1 || ip[zpos] != '0')) {
500 for (; ex < 0; ++ex) {
501 // Can only shift if right digit is zero
502 if (ip.empty() || ip.back() != '0')
503 throw std::runtime_error("Number must be whole");
504 ip.pop_back();
505 }
506 }
507 for (; ex > 0; --ex) {
508 if (!fp.empty()) {
509 // If ip is zero, replace right digit with fractional digit
510 if (ip.size() == zpos + 1 && ip[zpos] == '0')
511 ip.pop_back();
512 ip.push_back(fp[0]);
513 fp.erase(fp.begin());
514 } else {
515 // If ip is zero and fp empty, result is zero
516 if (ip.size() == zpos + 1 && ip[zpos] == '0')
517 break;
518 ip.push_back('0');
519 }
520 if (ip.size() > 100) // Arbitrary limit to stop loop
521 throw std::runtime_error("Number too large");
522 }
523 }
524 if (!fp.empty())
525 throw std::runtime_error("Number must be whole");
526 if (ip == "-0")
527 ip = "0";
528 return common::integer_cast<T>(ip);
529 } catch (const std::exception &ex) {
530 throw std::out_of_range("Json number (" + str + ") can not be converted because " + common::what(ex));
531 }
532}
533JsonValue::Integer JsonValue::get_integer() const {
534 if (type != NUMBER)
535 throw std::runtime_error("JsonValue type is not NUMBER");

Callers

nothing calls this directly

Calls 5

split_number_to_partsFunction · 0.85
emptyMethod · 0.45
sizeMethod · 0.45
eraseMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected