Loki-Astari / ThorsMongo

C++ MongoDB API and BSON/JSON Serialization library
GNU General Public License v3.0
316 stars 72 forks source link

read problem with map of pointers #84

Closed zhianguo closed 6 months ago

zhianguo commented 6 months ago

deserialize problem with map with pointer as template type version: commit 4db8e9d17aae29c0dd1d4774ac4587b6f53d70ff (HEAD -> header-only, origin/header-only) Author: Loki Astari Loki.Astari@gmail.com Date: Tue Aug 8 14:31:18 2023 -0700

here is a modified version of example3.cpp:

include "ThorSerialize/Serialize.h"

include "ThorSerialize/Serialize.tpp"

include "ThorSerialize/Traits.h"

include "ThorSerialize/JsonThor.h"

include

include

include

include

struct Vehicle { Vehicle(){} Vehicle(int speed) : speed(speed) {} virtual ~Vehicle() {} int speed; ThorsAnvil_PolyMorphicSerializer(Vehicle); }; struct Bike: public Vehicle { Bike(){} Bike(int speed, int stroke) : Vehicle(speed) , stroke(stroke) {} int stroke; ThorsAnvil_PolyMorphicSerializer(Bike); };

struct AllVs { std::map<std::string, Vehicle*> myVehicles; };

ThorsAnvil_MakeTrait(AllVs, myVehicles); ThorsAnvil_MakeTrait(Vehicle, speed); ThorsAnvil_ExpandTrait(Vehicle, Bike, stroke);

int main() { Vehicle* init = new Bike(10, 2); AllVs myGarage; myGarage.myVehicles.emplace("bike1", init);

std::ofstream outputJSONfile("pretty.json");
using ThorsAnvil::Serialize::jsonExporter;
outputJSONfile << jsonExporter(myGarage);

using ThorsAnvil::Serialize::jsonImporter;
AllVs myGarage1;
std::ifstream file("pretty.json");
if (file >> jsonImporter(myGarage1)) {
    std::cout << "Object Read OK\n";
    std::cout << jsonExporter(myGarage1) << "\n";
}
else {
    std::cout << "Object Read FAIL\n";
}

}

the installation was header only

g++ -std=c++17 -I/usr/local/include  example3.cpp -o example3 

There is no problem with export. Here is the error when importJson is called:
id: 0 ThorsAnvil::Serialize::DeSerializationForBlock::DeSerializationForBlock: Invalid Object Startid: 1 ThorsAnvil::Serialize::DeSerializer::parse: Caught Exception: id: 0 ThorsAnvil::Serialize::DeSerializationForBlock::DeSerializationForBlock: Invalid Object Startid: 2 ThorsAnvil::Serialize::DeSerializer::parse: ReThrow Exception: id: 0 ThorsAnvil::Serialize::DeSerializationForBlock::DeSerializationForBlock: Invalid Object Startid: 3 ThorsAnvil::Serialize::Importer::operator>>: Caught Exception: id: 0 ThorsAnvil::Serialize::DeSerializationForBlock::DeSerializationForBlock: Invalid Object StartObject Read FAIL

Environment:

Additional context

Add any other context about the problem here.

Loki-Astari commented 6 months ago

The problem is you did not close the output file before opening it for reading. As a result, the file was not flushed to disk.

Change your main to this:

int main()

{
    using ThorsAnvil::Serialize::jsonExporter;
    using ThorsAnvil::Serialize::jsonImporter;

    Vehicle* init = new Bike(10, 2);
    AllVs myGarage;
    myGarage.myVehicles.emplace("bike1", init);

    {
        std::ofstream outputJSONfile("pretty.json");
        outputJSONfile << jsonExporter(myGarage);
        // putting outputJSONfile in this block forces the stream to close.
        // this will force the data to be flushed to disk before the file is opened below.
    }

    AllVs myGarage1;
    std::ifstream file("pretty.json");
    if (file >> jsonImporter(myGarage1)) {
        std::cout << "Object Read OK\n";
        std::cout << jsonExporter(myGarage1) << "\n";
    }
    else {
        std::cout << "Object Read FAIL\n";
    }
}