improve resilience to breaking changes of serialization format

This commit is contained in:
2022-08-26 01:55:05 +09:00
parent 8c25d22955
commit 231f67d5dd
26 changed files with 488 additions and 237 deletions

View File

@@ -42,11 +42,16 @@ class FileHolder : public nf7::FileBase::Feature {
FileHolder& operator=(const FileHolder&) = delete;
FileHolder& operator=(FileHolder&&) = delete;
void Serialize(auto& ar) const {
void Serialize(nf7::Serializer& ar) const {
ar(entity_);
}
void Deserialize(auto& ar) {
ar(entity_);
void Deserialize(nf7::Deserializer& ar) {
try {
ar(entity_);
} catch (nf7::Exception&) {
entity_ = std::monostate {};
ar.env().Throw(std::current_exception());
}
SetUp();
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include <exception>
#include <memory>
#include <string>
#include <type_traits>
@@ -21,20 +22,22 @@ concept GenericTypeInfo_Description_ = requires() { T::kTypeDescription; };
template <typename T>
class GenericTypeInfo : public File::TypeInfo {
class GenericTypeInfo : public nf7::File::TypeInfo {
public:
GenericTypeInfo(const std::string& name, std::unordered_set<std::string>&& v) noexcept :
TypeInfo(name, AddFlags(std::move(v))) {
}
std::unique_ptr<File> Deserialize(Env& env, Deserializer& d) const override
std::unique_ptr<nf7::File> Deserialize(nf7::Deserializer& ar) const override
try {
return std::make_unique<T>(env, d);
return std::make_unique<T>(ar);
} catch (nf7::Exception&) {
throw nf7::DeserializeException {"deserialization failed"};
} catch (std::exception&) {
throw nf7::DeserializeException {"deserialization failed"};
}
std::unique_ptr<File> Create(Env& env) const override {
if constexpr (std::is_constructible<T, Env&>::value) {
std::unique_ptr<File> Create(nf7::Env& env) const override {
if constexpr (std::is_constructible<T, nf7::Env&>::value) {
return std::make_unique<T>(env);
} else {
throw nf7::Exception {name()+" has no factory without parameters"};
@@ -54,7 +57,7 @@ class GenericTypeInfo : public File::TypeInfo {
private:
static std::unordered_set<std::string> AddFlags(
std::unordered_set<std::string>&& flags) noexcept {
if (std::is_constructible<T, Env&>::value) {
if (std::is_constructible<T, nf7::Env&>::value) {
flags.insert("nf7::File::TypeInfo::Factory");
}
return flags;

View File

@@ -20,7 +20,9 @@ struct serializer<
public:
template <typename Archive>
static Archive& save(Archive& ar, const std::unique_ptr<nf7::File>& f) {
ar(std::string(f->type().name()));
ar(std::string {f->type().name()});
typename Archive::ChunkGuard guard {ar};
f->Serialize(ar);
return ar;
}
@@ -28,7 +30,16 @@ struct serializer<
static Archive& load(Archive& ar, std::unique_ptr<nf7::File>& f) {
std::string name;
ar(name);
f = nf7::File::registry(name).Deserialize(nf7::Env::Peek(), ar);
auto& type = nf7::File::registry(name);
try {
typename Archive::ChunkGuard guard {ar};
f = type.Deserialize(ar);
guard.ValidateEnd();
} catch (...) {
f = nullptr;
throw;
}
return ar;
}
};