mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-29 23:07:48 +02:00
Implemented compact serialization of integer numbers
This commit is contained in:
@@ -177,12 +177,65 @@ public:
|
||||
return * this;
|
||||
}
|
||||
|
||||
template < class T, typename std::enable_if_t < std::is_fundamental_v<T> && !std::is_same_v<T, bool>, int > = 0 >
|
||||
template< typename IntegerType>
|
||||
void loadEncodedInteger(IntegerType & value)
|
||||
{
|
||||
using UnsignedType = std::make_unsigned_t<IntegerType>;
|
||||
UnsignedType valueUnsigned = 0;
|
||||
|
||||
uint_fast8_t offset = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
uint8_t byteValue;
|
||||
load(byteValue);
|
||||
|
||||
if ((byteValue & 0x80) != 0)
|
||||
{
|
||||
valueUnsigned |= (byteValue & 0x7f) << offset;
|
||||
offset += 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
valueUnsigned |= (byteValue & 0x3f) << offset;
|
||||
|
||||
if constexpr(std::is_signed_v<IntegerType>)
|
||||
{
|
||||
bool isNegative = (byteValue & 0x40) != 0;
|
||||
if (isNegative)
|
||||
value = -valueUnsigned;
|
||||
else
|
||||
value = valueUnsigned;
|
||||
}
|
||||
else
|
||||
value = valueUnsigned;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template < class T, typename std::enable_if_t < std::is_floating_point_v<T>, int > = 0 >
|
||||
void load(T &data)
|
||||
{
|
||||
this->read(static_cast<void *>(&data), sizeof(data), reverseEndianness);
|
||||
}
|
||||
|
||||
template < class T, typename std::enable_if_t < std::is_integral_v<T> && !std::is_same_v<T, bool>, int > = 0 >
|
||||
void load(T &data)
|
||||
{
|
||||
if constexpr (sizeof(T) == 1)
|
||||
{
|
||||
this->read(static_cast<void *>(&data), sizeof(data), reverseEndianness);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasFeature(Version::COMPACT_INTEGER_SERIALIZATION))
|
||||
loadEncodedInteger(data);
|
||||
else
|
||||
this->read(static_cast<void *>(&data), sizeof(data), reverseEndianness);
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if_t < is_serializeable<BinaryDeserializer, T>::value, int > = 0 >
|
||||
void load(T &data)
|
||||
{
|
||||
@@ -199,6 +252,11 @@ public:
|
||||
load(data[i]);
|
||||
}
|
||||
|
||||
void load(Version &data)
|
||||
{
|
||||
this->read(static_cast<void *>(&data), sizeof(data), reverseEndianness);
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if_t < std::is_enum_v<T>, int > = 0 >
|
||||
void load(T &data)
|
||||
{
|
||||
|
||||
@@ -140,6 +140,32 @@ public:
|
||||
return * this;
|
||||
}
|
||||
|
||||
template< typename IntegerType>
|
||||
void saveEncodedInteger(const IntegerType & value)
|
||||
{
|
||||
using UnsignedType = std::make_unsigned_t<IntegerType>;
|
||||
UnsignedType valueUnsigned;
|
||||
if constexpr(std::is_signed_v<IntegerType>)
|
||||
valueUnsigned = std::abs(value);
|
||||
else
|
||||
valueUnsigned = value;
|
||||
|
||||
while (valueUnsigned > 0x3f)
|
||||
{
|
||||
uint8_t byteValue = (valueUnsigned & 0x7f) | 0x80;
|
||||
valueUnsigned = valueUnsigned >> 7;
|
||||
save(byteValue);
|
||||
}
|
||||
|
||||
uint8_t lastByteValue = valueUnsigned & 0x3f;
|
||||
if constexpr(std::is_signed_v<IntegerType>)
|
||||
{
|
||||
if (value < 0)
|
||||
lastByteValue |= 0x40;
|
||||
}
|
||||
save(lastByteValue);
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if_t < std::is_same_v<T, bool>, int > = 0 >
|
||||
void save(const T &data)
|
||||
{
|
||||
@@ -147,13 +173,35 @@ public:
|
||||
save(writ);
|
||||
}
|
||||
|
||||
template < class T, typename std::enable_if_t < std::is_fundamental_v<T> && !std::is_same_v<T, bool>, int > = 0 >
|
||||
template < class T, typename std::enable_if_t < std::is_floating_point_v<T>, int > = 0 >
|
||||
void save(const T &data)
|
||||
{
|
||||
// save primitive - simply dump binary data to output
|
||||
this->write(static_cast<const void *>(&data), sizeof(data));
|
||||
}
|
||||
|
||||
template < class T, typename std::enable_if_t < std::is_integral_v<T> && !std::is_same_v<T, bool>, int > = 0 >
|
||||
void save(const T &data)
|
||||
{
|
||||
if constexpr (sizeof(T) == 1)
|
||||
{
|
||||
// save primitive - simply dump binary data to output
|
||||
this->write(static_cast<const void *>(&data), sizeof(data));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasFeature(Version::COMPACT_INTEGER_SERIALIZATION))
|
||||
saveEncodedInteger(data);
|
||||
else
|
||||
this->write(static_cast<const void *>(&data), sizeof(data));
|
||||
}
|
||||
}
|
||||
|
||||
void save(const Version &data)
|
||||
{
|
||||
this->write(static_cast<const void *>(&data), sizeof(data));
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if_t < std::is_enum_v<T>, int > = 0 >
|
||||
void save(const T &data)
|
||||
{
|
||||
|
||||
@@ -45,6 +45,7 @@ enum class ESerializationVersion : int32_t
|
||||
RELEASE_150 = ARTIFACT_COSTUMES, // for convenience
|
||||
|
||||
COMPACT_STRING_SERIALIZATION,
|
||||
COMPACT_INTEGER_SERIALIZATION,
|
||||
|
||||
CURRENT = COMPACT_STRING_SERIALIZATION
|
||||
CURRENT = COMPACT_INTEGER_SERIALIZATION
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user