Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Cereal to deserialize a JSON string

I am new to Cereal and I am having a hard time understanding how to deserialize a JSON string. Unfortunately, my work firewall restricts me from accessing Google Groups to post on the message board.

I have a class that I can turn into a JSON string but can’t for the life of me take the string and recreate the class. Any help would be appreciated and please be gentle I just got out of school, it is my first job, and I am way out my depth.

This is the error I am getting:

terminate called after throwing an instance of 'cereal::RapidJSONException' what(): rapidjson internal assertion failure: IsObject()

Below is MyClass.hpp class:

#include <cstdio>
#include <iostream>
#include <string>
#include "../cereal/access.hpp"

class MyClass{
Public: //function declarations 
     template<class Archive> // public serialization (normal)
     void serialize(Archive & ar)
     {
         ar(x, y, z);
     }

private: // member variables 
    string x; 
    int y; 
    bool z;
};

Below is my Main.cpp:

#include <../cereal/types/unordered_map.hpp>
#include <../cereal/types/memory.hpp>
#include <../cereal/types/concepts/pair_associative_container.hpp>
#include <../cereal/archives/json.hpp>
#include <../cereal/types/vector.hpp>

#include <iostream>
#include <fstream>

#include "MyClass.hpp"

int main(){
    // serialize (this part all works... i think)
    {
        // create a class object and give it some data 
        MyClass data("hello", 6, true);
        // create a string stream object 
        std::stringstream os;
        // assign the string stream object to the Output Archive 
        cereal::JSONOutputArchive archive_out(os);
        //write data to the output archive 
        archive_out(CEREAL_NVP( data ));
        // write the string stream buffer to a variable 
        string json_str = os.str();
    }   
    // deserialize
    {
        // create a string stream object and pass it the string variable holding the JSON archive 
        std::stringstream is( json_str );
        // pass the stream sting object into the input archive **** this is the line of code that generates the error
        cereal::JSONInputArchive archive_in( is );
        // create a new object of MyClass
        MyClass data_new;
        // use input archive to write data to my class
        archive_in( data_new );
    }
}
like image 595
A.Webb Avatar asked Dec 19 '22 02:12

A.Webb


1 Answers

As per cereal documentation

Some archives in cereal can only safely finish flushing their contents upon their destruction. Make sure, especially for output serialization, that your archive is automatically destroyed when you are finished with it.

So it is imporant to call os.str() outside of serialize block, i.e.

MyClass data("hello", 6, true);
std::stringstream os;
{
    cereal::JSONOutputArchive archive_out(os);
    archive_out(CEREAL_NVP(data));
}
string json_str = os.str();
cout << json_str << endl;

// deserialize
std::stringstream is(json_str);
MyClass data_new;
{
    cereal::JSONInputArchive archive_in(is);
    archive_in(data_new);
    cout << data_new.y << endl;
}

This is working code. You may want to change it further upon your needs

like image 89
miradham Avatar answered Dec 24 '22 02:12

miradham