USCiLab/cereal

Issue with closing braces in JSON using std::stringstream

jonah-gourlay44 opened this issue · 1 comments

It seems like the only way to get a final closing brace in the output JSON when using std::stringstream with cereal::JSONOutputArchive is to destroy the archive before using the string. Is this intentional? Making a call to cereal::JSONOutputArchive::finishNode causes an access violation on destruction of the archive.

Example:

int main()
{
    std::stringstream ss;
    auto* o_ar = new cereal::JSONOutputArchive(ss);
    
    ArchiveObject m;
    /* initialization */
    
    (*o_ar)(CEREAL_NVP(m));
    
    std::cout << ss.str() << std::endl; // Won't have final closing bracket '}' in output

    delete o_ar;    

    std::cout << ss.str() << std::endl; // Now final closing bracket '}' appears in output

    return 0;
}

This makes reusing an archive impossible, because I will have to destroy it each time I want to serialize a new object.

Even if archive reusability goes against the design intention here, I still have to wait for the archive to go out of scope or destroy it manually in order for the std::stringstream to store valid JSON. I've added a call to check if itsNodeStack is empty in the JSONOutputArchive destructor for now so I can make a call to finishNode before the archive is destroyed.

For context, I am developing an RPC application in which I will need the complete serialized string before the archive is destroyed.

The archives are intended to be both created and destroyed when they are needed - you are correct that it needs to go out of scope to finalize the output for the JSON archive. This is touched on in more detail in the main documentation. I would recommend against dynamically allocating the archive and just let the stack clean it up. You can always use a nested scope if you need it gone sooner than later. There is very little overhead to the creation or destruction of the archives.