Search code examples
c++jsonrapidjsoncereal

Accept null values for strings with rapidjson inside cereal, make them ""


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()"


Solution

  • 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