Throw exception during binary deserialization when version is not supported
This commit is contained in:
parent
13428667f8
commit
44c6b8c609
|
@ -379,7 +379,7 @@ as_of_version(3):
|
|||
std::uint32_t bar; // will be read/written if outer scope version is >= 3
|
||||
};
|
||||
|
||||
// example struct where version is serialized/deserialized; defaults to version when writing
|
||||
// example struct where version is serialized/deserialized; defaults to version 3 when writing
|
||||
struct Example : public BinarySerializable<Example, 3> {
|
||||
Nested nested; // will be read/written in any case, version is "propagated down"
|
||||
std::uint32_t a, b; // will be read/written in any case
|
||||
|
@ -395,8 +395,11 @@ as_of_version(4):
|
|||
};
|
||||
</pre>
|
||||
|
||||
A mechanism to catch unsupported versions during deserialization is yet to be implemented.
|
||||
Additionally, the versioning is completely untested at this point.
|
||||
The version specified as template argument is also assumed to be the highest supported version.
|
||||
If a higher version is encountered during deserialization, `BinaryVersionNotSupported` is thrown
|
||||
and the deserialization aborted.
|
||||
|
||||
Note that the versioning is mostly untested at this point.
|
||||
|
||||
### Remarks
|
||||
* Static member variables and member functions are currently ignored by the generator.
|
||||
|
|
|
@ -308,10 +308,13 @@ void BinarySerializationCodeGenerator::generate(std::ostream &os) const
|
|||
<< ">(BinaryDeserializer &deserializer, ::" << relevantClass.qualifiedName << " &customObject, BinaryVersion version)\n{\n";
|
||||
if (!relevantClass.relevantBase.empty()) {
|
||||
os << " // read version\n"
|
||||
" if constexpr (Versioning<"
|
||||
" using V = Versioning<"
|
||||
<< relevantClass.relevantBase
|
||||
<< ">::enabled) {\n"
|
||||
" version = deserializer.readVariableLengthUIntBE();\n"
|
||||
<< ">;\n"
|
||||
" if constexpr (V::enabled) {\n"
|
||||
" V::assertVersion(version = deserializer.readVariableLengthUIntBE(), \""
|
||||
<< relevantClass.qualifiedName
|
||||
<< "\");\n"
|
||||
" }\n";
|
||||
}
|
||||
os << " // read base classes\n";
|
||||
|
|
|
@ -14,10 +14,13 @@
|
|||
|
||||
namespace ReflectiveRapidJSON {
|
||||
|
||||
using BinaryVersionNotSupported = VersionNotSupported<BinaryVersion>;
|
||||
|
||||
/*!
|
||||
* \brief The BinarySerializable class provides the CRTP-base for (de)serializable objects.
|
||||
*/
|
||||
template <typename Type, BinaryVersion v> struct BinarySerializable {
|
||||
using VersionNotSupported = BinaryVersionNotSupported;
|
||||
void toBinary(std::ostream &outputStream, BinaryVersion version = 0) const;
|
||||
BinaryVersion restoreFromBinary(std::istream &inputStream);
|
||||
static Type fromBinary(std::istream &inputStream);
|
||||
|
|
|
@ -26,6 +26,11 @@ public
|
|||
|
||||
CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsVersioned, T::version);
|
||||
|
||||
template <typename VersionType> struct VersionNotSupported {
|
||||
VersionType presentVersion = 0, maxVersion = 0;
|
||||
const char *record = nullptr;
|
||||
};
|
||||
|
||||
template <typename Type, bool Condition = IsVersioned<Type>::value> struct Versioning {
|
||||
static constexpr auto enabled = false;
|
||||
};
|
||||
|
@ -33,10 +38,21 @@ template <typename Type, bool Condition = IsVersioned<Type>::value> struct Versi
|
|||
template <typename Type> struct Versioning<Type, true> {
|
||||
static constexpr auto enabled = Type::version != 0;
|
||||
static constexpr auto serializationDefault = Type::version;
|
||||
static constexpr auto maxSupported = Type::version;
|
||||
static constexpr auto applyDefault(decltype(serializationDefault) version)
|
||||
{
|
||||
return version ? version : serializationDefault;
|
||||
}
|
||||
static constexpr auto isSupported(decltype(maxSupported) version)
|
||||
{
|
||||
return version <= maxSupported;
|
||||
}
|
||||
static constexpr auto assertVersion(decltype(maxSupported) version, const char *record = nullptr)
|
||||
{
|
||||
if (!isSupported(version)) {
|
||||
throw typename Type::VersionNotSupported({ .presentVersion = version, .maxVersion = maxSupported, .record = record });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ReflectiveRapidJSON
|
||||
|
|
Loading…
Reference in New Issue