Open
Description
I'm using serialize19 to create and load binary files of structured data.
But if the file format changes, e.g. because data members have been added / removed, or if the file gets corrupted in some way, the archive reader might cause a read access exception which can't be caught without messing with signal handlers.
=> is there a clean and reliable way to detect and handle this condition without application crash?
#include "serialize19/ReadArchive.h"
#include "serialize19/dynamicWrite.h"
#include "serialize19/serialize.std_string.h"
struct OldFileFormat
{
int a{};
int b{};
std::string s{};
};
struct NewFileFormat
{
int a{};
int b{};
int c{};
std::string s{};
};
template<class A>
void serialize(A& a, OldFileFormat& x)
{
serialize(a, x.a);
serialize(a, x.b);
serialize(a, x.s);
}
template<class A>
void serialize(A& a, NewFileFormat& x)
{
serialize(a, x.a);
serialize(a, x.b);
serialize(a, x.c);
serialize(a, x.s);
}
void main()
{
OldFileFormat old_data{1, 2, "test"};
const auto buffer_old = serialize19::dynamicWrite(old_data);
// the buffer contents usually get saved into a binary file:
// std::ofstream fout{filename, std::ios::binary};
// fout.write(reinterpret_cast<const char*>(slice.begin()), slice.count());
//
// ... and later on we read the file back into a buffer slice via
// std::ifstream fin{filename, std::ios::binary};
// const auto file_buffer = std::vector<uint8_t>{std::istreambuf_iterator(fin), {}}
// const auto file_buffer_slize = serialize19::BufferSlice{file_buffer.data(), file_buffer.size()});
//
// here we just skip this step and hand over the already existing buffer slice
auto reader = serialize19::ReadArchive{buffer_old.slice()};
NewFileFormat new_data;
try
{
serialize(reader, new_data);
}
catch (const std::exception& ex)
{
// We want to catch all file read exceptions in a clean way but there is only a hardware exception being thrown which requires dirty signal handler
}
}