Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect with "JSON for Modern C++" library that integer doesn't fit into a specified type?

This code prints -1:

#include <iostream>
#include <nlohmann/json.hpp>

int main()
{
    auto jsonText = "{ \"val\" : 4294967295 }";
    auto json = nlohmann::json::parse(jsonText);
    std::cout << json.at("val").get<int>() << std::endl;
}

I would like to detect that the value is out of the expected range. Is it possible to accomplish somehow?

like image 727
Ivan Ivanov Avatar asked Sep 06 '19 14:09

Ivan Ivanov


1 Answers

The only way to do what you want is to actually retrieve the value in a larger integer type, and then check if the value is within the range of int.

using integer_t = nlohmann::json::number_integer_t;
auto ivalue = json.at("val").get<integer_t>();

if (ivalue < std::numeric_limits<int>::min() || ivalue > std::numeric_limits<int>::max()) {
    // Range error... 
}

Some details...

The number is parsed during the call to parse() using std::strtoull or std::strtoll (depending on the presence of a - sign), and converted to a nlohmann::json::number_integer_t (int64_t1) or nlohmann::json::number_unsigned_t (uint64_t1).

When you query the value with get<int>, the only thing done is a cast from the stored int64_t/uint64_t value to int, so there is no way to check the range at this point.

Also, you cannot retrieve the original "string" since only the actual (unsigned) integer value is stored.

1int64_t and uint64_t are the default types since nlohmann::json is actually an alias to a basic_json template (much like std::string), but you can use whatever types you want.

like image 188
Holt Avatar answered Sep 20 '22 13:09

Holt