For deserializing JSON into a c++ class, I'm using Cereal, which uses RapidJSON. As expected, c++ std::string can't have a null value. But other platforms do support null for strings (.NET SQL etc) and I get JSON from them with null values for strings. I need to tolerate this, and just make an empty string for nulls. What's the best way to do that?
I default to string substitute on the JSON changing nulls to "" like the following, but it is not a clean solution.
#include <cereal/archives/json.hpp>
#include <boost/algorithm/string.hpp>
// i.e. substitue all ":null with ":"" Like {"key":null} into {"key":""}
boost::replace_all(json, "\":null", "\":\"\"");
auto r = std::make_shared<R>();
std::stringstream ss(json);
{
cereal::JSONInputArchive archive(ss);
r->serialize(archive);
}
In case someone looks for this answer based on the exception generated by Cereal, it is: "rapidjson internal assertion failure: IsString()"
in cereal-1.1.2\include\cereal\external\rapidjson\document.h change this
const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return data_.s.str; }
to this
const Ch* GetString() const { if (IsNull_()) return ""; RAPIDJSON_ASSERT(IsString()); return data_.s.str; }
I'm not proposing this should be changed in the cereal source because some people may want strict type checking like the original