I'm trying to use cereal to deserialize a JSON message. The (current) message structure is as follows:
"A":"B",
"C":{"D":"E","F":"G","H":"I"}
"J":"K",
"L":"M"
"N":{"O":{"P":"Q"}}}
The most important piece of data is "Q." I can read all the normal strings easily. I was able to read the top-level items easily. I eventually was able to read "D"-"I" by treating "C" as an array (despite the lack of "["and "]"). However, I am unable to archive "N" as a string, array, vector, or object. It simply fails the respective IsString(), IsObject(), etc check on the iarchive(C);
line. I see a GetType()
, but I don't know to call that on "N" because anything I try to do with "N" fails.
I then was able to break the string down to just
{"O":{"P":"Q"}}
great, so just "C", but even simpler. Unfortunately, I had the same issue as before.
I then broke it down to just {"P":"Q"} and was able to finally get the value of Q via iarchive(value)
std::string msgtype,protocol_version, command, radio1_frequency,value;
std::string unit_id[3];
std::stringstream ss(msg->get_payload());
{//at this point, ^ss has the same format as outlined above, from "A" to "Q."
cereal::JSONInputArchive iarchive(ss);
iarchive(CEREAL_NVP(msgtype), CEREAL_NVP(protocol_version), CEREAL_NVP(command),CEREAL_NVP(unit_id));<-----------------------
}
rapidjson::Document doc;
doc.Parse((msg->get_payload()).c_str());
const rapidjson::Value& vars = doc["variables"];//<--this string is N
rapidjson::StringBuffer sb;
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
vars.Accept(writer);
std::stringstream sst(sb.GetString());
std::cout << sst.str() << "\n"; //here, sst has {"O":{"P":"Q"}}
doc.Parse(sb.GetString());
const rapidjson::Value& val = doc["radio1_frequency"];//<--this string is O
sb.Clear();
rapidjson::Writer<rapidjson::StringBuffer> writerTwo(sb);
val.Accept(writerTwo);
std::cout << sb.GetString() << "\n";//ss3 will now have {"P":"Q"}
std::stringstream ss3(sb.GetString());
{
cereal::JSONInputArchive iarchive(ss3);
iarchive((value));
std::cout << value << '\n';//Q
}
if I add ,CEREAL_NVP(variables)
to the line with the arrow, I get the following output:
terminate called after throwing an instance of 'cereal::RapidJSONException'
what(): rapidjson internal assertion failure: IsString()
Child terminated with signal = 0x6 (SIGABRT)
To be clear, I get the result that I want, Q. I just feel like there must be a better way. I feel like the root of the problem is that I am unable to identify what type N is. Since I don't know the type, I don't know how to properly archive it in cereal. What can I do better inside the realm of C++11 and cereal, which uses rapidjson?
I wonder if it is because "O" has a number in the middle of the string and that is throwing it off. I should hope not because that's a valid string I believe
Aucun commentaire:
Enregistrer un commentaire